yaro/log-envelope
Log Envelope for Laravel adds consistent context to every log entry, such as request IDs, user details, tenant info, and custom metadata, so you can trace and debug across requests, queues, and services without repeating context in each log call.
composer require yaro/log-envelope
config/app.php:
Yaro\LogEnvelope\LogEnvelopeServiceProvider::class,
php artisan vendor:publish --provider="Yaro\LogEnvelope\LogEnvelopeServiceProvider"
config/log-envelope.php and set the recipient, sender, subject, enabled flag, and minimum log level. Prefer environment variables so each environment can differ:
LOG_ENVELOPE_ENABLED=true
[email protected]
[email protected]
Log::error('LogEnvelope smoke test', ['route' => request()->path()]);
In local development, set MAIL_MAILER=log and inspect storage/logs/laravel.log rather than sending real mail.Where to look first:
config/log-envelope.php after publishing.Production-only alerting. Enable the package only where you want email alerts, typically production or staging:
// config/log-envelope.php
'enabled' => env('LOG_ENVELOPE_ENABLED', app()->environment('production')),
Keep it disabled in local and testing to avoid noise and accidental mail.
Drive it through Laravel's exception reporting. The clean path is to let uncaught exceptions flow through App\Exceptions\Handler::report(), which logs them. If you override report(), call parent::report($exception) so the package still sees the error:
public function report(Throwable $exception)
{
parent::report($exception);
}
Use explicit error logs for non-exception failures. Background jobs, failed API calls, and validation of external services may not throw. Log them at error or above:
Log::error('Payment gateway rejected charge', [
'order_id' => $order->id,
'gateway' => 'stripe',
'response' => $response->json(),
]);
Enrich context with request metadata. Add a middleware or exception-handler hook that includes URL, user ID, tenant ID, and request ID. This makes the email actionable without opening the server:
Log::error($message, [
'url' => request()->fullUrl(),
'user_id' => optional(auth()->user())->id,
'request_id' => request()->header('X-Request-Id'),
]);
Throttle and deduplicate. Error storms can send hundreds of emails. Wrap notifications with a cache lock or rate limiter, or configure a higher threshold and rely on a separate monitoring system for volume:
if (Cache::add('log-envelope:'.$fingerprint, true, now()->addMinutes(5))) {
Log::error($message, $context);
}
Choose the right mail transport. For low-volume alerting, SMTP is fine. For anything that may burst, use a queued transport or a transactional email provider. If the package sends synchronously, an SMTP timeout can slow down the failing request.
Test with the log mailer, not a real inbox. Set MAIL_MAILER=log locally and trigger errors. In automated tests, assert against the log output or bind a fake mailer if the package uses Laravel's Mail facade. Verify the exact behavior rather than assuming Mail::fake() intercepts it.
Keep it as a lightweight fallback. LogEnvelope is useful for small teams and low-traffic apps. For serious production monitoring, pair it with Sentry, Flare, Bugsnag, or Laravel Telescope/Horizon alerting, and avoid duplicate alert paths.
Customize the notification where supported. If the package publishes views or exposes a handler class, override the subject and template to include environment, release version, and a link to your logs. Keep stack traces but redact secrets.
Log::listen-style hooks may no longer fire. Test on your exact Laravel version before depending on it; be prepared to fork the package and adapt the handler to a Monolog processor or custom log channel.$dontReport in your exception handler and scrub context before logging.php artisan config:clear after changing environment variables. Cached config can make it look like the package is ignoring your recipient or enabled flag.error and above, warning or notice entries will not send mail. Confirm whether emergency, alert, and critical are included.from address on a domain without SPF/DKIM can land in spam. Use a verified sender and test deliverability.Log::error calls, and the package can all fire for the same event. Pick one reporting path per failure type.How can I help you explore Laravel packages today?