Symfony2 : use Processors while logging in different files

前端 未结 2 1501
夕颜
夕颜 2021-01-07 04:22

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

相关标签:
2条回答
  • 2021-01-07 05:04

    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.

    0 讨论(0)
  • 2021-01-07 05:13

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

    0 讨论(0)
提交回复
热议问题