Fluentd는 로그 수집기입니다. 보통 로그를 수집하지만, 다양한 데이터 소스(HTTP, TCP 등)로부터 데이터를 받아올 수 있습니다.
Fluentd로 전달된 데이터는tag
,time
,record(JSON)
로 구성된 이벤트로 처리되며, 원하는 형태로 가공되어 다양한 목적지(Elasticsearch, S3, HDFS 등)로 전달될 수 있습니다.
Fluentd는 C와 Ruby로 개발되었으며 더 적은 메모리를 사용해야 하는 환경에서는 Fluentd forwarder의 경량화 버전인 Fluent-bit와 함께 사용할 수 있습니다.
데이터 유실을 막기 위해 메모리와 파일 기반의 버퍼 시스템을 갖고 있으며, Failover를 위한 HA(High Availability)구성도 가능합니다.
Fluentd가 읽어들인 데이터는 tag, time, record로 구성된 이벤트로 처리됩니다.
태그는 Fluent의 핵심 요소라고 할 수 있습니다. 태그는 이벤트가 흘러가면서 적합한 Filter, Parser 그리고 Output 플러그인으로 이동할 수 있는 기준이 됩니다.
<source>
@type tail
tag sayho
path /var/log/sayho.log
</source>
<match sayho>
@type stdout
</match>
위 코드의 경우, sayho
라는 태그를 사용하여 match를 시킨 예제입니다.
Fluentd는 원하는 기능들을 플러그인 방식으로 설정 파일에 추가함으로써 사용할 수 있습니다.
전체적인 동작 흐름은 Input -> Filter -> Buffer -> Output
단계로 동작하며, 세부적으로 7개의 플러그인을 목적대로 자유롭게 활용할 수 있습니다.
설정을 위해서는 Fluentd를 설치하고 FLUENT_CONF
에 명시하거나 -c 실행 파라미터에 전달하면 됩니다.
Ubuntu 기준으로 아래의 경로에 Fluentd 설정 파일이 위치하게 됩니다.
$ /etc/td-agent/td-agent.conf
다양한 데이터 소스로부터 로그 데이터를 받거나 가져옵니다
대표적인 in_tail
플러그인은 파일을 tail해서 데이터를 읽어 들입니다. 단 파일의 시작부터 읽지 않으며 로테이팅되어 새로운 파일이 생성되었을 경우에만 처음부터 읽게 됩니다.
그리고 해당 파일의 inode
를 추적하기 때문에 pos_file
파라미터를 사용할 경우 Fluentd가 재실행 되었을 때 파일의 마지막에 읽은 부분부터 다시 처리하게 됩니다.
<source>
@type tail
path /var/log/sayho.log
pos_file /var/log/sayho.log.pos
tag sayho
</source>
<match sayho>
@stdout
</match>
forward
라는 프로토콜을 사용해 TCP
로 데이터를 수신할 수 있습니다. 보통 다른 Fluentd 노드로부터 데이터를 전달받기 위해 사용됩니다.
Forward로 전달되는 데이터는 JSON
이나 Messagepack
형식으로 되어 있습니다.
<source>
@type forward
port 24224
bind 0.0.0.0
</source>
전달 받은 데이터를 파싱하기 위해 사용하는 플러그인입니다.
parse
섹션은 Input 플러그인, Output 플러그인, Filter 플러그인 안에서 정의하며, @type
파라미터로 사용할 Parser 플러그인 이름을 지정합니다.
기본적으로 내장된 Parser 플러그인은 apache2, nginx, syslog, csv, tsv, json, none 등이 있습니다.
정규표현식으로 데이터를 파싱할 수 있는 Parser입니다.
정규표현식 패턴은 expression
파라미터에 명시하며, 반드시 1개 이상의 캡쳐 그룹과 time 캡쳐 그룹이 필요합니다.
time
캡쳐 그룹의 키 이름은 time_key
파라미터로 변경할 수 있습니다.
시간과 관련된 추가 파라미터로는 시간 포맷을 지정할 수 있는 time_format
과 타임존을 설정하는 timezone
파라미터가 있습니다.
<parse>
@type regexp
expression /^(?<remote_addr>[^ ]+) "(?<http_x_forwarded_for>([^ ]+(, )?)+)" (?<http_x_client>[^ ]+) \[(?<timestamp>(0?[1-9]|[12][0-9]|3[01])/[a-zA-Z]+/\d\d\d\d:(00|0[0-9]|1[0-9]|2[0-3]):([0-9]|[0-5][0-9]):([0-9]|[0-5][0-9]) \+[0-9]+)\] "(?<request_method>\S+) (?<request_uri>[^"]+) (?<server_protocol>[^"]+)" (?<status_code>\d{3}) (?<body_byte_sent>\d+) "(?<http_referer>[^"]*)" "(?<http_user_agent>.+)" (?<request_time>[^ ]+)$/
time_key timestamp
time_format %d/%b/%Y:%H:%M:%S %z
timezone +09:00
</parse>
데이터를 행마다 새로운 필드 1개로 다시 담을 때 사용합니다. 데이터를 필터 / 가공하지 않고 다음 플러그인이나 다른 Fluentd 노드로 전달할 때 사용될 수 있습니다.
<source>
@type none
message_key log # JSON 형식의 "log" Key로 데이터가 담김
</source>
명시된 필드값에 정규표현식과 매칭되는 값만 필터링합니다.
@type grep
<regexp>
key log # key : <regexp>섹션에서 정규표현식을 적용할 필드명을 지정
pattern ^statement: .+$ # pattern : 정규표현식
</regexp>
</filter>
이벤트 레코드를 파싱해서 파싱된 결과를 다시 이벤트에 적용합니다. filter_parser
플러그인은 데이터를 파싱하기 위해 Parser 플러그인을 함께 사용합니다.
이벤트 레코드에 새로운 컬럼을 추가하거나 수정, 삭제할 때 사용하는 플러그인입니다.
<filter sayho*>
@type record_transformer
<record>
worker_name fluentd_multi
tag ${tag}
remove_keys sample
</record>
</filter>
record
섹션 안에 "NEW_FIELD: NEW_VALUE" 형태로 새로 추가할 컬럼을 명시remove_keys
파라미터에 배열 형태로 전달된 컬럼들을 삭제Output 플러그인은 <match>
섹션에 정의합니다.
<match **>
@type stdout
</match>
위 코드는 이벤트를 표준출력(stdout)으로 내보냅니다.
다른 Fluentd 노드로 이벤트를 전달할 때 사용되며, 반드시 1개 이상의 <server>
섹션을 포함해야 합니다.
이 플러그인은 Load-Balancing
, Failover
, Replication
기능을 설정하기 위한 파라미터들을 포함하고 있습니다.
<match **>
@type forward
<server>
name another.fluentd1
host 127.0.0.1
port 24224
weight 60
</server>
<server>
name another.fluentd2
host 127.0.0.1
port 24225
weight 40
</server>
</match>
<server>
섹션에서 로드 밸런싱 가중치 설정heartbeat_interval
보다 반드시 커야함Elasticsearch
로 이벤트 레코드를 전송합니다. 레코드 전송은 Bulk
단위로 이루어지기 때문에 최초 전달받은 이벤트가 즉시 ES
로 전달되지 않습니다.
output_elasticsearch
플러그인은 Fluentd에 기본적으로 설치가 돼있지 않기 때문에 따로 설치를 해야합니다.
@type elasticsearch
host 127.0.0.1
port 9200
index_name sayho
type_name log
fluent
buffer
플러그인은 Output 플러그인에서 사용됩니다. buffer는 chunk
들의 집합을 담고 있으며, 각 chunk는 이벤트들의 묶음이 저장된 Blob
파일입니다.
이 chunk
가 가득차게 되면, 다음 목적지로 전달됩니다.
buffer
는 내부적으로 이벤트가 담긴 chunk
를 저장하는 stage
영역과 전달되기 전 대기하는 chunk
를 보관하는 queue
로 나뉩니다.
위에서 소개한 파라미터들은 모두 defualt값이 있으니, 모두 설정할 필요는 없습니다.