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

Metrics Laravel Package

directorytree/metrics

Record and query metrics in Laravel with a simple, elegant API. Track page views, API calls, signups, and other events with optional values, categories, dates, hourly buckets, model-scoped metrics, and custom attributes. Supports Redis and extensible drivers.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require directorytree/metrics
    php artisan vendor:publish --tag="metrics-migrations"
    php artisan migrate
    

    Publish config (optional):

    php artisan vendor:publish --tag="metrics-config"
    
  2. First Use Case: Track a simple event (e.g., page views):

    use DirectoryTree\Metrics\Facades\Metrics;
    
    Metrics::record(new \DirectoryTree\Metrics\MetricData('page_views'));
    

    Or use the helper:

    metric('page_views')->record();
    
  3. Where to Look First:

    • Facade/Helper: Metrics facade or metric() helper for recording.
    • Query Builder: Metric model for querying (e.g., Metric::today()->sum('value')).
    • Config: config/metrics.php for driver/queue settings.

Implementation Patterns

Core Workflows

  1. Event Tracking:

    • Use middleware or service providers to auto-record metrics for routes/APIs:
      // app/Http/Middleware/TrackPageViews.php
      public function handle(Request $request, Closure $next) {
          metric('page_views')->record();
          return $next($request);
      }
      
  2. Model-Based Metrics:

    • Attach metrics to Eloquent models (e.g., track user activity):
      class User extends Model {
          use \DirectoryTree\Metrics\HasMetrics;
      }
      // Record:
      metric('user_logins')->measurable($user)->record();
      // Query:
      $user->metrics()->where('name', 'user_logins')->sum('value');
      
  3. Batch Processing:

    • Use capture()/commit() for bulk operations (e.g., imports):
      Metrics::capture();
      foreach ($data as $item) {
          metric('imported_items')->record();
      }
      Metrics::commit(); // Single DB write
      
  4. Hourly Granularity:

    • Enable for time-sensitive metrics (e.g., real-time dashboards):
      metric('api_calls')->hourly()->record();
      // Query:
      Metric::thisHour()->where('name', 'api_calls')->sum('value');
      
  5. Custom Attributes:

    • Segment metrics by context (e.g., traffic sources):
      metric('signups')->with(['source' => 'campaign_a'])->record();
      // Query:
      Metric::where('name', 'signups')->where('source', 'campaign_a')->sum('value');
      

Integration Tips

  • Redis Driver: For high-traffic apps, use Redis to batch-commit metrics:

    // config/metrics.php
    'driver' => 'redis',
    'auto_commit' => false,
    

    Schedule the commit command:

    // app/Console/Kernel.php
    $schedule->command('metrics:commit')->hourly();
    
  • Observers: Auto-record metrics on model events:

    class UserObserver {
        public function created(User $user) {
            metric('user_creations')->record();
        }
    }
    
  • Laravel Events: Dispatch events and listen for metrics:

    event(new UserRegistered($user));
    // In listener:
    metric('user_registrations')->record();
    

Gotchas and Tips

Pitfalls

  1. Hourly Metrics Overuse:

    • Hourly metrics create 24x more rows than daily. Reserve for critical time-sensitive data.
    • Fix: Use daily metrics by default; enable hourly only when needed.
  2. Custom Attributes Uniqueness:

    • Metrics with identical name + attributes are merged. Oversight can lead to incorrect aggregations.
    • Fix: Explicitly define attributes when segmenting:
      metric('views')->with(['source' => 'google'])->record();
      
  3. Redis TTL Misconfiguration:

    • Default Redis TTL is 1 day. If metrics:commit fails, metrics may be lost.
    • Fix: Monitor the command and adjust TTL in config:
      'redis_ttl' => 86400, // 1 day in seconds
      
  4. Model Metrics Performance:

    • Querying metrics for many models (e.g., User::all()->metrics()) triggers N+1 queries.
    • Fix: Use eager loading:
      $users = User::withMetrics()->get();
      
  5. Auto-Commit Conflicts:

    • Enabling both auto_commit and Redis driver may cause duplicate entries.
    • Fix: Disable auto_commit when using Redis:
      'auto_commit' => env('METRICS_DRIVER') === 'redis' ? false : true,
      

Debugging

  • Missing Metrics:

    • Check if capture() is active (metrics won’t persist without it).
    • Verify the driver is configured correctly in config/metrics.php.
  • Query Issues:

    • Use Metric::toSql() to debug complex queries:
      $query = Metric::thisMonth()->where('name', 'signups');
      dd($query->toSql(), $query->getBindings());
      
  • Redis Stuck Metrics:

    • Manually trigger commit:
      php artisan metrics:commit --force
      

Extension Points

  1. Custom Metric Models:

    • Extend the Metric model to add scopes or accessors:
      class CustomMetric extends \DirectoryTree\Metrics\Metric {
          public function scopeActive($query) {
              return $query->where('value', '>', 0);
          }
      }
      
  2. Metric Repository:

    • Override the repository for custom storage logic:
      // config/metrics.php
      'repository' => \App\Repositories\CustomMetricRepository::class,
      
  3. Metric Manager:

    • Replace the manager to modify recording behavior:
      // config/metrics.php
      'manager' => \App\Services\CustomMetricManager::class,
      
  4. Attribute Validation:

    • Add validation to custom attributes in a service provider:
      Metrics::extend(function ($manager) {
          $manager->validating(function ($data) {
              if ($data->has('country')) {
                  $data->set('country', strtoupper($data->get('country')));
              }
          });
      });
      

Performance Tips

  • Batch Recording: Use capture()/commit() for bulk operations (e.g., imports).
  • Indexing: Add indexes to frequently queried attributes:
    Schema::table('metrics', function (Blueprint $table) {
        $table->index(['name', 'category', 'year', 'month', 'day']);
    });
    
  • Hourly Metrics: Avoid querying hourly metrics unless necessary (high storage overhead).
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.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle