DEV Community

Zarmin
Zarmin

Posted on

Datadog PHP APM filtering

A client needed a solution to filter PHP APM traces before sending them to the Datadog server to reduce ingestion fees.

The filter rules were to exclude everything except requests exceeding 1 second and errors (HTTP code >= 400, exceptions, PHP errors).

They still wanted to utilize automatic instrumentation for several libraries (e.g., Laravel, Curl, PDO).

(The client is still using PHP 7.4, which is end-of-life; I know - they will upgrade to 8.x later.)

This auto-prepend script will filter out the specified request traces (returning from the function will retain the trace).

<?php

// dd-filter.php

register_shutdown_function(function() {
  // config
  $TIME_LIMIT_SEC = 1.0;

  // exit if Datadog (DDTrace) is NOT loaded
  if (!class_exists('\DDTrace\GlobalTracer') || !class_exists('\DDTrace\Tag')) {
    return;
  }

  // get HTTP status code
  $httpResponseCode = http_response_code();
  if ($httpResponseCode >= 400) {
    return; // keep DD trace
  }

  // is the script exited with an error?
  $lastError = error_get_last();
  if ($lastError) {
    return; // keep DD trace
  }

  // get current request time
  if (empty($_SERVER['REQUEST_TIME_FLOAT'])) {
    return; // keep DD trace 
  }
  $startTime = $_SERVER['REQUEST_TIME_FLOAT'];
  $currentTime = microtime(true);
  $elapsedTime = max($currentTime - $startTime, 0.0);

  if ($elapsedTime > $TIME_LIMIT_SEC) {
    return; // keep DD trace
  }

  // drop DD trace
  $tracer = \DDTrace\GlobalTracer::get();
  $span = $tracer->getActiveSpan();
  if (null !== $span) {
    $span->setTag(\DDTrace\Tag::MANUAL_DROP, true);
  }
});
Enter fullscreen mode Exit fullscreen mode

(Yes, I know it would be better if the configuration, for example, TIME_LIMIT_SEC, were kept in a separate file.)

This can be set up in the following way:

  • Place this script to /etc/php/7.4/datadog-filter/dd-filter.php
  • Set the script for auto-prepending in /etc/php/7.4/fpm/php.ini: auto_prepend_file = /etc/php/7.4/datadog-filter/dd-filter.php
  • Restart PHP-FPM: systemctl restart php7.4-fpm

(The client is using their app on a Debian 12 Linux VM.)

Top comments (0)