tuser/query-spy
Composer 安装命令:
composer require tuser/query-spy
包简介
QuerySpy: Real-time Laravel query performance monitoring — N+1 detection, slow queries, duplicate queries, memory tracking, and a beautiful developer dashboard.
README 文档
README
Real-time Laravel query performance monitoring. Drop it in, browse your app, and instantly see N+1 queries, slow SQL, duplicates, memory spikes, and more — all in a beautiful developer dashboard.
✨ Features
| Feature | Description | |
|---|---|---|
| 🔁 | N+1 Detection | Finds repeated SQL patterns caused by missing eager-loading |
| 🐢 | Slow Queries | Flags individual queries over your ms threshold |
| 📄 | Duplicate SQL | Catches identical queries run multiple times per request |
| 🧠 | Memory Tracking | Peak memory, growth per request, configurable alert threshold |
| ⭐ | SELECT * Detection | Warns when all columns are fetched unnecessarily |
| 🔍 | Index Hints | Detects leading-wildcard LIKE '%...' that force full table scans |
| 📊 | Severity Score | Every request scored 0–100 and labelled OK / Notice / Warning / Critical |
| 🖥 | Dashboard | Dark, dev-friendly UI at /queryspy |
| 📈 | Timeline Chart | Dual-axis Chart.js bar+line showing request time and query count |
| 📋 | Pagination | 25 entries per page with smart controls |
| ♻️ | Auto-refresh | 10-second polling toggle on the dashboard |
| 📋 | Copy SQL | One-click copy button on every SQL block |
| 📤 | Export | Download as JSON or CSV directly from the dashboard |
| 🌐 | Response Headers | X-QuerySpy-* headers visible in your browser's Network tab |
| 🔐 | Password Protection | Optional dashboard password via .env |
| 🌍 | Environment Guard | Skips production, CLI commands, and ignored URL patterns |
| 🖨 | Artisan Commands | summary, watch, clear, export |
📦 Installation
composer require tuser/query-spy
Laravel auto-discovers the service provider — no manual registration needed.
Publish the config:
php artisan vendor:publish --tag=queryspy-config
⚙️ Configuration
Add any of these to your .env (all are optional):
QS_ENABLED=true QS_SLOW_QUERY_MS=100 # Flag queries slower than this (ms) QS_MAX_QUERIES=50 # Alert when queries/request exceed this QS_N_PLUS_ONE=5 # Same SQL pattern N times = N+1 warning QS_SLOW_REQUEST_SECONDS=2 # Flag requests slower than this QS_MEMORY_THRESHOLD_MB=64 # Alert when peak memory exceeds this (MB) QS_INJECT_HEADERS=true # Add X-QuerySpy-* headers to responses QS_LOG_CHANNEL=stack # Laravel log channel for alerts QS_DASHBOARD_URL=/queryspy # Dashboard URL QS_PASSWORD= # Optional dashboard password QS_MAX_LOG_ENTRIES=200 # Max entries kept in storage
Full reference: config/queryspy.php
🖥 Dashboard
Visit /queryspy in your browser after installing.
What you get:
- 7 stat cards — Total, Critical, Warning, Notice, Clean, Avg Duration, Total N+1
- Sidebar — avg queries, avg memory, avg severity score with progress bar
- Timeline chart — request duration (bars) + query count (line), coloured by severity
- Filters — by severity level or issue type (N+1, slow, dupes, memory)
- Search — by URL, route name, or any SQL text
- Pagination — 25 per page
- Auto-refresh — 10-second toggle
- Export CSV / JSON — one-click download
- Per-request drill-down with tabs:
- Summary — all metrics, memory, index hints, SELECT* warnings
- All Queries — time badge, full SQL with Copy button, source
file:line - N+1 — pattern, count, total time, eager-load suggestion, source
- Slow — full SQL, caller, source
- Duplicates — count, source
🌐 Response Headers
When QS_INJECT_HEADERS=true, every response includes:
X-QuerySpy-Queries: 14
X-QuerySpy-Time-Ms: 87.4
X-QuerySpy-Memory-MB: 12.5
X-QuerySpy-Severity: warning
X-QuerySpy-Score: 45
X-QuerySpy-N1: 2
X-QuerySpy-Slow: 1
X-QuerySpy-Duplicates: 0
Visible in your browser's Network tab → select request → Headers.
🖨 Artisan Commands
# Pretty table of recent entries php artisan queryspy:summary php artisan queryspy:summary --limit=50 # Live tail — prints new entries as they arrive php artisan queryspy:watch php artisan queryspy:watch --interval=5 # Wipe all stored logs php artisan queryspy:clear # Export to file php artisan queryspy:export --format=csv php artisan queryspy:export --format=json php artisan queryspy:export --format=csv --output=/tmp/report.csv
📡 JSON API
All endpoints accept ?password= when QS_PASSWORD is set.
GET /queryspy/api → paginated JSON log
GET /queryspy/api?severity=critical
GET /queryspy/api?page=2&per_page=20
GET /queryspy/export/csv → CSV download
POST /queryspy/clear → clear all logs
API response shape:
{
"data": [ ... ],
"stats": { "total": 42, "critical": 3, "warning": 8, ... },
"meta": { "total": 42, "page": 1, "per_page": 50, "last_page": 1 }
}
🌍 Environment Guard
QuerySpy only runs in:
// config/queryspy.php 'environments' => ['local', 'development', 'staging'],
It never runs in production by default, in CLI/Artisan commands, or for URLs matching ignore_urls patterns (/queryspy*, /_ignition*, /telescope*, /horizon*).
🔐 Password Protection
QS_PASSWORD=my-secret
The dashboard shows a password form. Pass ?password=my-secret to API endpoints.
🗂 Issue Types Explained
🔁 N+1 Queries
The same SQL pattern (with bindings normalised to ?) runs 5+ times per request. Classic sign of missing with('relation') in Eloquent.
🐢 Slow Queries
Any individual query taking longer than QS_SLOW_QUERY_MS (default 100ms). Includes full SQL with real binding values and the source file:line.
📄 Duplicate SQL
Identical SQL (including bindings) run more than once — usually a missing cache or a logic loop.
🧠 Memory
Peak PHP memory exceeds QS_MEMORY_THRESHOLD_MB. Also tracks memory growth across the request lifecycle.
⭐ SELECT *
SELECT * on wide tables fetches unnecessary columns, wasting memory and network bandwidth.
🔍 Index Hints
LIKE '%value' (leading wildcard) can't use a B-tree index and results in a full table scan. Consider a full-text index or a dedicated search engine.
🛠 Publishing
# Config php artisan vendor:publish --tag=queryspy-config # Blade views (to customise the dashboard) php artisan vendor:publish --tag=queryspy-views
📝 Changelog
See CHANGELOG.md.
📄 License
MIT © QuerySpy
tuser/query-spy 适用场景与选型建议
tuser/query-spy 是一款 基于 Blade 开发的 Composer 扩展包,目前已累计 4 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 03 月 19 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「performance」 「debugging」 「query」 「monitoring」 「laravel」 「slow-query」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 tuser/query-spy 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 tuser/query-spy 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 tuser/query-spy 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
g4 application profiler package
CSS/Javascript Minificator, Compressor and Concatenator for TYPO3 - highly configurable frontend asset optimization for CSS/JS merging, minification and compression with optional body parsing, async/defer loading, inline output, data-ignore exclusions, SRI integrity validation/calculation, external
WordPress mu-plugin to remove jQuery Migrate from the list of jQuery dependencies and to allow jQuery to enqueue before </body> instead of in the <head>.
Create link to static resources with cache-breaking segment based on md5 of the file
A PHP package that takes a snapshot of your application and allows you to retrieve it later to help with debugging.
Query filtering in your frontend
统计信息
- 总下载量: 4
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 38
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-03-19