fluentd

25gStroy·2022년 2월 9일
0

Fluentd 소개

Fluentd는 로그데이터 수집기 이다. 보통 로그를 수집하는 데 사용하지만 다양한 데이터 소스로부터 데이터를 받아 올 수 있다. Fluentd로 전달된 데이터는 tag,time,record(json)로 구성된 이벤트로 처리되며, 원하는 형태로 가공되어 당양한 목적지(Elasticsearch,S3등)로 전달 될 수 있다.

Fluentd는 C와 Ruby로 개발 됐다. 더 적은 메모리를 사용해야 하는 환경에서는 제공하는 Fluentd-bit라는 경량화 버전과 함께 사용 할 수 있다. 데이터 유실을 막기 위해 메모리와 파일 기반의 버퍼 시스템을 갖고 있으며, Failover를 위한 HA 구성도 가능하다.

Fluentd가 내부에서 처리하는 데이터의 특징

이벤트 | Event
Fluentd가 읽어들인 데이터는 tag, time, record 로 구성된 이벤트(Event) 로 처리된다.

  • tag: 이벤트를 어디로 보낼지 결정하기 위한 구분값
  • time: 이벤트가 발생한 시간
  • record: 데이터 (JSON)

태그 | Tag

Fluentd의 특징 중에 가장 핵심은 태그(Tag) 이다. 태그는 이벤트가 흘러가면서 적절한 Filter, Parser 그리고 Output 플러그인으로 이동할 수 있는 기준이 된다.

아래 예시의 경우 input_tail 플러그인으로 전달된 이벤트에는 dev.sample라는 태그가 붙게 된다.
ex)

# tag 사용 예시
<source>
  @type tail
  tag dev.sample
  path /var/log/sample.log
</source>

<match dev.sample>
  @type stdout
<match>

Fluentd를 어떻게 써야할까?

먼저 Fluentd를 어떻게 쓸 수 있는지 알아보는 것이 이해에 도움이 될 것 같다.

어플리케이션 로그를 한곳으로 모으기 (예: Python 로그, PHP 로그)
서비스 로그 모니터링 (예: Elasticsearch와 Kibana)
데이터 분석을 위한 hdfs로 적재하기
AWS S3로 데이터 저장
Stream 데이터 처리

Fluentd 설정하기

Fluentd는 원하는 기능들을 플러그인 방식으로 설정 파일에 추가함으로써 사용할 수 있다.
전체적인 동작 흐름은 Input -> Filter -> Buffer -> Output 단계로 동작하며, 세부적으로 7개의 플러그인(Input, Parser, Filter, Fomatter, Storage, Buffer, Output)을 목적대로 자유롭게 활용할 수 있다.

Fluentd를 설치하고, 작성한 설정 파일을 환경변수 FLUENT_CONF에 명시하거나 -c 실행 파라미터 에 전달하면 된다.

# export FLUENT_CONF="/etc/fluent/fluent.conf"

fluentd -c /etc/fluent/fluent.conf

Fluentd 플러그인

Input 플러그인
다양한 데이터 소스로부터 로그 데이터를 받거나 가져온다.

  • in_tail

대표적인 in_tail 플러그인은 파일을 tail 해서 데이터를 읽어 들인다. 단 파일의 시작부터 읽지 않으며, 로테이팅 되어 새로운 파일이 생성된 경우에만 처음부터 읽게 된다.
그리고 해당 파일의 inode를 추적하기 때문에 pos_file 파라미터를 사용할 경우 fluentd가 재실행 되었을 때 파일의 마지막에 읽은 부분부터 다시 처리하게 된다.

