spatie/laravel-http-logger
This Laravel middleware logs incoming HTTP requests to your default log, so you can still access the original request data if something goes wrong. An extra safety net for critical user submissions like lead-generating forms, with configurable log profile, writer, and channel.
Architecture fit
Spatie\HttpLogger\Middlewares\HttpLogger) that captures inbound request metadata and body, then hands it to a LogWriter for emission through Laravel's native logging stack. There is no service, queue, database schema, or external dependency introduced — it sits entirely inside the existing HTTP kernel and Log facade, which makes it architecturally low-impact and easy to reason about in a design review.LogProfile::shouldLogRequest() controls whether to log, and LogWriter::logRequest() controls how. Both are interface-bound and config-swappable, so custom redaction, JSON-structured output, tenant tagging, or queued writes can be introduced without touching vendor code. This is the package's main architectural asset and the reason it survives compliance review better than a hand-rolled Log::info() in middleware.Integration feasibility
composer require, optional config publish, one middleware registration (global via ->withMiddleware() on Laravel 11+, or a single route/group). A competent Laravel engineer can have it running in staging in under an hour; hardening the redaction config is the real work.Technical risk
password and password_confirmation, and sanitize_headers ships empty. Any endpoint carrying emails, phone numbers, addresses, national IDs, card-adjacent fields, free-text support messages, or bearer tokens will land in log storage verbatim unless explicitly configured. Log storage typically has different access controls and retention than the primary datastore, which is exactly the pattern regulators flag.HTTP_LOGGER_ENABLED wired per-environment in the deployment manifests?Stack fit
^1.11 and accept the feature freeze. Laravel ≤10 is effectively out of scope.stack channel mixes request bodies into general application logs, which is bad for both retrieval and retention policy. The recommended pattern is a dedicated channel (e.g., http-logger → daily-rotated file or a separate log sink) with its own retention rule and access boundary, selected via LOG_CHANNEL or the log_channel config key.Migration path
config/http-logger.php into version control so redaction is code-reviewed rather than environment-dependent.LogWriter if structured JSON output, tenant identifiers, or async dispatch is required — this is the single highest-leverage customization and should not be deferred past the pilot.except with every PII-bearing field per endpoint, and populate sanitize_headers with Authorization, Cookie, Set-Cookie, and any internal auth tokens.Compatibility
sanitize_headers requires ≥1.10.2, configurable log_level ≥1.10.0, configurable log_channel ≥1.8.0, request-file handling ≥1.4.0, header capture ≥1.6.0. Anything older lacks the redaction and channel controls that make this acceptable from a risk standpoint — do not adopt below 1.10.x.Sequencing
except and sanitize_headers, HTTP_LOGGER_ENABLED=false in local and test.Maintenance
laravel-shift PRs, which historically land promptly.except and sanitize_headers silently fall out of date. Assign ownership to the team that owns the endpoint inventory, and add a PR checklist item requiring review of http-logger.php whenever a form or write endpoint changes. This is the single most likely way the package becomes a liability.Support
Scaling
LogWriter; push writes to a queue in the custom writer to decouple from request latency; narrow LogProfile to specific URIs rather than all non-GET verbs; set the log channel to a rotating handler with an explicit retention window.LogNonGetRequests profile will capture webhooks, health-check POSTs, and internal service calls if applied globally — a common source of surprise volume.Failure modes
Ramp-up
LogWriter if structured output or async dispatch is wanted. No training program required.LogWriter that cannot fail the request. Reject any proposal to enable it globally with default configuration — the default redaction posture is not defensible for production PII, and the latency and volume characteristics are unmeasured.How can I help you explore Laravel packages today?