通過OpenTelemetry為應用埋點并上報鏈路數據至可觀測鏈路 OpenTelemetry 版后,可觀測鏈路 OpenTelemetry 版即可開始監控應用,您可以查看應用拓撲、調用鏈路、異常事務、慢事務和SQL分析等一系列監控數據。本文介紹如何使用OpenTelemetry為PHP應用進行自動或手動埋點并上報數據。
前提條件
新版控制臺
登錄可觀測鏈路 OpenTelemetry 版控制臺,在左側導航欄單擊接入中心。
在開源框架區域單擊OpenTelemetry卡片。
在彈出的OpenTelemetry面板中選擇數據需要上報的地域。
說明初次接入的地域將會自動進行資源初始化。
選擇連接方式和上報方式,然后復制接入點信息。
連接方式:若您的服務部署在阿里云上,且所屬地域與選擇的接入地域一致,推薦使用阿里云內網方式,否則選擇公網方式。
上報方式:根據客戶端支持的協議類型選擇HTTP或gRPC協議上報數據。
舊版控制臺
在左側導航欄單擊集群配置,然后在右側頁面單擊接入點信息頁簽。
在頁面頂部選擇需要接入的地域,然后在集群信息區域打開顯示Token開關。
在客戶端采集工具區域單擊OpenTelemetry。
在相關信息列中,獲取接入點信息。
說明如果應用部署于阿里云生產環境,則選擇阿里云VPC網絡接入點,否則選擇公網接入點。
背景信息
OpenTelemetry PHP支持自動埋點和手動埋點,對PHP的版本要求如下:
自動埋點支持的版本:PHP 8.0 +
手動埋點支持的版本:PHP 7.4 +
支持自動埋點的框架列表如下,完整信息請參見OpenTelemetry官方文檔。
CodeIgniter Framework
PHP HTTP Async Client
PHP IO
Laravel
MongoDB
PDO
PSR-15 middleware
PSR-18 HTTP clients
PSR-3
Slim
Symfony
WordPress
Yii
示例Demo
示例代碼倉庫地址:php-opentelemetry-demo
基于OpenTelemery PHP Extension為應用自動埋點并上報鏈路數據
Auto-demo是基于PHP Slim Web框架實現一個模擬扔骰子游戲的應用,并使用OpenTelemetry為應用自動埋點(即自動創建Trace/Span等鏈路數據),實現無侵入的PHP應用鏈路追蹤。
OpenTelemetry除了支持Slim框架的自動埋點,還支持多種框架,完整列表請參見官方文檔。
前提條件
已安裝PHP、Composer、PECL,且PHP版本≥8.0。
操作步驟
創建投骰子應用。
初始化。
mkdir <project-name> && cd <project-name> composer init \ --no-interaction \ --stability beta \ --require slim/slim:"^4" \ --require slim/psr7:"^1" composer update
編寫應用代碼。
在<project-name>目錄下創建一個index.php文件,添加如下內容。
這段代碼模擬扔骰子游戲,返回1-6之間的一個隨機數。
<?php use 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('/rolldice', function (Request $request, Response $response) { $result = random_int(1,6); $response->getBody()->write(strval($result)); return $response; }); $app->run();
此時應用已經編寫完成,執行
php -S localhost:8080
命令即可運行應用,訪問地址為http://localhost:8080/rolldice
。
構建OpenTelemetry PHP擴展。
下載構建OpenTelemetry PHP extension所需要的工具。
macOS
brew install gcc make autoconf
Linux(apt)
sudo apt-get install gcc make autoconf
使用PECL構建OpenTelemetry PHP擴展。
pecl install opentelemetry
注意,構建成功時輸出內容的最后幾行如下(路徑可能不完全一致):
Build process completed successfully Installing '/opt/homebrew/Cellar/php/8.2.8/pecl/20220829/opentelemetry.so' install ok: channel://pecl.php.net/opentelemetry-1.0.0beta6 Extension opentelemetry enabled in php.ini
(可選)啟用OpenTelemetry PHP擴展。
如果上一步輸出了
Extension opentelemetry enabled in php.ini
,表明已經啟用,請跳過當前步驟。在php.ini文件中添加如下內容:
[opentelemetry] extension=opentelemetry.so
再次驗證是否構建并啟用成功。
方法一:
php -m | grep opentelemetry
預期輸出:
opentelemetry
方法二
php --ri opentelemetry
預期輸出:
opentelemetry opentelemetry support => enabled extension version => 1.0.0beta6
為投骰子應用添加OpenTelemetry PHP自動埋點需要的額外依賴。
# 這一步構建時間較長,會在控制臺打印很多內容 pecl install grpc composer config allow-plugins.php-http/discovery false composer require \ open-telemetry/sdk \ open-telemetry/opentelemetry-auto-slim \ open-telemetry/exporter-otlp \ php-http/guzzle7-adapter \ open-telemetry/transport-grpc
open-telemetry/sdk:OpenTelemetry PHP SDK。
open-telemetry/opentelemetry-auto-slim:OpenTelemetry PHP針對Slim框架實現的自動埋點插件。
open-telemetry/exporter-otlp:OpenTelemetry PHP OTLP協議數據上報所需的依賴。
運行應用。
執行以下命令。
env OTEL_PHP_AUTOLOAD_ENABLED=true \ OTEL_SERVICE_NAME=<your-service-name> \ OTEL_TRACES_EXPORTER=otlp \ OTEL_METRICS_EXPORTER=none \ OTEL_LOGS_EXPORTER=none \ OTEL_EXPORTER_OTLP_PROTOCOL=grpc \ OTEL_EXPORTER_OTLP_ENDPOINT=<endpoint> \ OTEL_EXPORTER_OTLP_HEADERS=Authentication=<token> \ OTEL_PROPAGATORS=baggage,tracecontext \ php -S localhost:8080
<your-service-name>:應用名,如:
php-demo
。<endpoint>:前提條件中獲取的gRPC接入點,如:
http://tracing-analysis-dc-hz.aliyuncs.com:8090
。<token>:前提條件中獲取的接入鑒權信息。
在瀏覽器中訪問以下鏈接。
http://localhost:8080/rolldice
每次進入該頁面,OpenTelemetry都會自動創建Trace,并將鏈路數據上報至阿里云可觀測鏈路 OpenTelemetry 版。
查看鏈路數據。
登錄可觀測鏈路 OpenTelemetry 版控制臺,在應用列表頁面找到應用名為
<your-service-name>
的應用(例如php-demo),單擊應用名稱進入應用詳情中查看調用鏈。
基于OpenTelemery PHP SDK為應用手動埋點并上報鏈路數據
Manual-demo是基于PHP Slim Web框架實現一個模擬扔骰子游戲的應用,并使用OpenTelemetry PHP SDK為應用手動埋點(即在代碼中創建Span,并為Span設置屬性、事件、狀態等),實現自定義的PHP應用鏈路追蹤。
當OpenTelemetry PHP Extension自動埋點不滿足您的場景,或者需要增加一些自定義業務埋點時,可以使用手動埋點方式上報鏈路數據。
前提條件
已安裝PHP、Composer、PECL,且PHP版本≥7.4。
操作步驟
創建投骰子應用。
初始化。
mkdir <project-name> && cd <project-name> composer init \ --no-interaction \ --stability beta \ --require slim/slim:"^4" \ --require slim/psr7:"^1" composer update
編寫應用代碼。
在<project-name>目錄下創建一個index.php文件,添加如下內容。
這段代碼模擬扔骰子游戲,返回1-6之間的一個隨機數。
<?php use 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('/rolldice', function (Request $request, Response $response) { $result = random_int(1,6); $response->getBody()->write(strval($result)); return $response; }); $app->run();
此時應用已經編寫完成,執行
php -S localhost:8080
命令即可運行應用,訪問地址為http://localhost:8080/rolldice
。
導入OpenTelemetry PHP SDK以及OpenTelemetry gRPC Explorer所需依賴。
下載PHP HTTP客戶端庫,用于鏈路數據上報。
composer require guzzlehttp/guzzle
下載OpenTelemetry PHP SDK。
composer require \ open-telemetry/sdk \ open-telemetry/exporter-otlp
下載使用gRPC上報數據時所需依賴。
pecl install grpc # 如果之前已經下載過grpc,可以跳過這一步 composer require open-telemetry/transport-grpc
編寫OpenTelemetry初始化工具類。
在index.php文件所在目錄中創建opentelemetry_util.php文件。
在文件中添加如下代碼。
<?php use OpenTelemetry\API\Common\Instrumentation\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\Common\Signal\Signals; // OpenTelemetry 初始化配置(包含設置應用名、Trace導出方式、Trace上報接入點,并創建全局TraceProvide。需要在PHP應用初始化時就進行OpenTelemetry初始化配置) function initOpenTelemetry() { // 1. 設置 OpenTelemetry 資源信息 $resource = ResourceInfoFactory::emptyResource()->merge(ResourceInfo::create(Attributes::create([ ResourceAttributes::SERVICE_NAME => '<your-service-name>', # 應用名,必填,如php-manual-demo ResourceAttributes::HOST_NAME => '<your-host-name>' # 主機名,選填 ]))); // 2. 創建將 Span 輸出到控制臺的 SpanExplorer // $spanExporter = new SpanExporter( // (new StreamTransportFactory())->create('php://stdout', 'application/json') // ); // 2. 創建通過 gRPC 上報 Span 的 SpanExplorer $headers = [ 'Authentication' => "<your-token>", ]; $transport = (new GrpcTransportFactory())->create('<grpc-endpoint>' . OtlpUtil::method(Signals::TRACE), 'application/x-protobuf', $headers); $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 添加到全局 } ?>
<your-service-name>:應用名。
<your-host-name>:主機名。
<your-token>:通過gRPC上報數據的鑒權Token。
<grpc-endpoint>:通過gRPC上報數據的接入點。
修改應用代碼,使用OpenTelemetry API創建Span。
在index.php文件中導入所需包。
<?php use OpenTelemetry\API\Common\Instrumentation\Globals; use OpenTelemetry\SDK\Common\Attribute\Attributes; use OpenTelemetry\SDK\Trace\TracerProvider; require __DIR__ . '/opentelemetry_util.php';
調用initOpenTelemetry方法完成初始化,需要在PHP應用初始化時就進行OpenTelemetry初始化配置。
// OpenTelemetry 初始化,包含設置應用名、Trace導出方式、Trace上報接入點,并創建全局TraceProvider initOpenTelemetry();
在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 = $tracer->spanBuilder("/rolldice")->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; });
創建嵌套Span。
新建一個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")->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; });
使用Span記錄代碼中發生的異常。
新建error接口,模擬接口發生異常。
以下代碼演示如何在代碼發生異常時使用Span記錄狀態。
$app->get('/error', function (Request $request, Response $response) { // 獲取 tracer $tracer = \OpenTelemetry\API\Globals::tracerProvider()->getTracer('my-tracer'); // 創建 Span $span3 = $tracer->spanBuilder("/error")->startSpan(); try { // 模擬代碼發生異常 throw new \Exception('exception!'); } catch (\Throwable $t) { // 設置Span狀態為error $span3->setStatus(\OpenTelemetry\API\Trace\StatusCode::STATUS_ERROR, "exception in span3!"); // 記錄異常棧軌跡 $span3->recordException($t, ['exception.escaped' => true]); } finally { $span3->end(); $response->getBody()->write("error"); return $response; } });
運行應用。
執行以下命令
php -S localhost:8080
在瀏覽器中訪問以下鏈接:
http://localhost:8080/rolldice http://localhost:8080/rolltwodices http://localhost:8080/error
每次訪問頁面,OpenTelemetry會創建鏈路數據,并將鏈路數據上報至阿里云可觀測鏈路 OpenTelemetry 版。
查看鏈路數據。
登錄可觀測鏈路 OpenTelemetry 版控制臺,在應用列表頁面找到應用名為
<your-service-name>
的應用(例如php-manual-demo),單擊應用名稱進入應用詳情中查看調用鏈。