OpenTelemetry PHP
접속하기 전에 먼저 DataKit의 OpenTelemetry 수집기를 활성화하세요.
사전 조건¶
- PHP 8.1, 8.2, 8.3 또는 8.4;
- Composer;
- DataKit와 PHP 애플리케이션 사이의 포트가 연결 가능해야 합니다.
1. 무코드 방식 주입¶
확장 설치¶
PHP 버전, 스레드 모드, 확장 디렉터리를 확인합니다:
php -r 'printf("PHP=%s.%s MODE=%s EXT=%s\n", PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_ZTS ? "ts" : "nts", ini_get("extension_dir"));'
uname -m
Release 페이지에서 PHP 버전, ts/nts, 운영 체제, CPU 아키텍처와 일치하는 아티팩트를 다운로드합니다. 예를 들어 PHP 8.2 NTS, Linux x86_64의 경우 다음을 사용합니다:
확장을 설치합니다:
tar -xzf php_opentelemetry-1.3.4-gtrace-8.2-nts-linux-x86_64.tar.gz
sudo install -m 0755 \
php_opentelemetry-1.3.4-gtrace-8.2-nts-linux-x86_64/opentelemetry.so \
"$(php -r 'echo ini_get("extension_dir");')/opentelemetry.so"
php --ini
PHP가 스캔하는 설정 디렉터리에 99-opentelemetry.ini를 생성합니다:
PHP-FPM, Apache 또는 애플리케이션 프로세스를 재시작한 뒤 확장을 확인합니다:
자동 인스트루먼테이션 의존성 설치¶
자동 인스트루먼테이션 패키지는 애플리케이션에서 사용하는 프레임워크와 구성요소에 맞아야 합니다. 아래는 Slim과 PSR-18 예시입니다:
composer config allow-plugins.php-http/discovery false
composer require \
open-telemetry/sdk \
open-telemetry/exporter-otlp \
open-telemetry/opentelemetry-auto-slim \
open-telemetry/opentelemetry-auto-psr18 \
php-http/guzzle7-adapter \
nyholm/psr7
전송 설정¶
애플리케이션과 DataKit가 같은 호스트에 있다면 루프백 주소로 전송합니다:
export OTEL_PHP_AUTOLOAD_ENABLED=true
export OTEL_SERVICE_NAME=my-php-service
export OTEL_SERVICE_VERSION=1.0.0
export OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=prod
export OTEL_TRACES_EXPORTER=otlp
export OTEL_METRICS_EXPORTER=none
export OTEL_LOGS_EXPORTER=none
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:9529/otel
export OTEL_PROPAGATORS=baggage,tracecontext
php -S 0.0.0.0:8080 -t public
PHP-FPM, Supervisor, systemd 또는 컨테이너 배포 시에는 이러한 변수를 해당 프로세스의 시작 환경에 기록하고 프로세스를 재시작해야 합니다.
OTLP/gRPC 4317을 사용하려면 PHP grpc 확장과 Composer 전송 패키지도 설치해야 합니다:
composer require open-telemetry/transport-grpc
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc
export OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4317
검증¶
애플리케이션 라우트에 요청한 뒤 DataKit 수신 로그를 확인합니다:
로그에 POST /otel/v1/traces가 나타나고 상태 코드가 200이면 Trace가 DataKit에 수신된 것입니다.
2. SDK 방식¶
SDK 방식은 비즈니스 코드가 Span을 생성하며, 자동 인스트루먼테이션 확장 설치를 요구하지 않습니다.
의존성 설치¶
composer config allow-plugins.php-http/discovery false
composer require \
open-telemetry/sdk \
open-telemetry/exporter-otlp \
php-http/guzzle7-adapter \
nyholm/psr7
Span 생성¶
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use OpenTelemetry\API\Trace\StatusCode;
use OpenTelemetry\Contrib\Otlp\OtlpHttpTransportFactory;
use OpenTelemetry\Contrib\Otlp\SpanExporter;
use OpenTelemetry\SDK\Common\Attribute\Attributes;
use OpenTelemetry\SDK\Resource\ResourceInfo;
use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
use OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessorBuilder;
use OpenTelemetry\SDK\Trace\TracerProvider;
$resource = ResourceInfoFactory::defaultResource()->merge(
ResourceInfo::create(Attributes::create([
'service.name' => 'my-php-service',
'service.version' => '1.0.0',
'deployment.environment.name' => 'prod',
]))
);
$transport = (new OtlpHttpTransportFactory())->create(
'http://127.0.0.1:9529/otel/v1/traces',
'application/x-protobuf'
);
$exporter = new SpanExporter($transport);
$processor = (new BatchSpanProcessorBuilder($exporter))->build();
$tracerProvider = TracerProvider::builder()
->setResource($resource)
->addSpanProcessor($processor)
->build();
$tracer = $tracerProvider->getTracer('application');
$span = $tracer->spanBuilder('order.submit')->startSpan();
$scope = $span->activate();
try {
$span->setAttribute('order.id', 'A1001');
// 비즈니스 코드
} catch (Throwable $exception) {
$span->recordException($exception);
$span->setStatus(StatusCode::STATUS_ERROR, $exception->getMessage());
throw $exception;
} finally {
$scope->detach();
$span->end();
$tracerProvider->shutdown();
}