Symfony2 : use Processors while logging in different files

谁都会走 提交于 2020-01-11 04:08:07

问题


I want to write my application logs in another file than the one Symfony2 writes its own logs and system logs. I understood that I needed to create a service of my own like this :

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]

That works fine when I use $logger = $this->get('actionslogger'); in my application, so that's ok. But I also want to use a Formatter and a Processor to manage the way my logs are written. To do that, I use this configuration :

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 }

I can use this Formatter and Processor with Symfony2 default logger with this config:

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

But if I can use the Formatter with my own logger, I can't use the Processor. Here's my config:

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]]

The tags channel and handler in the Processor's config seems useless.

What can I do to make the Processor work with my logger? What should I pass to the pushProcessor method in the commented line (if that could be a valid option)?

Thanks for the help.

Note: using Symfony 2.0.0


回答1:


Rename your processRecord method to __invoke. That makes LogProcessor instances callable, and you'll be able to pass the corresponding serice as a processor.




回答2:


Answer to myself:

Well, I couldn't find how to set this, so I ended up with this not-so-heavy solution :

I create a new logger, that is quite simple, and affect it my brand new Processor in the constructor, so the files are in My/Bundle and like this:

#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')));
    }   
}

(That could even come in handy if I want to modify the addRecord method of Logger later)

Then I create a new service like this:

#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"

And here I go. I can now use my new logging service, with my Formatter /and/ my Processor, and do what I want with them (here: adding session id and log context information in an easy-to-use format).

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

Anyway, if someone has the answer for my 1st question (about how to link the processor on a personal logging service, directly in the config), please post here.



来源:https://stackoverflow.com/questions/11520298/symfony2-use-processors-while-logging-in-different-files

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!