PHPackages                             michael4d45/context-logging - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Logging &amp; Monitoring](/categories/logging)
4. /
5. michael4d45/context-logging

ActiveLibrary[Logging &amp; Monitoring](/categories/logging)

michael4d45/context-logging
===========================

Contextual logging for Laravel applications

v6.2.0(1mo ago)0490↓50%MITPHPPHP ^8.3

Since Jan 5Pushed 1mo agoCompare

[ Source](https://github.com/Michael4d45/Laravel-Context-Logging)[ Packagist](https://packagist.org/packages/michael4d45/context-logging)[ RSS](/packages/michael4d45-context-logging/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (11)Versions (45)Used By (0)

Contextual Logging for Laravel
==============================

[](#contextual-logging-for-laravel)

[![Latest Version on Packagist](https://camo.githubusercontent.com/769451c90eab87fe50404f1e997e7491e25ac182c6388333307db949b55c8be6/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d69636861656c346434352f636f6e746578742d6c6f6767696e672e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/michael4d45/context-logging)[![Tests](https://camo.githubusercontent.com/14df43a1ac9f6bc6a243384d9b141f62926831ddf2d478c66355a99b0d0301fd/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f4d69636861656c346434352f436f6e746578742d4c6f6767696e672f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/Michael4d45/Context-Logging/actions?query=workflow%3Arun-tests+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/064aacb5cd327948be723cbd367563ac1048fdca5365f8cfec5318d46f118e52/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6d69636861656c346434352f636f6e746578742d6c6f6767696e672e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/michael4d45/context-logging)

This package provides a structured, context-first logging model for Laravel applications.

Instead of emitting many unstructured log lines during execution, the system accumulates contextual information throughout a request's lifecycle and emits **a single structured log event** at completion. The resulting log data is high-signal, query-friendly, and compatible with modern observability workflows.

**Inspired by** ["Logging sucks"](https://loggingsucks.com) - a comprehensive exploration of wide events and modern observability practices.

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require michael4d45/context-logging
```

Laravel Middleware Registration
-------------------------------

[](#laravel-middleware-registration)

This package requires two global HTTP middleware to function correctly:

- One to initialize request-level context
- One to emit a single structured log entry after the request completes

Laravel 12+ registers middleware via `bootstrap/app.php`.

### Registering Global Middleware

[](#registering-global-middleware)

Open `bootstrap/app.php` and locate the `withMiddleware` section.

Append the package middleware to the global stack:

```
use Illuminate\Foundation\Configuration\Middleware;
use Michael4d45\ContextLogging\Middleware\RequestContextMiddleware;
use Michael4d45\ContextLogging\Middleware\EmitContextMiddleware;

->withMiddleware(function (Middleware $middleware): void {
    $middleware->append(RequestContextMiddleware::class);
    $middleware->append(EmitContextMiddleware::class);
})
```

- `RequestContextMiddleware` runs early and seeds request metadata.
- `EmitContextMiddleware` implements both `handle` and `terminate` methods, ensuring it runs during request processing and emits the structured log entry after the response is sent.

Both middleware are appended to run after Laravel's core request processing.

### Ordering Considerations

[](#ordering-considerations)

Middleware execution order matters.

Recommended placement:

- `RequestContextMiddleware` **after** request normalization middleware (e.g. trimming, proxy handling)
- `EmitContextMiddleware` **at the end** of the global stack

Using `append()` achieves this safely.

If you need the request context earlier, you may use `prepend()` instead:

```
$middleware->prepend(RequestContextMiddleware::class);
```

### Manually Managing the Global Middleware Stack (Optional)

[](#manually-managing-the-global-middleware-stack-optional)

If your application explicitly defines Laravel's global middleware stack using `use()`, include the package middleware in that list.

Example:

```
use Illuminate\Foundation\Configuration\Middleware;
use Michael4d45\ContextLogging\Middleware\RequestContextMiddleware;
use Michael4d45\ContextLogging\Middleware\EmitContextMiddleware;

->withMiddleware(function (Middleware $middleware): void {
    $middleware->use([
        \Illuminate\Foundation\Http\Middleware\InvokeDeferredCallbacks::class,
        \Illuminate\Http\Middleware\TrustProxies::class,
        \Illuminate\Http\Middleware\HandleCors::class,
        \Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance::class,
        \Illuminate\Http\Middleware\ValidatePostSize::class,
        \Illuminate\Foundation\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,

        // Contextual logging
        RequestContextMiddleware::class,
        EmitContextMiddleware::class,
    ]);
})
```

When using `use()`, Laravel **does not** automatically include defaults—you are responsible for the full stack. Both middleware should be included in the array.

### Notes

[](#notes)

- Middleware registration is intentionally **not** automatic.
- This avoids surprising behavior and allows explicit control.
- No changes to route middleware or middleware groups are required.

### Summary

[](#summary)

To enable contextual logging in Laravel:

1. Install the package via Composer
2. Register the two global middleware in `bootstrap/app.php`
3. Continue using `Log::info()`, `Log::error()`, etc. as usual

Once enabled, the package will emit **one structured log event per request** using Laravel's existing logging configuration.

How It Works
------------

[](#how-it-works)

### Traditional Logging

[](#traditional-logging)

```
Application code → Log::info() → formatter → handler → output

```

### Contextual Logging

[](#contextual-logging)

```
Application code → Log::info() → in-memory context only
Request termination → single wide event → Laravel logger → output

```

Log calls become **annotations** that are collected into comprehensive wide events.

### Bootstrap and early log calls

[](#bootstrap-and-early-log-calls)

Logs that run **before** the request context is established are buffered and promoted into the next lifecycle that starts. For HTTP, that means any `Log::info()` (or other level) written during bootstrap, such as in `routes/channels.php`, in a service provider, or while `Broadcast::channel()` definitions are loaded, will be included in the eventual request-wide event instead of being discarded when `RequestContextMiddleware` initializes the store.

The same promotion behavior is used when console and queue lifecycles start, while long-lived lifecycle resets clear the store after emit so completed runs and jobs do not leak into the next one.

Philosophy: Wide Events Only
----------------------------

[](#philosophy-wide-events-only)

This package embraces **Wide Events** exclusively - no more scattered logs! Instead of emitting individual log entries throughout request processing, all logging calls are accumulated and emitted as a single comprehensive event at request completion.

**Why Wide Events?**

- **Complete context**: Every log call from the entire request in one place
- **Request metadata**: Method, path, duration, status, user info
- **Temporal ordering**: All events with precise timestamps
- **Query-friendly**: Single event per request for analysis
- **Clean logs**: No scattered entries to grep through

**The transformation:**

- ❌ **Before**: Dozens of individual log lines per request
- ✅ **After**: One structured event containing everything

Your logs stop lying to you. They start telling the whole truth.

Usage
-----

[](#usage)

The package preserves the existing Laravel logging interface. No changes to your application code are required!

```
