mrsuh/nginx-session-handler
A PHP session handler backed by nginx that stores session data in nginx shared memory, avoiding file or database lookups on each request. Drop-in integration with PHP's native session API for fast, centralized session storage.
This package is not a Laravel session driver. Despite the name, it parses the binary session files written by nginx's ngx_http_session_log_module — the module that groups requests from one client into a "session" (request count, bytes sent, duration, user agent, referer, etc.). Treat it as an analytics/ingestion library, not as a drop-in replacement for SESSION_DRIVER=file.
Minimal steps:
composer require mrsuh/nginx-session-handlersession_log zone=client_sessions:1m path=/var/log/nginx/sessions format=json;
src/ for the exact class names and the getSession()/iteration methods; the repo is small enough to read end-to-end in ten minutes.First use case worth wiring up: an Artisan command that parses a session log file and dumps sessions into a table, so you can answer "how many requests and bytes did each client session generate in the last hour?" without standing up a separate analytics stack.
// app/Console/Commands/ImportNginxSessions.php
$handler = new \Mrsuh\NginxSessionHandler\Handler($this->argument('path'));
foreach ($handler as $session) {
NginxSession::create([
'client_ip' => $session->getClientIp(), // verify method names in src/
'requests' => $session->getRequests(),
'bytes_sent' => $session->getBytesSent(),
'started_at' => $session->getStartTime(),
]);
}
Wrap it in a service, not a controller. Create app/Services/NginxSessionParser.php that owns the handler and returns Laravel DTOs or Eloquent models. Keep the third-party classes on the boundary so the package's API never leaks into your app.
Stream, don't slurp. Session logs grow fast. Iterate the handler session-by-session and chunk() inserts into the DB (e.g. 500 rows per insert()), rather than collecting everything into an array.
Queue the ingestion. A ProcessNginxSessionLog job dispatched from a scheduled command keeps the heavy parse off the request path:
$schedule->command('nginx:import-sessions')
->everyFiveMinutes()
->withoutOverlapping();
Rotate by byte offset. Store the last-parsed filename + offset in a settings table and resume from there on the next run. Nginx rotation creates new files, so track filename and offset, not just offset.
Join with your own data. The highest-value pattern is joining by IP + time window against login events or orders to attribute traffic to real users. Store the raw parsed session in a nginx_sessions table with an index on (client_ip, started_at) for this.
Debug view. Add a GET /admin/sessions/{id} route that reads one file and renders a parsed session — invaluable for verifying format changes after an nginx upgrade.
SessionHandlerInterface. Add a one-line comment in composer.json or a README note in your app so nobody wires it into config/session.php.session_log binary layout has shifted across nginx versions. Upgrade nginx, re-test your parser; a silent truncation or garbage field is the usual symptom.640 nginx:adm. Either add the PHP-FPM user to adm or ship a log-shipper; don't chmod 777 the log dir.split -l or process one file per job; memory_limit exhaustion is the most common failure.composer.json. Add a unit test with a checked-in sample log file so a future nginx upgrade fails loudly in CI rather than silently corrupting analytics.vendor/; the class is small enough that fork-and-own is a legitimate long-term option.How can I help you explore Laravel packages today?