PHPackages                             kolaybi/request-tracer - 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. [HTTP &amp; Networking](/categories/http)
4. /
5. kolaybi/request-tracer

ActiveLibrary[HTTP &amp; Networking](/categories/http)

kolaybi/request-tracer
======================

Standalone request tracing package for Laravel — captures outgoing HTTP/SOAP requests and optionally incoming requests.

v1.4.1(1mo ago)047↓66.7%MITPHPPHP ^8.4

Since Feb 27Pushed 1mo agoCompare

[ Source](https://github.com/kolaybi/request-tracer)[ Packagist](https://packagist.org/packages/kolaybi/request-tracer)[ RSS](/packages/kolaybi-request-tracer/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (8)Dependencies (8)Versions (10)Used By (0)

Request Tracer
==============

[](#request-tracer)

Standalone request tracing package for Laravel. Captures outgoing HTTP and SOAP requests, and optionally incoming requests. All traces are stored asynchronously via queued jobs.

Requirements
------------

[](#requirements)

- PHP 8.4+
- Laravel 12+
- `ext-soap` and `ext-simplexml` (only if using SOAP tracing)

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

[](#installation)

```
composer require kolaybi/request-tracer
```

Publish the config:

```
php artisan vendor:publish --tag=request-tracer-config
php artisan migrate
```

Configuration
-------------

[](#configuration)

```
// config/kolaybi/request-tracer.php

return [
    'connection'       => env('REQUEST_TRACER_DB_CONNECTION'),
    'schema'           => env('REQUEST_TRACER_DB_SCHEMA'),

    'queue_connection' => env('REQUEST_TRACER_QUEUE_CONNECTION', 'redis'),
    'queue'            => env('REQUEST_TRACER_QUEUE', 'request_logging'),

    'tenant_column'    => 'tenant_id',
    'tenant_cast'      => 'integer', // 'integer', 'string', or any Eloquent cast type
    'user_cast'        => 'integer', // 'integer', 'string', or any Eloquent cast type

    'max_body_size'    => (int) env('REQUEST_TRACER_MAX_BODY_SIZE', 0),
    'retention_days'   => (int) env('REQUEST_TRACER_RETENTION_DAYS', 0),

    'mask_sensitive'   => (bool) env('REQUEST_TRACER_MASK_SENSITIVE', false),
    'mask_value'       => env('REQUEST_TRACER_MASK_VALUE', '[REDACTED]'),
    'sensitive_keys'   => env(
        'REQUEST_TRACER_SENSITIVE_KEYS',
        'authorization,proxy-authorization,cookie,set-cookie,x-api-key,api-key,apikey,token,access_token,refresh_token,id_token,password,passcode,secret,client_secret,private_key',
    ),

    'context_provider' => null,

    'outgoing' => [
        'enabled'     => env('REQUEST_TRACER_OUTGOING_ENABLED', true),
        'table'       => 'outgoing_request_traces',
        'model'       => OutgoingRequestTrace::class,
        'sample_rate' => (float) env('REQUEST_TRACER_OUTGOING_SAMPLE_RATE', 1.0),
        'only'        => env('REQUEST_TRACER_OUTGOING_ONLY', ''),   // Comma-separated host/path patterns (supports wildcards: 'api.example.com*')
        'except'      => env('REQUEST_TRACER_OUTGOING_EXCEPT', ''), // Comma-separated host/path patterns (supports wildcards: '*.internal.com*')
    ],

    'incoming' => [
        'enabled'               => env('REQUEST_TRACER_INCOMING_ENABLED', false),
        'table'                 => 'incoming_request_traces',
        'model'                 => IncomingRequestTrace::class,
        'sample_rate'           => (float) env('REQUEST_TRACER_INCOMING_SAMPLE_RATE', 1.0),
        'only'                  => env('REQUEST_TRACER_INCOMING_ONLY', ''), // Comma-separated paths (supports wildcards: 'api/orders*')
        'except'                => env('REQUEST_TRACER_INCOMING_EXCEPT', ''), // Comma-separated paths (supports wildcards: 'health*,telescope*')
        'capture_response_body' => (bool) env('REQUEST_TRACER_INCOMING_CAPTURE_RESPONSE', false),
        'channel_header'        => env('REQUEST_TRACER_INCOMING_CHANNEL_HEADER'), // Header name to read channel from (e.g. 'Channel')
    ],
];
```

If `REQUEST_TRACER_MASK_SENSITIVE=true`, matching keys in headers and JSON/form payloads are masked before storage.

Middleware
----------

[](#middleware)

Add `RequestTracerMiddleware` to your middleware stack. It generates a `trace_id` for every request and records incoming traces when enabled.

```
// bootstrap/app.php

use KolayBi\RequestTracer\Middleware\RequestTracerMiddleware;

->withMiddleware(function (Middleware $middleware) {
    $middleware->prepend(RequestTracerMiddleware::class);
})
```

The middleware accepts an optional channel parameter to tag incoming traces by route group:

```
// Per route group — channel set via middleware parameter
Route::middleware([RequestTracerMiddleware::class.':web'])->group(...)
Route::middleware([RequestTracerMiddleware::class.':mobile'])->group(...)

// Channel from request header — set incoming.channel_header in config
// Header value takes priority over middleware parameter
```

Context Provider
----------------

[](#context-provider)

Implement `TraceContextProvider` to supply tenant, user, and server information:

```
use KolayBi\RequestTracer\Contracts\TraceContextProvider;

class AppTraceContextProvider implements TraceContextProvider
{
    public function tenantId(): int|string|null
    {
        return auth()->user()?->company_id;
    }

    public function userId(): int|string|null
    {
        return auth()->id();
    }

    public function clientIp(): ?string
    {
        return request()?->ip();
    }

    public function serverIdentifier(): ?string
    {
        return gethostname();
    }
}
```

Register it in your config:

```
'context_provider' => AppTraceContextProvider::class,
```

Usage
-----

[](#usage)

### HTTP Tracing

[](#http-tracing)

Outgoing HTTP requests are traced automatically when `outgoing.enabled` is `true`. Use `channel()` or `traceOf()` to tag requests:

```
Http::channel('payment-gateway')->post('https://api.example.com/charge', $data);

Http::traceOf('bank-api')
    ->withTraceExtra(['order_id' => 123])
    ->get('https://bank.example.com/status');
```

### SOAP Tracing

[](#soap-tracing)

Extend `TracingSoapClient` for traced SOAP calls:

```
use KolayBi\RequestTracer\Soap\TracingSoapClient;

$client = TracingSoapClient::with('https://service.example.com?wsdl');

$client->channel('e-invoice')->SomeOperation($params);
```

`TracingSoapClient` supports lazy initialization — set the WSDL later if needed:

```
$client = new TracingSoapClient();
$client->setWsdl('https://service.example.com?wsdl');
$client->setOptions(['soap_version' => SOAP_1_2]);
```

### Incoming Tracing

[](#incoming-tracing)

Enable in config:

```
REQUEST_TRACER_INCOMING_ENABLED=true
```

The middleware records every incoming request with method, path, route, status, timing, headers, and optionally the response body.

> **Note:** `response_size` is always recorded regardless of the `capture_response_body` setting. It is read from the Symfony `Response` content when available, and falls back to the `Content-Length` header when content is unavailable.

Debugging
---------

[](#debugging)

Display a chronological waterfall of all traces linked to a `trace_id`:

```
php artisan request-tracer:waterfall 01JEXAMPLE123
```

The command first prints a summary header:

```
Trace ID …………………………………………………… 01JEXAMPLE123
Tenant ID ………………………………………………… 42
User ID ……………………………………………………… 7
Client IP ………………………………………………… 192.168.1.10
First Start …………………………………………… 2026-02-28 12:00:00.000
Last End …………………………………………………… 2026-02-28 12:00:01.250
Total Duration …………………………………… 1250ms

```

Followed by a waterfall table of all traces sorted by start time:

```
+---+-----+----------+------+-----------------------------------------------+--------+----------+-----------------+--------+-------------------------+
| # | ID  | Type     | Method | Endpoint                                    | Status | Duration | Channel         | Server | Start                   |
+---+-----+----------+------+-----------------------------------------------+--------+----------+-----------------+--------+-------------------------+
| 1 | 501 | INCOMING | POST | api.example.com/webhooks (api/webhooks)       | 200    | 1250ms   | —               | web-01 | 2026-02-28 12:00:00.000 |
| 2 | 830 | OUTGOING | GET  | https://bank.example.com/status?ref=abc       | 200    | 320ms    | bank-api        | web-01 | 2026-02-28 12:00:00.100 |
| 3 | 831 | OUTGOING | POST | https://payment.example.com/charge            | 201    | 890ms    | payment-gateway | web-01 | 2026-02-28 12:00:00.350 |
+---+-----+----------+------+-----------------------------------------------+--------+----------+-----------------+--------+-------------------------+

```

This is useful for inspecting the full request flow — incoming request plus all outgoing calls it triggered — in chronological order.

### Inspect

[](#inspect)

Drill into a single trace by its ULID with progressive verbosity:

```
# Metadata only (type, method, endpoint, status, duration, timing, sizes, etc.)
php artisan request-tracer:inspect 01JEXAMPLE123

# + request/response headers
php artisan request-tracer:inspect 01JEXAMPLE123 -v

# + request/response body (truncated to 20 lines)
php artisan request-tracer:inspect 01JEXAMPLE123 -vv

# + body at 40 lines + exception, message, stats, extra (outgoing)
php artisan request-tracer:inspect 01JEXAMPLE123 -vvv

# Everything, no truncation
php artisan request-tracer:inspect 01JEXAMPLE123 --full
```

The command searches both incoming and outgoing tables automatically — no need to specify which.

Data Retention
--------------

[](#data-retention)

### Table Rotation (recommended)

[](#table-rotation-recommended)

Rotate trace tables daily — the current table is atomically swapped with a fresh empty one, and the old data moves to a dated archive table (e.g. `outgoing_request_traces_20260309`). Archives older than `retention_days` are dropped automatically.

```
php artisan request-tracer:rotate
php artisan request-tracer:rotate --days=30
```

Schedule it to run daily:

```
$schedule->command('request-tracer:rotate')->daily();
```

### Row-level Purge

[](#row-level-purge)

Alternatively, delete old rows from the current table in chunks:

```
php artisan request-tracer:purge --days=30
php artisan request-tracer:purge --days=90 --chunk=10000
```

Or set `retention_days` in config and schedule it:

```
$schedule->command('request-tracer:purge')->daily();
```

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

[](#how-it-works)

### Outgoing Traces

[](#outgoing-traces)

- `RequestSending` listener stores per-request trace metadata (`started_at`) in request attributes and `RequestTimingStore`
- `Http::channel()` / `Http::traceOf()` and `Http::withTraceExtra()` set per-request metadata in `request_tracer` attributes
- Event listeners (`ResponseReceived`, `ConnectionFailed`) build trace attributes and dispatch `StoreTraceJob`
- Any `X-Trace-*` headers present on requests/responses are stripped before persisting

### Incoming Traces

[](#incoming-traces)

- `RequestTracerMiddleware` generates a `trace_id` and records start time
- After the response is returned, `IncomingTraceRecorder` builds attributes and dispatches `StoreTraceJob`
- The same `trace_id` links incoming and outgoing traces within a request

### SOAP Traces

[](#soap-traces)

- `TracingSoapClient` stores channel/extra as instance properties
- `__doRequest()` dispatches events with timing, channel, and extra
- Properties are reset after each call (no leakage between calls)

### Workers / Queue Jobs

[](#workers--queue-jobs)

- The middleware does not run on workers, but outgoing tracing works identically
- `trace_id` is lazily generated via `Context` on the first outgoing call
- Laravel resets `Context` between queue jobs, so each job gets a fresh `trace_id`

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](https://github.com/kolaybi/.github/blob/master/CONTRIBUTING.md) for details.

License
-------

[](#license)

Please see [License File](LICENSE.md) for more information.

###  Health Score

45

—

FairBetter than 92% of packages

Maintenance96

Actively maintained with recent releases

Popularity11

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity57

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~4 days

Total

9

Last Release

37d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/55d848a38c4172de8d020b7ebe2a586b41c9924a2d048670a67ddd6c53268fb5?d=identicon)[kolaybi](/maintainers/kolaybi)

---

Top Contributors

[![uguurozkan](https://avatars.githubusercontent.com/u/6731054?v=4)](https://github.com/uguurozkan "uguurozkan (54 commits)")

---

Tags

httplaravelloggingobservabilitypackagerequest-tracingsoaphttplaravelloggingsoapobservabilityrequest tracing

###  Code Quality

TestsPest

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/kolaybi-request-tracer/health.svg)

```
[![Health](https://phpackages.com/badges/kolaybi-request-tracer/health.svg)](https://phpackages.com/packages/kolaybi-request-tracer)
```

###  Alternatives

[dragon-code/laravel-http-logger

Logging incoming HTTP requests

319.8k3](/packages/dragon-code-laravel-http-logger)[sven/super-basic-auth

A lightweight package to add basic authentication to your Laravel app.

232.6k](/packages/sven-super-basic-auth)[behamin/service-proxy

for proxy or sending requests to other services with useful utilities

102.2k](/packages/behamin-service-proxy)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
