web-dev-qa-db-fra.com

Configuration de Log4j - différents journaux dans différents fichiers

Cela peut être une question très facile pour certains, mais personnellement, je trouve que la configuration de Log4j est terriblement difficile et que l'apprentissage de la chirurgie cérébrale peut être moins difficile.

J'essaie de laver plusieurs enregistreurs se connectant à différents fichiers. Voici ce que j'ai dans mon fichier log4j.properties:

# Root logger option
log4j.rootLogger=INFO, file, admin

# Direct log messages to a log file
log4j.appender.file=org.Apache.log4j.RollingFileAppender
log4j.appender.file.File=/home/nick/logging/file.log
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=1
log4j.appender.file.layout=org.Apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n

log4j.appender.admin=org.Apache.log4j.RollingFileAppender
log4j.appender.admin.File=/home/nick/logging/admin.log
log4j.appender.admin.MaxFileSize=1MB
log4j.appender.admin.MaxBackupIndex=1
log4j.appender.admin.layout=org.Apache.log4j.PatternLayout
log4j.appender.admin.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n

Et voici mon (très simple) Java app utilisée pour tester la config:

public static void main(String[] args) throws Exception {

    Properties resource = new Properties();
    InputStream in = new FileInputStream("/home/nick/logging/log4j.properties");
    resource.load(in);
    PropertyConfigurator.configure(resource);

    Logger admin = Logger.getLogger("admin");
    Logger file = Logger.getLogger("file");

    admin.info("hello admin");
    file.info("hello file");
}

J'ai 2 problèmes:

Un problème, je reçois toujours une exception dans la ligne PropertyConfigurator.configure(resource);:

Java.io.FileNotFoundException: /home/nick/logging (Is a directory)
 at Java.io.FileOutputStream.open(Native Method)
 at Java.io.FileOutputStream.<init>(FileOutputStream.Java:212)
 at Java.io.FileOutputStream.<init>(FileOutputStream.Java:136)
 at org.Apache.log4j.FileAppender.setFile(FileAppender.Java:289)
 at org.Apache.log4j.RollingFileAppender.setFile(RollingFileAppender.Java:167)
 at org.Apache.log4j.FileAppender.activateOptions(FileAppender.Java:163)
 at org.Apache.log4j.config.PropertySetter.activate(PropertySetter.Java:256)

Le deuxième problème est que les deux messages sont écrits dans les deux journaux. Voici le résultat réel:

Administrateur du fichier: journal:

2014-04-27 11:55:30 INFO  admin - hello admin
2014-04-27 11:55:30 INFO  file - hello file

Fichier file.log:

2014-04-27 11:55:30 INFO  admin - hello admin
2014-04-27 11:55:30 INFO  file - hello file

Voici le résultat obligatoire:

Administrateur du fichier: journal:

2014-04-27 11:55:30 INFO  admin - hello admin

Fichier file.log:

2014-04-27 11:55:30 INFO  file - hello file

Quelle est la cause de l'exception et comment puis-je obtenir le résultat requis?

26
NickJ

Log4J fait une distinction entre enregistreurs , qui sont responsables de la génération des messages de journal, et appender , qui sont chargés d'envoyer ces messages quelque part (un fichier, la console, une base de données, etc.). Les enregistreurs forment une hiérarchie, l'enregistreur racine est le parent de l'enregistreur nommé admin, qui est le parent de admin.component1, etc., et vous pouvez attacher des annexes à n'importe quel enregistreur de la hiérarchie. Par défaut, un enregistreur enverra des messages à tous les ajouteurs qui lui sont directement attachés, ou à l'un de ses ancêtres dans la hiérarchie (c'est pourquoi les enregistreurs sont conventionnellement nommés comme Java classes, par exemple, vous pouvez journal de contrôle pour com.example.Class1 et com.example.subpkg.AnotherClass en configurant le com.example enregistreur).

Les enregistreurs et les appendeurs forment des espaces de noms séparés et c'est la source de votre confusion - l'enregistreur nommé admin et l'appender nommé admin sont deux entités distinctes.

La configuration que vous avez donnée dans la question définit un enregistreur (l'enregistreur racine) qui envoie tous les messages qu'il génère à deux appendereurs distincts , un pour chacun des les deux fichiers. Votre code demande ensuite deux enregistreurs différents et génère un message de journal avec chaque enregistreur. Ces deux enregistreurs héritent de la configuration de l'appender de l'enregistreur racine, ils envoient donc tous les deux leurs messages à les deux des appenders configurés.

enter image description here

Au lieu d'attacher les deux ajouts à l'enregistreur racine, vous devez attacher l'appendice file à l'enregistreur file et l'appendice admin à l'enregistreur admin:

log4j.rootLogger=INFO
log4j.logger.file=INFO, file
log4j.logger.admin=INFO, admin

De cette façon, l'enregistreur file n'enverra des messages qu'à file.log, l'enregistreur admin uniquement pour admin.log, et tous les messages des autres enregistreurs seront supprimés en silence, car il n'y a aucun ajout attaché à la racine.

enter image description here


L'indicateur d'additivité est l'exception à cette règle - définir l'additivité d'un enregistreur sur false déconnecte essentiellement la flèche d'un enregistreur jusqu'à son parent, donc les messages générés par cet enregistreur (ou y coulant depuis l'un de ses enfants) ne remontera pas plus haut dans l'arbre, ils iront seulement aux appendeurs attachés directement à la enregistreur en question.

84
Ian Roberts

Pour répondre à ma propre question, voici ce dont j'avais besoin:

log4j.logger.file=DEBUG, fileAppender
log4j.logger.admin=DEBUG, adminAppender

log4j.additivity.file=false
log4j.additivity.admin=false

log4j.appender.fileAppender=org.Apache.log4j.RollingFileAppender
log4j.appender.fileAppender.File=/home/nick/logging/file.log
log4j.appender.fileAppender.MaxFileSize=1MB
log4j.appender.fileAppender.MaxBackupIndex=1
log4j.appender.fileAppender.layout=org.Apache.log4j.PatternLayout
log4j.appender.fileAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n

log4j.appender.adminAppender=org.Apache.log4j.RollingFileAppender
log4j.appender.adminAppender.File=/home/nick/logging/admin.log
log4j.appender.adminAppender.MaxFileSize=1MB
log4j.appender.adminAppender.MaxBackupIndex=1
log4j.appender.adminAppender.layout=org.Apache.log4j.PatternLayout
log4j.appender.adminAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n
14
NickJ

Vous n'avez pas besoin de charger le fichier de propriétés. Placez-le simplement dans le dossier src qui sera automatiquement ajouté dans le chemin d'accès aux classes.

Exemple de code:

public static void main(String[] args) throws Exception {

   Logger admin = Logger.getLogger("admin");
   Logger file = Logger.getLogger("file");

   admin.info("hello admin");
   file.info("hello file");
}
3
Braj