forward라는 프로토콜을 사용해 TCP로 데이터를 수신할 수 있다. 보통 다른 Fluentd 노드로부터 데이터를 전달받기 위해 사용한다.
forward로 전달되는 데이터는 JSON이나 Messagepack 형식으로 되어 있다. fluentd 인스턴스를 멀티 프로세스로 실행 했을때는 각각의 프로세스가 동일한 forward 포트를 공유하게 된다.

  • doc

  • https://docs.fluentd.org/v1.0/articles/in_forward

  • Parser 플러그인
    전달 받은 데이터를 파싱하기 위해 parse 섹션을 정의해서 사용한다.
    parse 섹션은 Input 플러그인(source), Output 플러그인(match), Filter 플러그인(filter) 안에서 정의하며, @type 파라미터로 사용할 Parser 플러그인 이름을 지정한다.
    기본적으로 내장된 Parser 플러그인은 regexp, 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>
  • Filter 플러그인
    1.특정 필드에 대해 필터링 조건을 적용
    2.새로운 필드를 추가
    3.필드의 삭제하거나 값을 숨김
  • Output 플러그인
    Output 플러그인은 섹션에 정의하며, v1.0부터 Buffering과 Flushing에 대한 설정을 섹션안에 서브 섹션으로 정의한다.

Buffering과 Flushing에 대해서는 3가지 모드를 제공한다.

Non-Buffered mode: 데이터를 buffer에 담지않고, 즉시 내보낸다.
Synchronous Buffered mode: stage 라는 buffer chunk에 담고, 이 chunk를 queue 에 쌓아서 처리한다.
Asynchronous Buffered mode: Synchronous buffered mode와 동일하게 stage 와 queue 가 있지만 동기 방식으로 chunk를 만들지 않는다.
Output 플러그인은 buffer chunk에 key를 지정할 수 있으며, key와 동일한 이름을 갖는 이벤트를 분리해서 chunk에 담도록 설정할 수 있다.

  • Buffer 플러그인
    buffer 플러그인은 Output 플러그인에서 사용된다. buffer에는 chunk 들의 집합을 담고 있으며, 각 chunk 에는 이벤트들의 묶음이 저장된 하나의 Blob 파일이다.
    이 chunk 가 가득차게 되었을때 다음 목적지로 전달된다.
    buffer는 내부적으로는 이벤트가 담긴 chunk를 저장하는 “stage” 영역과 전달되기 전 대기하는 chunk 를 보관하는 “queue” 로 나뉜다.

Fluentd 내부 구조

Fluentd를 이용해서 로그 수집 아키텍쳐를 구성하는 방법을 대략적으로 알아보았는데, 그렇다면 Fluentd 자체의 구조는 어떻게 되어 있을까?
Input,Parser,Engine,Filter,Buffer,Ouput,Formatter 7개의 컴포넌트로 구성이 된다. 7개의 컴포넌트중 Engine을 제외한 나머지 6개는 플러그인 형태로 제공이 되서 사용자가 설정이 가능하다.

  • retry_wait: 최초 재시도를 하게 되는 시간
  • retry_exponential_backoff_base: 재시도 횟수를 배수로 증가 시키기 위한 기준값 N
  • retry_type: 기본값은 exponential_backoff, periodic으로 변경하면 주기적으로 재시도 하도록 할 수 있다.
  • retry_randomize: 재시도 간격은 기본적으로 랜돔한 값으로 정해진다. 이 파라미터를 false 로 설정할 경우 이 동작을 끌 수 있다.
  • retry_max_interval: 최대 재시도 기간
    -retry_max_times 와 retry_timeout이 초과하게 되면 queue에 있는 모든 chunk들은 제거된다.
    -retry_timeout: 재시도 시간 초과
    -retry_forever: 영원히 재시도
    -retry_secondary_threshold: Secondary로 재시도하기 위한 임계치, 이 비율을 넘게 되면 chunk는 secondary로 전달된다.
    위 파라미터들은 모두 기본값이 설정되어 있기 때문에 모두 설정할 필요는 없다.

일반적인 데이타 흐름은 Input → Engine → Output 의 흐름으로 이루어 지고, Parser, Buffer, Filter, Formatter 등은 설정에 따라서 선택적으로 추가 또는 삭제할 수 있다.

profile
애기 개발자

0개의 댓글