Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Log Center Laravel Package

nabafzar/laravel-log-center

laravel-log-center provides a centralized log center for Laravel applications, letting you browse, search, and manage log files from one place. It simplifies debugging and monitoring by making application logs easier to inspect and review without manually digging through raw files.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a first release (v1.0.0), so there's no migration story to worry about — you're adopting greenfield. The package targets Laravel 10–13, tested across all four in CI, so it fits most current projects.

Minimal path:

composer require nabafzar/laravel-log-center
php artisan vendor:publish --tag=logcenter-config

Then three things, in this order:

  1. Add the logcenter channel to your log stack in config/logging.php — either append it to the stack channel (get everything) or create a dedicated errors stack that only includes it (get only what you want to be paged about). The latter is usually the right call.
  2. Set driver credentials in .env — Telegram/Bale/Mattermost tokens, webhook URL, or queue connection, depending on transport.
  3. php artisan logcenter:check — run this before anything else. It validates channels, drivers, credentials, queue and viewer access without sending a log, which is exactly the fast feedback loop you want after fiddling with config.

Where to look first: the published config/logcenter.php. It's the contract for everything else — transport, formatter, queue, fallback driver, suppression TTL, enrichment. Skim it end to end before writing any code, because most "why isn't this working" questions resolve there rather than in the README.

One thing you'll hit immediately: the viewer is locked down outside local. You must define the gate or you get a 403 and no clue why:

Gate::define('viewLogCenter', fn ($user) => $user->isAdmin());

First use case that justifies the install: point production/staging error logs at Telegram or Mattermost so failures reach someone, and use the viewer for grouped triage instead of grepping storage/logs. The "issues grouped with counts and first/last seen" view is the killer feature for a noisy app — it collapses the same exception thrown 4,000 times into one row.

Implementation Patterns

Stack inclusion, not channel switching. Don't set LOG_CHANNEL=logcenter. Add it to a stack so the file channel remains your full-fidelity record and the transport is the notification surface:

'stack' => [
    'driver' => 'stack',
    'channels' => ['daily', 'logcenter'],
],

Keeping the file channel matters — the transport is for humans, the file is for forensics and for when the transport is down.

Match formatter to transport, always. Plain, JSON, Markdown, Telegram HTML and Bale Markdown are not interchangeable. Telegram HTML and Bale Markdown have different escaping rules; using the wrong one produces literal <b> tags or mangled output in the alert itself — the worst place to debug. Keep messages simple (one line of summary, stack trace truncated) so formatter quirks don't bite.

Async by default in production. Queue delivery with retries and backoff keeps logging off the request path. The sync-on-queue-failure fallback is the important detail: if the queue is down, the log still goes out rather than vanishing. Configure the queue connection explicitly and make sure workers are running — otherwise you're on the sync path permanently and paying the latency.

Layer the reliability features deliberately. Queue (delivery mechanism) and fallback driver (a second transport tried when a send fails) solve different problems and compose: queue first, fallback when the primary provider is having an outage. Use the null sink for local and CI so nothing leaves the machine.

Suppression TTL as a noise dial, not a filter. Duplicate errors within the window collapse into one notification. Set it to something like 5–15 minutes. This is what turns an alerting channel from unusable to useful during an incident.

#[LogTopic] for routing. Attribute a controller or class and its logs land in a specific Telegram forum topic (and get tagged on drivers that have no topic concept). Good pattern:

#[LogTopic('billing')]
class ChargeCustomer { ... }

Per-domain topics — billing, webhooks, imports — mean the payments engineer and the integrations engineer stop reading each other's noise.

Enrichment, computed once. Git SHA, hostname, deploy version on every log is invaluable for "which release broke this". Compute the SHA once at boot (or read a build artifact) and stash it in config — don't shell out to git per log record.

Testing with LogCenter::fake(). This is the piece that makes the package safe to put in a hot path. Assert your exception handler or job actually logs:

LogCenter::fake();

$this->post('/webhook', $payload)->assertStatus(500);

LogCenter::assertSentTo('telegram');
LogCenter::assertNothingSent(); // in the happy path test

Use assertSent() broadly and assertSentTo() to pin the transport/topic when routing logic is what you're testing.

Digest as a heartbeat. Schedule php artisan logcenter:digest daily or weekly for entry counts per level and top issues. It's a cheap "is the app quietly erroring?" signal that doesn't require anyone to open a dashboard.

HTTP ingress for non-Laravel services. Token auth plus validation means your Go worker, Python cron, or Node sidecar can push structured logs into the same viewer and the same alerting pipeline. Worth standardizing on if you have polyglot services — one triage surface instead of three.

Gotchas and Tips

  • The viewer 403 is almost always the gate. Outside local, viewLogCenter must be defined. If a non-admin sees a blank/forbidden, that's it — not a routing or middleware issue.
  • Secret masking is best-effort, not a guarantee. Passwords, tokens, API keys and Authorization headers are masked in context and message text. That's pattern matching — it will miss a secret embedded in an unusual format, a base64 blob, or a URL query string that doesn't look like a token. Don't log raw request bodies and rely on masking to save you. Write one test that logs a known secret and asserts it doesn't appear, so a pattern regression is caught.
  • Sync fallback can reintroduce the latency you queued to avoid. If the queue silently stops working, every log is a synchronous network call to Telegram inside a request. Alert on queue depth / failed jobs, and treat an unexplained latency bump as a possible transport problem.
  • Suppressed ≠ absent. The TTL window means no notification, not no log. An escalation of an already-firing error (10 → 10,000 occurrences) may not produce a new alert. Glance at the viewer's counts, not just the chat channel. Keep the TTL short enough that recurrence still reaches you.
  • logcenter:check validates configuration, not delivery. It explicitly does not send a log. After a green check, send one real error through the stack (or use LogCenter::fake() in a test) to confirm end-to-end formatting and routing. A misconfigured formatter passes the check and fails in the chat.
  • Formatter/transport mismatches are the most common visual bug. Markdown formatter on a Telegram HTML transport, or vice versa, produces broken escaping. If messages look wrong, check that pairing first — it's config, not a bug.
  • Topic routing degrades by design. Only the Telegram forum transport has real topics; everyone else gets tags. Don't design alerting that depends on topic semantics and then switch transports.
  • Register TransportFactory::extend() / FormatterFactory::extend() in a service provider's boot(), not by editing the published config's closures. Keeps custom transports testable and survives config caching.
  • Protect the HTTP ingress route. Token auth is provided, but you still own rate limiting, IP scoping where possible, and payload size limits — an open log-ingest endpoint is a cheap way to fill a queue and page the on-call.
  • Null sink in CI is not optional if CI shares credentials. Set the null transport (or LogCenter::fake()) in the test environment so a failing pipeline doesn't spam the production channel.
  • "Copy AI prompt" sends your stack trace and source preview to wherever you paste it. Useful for triage, but be aware source preview means file contents leave the app — check that against your data-handling posture before encouraging the team to use it on production issues.
  • Known unknowns at v1.0.0: exact config keys, gate name casing (viewLogCenter), and the full fake() assertion surface beyond those listed. Read the published config and the README's testing section rather than guessing — and pin the version in composer.json since pre-1.x API churn is a real risk for a package this young.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource