[Elastic Stack] Filebeat LogBack multiline pattern 적용하기

허주환·2022년 11월 11일
0

Elastic Stack

목록 보기
1/6
post-thumbnail

0. Summary

여러 서비스에 여러대의 BE 서버를 구성하여 운영중에 있다.
서비스의 로그를 확인하기 위해서 해당 서비스의 BE 서버에 접속하여 로그를 확인해야 하는 매우 큰 불편함이 있어 Kafka 강의를 들으면서 이걸 써먹어야 겠다는 생각이 들어서
Dev BE 서버에 Elastic Stack을 구축을 하면서 격은 오류? 를 정리 하려고 한다.

1, Architecture

  • Elastic Stack (ELK + Filebeat)
    • elastic version 8.5
  • kafka
    • 2.13-3.3.1
  • AWS EC2 3대
    • dev1 (Spring Boot)
    • dev2 (Spring Boot)
    • Elastic Stack + kafka

2, filebeat의 multiline 옵션

멀티라인 설정을 않하고 kafka 로 전송시 spring에서 Error가 발생하여 Stack으로 쌓이는 로그나 log.info("{} \n", ...); \n이 들어간 로그가 있을 경우 한줄 씩 보내어 의도와 다르게 로그가 수집되는 현상을 격었다.
ex) input

2022-11-11 09:14:00,209 [INFO ] com.test.persistence.TestRepositoryImpl.findWorklistCount:709 - StopWatch 'findWorklistCount': running time = 85525494 ns
---------------------------------------------
ns         %     Task name
---------------------------------------------
087253813  100%  TestDB

ex) output (elasticSearch에 수집된 로그)

{
  "_index": "test-dev-log-2022.11.11",
  "_version": 1,
  "_score": 0,
  "message": "2022-11-11 09:14:00,209 [INFO ] com.test.persistence.TestRepositoryImpl.findWorklistCount:709 - StopWatch 'findWorklistCount': running time = 85525494 ns",
  // ...
},
{
  "_index": "test-dev-log-2022.11.11",
  "_version": 1,
  "_score": 0,
  "message": "---------------------------------------------",
  // ...
},
{
  "_index": "test-dev-log-2022.11.11",
  "_version": 1,
  "_score": 0,
  "message": "ns         %     Task name",
  // ...
},
{
  "_index": "test-dev-log-2022.11.11",
  "_version": 1,
  "_score": 0,
  "message": "---------------------------------------------",
  // ...
},
{
  "_index": "test-dev-log-2022.11.11",
  "_version": 1,
  "_score": 0,
  "message": "087253813  100%  TestDB",
   // ...
}

이 때 멀티라인 설정을 해주면 이와 같은 문제를 해결할 수 있다.

  • multiline.pattern
    • 정규식을 지정함
    • logstash와 패턴이 조금 다름
    • filebeat pattern Test (링크) - 유용함
  • multiline.negate
    • true | false(default)
    • multiline.pattern에 부정하는지 여부
  • multiline.match
    • after | before
    • line 들의 결합 방식을 지정하는 옵션
    • 이 설정은 multiline.negate 옵션에 따라 결과 값이 달라짐

multiline.negate + multiline.match 조합

  • 예시 패턴) ^b
    • b로 시작하는 모든문자열
  • Input
    • 빨간색글씨: 패턴에 일치하는 문자
    • 검은색글씨: 설명의 이전 | 다음 에 해당하는 문자
조합 번호multiline.negatemultiline.match설명InputOutput풀이
1falseafter<공식문서 - papago 번역>
패턴에 일치하는 연속된 줄을
패턴에 일치하지 않는 이전줄에 추가

a
b
b
c
b
b
abb
cbb
패턴 일치 O: bb
패턴 일치 X: a
a의 after
즉 a + bb = abb

패턴 일치 O: bb
패턴 일치 X: c
c의 after
즉 c + bb = cbb
2falsebefore<공식문서>
패턴에 일치하는 연속된 줄을
패턴에 일치하지 않는 다음줄에 추가
b
b
a
b
b
c
bba
bbc
패턴 일치 O: bb
패턴 일치 X: a
a의 before
즉 bb + a = bba

패턴 일치 O: bb
패턴 일치 X: c
c의 after
즉 bb + c = bbc
3trueafter<공식문서>
패턴에 일치하는 않는 연속된 줄을
패턴에 일치하는 이전줄에 추가
b
a
c
b
d
e
bac
bde
패턴 일치 O: b
패턴 일치 X: ac
b의 after
즉 b + ac = bac

패턴 일치 O: b
패턴 일치 X: de
b의 after
즉 b + de = bde
4truebefore<공식문서>
패턴에 일치하는 않는 연속된 줄을
패턴에 일치하는 다음줄에 추가

a
c
b
d
e
b
acb
deb
패턴 일치 O: b
패턴 일치 X: ac
b의 before
즉 ac + b = acb

패턴 일치 O: b
패턴 일치 X: de
b의 before
즉 de + b = deb

3, 설정

Filebeat

  • filebeat.yml

    filebeat.inputs:
    - type: log
      enabled: true
      paths:
        - /home/ec2-user/test/logs/spring-test.log
      multiline.pattern: '^\d{4}-\d{2}-\d{2}'
      multiline.negate: true
      multiline.match: after
    
    output.kafka:
      hosts: ["kafka-dev:9092"] # dev server라 replica 1개
      topic: "test-dev-logs"
      compression: gzip
    • log 가 2022-11-11 (YYYY-MM-DD) 형태로 시작하기 때문에
    • 패턴을 ^\d{4}-\d{2}-\d{2} 로 설정
      • 좀더 정규식을 logback 정규식에 맞춰서 할 필요는 있어보임
    • 옵션 조합은 (3) 번 true, after 옵션이 필요했다

Logstash

  • logstash.conf

      grok {
            match => {
                "message" => "%{TIMESTAMP_ISO8601:timestamp} \[%{LOGLEVEL:logLevel}\s?\] %{DATA:method}:%{NUMBER:line} \- %{GREEDYDATA:msg}"
            }
    
            add_field => {
                    "code" => "%{method}:%{line}"
            }
      }

4, 결과

input

2022-11-11 09:13:59,228 [INFO ] com.test.service.Service.lambda$subscribe$13:218 - SSE Sinks doOnSubscribe currentSubscriberCount: 38, reactor.core.publisher.FluxFlatMap$FlatMapMain@70a05dae
2022-11-11 09:14:00,209 [INFO ] com.test.persistence.TestRepositoryImpl.findWorklistCount:709 - StopWatch 'findWorklistCount': running time = 85525494 ns
---------------------------------------------
ns         %     Task name
---------------------------------------------
087253813  100%  TestDB

output (elasticSearch 수집된 로그)

{
  "_index": "test-dev-log-2022.11.11",
  "_version": 1,
  "_score": 0,
  "message": "2022-11-11 09:13:59,228 [INFO ] com.test.service.Service.lambda$subscribe$13:218 - SSE Sinks doOnSubscribe currentSubscriberCount: 38, reactor.core.publisher.FluxFlatMap$FlatMapMain@70a05dae",
  //...
},
{
  "_index": "test-dev-log-2022.11.11",
  "_version": 1,
  "_score": 0,
  "message": "2022-11-11 09:14:00,209 [INFO ] com.test.persistence.TestRepositoryImpl.findWorklistCount:709 - StopWatch 'findWorklistCount': running time = 85525494 ns
  ---------------------------------------------
  ns         %     Task name
  ---------------------------------------------
  087253813  100%  TestDB",
  //...
},

5, Reference

  • Manage multiline message (링크)
  • [정규식] 핵심만 모아놓는 Cheat Sheet (링크)
  • filebeat multiline 옵션을 간단하게 설정해 봅시다. (링크)
  • Filebeat multiline parsing of Java exception in docker container not working (링크)
  • [FILEBEAT] 무작정 시작하기 (2) - Multiline (링크)
profile
Junior BE Developer

0개의 댓글