christian98/datadog-laravel

This package provides a neat way to interact with the official Datadog PHP SDK.

Installs: 1 909

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Forks: 0

pkg:composer/christian98/datadog-laravel

v4.1.0 2025-10-24 12:36 UTC

README

pipeline status coverage report Latest Release Packagist Downloads Packagist Version Packagist License

This package provides seamless integration with the official Datadog PHP SDK, allowing you to easily monitor and report metrics, service checks, and events from your Laravel applications with a fluent, Laravel-style API.

Features

  • Custom Metrics: Track metrics with support for gauge, histogram, distribution, count, increment/decrement, set, timing, and micro-timing.
  • Service Checks: Send detailed service health checks to Datadog.
  • Events: Push application events with priority and alert types.
  • Timers: Measure execution time via built-in timers with start/stop functionality.
  • Automatic Laravel Integrations:
    • Database query execution time metric (automatically tracked in production).
    • HTTP response time metric (automatically tracked in production).
    • Custom event dispatching (automatically forwards Laravel events implementing DispatchDatadogEvent).
  • Trait Support: Use InteractsWithDatadog trait for easy access to the Datadog client in your classes.
  • Testing Support: Includes a fake client for testing without real data submission, with assertion methods.
  • Fluent API: Method chaining for all operations following Laravel conventions.

Requirements

  • PHP: ^8.1.0
  • Laravel: ^10 || ^11 || ^12
  • Datadog PHP SDK: >=1.5.3

Installation

  1. Install the package
    Using Composer:

    composer require christian98/datadog-laravel
    
  2. Publish the Config File
    Publish the configuration file to customize Datadog settings:

    php artisan vendor:publish --provider="DatadogLaravel\DatadogLaravel\DatadogLaravelServiceProvider" --tag=config
    

    This will create a config/datadog.php file in your project.

  3. Add Environment Variables
    Update .env to include your Datadog configuration:

    DATADOG_STATSD_HOST=127.0.0.1
    DATADOG_STATSD_PORT=8125
    DATADOG_API_HOST=https://api.datadoghq.com
    DATADOG_API_KEY=your-api-key
    DATADOG_APP_KEY=your-application-key
    
  4. Ready to Use
    The DatadogLaravelServiceProvider automatically registers built-in integrations for database query execution time and HTTP response time in production mode. You can begin using the Datadog facade to interact with Datadog.

Usage

1. Metrics

The package supports all Datadog metric types with a fluent, chainable API.

Gauge

Track a value that can increase or decrease:

use DatadogLaravel\DatadogLaravel\Datadog;

Datadog::makeMetric('app.active_users')
    ->withTag('env', 'production')
    ->withTag('service', 'api')
    ->reportGauge(120);

Count

Update a counter by an arbitrary amount:

Datadog::makeMetric('app.page_views')
    ->withTags(['page' => 'home', 'device' => 'mobile'])
    ->reportCount(5); // Increment by 5

Increment / Decrement

Increment or decrement a counter:

// Increment by 1 (default)
Datadog::makeMetric('app.requests')
    ->reportIncrement();

// Increment by custom amount
Datadog::makeMetric('app.requests')
    ->reportIncrement(10);

// Decrement
Datadog::makeMetric('app.active_connections')
    ->reportDecrement(2);

Histogram

Sample statistical distribution of values:

Datadog::makeMetric('app.upload_size')
    ->withTag('type', 'image')
    ->reportHistogram(2048.5); // Size in KB

Distribution

Track the statistical distribution of a set of values across your infrastructure:

Datadog::makeMetric('app.latency')
    ->reportDistribution(3.5); // Value in seconds

Set

Count unique occurrences of a value:

Datadog::makeMetric('app.unique_visitors')
    ->reportSet('user_123'); // Can be string or float

Timing

Record timing in milliseconds:

Datadog::makeMetric('api.response_time')
    ->withTags(['method' => 'GET', 'status' => '200'])
    ->reportTiming(150); // Value in milliseconds

Micro-Timing

Record timing in seconds (with microsecond precision):

Datadog::makeMetric('job.execution_time')
    ->reportMicroTiming(2.456); // Value in seconds

Sample Rate

Control how frequently metrics are sent (useful for high-volume metrics):

Datadog::makeMetric('high.frequency.metric')
    ->withSampleRate(0.1) // Send only 10% of samples
    ->reportIncrement();

2. Timers

The package includes a built-in timer for measuring operation durations:

Basic Timer Usage

$timer = Datadog::makeMetric('job.processing_time')->timer();

$timer->start();

// Your code to measure
processJob();

$timer->stopAndReport(); // Automatically reports elapsed time in seconds

Manual Timer Control

$timer = Datadog::makeMetric('task.duration')->timer();

$timer->start();
performTask();
$timer->stop();

// Do something else...

$timer->report(); // Manually report the measured time

Timer Reset

$timer = Datadog::makeMetric('loop.iteration')->timer();

