如何不在独白日志行中显示最后一个括号?

Posted

技术标签:

【中文标题】如何不在独白日志行中显示最后一个括号?【英文标题】:How not to show last bracket in a monolog log line? 【发布时间】:2012-12-07 18:49:00 【问题描述】:
// in my php code
$log = new Logger('LaurentCommand');
$log->pushHandler(new StreamHandler('./app/logs/LaurentCommand.log'));
$log->addInfo("Start command",array('username' => 'Joe', 'Age' => '28'));

日志文件 LaurentCommand.log 中的结果:

[2012-12-20 10:28:11] LaurentCommand.INFO:启动命令 "username":"Joe","Age":"28" []

为什么最后是这个括号?

【问题讨论】:

【参考方案1】:

Symfony 4 解决方案:

    创建记录器:

    use Monolog\Formatter\LineFormatter;
    
    class Formatter extends LineFormatter
    
        public function __construct(
            $format = null,
            $dateFormat = null,
            $allowInlineLineBreaks = false,
            $ignoreEmptyContextAndExtra = false
        ) 
            parent::__construct($format, $dateFormat, $allowInlineLineBreaks, true);
        
    
    

    services.yml中定义格式化程序:

    log.custom.formatter:
      class: App\Formatter
    

    monolog.yml 中为需要的环境定义格式化程序:

    handlers:
      main:
        type: stream
        path: "%kernel.logs_dir%/%kernel.environment%.log"
        level: debug
        channels: ["!event"]
        formatter: log.custom.formatter
    

【讨论】:

【参考方案2】:

老问题,但抛出了另一个简单的选项:

$slackHandler = new \Monolog\Handler\SlackWebhookHandler(...);
$slackHandler->getFormatter()->ignoreEmptyContextAndExtra(true);

【讨论】:

【参考方案3】:

这是额外的数据。 LineFormatter 的默认格式为 "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"。用户名/年龄是上下文,通常为空的额外内容会导致此空数组[]

如果您使用处理器将数据附加到日志记录,它们通常会将其写入额外键以避免与上下文信息冲突。如果这对您来说确实是个问题,您可以更改默认格式并省略 %extra%

编辑:从 Monolog 1.11 开始,LineFormatter 在构造函数中有一个 $ignoreEmptyContextAndExtra 参数,可让您删除这些参数,因此您可以使用它:

// the last "true" here tells it to remove empty []'s
$formatter = new LineFormatter(null, null, false, true);
$handler->setFormatter($formatter);

【讨论】:

Seldaek 的意思是$log = new Logger('LaurentCommand'); $handler = new StreamHandler('./app/logs/LaurentCommand.log'); $handler->setFormatter(new LineFormatter("[%datetime%] %channel%.%level_name%: %message% %context%\n")); $log->pushHandler($handler); $log->addInfo("Start command",array('username' => 'Joe', 'Age' => '28')); 像魅力一样工作。谢谢:)【参考方案4】:

我知道这是一个老问题,但我也遇到过,我想分享我的解决方案。

日志行末尾的括号是由于 Monolog 的 LineFormatter 如何尝试 json_encode() %extra% 中的数据。括号是空数组的 JSON 表示。

要关闭这些括号,我最终不得不用我自己的类继承 Monolog\Formatter\LineFormatter 并覆盖它的 convertToString($data) 函数,因此如果没有数据存在,它会返回一个空字符串。这是我的新子类:

namespace My\Fancy\Monolog;
use Monolog\Formatter\LineFormatter;

class LineFormatter extends LineFormatter 

    protected function convertToString($data)
    
        if (null === $data || is_scalar($data)) 
            return (string) $data;
        

        // BEGIN CUSTOM CODE - This section added to prevent empty 
        // brackets from appearing at the end of log lines:
        if ((is_array($data) && !$data) 
            || is_object($data) && !get_object_vars($data)) 
            return '';
        
        // END CUSTOM CODE 

        $data = $this->normalize($data);
        if (version_compare(PHP_VERSION, '5.4.0', '>=')) 
            return $this->toJson($data);
        

        return str_replace('\\/', '/', json_encode($data));
    

您可以通过将它的一个实例注入到您的 Monolog 处理程序类中来使用该类,如下所示:

$handler = new Monolog\Handler\StreamHandler('/path/to/my/logfile', 'debug');
$handler->setFormatter(new My\Fancy\Monolog\LineFormatter());
$monolog->pushHandler($handler);

享受吧!

【讨论】:

以上是关于如何不在独白日志行中显示最后一个括号?的主要内容,如果未能解决你的问题,请参考以下文章

如何从命令行获取最后 5 分钟的日志

独白发送旧日志

Symfony 独白系统日志格式化程序

Gradle 4.0 不在命令行中显示已执行的任务

当用户不在聊天中时如何显示发送的最后一条消息?

PHP:如何使用独白登录到控制台(php://out)?