onlime / laravel-sql-reporter
在 Laravel 框架中记录 SQL 查询
Requires
- php: ^8.2
- illuminate/container: ^10.15|^11.0
- illuminate/filesystem: ^10.15|^11.0
- illuminate/support: ^10.15|^11.0
Requires (Dev)
- laravel/pint: ^1.14
- mockery/mockery: ^1.0
- orchestra/testbench: ^8.0|^9.0
- pestphp/pest: ^2.34
README
此模块允许您将 SQL 查询记录到 Laravel 框架中的日志文件。当开发应用程序时,它非常有用,可以验证您的查询是否有效,并确保您的应用程序不会运行过多或过慢的数据库查询。
您也可以在生产环境中使用它,因为它不会造成大量开销。记录的查询可以通过查询模式进行限制,并且仅在每次请求或 artisan 命令执行结束时进行记录,而不是每次查询执行时记录。
它报告了许多元数据,如总查询数、总执行时间、来源(请求 URL/控制台命令)、认证用户、应用环境、客户端浏览器代理/IP/主机名。
安装
-
在控制台中运行以下命令安装此模块(注意
--dev
标志 - 建议仅在开发中使用此包)。$ composer require onlime/laravel-sql-reporter --dev
Laravel 使用包自动发现,它将自动加载此服务提供者,因此您不需要在
config/app.php
的providers
部分中添加任何内容。在您的控制台中运行以下命令以发布默认配置文件
-
默认情况下,您不应编辑已发布的文件,因为所有设置都默认从
.env
文件加载。$ php artisan vendor:publish --provider="Onlime\LaravelSqlReporter\Providers\ServiceProvider"
在您的
.env
文件中添加以下条目 -
并根据您的需求调整值。您可以跳过您想使用默认值的变量。
SQL_REPORTER_DIRECTORY="logs/sql" SQL_REPORTER_USE_SECONDS=false SQL_REPORTER_CONSOLE_SUFFIX= SQL_REPORTER_LOG_EXTENSION=".sql" SQL_REPORTER_QUERIES_ENABLED=true SQL_REPORTER_QUERIES_OVERRIDE_LOG=false SQL_REPORTER_QUERIES_INCLUDE_PATTERN="#.*#i" SQL_REPORTER_QUERIES_EXCLUDE_PATTERN="/^\$/" SQL_REPORTER_QUERIES_REPORT_PATTERN='/^(?!select\s|start transaction|commit|(insert into|update|delete from) `(sessions|jobs|bans|logins)`).*/i' SQL_REPORTER_QUERIES_MIN_EXEC_TIME=0 SQL_REPORTER_QUERIES_FILE_NAME="[Y-m]-log" SQL_REPORTER_FORMAT_HEADER_FIELDS="datetime,origin,status,user,env,agent,ip,host,referer" SQL_REPORTER_FORMAT_ENTRY_FORMAT="-- Query [query_nr] [[query_time]]\\n[query]"
如果您还有
.env.example
文件,建议在.env.example
文件中也添加这些条目,以确保每个人都知道这些环境变量。请注意,SQL_REPORTER_DIRECTORY
是存储目录内的目录。如果您只想记录像
INSERT
、UPDATE
、DELETE
这样的 DML/修改查询,但不记录对last_visit
或remember_token
的任何更新,我建议使用SQL_REPORTER_QUERIES_INCLUDE_PATTERN="/^(?!SELECT).*/i" SQL_REPORTER_QUERIES_EXCLUDE_PATTERN="/^UPDATE.*(last_visit|remember_token)/i"
如果您还有
.env.example
文件,建议在.env.example
文件中也添加这些条目,以确保每个人都知道这些环境变量。请注意,SQL_REPORTER_DIRECTORY
是存储目录内的目录。有关这些设置的更多信息,请参阅 配置文件
-
请确保在
.env
文件中指定的目录在存储路径中存在,并且您有在该目录中创建和修改文件的合法权限(如果它不存在,此包将在需要时自动创建它,但建议您手动创建它并设置有效的文件权限)。 -
请确保在生产服务器上,您将在
.env
文件中将记录 SQL 查询设置为 false:SQL_REPORTER_QUERIES_ENABLED=false
。此包建议仅用于开发,以免影响生产应用程序的性能。
可选
GeoIP 支持
对于可选的 GeoIP 支持(将国家信息添加到日志头中的客户端 IP),您可以在项目中安装 stevebauman/location
$ composer require stevebauman/location
$ php artisan vendor:publish --provider="Stevebauman\Location\LocationServiceProvider"
它将被自动检测,无需配置。如果您希望使用默认的 IpApi 之外的驱动程序,例如 MaxMind
,请确保您根据文档正确配置它: 可用驱动程序
QueryLogWritten
事件
该包在日志文件写入后触发一个 QueryLogWritten
事件。您可以使用此事件来进一步调试或分析应用程序中记录的查询。查询通过 SQL_REPORTER_QUERIES_REPORT_PATTERN
设置进行筛选,该设置具有合理的默认值,以排除 SELECT
查询和一些默认表,如 sessions
、jobs
、bans
、logins
。如果您不想筛选任何查询,则可以留空此设置。
除了模式之外,您还可以配置一个回调来定义自己的自定义筛选逻辑,例如,在您的 AppServiceProvider
中。
use Onlime\LaravelSqlReporter\SqlQuery; use Onlime\LaravelSqlReporter\Writer; Writer::shouldReportQuery(function (SqlQuery $query) { // Only include queries in the `QueryLogWritten` event that took longer than 100ms return $query->time > 100; });
使用 SqlQuery
对象,您既可以访问 $rawQuery
也可以访问(未准备的)$query
/$bindings
。通过向 Writer::shouldReportQuery()
提供回调,筛选可能性是无限的!
开发
检出项目并运行测试
$ git clone https://github.com/onlime/laravel-sql-reporter.git $ cd laravel-sql-reporter $ composer install # run both Feature and Unit tests $ vendor/bin/pest # run unit tests with coverage report $ vendor/bin/pest --coverage
常见问题解答
此包与 mnabialek/laravel-sql-logger
有何不同?
此包受到 mnabialek/laravel-sql-logger 的启发,基本上做的是同一件事:记录您的 SQL 查询。以下是区别:
- 查询记录不是在每次查询执行时触发的,而是在最终步骤,使用
RequestHandled
和CommandFinished
事件。 - 这允许我们包括关于整个查询执行的更多信息,如总查询数、总执行时间以及非常详细的标题信息,如来源(请求 URL/控制台命令)、认证用户、应用程序环境、客户端浏览器代理/IP/主机名。
- 此包大大简化,并且仅支持 Laravel 10+ / PHP 8.2+。
- 它使用 Laravel 内置的查询记录(
DB::enableQueryLog()
),将所有查询记录在内存中,这应该比将每个查询都写入日志文件表现更好。 - 默认情况下,
onlime/laravel-sql-reporter
生成的日志输出更加优雅,尤其是在我们只在第一个查询之前写入标题信息之后。
示例日志输出
-- --------------------------------------------------
-- Datetime: 2024-03-11 09:33:22
-- Origin: (request) GET https://:8000/demo
-- Status: Executed 3 queries in 1.85ms
-- User: testuser@example.com
-- Guard: web
-- Env: local
-- Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:123.0) Gecko/20100101 Firefox/123.0
-- Ip: 127.0.0.1
-- Host: localhost
-- Referer:
-- --------------------------------------------------
-- Query 1 [1.45ms]
select * from `users` where `id` = 1 limit 1;
-- Query 3 [0.4ms]
update `users` set `last_visit` = '2021-05-28 15:24:46' where `id` = 1;
相比之下,mnabialek/laravel-sql-logger
的示例日志输出
/*==================================================*/
/* Origin (request): GET https://:8000/mail/api/user
Query 1 - 2021-05-20 21:00:08 [1.4ms] */
select * from `users` where `id` = 1 limit 1;
/*==================================================*/
/* Origin (request): GET https://:8000/mail/api/user
Query 2 - 2021-05-20 21:00:08 [4.72ms] */
update `users` set `last_visit` = '2021-05-20 21:00:08' where `id` = 1;
作者
此出色包的作者是 Philip Iezzi (Onlime GmbH)。
此包的大部分内容是从原始的 mnabialek/laravel-sql-logger 转移过来的。荣誉归 Marcin Nabiałek。请在 GitHub 上为他出色的包点赞!您可以使用 composer thanks
来做到这一点。
更改
所有更改都在 CHANGELOG 中列出
注意事项
- 如果您的应用程序崩溃,则此包不会记录任何查询,因为记录仅在请求周期结束时触发。作为替代,您可以使用 mnabialek/laravel-sql-logger,它在每次查询执行时触发 SQL 记录。
- 目前无法将慢查询记录到单独的日志文件中。我想保持该包简单。
待办事项
- 改进单元测试以实现 100% 覆盖率
- 集成 Coveralls.io 并将测试覆盖率状态徽章添加到 README
- 将浏览器类型信息添加到日志标题中,也许可以使用 hisorange/browser-detect
许可
此包受 MIT 许可证 的许可,但支持总是受欢迎的。