for ($i = 0; $i < 10; $i++) {
    $timer->start();
    doWork();
    $timer->stopAndReport();
    $timer->reset(); // Reset for next iteration
}

3. Service Checks

Service checks allow you to report the status of various services with four status levels:

use DatadogLaravel\DatadogLaravel\Datadog;
use DatadogLaravel\DatadogLaravel\Support\ServiceChecks\ServiceCheckStatus;

// Report OK status
Datadog::makeServiceCheck('database.connection')
    ->withTag('database', 'primary')
    ->withMessage('Connection is healthy')
    ->reportOk();

// Report Warning
Datadog::makeServiceCheck('cache.connection')
    ->withMessage('High latency detected')
    ->reportWarn();

// Report Critical
Datadog::makeServiceCheck('payment.gateway')
    ->withTag('provider', 'stripe')
    ->withMessage('Gateway unreachable')
    ->reportCritical();

// Report Unknown
Datadog::makeServiceCheck('external.api')
    ->reportUnknown();

// Custom status using report() method
Datadog::makeServiceCheck('custom.service')
    ->report(ServiceCheckStatus::Ok);

4. Events

Push detailed application events to Datadog with customizable metadata:

Basic Event

use DatadogLaravel\DatadogLaravel\Datadog;

Datadog::makeEvent('Deployment Started', 'Version 2.0.0 is being deployed')
    ->withTag('version', '2.0.0')
    ->withTag('environment', 'production')
    ->report();

Event with Alert Type

use DatadogLaravel\DatadogLaravel\Support\Events\AlertType;

// Using enum
Datadog::makeEvent('Error Occurred', 'Database connection failed')
    ->withAlertType(AlertType::Error)
    ->withTag('service', 'api')
    ->report();

// Using convenience methods
Datadog::makeEvent('Success', 'Deployment completed')
    ->asSuccess()
    ->report();

Datadog::makeEvent('Warning', 'High memory usage detected')
    ->asWarning()
    ->report();

Datadog::makeEvent('Info', 'Cache cleared')
    ->asInfo()
    ->report();

Datadog::makeEvent('Critical Error', 'Payment processing failed')
    ->asError()
    ->report();

Event with Aggregation Key

Group related events together:

Datadog::makeEvent('Build Failed', 'Unit tests failed')
    ->withAggregationKey('build-pipeline-123')
    ->asError()
    ->report();

5. Built-in Laravel Integrations

The package automatically registers several integrations in production mode only.

Database Query Execution Time

Automatically tracks the duration of all database queries:

  • Metric Name: db.query
  • Tags: status:executed
  • Type: Timing (milliseconds)

This integration is automatically enabled and will report every database query execution time.

HTTP Response Time

Measures the time from the request's start until the response:

  • Metric Name: response_time
  • Tags:
    • code: HTTP status code (e.g., 200, 404)
    • method: HTTP method (e.g., GET, POST)
  • Type: Micro-timing (seconds)

This integration uses the LARAVEL_START constant, so ensure it's defined in your public/index.php.

Custom Laravel Events to Datadog

Automatically forwards Laravel events to Datadog. Any Laravel event that implements the DispatchDatadogEvent interface will be automatically sent to Datadog.

Create a custom event:

use DatadogLaravel\DatadogLaravel\Support\Events\DispatchDatadogEvent;
use DatadogLaravel\DatadogLaravel\Support\Events\Event;
use DatadogLaravel\DatadogLaravel\Datadog;

class UserRegistered implements DispatchDatadogEvent
{
    public function __construct(public int $userId)
    {
    }

    public function toDatadogEvent(): Event
    {
        return Datadog::makeEvent('User Registered', "User {$this->userId} has registered")
            ->withTag('user_id', (string) $this->userId)
            ->asSuccess();
    }
}

Dispatch the event:

event(new UserRegistered(123));
// This will automatically be sent to Datadog

6. InteractsWithDatadog Trait

Use this trait in any class to get easy access to the Datadog client:

use DatadogLaravel\DatadogLaravel\Support\InteractsWithDatadog;

class MyService
{
    use InteractsWithDatadog;

    public function performAction()
    {
        // Access the raw Datadog client
        $this->datadog()->increment('my.custom.metric');
        
        // Or use the facade
        Datadog::makeMetric('my.metric')->reportIncrement();
    }
}

7. Tags

All metrics, service checks, and events support tags for better organization and filtering:

Single Tag

Datadog::makeMetric('app.requests')
    ->withTag('environment', 'production')
    ->reportIncrement();

Multiple Tags

Datadog::makeMetric('app.requests')
    ->withTags([
        'environment' => 'production',
        'service' => 'api',
        'region' => 'eu-west-1',
    ])
    ->reportIncrement();

Chaining Tags

Datadog::makeMetric('app.requests')
    ->withTag('environment', 'production')
    ->withTag('service', 'api')
    ->withTag('version', 'v2')
    ->reportIncrement();

Configuration

