2017년 8월 12일 토요일

Elasticsearch 활용(winlogbeat 사용이 힘들 때)

윈도우 이벤트 로그를 Elasticsearch와 연동할 때, winlogbeat를 이용하면 이래도 되나 싶을 정도로 편하다. 이벤트 로그의 모든 필드를 알아서 정규화해주기 때문. 이래저래 이벤트 로그는 다루기 참 편한 것 같다. Logparser만 있어도 거의 RDB 수준으로 분석할 수 있으니까.

그런데 nxlog 등을 통해 이미 이벤트 로그를 수집하고 있다면, winlogbeat를 이용한 재구축은 번거로울 것이다. 이미 텍스트 형태로 수집된 로그를 Elasticsearch와 연동할 때, 로그 필드 정규화가 필요하다면 grok 필터가 최선. 다음은 nxlog를 이용해서 수집된 윈도우 이벤트 로그.


뚜렷한 'Key - Value' 구조.


해당 로그에서 EventTime, Hostname, EventID, Message 필드를 정규화 후, 추출해주는 grok 정규표현식을 작성해보자. Key 값은 모두 문자열이니 정규표현식 메타문자 \w로 커버 가능.


Key와 Value 값의 구분은 모두 ":", 즉 문자열이 아니다. 메타문자 \W로 커버 가능.


Value 값은 문자(숫자)와 문자가 아닌 것의 조합

이럴 때 '문자 클래스'의 검사 범위 반전 기능을 이용하면 편하다. 메타문자 [^"]"가 아닌 문자만을 검사하기 때문에 "를 만나면 검사를 멈추며, 결과적으로 Value 값만을 검사한다.


검사 결과 중 Value 값에만 추출을 위해 캡쳐그룹을 씌우고,


필드명으로 사용할 이름을 주면 끝.


다음은 검사된 전체 문자열 중 EventTime, Hostname, EventID, Message 필드값만을 캡쳐그룹으로 추출하는 정규표현식.

regex101.com/r/upQyE2/1

grok 필터에 해당 정규표현식 반영
input {
 file {
  path => "d:/event.log"
  start_position => "beginning"
  sincedb_path => "/dev/null"   
 }
}

filter {  grok {    match => { "message" => ".\w+\W+(?<EventTime>[^"]+)\W+\w+\W+(?<HostName>\w+).+?EventID\W+(?<EventID>\w+).+?Message\W+(?<Message>[^"]+).+" }  }
 date {   match => [ "EventTime", "YYYY-MM-dd HH:mm:ss" ]  }  }
output {  elasticsearch { hosts => [ "localhost:9200" ]           index => "event_log"  }  stdout { codec => rubydebug } }

자신있게 실행했으나 에러 발생.


문제가 있다는 11번 라인은 grok 정규표현식인데? 뭐가 문제일까?


원인을 모르겠다면 문제가 되는 부분을 하나씩 제거해보는 수 밖에 없다. 다음은 filter 영역을 전부 주석 처리한 후 실행한 결과. 무슨 인코딩 에러가 나긴 하는데, 로그는 넘어 간다.


다음은 해당 로그 조회 결과. 자세히 보니 로그 내용 중 " 문자가 전부 \로 예외처리가 되어 있다. grok 정규표현식 구분자 "와 구분하기 위해 자동으로 예외처리된 듯.


정규표현식 수정.

regex101.com/r/yUzAM0/1

수정된 정규표현식 반영 후 실행한 결과는 다음과 같다.



일단 로그도 잘 넘어가고, 원했던 필드 정규화도 잘 이루어진다. 한글이 깨지는 문제가 있는데 인코딩이 뭔가 안 맞나 보다. 구글신께 물어봐야 할 듯.

관련 글

댓글 없음:

댓글 쓰기

크리에이티브 커먼즈 라이선스