Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Request Tracker Laravel Package

dragon-code/laravel-request-tracker

Laravel Request Tracker logs every incoming HTTP request to your database — method, URL, status, duration, IP and user agent — via a drop-in middleware. Includes Artisan commands, configurable retention, and a dashboard for reviewing and pruning request history.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and publish

composer require dragon-code/laravel-request-tracker
php artisan vendor:publish --provider="DragonCode\RequestTracker\ServiceProvider"
php artisan migrate

The package ships a migration for a request_tracker table (UUID, method, URL, status, duration, payload/headers, timestamps). Nothing else works until that migration has run — if php artisan migrate reports "Nothing to migrate", the provider wasn't auto-discovered or the tag name in --tag= was wrong; check vendor/dragon-code/laravel-request-tracker/database/migrations.

Where to look first

  1. config/request-tracker.php — enable/disable flag, header name used for correlation, DB connection, retention.
  2. The service provider's boot() — confirms whether the tracking middleware and the HTTP-client hook are registered automatically or need manual registration in bootstrap/app.php / Kernel.php.
  3. src/Models/RequestTracker.php — the model you'll actually query; check its $fillable, casts and any scopes.
  4. The README's usage block — the only reliable source for the façade/helper name (Tracker::, request_tracker(), or similar).

First use case

Two Laravel services, A calls B over HTTP. Add the tracking middleware to both. When A calls B, A writes one row for the outgoing call, B writes one row for the incoming request, and both share the same correlation UUID. That UUID is the whole point: it's what lets you reconstruct a single user action across services without a full tracing backend.

// Service A
$response = Http::withHeaders([
    config('request-tracker.header') => request_tracker()->uuid(), // confirm helper name
])->post('https://service-b/api/orders', $payload);

Verify it end-to-end with php artisan tinker against both databases for the same UUID before wiring anything else. If you can't get a matching pair of rows, stop — every later step depends on this.

Realistic expectation setting: 6 stars, 0 dependents, and a release date of 2026-07-01 (which you should sanity-check against the tag list — future-dated tags usually mean an automated release pipeline, not a stable API). Pin the exact version in composer.json and read src/ rather than trusting the README to be current.

Implementation Patterns

Propagate via a global HTTP-client middleware, not per-call headers

The withHeaders() approach above rots the moment someone adds a new Http:: call. Laravel 10+ lets you register once:

// AppServiceProvider::boot()
use Illuminate\Support\Facades\Http;
use DragonCode\RequestTracker\Facades\Tracker;

Http::globalRequestMiddleware(function ($request) {
    return $request->withHeader(
        config('request-tracker.header', 'X-Request-Id'),
        Tracker::uuid()
    );
});

This is the highest-leverage integration in the package: every outbound call, including ones written after you ship, carries the ID.

Middleware placement

Register the tracking middleware as a global middleware or as the first item in the api group — before auth, before throttle. If it runs after auth, unauthenticated or 401 requests leave no row, which is exactly the traffic you want when debugging.

Manual spans for non-HTTP work

Queues and console commands are where correlation breaks. When dispatching a job, stash the UUID on the payload and re-bind it in handle():

class ProcessOrder implements ShouldQueue
{
    public function __construct(public string $orderId, public ?string $trackerId = null) {}

    public function handle(): void
    {
        Tracker::setUuid($this->trackerId); // or tracker()->set(...)
        // ...any Http:: calls now inherit the parent UUID
    }
}

ProcessOrder::dispatch($orderId, tracker()->uuid());

Console commands triggered by cron have no parent; generate a fresh UUID at the top of the command so the whole run is greppable.

Cross-service querying

The pattern that pays off day-to-day is a tiny read-only Artisan command that takes a UUID and dumps the timeline from every configured connection:

foreach (config('request-tracker.connections', ['mysql']) as $conn) {
    RequestTracker::on($conn)->where('uuid', $uuid)->orderBy('created_at')->get();
}

That single command replaces most of the "what actually happened?" conversations, and it's worth building before you have an incident, not during one.

Bridging to existing tooling

Use the UUID as the tag on everything else: Log::withContext(['request_id' => $uuid]), Sentry's before_send tag, and — if you later adopt OpenTelemetry — as the attribute on your root span. This package is a poor man's distributed tracing; treat it as the correlation ID source and let a real tracing system own spans and timing when you outgrow it.

Gotchas and Tips

The table grows fast and unbounded. One row per inbound request plus one per outbound call. At 50 rps that's ~4M rows/day. Before you deploy to production, confirm the retention/prune command and schedule it explicitly in routes/console.php — do not assume the package prunes itself. Add a composite index on (uuid) and on (created_at) if the migration doesn't; the UUID lookup is the only query you'll run interactively.

Payload capture is the privacy landmine. If the package stores request/response bodies or headers, it will happily record Authorization: Bearer …, cookies, and password-reset tokens. Find the masking/ignoring config (often except or hidden arrays of keys) and populate it on day one. If there's no masking layer, subclass the model or add a listener that sanitises before insert — a request_tracker table full of live tokens is a real incident.

Middleware order vs. terminable middleware. Duration is measured at request end. If the tracking middleware runs early but is not terminable, duration may record as near-zero. Check whether the package measures via LARAVEL_START or via microtime(true) in handle()/terminate().

Proxies strip unknown headers. Behind an ALB, nginx, or Cloudflare, custom headers may be dropped or rewritten unless allow-listed. Symptom: service B records a request but with a new UUID rather than A's. Test with a header name that survives your infrastructure, or use a widely-allowed one like X-Request-Id.

Config cache and the enabled flag. If there's an enabled or sample key, php artisan config:cache in deploy scripts will freeze it. Set it per-environment via .env and re-run config:cache in the deploy hook, not before it.

Customising the model. If you need extra columns (tenant ID, user ID), the extension point is usually a config('request-tracker.model') binding or a Model::resolveRelationUsing. Prefer adding columns via your own migration to publishing a forked model — it keeps upgrade paths open.

Treat it as unmaintained until proven otherwise. Zero dependents means you are the QA. Pin "dragon-code/laravel-request-tracker": "x.y.*", vendor-lock the version, and wrap the façade calls you use in one small App\Support\Tracker class of your own. If the package stalls or the API shifts, you swap one file instead of grepping the codebase. Also check whether the release you're pinning is a real tag or an automated nightly — composer show --all and the tag list will tell you.

Debugging empty rows. In order of likelihood: migration not run on that connection; middleware not registered in the api group (common when routes are api.php but the middleware was added to web); DB transaction rolled back and took the row with it (if the package writes inside the caller's transaction, a failed request leaves no trace — worth checking in src/); or the enabled flag is off in the current environment.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package