DD Trace PHP

repository·master·Indexed 20 days ago

https://github.com/datadog/dd-trace-php

A tracing library providing Application Performance Monitoring (APM) and distributed tracing for PHP applications. Includes the Datadog Application Security (AppSec) extension, support for building components from source, and Docker-based Clang tools for C++ static analysis and formatting.

Tokens
24.6K
Snippets
65
Records
119
Agent score
68%

What's inside dd-trace-php

  1. How the PHP Profiler performs time profiling

    master

    The profiler uses a mechanism to collect performance data with low overhead:

    1. Interrupt Mechanism: The profiler sets the Zend VM interrupt flag approximately every 10ms. The Zend Engine handles this interrupt at the next safe point (e.g., after an internal function like curl_exec is popped off the stack).
    2. Internal Hooks: It installs a zend_execute_internal hook to ensure the profiler can see internal functions without clearing the interrupt, allowing other extensions to continue processing interrupts normally.
    3. Data Collection: When the interrupt handler runs, it collects both wall-time and cpu-time since the last run.

    Note on CPU-time: Because of the collection method, cpu-time is biased towards functions performing I/O. This approach is chosen to keep the overhead on the process extremely low.

  2. Understand the role of libdatadog in dd-trace-php

    master

    The dd-trace-php extension relies on common components imported from the libdatadog repository via git submodules. These components are located in the libdatadog folder at the project's root.

    Key functionalities provided by the compiled libdatadog_php.a static library include:

    • Sidecar initialization and communication.
    • Sending telemetry.
    • Common functionality such as container identification and runtime ID generation.
  3. Handle errors and warnings in getID3()

    master

    The way errors are reported depends on the version of getID3() you are using:

    getID3() 1.x

    • Critical Errors: Found in $fileinfo['error']. If this key is populated, the file was not correctly parsed and the returned data may be incomplete or incorrect.
    • Warnings: Found in $fileinfo['warning']. If this key is populated but ['error'] is empty, the data is generally considered OK. Warnings usually indicate that the library encountered known bugs in other programs and worked around them, or that some specific data could not be extracted due to file errors.

    getID3() 2.x

    • Errors are thrown as exceptions, so you will receive at most one error.
  4. How the dd-trace-php extension is built

    master

    The extension is built by compiling Rust sources into a static library named libdatadog_php.a. This library is then linked into ddtrace.so, which is the main PHP extension loaded by the PHP engine at runtime to provide tracing functionality.

    The build process follows this flow:

    1. The compile_rust.sh script handles the compilation.
    2. This script is invoked via the Makefile (which is generated from config.m4).
    3. The resulting ddtrace.so contains the linked functionality from the Rust components.
  5. Component naming and include conventions

    master

    When developing components, follow these strict naming and inclusion rules to maintain consistency and avoid symbol collisions:

    • Header Inclusion: Use double-quotes and the relative path from the components/ directory. Example: #include "component_name/component_name.h"
    • Symbol Prefixing: All symbols (functions, variables, etc.) defined in a component header must be prefixed with datadog_php_.
    • Macro Prefixing: All macros defined in a component must be prefixed with DATADOG_PHP_.
  6. Migrate from dd-trace-php 0.x to 1.0

    master

    Upgrading to version 1.0 involves several breaking changes. Follow these steps for a smooth transition:

    1. Check PHP Version: Ensure you are running at least PHP 7. Support for PHP 5 was removed in version 1.0.
    2. Update WordPress Integration: Adjust configuration and monitors to account for the new enhanced integration and changed span names.
    3. Review Sampling Rules: Update DD_TRACE_SAMPLING_RULES from regex patterns to glob patterns.
    4. Update Deprecated APIs/Config: Replace removed functions, interfaces, and configuration keys with their 1.0 equivalents.
    5. Test Thoroughly: Verify application functionality after the upgrade.

    Tip: Enable debug logs by setting DD_TRACE_DEBUG=1 to identify deprecations before completing the migration.

  7. Configure DD Trace for Apache with mod_php

    master

    When using Apache with mod_php, you can configure the Datadog tracer using two primary methods:

    1. Host Environment Variables: Any environment variable set on the host machine (or via docker-compose.yml) is visible to the PHP process. This is useful for global settings like DD_AGENT_HOST.
    2. Apache SetEnv Directive: You can use the SetEnv directive within your Apache configuration (e.g., in a virtual host file) to apply specific tracer settings to particular virtual hosts. This is useful for settings like DD_TRACE_AGENT_PORT.
  8. Compile the PHP Profiler

    master

    The profiler is built using cargo. The build.rs script adapts the build to various PHP versions, and bindgen is used to generate Rust bindings to the Zend Engine.

    To build the profiler, use:

    cargo build

    To build a version suitable for running tests or production use, use the release flag:

    cargo build --release
  9. Requirements for the PHP Profiler

    master

    The PHP Profiler is implemented in Rust. Before using it, ensure your environment meets the following requirements:

    • PHP Version: Requires PHP 7.1 or higher.
    • Build Type: Does not support debug builds (use release builds for testing/running).
    • Rust Toolchain: The required Rust version is specified in the repository's rust-toolchain.toml file.
  10. Use the dogstatsd_client C API

    master

    The dogstatsd client allows you to send metrics to a DogStatsD server.

    Lifecycle:

    1. Resolve Address: Use dogstatsd_client_getaddrinfo to resolve the host and port. The client takes responsibility for calling freeaddrinfo later.
    2. Initialize: Create a client using dogstatsd_client_ctor. You must provide a buffer of size DOGSTATSD_CLIENT_RECOMMENDED_MAX_MESSAGE_SIZE. You can also provide const_tags which will be automatically attached to every metric sent by this client.
    3. Send Metrics: Use functions like dogstatsd_client_count to increment metrics. Tags can be specific to the metric or NULL/empty string.
    4. Cleanup: Always call dogstatsd_client_dtor to clean up the client and the address info. Note that the dtor does not free the buffer or the constant tags provided during construction.
    char buf[DOGSTATSD_CLIENT_RECOMMENDED_MAX_MESSAGE_SIZE];
    size_t len = DOGSTATSD_CLIENT_RECOMMENDED_MAX_MESSAGE_SIZE;
    int error;
    struct addrinfo *addrs = NULL;
    
    // 1. Resolve address
    if ((error = dogstatsd_client_getaddrinfo(&addrs, "localhost", "8125"))) {
      fprintf(stderr, "Failed: %s\n", (error == EAI_SYSTEM) ? strerror(errno) : gai_strerror(error));
    } else {
      // 2. Initialize client with constant tags
      dogstatsd_client client = dogstatsd_client_ctor(addrs, buf, len, "lang:php");
    
      // 3. Increment a metric
      dogstatsd_client_count(&client, "datadog.tracer.uncaught_exceptions", "1", "class:sigsegv");
    
      // 4. Cleanup
      dogstatsd_client_dtor(&client);
    }