产品动态
php -vcomposer -v
index.php 是一个 HTTP Server 使用 PDO 连接 MySQL 数据库操作,对应的 MySQL 服务请自行搭建,或直接购买云产品。mkdir <project-name> && cd <project-name>composer init \\--no-interaction \\--stability beta \\--require slim/slim:"^4" \\--require slim/psr7:"^1"composer update
index.php文件,添加如下内容。<?phpuse Psr\\Http\\Message\\ResponseInterface as Response;use Psr\\Http\\Message\\ServerRequestInterface as Request;use Slim\\Factory\\AppFactory;require __DIR__ . '/vendor/autoload.php';$app = AppFactory::create();$app->get('/getID', function (Request $request, Response $response) {$dbms = 'mysql'; // 数据库类型$host = 'localhost'; // 数据库主机名$dbName = 'Mydb'; // 使用的数据库$user = 'root'; // 数据库连接用户名$pass = ''; // 对应的密码$dsn = "$dbms:host=$host;dbname=$dbName";try {$dbh = new PDO($dsn, $user, $pass); // 初始化一个PDO对象echo "连接成功<br/>";foreach ($dbh->query('SELECT id from userInfo') as $row) {$response->getBody()->write($row[0] . "<br/>");}$dbh = null;} catch (PDOException $e) {die ("Error!: " . $e->getMessage() . "<br/>");}return $response;});$app->run();
brew install gcc make autoconf
sudo apt-get install gcc make autoconf
pecl install opentelemetry
Build process completed successfullyInstalling '/opt/homebrew/Cellar/php/8.2.8/pecl/2020829/opentelemetry.so'install ok: channel://pecl.php.net/opentelemetry-1.0.3Extension opentelemetry enabled in php.ini
Extension opentelemetry enabled in php.ini,表明已经启用,请跳过当前步骤。php.ini文件中添加如下内容。[opentelemetry]extension=opentelemetry.so
php.ini文件可能存在的位置。OS | PATH |
Linux | /etc/php.ini /usr/bin/php5/bin/php.ini /etc/php/php.ini /etc/php5/apache2/php.ini |
Mac OSX | /private/etc/php.ini |
Windows (with XAMPP installed) | C:/xampp/php/php.ini |
php -m | grep opentelemetry
opentelemetry
php --ri opentelemetry
opentelemetryopentelemetry support => enabledextension version => 1.0.3
pecl install grpc # 这一步构建时间较长composer config allow-plugins.php-http/discovery falsecomposer require \\open-telemetry/sdk \\open-telemetry/exporter-otlp \\open-telemetry/transport-grpc \\php-http/guzzle7-adapter \\open-telemetry/opentelemetry-auto-slim \\open-telemetry/opentelemetry-auto-pdo
open-telemetry/opentelemetry-auto-slim 和 open-telemetry/opentelemetry-auto-pdo 包是因为示例 demo 中使用了 PDO 和 Slim 框架,可以根据具体业务进行调整。如果业务中组件需要 OpenTelemetry 自动埋点,需要在项目中导入对应的自动埋点包,自动埋点包导入方式具体详情请参见 OpenTelemetry 官方文档。env OTEL_PHP_AUTOLOAD_ENABLED=true \\OTEL_TRACES_EXPORTER=otlp \\OTEL_METRICS_EXPORTER=none \\OTEL_LOGS_EXPORTER=none \\OTEL_EXPORTER_OTLP_PROTOCOL=grpc \\OTEL_EXPORTER_OTLP_ENDPOINT=<endpoint> \\ # 此处替换成步骤1中获得的接入点OTEL_RESOURCE_ATTRIBUTES="service.name=<service-name>,token=<token>" \\ # 此处<service-name>改为自定义服务名,<token>替换成步骤1中获得的tokenOTEL_PROPAGATORS=baggage,tracecontext \\php -S localhost:8080
http://localhost:8080/getID
https://localhost:8080/getID。在有正常流量的情况下,应用性能监控 > 应用列表 中将展示接入的应用。单击应用名称/ID 进入应用详情页,再选择实例分析,即可看到接入的应用实例。由于可观测数据的处理存在一定延时,如果接入后在控制台没有查询到应用或实例,请等待30秒左右。<?phpuse OpenTelemetry\\API\\Globals; // 必须的包require __DIR__ . '/vendor/autoload.php';function wait(): void{// 通过Globals包获取当前已经配置的providers$tracerProvider = Globals::tracerProvider();$tracer = $tracerProvider->getTracer('instrumentation-scope-name', //name (required)'instrumentation-scope-version', //version'http://example.com/my-schema', //schema url['foo' => 'bar'] //attributes);// 自定义埋点$span = $tracer->spanBuilder("wait")->startSpan();// 业务代码sleep(5);// 自定义埋点结束$span->end();}wait();

echo -e "\\nOTEL_PHP_AUTOLOAD_ENABLED=$OTEL_PHP_AUTOLOAD_ENABLEDOTEL_TRACES_EXPORTER=$OTEL_TRACES_EXPORTEROTEL_METRICS_EXPORTER=$OTEL_METRICS_EXPORTEROTEL_LOGS_EXPORTER=$OTEL_LOGS_EXPORTEROTEL_EXPORTER_OTLP_PROTOCOL=$OTEL_EXPORTER_OTLP_PROTOCOLOTEL_EXPORTER_OTLP_ENDPOINT=$OTEL_EXPORTER_OTLP_ENDPOINTOTEL_RESOURCE_ATTRIBUTES=$OTEL_RESOURCE_ATTRIBUTESOTEL_PROPAGATORS=$OTEL_PROPAGATORS"
OTEL_TRACES_EXPORTER=console ,重启 PHP 项目,发送请求到该 PHP 服务。

composer require guzzlehttp/guzzle
composer require \\open-telemetry/sdk \\open-telemetry/exporter-otlp
pecl install grpc # 如果之前已经下载过grpc,可以跳过这一步composer require open-telemetry/transport-grpc
index.php文件所在目录中创建opentelemetry_util.php文件。并在文件中添加如下代码。<?php// 包含设置应用名、Trace导出方式、Trace上报接入点,并创建全局TraceProvideuse OpenTelemetry\\API\\Globals;use OpenTelemetry\\API\\Trace\\Propagation\\TraceContextPropagator;use OpenTelemetry\\Contrib\\Otlp\\SpanExporter;use OpenTelemetry\\SDK\\Common\\Attribute\\Attributes;use OpenTelemetry\\SDK\\Common\\Export\\Stream\\StreamTransportFactory;use OpenTelemetry\\SDK\\Resource\\ResourceInfo;use OpenTelemetry\\SDK\\Resource\\ResourceInfoFactory;use OpenTelemetry\\SDK\\Sdk;use OpenTelemetry\\SDK\\Trace\\Sampler\\AlwaysOnSampler;use OpenTelemetry\\SDK\\Trace\\Sampler\\ParentBased;use OpenTelemetry\\SDK\\Trace\\SpanProcessor\\SimpleSpanProcessor;use OpenTelemetry\\SDK\\Trace\\SpanProcessor\\BatchSpanProcessorBuilder;use OpenTelemetry\\SDK\\Trace\\TracerProvider;use OpenTelemetry\\SemConv\\ResourceAttributes;use OpenTelemetry\\Contrib\\Grpc\\GrpcTransportFactory;use OpenTelemetry\\Contrib\\Otlp\\OtlpUtil;use OpenTelemetry\\API\\Signals;// OpenTelemetry 初始化配置(需要在PHP应用初始化时就进行OpenTelemetry初始化配置)function initOpenTelemetry(){// 1. 设置 OpenTelemetry 资源信息$resource = ResourceInfoFactory::emptyResource()->merge(ResourceInfo::create(Attributes::create([ResourceAttributes::SERVICE_NAME => '<your-service-name>', // 应用名,必填,如php-opentelemetry-demoResourceAttributes::HOST_NAME => '<your-host-name>' // 主机名,选填'token' => '<your-token>' // 替换成步骤1中获得的 Token])));// 2. 创建将 Span 输出到控制台的 SpanExplorer// $spanExporter = new SpanExporter(// (new StreamTransportFactory())->create('php://stdout', 'application/json')// );// 2. 创建通过 gRPC 上报 Span 的 SpanExplorer$transport = (new GrpcTransportFactory())->create('<grpc-endpoint>' . OtlpUtil::method(Signals::TRACE)); # 替换成步骤1中获得的接入点信息$spanExporter = new SpanExporter($transport);// 3. 创建全局的 TraceProvider,用于创建 tracer$tracerProvider = TracerProvider::builder()->addSpanProcessor((new BatchSpanProcessorBuilder($spanExporter))->build())->setResource($resource)->setSampler(new ParentBased(new AlwaysOnSampler()))->build();Sdk::builder()->setTracerProvider($tracerProvider)->setPropagator(TraceContextPropagator::getInstance())->setAutoShutdown(true) // PHP 程序退出后自动关闭 tracerProvider,保证链路数据都被上报->buildAndRegisterGlobal(); // 将 tracerProvider 添加到全局}?>
index.php文件中导入所需包。<?phpuse OpenTelemetry\\API\\Globals;use OpenTelemetry\\API\\Trace\\StatusCode;use OpenTelemetry\\API\\Trace\\SpanKind;use OpenTelemetry\\SDK\\Common\\Attribute\\Attributes;use OpenTelemetry\\SDK\\Trace\\TracerProvider;use Psr\\Http\\Message\\ResponseInterface as Response;use Psr\\Http\\Message\\ServerRequestInterface as Request;use Slim\\Factory\\AppFactory;require __DIR__ . '/opentelemetry_util.php';
initOpenTelemetry方法完成初始化,需要在 PHP 应用初始化时就进行 OpenTelemetry 初始化配置。// OpenTelemetry 初始化,包含设置应用名、Trace导出方式、Trace上报接入点,并创建全局TraceProviderinitOpenTelemetry();
rolldice接口中创建 Span。/*** 1. 接口功能:模拟扔骰子,返回一个1-6之间的随机正整数* 并演示如何创建Span、设置属性、事件、带有属性的事件*/$app->get('/rolldice', function (Request $request, Response $response) {// 获取 tracer$tracer = \\OpenTelemetry\\API\\Globals::tracerProvider()->getTracer('my-tracer');// 创建 Span; 设置span kind,不设置默认为KIND_INTERNAL$span = $tracer->spanBuilder("/rolldice")->setSpanKind(SpanKind::KIND_SERVER)->startSpan();// 为 Span 设置属性$span->setAttribute("http.method", "GET");// 为 Span 设置事件$span->addEvent("Init");// 设置带有属性的事件$eventAttributes = Attributes::create(["key1" => "value","key2" => 3.14159,]);// 业务代码$result = random_int(1,6);$response->getBody()->write(strval($result));$span->addEvent("End");// 销毁 Span$span->end();return $response;});
rolltwodices接口,模拟扔两个骰子,返回两个1 - 6之间的随机正整数。以下代码演示如何创建嵌套的 Span。$app->get('/rolltwodices', function (Request $request, Response $response) {// 获取 tracer$tracer = \\OpenTelemetry\\API\\Globals::tracerProvider()->getTracer('my-tracer');// 创建 Span$parentSpan = $tracer->spanBuilder("/rolltwodices/parent")->setSpanKind(SpanKind::KIND_SERVER)->startSpan();$scope = $parentSpan->activate();$value1 = random_int(1,6);$childSpan = $tracer->spanBuilder("/rolltwodices/parent/child")->startSpan();// 业务代码$value2 = random_int(1,6);$result = "dice1: " . $value1 . ", dice2: " . $value2;// 销毁 Span$childSpan->end();$parentSpan->end();$scope->detach();$response->getBody()->write(strval($result));return $response;});
error接口,模拟接口发生异常。以下代码演示如何在代码发生异常时使用 Span 记录状态。$app->get('/error', function (Request $request, Response $response) {// 获取 tracer$tracer = \\OpenTelemetry\\API\\Globals::tracerProvider()->getTracer('my-tracer');// 创建 Span$span3 = $tracer->spanBuilder("/error")->setSpanKind(SpanKind::KIND_SERVER)->startSpan();try {// 模拟代码发生异常throw new \\Exception('exception!');} catch (\\Throwable $t) {// 设置Span状态为error$span3->setStatus(\\OpenTelemetry\\API\\Trace\\StatusCode::STATUS_ERROR, "expcetion in span3!");// 记录异常栈轨迹$span3->recordException($t, ['exception.escaped' => true]);} finally {$span3->end();$response->getBody()->write("error");return $response;}});
php -S localhost:8080
http://localhost:8080/rolldicehttp://localhost:8080/rolltwodiceshttp://localhost:8080/error
https://localhost:8080/getID。在有正常流量的情况下,应用性能监控 > 应用列表 中将展示接入的应用,单击应用名称/ID 进入应用详情页。再选择实例分析,即可看到接入的应用实例。由于可观测数据的处理存在一定延时,如果接入后在控制台没有查询到应用或实例,请等待30秒左右。文档反馈