[CNCF Observability 04] Fluent Bit: JSON Log 한 줄이 검색 가능한 기록이 되는 과정

이재인·2026년 10월 10일

CNCF

목록 보기
23/30
post-thumbnail

시바 일러스트

주문 프로그램이 level, service, message를 담은 기록을 한 줄씩 남긴다고 가정해 보겠습니다. 여러 파일에서 주문 오류만 모아 살펴보려면 각 줄을 읽고, 항목을 나누고, 목적지로 보내야 합니다. 이 글에서는 Fluent Bit의 수집 흐름을 따라가며 기록 한 줄이 어떻게 변하는지 확인합니다.

파일에서 항목을 꺼내기

Log는 특정 시점에 발생한 사건을 남긴 기록입니다. JSON은 항목 이름과 값을 정해진 문법으로 표현하는 데이터 형식입니다. {"level":"ERROR"}처럼 이름이 있으면 프로그램이 오류 등급을 꺼내 확인할 수 있습니다.

Fluent Bit은 기록을 수집하고 가공해 목적지로 보내는 도구입니다. Fluentd와 함께 기록 수집 흐름을 구성하거나 독립적으로 사용할 수 있습니다. 활용 관계는 Fluentd와 Fluent Bit 공식 설명에서 확인할 수 있습니다.

Input은 데이터를 가져오는 단계입니다. 파일을 읽을 때 사용할 수 있는 Tail Input은 새 줄을 발견하면 기록을 만듭니다. Parser는 입력의 문법을 읽어 항목별 데이터로 바꾸는 기능입니다. Tail에 JSON Parser를 연결하면 한 줄의 JSON에서 level과 service를 꺼낼 수 있습니다. Tail 문서와 JSON Parser 문서가 이 구성을 설명합니다.

가공과 전달

Filter는 모은 기록의 항목을 수정하거나 조건에 맞게 가공하는 단계입니다. 예를 들어 service가 주문 서비스이고 level이 ERROR인 기록을 선택할 수 있습니다. Output은 기록을 보낼 목적지를 정하는 단계입니다. 로컬 파일이나 원격 저장 서비스 등이 목적지가 될 수 있습니다. 수집과 가공, 전달의 역할은 Data pipeline 문서에 정리되어 있습니다.

JSON 한 줄: service=checkout, level=ERROR
  ↓
Input: 새 줄 읽기
  ↓
Parser: JSON 항목 해석
  ↓
Filter: 조건에 맞는 오류 기록 선택
  ↓
Output: 목적지로 전달

이 흐름을 실제로 구성할 때는 데이터를 잠시 보관하는 Buffer와 전달 경로를 정하는 Routing도 있습니다. Buffer는 대기 중인 기록을 보관합니다. Routing은 기록의 Tag, 즉 전달용 표식과 일치 규칙으로 목적지를 선택합니다. 이 도식은 항목을 꺼내 선택하는 과정을 따라갑니다.

가상 오류 기록 하나를 끝까지 따라가 보세요. 새 줄을 읽었는지, service와 level이 각각의 항목으로 만들어졌는지, 조건에 맞는 기록이 남았는지 차례로 확인합니다. 마지막에는 목적지에서 같은 기록을 받았는지 살펴봅니다. 어느 단계에서 기록이 끊겼는지 찾으면 확인할 설정도 좁혀집니다.

예제는 같은 항목 이름을 가진 올바른 형식의 두 줄을 사용합니다. 항목 이름이나 값의 표기가 달라지면 선택 조건도 함께 확인해야 합니다. 아래 조건식은 오류 등급을 대문자로 지정했습니다. 기록을 만드는 프로그램과 Parser가 같은 항목 이름과 값의 표기를 사용하도록 맞춰야 합니다.

합성 기록에서 오류만 꺼내기

import json

lines = [
    '{"service":"checkout","level":"ERROR","message":"payment timeout"}',
    '{"service":"checkout","level":"INFO","message":"order completed"}',
]
records = [json.loads(line) for line in lines]
selected = [r for r in records if r["service"] == "checkout" and r["level"] == "ERROR"]
for record in selected:
    print(record["service"], record["message"])

예제에서는 checkout payment timeout이 출력됩니다. json.loads()가 문자열을 항목별 데이터로 읽습니다. 조건식은 서비스 이름과 오류 등급이 둘 다 맞는 기록을 선택합니다. 마지막 줄은 선택한 메시지를 보여 줍니다.

코드는 직접 만든 JSON 두 줄을 해석하고 조건에 맞는 기록을 고릅니다. Fluent Bit으로 구성할 때는 실제 입력 형식, Parser 연결, 목적지의 수신 상태와 전달 재시도 설정을 살펴야 합니다. 여러 줄로 나뉜 사건 기록에는 줄을 결합하는 설정도 필요합니다.

확인 문제와 정답

  1. 파일의 새 줄을 가져오는 단계는 무엇인가요?
  2. JSON의 이름과 값을 해석하는 기능은 무엇인가요?
  3. service가 payment인 ERROR 기록을 추가하면 위 조건식은 어떻게 처리하나요?

정답: 1은 Input이며 이 상황에서는 Tail을 사용합니다. 2는 Parser입니다. 3은 서비스 조건이 checkout이므로 그 기록은 선택 결과에서 빠집니다. 서비스와 등급 조건을 모두 만족한 기록이 출력됩니다.

payment의 오류도 선택하려면 Filter의 서비스 조건을 그 범위에 맞게 바꿉니다. OpenTelemetry 기록 연결에서는 Log에 Trace ID를 남겨 같은 요청의 작업 기록을 찾는 방법으로 이어집니다.

profile
게으르게 일하기 위해 진지하게 고민하는 개발자

0개의 댓글