Fluent-Bit
1 Fluent Bit
- Fluent Bit은 Fluentd의 경량 버전이라고 생각하면 된다.
1.1 Fluent Bit과 Fluentd
Fluent Bit과 Fluentd 비교
- Fluentd와 Fluentbit은 상호 배타적 관계가 아니다.
- Fluentbit은 Fluentd의 경량 버전이라고 생각하면 쉽다.
- Fluentbit과 Fluentd의 관계는 Beats와 Logstash의 관계와 유사하다.
- https://logz.io/blog/fluentd-vs-fluent-bit/ 를 참고하자.
Fluent Bit과 Fluentd를 같이 사용하는 아키텍처가 가능하다
- Fluent Bit을 daemonset을 이용해서 노드마다 하나씩 배포한다.
- Fluent Bit은 데이터를 수집하고 Fluentd로 포워딩한다.
- Fluentd는 클러스터 당 하나의 인스턴스를 배포한다.
- Fluent Bit로부터 받은 데이터를 aggregation하고 다시 포워딩한다.
1.2 Key Concept
1.2.1 Event or Record
- 레퍼런스
- Fluent Bit로 들어오는 모든 데이터 조각들을 Event 또는 Record라고 부른다.
- 데이터: 로그 또는 메트릭
Event의 포맷
- Event는 아래 3가지로 구성된다.
- timestamp
- key/value metadata (since v2.1.0)
- payload
[[TIMESTAMP, METADATA], MESSAGE]
- TIMESTAMP: 초 단위로 표현된 정수 또는 부동소수점 값으로 나타내는 타임스탬프입니다(문자열이 아님).
- METADATA: 이벤트 메타데이터를 포함하는 가능성이 있는 객체
- MESSAGE: 이벤트 본문을 포함하는 객체
Structured Messages
- Messages는 아래와 같이 Structure를 가질수도 있고 아닐수도 있다.
{"project": "Fluent Bit", "created": 1398289291}
"Project Fluent Bit created on 1398289291"
- structure가 있는 메시지를 처리하는 것이 더 빠르다.
1.2.2 Tag
- 모든 이벤트에는 Tag가 부여된다.
- Tag는 이후 필터 단계와 아웃풋 단계에서 사용된다.
- 대부분의 Tag는 설정을 통해 직접 부여된다.
- 만약 Tag를 명시하지 않으면 Fluent Bit는 자동으로 인풋 플러그인의 이름을 Tag로 부여한다.
1.3 Data Pipeline
- Fluent Bit로 들어오는 데이터는 아래와 같은 파이프라인을 거친다.
- input
- Parser
- Filter
- Buffer
- Router
- Output
2 Input
- 레퍼런스
- Fluent Bit는 여러 가지 소스로부터 정보를 모으기 위해 여러 Input Plugin을 제공한다.
- 여러 인풋 플러그인 https://docs.fluentbit.io/manual/pipeline/inputs 참고
2.1 Tail Plugin
- tail input plugin은 텍스트 파일을 모니터링한다.
tail -f
와 유사하게 작동한다.
- Tail은
Path
패턴에 매칭되는 모든 파일을 모니터링한다.- 텍스트 파일에 새로운 줄이 추가되면 새로운 이벤트(레코드)를 생 성한다.
Configuration Parameters
Multiline Support
- Fluent Bit 1.8버전 부터 Multiline 기능이 추가되었다.
- 그래서 현재 old configuration mechanism과 new configuration mechanism 두가지 방식이 존재한다.
- 하위 호환성을 위해 old configuration mechanism은 그대로 남겨두었다.
- new configuration mechanism을 이용하면
multiline.parser
라는 키를 이용하면 된다.- multiline.parser를 사용하게 되면 old configuration mechanism인 아래의 키를 사용할 수 없다.
- parser
- parser_firstline
- parser_N
- multiline
- multiline_flush
- docker_mode
3 Parser
- Parser는 structure가 없는 데이터에 structure를 부여하는 역할을 한다.
- 구조가 없는 데이터 처리하는 것은 매우 비효율적이기 때문에 Input 단계에서 구조가 없는 데이터가 들어오면 바로 Parser에 의해 구조를 부여한다.
예시
192.168.2.20 - - [28/Jul/2006:10:27:10 -0300] "GET /cgi-bin/try/ HTTP/1.0" 200 3395
- 위와 같은 구조가 없는 데이터를 Parser를 이용해 아래와 같이 구조를 가진 데이터로 만든다.
{
"host": "192.168.2.20",
"user": "-",
"method": "GET",
"path": "/cgi-bin/try/",
"code": "200",
"size": "3395",
"referer": "",
"agent": ""
}
3.1 JSON Parser
- JSON는 원본 로그 소스가 JSON 형태일 경우 사용할 수 있다.
- 로그 소스를 구조화하고 직접적으로 내부 바이너리 표현으로 변환한다.
[PARSER]
Name docker
Format json
Time_Key time
Time_Format %Y-%m-%dT%H:%M:%S %z
{"key1": 12345, "key2": "abc", "time": "2006-07-28T13:22:04Z"}
- 원본 로그 소스가 위처럼 JSON 형태일 경우
`[1154103724, {"key1"=>12345, "key2"=>"abc"}]`
- JSON Parser를 거치면 위와 같이 표현으로 변환된다.
3.2 Regular Expression Parser
- 레퍼런스
- Ruby Regular Expression을 사용해서 원본 소스에 구조를 부여할 수 있다.
- Ruby Regular Expression이 제대로 동작하는 아래 사이트에서 테스트할 수 있다.
예시
[PARSER]
Name apache
Format regex
Regex ^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$
Time_Key time
Time_Format %d/%b/%Y:%H:%M:%S %z
Types code:integer size:integer
위 Parser 설정은 Apache HTTP Server log entry를 정규 표현식으로 구조화한다.
192.168.2.20 - - [29/Jul/2015:10:27:10 -0300] "GET /cgi-bin/try/ HTTP/1.0" 200 3395
위는 Apache HTTP Server log entry로 보시다시피 구조가 없는 상태다.
위 정규 표현식 테스트 사이트에 원본 로그 데이터와 정규 표현식을 넣으면 오른쪽 아래와 같이 구조화된 데이터를 얻을 수 있다.
3.1 Parser Plugin
-
기본적으로 Fluent Bit 여러 타입의 로그에 대한 미리 정의된 Parser를 제공한다.
-
Apache
-
Nginx
-
Docker
-
Syslog rfc5424
-
Syslog rfc3164
-
Configuration Parameters
3.3 Multiline Parsing
- 레퍼런스
- 이상적으로, 애플리케이션들은 로그 메시지를 한 줄로 기록할 수 있지만, 실제로는 애플리케이션들이 같은 컨텍스트에 속한 여러 로그 메시지를 생성한다.
- 이런 정보를 처리할 때는 매우 복잡하다.
- 예를 들어, 애플리케이션 stack trace는 항상 여러 로그 라인을 가지고 있기 때문이다.
- Multiline parser를 사용하는 방법에는 2가지가 있다.
- Built-in multiline parser를 이용하기
- Configurable multiline parser를 이용하기
Built-in Multiline Parsers
- 추가 설정 없이 Fluent Bit에서 미리 설정한 Built-in Multiline Parsers를 사용할 수 있다.
- 아래표 참고해서 적합한 Built-in Multiline Parsers가 있다면 바로 사용할 수 있다.
Parser | Description |
---|---|
docker | Process a log entry generated by a Docker container engine. This parser supports the concatenation of log entries split by Docker. |
cri | Process a log entry generated by CRI-O container engine. Same as the docker parser, it supports concatenation of log entries |
go | Process log entries generated by a Go based language application and perform concatenation if multiline messages are detected. |
python | Process log entries generated by a Python based language application and perform concatenation if multiline messages are detected. |
java | Process log entries generated by a Google Cloud Java language application and perform concatenation if multiline messages are detected. |
Configurable Multiline Parsers
- 레퍼런스
- Built-in Multiline Parsers