Hace poco leía un interesante artículo en el que explicaban como desarrollar un logger que guardase la información en una base de datos mongo (reconozco que no sabía qué era Mongo hasta que lo leí). Este post me “iluminó” para hacer un experimento simple y de paso aprender algo sobre los logs de symfony.

El experimento
Después de la mini-introducción y el título de este post no habrá que ser muy listo para darse cuenta de que el experimento consiste en conectar el logger de symfony con una cuenta de Twitter de manera que cada vez que hay un mensaje de log se haga un update en una cuenta de twitter, en este caso, esta cuenta es @fTwittyLogger, que es el nombre cariñoso que le he dado a la criatura.

La clase sfLogger
Antes de empezar, un poco de teoría. Cualquier logger en symfony deberá heredar de una otra manera de la clase abstracta sfLogger. Como clientes de esta clase nuestra única preocupación será implementar el método sfLogger::doLog($message, $priority) que recibe dos parámetros, el mensaje que queremos que aparezca en el log y la prioridad del mensaje que puede ser una de las siguientes constantes: EMERG, ALERT, CRIT, ERR, WARNING, NOTICE, INFO y DEBUG.

Además, existen dos métodos que también nos pueden resultar útiles, sfLogger:initialize() y sfLogger::shutdown(), que se ejecutan al principio y el fin del proceso.

Nuestra logger, fTwittyLogger

// lib/fTwittyLogger.class.php
<?php
 
class fTwittyLogger extends sfLogger
{
  protected
    $format     = '[%priority%] %message%';
 
  public function initialize(sfEventDispatcher $dispatcher, $options = array())
  {
 
    parent::initialize($dispatcher, $options);
 
    if (!$this->hasOption('user'))
    {
      throw new sfInitializationException(sprintf('You must provide the twitter username account'));
    }
 
    if (!$this->hasOption('pass'))
    {
      throw new sfInitializationException(sprintf('You must provide the twitter password account'));
    }
 
    $this->user = $this->getOption('user');
    $this->pass = $this->getOption('pass');
 
    return true;
  }
 
  protected function doLog($message, $priority)
  {
    $this->tweet(strtr($this->format, array(
      '%message%'  => $message,
      '%priority%' => $this->getPriority($priority))
    ));
 
  }
 
  protected function getPriority($priority)
  {
    return sfLogger::getPriorityName($priority);
  }
 
  public function hasOption($option)
  {
    return array_key_exists($option, $this->options);
  }
 
  private function tweet($message)
  {
    $context = stream_context_create(array(
      'http' => array(
      'method'  => 'POST',
      'header'  => sprintf("Authorization: Basic %s\r\n", base64_encode($this->user.':'.$this->pass)).
                   "Content-type: application/x-www-form-urlencoded\r\n",
      'content' => http_build_query(array('status' => $message)),
      'timeout' => 5,
      ),
    ));
 
    $ret = file_get_contents('http://twitter.com/statuses/update.xml', false, $context);
 
    return false !== $ret;
  }
}

De arriba a abajo:

  • El método initialize() asegurá que se han pasado el nombre de usuario y la contraseña de la cuenta de twitter
  • El método doLog() twittea el mensaje. El método tweet() es una copia de lo que se hizo en este post

Utilizando fTwittyLogger, modificando factories.yml
Lo último que quedaría sería informar a symfony de que ya no queremos utilizar su logger por defecto y en su lugar queremos utilizar nuestra nueva creación:

// app/config/factories.yml
prod:
  logger:
    class:   fTwittyLogger
    param:
      loggers: ~
      user: fTwittyLogger
      pass: symfony

NOTA: No ha sido un descuido dejar la contraseña, lo he puesto adrede por si alguien quiere hacer alguna prueba que no tenga que andar creando cuentas “zombie” en Twitter.

… pues menuda tontería
Antes de que alguien me ataque de forma despiada, soy consciente de que mostrar tus logs en una cuenta de twitter no tiene ninguna utilidad práctica. Twitter sólo te deja escribir 140 caracteres y además es público pero no se trata de eso sino de explorar y hacer cosas nuevas con el único fin de aprender algo nuevo.


Compártelo:
  • Print this article!
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • LinkedIn
  • Ping.fm
  • RSS
  • Twitter