개요
- logstash filter를 쓸 때 grok pattern을 사용하는 법을 익힌다.
- logstash grok 관련 문서
logstash 정형화 방법
- logstash는 비정형 데이터를 input으로 받았을 때 filter를 통해 정형 데이터로 바꿀 수 있다.
- 이때 dissect나 grok을 쓸 수 있는데,
dissect는 구분자(delimiter)를 이용하여 정형화하는 방법이고,
grok은 정규식을 이용하여 정형화하는 방법이다. - 여기서는 grok만 알아본다.
Grok Basic
- grok 문법
- %{SYNTAX:SEMANTIC}
- 상세
- SYNTAX
- logstash input에서 감지해야하는 정규식 패턴이다.
- SEMANTIC
- 감지된 패턴 데이터를 할당할 logstash 변수명(identifier, 식별자)이다.
- SYNTAX
- SYNTAX 사용법
- 기본 패턴 사전
- logstash 기본 패턴 사전에 등록된 패턴을 SYNTAX로 쓸 수 있다.
- 예를 들어 단어를 SYNTAX로 쓰고 싶은 경우, SYNTAX로 WORD를 쓸 수 있다.
- 기본 패턴 사전에 등록된 WORD의 정규식은 WORD \b\w+\b이다.
- 커스텀 패턴 사전
- logstash는 /usr/share/logstash/pipeline/(이하 pipeline) 디렉토리에서 설정파일을 둔다.
- grok 패턴 사전의 경우, pipeline 디렉토리 하위에 patterns 디렉토리를 만들고 그 안에 파일을 넣어 사용한다.
- 파일은 확장자 없이 생성하며, 모든 파일이 logstash에 import 된다.
- 기본 패턴 사전
- 예시
- logstash input에서 아래와 같은 문장이 왔다고 하자.
- kimsumi is king
- 아래와 같은 grok 패턴을 사용했다.
- %{WORD:s} %{WORD:v} %{WORD:c}
- 결과
- s 변수에 “kimsumi” 할당
- v 변수에 “is” 할당
- c 변수에 “king” 할당
- logstash input에서 아래와 같은 문장이 왔다고 하자.
Test Grok Patterns
- 개요
- 웹에서 grok pattern을 테스트 할 수 있는 사이트이다.
- 링크
- 사용법
- 결과
정규식 연습
- 개요
- test grok patterns에서 실험해보기 전에 정규식이 맞는지부터 확인하면 좋다.
- 여러 정규식 패턴 연습 사이트 중 자주 쓰는 곳이다. 링크
- 실험모습
gin log 파싱해보기
- gin log 예시
- [GIN] 2021/10/05 - 09:04:47 | 200 | 0s | ::1 | GET “/now”
- “김수미 킹왕짱” 예시보다 복잡하지만,
기본 패턴 사전을 잘 활용하여 커스텀 패턴을 만들어 해결할 수 있다. - grok에서 “[”, “]”, ‘”’, “|“는 escaping을 해줘야한다.
- SEMANTIC를 대괄호를 사용하여 지정하면 계층식 변수 선언이 가능하다.
- 예를 들어 [gin][type]으로 했다면 { gin: { type: somthing } } 식으로 할당된다.
- !주의 - Test grok pattern에서는 대괄호를 사용한 SEMANTIC 선언이 되지 않는다.
- 아래의 GINLOG에서 사용된 \s*는 파싱 시 whitespace를 제거하기 위해 사용하였다.
- pattern 예시
- GIN_TIMESTAMP %{YEAR}/%{MONTHNUM}/%{MONTHDAY} - %{HOUR}:%{MINUTE}:%{SECOND}
- GINLOG [%{DATA:[gin][type]}] %{GIN_TIMESTAMP:[gin][time]} | %{NUMBER:[gin][response_status]} | \s%{DATA:[gin][response_time]}\s | \s%{IPORHOST:[gin][remote_ip]}\s | \s%{DATA:[gin][method]}\s "%{DATA:[gin][url]}"
logtstash에 적용해보기
- 개요
- 이제 실제로 logstash.conf에 grok 패턴을 적용시켜보자.
- 예시에서는 문제를 간단하게 하기 위해 logstash.input을 파일로 지정한다.
- logstash config 디렉토리
- 아래와 같은 구조로 디렉토리 및 파일을 만든다.
1 2 3 4 5 6
- logstash - patterns - gin - logstash.conf
- gin grok 패턴
1 2 3
# gin GIN_TIMESTAMP %{YEAR}/%{MONTHNUM}/%{MONTHDAY} - %{HOUR}:%{MINUTE}:%{SECOND} GINLOG \[%{DATA:[gin][type]}\] %{GIN_TIMESTAMP:[gin][time]} \| %{NUMBER:[gin][response_status]} \| \s*%{DATA:[gin][response_time]}\s* \| \s*%{IPORHOST:[gin][remote_ip]}\s* \| \s*%{DATA:[gin][method]}\s* \"%{DATA:[gin][url]}\"
- logstash 설정 파일
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
# logstash.conf input { file { path => ["/usr/share/logstash/gin.log"] sincedb_path => "/dev/null" start_position => "beginning" } } filter { grok { patterns_dir => ["/usr/share/logstash/pipeline/patterns"] match => {"message" => ["%{GINLOG}"]} remove_field => "message" remove_field => "[gin][type]" } } output { stdout { codec => rubydebug } }
- 아래와 같은 구조로 디렉토리 및 파일을 만든다.
- 예시 파일
- 최상위 디렉토리 하위에 gin.log 파일을 생성한다.
1 2 3 4 5 6 7 8
# gin.log [GIN] 2021/10/05 - 09:04:37 | 200 | 27.3227ms | ::1 | GET "/now" [GIN] 2021/10/05 - 09:04:46 | 200 | 26.6912ms | ::1 | GET "/now" [GIN] 2021/10/05 - 09:04:46 | 200 | 0s | ::1 | GET "/now" [GIN] 2021/10/05 - 09:04:46 | 200 | 0s | ::1 | GET "/now" [GIN] 2021/10/05 - 09:04:46 | 200 | 0s | ::1 | GET "/now" [GIN] 2021/10/05 - 09:04:47 | 200 | 0s | ::1 | GET "/now" [GIN] 2021/10/05 - 09:04:47 | 200 | 0s | ::1 | GET "/now"
- logstash 컨테이너 생성
1 2 3 4 5 6 7
# windows 명령어이다. 만약 linux나 os X를 사용한다면 %cd%를 .으로 변경 > docker run \ --name es-c-logstash \ --rm \ -v %cd%/gin.log:/usr/share/logstash/gin.log \ -v %cd%/logstash/:/usr/share/logstash/pipeline/ \ docker.elastic.co/logstash/logstash:7.15.0
- 결과
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
... { "@timestamp" => 2021-10-05T09:04:46.000Z, "gin" => { "response_status" => "200", "remote_ip" => "::1", "response_time" => "0s", "url" => "/now", "method" => "GET" }, "path" => "/usr/share/logstash/gin.log", "host" => "8483a7f58c1d", "@version" => "1" } ...