The config/datadog.php file provides extensive configuration options:

return [
    'statsd' => [
        'host' => env('DATADOG_STATSD_HOST', '127.0.0.1'),
        'port' => env('DATADOG_STATSD_PORT', 8125),
        'socket_path' => env('DATADOG_STATSD_SOCKET_PATH', null),
    ],
    
    'api' => [
        'host' => env('DATADOG_API_HOST', 'https://api.datadoghq.com'),
        'api_key' => env('DATADOG_API_KEY'),
        'application_key' => env('DATADOG_APP_KEY'),
    ],
    
    'global_tags' => [
        // Tags applied to all metrics/events
        'env' => env('APP_ENV'),
        'service' => env('APP_NAME'),
    ],
    
    'metric_prefix' => env('DATADOG_METRIC_PREFIX', ''),
];

Configuration Options

  • statsd.host: The hostname or IP of your Datadog agent (default: 127.0.0.1)
  • statsd.port: The port for StatsD communication (default: 8125)
  • statsd.socket_path: Unix socket path (alternative to host/port)
  • api.host: Datadog API endpoint
  • api.api_key: Your Datadog API key (required for events)
  • api.application_key: Your Datadog application key (required for events)
  • global_tags: Tags automatically applied to all metrics, service checks, and events
  • metric_prefix: Prefix added to all metric names

Testing

The package provides comprehensive testing support with a fake client and assertion methods.

Using the Fake Client

use DatadogLaravel\DatadogLaravel\Datadog;
use DatadogLaravel\DatadogLaravel\Support\ServiceChecks\ServiceCheckStatus;

class MyTest extends TestCase
{
    public function test_metric_is_reported()
    {
        // Replace Datadog client with fake
        $fake = Datadog::fake();
        
        // Execute code that reports metrics
        Datadog::makeMetric('test.metric')
            ->withTag('env', 'testing')
            ->reportGauge(42);
        
        // Assert the metric was reported
        $this->assertTrue(
            $fake->reportedMetric(
                'test.metric',
                \DatadogLaravel\DatadogLaravel\Testing\MetricType::Gauge,
                42,
                1.0,
                ['env' => 'testing']
            )
        );
    }
    
    public function test_service_check_is_reported()
    {
        $fake = Datadog::fake();
        
        Datadog::makeServiceCheck('my.service')
            ->withMessage('Service is healthy')
            ->reportOk();
        
        $fake->assertServiceCheckReported(
            'my.service',
            ServiceCheckStatus::Ok,
            null,
            null,
            'Service is healthy'
        );
    }
    
    public function test_event_is_reported()
    {
        $fake = Datadog::fake();
        
        Datadog::makeEvent('Test Event', 'Event description')
            ->withTag('test', 'true')
            ->report();
        
        $fake->assertEventReported('Test Event', [
            'text' => 'Event description',
            'tags' => ['test' => 'true'],
            // ... other event properties
        ]);
    }
}

Assertion Methods

The FakeDatadogClient provides several assertion methods:

  • assertReportedDistribution(string $stat, ?float $value, ?float $sampleRate, null|array|string $tags)
  • assertServiceCheckReported(string $name, ServiceCheckStatus $status, array|string|null $tags, ?string $hostname, ?string $message, ?int $timestamp)
  • assertEventReported(string $title, array $vals)
  • reportedMetric(string $stat, MetricType $type, ?float $value, ?float $sampleRate, null|array|string $tags): bool

Advanced Usage

Creating Custom Registerable Metrics

You can create custom metric classes that implement the Registerable interface:

use DatadogLaravel\DatadogLaravel\Datadog;
use DatadogLaravel\DatadogLaravel\Support\Collector;
use Illuminate\Support\Facades\Event;

class CustomMetric implements Collector
{
    public function register(): void
    {
        Event::listen(MyEvent::class, function (MyEvent $event) {
            Datadog::makeMetric('my.custom.metric')
                ->withTag('type', $event->type)
                ->reportIncrement();
        });
    }
}

Register it in your service provider:

public function boot()
{
    resolve(CustomMetric::class)->register();
}

Direct Access to DogStatsd Client

If you need direct access to the underlying DogStatsd client:

use DataDog\DogStatsd;

$client = app(DogStatsd::class);
$client->increment('my.metric');

Development and Contribution

Development Tools

  • Run Tests:

    composer test
    
  • Run Tests with Coverage:

    composer test:ci
    
  • Static Analysis:

    composer phpstan
    
  • Fix Code Style:

    composer cs-fix
    
  • Check Code Style:

    composer phpcs
    

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new features
  4. Ensure all tests pass
  5. Submit a pull request

Support

If you encounter an issue or have a feature request, please open an issue on the GitLab Repository.

License

This package is MIT-licensed. See the LICENSE file for more details.

It is also Treeware. If you use this package in production, we ask that you plant a tree to support sustainability efforts. 🌳

Credits

Happy Monitoring! 🚀