tencent cloud

Feedback

Connecting PHP Application via OpenTelemetry-PHP (Recommended)

Last updated: 2024-11-01 18:19:03
    Note:
    OpenTelemetry is a collection of tools, APIs, and SDKs for monitoring, generating, collecting, and exporting telemetry data (metrics, logs, and traces) to help users analyze the performance and behavior of the software. For more information about OpenTelemetry, see the OpenTelemetry official website.
    The OpenTelemetry community is active, with rapid technological changes, and widely compatible with mainstream programming languages, components, and frameworks, making its link-tracing capability highly popular for cloud-native microservices and container architectures.
    This document introduces how to integrate PHP applications using the community's OpenTelemetry-PHP scheme through relevant operations.
    The OpenTelemetry-PHP scheme provides automatic event tracking for commonly used PHP dependency libraries and frameworks, such as Slim, without modifying the code to report linkage information. For other dependency libraries and frameworks that support automatic event tracking, see complete list provided by the OpenTelemetry community.

    Prerequisites

    Install the following tools:
    PECL
    composer
    Ensure that you can run the following commands in the shell:
    php -v
    composer -v

    Automatic Integration

    PHP 8.0+
    For details on the list of frameworks supported by automatic event tracking, see OpenTelemetry official documentation.

    Manual Integration

    PHP 7.4+

    Demo Application

    The sample code index.php is an HTTP Server using PDO to connect to a MySQL database for database operations. Set up the corresponding MySQL service yourself or purchase cloud services directly.
    1. Initializing Application
    mkdir <project-name> && cd <project-name>
    
    composer init \\
    --no-interaction \\
    --stability beta \\
    --require slim/slim:"^4" \\
    --require slim/psr7:"^1"
    composer update
    2. Writing Business Code
    Create an index.php file in the <project-name> directory and add the following content.
    The following content will simulate a search operation using PDO to connect to MySQL with an HTTP Server API.
    <?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('/getID', function (Request $request, Response $response) { $dbms = 'mysql'; // Database type $host = 'localhost'; // Database hostname $dbName = 'Mydb'; // Database in use $user = 'root'; // Database connection username $pass = ''; // Corresponding password $dsn = "$dbms:host=$host;dbname=$dbName"; try { $dbh = new PDO($dsn, $user, $pass); // Initialize a PDO object echo "Connection successful<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();

    Preliminary steps: Get the access point and token.

    1. Log in to the TCOP console.
    2. In the left sidebar, select Application Performance Management > Application monitoring, and click Application list > Access application.
    3. In the Data Ingestion drawer that pops up on the right, click PHP language.
    4. On the Integrate PHP Applications page, select the desired Region and Business System.
    5. Select Access protocol type as OpenTelemetry.
    6. Reporting method Choose your desired reporting method, and obtain your Access Point and Token.
    Note:
    Private network reporting: Using this reporting method, your service needs to run in the Tencent Cloud VPC. Through VPC connecting directly, you can avoid the security risks of public network communication and save on reporting traffic overhead.
    Public network reporting: If your service is deployed locally or in non-Tencent Cloud VPC, you can report data in this method. However, it involves security risks in public network communication and incurs reporting traffic fees.

    Automatic Integration Scheme (Recommended)

    Step 1: Build OpenTelemetry PHP extension.

    Note:
    If you have already built the OpenTelemetry PHP extension, you can skip this step.
    1. Download the tools required to build the OpenTelemetry PHP extension:
    macOS
    brew install gcc make autoconf
    Linux (apt)
    sudo apt-get install gcc make autoconf
    2. Build the OpenTelemetry PHP extension using PECL:
    pecl install opentelemetry
    Note:
    The last few lines of output upon successful build are as follows (paths may vary):
    Build process completed successfully
    Installing '/opt/homebrew/Cellar/php/8.2.8/pecl/2020829/opentelemetry.so'
    install ok: channel://pecl.php.net/opentelemetry-1.0.3
    Extension opentelemetry enabled in php.ini
    3. Enable the OpenTelemetry PHP extension.
    Note:
    If Extension opentelemetry enabled in php.ini is output in the previous step, it is enabled. Skip this step.
    Add the following contents to the php.ini file:
    [opentelemetry]
    extension=opentelemetry.so
    php.ini file locations may include:
    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
    4. Verify that the build and enablement were successful.
    Solution 1:
    php -m | grep opentelemetry
    Expected output:
    opentelemetry
    Solution 2:
    php --ri opentelemetry
    Expected output:
    opentelemetry
    opentelemetry support => enabled
    extension version => 1.0.3
    5. Add additional dependencies required for OpenTelemetry PHP automatic event tracking to the application.
    pecl install grpc # This step takes a long time to build.
    composer 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/sdk: OpenTelemetry PHP SDK.
    open-telemetry/exporter-otlp: Dependencies required for OpenTelemetry PHP OTLP protocol data reporting.
    open-telemetry/opentelemetry-auto-slim: Automatic event tracking packet of OpenTelemetry PHP for Slim framework implementation.
    open-telemetry/opentelemetry-auto-pdo: Automatic event tracking packet of OpenTelemetry PHP for PHP DataObject implementation.
    Note:
    The packets open-telemetry/opentelemetry-auto-slim and open-telemetry/opentelemetry-auto-pdo are imported because the example demo uses the PDO and Slim frameworks. You can adjust according to your specific business needs. If your business components require OpenTelemetry automatic event tracking, you need to import the corresponding automatic event tracking packets into the project. For detailed import methods, see OpenTelemetry official documentation.

    Step 2: Run the application.

    1. Execute the following command:
    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> \\ # Replace with the access point obtained in Step 1.
    OTEL_RESOURCE_ATTRIBUTES="service.name=<service-name>,token=<token>" \\ # Replace <service-name> with your custom service name and <token> with the token obtained in Step 1.
    OTEL_PROPAGATORS=baggage,tracecontext \\
    php -S localhost:8080
    2. Visit the following link in the browser:
    http://localhost:8080/getID
    Each time you visit this page, OpenTelemetry will automatically create a Trace and report the linkage data to APM.

    Connection Verification

    After starting the PHP application, visit the corresponding interface via port 8080, for example, https://localhost:8080/getID. If there is normal traffic, the integrated application will be displayed in APM > Application monitoring > Application list, and the integrated application instances will be displayed in APM > Application monitoring > Application details > Instance monitoring. Since there is a certain delay in processing observable data, if the application or instance is not found in the console after integration, please wait about 30 seconds.

    Custom Event Tracking (Optional)

    PHP Custom Tracing Documentation.' style="color:#000000;font-size:12px;"> When automatic event tracking does not meet your scenarios, or you need to add business layer event tracking, you can refer to the following content to use the OpenTelemetry PHP SDK to add custom event tracking. This document only demonstrates the most basic custom event tracking method. The OpenTelemetry community provides more flexible custom event tracking methods, and specific usage methods can be found in the OpenTelemetry community's PHP Custom Tracing Documentation.
    <?php use OpenTelemetry\\API\\Globals; // Required packet require __DIR__ . '/vendor/autoload.php'; function wait(): void { // Obtain the currently configured providers through the Globals packet.
    $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 );
    // Custom Event Tracking $span = $tracer->spanBuilder("wait")->startSpan();
    // Business code.null sleep(5);null
    // Custom event tracking ends.
    $span->end(); } wait();

    Manual Connection Scheme

    If your PHP application version cannot meet 8.0+ but can meet 7.4+, you can choose manual event tracking to report. This document only demonstrates the most basic manual event tracking method. The OpenTelemetry community provides more flexible manual event tracking methods, and specific usage methods can be found in the OpenTelemetry community's PHP Manual Integration Documentation.

    Import the dependencies needed for the OpenTelemetry PHP SDK and OpenTelemetry gRPC Explorer.

    1. Download the PHP HTTP Client Library to report linkage data.
    composer require guzzlehttp/guzzle
    2. Download the OpenTelemetry PHP SDK.
    composer require \\
    open-telemetry/sdk \\
    open-telemetry/exporter-otlp
    3. Download the dependencies needed to report data using gRPC.
    pecl install grpc # Skip this step if gRPC has already been downloaded.
    composer require open-telemetry/transport-grpc

    Create an OpenTelemetry initialization tool.

    Create the opentelemetry_util.php file in the directory where the index.php file is located and add the following code to the file:
    <?php
    // Includes setting application name, Trace export method, Trace reporting access point, and creates a global TraceProvider.
    
    use 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 initialization configuration (OpenTelemetry initialization configuration needs to be done when the PHP application initializes)
    function initOpenTelemetry()
    {
    // 1. Set OpenTelemetry resource information.
    $resource = ResourceInfoFactory::emptyResource()->merge(ResourceInfo::create(Attributes::create([
    ResourceAttributes::SERVICE_NAME => '<your-service-name>', // Application name, required, e.g., php-opentelemetry-demo.
    ResourceAttributes::HOST_NAME => '<your-host-name>' // hostname, optional.
    'token' => '<your-token>' // Replace with the token obtained in step 1.
    ])));
    // 2. Create a SpanExplorer to output spans to the console.
    // $spanExporter = new SpanExporter(
    // (new StreamTransportFactory())->create('php://stdout', 'application/json')
    // );
    // 2. Create a SpanExplorer to report spans via gRPC.
    $transport = (new GrpcTransportFactory())->create('<grpc-endpoint>' . OtlpUtil::method(Signals::TRACE)); # Replace with the access point information obtained in step 1.
    $spanExporter = new SpanExporter($transport);
    // 3. Create a global TraceProvider to create a 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) // Automatically shut down the tracerProvider after the PHP program exits to ensure all linkage data is reported.
    ->buildAndRegisterGlobal(); // Add the tracerProvider to the global.
    
    }
    ?>

    Modify the application code and create spans using the OpenTelemetry API.

    1. Import the required packets in the index.php file:
    <?php
    
    use 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';
    2. Call the initOpenTelemetry method to complete initialization. OpenTelemetry initialization configuration needs to be done when the PHP application initializes:
    // OpenTelemetry initialization, including setting the application name, trace export method, trace reporting access point and creating a global TraceProvider.
    initOpenTelemetry();
    3. Create a span in the rolldice API.
    /**
    * 1. API feature: Simulate rolling a dice, returning a random integer between 1 and 6.
    * Demonstrate how to create a span, set attributes, events, and events with attributes.
    */
    $app->get('/rolldice', function (Request $request, Response $response) {
    // Obtain tracer.
    $tracer = \\OpenTelemetry\\API\\Globals::tracerProvider()->getTracer('my-tracer');
    // Create span; set span kind; default is KIND_INTERNAL if not set.
    $span = $tracer->spanBuilder("/rolldice")->setSpanKind(SpanKind::KIND_SERVER)->startSpan();
    // Set attributes for span.
    $span->setAttribute("http.method", "GET");
    // Set events for span.
    $span->addEvent("Init");
    // Set events with attributes.
    $eventAttributes = Attributes::create([
    "key1" => "value",
    "key2" => 3.14159,
    ]);
    
    // Business code.
    $result = random_int(1,6);
    $response->getBody()->write(strval($result));
    
    $span->addEvent("End");
    // Terminate span.
    $span->end();
    
    return $response;
    });
    4. Create nested span.
    Create a rolltwodices API to simulate rolling two dice, returning two random positive integers between 1 and 6. The following code demonstrates how to create nested spans:
    $app->get('/rolltwodices', function (Request $request, Response $response) {
    // Obtain tracer.
    $tracer = \\OpenTelemetry\\API\\Globals::tracerProvider()->getTracer('my-tracer');
    // Create 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();
    // Business code.
    $value2 = random_int(1,6);
    $result = "dice1: " . $value1 . ", dice2: " . $value2;
    
    // Terminate span.
    $childSpan->end();
    $parentSpan->end();
    $scope->detach();
    
    $response->getBody()->write(strval($result));
    return $response;
    });
    5. Use span to record exceptions that occur in the code.
    Create an error API to simulate an API exception. The following code demonstrates how to use span to record the status when an exception occurs in the code:
    $app->get('/error', function (Request $request, Response $response) {
    // Obtain tracer.
    $tracer = \\OpenTelemetry\\API\\Globals::tracerProvider()->getTracer('my-tracer');
    // Create span.
    $span3 = $tracer->spanBuilder("/error")->setSpanKind(SpanKind::KIND_SERVER)->startSpan();
    try {
    // Simulate code exception.
    throw new \\Exception('exception!');
    } catch (\\Throwable $t) {
    // Set span status to error.
    $span3->setStatus(\\OpenTelemetry\\API\\Trace\\StatusCode::STATUS_ERROR, "expcetion in span3!");
    // Record exception stack track.
    $span3->recordException($t, ['exception.escaped' => true]);
    } finally {
    $span3->end();
    $response->getBody()->write("error");
    return $response;
    }
    });

    Run the application.

    1. Execute the following command:
    php -S localhost:8080
    2. Visit the following link in the browser:
    http://localhost:8080/rolldice
    http://localhost:8080/rolltwodices
    http://localhost:8080/error
    Each time the page is accessed, OpenTelemetry will create linkage data and report it to APM.

    Connection Verification

    After starting the PHP application, visit the corresponding interface via port 8080, for example, https://localhost:8080/getID. If there is normal traffic, the integrated application will be displayed in APM > Application monitoring > Application list, and the integrated application instances will be displayed in APM > Application monitoring > Application details > Instance monitoring. Since there is a certain delay in processing observable data, if the application or instance is not found in the console after integration, please wait about 30 seconds.
    Contact Us

    Contact our sales team or business advisors to help your business.

    Technical Support

    Open a ticket if you're looking for further assistance. Our Ticket is 7x24 avaliable.

    7x24 Phone Support