PHPackages                             stechstudio/laravel-metrics - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Logging &amp; Monitoring](/categories/logging)
4. /
5. stechstudio/laravel-metrics

ActiveLibrary[Logging &amp; Monitoring](/categories/logging)

stechstudio/laravel-metrics
===========================

Easily track metrics from Laravel events, or on your own

2.11(3mo ago)50227.9k↓53%9[1 issues](https://github.com/stechstudio/laravel-metrics/issues)[1 PRs](https://github.com/stechstudio/laravel-metrics/pulls)MITPHPPHP ^8.2CI failing

Since Oct 23Pushed 3mo ago3 watchersCompare

[ Source](https://github.com/stechstudio/laravel-metrics)[ Packagist](https://packagist.org/packages/stechstudio/laravel-metrics)[ RSS](/packages/stechstudio-laravel-metrics/feed)WikiDiscussions master Synced 2d ago

READMEChangelog (10)Dependencies (19)Versions (47)Used By (0)

Laravel Metrics
===============

[](#laravel-metrics)

[![Latest Version on Packagist](https://camo.githubusercontent.com/48d1e8ffd8a601f2b65b5c5443c09f0d655238b4fb2f6df85cff44c1a384227a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f737465636873747564696f2f6c61726176656c2d6d6574726963732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/stechstudio/laravel-metrics)[![Total Downloads](https://camo.githubusercontent.com/d9c1744df247ae0a26b1e49102805eb49619d7ec512b6d61285b05d065544647/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f737465636873747564696f2f6c61726176656c2d6d6574726963732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/stechstudio/laravel-metrics)[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE.md)

This package makes it incredibly easy to ship app metrics to backends such as PostHog, InfluxDB or CloudWatch.

There are two major components: a facade that lets you create metrics on your own, and an event listener to automatically send metrics for Laravel events.

Installation
------------

[](#installation)

You know the drill...

```
composer require stechstudio/laravel-metrics

```

Backend configuration
---------------------

[](#backend-configuration)

### PostHog

[](#posthog)

1. Install the PostHog PHP client: `composer require posthog/posthog-php`
2. Add the following to your `.env` file:

```
METRICS_BACKEND=posthog
POSTHOG_API_KEY=...

```

### InfluxDB v1.7 and under

[](#influxdb-v17-and-under)

1. Install the InfluxDB PHP client: `composer require influxdb/influxdb-php`
2. Add the following to your `.env` file:

```
METRICS_BACKEND=influxdb
IDB_USERNAME=...
IDB_PASSWORD=...
IDB_HOST=...
IDB_DATABASE=...
IDB_VERSION=1 # Default

# Only if you are not using the default 8086
IDB_TCP_PORT=...

# If you want to send metrics over UDP instead of TCP
IDB_UDP_PORT=...

```

### InfluxDB V1.8 and above

[](#influxdb-v18-and-above)

1. Install the InfluxDB PHP client: `composer require influxdata/influxdb-client-php`
2. Add the following to your `.env` file:
3. In order to use UDP with InfluxDB V1.8+ you must follow extra [setup steps](https://github.com/influxdata/influxdb-client-php#writing-via-udp)

Add the following to your `.env` file:

```
METRICS_BACKEND=influxdb
IDB_TOKEN=...
IDB_DATABASE=... # Use the name of your desired bucket for this value
IDB_HOST=...
IDB_ORG=...
IDB_VERSION=2

# Only if you are not using the default 8086
IDB_TCP_PORT=...

# If you want to send metrics over UDP instead of TCP
IDB_UDP_PORT=...

```

### CloudWatch

[](#cloudwatch)

1. Install the AWS PHP SDK: `composer require aws/aws-sdk-php`.
2. Add the following to your `.env` file:

```
METRICS_BACKEND=cloudwatch
CLOUDWATCH_NAMESPACE=...

AWS_DEFAULT_REGION=...
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...

```

### Prometheus

[](#prometheus)

1. Install the Prometheus PHP client: `composer require promphp/prometheus_client_php`
2. Configuring the backend to use Prometheus, makes sense only if you have an endpoint to expose them. Its purpose is only to format the registered metrics in a way that Prometheus can scrape them.

```
METRICS_BACKEND=prometheus

```

### NullDriver (for development)

[](#nulldriver-for-development)

If you need to disable metrics just set the backend to null:

```
METRICS_BACKEND=null

```

This `null` driver will simply discard any metrics.

Sending an individual metric
----------------------------

[](#sending-an-individual-metric)

You can create metric by using the facade like this:

```
Metrics::create('order_placed')
    ->setValue(1)
    ->setTags([
        'source' => 'email-campaign',
        'user' => 54
    ]);
```

The only required attribute is the `name`, everything else is optional.

Driver mapping
--------------

[](#driver-mapping)

This is how we are mapping metric attributes in our backends.

Metric attributePostHogInfluxDBCloudWatchPrometheusnameeventmeasurementMetricNamenamevalueproperties\[value\]fields\[value\]Valuevalueunit*ignored**ignored*Unit*ignored*resolution*ignored**ignored*StorageResolution*ignored*tags*ignored*tagsDimensionskeys -&gt; labelNames
 values -&gt; labelValuesextrapropertiesfields*ignored**ignored*timestamp*ignored*timestampTimestamp*ignored*description*ignored**ignored**ignored*helpnamespace*ignored**ignored**ignored*namespacetype*ignored**ignored**ignored*used to register counter or gauge metricSee the [CloudWatch docs](http://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_MetricDatum.html)and [InfluxDB docs](https://docs.influxdata.com/influxdb/latest/concepts/key_concepts/) for more information on their respective data formats. Note we only do minimal validation, you are expected to know what data types and formats your backend supports for a given metric attribute.

Sending metrics from Laravel events
-----------------------------------

[](#sending-metrics-from-laravel-events)

The main motivation for this library was to send metrics automatically when certain events occur in a Laravel application. So this is where things really get fun!

Let's say you have a simple Laravel event called OrderReceived:

```
class OrderReceived {
    protected $order;

    public function __construct($order)
    {
        $this->order = $order;
    }
}
```

The first step is to implement an interface:

```
use STS\Metrics\Contracts\ShouldReportMetric;

class OrderReceived implements ShouldReportMetric {
```

This will tell the global event listener to send a metric for this event.

There are two different ways you can then provide the metric details.

### 1. Use the `ProvidesMetric` trait

[](#1-use-the-providesmetric-trait)

You can also include a trait that helps with building this metric:

```
use STS\Metrics\Contracts\ShouldReportMetric;
use STS\Metrics\Traits\ProvidesMetric;

class OrderReceived implements ShouldReportMetric {
    use ProvidesMetric;
```

In this case, the trait will build a metric called `order_received` (taken from the class name) with a value of `1`.

#### Customizing event metric data

[](#customizing-event-metric-data)

If you decide to use the trait, you likely will want to customize the event metric data.

You can provide metric data with class attributes:

```
class OrderReceived implements ShouldReportMetric {
    use ProvidesMetric;

    protected $metricName = "new_order";
    protected $metricTags = ["category" => "revenue"];
    ...
```

Or if some of your metric data is dynamic you can use getter methods:

```
public function getMetricValue()
{
    return $this->order->total;
}
```

You can provide any of our metric attributes using these class attributes or getter methods.

### 2. Create the metric yourself

[](#2-create-the-metric-yourself)

Depending on how much detail you need to provide for your metric, it may be simpler to just build it yourself. In this case you can ditch the trait and simply provide a public `createMetric` function that returns a new `Metric` instance:

```
use STS\Metrics\Contracts\ShouldReportMetric;
use STS\Metrics\Metric;

class OrderReceived implements ShouldReportMetric {
    protected $order;

    public function __construct($order)
    {
        $this->order = $order;
    }

    public function createMetric()
    {
        return (new Metric('order_received'))
            ->setValue(...)
            ->setTags([...])
            ->setTimestamp(...)
            ->setResolutions(...);
    }
}
```

Default tags and extra data
---------------------------

[](#default-tags-and-extra-data)

You can set default tags and extra data on the driver that will be merged into every metric:

```
Metrics::setTags(['environment' => 'production']);
Metrics::setExtra(['server' => 'web-01']);
```

### Dynamic extra data with closures

[](#dynamic-extra-data-with-closures)

If you need extra data that is evaluated at the time each metric is dispatched (rather than when it's initially set), you can pass a closure:

```
Metrics::setExtra(fn() => [
    'memory' => memory_get_usage(),
    'cpu' => sys_getloadavg()[0],
]);
```

The closure will be called fresh each time a metric is formatted. This also works on individual metrics:

```
(new Metric('my_metric'))
    ->setExtra(fn() => ['memory' => memory_get_usage()])
    ->add();
```

User ID resolution
------------------

[](#user-id-resolution)

Drivers automatically resolve the current user ID via `getUserId()`:

1. If a user is authenticated: `auth()->id()`
2. Otherwise: `getAnonymousId()`, which returns a UUID stored in the session (stable across requests), or a static UUID for non-session contexts (CLI, queues)

This is used by the PostHog driver as the `distinctId`, and is available to any driver via `$driver->getUserId()`.

### Custom user ID resolver

[](#custom-user-id-resolver)

You can override the default resolution by providing your own closure. The driver instance is passed to your closure, so you can fall back to the built-in anonymous ID if needed:

```
Metrics::resolveUserIdUsing(function($driver) {
    return auth()->check()
        ? 'custom-prefix:' . auth()->id()
        : $driver->getAnonymousId();
});
```

This will apply to all drivers. You can also set it on a specific driver:

```
Metrics::driver('posthog')->resolveUserIdUsing(fn() => $team->id);
```

###  Health Score

64

—

FairBetter than 99% of packages

Maintenance80

Actively maintained with recent releases

Popularity47

Moderate usage in the ecosystem

Community20

Small or concentrated contributor base

Maturity88

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 89.4% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~76 days

Recently: every ~6 days

Total

41

Last Release

107d ago

Major Versions

0.16 → 1.02019-09-17

1.7 → 2.02023-08-06

PHP version history (3 changes)2.0PHP ^8.0

2.4PHP ^8.1

2.9PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/315be5f111b5501a41b99a0205c9c85915335391168a0ed10316546a1a38bbd8?d=identicon)[jszobody](/maintainers/jszobody)

---

Top Contributors

[![jszobody](https://avatars.githubusercontent.com/u/203749?v=4)](https://github.com/jszobody "jszobody (84 commits)")[![djfrailey](https://avatars.githubusercontent.com/u/5817088?v=4)](https://github.com/djfrailey "djfrailey (3 commits)")[![dp88](https://avatars.githubusercontent.com/u/3003563?v=4)](https://github.com/dp88 "dp88 (1 commits)")[![fedeisas](https://avatars.githubusercontent.com/u/251675?v=4)](https://github.com/fedeisas "fedeisas (1 commits)")[![ilya-nurullin](https://avatars.githubusercontent.com/u/7872288?v=4)](https://github.com/ilya-nurullin "ilya-nurullin (1 commits)")[![jansgescheit](https://avatars.githubusercontent.com/u/21027386?v=4)](https://github.com/jansgescheit "jansgescheit (1 commits)")[![chinthakagodawita](https://avatars.githubusercontent.com/u/1452384?v=4)](https://github.com/chinthakagodawita "chinthakagodawita (1 commits)")[![laravel-shift](https://avatars.githubusercontent.com/u/15991828?v=4)](https://github.com/laravel-shift "laravel-shift (1 commits)")[![dmtar](https://avatars.githubusercontent.com/u/37380766?v=4)](https://github.com/dmtar "dmtar (1 commits)")

---

Tags

cloudwatchinfluxdblaravelmetricsposthogprometheus

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/stechstudio-laravel-metrics/health.svg)

```
[![Health](https://phpackages.com/badges/stechstudio-laravel-metrics/health.svg)](https://phpackages.com/packages/stechstudio-laravel-metrics)
```

###  Alternatives

[spatie/laravel-health

Monitor the health of a Laravel application

87512.0M164](/packages/spatie-laravel-health)[illuminate/log

The Illuminate Log package.

6225.3M622](/packages/illuminate-log)[spatie/laravel-flare

Send Laravel errors to Flare

111.4M7](/packages/spatie-laravel-flare)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
