通過OpenTelemetry為應用埋點並上報鏈路資料至Managed Service for OpenTelemetry後,Managed Service for OpenTelemetry即可開始監控應用,您可以查看應用拓撲、調用鏈路、異常事務、慢事務和SQL分析等一系列監控資料。本文介紹如何使用OpenTelemetry為PHP應用進行自動或手動埋點並上報資料。
前提條件
背景資訊
OpenTelemetry PHP支援自動埋點和手動埋點,對PHP的版本要求如下:
自動埋點支援的版本:PHP 8.0 +
手動埋點支援的版本:PHP 7.4 +
支援自動埋點的架構列表如下,完整資訊請參見OpenTelemetry官方文檔。
樣本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,並將鏈路資料上報至阿里雲Managed Service for 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會建立鏈路資料,並將鏈路資料上報至阿里雲Managed Service for OpenTelemetry。
查看鏈路資料。
登入可觀測鏈路 OpenTelemetry 版控制台,在應用列表頁面找到應用程式名稱為
<your-service-name>
的應用(例如php-manual-demo),單擊應用程式名稱進入應用詳情中查看調用鏈。