1. 개요
Spring Boot 애플리케이션 로그를 JSON으로 출력하고, OpenTelemetry Collector로 수집하도록 붙인 설정을 정리했다. 문자열 로그를 정규식으로 파싱하다 지쳐서 JSON으로 갈아탄 기록이기도 하다.
2. 환경
- Java: 1.8
- Spring Boot: 2.5.1
- OpenTelemetry Collector: contrib 버전
3. 로그 형식을 JSON으로 변경
3-1. 기존 방식의 문제점
기존에는 Logback으로 문자열(String) 로그를 출력했다. 이 방식이 걸렸던 지점은 이랬다.
- 파싱 정확도: 필드를 나누려면 정규식을 써야 하는데, 로그 포맷이 조금만 바뀌어도 파싱이 깨진다.
- 리소스 낭비: 복잡한 정규식 패턴 매칭은 CPU·메모리를 제법 잡아먹는다.
- 유지보수: 포맷이 바뀔 때마다 파싱 규칙도 같이 손봐야 한다.
그래서 로그 형식을 JSON으로 바꾸기로 했다.
3-2. logstash-logback-encoder 의존성 추가
JSON 로그를 뽑으려면 logstash-logback-encoder 라이브러리가 필요하다. 이 라이브러리는 자바 버전, Jackson 버전, logback-classic 버전 호환성을 같이 따져야 한다.
INFO
Spring Boot Starter에 딸려오는 logback-classic과 버전이 충돌할 수 있어 exclude로 걷어내야 하는 경우가 있다.
Java 1.8이라 logstash-logback-encoder는 8.x가 아닌 7.0을 골랐다. (8.x는 Java 11 이상이 필요하다.)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.5.1</version>
<exclusions>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.11</version>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>7.0</version>
</dependency>Starter에 포함된 기본 logback-classic을 빼고, 호환되는 버전을 직접 명시해 넣는 방식이다.
3-3. Logback 설정 변경
의존성을 넣었으면 logback-spring.xml에서 JSON 인코더를 쓰도록 바꿔준다.
<appender name="LOGGER" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
</appender>이제 애플리케이션 로그가 JSON으로 나오고, 각 필드를 구조화된 데이터로 그대로 다룰 수 있다.
4. OpenTelemetry Collector 수집 설정
4-1. FileLog Receiver 선택 이유
수집 방식은 여러 가지가 있지만, 제일 단순한 OpenTelemetry Collector Contrib의 filelogreceiver를 골랐다. 파드 로그가 이미 노드 파일로 떨어지니, 그 파일만 읽으면 됐다.
4-2. FileLog Receiver 설정
receivers:
filelog/test-app:
include:
- "/var/log/pods/test-app-java-backend-1*/*/*.log"
- "/var/log/pods/test-app-java-backend-2*/*/*.log"
include_file_name: false
include_file_path: true
start_at: beginning # 또는 end
operators:
- type: container
add_metadata_from_filepath: true
- type: json_parser
id: parse_json
parse_from: body
parse_to: attributes
- type: move
from: attributes.message
to: body각 설정 항목의 의미는 다음과 같다.
include: 수집할 로그 파일 경로 패턴을 지정한다.include_file_path: 로그 레코드에 파일 경로 정보를 포함할지 여부다.start_at: 컬렉터 시작 시 로그 파일의 어느 지점부터 읽을지 결정한다.operators: 로그 데이터를 처리하는 파이프라인을 정의한다.
IMPORTANT
json_parser오퍼레이터가 핵심인데, 이것이 JSON 형태의 로그를 파싱해서 구조화된 속성(attributes)으로 변환해준다.
5. 설정 검증 및 확인
파이프라인을 구성한 뒤에는 세 지점을 순서대로 확인했다.
- 애플리케이션 로그: JSON 형태로 잘 찍히는지.
- 컬렉터 로그: 컬렉터가 대상 파일을 제대로 읽고 있는지.
- 파싱 결과: JSON 필드가 attributes로 잘 쪼개졌는지.
전체 OpenTelemetry Collector 설정 예시는 여기에 올려뒀다.