PHP 로그와 트레이스 상호 연관 (Correlating PHP Logs and Traces)
PHP 애플리케이션의 로그에 트레이스 ID를 주입해 Datadog에서 로그와 트레이스를 연결하는 방법을 안내해요.
출처: 문서
본문
자동 주입
버전 1.12.0부터 PHP 트레이서는 애플리케이션 로그에 트레이스 상호 연관 식별자를 자동으로 주입해요. 이전 트레이서 버전에서 자동 주입을 활성화하려면 환경 변수 DD_LOGS_INJECTION(INI 설정 datadog.logs_injection)을 true로 설정해요.
PHP 트레이서는 Monolog 또는 Laminas Log 같은 PSR-3 호환 로거를 지원해요.
참고: 로깅 라이브러리를 설정해 로그를 JSON 형식으로 생성하도록 해서:
- 커스텀 파싱 규칙이 필요 없게 하고
- 스택 트레이스가 로그 이벤트에 제대로 래핑되도록 해요.
로그에서 주입 구성
아직 하지 않았다면 PHP 트레이서를 DD_ENV, DD_SERVICE, DD_VERSION으로 구성해요. 이렇게 하면 로그에 env, service, version을 추가하는 데 최상의 경험이 제공돼요 (자세한 내용은 Unified Service Tagging 참조).
PHP 트레이서는 로그에 트레이스 상호 연관 식별자를 주입하는 다양한 방법을 제공해요:
- 모든 트레이스 상호 연관 식별자를 로그 컨텍스트에 추가
- 메시지에서 플레이스홀더 사용
옵션 1: 모든 트레이스 상호 연관 식별자를 로그 컨텍스트에 추가
PHP 트레이서의 기본 동작은 모든 트레이스 상호 연관 식별자를 로그 컨텍스트에 추가하는 것이에요.
예를 들어 Laravel 애플리케이션에서 Monolog 라이브러리를 다음과 같이 사용한다면:
use Illuminate\Support\Facades\Log;
# ...
Log::debug('Hello, World!');
PHP 트레이서는 사용 가능한 트레이스 상호 연관 식별자를 JSON 형식으로 로그 컨텍스트에 추가해요. 위의 로깅된 메시지는 다음과 같이 변환될 수 있어요:
[2022-12-09 16:02:42] production.DEBUG: Hello, World! {"dd.trace_id":"1234567890abcdef","dd.span_id":"1234567890abcdef","dd.service":"laravel","dd.version":"8.0.0","dd.env":"production","status":"debug"}
참고: 메시지에 플레이스홀더가 있거나 메시지에 트레이스 ID가 이미 있으면 PHP 트레이서는 트레이스 상호 연관 식별자를 로그 컨텍스트에 추가하지 않아요.
옵션 2: 메시지에서 플레이스홀더 사용
메시지에서 플레이스홀더를 사용해 로그에 자동으로 주입할 트레이스 상호 연관 식별자를 선택할 수 있어요. PHP 트레이서는 다음 플레이스홀더를 지원해요:
%dd.trace_id%: 트레이스 ID%dd.span_id%: 스팬 ID%dd.service%: 서비스 이름%dd.version%: 서비스 버전%dd.env%: 서비스 환경
플레이스홀더는 대소문자를 구분하며 % 문자로 감싸야 해요.
예를 들어 Laravel 애플리케이션에서 Monolog 라이브러리를 사용한다면 로그 메시지에 주입을 다음과 같이 구성할 수 있어요:
use Illuminate\Support\Facades\Log;
# ...
Log::info('Hello, World! [%dd.trace_id% %dd.span_id% %status%]');
PHP 트레이서는 플레이스홀더를 해당 값으로 바꿔요. 예를 들어 위의 로깅된 메시지는 다음과 같이 변환돼요:
[2022-12-09 16:02:42] production.INFO: Hello, World! [dd.trace_id="1234567890abcdef" dd.span_id="1234567890abcdef" status="info"]
참고: PHP 로그 파이프라인에서 제공하는 기본 파싱 규칙을 사용하려면 대괄호가 필수예요. 커스텀 파싱 규칙을 사용한다면 필요에 따라 대괄호를 생략할 수 있어요.
수동 주입
참고: \DDTrace\current_context() 함수는 버전 0.61.0에서 도입되었으며 10진수 트레이스 식별자를 반환해요.
로그와 트레이스를 연결하려면 로그에 각각 트레이스 ID와 스팬 ID를 담는 dd.trace_id와 dd.span_id 속성이 포함되어야 해요.
로그를 파싱하기 위해 Datadog 로그 통합을 사용하지 않는다면, 커스텀 로그 파싱 규칙에서 dd.trace_id와 dd.span_id가 문자열로 파싱되고 Trace Remapper로 리매핑되도록 해야 해요. 자세한 내용은 연관된 로그가 트레이스 ID 패널에 표시되지 않음에서 확인할 수 있어요.
예를 들어 다음 두 속성을 로그에 추가하려면:
<?php
$append = sprintf(
' [dd.trace_id=%s dd.span_id=%s]',
\DDTrace\logs_correlation_trace_id(),
\dd_trace_peek_span_id()
);
my_error_logger('Error message.' . $append);
?>
로거가 monolog/monolog 라이브러리를 구현한다면 Logger::pushProcessor()를 사용해 모든 로그 메시지에 식별자를 자동으로 추가해요. monolog v1의 경우 다음 구성을 추가해요:
<?php
$logger->pushProcessor(function ($record) {
$record['message'] .= sprintf(
' [dd.trace_id=%s dd.span_id=%s]',
\DDTrace\logs_correlation_trace_id(),
\dd_trace_peek_span_id()
);
return $record;
});
?>
monolog v2의 경우 다음 구성을 추가해요:
<?php
$logger->pushProcessor(function ($record) {
return $record->with(message: $record['message'] . sprintf(
' [dd.trace_id=%s dd.span_id=%s]',
\DDTrace\logs_correlation_trace_id(),
\dd_trace_peek_span_id()
));
});
?>
애플리케이션이 JSON 로그 형식을 사용한다면 로그 메시지에 trace_id와 span_id를 추가하는 대신 trace_id와 span_id를 포함하는 1차 키 dd를 추가할 수 있어요:
<?php
$logger->pushProcessor(function ($record) use ($context) {
$record['dd'] = [
'trace_id' => \DDTrace\logs_correlation_trace_id(),
'span_id' => \dd_trace_peek_span_id()
];
return $record;
});
?>
monolog v3의 경우 다음 구성을 추가해요:
<?php
$logger->pushProcessor(function ($record) {
$record->extra['dd'] = [
'trace_id' => \DDTrace\logs_correlation_trace_id(),
'span_id' => \dd_trace_peek_span_id()
];
return $record;
});
?>
로그를 JSON으로 수집한다면 JSON 로그 전처리로 이동해 Trace Id Attributes 필드에 extra.dd.trace_id를 추가해요.