Wednesday, April 11, 2012

Set up a specific log file for connections with Symfony2

Symfony2 basically embeds a full-featured logger, Monolog. A default implementation is available as 'logger' service. But you may need to log to a specifi file instead of traditional dev/prod/test.log... This article shows how to define a specific logger for connections.

I don't need to re-code a logger, the default one perfectly works. I just need to define a new file to log in, so a Monolog handler and to instanciate a new logger service based on Monolog Logger class. Let's have a look at this services.yml file :

parameters:
    connections_logs_path: %kernel.logs_dir%/connections.log

services:

    alterphp.connection.logger:
        class: Symfony\Bridge\Monolog\Logger
        arguments: [CONNECTION]
        calls:
            - [pushHandler, ['@alterphp.connection.logger_handler']]

    alterphp.connection.logger_handler:
        class: Monolog\Handler\StreamHandler
        arguments: [%connections_logs_path%, 200]

Note that connections_logs_path parameter can be directly set in app/configparameters.ini !

Then, let's see how I will use this logger to log users connections. I pass alterphp.connection.logger service in my AuthenticationSuccessHandler constructor (Read a past article about AuthenticationSuccessHandler implementation).

Service configuration file defining my AuthenticationSuccessHandler, services.yml :

services:

    security.authentication.success_handler:
        class: %security.authentication.success_handler.class%
        public: false
        tags:
            - { name: monolog.logger, channel: security }
        arguments:  ['@router', '@security.user.entity_manager', '@logger', '@alterphp.connection.logger']

And my AuthenticationSuccessHandler :

<php

namespace Acme\DemoBundle\Security\Http\Authentication;

use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\RouterInterface;
use Doctrine\ORM\EntityManager;
use Symfony\Component\HttpKernel\Log\LoggerInterface;

/**
 * Custom authentication success handler
 */
class AuthenticationSuccessHandler implements AuthenticationSuccessHandlerInterface
{

   private $router;
   private $em;
   private $logger;
   private $connectionLogger;

   /**
    * AuthenticationSuccessHandler constructor
    * @param RouterInterface   $router
    * @param EntityManager     $em
    * @param LoggerInterface   $logger
    * @param LoggerInterface   $connectionLogger
    */
   public function __construct(RouterInterface $router, EntityManager $em, LoggerInterface $logger, LoggerInterface $connectionLogger)
   {
      $this->router = $router;
      $this->em = $em;
      $this->logger = $logger;
      $this->connectionLogger = $connectionLogger;
   }

   /**
    * This is called when an interactive authentication attempt succeeds. This
    * is called by authentication listeners inheriting from AbstractAuthenticationListener.
    * @param Request        $request
    * @param TokenInterface $token
    * @return Response The response to return
    */
   function onAuthenticationSuccess(Request $request, TokenInterface $token)
   {
      //On logge spécialement les connexions à Sellermania (login principal)
      $logMess = 'UserID : ' . $token->getUser()->getId();
      $logMess .= '; Username : ' . $token->getUser()->getUsername();
      $logMess .= '; IP : ' . $request->getClientIp();

      $this->connectionLogger->info($logMess);

      return new RedirectResponse($this->router->generate('_home');
   }

And here is what we can read in app/logs/connections.log :


[2012-04-04 16:30:14] CONNECTION.INFO: UserID : 6523; Username : alterphp; IP : 127.0.0.1 [] []

No comments :

Post a Comment

Comments are moderated before being published.