Download the PHP package syriable/laravel-metrics without Composer
On this page you can find all versions of the php package syriable/laravel-metrics. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download syriable/laravel-metrics
More information about syriable/laravel-metrics
Files in syriable/laravel-metrics
Package laravel-metrics
Short Description A modern, extensible, API-first analytics/metrics engine for Laravel — values, trends, partitions, comparisons, formulas and multi-dataset metrics computed database-side.
License MIT
Homepage https://github.com/syriable/laravel-metrics
Informations about the package laravel-metrics
Laravel Metrics — an API-first analytics engine
A standalone, backend-only metrics engine for Laravel. It computes values, trends, partitions, comparisons, multi-dataset metrics and formulas — all aggregated database-side — and returns normalized, serializer-friendly structures ready for any consumer: REST, GraphQL, Filament, Vue, React, Flutter, CLI.
No charts. No Blade. No Livewire. No widgets. Just an engine.
This package separates metrics computation from presentation. Define metrics as pure, reusable components that work everywhere — in API endpoints, queued reports, tests, and CLI commands — without coupling to HTTP requests, UI frameworks, or presentation concerns. The engine's architecture is guided by explicit design decisions documented in docs/architecture.md for the full picture.
Requirements
- PHP 8.4+
- Laravel 11 / 12 / 13
- MySQL, MariaDB, PostgreSQL, SQLite or SQL Server
Installation
Quick start
Concepts
| Concept | What it is |
|---|---|
| Value | one number per dataset, optionally compared against a reference period |
| Trend | a time series per dataset, gap-filled, bucketed by minute→year |
| Partition | one number per group per dataset (groupBy) |
| Dataset | one aggregation inside a metric; a metric can hold many |
| Formula | a computed dataset evaluated over the others, server-side |
| Range | a named resolver ("mtd", "30d") producing an immutable Period |
| Comparison | a strategy picking the reference window + uniform math (Δ, %, direction) |
| Metric | a reusable, named definition — a class extending Metric, scaffolded with make:metric and run by key |
Ranges
Built-in keys: today, yesterday, wtd, last_week, mtd, last_month,
qtd, last_quarter, ytd, last_year, all — plus rolling patterns that
need no registration: 90m, 24h, 30d, 4w, 12mo, 2q, 5y.
Calendar-aligned ranges compare like-for-like: mtd on July 10 compares
July 1–10 against June 1–10, not against the 10 days ending June 30.
Trends
Every point carries a canonical machine key (2026-W28, 2026-07-10,
2026-Q3), a human label, the bucket start, and the value. Missing buckets
are zero-filled with the aggregate's empty value (0 for count/sum, null for
avg/min/max). Series joining happens on machine keys — labels are pure
presentation.
Comparisons
The engine computes previous, difference, percentage and direction
server-side. A value + comparison is one SQL query (conditional
aggregation), not two.
Datasets & formulas
Formulas are parsed by a small, safe arithmetic evaluator (no eval, no SQL).
They work across all three metric shapes — per value, per trend point, per
partition group — and comparisons flow through them. Division by zero and
null operands yield null ("no data"), never an exception.
Named metrics (the API story)
No Metrics::register() call needed — any Metric subclass living under
the configured namespace/path (App\Metrics / app/Metrics by default,
whether hand-written or generated with make:metric) is discovered and
registered automatically at boot. Register manually only for metrics that
live elsewhere — a package, a different directory:
The package deliberately ships no routes — one line of your routing exposes every registered metric, under your auth, your throttling, your versioning.
Generating metrics
Scaffolds a new class in the configured metrics namespace (App\Metrics /
app/Metrics by default) from a publishable stub — the same experience as
make:model or make:notification:
Nested names respect PSR-4, just like every first-party generator:
--force overwrites an existing class; without it, make:metric refuses to
clobber your work. Everything else is configurable in config/metrics.php:
Publish the stub to customize it in place — no config change required:
Every metric generated this way is registered automatically — see
Automatic discovery. Set metrics.discover to
false if you'd rather register everything by hand.
Metric shapes are an open vocabulary, not a hardcoded switch: make:metric
discovers its --{option} flags from a blueprint registry, so a future
--trend/--value/--partition scaffold is registering a
MetricBlueprint, never editing the command.
Automatic discovery
Every concrete Metric subclass under the configured namespace/path is
found and registered at boot — the same file-path-to-class discovery
Laravel uses for console commands in app/Console/Commands. No manifest,
no cache, no Metrics::register() call:
Turn it off in config/metrics.php if you'd rather register everything
explicitly (or have a very large metrics directory and want to avoid the
boot-time scan):
Caching
Keys are hashed from the compiled SQL + bindings of every dataset plus the
resolved period/interval/timezone/formulas — changing anything about a
metric's definition is automatically a cache miss. Only plain arrays are
cached, never objects or closures. Store and global TTL are configurable in
config/metrics.php.
Output
Every result serializes to the same normalized shape:
Extending everything
Performance notes
- Aggregation is always database-side; result rows are never hydrated into models (queries run through the base query builder).
- Value + comparison = 1 query. Trend = 1 grouped query per dataset. Partition = 1 grouped query per dataset.
- Range filtering stays on the raw indexed column (
whereBetween); only the bucket key is computed per row. - Timelines are generated lazily and capped (
metrics.max_buckets) so a minute-over-a-year request fails fast instead of exhausting memory. ->withNow($instant)pins the clock — deterministic tests and backfills without freezing global time.
Testing
Documentation
- Architecture overview
- Architecture decision records
License
MIT — see LICENSE.md.
All versions of laravel-metrics with dependencies
spatie/laravel-package-tools Version ^1.16
illuminate/contracts Version ^11.0||^12.0||^13.0