Comment être notifié par mail lors d’erreurs Symfony

Symfony fournit un mécanisme de journaux permettant de tracer toute sorte de messages, en leur affectant un niveau de criticité (info, warning, err, …). Ainsi, lorsque l’on constate un comportement anormal, on peut aller voir dans les logs les messages nous permettant de mieux comprendre le problème.

Néanmoins, on ne va pas fouiller ces journaux tous les jours, comment faire pour être automatiquement averti lorsqu’un problème survient ?

Il existe plusieurs plugins, par exemple sfErrorNotifierPlugin ou sfHoptoadNotifierPlugin.

sfErrorNotifierPlugin

sfErrorNotifierPlugin est tout simple, il envoie un mail lorsqu’une exception est levée. Inconvénients :

  • ne se base pas sur le journal, les messages de type ‘err’ par exemple ne seront donc pas nécessairement remontés.
  • se base sur la fonction mail(), ce qui peut parfois être restrictif.

Ces 2 inconvénients sont cependant facilement contournables, faisant de sfErrorNotifierPlugin une excellente solution de secours.

sfHoptoadNotifierPlugin

sfHoptoadNotifierPlugin propose quelques mécanismes très pratiques.

Il s’agit d’un plugin qui, lors d’un problème, va se connecter au site Hoptoad (initialement dédié aux applications Rails) pour lui indiquer le problème.

Les 2 principaux inconvénients de ce plugin sont :

  • comme sfErrorNotifierPlugin, ne se base pas sur le log (mais on va voir plus bas comment contourner ce problème)
  • nécessite une connexion internet (vers http://hoptoadapp.com)

Service Hoptoad

Ce site offre deux services :

  • Envoi de mail lors d’un problème
  • Tableau de bord de suivi des problèmes

Ce qui est très intéressant est que le site détecte s’il s’agit d’erreurs similaires. Ainsi, si une centaine d’erreurs similaires sont déclarées, Hoptoad n’enverra qu’un seul mail.

Ci-dessus, le tableau de bord indique qu’il y a eu 17 erreurs du type “Error while creating new event”.

Le tableau permet également de déclarer qu’un problème a été résolu (dans l’exemple ci-dessus, le 2eme message est grisé car déclaré comme résolu), et si une nouvelle erreur de cette famille survient, un nouveau mail est alors envoyé.

Installation du plugin

Je regrette que ce plugin ne soit ps disponible dans un dépôt Subversion : il utilise git. Toutefois, l’installation reste très simple (je ne fais que reprendre le readme.txt) :

pear channel-discover pear.horde.org
pear install horde/yaml
pear install HTTP_Request
git clone git://github.com/krasio/sfhoptoadnotifierplugin.git \
             plugins/sfHoptoadNotifierPlugin

Puis ajouter dans le app.yml de l’application souhaitée :

all :
    sf_hoptoad_notifier_plugin :
      api_key : you_api_key_goes_here

Et c’est tout !

Ajustement du plugin pour se baser sur le journal

Mon besoin est de détecter les messages de type

dispatcher->connect(
   'application.log',
   array('sfHoptoadNotifier', 'listenToApplicationLogEvent')
) ;

Puis ajouter dans le fichier sfHoptoadNotifier.php la méthode :

static public function listenToApplicationLogEvent(sfEvent $event) {
  $params = $event->getParameters() ;
  // check if there is a log level
  if (isset($params['priority'">err]

et, en début de vie de l’application, détecter les messages de type [warning]. Il suffit de détecter les évènements de type ‘application.log’. Pour cela :

Dans le fichier sfHoptoadNotifierPluginConfiguration.class.php, ajouter à la fin de la méthode configure() le code suivant :

$this</a>)) {
    // level high enough ?
    $log_level_str = sfConfig ::get('app_sf_hoptoad_notifier_plugin_log_level',
                                   'err') ;
    $log_level = constant('sfLogger : :'.strtoupper($log_level_str)) ;

    if ($params['priority'] <= $log_level) {
      // yes.
      $apiKey = sfConfig ::get('app_sf_hoptoad_notifier_plugin_api_key', false) ;
      if ($apiKey) {
        if (!defined('HOPTOAD_API_KEY')) {
          define('HOPTOAD_API_KEY', $apiKey) ;
        }
        $priority_str = sfLogger ::getPriorityName($params['priority']) ;
        $exception = new sfException("'[$priority_str] " . $params[0] . "'") ;
        Hoptoad ::exceptionHandler($exception) ;
      }
    }
  }
}

Enfin, ajouter dans le app.yml le niveau de criticité souhaité :

sf_hoptoad_notifier_plugin :
    api_key : you_api_key_goes_here
    log_level : warning # ou err 

Évidemment, plutôt que de modifier le plugin existant, j’aurais facilement pu faire un nouveau plugin puisque l’on se base sur un type d’évènement différent, mais je pense que le mieux est d’essayer d’enrichir le code de celui qui existe.