datadog/php-datadogstatsd
DogStatsD client for PHP from Datadog. Send metrics, events, and service checks to the Datadog Agent via UDP or UDS, with support for tags, sampling, buffering, and namespacing. Useful for instrumenting PHP apps and services.
Installation
composer require datadog/php-datadogstatsd
Add to composer.json if using a custom package name (e.g., datadog/datadog-statsd).
Basic Initialization
use Datadog\Statsd\DogStatsd;
$statsd = new DogStatsd([
'host' => 'your-dogstatsd-host', // e.g., 'localhost' or 'statsd.example.com'
'port' => 8125, // Default DogStatsd port
'prefix' => 'myapp.', // Optional prefix for metrics
]);
First Use Case: Incrementing a Counter
$statsd->increment('user.signups'); // Tracks "user.signups" metric
Where to Look First
src/DogStatsd.php for core methods (increment(), gauge(), histogram(), etc.).src/Transport/UdpTransport.php for debugging connection issues and error handling.Metric Types
auth.failed).
$statsd->increment('auth.failed');
$statsd->decrement('auth.success');
queue.size).
$statsd->gauge('queue.size', 42);
$statsd->timer('api.request', 150); // Milliseconds
$statsd->histogram('api.response_size', 1024);
active_users).
$statsd->set('active_users', ['user123', 'user456']);
Tagging Metrics
$statsd->increment('user.signups', 1, ['source' => 'web', 'region' => 'us-west']);
Batching and Async
$statsd = new DogStatsd([...], ['async' => true]);
$statsd->flush();
Integration with Laravel
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->singleton(DogStatsd::class, function ($app) {
return new DogStatsd([
'host' => config('datadog.statsd.host'),
'prefix' => config('datadog.statsd.prefix'),
]);
});
}
// app/Http/Middleware/LogRequestTime.php
public function handle($request, Closure $next)
{
$start = microtime(true);
$response = $next($request);
$statsd = app(DogStatsd::class);
$statsd->timer('http.request', (microtime(true) - $start) * 1000);
return $response;
}
Error Handling
try {
$statsd->increment('critical.operation');
// Risky operation...
} catch (\Exception $e) {
$statsd->increment('critical.operation.failed');
throw $e;
}
Connection Issues
host/port in config (default: localhost:8125).$statsd = new DogStatsd([...], [
'errorHandler' => function (\Throwable $error) {
\Log::error("DogStatsd socket error: " . $error->getMessage());
// Optionally notify monitoring systems or retry logic
}
]);
UdpTransport:
$statsd = new DogStatsd([...], [
'transport' => new \Datadog\Statsd\Transport\UdpTransport($socket, true)
]);
Metric Naming Collisions
prefix and validate with:
$statsd->setPrefix('app.'); // Ensure consistency
Async Mode Quirks
flush() before critical sections (e.g., app shutdown).Sampling
maxPacketSize.Tag Limits
env:prod instead of environment:production).Enable Verbose Logging
$statsd = new DogStatsd([...], [
'transport' => new \Datadog\Statsd\Transport\UdpTransport($socket, true, true) // Enable debug
]);
Test Locally with dd-agent
docker run -p 8125:8125/udp datadog/agent:latest
nc -ul 8125 to inspect raw UDP traffic.Validate Metrics in Datadog
prefix (e.g., myapp.*).Custom Transport
Datadog\Statsd\Transport\TransportInterface for non-UDP backends (e.g., HTTP):
class HttpTransport implements TransportInterface {
public function send($data) {
file_put_contents('http://statsd-endpoint', $data);
}
}
DogStatsd:
$statsd = new DogStatsd([...], ['transport' => new HttpTransport()]);
Custom Error Handling
$statsd = new DogStatsd([...], [
'errorHandler' => function (\Throwable $error) {
\Sentry\captureException($error); // Example: Send to Sentry
// Or: \App\Services\Monitoring::alert($error);
}
]);
UdpTransport for most use cases.Metric Sanitization
sanitizeMetricName() to enforce naming conventions:
$statsd = new DogStatsd([...]);
$statsd->sanitizeMetricName = function ($name) {
return strtolower(preg_replace('/[^a-z0-9._]/', '_', $name));
};
Contextual Metrics
$statsd->increment('user.action', 1, [
'user_id' => auth()->id(),
'request_id' => request()->header('X-Request-ID'),
]);
Rate Limiting
$statsd->setRateLimit(1000); // Max 1000 metrics/sec
How can I help you explore Laravel packages today?