slogger / laravel
Tracing and observability for Laravel with dispatchers, masking, and profiling.
Installs: 830
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 1
Forks: 0
Open Issues: 0
pkg:composer/slogger/laravel
Requires
- php: ^8.2
- ext-pcntl: *
- ext-posix: *
- laravel/framework: ^10.0 | ^11.0 | ^12.0
- symfony/process: ^6.4|^7.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.94
- guzzlehttp/guzzle: ^7.0
- orchestra/testbench: ^8.0 | ^9.0 | ^10.0
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^10.5 | ^11.0
README
SLogger Laravel is a tracing/observability package for Laravel apps. It records request/command/job/event/etc. traces and delivers them to a remote backend via configurable dispatchers.
This README documents installation, configuration, watchers, masking, dispatchers, profiling, and usage patterns.
Requirements
- PHP >= 8.2
- Laravel 10+ (tested), should work on Laravel 12
- Queue driver for
queuedispatcher - Optional: XHProf extension for profiling
Installation
- Install the package (via Composer in your app):
composer require slogger/slogger-laravel
- Publish config:
php artisan vendor:publish --tag=slogger-laravel
- Configure env and
config/slogger.php(see below).
Quick Start
Enable and use the queue dispatcher:
SLOGGER_ENABLED=true SLOGGER_TOKEN=your-api-token SLOGGER_DISPATCHER=queue SLOGGER_DISPATCHER_QUEUE_CONNECTION=redis SLOGGER_DISPATCHER_QUEUE_NAME=slogger SLOGGER_DISPATCHER_QUEUE_HTTP_CLIENT_URL=https://your-slogger-api SLOGGER_LOG_REQUESTS_ENABLED=true
Then start dispatcher workers:
php artisan slogger:dispatcher:start
Trace Collection Backend
SLogger Laravel sends traces to a separate backend service. The reference backend project is:
https://github.com/sprust/slogger
Use its setup instructions to provision the server and configure the API client URL/token in this package.
Custom backend / client
You can replace the backend by providing your own API client. Redefine ApiClientFactory::create and return a custom implementation of SLoggerLaravel\\Dispatcher\\ApiClients\\ApiClientInterface that sends traces to your backend.
Configuration
All configuration lives in config/slogger.php with environment overrides. Key sections:
General
SLOGGER_ENABLED=false SLOGGER_TOKEN= SLOGGER_TRACE_ID_PREFIX= SLOGGER_LOG_CHANNEL=daily
SLOGGER_ENABLED: globally toggle all tracing.SLOGGER_TOKEN: API token for dispatchers.SLOGGER_TRACE_ID_PREFIX: custom prefix for trace IDs. If empty, uses sluggedapp.nameorapp.SLOGGER_LOG_CHANNEL: where internal errors are logged.
Dispatchers
SLOGGER_DISPATCHER=queue SLOGGER_DISPATCHER_QUEUE_CONNECTION="${QUEUE_CONNECTION}" SLOGGER_DISPATCHER_QUEUE_NAME=slogger SLOGGER_DISPATCHER_QUEUE_WORKERS_COUNT=3 SLOGGER_DISPATCHER_QUEUE_API_CLIENT=http SLOGGER_DISPATCHER_QUEUE_HTTP_CLIENT_URL=http://0.0.0.0:0001 SLOGGER_DISPATCHER_QUEUE_SOCKET_CLIENT_URL=tcp://0.0.0.0:0002
SLOGGER_DISPATCHER:queueormemory.queuedispatcher runs worker processes (similar to Horizon) and sends traces via HTTP or socket client.memorydispatcher stores traces in memory (useful for tests/dev).
Profiling
SLOGGER_PROFILING_ENABLED=true
Enables XHProf profiling for HTTP client traces (see Profiling section).
Request parent trace header
SLOGGER_REQUESTS_HEADER_PARENT_TRACE_ID_KEY=x-parent-trace-id
Allows linking child traces to parent requests via a custom header.
Watchers (enable/disable)
SLOGGER_LOG_COMMANDS_ENABLED=true SLOGGER_LOG_JOBS_ENABLED=true SLOGGER_LOG_REQUESTS_ENABLED=true SLOGGER_LOG_CACHE_ENABLED=true SLOGGER_LOG_DATABASE_ENABLED=true SLOGGER_LOG_DUMP_ENABLED=true SLOGGER_LOG_EVENT_ENABLED=true SLOGGER_LOG_GATE_ENABLED=true SLOGGER_LOG_HTTP_ENABLED=true SLOGGER_LOG_LOG_ENABLED=true SLOGGER_LOG_MAIL_ENABLED=true SLOGGER_LOG_MODEL_ENABLED=true SLOGGER_LOG_NOTIFICATION_ENABLED=true SLOGGER_LOG_SCHEDULE_ENABLED=true
What SLogger Writes
Each trace contains:
trace_id,parent_trace_id,type,status,tagsdata(watcher-specific payload)duration,memory,cpu,logged_at
Watcher data highlights:
request: url, method, action, headers/params, response (for JSON responses)job: connection, payload, status, exceptionevent: listeners, broadcast, optional serialized payloadmodel: action, model class, key, changesmail: from/to/cc/bcc, subject, queued, mailable/notificationnotification: notifiable, channel, queued, responsecache: type, key, tags, valuedb: query, bindings, timehttp-client: method, url, request/responseschedule: command, description, cron, outputdump,log,gate: dump/message/ability info
Requests
Middleware
For HTTP request tracing, add the middleware to the routes you want traced:
\SLoggerLaravel\Middleware\HttpMiddleware::class
Request watcher config
config/slogger.php:
'watchers' => [ [ 'class' => \SLoggerLaravel\Watchers\Parents\RequestWatcher::class, 'enabled' => env('SLOGGER_LOG_REQUESTS_ENABLED', false), 'config' => [ // log only matched paths (optional) 'only_paths' => [ // 'api/*', ], // skip matched paths 'excepted_paths' => [ // 'health', ], 'input' => [ // apply input formatting only for these paths 'only_paths' => [ // 'api/*', ], // hide all request params for these paths 'hidden_paths' => [ // 'auth/*', ], // header masking by url_pattern 'headers_masking' => [ '*' => ['authorization', 'cookie', 'x-xsrf-token'], ], // param masking by url_pattern 'parameters_masking' => [ '*' => ['*token*', '*password*'], ], ], 'output' => [ // apply response formatting only for these paths 'only_paths' => [ // 'api/*', ], // hide all response data for these paths 'hidden_paths' => [ // 'auth/*', ], // response header masking by url_pattern 'headers_masking' => [ '*' => ['set-cookie'], ], // response field masking by url_pattern 'fields_masking' => [ '*' => ['*token*', '*password*'], ], // limit json response size (bytes) 'max_content_length' => 1048576, ], ], ], ],
only_paths
only_paths(top-level): log only matched request paths.input.only_paths: apply input masking only to matched paths (others are scrubbed).output.only_paths: apply output masking only to matched paths (others are scrubbed).
Patterns use Laravel Str::is matching.
JSON response size
Large JSON responses are skipped and marked with:
{"__skipped": "response_too_large"}
Masking Rules
Masking is pattern-based and configurable.
Masked values keep basic types:
bool->falseint->0float->0.0string-> masked string- arrays/objects -> masked string
Guzzle / HTTP Client tracing
You can attach the SLogger handler to Guzzle:
new \GuzzleHttp\Client([ 'base_uri' => 'https://url.com', 'handler' => app(\SLoggerLaravel\Guzzle\GuzzleHandlerFactory::class)->prepareHandler( (new \SLoggerLaravel\RequestPreparer\RequestDataFormatters()) ->add( new \SLoggerLaravel\RequestPreparer\RequestDataFormatter( urlPatterns: ['*'], requestHeaders: ['authorization'] ) ) ->add( new \SLoggerLaravel\RequestPreparer\RequestDataFormatter( urlPatterns: ['/api/auth/*', '*sensitive/some/*'], hideAllResponseData: true ) ) ), ])
Dispatchers
Queue dispatcher
Start the dispatcher (spawns queue workers):
php artisan slogger:dispatcher:start
- Parent traces are sent immediately.
- Child traces are batched (default batch size: 5).
- Orphan traces are sent immediately.
- On shutdown, remaining traces are flushed.
Stop the dispatcher:
php artisan slogger:dispatcher:stop
Memory dispatcher
Stores traces in memory only. Intended for tests/local development.
Storage
SLogger does not persist traces locally. The only local file is the dispatcher state file in:
storage/slogger/dispatcher-state-*.json
You may want to ignore the folder:
storage/slogger/*
Profiling (XHProf)
Only for HTTP client tracing.
- Install extension:
pecl install xhprof
- Enable in
php.ini:
[xhprof] extension=xhprof.so
- Enable:
SLOGGER_PROFILING_ENABLED=true
Testing
Run tests:
vendor/bin/phpunit
The testbench config uses in-memory sqlite and memory dispatcher.
Troubleshooting
- Dispatcher not starting: verify
SLOGGER_ENABLED=trueand correct dispatcher name. - No traces: ensure watchers are enabled and middleware is applied for requests.
- Queue dispatcher not sending: check queue workers and API client URL.
- Socket client errors: verify socket address and backend availability.
License
MIT