germania-kg/logger

我们公司的默认日志解决方案:Monolog 的 Pimple 服务提供者

4.4.4 2022-05-30 13:43 UTC

README

Germania KG · Logger

我们网站默认的日志解决方案: Monolog 1 和 2 的日志服务提供者。

Packagist PHP version Build Status Scrutinizer Code Quality Code Coverage Build Status

使用 Composer 安装

主要版本 4 需要 PHP 7.2+。较旧版本 3 支持 Monolog 2。

$ composer require germania-kg/logger

基本

LoggerServiceProvider 是一个 Pimple ServiceProviderInterface,可以被注册到任何 Pimple DI 容器 (或数组或 \ArrayAccess)。它的构造函数需要 App 或 Logger 名称。 – 可选地,可以传递 $_SERVER 上下文。可选的第三个参数可以开启 IP 地址匿名化。

<?php
use Germania\Logger\LoggerServiceProvider;

// Have your Pimple or Slim3 Container at hand
$dic = new \Pimple\Container;
$dic->register( new LoggerServiceProvider( "My App" );
               
// Alternatively, pass custom server data environment,
// and/or disable IP address anonymization               
$dic->register( new LoggerServiceProvider( "My App", $_SERVER, false ));

Pimple 不是必需的。

服务提供者还可以处理 数组\ArrayAccess 实例。

以数组为基础,与另一个更现代的 DI 容器一起使用。register 方法修改并返回传递的数组

$dic = array();
$dic = (new LoggerServiceProvider( "My App" ))->register($dic)

或者传递另一个实现 \ArrayAccess 的 DI 容器:

$dic = new MyContainer();
(new LoggerServiceProvider( "My App" ))->register($dic);

提供的服务

这个 Monolog Logger 实例是您的 PSR-3 Logger

<?php
use Psr\Log\LoggerInterface;
use Monolog\Logger as MonologLogger;

// These are equal and refer to the same instance:
$logger = $dic[LoggerInterface::class];
$logger = $dic[MonologLogger::class];

// Deprecated service names
$logger = $dic['Monolog.Psr3Logger'];
$logger = $dic['Logger'];

echo get_class($logger);
// Monolog\Logger

这个 Monolog Handlers 数组默认为空;它将由以下一些特定的 服务提供者 中的一个或多个填充。

除非您想添加除了由特定服务提供者配置的处理器以外的其他处理器,否则不需要使用这些。

$handlers = $dic['Monolog.Handlers'];
print_r($handlers); // Array ...

这个 Monolog Processors 数组默认只包含 Monolog 的 WebProcessor,带有 ipmethodurl 额外上下文变量。

除非您想添加除了由特定服务提供者配置的处理器以外的其他处理器,否则不需要使用这些。

$processors = $dic['Monolog.Processors'];
print_r($processors); // Array ...

向处理器添加处理器

Monolog 处理器 由 Pimple 服务提供。获取处理器实例,并通过扩展服务定义添加另一个 Monolog Processor

$dic->extend( \Monolog\Handler\RotatingFileHandler::class, function($handler, $dic) {
  $handler->pushProcessor( new \Monolog\Processor\IntrospectionProcessor );
  return $handler;
});

特定服务提供者

记录到日志文件

FileLoggerServiceProvider 需要一个 日志文件路径。可选地,您可以传递一个自定义的最大 日志文件数(默认:30)。

要设置日志级别,传递 Monolog Loglevel 常量PSR-3 LogLevel(例如 Monolog\Logger::DEBUG\Psr\Log\LogLevel::INFO)。默认是 Monolog\Logger::DEBUG

<?php
use Germania\Logger\FileLoggerServiceProvider;

// Use with Pimple
$dic = new \Pimple\Container();
$dic->register( new FileLoggerServiceProvider( "log/app.log" ));
$dic->register( new FileLoggerServiceProvider( "log/app.log", 30, \Monolog\Logger::DEBUG));

// Use with \ArrayAccess
$dic = new \Pimple\Container();
(new FileLoggerServiceProvider( "log/app.log" ))->register($dic);

// Use with array
$dic = array();
$dic = (new FileLoggerServiceProvider( "log/app.log" ))->register($dic);

获取 Monolog 处理器

这个处理器是 \Monolog\Handler\RotatingFileHandler 的一个实例

$handler = $dic['Monolog.Handlers.RotatingFileHandler'];
$handler = $dic[\Monolog\Handler\RotatingFileHandler::class];

记录到 StdErr(流)

StreamLoggerServiceProvider 接受可选参数,用于 输出流(默认:php://stderr)和日志级别,可以是 Monolog Loglevel 常量PSR-3 LogLevel(例如 Monolog\Logger::DEBUG\Psr\Log\LogLevel::INFO)。默认是 Monolog\Logger::DEBUG

<?php
use Germania\Logger\StreamLoggerServiceProvider;

// Use with Pimple
$dic = new \Pimple\Container();
$dic->register( new StreamLoggerServiceProvider );
$dic->register( new StreamLoggerServiceProvider("php://stderr", \Monolog\Logger::WARNING) );

// Use with \ArrayAccess
$dic = new \Pimple\Container();
(new StreamLoggerServiceProvider())->register($dic);

// Use with array
$dic = array();
$dic = (new StreamLoggerServiceProvider())->register($dic);

获取 Monolog 处理器

这个处理器是 \Monolog\Handler\StreamHandler 的一个实例

$handler = $dic['Monolog.Handlers.StreamHandler'];
$handler = $dic[\Monolog\Handler\StreamHandler::class];

使用 SwiftMailer 记录

此服务需要 SwiftMailerSwiftMailer.HtmlMessage 的服务定义。Germania KG 的 germania-kg/mailer 将提供这些。

$ composer require germania-kg/mailer

SwiftMailerLoggerServiceProvider 接受可选参数,用于 外部日志级别内部日志级别,两者都可以是 Monolog Loglevel 常量PSR-3 LogLevel(例如 Monolog\Logger::DEBUG\Psr\Log\LogLevel::INFO)。

外部的日志级别(默认:Monolog\Logger::WARNING)将触发 Monolog 的 FingersCrossedHandler,后者又会使用 Monolog 的 BufferHandler 来发送日志消息摘要,并通过 Monolog 的 SwiftMailerHandler 发送。邮件中发送的任何日志消息都将具有 内部日志级别 或更高(默认:Monolog\Logger::DEBUG

<?php
use Germania\Logger\SwiftMailerLoggerServiceProvider;

// Use with Pimple
$dic = new \Pimple\Container();
$dic->register( new SwiftMailerLoggerServiceProvider );
$dic->register( new SwiftMailerLoggerServiceProvider( \Monolog\Logger::WARNING ));

// Use with \ArrayAccess
$dic = new \Pimple\Container();
(new SwiftMailerLoggerServiceProvider)->register($dic);

// Use with array
$dic = array();
$dic = (new SwiftMailerLoggerServiceProvider)->register($dic);

获取 Monolog 处理器

尽管其名称如此,但实际上这个处理器是一个 Monolog\Handler\FingersCrossedHandler 实例,它包装了一个 Monolog\Handler\BufferHandler 实例,而后者又包装了一个 Monolog\Handler\SwiftMailerHandler 实例

$handler = $dic['Monolog.Handlers.SwiftMailerHandler'];
$handler = $dic[\Monolog\Handler\SwiftMailerHandler::class];

使用 CLImate Logger 记录日志

这需要 CLImate,可以通过 Composer 获得:league/climate

$ composer require league/climate

ClimateLoggerServiceProvider 需要一个 Monolog 日志级别常量PSR-3 日志级别(例如 Monolog\Logger::DEBUG\Psr\Log\LogLevel::INFO)。

<?php
use Germania\Logger\ClimateLoggerServiceProvider;

// Use with Pimple
$dic = new \Pimple\Container();
$dic->register( new ClimateLoggerServiceProvider( \Monolog\Logger::DEBUG ));

// Use with \ArrayAccess
$dic = new \Pimple\Container();
(new ClimateLoggerServiceProvider( \Monolog\Logger::DEBUG ))->register($dic);

// Use with array
$dic = array();
$dic = (new ClimateLoggerServiceProvider( \Monolog\Logger::DEBUG ))->register($dic);

获取 Monolog 处理器

注意。这实际上是一个 Monolog\Handler\PsrHandler 实例,它包装了一个 Climate Logger 的 League\CLImate\Logger

$handler = $dic['Climate.PsrLogger.MonologHandler'];

使用 BrowserConsole Logger 记录日志

BrowserConsoleLoggerServiceProvider 可以选择接受一个 Monolog 日志级别常量PSR-3 日志级别(例如 Monolog\Logger::DEBUG\Psr\Log\LogLevel::INFO)。如果省略或设置为 null,则将跳过浏览器控制台记录。

<?php
use Germania\Logger\BrowserConsoleLoggerServiceProvider;

// Use with Pimple
$dic = new \Pimple\Container();
$dic->register( new BrowserConsoleLoggerServiceProvider );
$dic->register( new BrowserConsoleLoggerServiceProvider( \Monolog\Logger::INFO ));

// Use with \ArrayAccess
$dic = new \Pimple\Container();
(new ClimateLoggerServiceProvider)->register($dic);

// Use with array
$dic = array();
$dic = (new ClimateLoggerServiceProvider)->register($dic);

获取 Monolog 处理器

该处理器是一个 Monolog\Handler\BrowserConsoleHandler 实例

$handler = $dic['Monolog.Handlers.BrowserConsoleHandler'];
$handler = $dic[\Monolog\Handler\BrowserConsoleHandler::class];

记录到 Microsoft Teams

使用 Monolog 的 HtmlFormatter 将格式良好的日志消息发送到 Microsoft Teams

这需要 CMDISP 的 monolog-microsoft-teams 包,可以通过 Composer 获得:cmdisp/monolog-microsoft-teams

$ composer require cmdisp/monolog-microsoft-teams "^1.2"

TeamsLoggerServiceProvider 需要一个 入站 Webhook URL 字符串,并且可以选择接受一个 Monolog 日志级别常量PSR-3 日志级别(例如 Monolog\Logger::DEBUG\Psr\Log\LogLevel::INFO)。如果将此 ServiceProvider 注册到 Pimple DI 容器中,并且 Webhook URL 为空,则将静默跳过。

<?php
use Germania\Logger\TeamsLoggerServiceProvider;
use Monolog\Logger;

$incoming_webhook_url="https://outlook.office.com/webhook/many-many-letters";

// Use with Pimple
$dic = new \Pimple\Container();
$dic->register( new TeamsLoggerServiceProvider( $incoming_webhook_url ));
$dic->register( new TeamsLoggerServiceProvider( $incoming_webhook_url, \Monolog\Logger::NOTICE ));

// Use with \ArrayAccess
$dic = new \Pimple\Container();
(new TeamsLoggerServiceProvider( $incoming_webhook_url ))->register($dic);

// Use with array
$dic = array();
$dic = (new TeamsLoggerServiceProvider( $incoming_webhook_url ))->register($dic);

弃用通知

Germania\Logger\HtmlFormattedTeamsLogHandlerCMDISP\MonologMicrosoftTeams\TeamsLogHandler 类的扩展,提供了更好的日志消息格式化。从 CMDISP 的 monolog-microsoft-teams 包的 v1.1 版本开始,这个扩展不再需要,将在主要版本 5 中被删除。

获取 Monolog 处理器

该处理器是一个 \CMDISP\MonologMicrosoftTeams\TeamsLogHandler 实例

$handler = $dic['Monolog.Handlers.TeamsHandler'];
$handler = $dic[\CMDISP\MonologMicrosoftTeams\TeamsLogHandler::class];

记录到 Slack 频道

SlackLoggerServiceProvider 需要一个 Slack 令牌频道用户名。它可以选择接受一个 Monolog 日志级别常量PSR-3 日志级别(例如 Monolog\Logger::DEBUG\Psr\Log\LogLevel::INFO)。

有关使用 Slack 作为日志记录器的更多信息,请参阅以下链接

<?php
use Germania\Logger\SlackLoggerServiceProvider;



// Use with Pimple
$dic = new \Pimple\Container();
$dic->register( new SlackLoggerServiceProvider(
  $slack_token,
  $slack_channel,
  $slack_username,
  \Monolog\Logger::CRITICAL
));

// Use with \ArrayAccess
$dic = new \Pimple\Container();
(new SlackLoggerServiceProvider( ... ))->register($dic);

// Use with array
$dic = array();
$dic = (new SlackLoggerServiceProvider( ... ))->register($dic);

获取 Monolog 处理器

该处理器是一个 \Monolog\Handler\SlackHandler 实例

$handler = $dic['Monolog.Handlers.SlackHandler'];
$handler = $dic[\Monolog\Handler\SlackHandler::class];

用法示例

<?php
use Germania\Logger\LoggerServiceProvider;
use Germania\Logger\FileLoggerServiceProvider;
use Monolog\Logger as Monolog;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;

// 1. Basic setup: Pimple
$dic = new \Pimple\Container();

$log_name     = "My App";
$anonymize_ip = true;
$server_data  = $_SERVER;

$dic->register( new LoggerServiceProvider(
  $log_name,
  $server_data,
  $anonymize_ip
));

// 2. The 'LoggerServiceProvider' alone won't do anything.
//    So, adding a specialized Service Provider is needed:
$max_files_count = 30;
$dic->register( new FileLoggerServiceProvider("log/app.log", 30, Monolog::DEBUG ));
$dic->register( new FileLoggerServiceProvider("log/app.log", 30, LogLevel::DEBUG ));

// 3. Now you can grab your PSR-3 Logger:
$logger = $dic[LoggerInterface::class];
$logger->info("Hooray!");

开发和单元测试

$ git clone https://github.com/GermaniaKG/Logger.git
$ cd Logger
$ composer install

可以将 phpunit.xml.dist 复制到 phpunit.xml 并根据需要调整,或者保持不变。运行 PhpUnit 测试或 composer 脚本,如下所示

$ composer test
# or
$ vendor/bin/phpunit