스플렁크를 포함한 DB는 결국 사용자의 역량에 따라 환골탈태하는 물건이다.
정말 관심이 없거나 생각이 없다면 그냥 Ctrl + F 검색을 더 쉽게 하는 수준으로 사용하는 것 같다.

거기서 조금만 발전하면 엑셀 표 뽑아주는 기계정도로 인식을 하는 듯 하고.
오라클 DB 같은 전통적인 DB의 경우 딱 그 정도까지만 해도 수십억 단위의 데이터의 저장 및 관리가 쉽다는 관점에서
실사용의 의의를 다 채웠다고 해도 할 말이 없다.
하지만 Splunk가 전통적인 DB와 차별점을 가지고, 기업용으로는 라이선스 비용조차 더 비싸게 받아먹는 이유는,
표, 통계, 보고서 작성, 대시보드 표기 등 DB 안에 있는 데이터를 가공/처리해서 보여주는 프런트엔드 애플리케이션을 만들고 유지보수할 필요 없이 쿼리만 가지고 뚝딱뚝딱 만들 수 있는 DB+애플리케이션 올인원 솔루션이라는 것이다.
이걸 안 쓸 거면 그냥 DB에 아파치 깔고 jquery 등 웹서버 <-> DB 통신 코드 짜고 그걸 웹페이지로 보여주게 세팅하는게 라이선스 비가 훨씬 싸다.
그러니 만약 Splunk를 쓴다면 당연히 데이터 가공과 처리를 하는 법을 알아야 하지 않을까?
그 기본이 바로 stats을 비롯한 통계 명령어 삼형제다.
stats 삼형제에서 사용 가능한 기능 하나하나를 소개하고 예시를 들어주는 것보다
먼저 필요한 것은 이 삼형제가 왜 셋이나 있는가를 알아야 한다.
어느 것 하나 버려지는 것 없이 쓸모는 확실히 있다.
예를 들어 간단한 가계부가 룩업파일 '가계부.csv' 로 저장되어 있다고 치자.
사용처 | 금액 |
월급 | 2,000,000 |
식당 | -10,000 |
보험 | -200,000 |
식당 | -10,000 |
대중교통 | -1,000 |
식당 | -10.000 |
대중교통 | -1,000 |
이를 불러오는 쿼리는 다음과 같다.
|inputlookup 가계부.csv
1. stats
이를 가장 간단하게 통계 결과로 내는 방법은, 역시 가장 기본 명령어인 stats이다.
실무에서도 가장 많이 쓴다.
역시 가계부는 일단 합산부터 계산해야 하지 않을까?
금액 합산을 하는 가장 기본적인 쿼리는 다음과 같다.
|inputlookup 가계부.csv
|stats sum(금액) as 잔액
여기서 sum()은 이름에서 알 수 있듯이 합산을 해주는 기능이고, 이 괄호 안에 칼럼명을 넣으면 그 칼럼의 숫자를 합산 해준다.
'as 잔액' 부분은 그냥 표시 칼럼의 이름을 지정해주는 기능인데,
지정하지 않으면 칼럼명이 'sum(금액)' 이런 식으로 저장되기 때문에 나중에 쓰기 불편하다.
아무튼 위의 쿼리를 실행하면 다음과 같이 나온다.
잔액 |
1,768,000 |
stats 명령어는 이렇게 한 번 실행하면 이전까지 갖고있던 가계부 데이터가 아니라 그냥 아예 싹 밀고 통계로 나온 새로운 결과를 보여준다.
다른 언어에서 쓰이는 GROUP BY 명령어처럼 사용처 별로 사용 금액을 알고 싶다면 명령어를 살짝 고치면 바로 나온다.
|inputlookup 가계부.csv
|stats sum(금액) as 금액 by 사용처
위의 'by' 로 인해서 이제 무작정 다 합산하는 게 아니라 사용처 별로 각각 합산하여 통계를 보여준다.
사용처 | 금액 |
월급 | 2,000,000 |
식당 | -30,000 |
보험 | -200,000 |
대중교통 | -2,000 |
이렇게만 사용해도 sum()을 비롯한 count 등 다양한 함수를 사용하는 선에서 통계 기능의 80%는 처리 가능하다.
이제 어디가서 Splunk를 사용할 수 있다고 말할 수 있는 수준은 된 것이다.
하지만 기능이 조금만 더 복잡해지면 문제가 생기는데,
통계 결과의 통계 결과를 내야할 경우다.
사용처 | 금액 |
월급 | 2,000,000 |
식당 | -10,000 |
보험 | -200,000 |
식당 | -10,000 |
대중교통 | -1,000 |
식당 | -10.000 |
대중교통 | -1,000 |
처음으로 돌아오면, 각 사용처별 횟수를 세서 가장 많은 횟수를 가진 사용처의 사용 비율을 계산하고 싶다고 치자.
그럼 일단 전체 사용횟수는 처음부터 당장 셀 수 있고,
최다사용처는 세기 전에 일단 최다사용처가 어디인지 먼저 알아야 하기 때문에 일단 이렇게 쿼리를 짜보자.
|inputlookup 가계부.csv
|stats count as 총수 sum(금액) as 금액 mode(사용처)
참고로 mode는 가장 자주 나오는 값을 알려주는 기능이다.
이 쿼리를 실행하면 결과는 다음과 같이 나온다.
총수 | 금액 | mode(사용처) |
7 | 1,768,000 | 식당 |
이제 이 데이터를 가지고 식당에 몇 번이나 갔는지 계산해야 하는데, 결과에 없으니 세질 못한다.
그렇다고 처음 stats 부터 세려니 어디가 최다사용처인지 알 수가 없다.
금고를 열기 위해 금고 안에 들어있는 열쇠를 꺼내야 하는 상황인 것이다.
컴퓨터공학에 기초지식과 응용력이 있는 사람이라면 이런 걸 시도해볼 수 있다.
|inputlookup 가계부.csv
|stats count as 총수 sum(금액) as 금액 mode(사용처) count(eval(사용처 == mode(사용처)))
'count(eval(조건))' 구문을 넣으면 조건부 셈, 즉 엑셀의 COUNTIF 와 같은 기능을 구현할 수 있다.
이것에 관해선 추후 Splunk Tip 항목으로 설명하기로 하고,
아무튼 거기에 mode를 넣는다면 한줄에 가능하지 않을까?
굉장히 직관적이고 합리적인 시도지만, 현실은 그리 호락호락하지 않다.
eval 구문 안에는 sum, count, mode 같은 stats 용 함수 사용이 불가능하다.
충분히 해줄 법도 한데, 아무튼 안된다.
이럴 때 구세주로 나오는 게 eventstats 다.
2. eventstats
|inputlookup 가계부.csv
|eventstats mode(사용처) as 최다사용처
eventstats 명령어는 통계를 내지만 통계 실행 전 결과를 없애버리지 않고,
칼럼으로 통계값을 추가해준다.
따라서 결과는 다음과 같이 나온다.
사용처 | 금액 | 최다사용처 |
월급 | 2,000,000 | 식당 |
식당 | -10,000 | 식당 |
보험 | -200,000 | 식당 |
식당 | -10,000 | 식당 |
대중교통 | -1,000 | 식당 |
식당 | -10.000 | 식당 |
대중교통 | -1,000 | 식당 |
이 다음 바로 아까 언급한 countif 기능과 함께 stats 구문을 한번 더 실행할 수 있다.
|inputlookup 가계부.csv
|eventstats mode(사용처) as 최다사용처
|stats count as 총수 sum(금액) as 금액 values(최다사용처) count(eval(사용처 == 최다사용처)) as 최다사용횟수
count 조건으로 사용처와 최대사용처의 값이 서로 같아야 한다고 명시했기 때문에 식당만 count가 된다.
value(칼럼명)은 해당 칼럼의 있는 값을 모두 보여주는 기능이다.
하지만 값이 '식당' 한 가지만 있기 때문에 결국 식당만 보여 준다.
따라서 결과는 다음과 같다.
총수 | 금액 | values(최다사용처) | 최다사용횟수 |
7 | 1,768,000 | 식당 | 3 |
이렇게 필요한 값은 모두 얻어 냈으니,
좀 더 자세한 설명은 다른 글에서 하겠지만, eval 구문을 통해 퍼센트를 계산할 수 있다.
|inputlookup 가계부.csv
|eventstats mode(사용처) as 최다사용처
|stats count as 총수 sum(금액) as 금액 values(최다사용처) count(eval(사용처 == 최다사용처)) as 최다사용횟수
|eval 퍼센트=round(최다사용횟수/총수,4)*100."%"
직관적으로 보면 알 수 있겠지만, 퍼센트를 계산하기 위해 분자에 분모를 나누고,
round(숫자,자릿수) 기능을 이용해 소수점 넷째 자리까지 반올림하게 한 다음, 100을 곱하여 소숫점 둘째자리 까지의 퍼센트 값을 구했다.
그리고 마침표(.) 를 이용해 문자열 "%"를 끝에 귀엽게 붙여줬다.
이에 관련해선 아래 글 참고.
Splunk 에서 문자열을 합치는 2가지 방법
스플렁크에서 문자열을 쓰는 방식 중 가장 많이 쓰는건 아무래도 + 기호다. |makeresults |eval 결과="문"+"자"+"열" + 기호는 C 시절 부터 Python까지 프로그래밍 언어에서도 문자열을 합치는 유구한 방식
splunk-tech.tistory.com
아무튼 결과는 다음과 같다.
총수 | 금액 | values(최다사용처) | 최다사용횟수 | 퍼센트 |
7 | 1,768,000 | 식당 | 3 | 42.86% |
이렇게 eventstats은 stats의 한계를 뛰어넘게 해주는 좋은 기능이지만,
stats 만 써도 충분한데 eventstats을 사용하면 문제가 있다.
특히 대용량 데이터를 처리할 때는 리소스를 잡아먹는 주범이 된다.
100만개의 데이터를 처리할 때 stats 이후 eval 계산을 한다면
100만개 -> 1개 의 데이터를 처리해야 한다.
하지만 eventstats을 쓰면 데이터 행이 하나도 없어지지 않으므로
100만개 -> 100만개 데이터를 처리해야 한다.
CPU도 CPU지만 무엇보다 저 데이터를 담아둘 RAM이 많이 소비된다.
3. streamstats
마지막 남은 streamstats은 통계 명령어 삼형제 중 가장 덜 쓰는 명령어긴 하지만
필요할 땐 streamstats이 아니고선 구현할수가 없다.
백문이 불여일견이니 같은 쿼리에서 eventstats과 streamstats만 바꿔 써보자.
|inputlookup 가계부.csv
|eventstats sum(금액) as 잔액
이렇게 쿼리를 실행 시킨다면, 아까 처럼 결과는 모든 행에 똑같이 나온다.
사용처 | 금액 | 잔액 |
월급 | 2,000,000 | 1,768,000 |
식당 | -10,000 | 1,768,000 |
보험 | -200,000 | 1,768,000 |
식당 | -10,000 | 1,768,000 |
대중교통 | -1,000 | 1,768,000 |
식당 | -10.000 | 1,768,000 |
대중교통 | -1,000 | 1,768,000 |
하지만 새로운 사용처가 나타날 때마다 변화하는 잔액값을 표시하고 싶다면 어떨까?
이럴때 streamstats가 필요하다.
이름 그대로 흐름에 맞춰 변화하는 통계값을 보여준다.
|inputlookup 가계부.csv
|streamstats sum(금액) as 잔액
사용처 | 금액 | 잔액 |
월급 | 2,000,000 | 2,000,000 |
식당 | -10,000 | 1,990,000 |
보험 | -200,000 | 1,790,000 |
식당 | -10,000 | 1,780,000 |
대중교통 | -1,000 | 1,779,000 |
식당 | -10.000 | 1,769,000 |
대중교통 | -1,000 | 1,768,000 |
위의 결과표에서 보다시피,
streamstats를 사용하면 흐름에 맞춰 변화하는 sum()의 값을 보여준다.
따라서 시간에 따라 누적되는 항목을 표현하는데 최적의 기능이다.
'Splunk Tech' 카테고리의 다른 글
Splunk 기초 - 따옴표 제대로 이해하기 (0) | 2023.01.19 |
---|---|
Splunk 기초 - Where 절의 효율적 사용 (0) | 2023.01.18 |
Splunk 기초 - Search 절을 이용한 필터링 (1) | 2023.01.18 |