aschmelyun/larametrics
Larametrics is a self-hosted metrics and monitoring package for Laravel. It records requests, response times, model changes, and database queries, displays them in a built-in dashboard, and sends alerts via email or Slack when issues or thresholds are hit.
Larametrics is a self-hosted, database-backed observability panel for Laravel: it records HTTP requests, Eloquent model events, Artisan commands, and log entries, then surfaces them in a /larametrics dashboard and can push alerts to email/Slack.
Before you install, check the version matrix. The package was last substantively released in January 2020 and is archived upstream. It targets Laravel 5.8–6.x / PHP 7.2+. Expect to spend time patching it if you're on Laravel 9+, and treat Laravel 10/11 as unsupported. Verify each step below against the README and the package's service provider, since some class names shifted between releases.
Pin to ^1.2.1 or later in the 1.x line. v1.2.1 is a small bug-fix release: earlier 1.x tags made DB calls during boot without first checking whether the vendor config file had been published, which caused errors on fresh installs and cold deploys. If you inherit a lockfile pinned below 1.2.1, that fix is not present — see the Gotchas section for the failure mode and workaround.
Minimal steps:
composer require aschmelyun/larametrics:^1.2.1
# publish config, migrations, and dashboard assets
php artisan vendor:publish --provider="Aschmelyun\Larametrics\LarametricsServiceProvider"
php artisan migrate
Then:
config/larametrics.php. This is the whole surface area: the dashboard route/prefix, the middleware stack guarding it, the notification channels, and the lists of "watched" items (models, commands, log monitoring on/off).web middleware only. Add auth (or your own gate middleware) in the config before deploying, otherwise your request log is publicly readable.LARAMETRICS_ENABLED) to false locally and on high-traffic production if you can't control write volume. A staging box is the ideal first target.First use case — the 10-minute win: add the request-tracking middleware to a route group, hit a few endpoints, and open /larametrics. You immediately get a request log with method, path, status, duration, and IP. That alone is worth the install on a legacy app where you have no APM.
Request tracking via middleware. The package ships a middleware that persists one row per request. Add it to app/Http/Kernel.php — either globally, on the web group, or (preferred) on a specific group so you control the blast radius:
// app/Http/Kernel.php
protected $middlewareGroups = [
'web' => [
// ...
\Aschmelyun\Larametrics\Http\Middleware\Larametrics::class, // confirm FQCN in the provider
],
];
For anything with real traffic, prefer a dedicated group applied only to the routes you care about, and explicitly exclude health checks, asset routes, and webhooks.
Model watching. Register the model classes you want audited in the config's watched-models list. Each created / updated / deleted event produces a row with the model class, key, and the changed attributes. This is effectively a poor-man's audit trail — useful for "who changed this order?" investigations on low-write tables. Do not blanket-watch everything; each save is now at least one extra INSERT.
Command watching. Same pattern for Artisan commands: list the command names in config and you get a record of scheduled/console runs. This is genuinely handy for confirming that schedule:run actually fired your nightly job on a box where cron is suspect.
Log monitoring + notifications. The package parses storage/logs/laravel.log and can alert on error-level entries. Wire up either channel in config:
'notifications' => [
'email' => ['enabled' => true, 'to' => '[email protected]'],
'slack' => ['enabled' => true, 'webhook' => env('SLACK_WEBHOOK')],
],
Notifications are delivered by a scheduled command, not synchronously. Register it in app/Console/Kernel.php:
protected function schedule(Schedule $schedule)
{
$schedule->command('larametrics:check')->everyMinute();
}
Without this scheduler entry the dashboard still populates, but no alerts ever fire — this is the single most common "it's broken" report.
Deploy pipelines: publish config before caching. Because pre-1.2.1 boot paths touched the database before checking for the published config, a pipeline that runs php artisan config:cache or package:discover against an image where the vendor config was never published could fail at boot. In v1.2.1+ that ordering constraint is relaxed, but it's still the sane order for any package with publishable config: composer install → vendor:publish → config:cache → migrate.
Recommended integration shape for a real app:
staging and one production environment, gated by env var.auth + a role/gate check, and use a separate DB connection if you don't want metrics writes competing with app writes.It's archived — budget for maintenance. No security fixes, no Laravel 8+ compat work. The 1.x line still receives the occasional one-line patch (v1.2.1 is exactly that), which is useful but does not change the compatibility picture. Known friction points on newer stacks: the service provider's route/schedule registration, facade alias registration, and migrations that assume older schema conventions. Fork it, pin the fork in composer.json via a VCS repository entry, and own the patches.
Pre-1.2.1 boots hit the DB before the config exists. The v1.2.1 fix wraps those calls in a "has the vendor config been published?" check. Symptoms on older pins: exceptions during composer install's post-autoload scripts, artisan commands dying on a fresh clone, or a package that appears to work only after you manually publish config. Workaround if you can't upgrade: publish the config file as the very first thing after composer require (before any other artisan call), and commit config/larametrics.php so it exists in every environment. Note this fix is about install ergonomics only — it does not add Laravel 9+ compatibility, and should not be read as a sign of renewed maintenance.
Write amplification is the headline risk. One row per request plus one row per watched model event. The tables have no built-in retention. On a site doing 50 rps you'll generate millions of rows in days and the dashboard queries will crawl. Mitigations:
// app/Console/Kernel.php
$schedule->call(function () {
DB::table('larametrics_requests')->where('created_at', '<', now()->subDays(7))->delete();
DB::table('larametrics_models')->where('created_at', '<', now()->subDays(30))->delete();
})->daily();
Adjust table names to whatever the published migrations created.
Sensitive data leakage. Request rows capture URL, method, IP, and (depending on config) payload/headers; model rows capture attribute diffs. Passwords, tokens, and PII land in the metrics tables unless you exclude them. Check the config for an ignore/except list and, if it doesn't exist, add one in a fork or strip fields in a saving hook on the metrics models. Also consider that the dashboard is a read-only view of this data — anyone who can reach it can see it.
Log parsing is file-based and naive. It reads the log file on each check. A multi-hundred-megabyte laravel.log will be slow and memory-hungry; daily log rotation (LOG_DAILY_DAYS) is effectively mandatory. It also doesn't understand custom Monolog channels — only the default single/daily file.
Debugging checklist when the dashboard is empty:
LARAMETRICS_ENABLED actually true for that environment.php artisan route:list -v).php artisan migrate:status.^1.2.1 if you saw boot-time DB errors on install).php artisan config:clear after every config edit.larametrics:check in the schedule? php artisan schedule:list / run it manually.Dashboard auth. The route is registered by the package, so middleware from your web group applies but auth does not by default. Prefer wrapping with your own middleware via config rather than editing vendor routes, and if you need finer control, define a gate and reference it in the middleware list.
Extension points are thin. There's no documented driver/contract system for notification channels. If you need PagerDuty, Teams, or Discord, the pragmatic path is a Slack-compatible webhook proxy, or override the notification class in a fork. Same for the dashboard: views are publishable, so restyling/branding is a publish-and-edit job.
Keep the vendor config in version control. It's the single lever for every behaviour in the package, and since the 1.2.1 fix exists precisely because a missing config file broke boot, treating it as deploy-time state rather than a published artifact removes a whole class of "works on my machine" failures.
Multi-environment dashboards. If staging and production share a database, the dashboard silently mixes them. Either use separate metric databases or add an environment column in a fork and filter the dashboard queries.
Alternatives worth pricing out first: Laravel Telescope (dev-focused, richer), Laravel Pulse (first-party, maintained, sampled), Sentry (exceptions + performance), and Oh Dear/Nightwatch for uptime. Larametrics' niche is "single self-hosted panel with alerting and zero external calls" — a real constraint in regulated/air-gapped environments. If that's not your constraint, Pulse or Sentry will cost you less in maintenance than keeping an archived package alive.
How can I help you explore Laravel packages today?