moesif/moesif-laravel
Laravel middleware that captures API calls and sends request/response data to Moesif for analytics, monitoring, and monetization. A quick drop-in way to log API traffic, track usage, and debug issues in Laravel apps.
Install with Composer:
composer require moesif/moesif-laravel
Package auto-discovery should register Moesif\Middleware\MoesifLaravelServiceProvider; if not, add it to config/app.php.
Grab an Application ID from Moesif Dashboard → API Keys and put it in .env:
MOESIF_APPLICATION_ID=your_app_id
Publish the config:
php artisan vendor:publish --provider="Moesif\Middleware\MoesifLaravelServiceProvider"
(If the tag is registered, --tag=moesif works too.) This creates config/moesif.php, which holds the app ID, user/company identification closures, body-logging flags, api_version, and enable_debug.
Register the middleware. On Laravel ≤ 10, edit app/Http/Kernel.php and add it to the api group (or web if you're instrumenting a web app):
protected $middlewareGroups = [
'api' => [
\Moesif\Middleware\MoesifLaravelMiddleware::class,
// ...existing entries
],
];
On Laravel 11+ use bootstrap/app.php:
->withMiddleware(function (Middleware $middleware) {
$middleware->append(\Moesif\Middleware\MoesifLaravelMiddleware::class);
// or ->api(append: [...]) for just the API group
})
Hit any route and open Live Event Log in Moesif. You should see request/response pairs with method, path, status, latency, and (if enabled) bodies. That is your first use case — traffic visibility — before you bother with user/company identification or governance rules.
Where to look first: the published config/moesif.php (that's where 90% of customisation happens), the Moesif docs on identifying users and companies, and the underlying moesif/moesif-php SDK if you need to understand how events are queued and sent.
Scope the middleware to the API surface. Put it only on the api middleware group or selected route groups — capturing every admin/web request is noisy and expensive. For mixed apps, apply per-route: Route::middleware(['api', MoesifLaravelMiddleware::class])->group(...).
Identify users with the config closure. The middleware runs after your auth middleware in the group, so $request->user() is populated:
'identify_user' => function ($request, $response) {
$user = $request->user();
return $user ? [
'user_id' => (string) $user->id,
'email' => $user->email,
'ip_address' => $request->ip(),
] : null;
},
Identify companies for B2B monetisation. Use the same closure shape for identify_company, returning company_id, company_domain, and a plan/tier. This is what makes Moesif's per-account analytics and usage-based billing work — without it, all traffic collapses into anonymous users.
Version your API. Set api_version (constant or closure based on route prefix) so Moesif can chart adoption per version and flag calls to deprecated endpoints. Especially useful during /v1 → /v2 migrations.
Mask sensitive payloads before they leave the app. The config supports an on_send / post-processing hook (or use capture_filters to drop whole fields) — strip passwords, tokens, card numbers, and health data there rather than in each controller. If you can't afford any body capture, set log_body => false and rely on metadata only.
Skip noisy endpoints. Exclude /health, /metrics, /telescope, /horizon, and webhook receivers via the capture filters so they don't skew analytics or burn quota.
Separate environments. Use different Moesif Application IDs per environment (or disable in local entirely by not registering the middleware) — otherwise your dev noise pollutes production dashboards.
Combine with Sanctum/Passport. Because the middleware sits after auth, bearer-token clients are identified for free; just make sure the closure returns the token's owning user and the client's app/company, not the request's acting user, if the two differ.
api, $request->user() will be null and every event lands as anonymous. Keep it after auth/auth:sanctum.php artisan tinker or a temporary dd(config('moesif.application_id')).php artisan config:cache will freeze closures. If you change identification callbacks in a cached config, redeploy and clear the cache; also remember env() calls inside config/moesif.php are only evaluated at cache time.storage/logs fast.proc_open is disabled (some shared hosts, hardened containers) it falls back to synchronous sending or drops events. Watch for missing entries and check storage/logs for SDK warnings.StreamedResponse won't capture bodies sensibly. Filter those routes out rather than debugging why the payload looks empty.Kernel.php; on Laravel 11 you must use bootstrap/app.php with ->withMiddleware(...), or the middleware never runs.api group, you'll get duplicate events (roughly double the count in Moesif).on_send hook in config first, then the moesif/moesif-php SDK directly if the Laravel wrapper doesn't expose it.How can I help you explore Laravel packages today?