全部產品
Search
文件中心

Application Real-Time Monitoring Service:通過OpenTelemetry上報PHP應用

更新時間:Aug 07, 2024

通過OpenTelemetry為應用埋點並上報鏈路資料至Managed Service for OpenTelemetry後,Managed Service for OpenTelemetry即可開始監控應用,您可以查看應用拓撲、調用鏈路、異常事務、慢事務和SQL分析等一系列監控資料。本文介紹如何使用OpenTelemetry為PHP應用進行自動或手動埋點並上報資料。

前提條件

擷取存取點資訊

  1. 登入ARMS控制台,在左側導覽列單擊接入中心

  2. 服務端應用地區單擊OpenTelemetry卡片。

  3. 在彈出的OpenTelemetry面板中選擇資料需要上報的地區。

    說明

    初次接入的地區將會自動進行資源初始化。

  4. 選擇串連方式上報方式,然後複製存取點資訊。

    • 串連方式:若您的服務部署在阿里雲上,且所屬地區與選擇的接入地區一致,推薦使用阿里雲內網方式,否則選擇公網方式。

    • 上報方式:根據用戶端支援的協議類型選擇HTTP或gRPC協議上報資料。

    image.png

背景資訊

OpenTelemetry PHP支援自動埋點和手動埋點,對PHP的版本要求如下:

  • 自動埋點支援的版本:PHP 8.0 +

  • 手動埋點支援的版本:PHP 7.4 +

支援自動埋點的架構列表如下,完整資訊請參見OpenTelemetry官方文檔

展開查看支援監控的PHP架構

  • 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。

操作步驟

  1. 建立投骰子應用。

    1. 初始化。

    mkdir <project-name> && cd <project-name>
    
    
    composer init \
     --no-interaction \
     --stability beta \
     --require slim/slim:"^4" \
     --require slim/psr7:"^1"
    composer update
    1. 編寫應用代碼。

      在<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

  2. 構建OpenTelemetry PHP擴充。

    1. 下載構建OpenTelemetry PHP extension所需要的工具。

      • macOS

        brew install gcc make autoconf
      • Linux(apt)

        sudo apt-get install gcc make autoconf
    2. 使用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
    3. (可選)啟用OpenTelemetry PHP擴充。

      如果上一步輸出了Extension opentelemetry enabled in php.ini,表明已經啟用,請跳過當前步驟。

      在php.ini檔案中添加如下內容:

      [opentelemetry]
      extension=opentelemetry.so
    4. 再次驗證是否構建並啟用成功。

      • 方法一:

        php -m | grep opentelemetry

        預期輸出:

        opentelemetry
      • 方法二

        php --ri opentelemetry

        預期輸出:

        opentelemetry
        opentelemetry support => enabled
        extension version => 1.0.0beta6
    5. 為投骰子應用添加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協議資料上報所需的依賴。

  3. 運行應用。

    1. 執行以下命令。

      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>:前提條件中擷取的接入鑒權資訊。

    2. 在瀏覽器中訪問以下連結。

      http://localhost:8080/rolldice

      每次進入該頁面,OpenTelemetry都會自動建立Trace,並將鏈路資料上報至阿里雲Managed Service for OpenTelemetry

    3. 查看鏈路資料。

      登入可觀測鏈路 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。

操作步驟

  1. 建立投骰子應用。

    1. 初始化。

    mkdir <project-name> && cd <project-name>
    
    
    composer init \
     --no-interaction \
     --stability beta \
     --require slim/slim:"^4" \
     --require slim/psr7:"^1"
    composer update
    1. 編寫應用代碼。

      在<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

  2. 匯入OpenTelemetry PHP SDK以及OpenTelemetry gRPC Explorer所需依賴。

    1. 下載PHP HTTP用戶端庫,用於鏈路資料上報。

      composer require guzzlehttp/guzzle
    2. 下載OpenTelemetry PHP SDK。

      composer require \
       open-telemetry/sdk \
       open-telemetry/exporter-otlp
    3. 下載使用gRPC上報資料時所需依賴。

      pecl install grpc # 如果之前已經下載過grpc,可以跳過這一步
      composer require open-telemetry/transport-grpc
  3. 編寫OpenTelemetry初始化工具類。

    1. 在index.php檔案所在目錄中建立opentelemetry_util.php檔案。

    2. 在檔案中添加如下代碼。

      <?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上報資料的存取點。

  4. 修改應用代碼,使用OpenTelemetry API建立Span。

  5. 在index.php檔案中匯入所需包。

    1. <?php
      
      use OpenTelemetry\API\Common\Instrumentation\Globals;
      use OpenTelemetry\SDK\Common\Attribute\Attributes;
      use OpenTelemetry\SDK\Trace\TracerProvider;
      
      require __DIR__ . '/opentelemetry_util.php';
    2. 調用initOpenTelemetry方法完成初始化,需要在PHP應用初始化時就進行OpenTelemetry初始化配置。

      // OpenTelemetry 初始化,包含設定應用程式名稱、Trace匯出方式、Trace上報存取點,並建立全域TraceProvider
      initOpenTelemetry();
    3. 在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;
      });
    4. 建立嵌套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;
      });
    5. 使用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;
       }
      });
  6. 運行應用。

    1. 執行以下命令

      php -S localhost:8080
    2. 在瀏覽器中訪問以下連結:

      http://localhost:8080/rolldice
      http://localhost:8080/rolltwodices
      http://localhost:8080/error

      每次訪問頁面,OpenTelemetry會建立鏈路資料,並將鏈路資料上報至阿里雲Managed Service for OpenTelemetry

    3. 查看鏈路資料。

      登入可觀測鏈路 OpenTelemetry 版控制台,在應用列表頁面找到應用程式名稱為<your-service-name>的應用(例如php-manual-demo),單擊應用程式名稱進入應用詳情中查看調用鏈。