Logger

Amélioration du débuggage avec loggers en Java

Ce site ne sera plus alimenté de contenu après août 2014. Tous les nouveaux articles seront redigés pour www.waitingforcode.com

Un bon système des logs est vital pour un bon fonctionnement d'une application web. C'est lui qui permet de suivre tout ce que font les utilisateurs. Il est donc un élément très important pour garantir une bonne maintenabilité de l'application.

Le logging du Java a été défini dans la spécification J2SE. Ce document a pour but de clarifier tout l'éco-système de cette fonctionnalité.

Fonctionnement du Logger en Java

Le flux de contrôle est composé d'un Logger et Handler. Le premier est appelé par l'application pour prendre en charge le message à sauvegarder. Il le passe à Handler qui s'occupe de sauvegarder physiquement le message sur un support précis (fichier, mémoire, socket, stream, console).

Chaque Handler est accompagné d'un Formatter dont le rôle consiste à traduire le message en format faciliement lisible par un humain.

Le message sauvegardé peut avoir un niveau d'importance appartenant à la classe java.util.logging.Level. Les valeurs possibles sont (entre parenthèses est indiqué le niveau d'importance - 7 le plus important, 1 le moins important) :
- SEVERE (7)
- WARNING (6)
- INFO (5)
- CONFIG (4)
- FINE (3)
- FINER (2)
- FINEST (1)

Exemple du Logger en Java

L'exemple d'une classe de log ressemble à une classe qui gère la sauvegarde des données dans un fichier. Toutes les classes des logs sont comprises dans le package java.util.logging. Voici comment ses composants peuvent être rassemblés :

import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

public class LoggerExemple {
    public static void main(String[] args) {
        Logger logger = Logger.getLogger("logg");
        FileHandler fileHandler;
        try {
          fileHandler = new FileHandler("C:\\logfile.log", true);
          logger.addHandler(fileHandler);
          logger.setLevel(Level.ALL);
          SimpleFormatter formatter = new SimpleFormatter();
          fileHandler.setFormatter(formatter);
          logger.log(Level.WARNING, "Warning message");
          logger.log(Level.SEVERE, "Severe message");
          logger.log(Level.INFO, "Info message from Throwable object", new Throwable("Throwable exception"));
      } catch (SecurityException se) {
          System.out.println("SecurityException was catched " + se.getMessage());
      } catch (IOException ioe) {
          System.out.println("IOException was catchted " + ioe.getMessage());
      }
    }
}

Et voici le résultat dans le fichier logfile.log :

déc. 12, 2012 2:47:43 AM LoggerExemple main
WARNING: Warning message
déc. 12, 2012 2:47:43 AM LoggerExemple main
SEVERE: Severe message
déc. 12, 2012 2:47:43 AM LoggerExemple main
INFO: Info message from Throwable object
java.lang.Throwable: Throwable exception
	at LoggerExemple.main(LoggerExemple.java:22)

Plusieurs systèmes des logs open source existent pour Java. Un parmi eux, log4j, est utilisé en tant que systèmes des logs dans application Spring.

Bartosz KONIECZNY Classes

Une question ? Une remarque ?

*

*

Un conseil Symfony2

Un problème avec la définition des valeurs par défaut pour input type checkbox ?

Si vous rencontrez un problème avec la définition des valeurs par défaut pour un champ du type checkbox sous Symfony2, assurez-vous de la conformité des types de ces valeurs. Par exemple, le code suivant ne va pas fonctionner (le checkboxes ne seront pas sélectionnés pour les valeurs indiquées) :

  private $gifts = array(1 => 'apple', 2 => 'orange');
  public function setPreferedGifts($value = array())
  {
    $vals = array();
    foreach($value as $v => $val)
    {
      $vals[] = $val;
    }
    $this->preferedGifts = $vals;
  }
Par contre, le code suivant fonctionnera correctement (les checkboxes seront sélectionnés pour des valeurs passées dans la boucle foreach) :
  private $gifts = array(1 => 'apple', 2 => 'orange');
  public function setPreferedGifts($value = array())
  {
    $vals = array();
    foreach($value as $v => $val)
    {
      $vals[] = (int)$val;
    }
    $this->preferedGifts = $vals;
  }
Pour résumer, si le tableau avec les choix ($gifts dans l'exemple) contient les clés qui sont des integers, les valeurs par défaut doivent aussi être des integers.