Looking to hire Laravel developers? Try LaraJobs

laravel-db-query-sniffer maintained by andriichuk

Description
Laravel package to log SQL queries and Redis commands with raw SQL, binary-safe bindings, and slow-query filters
Last update
2026/07/22 10:03 (dev-main)
License
Downloads
1

Comments
comments powered by Disqus

Laravel DB Query Sniffer: SQL Query and Redis Logger

Tests PHPStan Latest version

Laravel DB Query Sniffer is a Laravel SQL query logger and Redis command logger for local API debugging. Log Eloquent, query builder, and raw SQL queries to rotating files with request IDs, execution timings, and optional slow-query filters.

Capture queries from JSON APIs, mobile clients, Postman, browser requests, console commands, and queue jobs. No dashboard, migrations, or additional database tables are required.

What you can debug

  • SQL query logging: inspect executed SQL, bound values, connection names, and execution times.
  • Laravel API debugging: group queries by request ID, HTTP method, and URL path.
  • Redis command logging: inspect commands and sanitized parameters alongside SQL logs.
  • Slow query logging: record only SQL queries or Redis commands that meet a configurable duration threshold.

Requirements

  • PHP 8.3 or later, with mbstring.
  • Laravel 12 or 13.

Install the Laravel query logger

composer require andriichuk/laravel-db-query-sniffer --dev

The service provider is auto-discovered. Logging is restricted to the local environment by default. When LOG_DB_QUERIES is absent, the enable switch follows APP_DEBUG. Set it explicitly to control capture:

LOG_DB_QUERIES=true
DB_QUERY_LOG_ENABLED=true
REDIS_COMMAND_LOG_ENABLED=false

SQL query logging is enabled by default when the master switch allows capture. Redis command logging is opt-in: set REDIS_COMMAND_LOG_ENABLED=true to enable it. Both switches still respect the master switch and allowed environments.

The package supplies db and redis daily log channels with two-day retention when those channels do not already exist. Existing application channels are preserved. Files are written under storage/logs/db-YYYY-MM-DD.log and storage/logs/redis-YYYY-MM-DD.log.

Configuration publishing is optional:

php artisan vendor:publish --tag=db-query-sniffer-config

Debug SQL queries from Laravel API requests

SQL and Redis events are captured server-side, independently of the response format or client. Global middleware adds these fields while handling an HTTP request:

  • request_id: a generated identifier shared by that request's query records.
  • request_method: the HTTP method.
  • request_path: the URL path, excluding query parameters.

The response includes X-Query-Sniffer-Request-Id, allowing you to find its records in the logs. IDs are generated by the server; incoming headers are not trusted or reused. Set request_context to false to disable both correlation and the response header.

{
    "query": "select * from users where id = 7",
    "time": "1.24ms",
    "duration_ms": 1.24,
    "connection": "mysql",
    "request_id": "31de9d5984414e1ca7282caa3ca0c6c1",
    "request_method": "GET",
    "request_path": "/api/users/7"
}

Context is cleared when middleware exits, including exception paths. Console commands and asynchronous queue jobs are logged without HTTP fields. Queries during application bootstrap, request termination, or streamed response callbacks are still captured but may not have HTTP context.

Log slow SQL queries and Redis commands

Every successfully executed Laravel SQL query is logged by default when capture is enabled. Redis commands are recorded after opting in with REDIS_COMMAND_LOG_ENABLED=true. To focus on slow database queries, set database.slow_only to true in the published configuration and choose a database.slow_ms threshold in milliseconds. Use redis.slow_only and redis.slow_ms independently for slow Redis commands.

SQL and Redis logging configuration

Key Default Purpose
enabled LOG_DB_QUERIES, falling back to APP_DEBUG Master switch
environments ['local'] Allowed environments; ['*'] allows all
request_context true HTTP correlation fields and response header
database.enabled true Capture SQL queries; override with DB_QUERY_LOG_ENABLED
database.channel db Override with DB_QUERY_LOG_CHANNEL
database.message SQL Query: Log message
database.include_connection true Include the connection name
database.slow_only false Capture every query unless enabled
database.slow_ms 100 Inclusive minimum duration when slow_only is enabled
redis.enabled false Capture Redis commands; opt in with REDIS_COMMAND_LOG_ENABLED
redis.channel redis Override with REDIS_COMMAND_LOG_CHANNEL
redis.message Redis Command: Log message
redis.slow_only false Capture every command unless enabled
redis.slow_ms 100 Inclusive minimum duration when slow_only is enabled
bindings.max_string_length null Limit text in fallback bindings and Redis parameters
bindings.binary_as_base64 true Include binary bytes as base64, or a size placeholder when disabled

Both SQL and Redis records include the original time string and a numeric duration_ms field. Custom channel names must exist in config/logging.php. To use an existing logger, set the channel override to its name.

Reliability and scope

  • SQL capture uses Laravel's QueryExecuted event. It records successfully executed statements through Laravel connections, including Eloquent, the query builder, and raw DB queries. Direct PDO calls, other applications' queries, and failed statements are outside its scope.
  • Redis capture enables Laravel's command events. Direct calls to a Redis client that bypass Laravel's connection are outside its scope.
  • When raw SQL interpolation fails, the package logs the statement and sanitized bindings instead. NUL-containing and invalid UTF-8 strings are encoded for JSON-safe logging.
  • Queries issued by a log handler are deliberately excluded to prevent recursive logging. Handler failures go to PHP's error log without failing the application query.
  • Raw SQL and Redis parameters can contain application data. This is a local development tool, and binary encoding is not redaction. Text truncation applies to fallback bindings and Redis parameters, not interpolated SQL or base64 binary values.

Replacing inline listeners

Remove the application's old SQL and Redis listeners and their binding sanitizer after installing this package, otherwise queries will be logged twice. Keep any application log channel configuration you want to preserve. If you previously published the package configuration, update its database.enabled and redis.enabled entries to use the new environment switches; an existing published configuration overrides package defaults. The LOG_DB_QUERIES environment switch continues to work; the old logging.log_db_queries configuration entry is no longer used.

Development

composer install
composer check

composer check runs Pint, maximum-level PHPStan without a baseline, and the test suite. CI checks Linux and Windows, PHP 8.3 through 8.5, and Laravel 12 and 13 using compatible Pest/Testbench versions. A separate coverage job enforces at least 95% source line coverage.

composer test-coverage -- --min=95

Coverage requires PCOV or Xdebug. See CONTRIBUTING for contribution guidelines and CHANGELOG for releases.

License

MIT. See LICENSE.