adgoal/statsd-client-bundle
Symfony bundle for monitoring via StatsD/Graphite using statsd-php-client. Provides a StatsD service/factory, Monolog handler, metric collectors (visitors, auth, SQL verbs, memory), and CLI commands to aggregate and flush metrics.
Installation:
composer require liuggio/statsd-client-bundle
Add to config/bundles.php:
return [
// ...
Liuggio\StatsDClientBundle\LiuggioStatsDClientBundle::class => ['all' => true],
];
Configure (config/packages/liuggio_statsd_client.yaml):
liuggio_statsd_client:
host: 'localhost'
port: 8125
prefix: 'app.'
First Use Case: Inject the client in a controller/service and send a metric:
use Liuggio\StatsDClientBundle\StatsD\StatsDInterface;
public function index(StatsDInterface $statsd)
{
$statsd->increment('user.visits');
$statsd->flush();
}
statsd (autowired via DIC).monolog bundle is present.statsd:flush to manually trigger flushes.Metric Collection:
auth.attempts).
$statsd->increment('auth.attempts');
$statsd->decrement('auth.failures');
api.response.time).
$statsd->timing('api.response.time', 150); // 150ms
queue.size).
$statsd->gauge('queue.size', 42);
active.users).
$statsd->set('active.users', ['user1', 'user2']);
Contextual Metrics:
Use the prefix config to namespace metrics (e.g., app.user.visits).
Override dynamically:
$statsd->setPrefix('debug.');
$statsd->increment('memory.usage');
Monolog Integration:
Auto-sends log levels as metrics (configurable in monolog.yaml):
handlers:
statsd:
type: service
id: liuggio_statsd_client.handler.statsd
level: debug
Collectors:
Aggregate custom data (e.g., database queries, HTTP requests) via Collector services.
Example: Track slow queries:
$collector = $this->get('liuggio_statsd_client.collector.query');
$collector->collect('SELECT * FROM users', 250); // 250ms
CLI Usage: Flush pending metrics:
php bin/console statsd:flush
Test connectivity:
php bin/console statsd:ping
Middleware: Log request metrics (e.g., response time) in middleware:
public function handle(Request $request, Closure $next, StatsDInterface $statsd)
{
$start = microtime(true);
$response = $next($request);
$statsd->timing('http.response.time', (microtime(true) - $start) * 1000);
return $response;
}
Event Listeners: Track business events (e.g., order.created):
public function onOrderCreated(OrderCreatedEvent $event, StatsDInterface $statsd)
{
$statsd->increment('orders.created');
}
Background Jobs: Use collectors to monitor queue workers:
$collector = $this->get('liuggio_statsd_client.collector.job');
$collector->collect('send_email', 300); // 300ms
Custom Sampling: Throttle metrics to avoid overload (e.g., sample 1% of requests):
if (rand(0, 99) < 1) {
$statsd->increment('sampled.requests');
}
Connection Issues:
host/port in config. Use statsd:ping to test connectivity.statsd_client channel:
monolog:
handlers:
statsd:
level: debug
Memory Leaks:
config/packages/liuggio_statsd_client.yaml:
auto_flush: true
flush_interval: 60 # seconds
flush() in long-running scripts or CLI commands.Metric Naming Collisions:
app.user vs. app.user.).app.user.visits vs. app.user_visits).Monolog Handler Quirks:
monolog bundle is enabled.monolog.yaml.debug).Collector Overhead:
collectors:
query: false
job: true
Enable StatsD Debugging:
liuggio_statsd_client:
debug: true
Logs connection attempts and metric payloads.
Inspect Payloads:
Use a local StatsD server (e.g., docker run -p 8125:8125/udp hopsoft/graphite-statsd) with a tool like Graphite to visualize metrics.
Common Errors:
Connection refused: StatsD server not running.Invalid metric name: Names must be alphanumeric + ./_ (no spaces/special chars).Flush timeout: Increase flush_timeout in config (default: 1s).Custom Collectors:
Extend Liuggio\StatsDClientBundle\Collector\AbstractCollector to create domain-specific collectors (e.g., CacheCollector):
class CacheCollector extends AbstractCollector
{
public function collect($key, $duration)
{
$this->statsd->timing('cache.' . $key, $duration);
}
}
Register as a service in services.yaml:
services:
App\Collector\CacheCollector:
arguments: ['@statsd']
tags: ['liuggio_statsd_client.collector']
Custom Metric Types: Extend the client to support non-StatsD metrics (e.g., histograms):
$statsd->histogram('api.latency', [100, 200, 300]); // Hypothetical
Requires modifying the underlying statsd-php-client or wrapping the service.
Dynamic Prefixes: Override prefixes per request for multi-tenant apps:
$statsd->setPrefix('tenant.' . $tenantId . '.');
Rate Limiting: Implement a decorator to throttle metrics:
$statsd->decorate(new RateLimitingDecorator($statsd, 1000)); // 1 metric/sec
Auto-Flush vs. Manual Flush:
auto_flush: true flushes metrics on shutdown (not ideal for CLI).flush() explicitly in CLI scripts or long-running processes.UDP Reliability: StatsD uses UDP (fire-and-forget). For critical metrics, implement a fallback (e.g., log to file + retry).
Environment-Specific Configs:
Override settings per environment (e.g., disable in test):
# config/packages/dev/liuggio_statsd_client.yaml
liuggio_statsd_client:
host: 'statsd.dev.example.com'
# config/packages/test/liuggio_statsd_client.yaml
liuggio_statsd_client:
enabled: false
How can I help you explore Laravel packages today?