danielme85 / laravel-log-to-db
自定义 Laravel 日志通道处理器,可以将日志事件存储到 SQL 或 MongoDB 数据库中。使用 Laravel 本地日志功能。
Requires
- php: ^8.1
- illuminate/support: ^10.0|^11.0
Requires (Dev)
- ext-mongodb: *
- mockery/mockery: ^1.5
- mongodb/laravel-mongodb: ^4
- nunomaduro/collision: ^7.0|^8.0
- orchestra/testbench: ^8.0|^9.0
- phpunit/phpunit: ^10.0
Suggests
- jenssegers/mongodb: Adds support for MongoDB in Laravel/Eloquent
This package is auto-updated.
Last update: 2024-08-31 18:44:11 UTC
README
嗨,这是一个自定义的 Laravel 5.6+ 日志通道处理器,可以将日志事件存储到 SQL 或 MongoDB 数据库中。通过 Monolog 使用 Laravel 本地日志功能。
⚠️ 对于 Laravel 10 及更高版本,请使用此包的版本 4 或更高版本。
对于 Laravel 5.6 到 9,请使用版本 3.x.x。
安装
使用 composer require 或将以下内容添加到 composer.json 中。
composer require danielme85/laravel-log-to-db
如果您使用 SQL 数据库服务器存储日志事件,可以使用包含的迁移。MongoDB 驱动程序不需要迁移。将迁移文件(您也可以在此处进行任何更改或手动将其复制到数据库/migrations 文件夹)复制到您的应用程序中。
php artisan vendor:publish --tag=migrations --provider="danielme85\LaravelLogToDB\ServiceProvider"
运行 Laravel 迁移 artisan 命令。
php artisan migrate
对于可选的 MongoDB 支持,您需要安装 jenseegers/mongodb 扩展到 Laravel
#Optional mongodb support, not required!
composer require jenssegers/mongodb
配置
从 Laravel 5.6 及更高版本开始,您将有一个新的配置文件:"config/logging.php"。您需要在 "channels" 下添加一个数组以配置 Log-to-DB,如下所示
'database' => [ 'driver' => 'custom', 'via' => danielme85\LaravelLogToDB\LogToDbHandler::class ... ],
这是开始所需的最小日志配置设置。请注意,数组索引 'database' 可以是您喜欢的任何字符串,只要它在此日志配置中是唯一的。您还可以给日志通道一个名称,稍后可以在 DB 表的列中引用此名称,这样您就可以有多个日志到数据库的通道。
'channels' => [ 'stack' => [ 'name' => 'Log Stack', 'driver' => 'stack', 'channels' => ['database', 'other-database', 'file'], ], 'database' => [ 'driver' => 'custom', 'via' => danielme85\LaravelLogToDB\LogToDbHandler::class, 'name' => 'Basic DB Logging' ], 'other-database' => [ 'driver' => 'custom', 'via' => danielme85\LaravelLogToDB\LogToDbHandler::class, //'model' => App\Model\Log::class, //Your own optional custom model 'level' => env('APP_LOG_LEVEL', 'debug'), 'name' => 'My DB Log with a bunch more settings', 'connection' => 'default', 'collection' => 'log', 'detailed' => true, 'queue' => false, 'queue_name' => '', 'queue_connection' => '', 'max_records' => false, 'max_hours' => false, 'processors' => [ //Monolog\Processor\HostnameProcessor::class // .. ] ], ... ]
- driver = 必须触发日志驱动程序。
- via = 日志处理器类。
- level = 触发此日志通道的最小错误级别。
- name = 将与日志事件一起存储的通道名称。请注意,如果您使用的是堆栈驱动程序,则使用堆栈数组中的名称值。
- connection = 要使用的 DB 连接(默认为 'default')。
- collection = DB 表或集合名称。(默认:log)。
- detailed = 在异常(如堆栈跟踪)上存储详细日志(默认:true)。
- processors = 额外处理器的数组。这些将在记录的数据中的 'extra' 字段中添加更多信息。有关处理器的更多信息 更多信息关于处理器
有关一些这些选项的更多信息: https://laravel.net.cn/docs/9.x/logging#customizing-monolog-for-channels
在 'logtodb.php' 配置文件中,有一些默认设置和配置日志器的更多信息。如果您想使用供应商发布命令对其进行编辑,可以将其复制到项目中。
php artisan vendor:publish --tag=config --provider="danielme85\LaravelLogToDB\ServiceProvider"
您还可以在 .env 文件中更改这些设置。
LOG_DB_CONNECTION='default'
LOG_DB_DETAILED=false
LOG_DB_MAX=100
LOG_DB_QUEUE=false
LOG_DB_QUEUE_NAME='logToDBQueue'
LOG_DB_QUEUE_CONNECTION='default'
LOG_DB_MAX_COUNT=false
LOG_DB_MAX_HOURS=false
LOG_DB_DATETIME_FORMAT='Y-m-d H:i:s:ms'
请注意:从 v2.2.0 开始,datetime 列将按 logtodb.php 配置文件中给出的格式作为字符串保存,或在 .env 文件中的 LOG_DB_DATETIME_FORMAT 值。
配置优先级顺序
使用 log-to-db 时,您可以在三个地方更改不同的选项
- 配置文件:config/logtodb.php(在执行 vendor:publish 后)。
- 您的 .env 文件将覆盖 logtodb.php 配置文件中的设置。
- Laravel 日志配置文件:config/logging.php。您需要在此处添加一个自定义数组,如上所述,您可以在该数组中指定/覆盖特定日志通道的配置设置。
第1点和第2点设置的配置值将作为默认值应用于您在Laravel日志配置(config/logging.php)中“channels”数组中添加的所有新日志通道。
日志工作队列
保存日志事件时使用队列工作器可能是个好主意。这样,您的服务器就不必等待保存过程完成。您需要配置Laravel队列设置并运行队列监听器。[运行队列工作器](https://laravel.net.cn/docs/6.x/queues#running-the-queue-worker)
队列可以在以下任何位置启用/禁用
- LOG_DB_QUEUE = true | 在 .env 文件中
- queue_db_saves => true | 在 config/logtodb.php 文件中
- queue => true | 在日志通道配置数组中 -> config/logging.php
使用
由于这是一个针对Laravel的自定义日志通道,因此所有“标准”的生成日志事件等方法都应该与Laravel Log Facade一起工作。更多信息请见[日志文档](https://laravel.net.cn/docs/6.x/logging)。
Log::debug("This is an test DEBUG log event"); Log::info("This is an test INFO log event"); Log::notice("This is an test NOTICE log event"); Log::warning("This is an test WARNING log event"); Log::error("This is an test ERROR log event"); Log::critical("This is an test CRITICAL log event"); Log::alert("This is an test ALERT log event"); Log::emergency("This is an test EMERGENCY log event");
您也可以将日志记录到特定的日志通道:Log::channel('database')->debug("这是一个测试DEBUG日志事件");
获取日志
此通道的日志通过Eloquent模型构建器完成。LogToDB::model($channel, $connection, $collection); 可以省略所有函数变量和config/logtodb.php中的默认设置。
$model = LogToDB::model(); $model->get(); //All logs for default channel/connection
获取日志的更多示例
$logs = LogToDB::model()->get(); $logs = LogToDB::model()->where('level_name', '=', 'INFO')->get();
当获取特定通道或数据库连接和集合的日志时,您可以使用与config/logging.php匹配的通道名称或config/databases.php中的连接名称。如果需要,您还可以在获取模型时指定集合/表名称作为第三个函数变量。
$logsFromDefault = LogDB::model()->get(); //Get the logs from the default log channel and default connection. $logsFromChannel = LogDB::model('database')->get(); //Get logs from the 'database' log channel. $logsFromChannel = LogDB::model('customname')->get(); //Get logs from the 'customname' log channel. $logsFromMysql = LogToDB::model(null, 'mysql')->get(); //Get all logs from the mysql connection (from Laravel database config) $logsFromMongoDB = LogToDB::model(null, 'mongodb')->get(); //Get all logs from the mongodb connection (from Laravel database config) $logsFromMysqlTable = LogToDB::model(null, 'mysql', 'table')->get(); //Get all logs from the mysql table: 'table'
自定义 Eloquent 模型
由于Laravel预计将使用静态定义的集合/表名称,因此使用您自己的模型可能更好,以更稳健的方式。您可以通过在配置中引用它并添加“LogToDbCreateObject”特性来使用您自己的Eloquent模型。
SQL
namespace App\Models; use danielme85\LaravelLogToDB\Models\LogToDbCreateObject; use Illuminate\Database\Eloquent\Model; class CustomLog extends Model { use LogToDbCreateObject; protected $table = 'log'; protected $connection = 'mysql'; }
MongoDB
namespace App\Models; use danielme85\LaravelLogToDB\Models\LogToDbCreateObject; use Jenssegers\Mongodb\Eloquent\Model as Eloquent; class CustomLogMongo extends Eloquent { use LogToDbCreateObject; protected $collection = 'log'; protected $connection = 'mongodb'; }
LOG_DB_MODEL='App\Models\CustomLog'
警告:通过动态Eloquent模型(默认行为)获取模型可能会产生一些副作用,因为表和连接是动态声明的,而不是在模型类中分配属性。某些函数可能会损坏,如LogToDB::model->all(),而LogToDB::model->where()->get()将按正常工作。使用您自己的模型可以避免这些问题。
模型闭包和观察者
您可以在上述自定义应用程序模型上添加闭包,或者为默认的LogToDb模型添加模型观察者。
创建观察者
<?php
namespace App\Observers;
use danielme85\LaravelLogToDB\Models\DBLog;
class LogObserver
{
public function created(DBLog $log)
{
//
}
}
然后将它添加到您的AppServiceProvider(或调用app boot函数的另一个提供者)。
namespace App\Providers;
use App\Observers\LogObserver;
use danielme85\LaravelLogToDB\LogToDB;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
LogToDB::model()->observe(LogObserver::class);
}
}
添加表/扩展集合
SQL日志处理器期望以下模式
Schema::create('log', function (Blueprint $table) { $table->increments('id'); $table->text('message')->nullable(); $table->string('channel')->nullable(); $table->integer('level')->default(0); $table->string('level_name', 20); $table->integer('unix_time'); $table->text('datetime')->nullable(); $table->longText('context')->nullable(); $table->text('extra')->nullable(); $table->timestamps(); });
这是本插件附带迁移。您可以添加任意数量的表,并在'collection'配置值中引用它们。集合=表,我使用集合这个术语,因为它适用于SQL和非SQL。MongoDB不需要迁移。
默认情况下不会添加索引,所以如果您基于特定的时间范围或类型获取大量日志结果:添加一些索引可能是个好主意。
日志清理
有一些配置值您可以设置,以指定保留日志记录的最大数量或最大记录年龄(以小时为单位)。
- logging.php通道数组 -> (max_records, max_hours)。
- .env文件 -> (LOG_DB_MAX_COUNT, LOG_DB_MAX_HOURS)。
这些选项默认设置为false,在运行“log:delete” artisan命令之前必须将它们设置为所需的整数。
php artisan log:delete
此命令将根据上述设置删除记录。将此命令添加到Console/kernel.php,或手动在cron等中运行以启用自动清理。
手动清理
存在一个辅助函数,用于删除最旧的日志事件并保留指定数量
LogToDB::removeOldestIfMoreThan(100);
或者根据日期(必须是strtotime()支持的有效日期/日期时间) https://php.ac.cn/manual/en/function.strtotime.php
LogToDB::model()->removeOlderThan('2019-01-01'); LogToDB::model()->removeOlderThan('2019-01-01 23:00:00');
处理器
Monolog附带了一组处理器,这些处理器将生成额外的数据并填充'extra'字段。我还在这个包的src/Processors目录下添加了一些示例处理器。要启用处理器,可以将它们添加到日志配置数组中
'database' => [ 'driver' => 'custom', 'via' => danielme85\LaravelLogToDB\LogToDbHandler::class ... 'processors' => [ \danielme85\LaravelLogToDB\Processors\PhpVersionProcessor::class, Monolog\Processor\HostnameProcessor::class, ]
您也可以创建自己的自定义处理器,确保它们实现了Monolog\Processor\ProcessorInterface。
自定义处理器的示例
<?php namespace App\CustomProcessors; use Monolog\Processor\ProcessorInterface; class PhpVersionProcessor implements ProcessorInterface { /** * @return array The processed record */ public function __invoke(array $record) { $record['extra']['php_version'] = phpversion(); return $record; } }
更多的logging.php配置示例
'default' => env('LOG_CHANNEL', 'stack'), 'channels' => [ 'stack' => [ 'driver' => 'stack', 'channels' => ['database', 'mongodb', 'single'], ], 'database' => [ 'driver' => 'custom', 'via' => danielme85\LaravelLogToDB\LogToDbHandler::class, 'level' => env('APP_LOG_LEVEL', 'debug'), 'connection' => 'default', 'collection' => 'log' 'detailed' => true, 'queue' => true 'queue_name' => 'logQueue' 'queue_connection' => 'redis', 'max_records' => 1000, 'max_hours' => 24, ], 'mongodb' => [ 'driver' => 'custom', 'via' => danielme85\LaravelLogToDB\LogToDbHandler::class, 'level' => 'debug', 'connection' => 'mongodb', 'collection' => 'log', 'detailed' => true, 'queue' => true 'queue_name' => 'logQueue' 'queue_connection' => 'redis' ], 'limited' => [ 'driver' => 'custom', 'via' => danielme85\LaravelLogToDB\LogToDbHandler::class, 'level' => 'warning', 'detailed' => false, 'max_rows' => 10, 'name' => 'limited', ] 'single' => [ 'driver' => 'single', 'path' => storage_path('logs/laravel.log'), 'level' => env('APP_LOG_LEVEL', 'debug'), ], //.... ]
Lumen 安装
-
在项目的根目录下创建一个配置文件夹(如果您还没有的话),然后在那里添加一个logging.php配置文件。以Laravel logging.php配置文件作为示例/起点。您还可以将Laravel配置文件夹中的所有其他“缺失”的配置文件添加到您的Lumen项目中。
-
要使用这些配置文件,您必须在您的应用的bootstrap/app.php文件中加载它们(或添加自己的服务提供者文件并在该文件中加载它)。
您还需要确保通过以下方式设置logtodb所需的所有基本配置值
- 从该插件的配置文件夹中复制logtodb.php文件
- 或者只需将所有日志到数据库的选项添加到您的应用的config/logging.php文件中(可能是最简单的方法)。只需遵循配置部分下面的配置示例。
由于我们使用Lumen,我们需要在"bootstrap/app.php"文件中指定配置和服务提供者。
/*
|--------------------------------------------------------------------------
| Register Config Files
|--------------------------------------------------------------------------
|
| Now we will register the "app" configuration file. If the file exists in
| your configuration directory it will be loaded; otherwise, we'll load
| the default version. You may register other files below as needed.
|
*/
$app->configure('app');
//$app->configure('logtodb'); //if you copied over and want to use the base config from logtodb.
$app->configure('logging');
下一步是注册服务提供者,可以在bootstrap/app.php中或在app/Provider/AppServiceProvider中完成。
/*
|--------------------------------------------------------------------------
| Register Service Providers
|--------------------------------------------------------------------------
|
| Here we will register all of the application's service providers which
| are used to bind services into the container. Service providers are
| totally optional, so you are not required to uncomment this line.
|
*/
// $app->register(App\Providers\AppServiceProvider::class);
// $app->register(App\Providers\AuthServiceProvider::class);
// $app->register(App\Providers\EventServiceProvider::class);
$app->register(\danielme85\LaravelLogToDB\ServiceProvider::class);
添加服务提供者后,您应该能够在Lumen中运行数据库迁移
php artisan migrate --path=vendor/danielme85/laravel-log-to-db/src/migrations/2018_08_11_003343_create_log_table.php
请注意,此时您需要在Lumen中有一个正常工作的数据库连接。
然后可能就成功了... ¯_(ツ)_/¯
使用工作队列将日志写入Lumen数据库
在您可以使用队列之前,需要在Lumen中设置队列驱动程序(默认为:QUEUE_CONNECTION=sync,这基本上是没有队列)。有关Lumen文档中队列的更多信息队列(它们与Laravel大致相同)。我建议使用Redis队列驱动程序,但数据库也应该可以工作。
如何在Lumen中使Redis工作(一般方法)。
通过命令安装
composer require predis/predis
composer require illuminate/redis
或者添加到composer.json
...
"require": {
"predis/predis": "~1.0",
"illuminate/redis": "5.0.*",
...
或安装predis的其他替代品。
在bootstrap/app.php文件中添加服务提供者并启用eloquent(如果您使用模型/模型帮助类来获取新的日志事件,则Eloquent是必需的);
$app->withFacades();
$app->withEloquent();
$app->register(Illuminate\Redis\RedisServiceProvider::class);
if (!class_exists('Redis')) {
class_alias('Illuminate\Support\Facades\Redis', 'Redis');
}
现在您可以设置.env值以使用Redis作为队列和缓存,如果需要的话
REDIS_CLIENT=predis
QUEUE_CONNECTION=redis
CACHE_DRIVER=redis
使用 Docker 进行本地测试
有一个名为'runLocalTestInDocker.sh'的辅助bash脚本,该脚本运行以下Docker命令
docker-compose up -d mariadb mongo &&
docker-compose up php7 &&
docker-compose up php8 &&
docker-compose down
要运行Docker,需要给脚本执行权限并运行
chmod +x runLocalTestInDocker.sh &&
./runLocalTestInDocker.sh