quiet-guard/laravel-monitor
Monitor your Laravel application's health and performance in one place. Track errors, slow queries, uptime, and key metrics, then get alerted before small issues become outages. Lightweight setup and a simple dashboard keep production visibility easy.
This is a Quiet-Guard error/exception monitor for Laravel: it captures what went wrong, but the interesting part is what leaves your app — request context, headers, URL, logs — and how it is masked. Treat the config file as the primary API.
quiet-guard/core) as ^0.6.0. Upgrade the two together — PayloadBuilder calls Scrubber::masks() and reads ValueRedactor::CREDENTIALS from the core, so a mismatched pair fails at payload-build time, not at install time.monitor.request_headers — the allow list of header names whose values travel in clear.scrub — names (headers, query params, route parameters) that are masked.redact — the credential class list; null in a freshly published file means "follow the package defaults".Where to look first when something is wrong: PayloadBuilder (what is assembled), Transport::redact (the final cut), and the core's ValueRedactor (shape-based masking). Everything else is plumbing.
Zero-touch exception reporting. The default integration reports unhandled exceptions and logged errors with no per-callsite code. Keep it that way; reach for manual reporting only for handled-but-interesting failures (payment declines, third-party 5xx after retries).
Default-deny headers, opt-in values. Since v0.6.0 every header travels by name; only the allow-listed ones carry a value, everything else is [scrubbed]. The default list is deliberately boring (accept, content-type, host, origin, user-agent, x-requested-with, x-livewire, x-inertia, x-inertia-version, plus encoding/cache/length). If your app relies on a tracing header (x-request-id, traceparent), add it to monitor.request_headers — but only if you are certain the value is not a secret. The allow list is an exposure list, not a safety list.
IP capture when you have a legal basis. The six visitor-IP headers are absent from the allow list by design. To capture them, add them to monitor.request_headers and remove them from scrub — the scrub list applies on top of the allow list, so leaving them in scrub masks them anyway. Note forwarded masks x-forwarded-for by substring: if you whitelist x-forwarded-for, also drop forwarded from scrub, or you will capture nothing and spend an afternoon confused.
Signed-URL and reset-token coverage. Route parameters are masked by name when scrub matches (token, hash, signature), which covers /reset-password/{token} and Laravel's own /email/verify/{id}/{hash} regardless of length. The old shape rule (forty letters/digits) remains as a safety net. Add your own parameter names to scrub — the name rule is the reliable one.
Queue-safe by construction. Reports dispatched to a queue are masked before dispatch, so the queued path and the sync path produce identical payloads. This means masking config changes take effect on the next build: after editing scrub, redact, or request_headers, re-run config:cache and restart queue workers, or you will be comparing old and new reports.
Customising PayloadBuilder. It takes a sixth constructor argument — the headers sent in clear — where null falls back to PayloadBuilder::HEADERS. Binding a subclass with five arguments therefore still works and inherits the defaults; passing a list explicitly is how you widen exposure for one specific reporter.
Log collection. LogCollector feeds context/message text into the same pipeline (same soft-cut, same masking). Useful for correlating a report with surrounding log lines; just remember log lines are user-influenced text and get shape-redacted, not guaranteed-clean.
[scrubbed]. This is the intended failure mode, but it looks like a bug the first time your x-tenant-id disappears.$request->route() and falls back gracefully on anything unexpected. Shape-based redaction still applies, but name-based masking may not — do not treat it as a hard guarantee for exotic route bindings.['email', 'iban', 'nir', 'card', 'phone'] is read as the old default and still masks credentials. Fresh installs get 'redact' => null, which tracks the package and names no class of it — so removing the package never leaves a fatal config file. Prefer null and let the package own the list; only pin an explicit array if you have a compliance reason, and expect to maintain it.fullUrl() (percent-encoded query and path segments are decoded before matching). A secret that looks like nothing in particular still travels. Pair this with not logging secrets in the first place.PayloadBuilder constructor argument for headers, the scrub list for names, and the core's ValueRedactor/Cut classes for shape and truncation behaviour. Override at the top (PayloadBuilder) rather than patching the transport — Transport::redact is the last line of defence and you want it boring.How can I help you explore Laravel packages today?