IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Logging Java Discussion :

[Logger/Handler/System.err] Throwable.printStackTrace()


Sujet :

Logging Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 268
    Par défaut [Logger/Handler/System.err] Throwable.printStackTrace()
    Bonjour,

    Dans mon application, j'utilise la classe Logger pour gérer la console (ou éventuellement un fichier log) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public void extrait() {
      // NLogger est une classe qui étend Logger
      this.logger = new NLogger("name", null);
      // NLogFormateur est une classe qui étend Formatter
      Handler handler = new StreamHandler(System.out, new NLogFormateur());
      this.logger.addHandler(handler);
    }
    Tout marche bien, sauf lorsque dans une exception, je fais "exception.printStackTrace();" : j'obtiens :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    log
    lognoyau.exception.NEcritureException: message derreur
    	at noyau.ressources.NEcriture.exécuter(NEcriture.java:386)
    où un retour à la ligne manque entre le texte loggé "log" et le début du printStackTrace().
    J'ai essayé les codes suivants :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    System.setErr(System.out);
    this.logger.addHandler(new StreamHandler(System.err, new NLogFormateur()));
    mais rien à faire, il ne passe ni dans le formatteur, ni dans les méthodes "standard" du logger (info,fine(r)(st),config,warning et severe). Et comme je n'arrive pas à tracer pas à pas, en debug, les appels du PrintStream "System.err", je n'arrive pas à comprendre comment corriger mon problème.

    Quelqu'un aurait-il une idée ?

  2. #2
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    ton problème c'est que dans otn système de logging (t'as pas précisé lequel tu utilise accessoirement), quand tu fait

    log("message",exception);

    ca affiche

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    messagejava.lang.Exception blablabla:
    stack
    stack
    stack
    ?

    Dans ce cas, remplace betement ton appel par

    log("message\n",exception).
    La pluspart des logger que je connait commencent le printstacktrace à coté du message (et c'est nécessaire pour pouvoir faire le lien avec le message et la référence de log)

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 268
    Par défaut
    Je sais pas si ça répond à ta première question, mais j'utilise simplement une classe qui étend Logger :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    public static NLogger getNLogger(String name) {
    	LogManager manager = LogManager.getLogManager();
    	Logger result = manager.getLogger(name);
    	if (result == null) {
    		result = new NLogger(name, null);
    		manager.addLogger(result);
    		result = manager.getLogger(name);
    	}
    	//		if(!(result instanceof NLogger))return null;
    	return (NLogger) result;
    }
     
    // Utilisé comme ça :
     
    // Cas d'un fichier
    if (!"none".equals(fichierLog)) {
    	Handler handler = new FileHandler(cheminLog, true);
    	handler.setFormatter(new NLogFormateur());
    	this.logger.addHandler(handler);
    	File file = new File(cheminLog);
    	PrintStream prn = new PrintStream(new FileOutputStream(file,true),true);
    	System.setErr(prn);
    	System.setOut(prn);
    } 
    // Cas de la console (Eclipse)
    else {
    	//System.setErr(System.out);
    	this.logger.addHandler(new StreamHandler(System.out, new NLogFormateur()));
    	//this.logger.addHandler(new StreamHandler(System.err, new NLogFormateur()));
    	this.logger.setConsole(true);
    }
    Pour le "log("message\n",exception).", c'est ce que je faisais. Seulement, j'ai enlevé le "\n", pour me permettre d'ajouter sans retour à la ligne d'autres messages. Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    log("Début du traitement");
    log("Traitement 1 :");
    logAdd("OK");
    donne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Début du traitement
    Traitement 1:OK
    Tout va bien, sauf lors d'exception, puisque quelque soit ce que j'ai testé pour l'instant, les printStackTrace ne passe pas dans mes classes (Logger ou Handler).
    Je peux certes surchargé cette méthode, pour ajouter un retour à la ligne avant le stackTrace, mais ça ne marchera que pour les exceptions que je génère, pas les autres (NullPointerException entre autre).

  4. #4
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    ok, en fait tu fait des printstacktrace en dehors du système de logger. C'est à éviter, tout simplement. Au lieu de faire des printstacktrace, appelle le logger en lui passant l'évènement:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    try{
       log.debug("Début du traitement");
       traitement();
       log.debug("Traitement terminé");
    } catch (UneException e){
       log.error("une erreur c'est produite pendant le traitement",e);
    }
    Maintenant, la notation dépend de l'api de logging que tu utilsie (commons logging, java.util.logging, log4j, Juli, ... ?)

    Aussi, une bonne chose, c'est d'envoyer les log vers un fichier et non pas vers la console Ca évite de mélanger avec les crasse que l'une ou l'autre librairie enverrait vers la console.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 268
    Par défaut
    C'est java.util.logging que j'utilise.
    Dans le développement, c'est la console que nous utilisons (plus facile pour debbuger en direct que de lire un fichier à chaque test). Par contre, en utilisation sur les postes, c'est un fichier.

    Pour le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    try{
       log.debug("Début du traitement");
       traitement();
       log.debug("Traitement terminé");
    } catch (UneException e){
       log.error("une erreur c'est produite pendant le traitement",e);
    }
    c'est ce que je vais faire, cependant le problème est toujours là dans les cas imprévus tel que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    try{
       log.debug("Début du traitement");
       traitement();
       log.debug("Traitement terminé");
    } catch (UneException e){
       log.error("une erreur c'est produite pendant le traitement",e);
    }
    throw new NullPointerException("Oups, celui là n'était pas prévu");
    même si, au fur et à mesure du développement, il y a des "catch (Throwable e)" à différent endroits pour ne pas bloquer les utilisateurs dans ces cas imprévus.

  6. #6
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    puisqu'il n'y a qu'en developpement que ce genre de pollution de la console arrive et uniquement sur les cas imprévu, pourquoi se casser la nenetter à faire des bidouille pour aller les déplacer ailleurs? Surtout, juste pour un retour à la ligne

    PS: catch(Throwable) c'est quand même méchament à éviter: Je doute que tu puisse raisonnablement faire quelque chose des OutOfMemoryError, VirtualMachineError et autre ThreadDeath

    Maintenant, si tu veux faire des traitement utilisant le loggign sur des exception non prévues et non catchées, utilise simplement Thread.setUncaughtExceptionHandler()

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 268
    Par défaut
    Après quelques essais, je vois que j'ai le problème pour tout appel à System.out ou System.err. Outre le problème de ce retour à la ligne, il m'est impossible d'avoir plusieurs logger, et ça, c'est plus embetant.
    Y'a-t-il une FAQ avec des exemples sur la classe Logger ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Handler handler = new FileHandler("c:/logPrincipal", true);
    handler.setFormatter(new NLogFormateur());
    this.logger.addHandler(handler);
    File file = new File("c:/logPrincipal");
    PrintStream prn = new PrintStream(new FileOutputStream(file,true),true);
    System.setErr(prn);
    System.setOut(prn);
     
    // Et pour avoir des logs détaillés, sur certaines parties du logiciel
    Handler handler2 = new FileHandler("c:/logSecondaire", true);
    handler2.setFormatter(new NLogFormateur());
    this.logger.addHandler(handler2);
    Peut être que je m'y prend mal aussi

  8. #8
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    normalement, tu n'a pas besoin d'utiliser des handler des formatteur et un manager custom. Normalement on utilise l'api logging avec un fichier de configuration, c'est beaucoup plus souple que de faire de la config en hard comme tu fais. De plus tu manipule allègrement setErr et setOut, ce que j'éviterais de faire, personellement (ces stream peuvent etre accédés en // et c'est vite compliqué à gérer pour les renvoyer vers le logger, autant les laisser là ou il sont et systématiser dans ton code l'emploi du logger).

    regarde ici, a la fin, y a un exemple de fichier de config
    http://cyberzoide.developpez.com/java/logging/

    et dans la doc api de LogManager, si ma mémoire est bonne, tu trouvera de la doc sur comment fournir ton propre fichier de config (via un -D..... à la ligne de commande).

    Note que perso, je préfère log4j, plus facile à utiliser et à configurer.

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 268
    Par défaut
    Je suis obligé de faire un handler : Il faut bien définir vers quel fichier je log. Formatter étant abstract, je suis aussi obligé de la redéclarer. J'utilise déjà un fichier de configuration, j'ai simplement mis dans les extraits les valeurs prises dans ce fichier.
    Par contre, même si je suis d'accord pour System.out et System.err, je ne vois pas d'autres possibilité que de les manipuler : Si je ne le fais pas, je perd toute trace des éventuels System.out.print() (et donc les stackTrace, puisque ce n'est qu'un "printStackTrace(System.err)").
    Si log4j peut le faire, je devrais bien y arriver aussi . Je n'ai pour l'instant pas le temps de me plonger dans log4j, donc je vais essayer de me débrouiller avec l'API Logging. Et puis elle est de base, donc pourquoi s'en priver :/

  10. #10
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    le problème surtout, à ce que je vois dans ton code, c'est qu'il me sembe que pour chaque logger que tu démarre, tu rebidouille sysout et syserr. Tu devrais, une fois pour toute, le rediriger vers un logger, et faire çà dans l'initialisaiton de ton appli plutot que dans le handler.

    Ensuite, il est vrai que formatter est abstract, mais il existe en base SimpleFormatter et XmlFormatter. Quand au handler, il me semble qu'il et à définir dans le fichier de config de common logging. De cette manière, tu est sur que ce n'est initialisé qu'une seule fois (imagine le bordel si tu défini 5 fois le handler sur le même fichier, tout va se mélanger)

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 268
    Par défaut
    Non, en fait, l'extrait que j'ai mis n'est fais qu'à l'initialisation de l'application, une seule fois. La bidouille sur System.out et err n'est faite qu'à cette endroit.
    Du coup, quand je souhaite un second fichier log, j'y inscrit moi-même les System.ou et err, notamment pour les exceptions, uniquement quand je peux le faire. Autrement dis, les classes que je ne contrôle pas qui exécutent un Throwable.printStackTrace ne sont pas loggées dans ce second fichier

    Tu devrais, une fois pour toute, le rediriger vers un logger
    Justement, c'est ce que je n'arrive pas à faire : D'après ce que j'ai testé, et si j'ai bien compris, je peux rediriger le logger vers System.out (par exemple, quand j'utilise la console d'ecplise), mais pas le contraire. Quand j'utilise Eclipse, ce n'est pas gênant, puisque ces 2 printStream correspondent à la console. Mais quand j'utilise un fichier log, je bidouille sysout et syserr pour rediriger ces flux dans ce fichier (et j'ai donc le problème cité précédement, lors de plusieurs fichiers logs).

Discussions similaires

  1. Réponses: 0
    Dernier message: 19/04/2010, 15h02
  2. System.Web.UI.WebControls.Image et handler
    Par ouadie99 dans le forum ASP.NET
    Réponses: 2
    Dernier message: 23/02/2009, 15h14
  3. [VB6] [Système] Récupérer le contenu d'une fenêtre DOS
    Par Nounours666 dans le forum VB 6 et antérieur
    Réponses: 16
    Dernier message: 18/11/2004, 16h38
  4. [interbase]Se logger après une première installation
    Par Ultra-FX dans le forum InterBase
    Réponses: 3
    Dernier message: 13/09/2002, 11h44
  5. [TP7]systeme d'exploitation
    Par numeror dans le forum Turbo Pascal
    Réponses: 10
    Dernier message: 15/08/2002, 08h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo