Tym-Project

From: SUPINFO
To: Tous
Subject: IT

Gestion D'un Fichier Journal Basique en Java

Créer un fichier de journalisation peut-être très pratique pour résoudre les plantages d’une application. Mais qui dit fichier dit flux, ouvertures, fermetures…tout un tas de complications en tout genre !

Java propose un outil très pratique pour gérer ce type de problématiques sans trop de difficulté : le Logger.Prenons un exemple concret : une application qui compte de 1 à 10, en faisant des pauses de 10 secondes entre chaque nombre. Chaque action du programme sera écrite dans un fichier avec la date, de même pour les erreurs éventuelles.

Voici donc la classe principale sans la gestion de notre fichier journal :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package hellokitty;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Main {
public static void main(String[] args) {
    for (int i = 1; i < 11; i++) {
        System.out.println(i);
        try {
            Thread.sleep(10000);
        } catch (InterruptedException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
}

On remarque que Logger est déjà utilisé lors du try !

Dans ce tutoriel je ne vais pas rentrer dans les détails de la classe Logger qui est très vaste, je me concentrerai seulement sur la création d’un fichier journal basique.

Les différents journaux sont identifiés par leur nom. Comme nous allons utiliser le même fichier pour enregistrer à la fois le comportement et les erreurs, appelons le “journal”.

Commençons par enregistrer les éléments dans “journal” sans utiliser de fichier :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package hellokitty;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Main {
public static void main(String[] args) {
    for (int i = 1; i < 11; i++) {
        System.out.println(i);
        //On enregistre une nouvelle entrée dans le journal
        Logger.getLogger("journal").log(Level.INFO,"Je suis à la valeur "+i);
        try {
            Thread.sleep(10000);
        } catch (InterruptedException ex) {
            //On réutilise notre journal pour les erreurs
            Logger.getLogger("journal").log(Level.SEVERE, null, ex);
        }
    }
}
}

Tout nos évènements sont maintenant enregistrés dans “journal”. Le code qui suit va écrire ces évènements dans un fichier appelé “journal.txt” :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package hellokitty;
import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Main {
public static void main(String[] args) {
    FileHandler fileHandler = null;
        try {
            //On crée un gestionnaire de fichier par défaut
            fileHandler = new FileHandler("journal.txt");
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    //On assigne le gestionnaire de fichier précédent à notre Logger
    Logger.getLogger("journal").addHandler(fileHandler);
    for (int i = 1; i < 11; i++) {
        System.out.println(i);
        //On enregistre une nouvelle entrée dans le journal
        Logger.getLogger("journal").log(Level.INFO,"Je suis à la valeur "+i);
        try {
            Thread.sleep(10000);
        } catch (InterruptedException ex) {
            Logger.getLogger("journal").log(Level.SEVERE, null, ex);
        }
    }
}
}

Voici un extrait de notre fichier “journal.txt” après le fonctionnement du programme :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?xml version="1.0" encoding="windows-1252" standalone="no"?>
<!DOCTYPE log SYSTEM "logger.dtd">
<log>
<record>
  <date>2009-03-31T14:17:39</date>
  <millis>1238501859578</millis>
  <sequence>0</sequence>
  <logger>journal</logger>
  <level>INFO</level>
  <class>hellokitty.Main</class>
  <method>main</method>
  <thread>10</thread>
  <message>Je suis à la valeur 1</message>
</record>
<record>
  <date>2009-03-31T14:17:49</date>
  <millis>1238501869609</millis>
  <sequence>1</sequence>
  <logger>journal</logger>
  <level>INFO</level>
  <class>hellokitty.Main</class>
  <method>main</method>
  <thread>10</thread>
  <message>Je suis à la valeur 2</message>
</record>

Et oui…c’est du XML ! Pas forcément pratique dans notre cas. C’est pour cela que nous allons configurer notre FileHandler pour créer un fichier non structuré en XML avec la directive fileHandler.setFormatter(new SimpleFormatter());

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package hellokitty;
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 Main {
public static void main(String[] args) {
    FileHandler fileHandler = null;
        try {
            //On crée un gestionnaire de fichier "simple"
            fileHandler = new FileHandler("journal.txt");
            //On assigne une mise en forme simple
            fileHandler.setFormatter(new SimpleFormatter());
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    //On assigne le gestionnaire de fichier précédent à notre Logger
    Logger.getLogger("journal").addHandler(fileHandler);
    for (int i = 1; i < 11; i++) {
        System.out.println(i);
        //On enregistre une nouvelle entrée dans le journal
        Logger.getLogger("journal").log(Level.INFO,"Je suis à la valeur "+i);
        try {
            Thread.sleep(10000);
        } catch (InterruptedException ex) {
            Logger.getLogger("journal").log(Level.SEVERE, null, ex);
        }
    }
}
}

Voici maintenant la forme de notre “journal.txt” :

31 mars 2009 14:22:51 hellokitty.Main main
INFO: Je suis à la valeur 1
31 mars 2009 14:23:01 hellokitty.Main main
INFO: Je suis à la valeur 2

Plus lisible, non ?

Nous allons maintenant améliorer notre FileHandler de telle manière que à chaque lancement du programme le journal soit écrit à la suite du fichier :

fileHandler = new FileHandler("journal.txt");

Mais que va t-il se passer quand le programme aura été lancé un bon millier de fois ? Et bien vous aurez un fichier de log d’une taille très importante…
Ce que je fais habituellement c’est la mise en place d’une rotation de journaux : je travaille sur 5 fichier de 1Mo maximum. Quand le 5ème fichier est remplit, j’écrase le premier etc. Cela me permet de pouvoir remonter assez loin dans le erreurs sans surcharger le disque de l’utilisateur inutilement : fileHandler = new FileHandler("journal%g.txt",1000000, 5, true);
1000000 correspond à 1Mo (en octets) et “journal%g.txt” me donnera “journal1.txt”,”journal2.txt”…

Bonne journalisation ;-)

Comments