onlime/laravel-sql-reporter

在 Laravel 框架中记录 SQL 查询

v1.2.3 2024-09-12 14:36 UTC

This package is auto-updated.

Last update: 2024-09-12 14:39:05 UTC


README

Latest Version on Packagist Packagist Downloads PHP from Packagist Build Status GitHub License

此模块允许您将 SQL 查询记录到 Laravel 框架中的日志文件。当开发应用程序时,它非常有用,可以验证您的查询是否有效,并确保您的应用程序不会运行过多或过慢的数据库查询。

您也可以在生产环境中使用它,因为它不会造成大量开销。记录的查询可以通过查询模式进行限制,并且仅在每次请求或 artisan 命令执行结束时进行记录,而不是每次查询执行时记录。

它报告了许多元数据,如总查询数、总执行时间、来源(请求 URL/控制台命令)、认证用户、应用环境、客户端浏览器代理/IP/主机名。

安装

  1. 在控制台中运行以下命令安装此模块(注意 --dev 标志 - 建议仅在开发中使用此包)。

    $ composer require onlime/laravel-sql-reporter --dev

    Laravel 使用包自动发现,它将自动加载此服务提供者,因此您不需要在 config/app.phpproviders 部分中添加任何内容。

    在您的控制台中运行以下命令以发布默认配置文件

  2. 默认情况下,您不应编辑已发布的文件,因为所有设置都默认从 .env 文件加载。

    $ php artisan vendor:publish --provider="Onlime\LaravelSqlReporter\Providers\ServiceProvider"

    在您的 .env 文件中添加以下条目

  3. 并根据您的需求调整值。您可以跳过您想使用默认值的变量。

    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 是存储目录内的目录。

    如果您只想记录像 INSERTUPDATEDELETE 这样的 DML/修改查询,但不记录对 last_visitremember_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 是存储目录内的目录。

    有关这些设置的更多信息,请参阅 配置文件

  4. 请确保在 .env 文件中指定的目录在存储路径中存在,并且您有在该目录中创建和修改文件的合法权限(如果它不存在,此包将在需要时自动创建它,但建议您手动创建它并设置有效的文件权限)。

  5. 请确保在生产服务器上,您将在 .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 查询和一些默认表,如 sessionsjobsbanslogins。如果您不想筛选任何查询,则可以留空此设置。

除了模式之外,您还可以配置一个回调来定义自己的自定义筛选逻辑,例如,在您的 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 查询。以下是区别:

  • 查询记录不是在每次查询执行时触发的,而是在最终步骤,使用 RequestHandledCommandFinished 事件。
  • 这允许我们包括关于整个查询执行的更多信息,如总查询数、总执行时间以及非常详细的标题信息,如来源(请求 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 许可证 的许可,但支持总是受欢迎的。