본문 바로가기

Splunk Tip

Splunk 한 데이터모델의 여러 데이터셋을 간단하게 검색하고 싶어요!

스플렁크의 데이터모델 속, 데이터셋을 검색하고자 할때 사용하는 쿼리문은 다음과 같다

| datamodel 데이터모델명 데이터셋명 search
## 또 다른 방식
|from datamodel:데이터모델명.데이터셋명


같은 데이터 모델의 여러 데이터셋을 검색하고 싶다고

|datamodel 데이터모델명 데이터셋명, 데이터셋명 search
|datamodel 데이터모델명 (데이터셋명 OR 데이터셋명) search
|datamodel 데이터모델명 데이터셋명* search

위와 같은 시도를 할 수 있으나 datamodel 명령어는 다중 데이터셋 검색을 지원하지 않는다.
from datamodel 쿼리문도 마찬가지다.

그렇다고

|datamodel 데이터모델명 데이터셋명1
append [|datamodel 데이터모델명 데이터셋명2]
append [|datamodel 데이터모델명 데이터셋명3]
....

같은 비효율적인 쿼리를 무턱대고 짤 수도 없는 노릇이다.
이렇게 될 경우 1 쿼리를 실행하는 게 아니라 n개 쿼리를 실행하는 것처럼 동작하기 때문에 작업 스케줄러 입장에서 리소스를 무척 많이 먹게 된다.
한 두개 검색하는 거라면 모르겠으나 데이터셋 숫자가 많아질 수록 답도 없어지며, 가독성은 수직하락한다.

하지만 데이터셋 이름들을 일괄 추출할 수 있는 방법이 있다.

|datamodel 데이터모델명

위와 같이 검색할 경우 데이터 모델의 원본 설정 데이터를 JSON 형식으로 뽑아낼 수 있다.
그리고 이 원본 설정 데이터엔 데이터셋 이름이 모두 들어있다.

따라서 정규식을 이용해서 object란 이름의 칼럼에 데이터셋 이름을 추출해 저장한다.

|datamodel 데이터모델명
|rex field=_raw max_match=0 "(?ms)objectName\":\"(?<object>\w*)\""

위의 rex 명령어는 objectName":"내가원하는문자열"을 추출하는 정규식이다.
object란 컬럼명은 임의로 정한것이다.
그외 정규식의 (?ms)란 문자열은 정규식이 일치하는 데이터를 1회가 아니라 여러 번 추출한다는 뜻이다.

max_match는 (?ms)를 사용할 경우 같이 설정해줘야 하는 설정값인데, 이름 그대로 최대 몇번 추출할 것인지 설정한다.
설정하지 않을 시, 기본값은 1로 설정되어 있어 여러번 추출하는 목적을 달성하려면 무조건 설정을 해줘야 한다.
0으로 설정 시 정규식이 일치하는 만큼 무제한으로 추출한다는 뜻이다.

하지만 이대로 쿼리를 실행하면 1개의 행에 모든 데이터셋 이름이
데이터셋1
데이터셋2
데이터셋3
....
형식으로 저장된다.

따라서 이 n개의 데이터셋을 n개 행으로 나누려면 mvexpand 명령어를 사용한다.

|datamodel 데이터모델명
|rex field=_raw max_match=0 "(?ms)objectName\":\"(?<object>\w*)\""
|mvexpand object | where like(object, "%키워드%")
|table object

이렇게 object란 칼럼명을 가진 이벤트가 데이터셋 이름 갯수만큼 나눠지게 되면,
보통 실제로 필요한 하위 데이터셋 말고도 루트 데이터, 루트 이벤트, 기타 불필요한 데이터 셋이 자주 끼어들어가기 때문에
where을 이용해 필터링이 필요하다.
이 where 절을 효과적으로 사용하는 방법은 추후 다른 포스트를 통해 다루려고 한다.
그 후 실제로 필요한 건 object 칼럼 뿐이므로 table 을 이용해 object 칼럼만 남겨준다.

이제 필요한 밑작업은 다 끝났으니,
다중 검색을 실행한다.
다중 검색은 map 명령어를 이용해 토큰 형식으로 다수의 값만큼 검색을 실행한다.

|datamodel 데이터모델명
|rex field=_raw max_match=0 "(?ms)objectName\":\"(?<object>\w*)\""
|mvexpand object | where like(object, "%키워드%")
|table object
|map maxsearches=100 search="|from datamodel:데이터모델명.$object$"

이렇게 쿼리를 구성할 경우 이벤트의 숫자만큼 object 컬럼의 데이터를 추출해 쿼리에 끼워넣어 다중 실행 후 하나의 결과로 보여주게 된다.
maxsearch 설정은 글자 그대로 최대 몇 번의 검색을 실행할 수 있는지 설정하는 것으로 상황에 맞춰 임의 설정한다.

search 구문은 데이터모델을 검색하는 방법이 여러가지인 만큼 다음과 같은 방식으로도 표현할 수 있다.

|map maxsearches=100 search="|datamodel 데이터모델명 $object$ flat"

이 경우 최상단에서 datamodel 명령어를 검색시 마지막에 search를 썼는데 여기선 flat을 사용한게 눈에 띈다.
search로 검색하게 되면 컬럼명에 데이터셋 이름이 합쳐지기 때문인데, search를 사용시
데이터셋명1.컬럼명1
데이터셋명1.컬럼명2
데이터셋명2.컬럼명1
데이터셋명2.컬럼명2
...
이런 방식으로 통일된 컬럼명을 사용해도 데이터 컬럼이 나눠진다.

하지만 flat을 사용하면 직관적인 결과가 출력된다.
컬럼명1
컬럼명2
이렇게 데이터가 합쳐지게 된다.