2

我想将我的应用程序日志写入另一个文件,而不是 Symfony2 写入自己的日志和系统日志。我知道我需要像这样创建自己的服务:

services:
    actionslogger:
        class: Symfony\Bridge\Monolog\Logger
        arguments: [app]
        calls:
             - [pushHandler, [@actionslogger_handler]]
    actionslogger_handler:
        class: Monolog\Handler\StreamHandler       
        arguments: [%kernel.logs_dir%/actions_%kernel.environment%.log, 200]

当我使用$logger = $this->get('actionslogger');时效果很好 在我的应用程序中,没关系。但我也想使用格式化程序和处理器来管理我的日志写入方式。为此,我使用以下配置:

services:
    actionslogger.formatter.session_request:
        class: Monolog\Formatter\LineFormatter
        arguments:
            - "[%%datetime%%] [%%extra.token%%] %%channel%%.%%level_name%%: %%message%%\n"

    actionslogger.processor.session_request:
        class: My\Bundle\LogProcessor
        arguments:  [ @session ]
        tags:
            - { name: actionslogger.processor, method: processRecord }

我可以将此格式化程序和处理器与 Symfony2 默认记录器与此配置一起使用:

monolog:
    handlers:
        main:
            type:  stream
            path:  %kernel.logs_dir%/%kernel.environment%.log
            level: debug
            formatter: actionslogger.formatter.session_request

但是如果我可以将格式化程序与我自己的记录器一起使用,我就不能使用处理器。这是我的配置:

services:
    actionslogger.formatter.session_request:
        class: Monolog\Formatter\LineFormatter
        arguments:
            - "[%%datetime%%] [%%extra.token%%] %%channel%%.%%level_name%%: %%message%%\n"

    actionslogger.processor.session_request:
        class: My\Bundle\LogProcessor
        arguments:  [ @session ]
        tags:
            - { name: actionslogger.processor, channel: app, method: processRecord, handler: @actionslogger_handler }

    actionslogger:
        class: Symfony\Bridge\Monolog\Logger
        arguments: [app]
        calls:
             - [pushHandler, [@actionslogger_handler]]
    actionslogger_handler:
        class: Monolog\Handler\StreamHandler       
        arguments: [%kernel.logs_dir%/actions_%kernel.environment%.log, 200]
        calls:
             #- [pushProcessor, [???]]
             - [setFormatter, [@actionslogger.formatter.session_request]]

处理器配置中的标签通道和处理程序似乎没用。

我该怎么做才能使处理器与我的记录器一起工作?我应该在注释行中将什么传递给 pushProcessor 方法(如果这可能是一个有效选项)?

谢谢您的帮助。

注意:使用 Symfony 2.0.0

4

2 回答 2

1

将您的processRecord方法重命名为__invoke. 这使得 LogProcessor 实例可调用,并且您将能够将相应的服务作为处理器传递。

于 2015-10-15T15:59:15.500 回答
0

回答我自己:

好吧,我找不到如何设置它,所以我最终得到了这个不太重的解决方案:

我创建了一个非常简单的新记录器,并在构造函数中影响了我全新的处理器,因此文件位于 My/Bundle 中,如下所示:

#LogProcessor.php

use Symfony\Component\HttpFoundation\Session;
class LogProcessor
{
    private $session;
    private $token;
    public function __construct(Session $session)
    {
        $this->session = $session;
    }
    public function processRecord(array $record)
    {
        if (null === $this->token) {
            try {
                $this->token = ($this->session->getId());
            } catch (\RuntimeException $e) {
                $this->token = '????????';
            }
            $this->token .= '#' . substr(uniqid(), -8);
        }
        $record['extra']['token'] = $this->token;
        $record['extra']['context'] = "";
        foreach($record['context'] as $key=>$value) {
            $key=str_replace(array("=","#","|"),"",$key);
            $value=str_replace(array("=","#","|"),"",$value);
            $record['extra']['context'].=$key."=".$value."#";
        }
        return $record;
    }
}

#MyLogger.php

use Symfony\Bridge\Monolog\Logger;
use Symfony\Component\HttpFoundation\Session;
use My\Bundle\LogProcessor;

class MyLogger extends Logger {
    private $session;
    private $processor;

    public function __construct($name, Session $session)
    {
        parent::__construct($name);
        $this->session= $session;
        $this->processor= new LogProcessor($session);
        $this->pushProcessor((array($this->processor, 'processRecord')));
    }   
}

(如果我以后想修改 Logger 的 addRecord 方法,这甚至会派上用场)

然后我创建一个这样的新服务:

#app/config/config.yml or src/My/Bundle/Resources/config/services.yml (if imported in app/config/config.yml)

services:
    mylogger:
        class: My\Bundle\MyLogger
        arguments: [app, @session]
        calls:
             - [pushHandler, [@mylogger.handler]]
    mylogger.handler:
        class: Monolog\Handler\StreamHandler       
        arguments: [%kernel.logs_dir%/actions_%kernel.environment%.log, 200] # 200 means "INFO"
        calls:
             - [setFormatter, [@monolog.formatter.compactformat]]
    monolog.formatter.compactformat:
        class: Monolog\Formatter\LineFormatter
        arguments:
            - "%%datetime%%|%%channel%%|%%level_name%%|%%extra.token%%|%%message%%|%%extra.context%%\n"

我来了。我现在可以使用我的新日志服务和我的格式化程序/和/我的处理器,并用它们做我想做的事情(这里:以易于使用的格式添加会话 ID 和日志上下文信息)。

#MyController.php
public function myMethod() {
    ...
    $logger = $this->get('mylogger');
    $logger->info('ACCESS PAGE', array('user'=>$userName, 'IP'=>$userIP, 'section'=>$section));
    ...
}

无论如何,如果有人回答了我的第一个问题(关于如何直接在配置中链接个人日志服务上的处理器),请在此处发布。

于 2012-07-18T12:33:46.573 回答