Java 로그와 트레이스 상호 연관 (Correlating Java Logs and Traces)
Java 애플리케이션의 로그에 트레이스 ID를 주입해 Datadog에서 로그와 트레이스를 연결하는 방법을 안내해요.
출처: 문서
본문
시작하기 전에
로그 수집이 구성되어 있는지 확인해요. Log4j, Log4j 2 또는 Logback 지침은 Java 로그 수집을 참조하세요.
자동 주입
버전 0.74.0부터 Java 트레이서는 JSON 형식의 로그에 트레이스 상호 연관 식별자를 자동으로 주입해요. 이전 버전에서는 시스템 속성으로 dd.logs.injection=true를 추가하거나 환경 변수 DD_LOGS_INJECTION=true를 통해 Java 트레이서에서 자동 주입을 활성화해요. 전체 구성 세부 정보는 Java 트레이서 구성 페이지에서 확인할 수 있어요.
보다 보편적이고 구성 기반의 접근 방식을 위해 OpenTelemetry의 로그 appender를 사용할 수도 있어요. 설정 지침은 OpenTelemetry 트레이스와 로그 상호 연관을 참조하세요.
참고:
- 트레이스 상호 연관의 자동 주입은 Log4j2, Log4j 또는 SLF4J 및 Logback에서 사용할 수 있어요.
- 트레이스 ID의
attribute.path가dd.trace_id가 아니라면 트레이스 ID 예약 속성 설정이attribute.path를 고려하는지 확인하세요. 자세한 내용은 연관된 로그가 트레이스 ID 패널에 표시되지 않음을 참조하세요.
참고: 버전 1.18.3부터 서비스가 실행되는 곳에서 Agent Remote Configuration이 활성화되어 있다면 Catalog UI에서 DD_LOGS_INJECTION을 설정할 수 있어요.
수동 주입
로그에 상호 연관 식별자를 수동으로 추가하려면 트레이싱 API를 사용할 수 있어요. Datadog은 벤더 중립성과 더 넓은 호환성을 위해 표준 OpenTelemetry API를 사용할 것을 권장해요. 또는 Datadog 전용 API를 사용할 수 있어요.
OpenTelemetry API (권장)
OpenTelemetry API로 로그와 트레이스를 상호 연관하려면 먼저 프로젝트에 opentelemetry-api 종속성을 추가해요.
Maven
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<version>1.40.0</version> <scope>provided</scope>
</dependency>
Gradle
compileOnly 'io.opentelemetry:opentelemetry-api:1.40.0'
Gradle (Kotlin DSL)
compileOnly("io.opentelemetry:opentelemetry-api:1.40.0")
종속성을 추가한 후 OpenTelemetry Span 클래스를 사용해 현재 트레이스 및 스팬 ID에 접근하고 이를 로깅 컨텍스트에 추가해요.
예:
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanContext;
import org.slf4j.MDC;
// ...
SpanContext spanContext = Span.current().getSpanContext();
if (spanContext.isValid()) {
try {
MDC.put("dd.trace_id", spanContext.getTraceId());
MDC.put("dd.span_id", spanContext.getSpanId());
// 로그를 기록
} finally {
MDC.remove("dd.trace_id");
MDC.remove("dd.span_id");
}
}
참고: 활성 스팬이 없으면 spanContext.isValid()가 false를 반환하고 로그에 ID가 추가되지 않아요.
Datadog API
Datadog API로 로그와 트레이스를 수동으로 상호 연관하려면 프로젝트에 dd-trace-api 종속성을 추가해요.
Maven
<dependency>
<groupId>com.datadoghq</groupId>
<artifactId>dd-trace-api</artifactId>
<version>LATEST_VERSION</version>
</dependency>
Gradle
implementation 'com.datadoghq:dd-trace-api:LATEST_VERSION'
Gradle (Kotlin DSL)
implementation("com.datadoghq:dd-trace-api:LATEST_VERSION")
LATEST_VERSION을 Datadog Java SDK(dd-java-agent)와 같은 버전으로 바꿔요.
종속성을 추가한 후 CorrelationIdentifier.getTraceId()와 CorrelationIdentifier.getSpanId()를 사용해 ID를 검색하고 로깅 컨텍스트에 주입해요. 다음 예시를 참조하세요.
참고: 활성 스팬이 없으면 CorrelationIdentifier.getTraceId()와 getSpanId()는 "0"을 반환해요. 이 코드가 실행되기 전에 스팬이 시작되었는지 확인하세요.
Log4j 2
import org.apache.logging.log4j.ThreadContext;
import datadog.trace.api.CorrelationIdentifier;
// 이 블록 전에 스팬이 시작되고 활성화되어 있어야 함.
try {
ThreadContext.put("dd.trace_id", CorrelationIdentifier.getTraceId());
ThreadContext.put("dd.span_id", CorrelationIdentifier.getSpanId());
// 로그를 기록
} finally {
ThreadContext.remove("dd.trace_id");
ThreadContext.remove("dd.span_id");
}
SLF4J and Logback
import org.slf4j.MDC;
import datadog.trace.api.CorrelationIdentifier;
// 이 블록 전에 스팬이 시작되고 활성화되어 있어야 함.
try {
MDC.put("dd.trace_id", CorrelationIdentifier.getTraceId());
MDC.put("dd.span_id", CorrelationIdentifier.getSpanId());
// 로그를 기록
} finally {
MDC.remove("dd.trace_id");
MDC.remove("dd.span_id");
}
Tinylog
import org.tinylog.ThreadContext;
import datadog.trace.api.CorrelationIdentifier;
// 이 블록 전에 스팬이 시작되고 활성화되어 있어야 함.
try {
ThreadContext.put("dd.trace_id", CorrelationIdentifier.getTraceId());
ThreadContext.put("dd.span_id", CorrelationIdentifier.getSpanId());
// 로그를 기록
} finally {
ThreadContext.remove("dd.trace_id");
ThreadContext.remove("dd.span_id");
}
참고: 로그를 파싱하기 위해 Datadog 로그 통합을 사용하지 않는다면, 커스텀 로그 파싱 규칙에서 dd.trace_id와 dd.span_id가 문자열로 파싱되도록 해야 해요. 자세한 내용은 연관된 로그가 트레이스 ID 패널에 표시되지 않음을 참조하세요.
특정 logger 구현에 대한 자세한 내용과 JSON 형식으로 로깅하는 지침은 Java 로그 수집 문서를 참조하세요.