현재는 log파일을 input으로 하여 로그 데이터를 수집한다.
이때, input을 tail로 하고 파일에서 로그를 읽어오다 보니, 하나의 로그가 여러줄로 이루어져 있는경우에 각 줄이 다른 로그로 인식되어 전달 된다.
그래서 아래와 같은 예시처럼 가독성이 매우 떨어지는 문제가 발생했다.
#로그파일
[INFO ] 2022-10-25 14:33:10.127 [main] sqltiming - UPDATE t_request SET confirm_yn = 'Y', response_code = '1200', response_message
= 'Success' WHERE request_id = 'abcde'
{executed in 3 msec}
#cloudwatch log
{
"log": "[INFO ] 2022-10-25 14:33:10.127 [main] sqltiming - UPDATE t_request SET confirm_yn = 'Y', response_code = '1200', response_message \\n",
"node": "ip-120-10-211-175.ap-northeast-2.compute.internal",
"pod_name": "pod-27777931-vkdxr",
"pod_ip": "120.10.211.30",
"timestamp": "2022-10-25 14:33:11.703"
}
{
"log": "= 'Success' WHERE request_id = 'abcde' \\n",
"node": "ip-120-10-211-175.ap-northeast-2.compute.internal",
"pod_name": "pod-27777931-vkdxr",
"pod_ip": "120.10.211.30",
"timestamp": "2022-10-25 14:33:11.703"
}
{
"log": " {executed in 3 msec}\\n",
"node": "ip-120-10-211-175.ap-northeast-2.compute.internal",
"pod_name": "pod-27777931-vkdxr",
"pod_ip": "120.10.211.30",
"timestamp": "2022-10-25 14:33:11.703"
}
이런 문제를 피하기 위해서 Fluent bit 에서는 multiline parser를 제공한다. fllter에서 multiline parser를 사용할 수 있지만, input이 tail인 경우에는 input-tail의 옵션으로 parser를 사용하는것을 권장한다.
공식 홈페이지 설명(https://docs.fluentbit.io/manual/pipeline/filters/multiline-stacktrace)
If you wish to concatenate messages **read from a log file**, **it is highly recommended to use the multiline support in the Tail plugin itself**. This is because performing concatenation while reading the log file is more performant. Concatenating messages originally split by Docker or CRI container engines, is supported in the Tail plugin.
사용방법은 filter에서 쓰는것과 input에서 사용하는것이 거의 비슷한 듯 하다.
일단, multiline parser를 사용하도록 tail 플러그인에 파라미터를 추가해준다.
여기서는 사용자 정의로 parser의 rule을 지정해 주는 방식을 선택했다. 이외에도 docker, python, java 등의 로그들은 fluent-bit에서 built-in parser를 지원한다.
#fluent-bit.conf
[SERVICE]
parsers_file parsers_multiline.conf
[INPUT]
name tail
tag test.log
path /var/log/test.log
db /var/log/test.log.db
multiline.parser multiline-regex-springLog
<생략>
이제 위의 conf 파일에서 사용하는 사용자 정의 multiline parser 파일을 작성한다.
사용자 정의 가능한 rule의 타입은 현재로서는 정규식(regex) 타입만 지원된다.
rule은 필수적으로 “start_state”를 가장 먼저 정의해야 하며, 이어지는 문장의 형식을 지정해 주면 된다.
즉, 로그가 시작하는 줄의 패턴을 지정하여 로그단위의 시작을 매칭할 수 있도록 하고, 그 뒤에 이어지는 내용들의 패턴을 지정해서 로그의 시작점과 이어지는 지점을 fluent bit이 구분할 수 있도록 한다.
# parsers_multiline.conf
[MULTILINE_PARSER]
name multiline-regex-springLog
type regex
flush_timeout 1000
#
# Regex rules for multiline parsing
# ---------------------------------
#
# configuration hints:
#
# - first state always has the name: start_state
# - every field in the rule must be inside double quotes
#
# rules | state name | regex pattern | next state
# ------|---------------|--------------------------------------------
rule "start_state" "/(\\[\\w+(\\s|\\w)\\] \\d+-\\d+-\\d+)(.+)/" "cont"
rule "cont" "/^(?!\\[[A-Z]).*/" "cont"
위의 예시에서는
"start_state"에 [INFO ] 2022-10-26 ~~~와 같은 형식의 문장을 지정하였고,
"cont"에 위의 start_state에 해당하는 [대문자 알파벳]의 형식이 아닌 문장들을 지정하였다.
위와 같이 multiline parser 설정을 하면 아래와 같이 로그가 분류되어 나뉘었던 하나의 로그들이 함께 저장되는것을 확인 할 수 있다.
#로그파일
[INFO ] 2022-10-26 16:18:14.475 [main] sqltiming - SELECT * FROM t_request WHERE confirm_yn = 'N' AND request_date <= (NOW()
- INTERVAL '10 MINUTES') AND response_code = '1200' ORDER BY request_date ASC LIMIT 1
{executed in 8 msec}\\n
#cloudwatch.log
{
"log": "[INFO ] 2022-10-26 16:18:14.475 [main] sqltiming - SELECT * FROM t_request WHERE confirm_yn = 'N' AND request_date <= (NOW() \\n- INTERVAL '10 MINUTES') AND response_code = '1200' ORDER BY request_date ASC LIMIT 1 \\n {executed in 8 msec}\\n",
"node": "ip-120-10-211-114.ap-northeast-2.compute.internal",
"pod_name": "pod-27779477-nnxr8",
"pod_ip": "120.10.211.168",
"timestamp": "2022-10-26 16:18:15.435"
}'Data Engineering > Fluentd' 카테고리의 다른 글
| Fluent Bit에서 특정 패턴 Exclude 하기 (0) | 2023.07.23 |
|---|---|
| Fluent Bit으로 쿠버네티스 컨테이너의 로그파일에서 로그 수집 (0) | 2022.11.27 |