Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Statsd Laravel Package

m6web/statsd

Simple StatsD client for PHP. Send counters, gauges, timers and sets to a StatsD/Graphite backend with minimal overhead. Designed for easy integration and straightforward API to instrument apps and collect metrics.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require m6web/statsd
    

    Add to config/app.php under providers:

    M6Web\Statsd\StatsdServiceProvider::class,
    

    Publish config (optional):

    php artisan vendor:publish --provider="M6Web\Statsd\StatsdServiceProvider" --tag=config
    
  2. Basic Configuration Edit .env:

    STATSD_HOST=localhost
    STATSD_PORT=8125
    STATSD_PREFIX=myapp.
    

    Or configure via config/statsd.php.

  3. First Usage Inject the Statsd facade or service:

    use M6Web\Statsd\Facades\Statsd;
    
    // Increment a counter
    Statsd::increment('user.signups');
    
    // Record a timing (in milliseconds)
    Statsd::timing('user.signup.time', 150);
    
  4. Quick Wins

    • Use Statsd::gauge() for real-time metrics (e.g., active users).
    • Leverage Statsd::histogram() for distributions (e.g., request latency).
    • Tag metrics with Statsd::withTags() for dimensional analysis:
      Statsd::withTags(['env' => 'production'])->increment('api.calls');
      

Implementation Patterns

Core Workflows

  1. Request Metrics

    // Middleware: Track request duration
    public function handle($request, Closure $next) {
        $start = microtime(true);
        $response = $next($request);
        Statsd::timing('http.requests', (microtime(true) - $start) * 1000);
        return $response;
    }
    
  2. Database Query Tracking

    // Log query execution time
    DB::listen(function ($query) {
        Statsd::timing('db.queries', $query->time * 1000);
        Statsd::increment('db.queries.total');
    });
    
  3. Event-Based Metrics

    // Track failed jobs
    FailedJob::failed(function ($job, $exception) {
        Statsd::increment('jobs.failed');
        Statsd::histogram('jobs.duration', $job->attempts * 100);
    });
    
  4. Service Layer Instrumentation

    // Track API call success/failure
    public function fetchData() {
        try {
            $data = Http::get('https://api.example.com/data');
            Statsd::increment('api.calls.success');
            return $data;
        } catch (\Exception $e) {
            Statsd::increment('api.calls.failure');
            throw $e;
        }
    }
    

Integration Tips

  • Laravel Scheduler: Track cron job durations:
    $schedule->command('backup:run')->everyMinute()->then(function () {
        Statsd::timing('cron.backup', 1000); // Example: 1s duration
    });
    
  • Queue Workers: Monitor job processing:
    // In worker bootstrap
    Statsd::increment('queue.workers.active');
    
  • Health Checks: Expose metrics via /metrics endpoint:
    Route::get('/metrics', function () {
        return Statsd::getMetrics(); // If supported by the package
    });
    

Advanced Patterns

  1. Dynamic Naming with Context
    Statsd::withTags(['user_id' => auth()->id()])->increment('user.actions');
    
  2. Conditional Metrics
    if ($user->isPremium()) {
        Statsd::increment('premium.user.actions');
    }
    
  3. Batched Metrics
    // For high-volume events (e.g., logs)
    Statsd::batch(function () {
        Statsd::increment('logs.processed');
        Statsd::timing('log.processing', 50);
    });
    

Gotchas and Tips

Common Pitfalls

  1. Prefix Collisions

    • Ensure STATSD_PREFIX is unique to avoid mixing metrics with other services.
    • Example: myapp.users. vs. otherapp.users..
  2. Timing Granularity

    • StatsD expects milliseconds for timings. Convert microseconds:
      Statsd::timing('request.time', (microtime(true) - $start) * 1000);
      
  3. Tag Limits

    • StatsD has a 400-byte limit for metric names + tags. Avoid excessive tagging:
      // Bad: Too many tags
      Statsd::withTags(['a' => 'long_value', 'b' => 'another_long_value'])->increment('metric');
      
      // Good: Short, meaningful tags
      Statsd::withTags(['env' => 'prod', 'type' => 'api'])->increment('calls');
      
  4. Connection Issues

    • If StatsD is unreachable, metrics are dropped silently. Implement a fallback:
      try {
          Statsd::increment('fallback.test');
      } catch (\Exception $e) {
          Log::warning('StatsD unavailable, metric dropped', ['exception' => $e]);
      }
      
  5. Rate Limiting

    • High-frequency metrics (e.g., loop.iterations) may overwhelm StatsD. Use sampling:
      if (rand(1, 100) <= 10) { // 10% sample
          Statsd::increment('loop.iterations');
      }
      

Debugging Tips

  1. Verify Metrics Use statsd-nozzle or graphite-statsd to inspect incoming metrics:

    docker run -p 8126:8126 hopsoft/statsd-nozzle
    

    Then query http://localhost:8126/.

  2. Check Config Validate .env/config/statsd.php:

    // Test connection
    $client = Statsd::getClient();
    $client->ping(); // If supported
    
  3. Log Unsent Metrics Override the client to log drops:

    Statsd::extend(function ($statsd) {
        $originalFlush = $statsd->getClient()->flush;
        $statsd->getClient()->flush = function () use ($originalFlush) {
            Log::debug('Flushing metrics', ['queue' => $this->getClient()->getQueue()]);
            $originalFlush();
        };
    });
    

Extension Points

  1. Custom Metric Types Extend the Statsd facade to add domain-specific methods:

    Statsd::extend(function ($statsd) {
        $statsd->trackPayment = function ($amount, $status) {
            Statsd::gauge('payments.amount', $amount);
            Statsd::increment("payments.status.{$status}");
        };
    });
    
  2. Contextual Metrics Attach request/user context automatically:

    Statsd::macro('withRequestContext', function () {
        return $this->withTags([
            'request_id' => request()->header('X-Request-ID'),
            'user_id' => auth()->id(),
            'route' => request()->route()->getName(),
        ]);
    });
    
  3. Async Flushing For high-throughput apps, flush metrics asynchronously:

    Statsd::getClient()->setAsync(true);
    
  4. Metric Sanitization Prevent invalid characters in metric names:

    Statsd::macro('safeIncrement', function ($name) {
        $sanitized = preg_replace('/[^a-zA-Z0-9._-]/', '_', $name);
        $this->increment($sanitized);
    });
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor