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.)

Do your career a favor. Join DEV. (The website you're on right now)

It takes one minute and it's free.

Get started

Top comments (0)

Heroku

This site is powered by Heroku

Heroku was created by developers, for developers. Get started today and find out why Heroku has been the platform of choice for brands like DEV for over a decade.

Sign Up

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay