php方案 OpenTelemetry标准化
·
首先安装依赖:
composer require open-telemetry/sdk open-telemetry/exporter-otlp
opentelemetry_demo.php
<?php
require 'vendor/autoload.php';
use OpenTelemetry\SDK\Trace\TracerProviderFactory;
use OpenTelemetry\SDK\Metrics\MeterProviderFactory;
use OpenTelemetry\SDK\Logs\LoggerProviderFactory;
use OpenTelemetry\API\Trace\SpanKind;
use OpenTelemetry\API\Trace\StatusCode;
use OpenTelemetry\Contrib\Otlp\SpanExporter;
use OpenTelemetry\Contrib\Otlp\MetricExporter;
use OpenTelemetry\Contrib\Otlp\LogsExporter;
use OpenTelemetry\SDK\Common\Attribute\Attributes;
class OpenTelemetryDemo {
private $tracer;
private $meter;
private $logger;
public function __construct($endpoint = 'http://localhost:4318') {
// 初始化 Tracer
$tracerProvider = (new TracerProviderFactory())->create();
$this->tracer = $tracerProvider->getTracer('demo-app', '1.0.0');
// 初始化 Meter
$meterProvider = (new MeterProviderFactory())->create();
$this->meter = $meterProvider->getMeter('demo-app', '1.0.0');
// 初始化 Logger
$loggerProvider = (new LoggerProviderFactory())->create();
$this->logger = $loggerProvider->getLogger('demo-app', '1.0.0');
}
public function processOrder($orderId) {
// 创建 Span (Trace)
$span = $this->tracer->spanBuilder('process_order')
->setSpanKind(SpanKind::KIND_SERVER)
->startSpan();
$span->setAttribute('order.id', $orderId);
$span->addEvent('order_processing_started');
try {
// 模拟业务逻辑
$this->validateOrder($orderId);
$this->saveOrder($orderId);
// 记录 Metric
$counter = $this->meter->createCounter('orders_processed', 'orders', 'Total orders processed');
$counter->add(1, Attributes::create(['status' => 'success']));
// 记录 Log
$this->logger->emit('info', 'Order processed successfully', ['order_id' => $orderId]);
$span->setStatus(StatusCode::STATUS_OK);
echo "订单 $orderId 处理成功\n";
} catch (Exception $e) {
$span->recordException($e);
$span->setStatus(StatusCode::STATUS_ERROR, $e->getMessage());
$counter = $this->meter->createCounter('orders_failed', 'orders', 'Total orders failed');
$counter->add(1, Attributes::create(['error' => $e->getMessage()]));
$this->logger->emit('error', 'Order processing failed', [
'order_id' => $orderId,
'error' => $e->getMessage()
]);
echo "订单 $orderId 处理失败: " . $e->getMessage() . "\n";
} finally {
$span->end();
}
}
private function validateOrder($orderId) {
$span = $this->tracer->spanBuilder('validate_order')
->setSpanKind(SpanKind::KIND_INTERNAL)
->startSpan();
sleep(1); // 模拟验证耗时
$span->addEvent('validation_completed');
$span->end();
}
private function saveOrder($orderId) {
$span = $this->tracer->spanBuilder('save_order')
->setSpanKind(SpanKind::KIND_INTERNAL)
->startSpan();
sleep(1); // 模拟保存耗时
// 记录延迟 Metric
$histogram = $this->meter->createHistogram('order_save_duration', 'ms', 'Order save duration');
$histogram->record(1000, Attributes::create(['operation' => 'save']));
$span->end();
}
}
// 使用示例
$otel = new OpenTelemetryDemo();
// 处理多个订单
for ($i = 1; $i <= 3; $i++) {
$otel->processOrder("ORDER-$i");
}
echo "\n所有订单处理完成\n";
echo "Traces、Metrics 和 Logs 已发送到 OpenTelemetry Collector\n";
docker-compose.yml
version: '3.8'
services:
# OpenTelemetry Collector
otel-collector:
image: otel/opentelemetry-collector:latest
command: ["--config=/etc/otel-collector-config.yaml"]
volumes:
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
ports:
- "4317:4317" # OTLP gRPC
- "4318:4318" # OTLP HTTP
- "13133:13133" # health_check
# Jaeger (查看 Traces)
jaeger:
image: jaegertracing/all-in-one:latest
ports:
- "16686:16686" # Jaeger UI
- "14250:14250" # gRPC
# Prometheus (查看 Metrics)
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
# Grafana (可视化)
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
otel-collector-config.yaml
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
exporters:
jaeger:
endpoint: jaeger:14250
tls:
insecure: true
prometheus:
endpoint: "0.0.0.0:8889"
logging:
loglevel: debug
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [jaeger, logging]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [prometheus, logging]
logs:
receivers: [otlp]
processors: [batch]
exporters: [logging]
prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'otel-collector'
static_configs:
- targets: ['otel-collector:8889']
1. 安装依赖
composer require open-telemetry/sdk open-telemetry/exporter-otlp
2. 启动服务
docker-compose up -d
3. 运行示例
php opentelemetry_demo.php
4. 查看结果
Jaeger UI (Traces): http://localhost:16686
Prometheus (Metrics): http://localhost:9090
Grafana (可视化): http://localhost:3000
核心概念:
- Traces - 分布式追踪,查看请求链路
- Metrics - 指标监控,统计计数、延迟等
- Logs - 日志记录,结构化日志
完成!我创建了完整的 OpenTelemetry 标准化案例:
文件说明:
-
opentelemetry_demo.php - 完整版,包含 Traces、Metrics、Logs 三大支柱
-
docker-compose.yml - 一键启动所有服务
-
otel-collector-config.yaml - Collector 配置
-
prometheus.yml - Prometheus 配置
更多推荐


所有评论(0)