PHPackages                             logtracker/laravel - 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. logtracker/laravel

ActiveLibrary

logtracker/laravel
==================

A local, open-source incident tracer for Laravel.

02↑2900%PHPCI passing

Since Jul 27Pushed todayCompare

[ Source](https://github.com/magarrent/logtracker)[ Packagist](https://packagist.org/packages/logtracker/laravel)[ RSS](/packages/logtracker-laravel/feed)WikiDiscussions main Synced today

READMEChangelogDependenciesVersions (1)Used By (0)

LogTracker for Laravel
======================

[](#logtracker-for-laravel)

LogTracker is a local, open-source incident tracer for Laravel. It turns the logger and lifecycle signals Laravel already emits into a Rollbar-style Items inbox and execution-story detail page.

No Rollbar package is required. No collector, account, API key, subscription, or hosted service is involved. By default, no telemetry leaves the application.

> Status: `1.0.0`. The package includes the local recorder, Items dashboard, privacy defaults, issue workflow, optional notifications, upgrade tooling, and Laravel/database compatibility fixtures described below.

Requirements
------------

[](#requirements)

- PHP 8.3 or newer
- Laravel 11.31, 12, or 13
- SQLite, MySQL, or PostgreSQL through Laravel's database layer

Laravel 11 remains source-compatible and is covered by the package test matrix. As of July 2026, Composer's security blocking rejects a fresh Laravel 11 dependency solve because of upstream framework advisories. Do not disable security auditing for a production install; prefer Laravel 12 or 13 for new applications. The Laravel 11 CI fixture uses `--no-blocking` only so those upstream advisories do not hide compatibility regressions in this package.

Install
-------

[](#install)

LogTracker is available on [Packagist](https://packagist.org/packages/logtracker/laravel). Until the first stable tag is published, install the current `dev-main` build:

```
composer require logtracker/laravel:@dev
```

Then install and verify the package:

```
php artisan log-tracker:install
php artisan migrate
php artisan log-tracker:doctor
php artisan log-tracker:demo
```

Open `/log-tracker`.

The installer creates `config/log-tracker.php` with a unique, immutable installation ID. Do not copy that value between applications. Package migrations are loaded automatically.

Dashboard
---------

[](#dashboard)

The package owns its Blade views and CSS; the host application does not need a frontend build.

[![LogTracker Items inbox](docs/images/items.png)](docs/images/items.png)

[![LogTracker Issue execution story](docs/images/issue-detail.png)](docs/images/issue-detail.png)

Use Laravel's existing logger
-----------------------------

[](#use-laravels-existing-logger)

Existing application code is enough:

```
use Illuminate\Support\Facades\Log;

Log::error('Payment capture failed', [
    'payment_id' => $payment->id,
]);
```

`MessageLogged` makes that an incident trigger at configured levels. Lower levels become bounded breadcrumbs when an execution is already active. Channels built outside Laravel's log manager may not emit `MessageLogged` and are therefore outside the automatic guarantee.

Manual capture is available for cases that are not logs:

```
use LogTracker\Facades\LogTracker;

LogTracker::withContext(['tenant' => $tenant->uuid]);
LogTracker::identifyUser($customer->getKey()); // HMAC only; the ID is not stored
LogTracker::groupBy('payment-provider');
LogTracker::capture($exception);
LogTracker::capture('Checkout degraded', ['provider' => 'acme'], 'warning');
```

`capture()` never reports, throws, swallows, or rethrows an exception. The host application retains control of its exception policy.

Production authorization
------------------------

[](#production-authorization)

Local access is allowed only when both conditions are true:

- `APP_ENV=local`
- the request comes from `127.0.0.1` or `::1`

Every other environment denies access until the application defines both gates:

```
use Illuminate\Support\Facades\Gate;

Gate::define('viewLogTracker', fn ($user) => $user->isDeveloper());
Gate::define('manageLogTracker', fn ($user) => $user->isDeveloper());
```

Or register one runtime callback in an application service provider:

```
use LogTracker\Facades\LogTracker;

LogTracker::authUsing(
    fn ($request, string $ability) => $request->user()?->isDeveloper() === true
);
```

Run `php artisan log-tracker:doctor --production` before enabling the dashboard in production.

What is captured
----------------

[](#what-is-captured)

The native recorder uses Laravel's public surfaces:

SurfaceRoot or story entryTriggerHTTP middlewarerequest rootescaped exception, 5xx, slow request`MessageLogged`breadcrumbconfigured log level or throwable`QueryExecuted`span without bindingsconfigured slow queryLaravel HTTP client eventsspan without body/headers/query stringconnection failure, 5xx, slow callconsole eventscommand rootnon-zero exit, slow commandqueue eventsjob root or sync breadcrumbterminal failure, slow jobscheduler eventsschedule rootexception, non-zero exit, slow taskmail eventsspan without subject, addresses, data, or bodyparent failure policynotification eventsspanchannel failureconfigured application eventsallowlisted scalar breadcrumbparent failure policyPHP shutdown hookpartial shutdown root or current rootrecoverable fatal errorfacade APIcurrent or short manual rootexplicit captureSuccessful roots do not write to the LogTracker database.

Privacy defaults
----------------

[](#privacy-defaults)

Every persistence path uses the same recursive sanitizer:

- sensitive keys such as authorization, cookies, passwords, tokens, API keys, sessions, and private keys are replaced with `[REDACTED]`;
- bearer/basic credentials and private-key blocks embedded in strings are replaced;
- JWTs, credential-bearing URLs, and common provider-token prefixes are replaced;
- object graphs and resources are never retained;
- request bodies and query values are not collected; only query key names and an explicit request-header allowlist are retained;
- matched request paths use Laravel's route template, so parameter values are never stored; unmatched failing routes collapse to `/{unmatched}`;
- SQL bindings, comments, and literal values are not collected; SQL is stored as a bounded placeholder template;
- mail subjects, addresses, bodies, template data, cookies, session contents, and absolute application paths are not collected;
- depth, item, string, span, breadcrumb, trigger, envelope, and execution caps are enforced.

Review `config/log-tracker.php` for the exact defaults. The database, Blade UI, and notification adapters all consume the same sanitized representation.

Application-event breadcrumbs are opt-in and copy only explicitly named scalar paths:

```
'watchers' => [
    'application_events' => [
        App\Events\OrderPaid::class => ['order.id', 'provider'],
    ],
],
```

The event object itself is never serialized.

Affected users
--------------

[](#affected-users)

Authenticated request identifiers are HMACed with a key derived from `APP_KEY` and the immutable LogTracker installation ID. Only the 64-character digest enters an execution or signed queue envelope. Raw IDs, emails, names, and notifiable objects are not stored.

Use `LogTracker::identifyUser($id)` inside jobs, commands, or manual contexts. Pass `null` to clear the current execution identity. Retained distinct counts are repaired by `log-tracker:prune` and `log-tracker:regroup`.

Dedicated database connection
-----------------------------

[](#dedicated-database-connection)

LogTracker clones the configured host connection under the separate `log_tracker` connection name. Laravel therefore creates a separate connection/PDO even when it points to the same local DBngin-managed server and database.

An incident can commit while the host connection later rolls back. Package writes are also ignored by the query watcher, preventing recursive capture. Three consecutive persistence failures open a process-local circuit for 30 seconds.

To use another database server, define a normal Laravel connection named `log_tracker` yourself and set:

```
LOG_TRACKER_DB_CONNECTION=mysql
```

The package connection name and the host source connection name must remain different.

Grouping and execution stories
------------------------------

[](#grouping-and-execution-stories)

- Fingerprints include environment by default, so staging does not contaminate production triage.
- Exception fingerprints use stable application path/symbol information, not line numbers.
- IDs and queue context follow W3C trace/span formats.
- One retained execution story may link to up to five independently grouped Issues.
- Repeated fingerprints update one Issue and create distinct occurrences.
- A resolved Issue reopens when a new occurrence arrives.
- Items can be assigned to a local developer handle, changed individually or in batches, muted, resolved, reopened, and unassigned.

Queue propagation
-----------------

[](#queue-propagation)

Async context uses a reserved `_log_tracker` payload envelope with:

- schema version;
- W3C `traceparent`;
- bounded origin name/environment/release;
- the already-HMACed affected-user digest, when present;
- up to five bounded origin breadcrumbs;
- an HKDF-derived HMAC tied to `APP_KEY` and the installation ID.

The envelope is authenticated metadata. LogTracker does not claim the top-level envelope itself is confidential or encrypted. Invalid, old, missing, or modified envelopes are ignored and the job starts with `origin unavailable`.

The default signed-envelope lifetime is seven days with five minutes of allowed clock skew. Change it only when delayed jobs legitimately need a different correlation window.

OpenTelemetry
-------------

[](#opentelemetry)

The domain model is OpenTelemetry-compatible, but version 1.0 deliberately ships one native recorder and no OpenTelemetry runtime dependency.

The architecture spike found that the current Keepsuit integration offers custom processors but owns provider construction and defaults traces, metrics, and logs to OTLP. A separately installed Laravel package cannot guarantee auto-discovery order, safely mutate a provider that is already global, or promise that it never increases a host exporter's volume.

The native recorder keeps W3C-compatible IDs and queue context, so a future explicit interoperability adapter can be added without changing Issue, occurrence, or execution storage. See [recorder decision](docs/architecture/recorder-decision.md).

Optional email and Slack notifications
--------------------------------------

[](#optional-email-and-slack-notifications)

Outbound notifications are disabled by default. When enabled, only the sanitized Item title, level, execution identity, environment, release, occurrence count, and dashboard URL are sent. Stack traces, execution context, breadcrumbs, and affected-user hashes are never included.

```
'notifications' => [
    'events' => ['new_issue', 'reopened'],
    'dashboard_url' => env('LOG_TRACKER_DASHBOARD_URL', env('APP_URL')),
    'max_per_minute' => 60,
    'mail' => [
        'enabled' => true,
        'to' => ['developers@example.com'],
    ],
    'slack' => [
        'enabled' => true,
        'webhook_url' => env('LOG_TRACKER_SLACK_WEBHOOK_URL'),
    ],
],
```

Adapters use the host Laravel mailer and HTTP client. Delivery happens only after the incident transaction commits; a transport failure is diagnosed and never rolls back or changes host behavior. Muted Items do not emit reopen notifications. Dashboard links use the configured URL rather than the inbound request host, Slack control markup is escaped, and each worker enforces the configured per-minute delivery ceiling.

Commands
--------

[](#commands)

```
php artisan log-tracker:install
php artisan log-tracker:doctor
php artisan log-tracker:doctor --production
php artisan log-tracker:upgrade
php artisan log-tracker:upgrade --check
php artisan log-tracker:regroup
php artisan log-tracker:regroup --write --force
php artisan log-tracker:demo
php artisan log-tracker:prune
php artisan log-tracker:prune --days=14
```

Schedule pruning in the host application:

```
use Illuminate\Support\Facades\Schedule;

Schedule::command('log-tracker:prune')->daily();
```

Upgrade from the alpha
----------------------

[](#upgrade-from-the-alpha)

Back up the application database, update the package, then run:

```
php artisan log-tracker:upgrade
php artisan log-tracker:doctor
```

The upgrade command applies only this package's migrations, advances the published config contract to version 2 when it can do so safely, and records the schema/package version in the installation anchor. It never overwrites the installation ID.

`log-tracker:regroup` is preview-only by default. Use `--write` only after reviewing the projected Item count. New fingerprint groups inherit the first source Item's state. Alpha exception rows that predate stored exception-class metadata retain their previous group boundary instead of being guessed.

Runtime and failure boundary
----------------------------

[](#runtime-and-failure-boundary)

Queue loop/stopping events and available Octane/Horizon lifecycle events clear all singleton execution and watcher state between operations. Successful roots still perform no package database writes. Fixed query-budget tests cap the Items page at four package queries and Issue detail at seven.

Failure isolation is best effort for catchable PHP/Laravel failures. The package cannot guarantee capture during SIGKILL, machine loss, irrecoverable OOM, engine termination, or before Laravel boots.

Develop
-------

[](#develop)

```
composer install
composer test
composer analyse
vendor/bin/pint --test
```

The Testbench suite verifies every capture surface, request/SQL/mail/ notification privacy, embedded secret detection, payload limits, observer and adapter failure isolation, grouping/regrouping, affected-user HMAC counts, dedicated transaction isolation, worker cleanup, installation upgrades, signed and expiring queue context, real trends, assignment/bulk actions, dashboard authorization, optimistic state conflicts, automatic reopening, fixed query budgets, and signed-cursor recovery. CI runs Laravel 11–13 plus SQLite, MySQL 8.4, and PostgreSQL 17 fixtures.

License
-------

[](#license)

MIT. See [LICENSE.md](LICENSE.md).

###  Health Score

21

—

LowBetter than 17% of packages

Maintenance65

Regular maintenance activity

Popularity3

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity11

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% 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.

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/6561770?v=4)[Marc Garcia Torrent](/maintainers/magarrent)[@magarrent](https://github.com/magarrent)

---

Top Contributors

[![magarrent](https://avatars.githubusercontent.com/u/6561770?v=4)](https://github.com/magarrent "magarrent (3 commits)")

### Embed Badge

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

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

PHPackages © 2026

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