Laravel Package
cliqthemes/log-lens mounts the Log Lens dashboard and JSON API inside an existing
Laravel app. It's a thin adapter over cliqthemes/log-lens-core; all
parsing, storage, and API logic lives in the core engine. Package README:
the adapter's README.
Requirements
PHP 8.2+ and Laravel 10, 11, 12, or 13.
Install
composer require cliqthemes/log-lens
php artisan vendor:publish --tag=log-lens-assets # to public/vendor/log-lens
php artisan vendor:publish --tag=log-lens-config # optional to config/log-lens.php
The service provider is auto-discovered and the UI assets ship pre-built, so no
Node build is needed. Visit /log-lens - but read
Authorization first, since access is open in local by
default.
Authorization
Full guide: Access control (Laravel) covers every method with copy-paste examples (email allowlists, roles, permissions, gates, middleware, and the kill-switch).
Access is gated on every route - no API key in Laravel mode; the host app's auth
is the source of truth. Default: open in local, denied elsewhere. Restrict
with any one of:
// 1. Auth callback (AppServiceProvider::boot) - the usual choice
use LogLens\Laravel\LogLens;
LogLens::auth(fn ($request) => $request->user() !== null); // require login
LogLens::auth(fn ($request) => $request->user()?->hasRole('admin') ?? false);
LogLens::auth(fn ($request) => $request->user()?->can('view-logs') ?? false);
// 2. A Laravel Gate (used when no callback is set)
Gate::define('viewLogLens', fn ($user) => $user?->can('view-logs') ?? false);
// 3. Middleware - add 'auth' to config('log-lens.middleware') to redirect guests to login
The
localdefault allows an unauthenticated browser tab. Register a callback (option 1) to require login even in local. See Security.
This gate is all-or-nothing: can this request reach Log Lens at all. A separate,
optional layer — log-lens.identity — controls what someone can do once
inside (owner/editor/viewer, per application) and who a status change or tag
edit is attributed to; see Roles & assignment.
Without it, everyone the gate admits gets log-lens.default-role, which is
owner out of the box.
Configuration
config/log-lens.php:
| Key | Default | Purpose |
|---|---|---|
enabled | env('LOG_LENS_ENABLED', true) | false unregisters the routes entirely (kill-switch). |
route_prefix | log-lens | URI prefix for the dashboard + API. |
middleware | ['web'] | Route middleware for the dashboard + API (the gate is always appended). |
receiver-middleware | [] | Middleware for the two self-authenticating receivers ({prefix}/ingest, {prefix}/linear-webhook), which are mounted outside middleware and the gate. |
root | storage_path('log-lens') | Where the SQLite DB and logs//processed//sources/ live. |
identity | null | Maps the host user onto a Log Lens role, per application. See Roles & assignment. |
default-role | env('LOG_LENS_DEFAULT_ROLE', 'owner') | Role for an authenticated host user when identity is unset. owner means the access gate is the access control — lower it to editor/viewer if the gate admits a broad audience. |
assignable-users | null | Who an issue in the current application can be assigned to. See Roles & assignment. |
core | (defaults) | Engine settings passed to cliqthemes/log-lens-core (severities, limits, retention, database driver, ...). core.auth.token is empty in Laravel mode. |
Artisan
php artisan log-lens:import storage/logs --app=default
php artisan log-lens:sync --app=default # all connectors
php artisan log-lens:sync --app=default --connector=2
Schedule log-lens:sync in the console kernel for continuous connector ingestion.
CSRF and custom headers
Routes run through the web middleware group, which enforces CSRF. This is
handled automatically: the dashboard reads Laravel's XSRF-TOKEN cookie and
sends it back as the X-XSRF-TOKEN header on every request, so writes (status
changes, tags, process logs, delete, connectors) work out of the box. Session
auth is carried by the cookie as usual.
If you mount Log Lens behind a custom auth guard that needs an extra header
(e.g. a bearer token), set request_headers in config/log-lens.php — an array
of header => value, or a callable given the request. Log Lens injects them so
the SPA sends them with every API call:
'request_headers' => ['Authorization' => 'Bearer '.config('services.logs.token')],
// or dynamic:
'request_headers' => fn ($request) => ['Authorization' => 'Bearer '.$request->user()?->apiToken],
How it works
The provider registers one route at the prefix. Requests without an api
parameter return the SPA shell (assets served from public/vendor/log-lens,
built with base /vendor/log-lens/); requests with one are translated into a
LogLensRequest and passed to the core Kernel, whose LogLensResponse becomes
a Laravel JSON response. See Architecture.