한줄요약 : multiline 때문입니다. multiline_flush_interval 옵션을 사용하면 해결됩니다.
Fluentd로 로그를 수집하는데,
초당 로그를 일정하게 발생시키는 스크립트를 짜고 로그 수집을 테스트해보는데
왜인지 테스트 할때마다 로그가 1개씩 덜 들어왔다.
왜 그러지..? 싶었으나 원인을 쉽게 찾을 수 없었다.
그리고 Kinesis output을 사용할 때,
로그가 1초에 여러번 들어오면 '로그 발생 -> Kinesis -> ES 적재'까지 몇 초 내로 적재되었으나
로그를 1분에 한 번 꼴로 발생시킬 경우 '로그 발생 -> Kinesis -> ES 적재'까지 60초 + flush interval에 해당하는 시간이 걸렸다.
(여기서 알아챘어야 했다.. ㅎㅎ)
왜 위의 두가지 현상이 발생하나 했더니,
<parse>
@type multiline
format_firstline /\d{4}-\d{1,2}-\d{1,2}/
format1 /^(?<time>\d{4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2}:\d{1,2}) \[(?<thread>.*)\] (?<level>[^\s]+)(?<message>.*)/
</parse>
tail input에서 위와 같이 multiline parser를 사용할 경우,
2013-3-03 14:27:33 [main] INFO Main - Start
2013-3-03 14:27:33 [main] ERROR Main - Exception
javax.management.RuntimeErrorException: null
at Main.main(Main.java:16) ~[bin/:na]
2013-3-03 14:27:33 [main] INFO Main - End
위와 같은 로그에서
\d{4}-\d{1,2}=\d{1,2} (2013-3-03) 과 같은 연-월-일 형식으로 로그가 시작한다면 각 줄을 다른 로그로 인식한다.
그러면서 다음 줄을 기다리며 목적지로 flush 되지 않는다. 그래야 현재의 로그를 어떻게 처리할지 알 수 있기 때문이다.
그렇기 때문에 로그 수집이 1개씩 덜 되었고, 60초 뒤에 다음 로그가 생성될 때까지 로그 수집이 지연되었던 것이었다.
<source>
@type tail
<parse>
@type multiline
format_firstline /\d{4}-\d{1,2}-\d{1,2}/
format1 /^(?<time>\d{4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2}:\d{1,2}) \[(?<thread>.*)\] (?<level>[^\s]+)(?<message>.*)/
</parse>
tag multiline.*
multiline_flush_interval 1s
</source>
<match multiline.**>
@type kinesis_streams
region ap-northeast-2
stream_name test-stream
<buffer>
flush_interval 1s
flush_thread_interval 0.1 # The sleep interval (seconds) for threads to wait for the next flush try (when no chunks are waiting)
flush_thread_burst_interval 0.01 # The sleep interval (seconds) for threads between flushes when the output plugin flushes the waiting chunks to the next ones
flush_thread_count 4 # The number of threads to flush/write chunks in parallel
</buffer>
</match>
tail에 multiline_flush_interval을 넣으면 해결할 수 있다.
기존에는 로그스태시 -> SQS 를 사용하였는데, 로그 발생 -> 적재까지 1초 정도가 걸렸다.
같은 성능을 내기 위해 flush_interval, multiline_flush_interval을 1초로 해 주었는데,
1초에 50개씩 로그를 수집하는 환경에서 flush_interval을 5초, 1초, 0초로 달리하며 실험을 해 보았다.
flush_interval이 0초인 경우 flush_mode가 immediate고 multiline_flush_interval은 0.1로 설정해 주었다.
CPU 사용 측면에서는 multiline_flush_interval이 0.1초(flush mode는 immediate) 인 경우가
multiline_flush_interval이 1초, 5초인 경우보다 CPU 사용량이 2.5배 이상 많았다.
흥미로운 점은 1초와 5초의 경우 별반 차이가 나지 않았다는 점이다.
메모리 사용량의 경우 오히려 flush_interval이 짧을 수록 낮았는데,
kinesis output 플러그인이 메모리 버퍼를 사용해서 그런 듯 하다.
'인프라,데이터 > Fluentd, Fluent Bit' 카테고리의 다른 글
Kubernetes 환경에서 Fluent Bit의 신뢰성 (tail input, s3 output) (0) | 2022.09.01 |
---|---|
Fluentd로 S3 output path에 field(key) 값 넣기 (0) | 2022.06.12 |
Fluentd add Record Field by Ruby 'Case when~' Conditional Statements (0) | 2022.06.07 |
argocd 로그 모니터링 (0) | 2022.05.02 |
Fluent Bit에 SQS Output 연결하기(feat. Golang) (0) | 2022.04.14 |