delatbabel / applog
Laravel 应用程序和审计日志包。
Requires
- php: >=5.4.0
- laravel/framework: 5.1.*
This package is not auto-updated.
Last update: 2024-09-10 18:45:49 UTC
README
Laravel 5 的应用程序和审计日志包。
这个包基于我一些时间以来一直保留的代码。它为 Laravel 提供了一个数据库支持的日志,可以写入调试、信息和错误日志。它还提供了一个审计日志特性,可以将该特性附加到任何模型上,以自动记录该模型的创建和更新记录。
功能
此包扩展了现有的 Laravel 5 日志记录器,具有以下功能
- 添加一个日志监听器,以便应用程序(调试、信息、错误)日志不仅写入磁盘日志文件,还写入 applogs 数据库表。
- 扩展应用程序日志,包括记录日志条目时记录的类名、函数名、文件名和行号等信息。
- 添加审计日志数据库模型的功能,以便将数据库更改记录为 applogs 表中的审计日志。
- 当 app.debug 配置变量设置为 false 时,关闭所有调试日志。
此包包含以下类和特性
- Applog -- 允许将日志写入数据库的模型类。
- Auditable -- 一个可以应用于任何模型类的特性,允许自动审计表中的任何更改。
安装
将以下行添加到您的 composer.json 文件中
"require": {
"delatbabel/applog": "~1.0"
},
完成之后,运行 composer update 命令
composer update
或者直接运行此命令
composer require delatbabel/applog
注册服务提供者
在 composer update 完成后,将此行添加到您的 config/app.php 文件中的 'providers' 数组中
Delatbabel\Applog\DebugServiceProvider::class,
启动日志写入器
修改 app/Console/Kernel.php 和 app/Http/Kernel.php 中的每个文件,包括以下启动器函数
protected function bootstrappers() { $bootstrappers = parent::bootstrappers(); // Swap out the default Laravel ConfigureLogging class with our own. foreach ($bootstrappers as $key => $value) { if ($value == 'Illuminate\Foundation\Bootstrap\ConfigureLogging') { $bootstrappers[$key] = 'Delatbabel\Applog\Bootstrap\ConfigureLogging'; } } return $bootstrappers; }
注意,Delatbabel\Applog\Bootstrap\ConfigureLogging 替换了原始类 Illuminate\Foundation\Bootstrap\ConfigureLogging。您当然可能已经在 Kernel.php 文件中有其他启动器函数,其中已替换了其他启动器,在这种情况下,您只需修改它以包括更新的 ConfigureLogging 启动器代码即可。
合并和运行迁移
最后,合并并运行迁移脚本,创建以下数据库表
php artisan vendor:publish --tag=migrations --force
php artisan migrate
示例
审计日志
为了为一个模型类启用审计日志,请使用以下代码
use Delatbabel\Applog\Models\Auditable; class MyModel { use Auditable; // ... remainder of the model code }
现在将记录模型的变化到 applogs 表中。注意,有一个 Applog 模型类(Delatbabel\Applog\Models\Applog),您可以使用它来操作此表,请确保您在那个模型类中不要使用 Auditable 特性,否则会导致无限循环并填充数据库。
调试和错误日志
要在代码中使用调试日志,请使用以下代码
Log::debug(__CLASS__.':'.__TRAIT__.':'.__FILE__.':'.__LINE__.':'.__FUNCTION__.':'. 'POST login');
注意,第二行上的消息可以是您想要的任何内容 - 描述性。第一行应该恰好按上述方式书写。
您可以将 debug 函数名替换为 RFC 5254 中的任何日志级别,这些级别是 debug、info、notice、warning、error、critical 和 alert。所有这些都将写入 applogs 表以及磁盘文件。当 config/app.php 中的 debug 配置变量设置为 false 时,将不会写入 debug 级别的消息。
您可以将上下文数组作为 Log::debug 语句的第二个参数提供,如下所示
Log::debug(__CLASS__.':'.__TRAIT__.':'.__FILE__.':'.__LINE__.':'.__FUNCTION__.':'. 'POST login', ['attributes' => $attributes ]);
整个数组将被JSON编码并存储在applogs表的details字段中。您可以使用此功能在日志记录时捕获任何任意集合的变量。
辅助函数 -- get_user_name()
审计日志尝试捕获每次更改时登录的每个用户的用户名。为此,提供一个全局函数get_user_name(),返回一个字符串(用户名、电子邮件地址或其他标识符)。
以下是一个使用Cartalyst Sentinel外观的此类函数的示例
use Cartalyst\Sentinel\Laravel\Facades\Sentinel; function get_user_name() { // Fetch the currently logged in user try { $user = Sentinel::getUser(); $username = $user ? $user->email: ''; } catch (\Exception $e) { // Ignore } return $username; }
如果函数不存在或返回空值,将使用一些后备值,如果没有找到用户名,最终将使用"system"。
架构
本节解释了包的架构以及我在编码过程中所做的决策。
引导
Laravel包含一个名为Illuminate\Foundation\Http\Kernel的类,该类处理在Http模式下的应用程序引导,还有一个类似的类用于控制台模式下的引导。这两个类通常在应用程序中的App\Http\Kernel和App\Console\Kernel类中分别扩展。
这些类中每个都加载了许多需要引导的核心类,包括Laravel日志记录器。
这些类中每个都包含一个$bootstrappers数组,该数组包含要引导的类列表,以及一个bootstrappers()函数,该函数返回该数组的内容。最初我覆盖了$bootstrappers数组,但我发现它在Laravel的不同补丁版本中有所不同,所以我选择扩展bootstrappers()函数(或至少提供如何扩展它的文档),以便它返回$bootstrappers数组的修改版。
日志写入器
创建Monolog日志写入器很简单,只需创建一个实现LogContract和PsrLoggerInterface接口的Writer类。我选择扩展原始的Illuminate\Log\Writer类,以提供基本的Laravel日志记录功能以及我选择的任何附加功能。
我的扩展日志写入器类是Delatbabel\Applog\Log\Writer,我所做的唯一更改是将debug()函数扩展为如果应用程序调试模式关闭,则丢弃日志消息。
附加写入器
有一个额外的函数通过将闭包传递给Log::listen调用来拦截日志监听器事件。这发生在服务提供程序的引导中,即Delatbabel\Applog\DebugServiceProvider::boot函数。
这就是数据库支持的日志记录发生的地方,即写入Applog模型。
记录器
在原始的Illuminate\Foundation\Bootstrap\ConfigureLogging类中有一个名为registerLogger的函数,它创建"log"应用程序实例并将其绑定到一个新的Monolog写入器上。不幸的是,这个Monolog写入器是在registerLogger函数内部作为一个对象实例创建的,因此不能被修改或扩展。
唯一的替代方案是创建一个新的ConfigureLogging类,它为相同的"log"应用程序实例提供不同的对象实例,在这种情况下,提供了Delatbabel\Applog\Log\Writer类。
理想情况下,日志写入器的创建将与它们在应用程序中的注册分开进行。例如,我会创建一个ConfigureLogging类,该类从应用程序配置中查找日志写入器的数组,然后将其作为实例传递给Monolog框架。
创建多个符合Monolog规范的日志写入器相对简单,Monolog支持多个写入器订阅日志事件的想法,这会创建一个更模块化的日志架构。不幸的是,Laravel没有通过以这种方式初始化记录器来充分利用Monolog框架的完整功能。
审计日志
审计日志记录比一般日志记录要简单得多,因为在这个阶段,我们只对模型保存到数据库的具体事件感兴趣。
所有这些都在Delatbabel\Applog\Models\Auditable特性中处理。
首先,这是Laravel的一个标准特性,在启动每个附加到模型上的特性时会调用bootTrait()方法。因此,当启动包含Auditable特性的任何模型时,会自动调用bootAuditable()函数。
bootAuditable()特性设置了一个监听器,用于监听Laravel的"eloquent.saved: $classname"事件,该事件在每次保存模型时都会触发。监听器是一个闭包,它只是调用内部(公共静态)的eventAuditLogger()方法。
eventAuditLogger()执行审计日志的实际工作——将条目写入applogs表。
请注意,我选择使用DB::table()->insert()调用来写入数据,而不是创建一个Applog模型并保存它,以防有人不小心将Auditable特性绑定到Applog模型上(这将创建一个无限循环)。
通过这种方式,我实际上创建了一个新的日志级别,称为"audit"。
再次强调,在理想的世界里,每个审计事件都会简单地向Monolog框架发出调用,并且可以在框架中附加一个Monolog兼容的写入实例来监听并记录所有审计事件并记录日志,但Laravel目前并不是这样构建的。