80 votes

Log4j, configuration d'une application Web pour utiliser un chemin relatif

J'ai une application web java qui doit être déployée sur des machines Win ou Linux. Je veux maintenant ajouter log4j pour la journalisation et j'aimerais utiliser un chemin relatif pour le fichier journal car je ne veux pas changer le chemin du fichier à chaque déploiement. Le conteneur sera très probablement Tomcat, mais pas nécessairement.

Quelle est la meilleure façon de procéder ?

99voto

Steve K Points 10475

Tomcat définit une propriété système catalina.home. Vous pouvez l'utiliser dans votre fichier de propriétés log4j. Quelque chose comme ceci :

log4j.rootCategory=DEBUG,errorfile

log4j.appender.errorfile.File=${catalina.home}/logs/LogFilename.log

Sur Debian (y compris Ubuntu), ${catalina.home} ne fonctionnera pas car il pointe vers /usr/share/tomcat6 qui n'a pas de lien vers /var/log/tomcat6. Ici, utilisez simplement ${catalina.base} .

Si vous utilisez un autre conteneur, essayez de trouver une propriété système similaire, ou définissez la vôtre. La définition de la propriété système varie selon la plate-forme et le conteneur. Mais pour Tomcat sur Linux/Unix, je créerais un setenv.sh dans le répertoire CATALINA_HOME/bin. Il contiendrait :

export JAVA_OPTS="-Dcustom.logging.root=/var/log/webapps"

Alors votre log4j.properties serait :

log4j.rootCategory=DEBUG,errorfile

log4j.appender.errorfile.File=${custom.logging.root}/LogFilename.log

53voto

Iker Jimenez Points 3351

J'ai finalement réussi à le faire de cette manière.

Ajout d'un ServletContextListener qui fait ce qui suit :

public void contextInitialized(ServletContextEvent event) {
    ServletContext context = event.getServletContext();
    System.setProperty("rootPath", context.getRealPath("/"));
}

Puis dans le fichier log4j.properties :

log4j.appender.file.File=${rootPath}WEB-INF/logs/MyLog.log

En procédant de cette manière, Log4j écrira dans le bon dossier tant que vous ne l'utilisez pas avant que la propriété système "rootPath" ait été définie. Cela signifie que vous ne pouvez pas l'utiliser à partir du ServletContextListener lui-même, mais que vous devriez être en mesure de l'utiliser à partir de n'importe quel autre endroit de l'application.

Il devrait fonctionner sur tous les conteneurs web et tous les systèmes d'exploitation car il ne dépend pas d'une propriété système spécifique au conteneur et n'est pas affecté par les problèmes de chemins spécifiques au système d'exploitation. J'ai testé avec les conteneurs web Tomcat et Orion et sous Windows et Linux et cela fonctionne bien jusqu'à présent.

Qu'en pensez-vous ?

14voto

Megadix Points 646

Si vous utilisez Spring, vous pouvez :

1) créez un fichier de configuration de log4j, par exemple "/WEB-INF/classes/log4j-myapp.properties". NE PAS le nommer "log4j.properties".

Exemple :

log4j.rootLogger=ERROR, stdout, rollingFile

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n

log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
log4j.appender.rollingFile.File=${myWebapp-instance-root}/WEB-INF/logs/application.log
log4j.appender.rollingFile.MaxFileSize=512KB
log4j.appender.rollingFile.MaxBackupIndex=10
log4j.appender.rollingFile.layout=org.apache.log4j.PatternLayout
log4j.appender.rollingFile.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.rollingFile.Encoding=UTF-8

Nous définirons "myWebapp-instance-Root" plus tard au point (3)

2) Spécifiez l'emplacement de la configuration dans le fichier web.xml :

<context-param>
  <param-name>log4jConfigLocation</param-name>
  <param-value>/WEB-INF/classes/log4j-myapp.properties</param-value>
</context-param>

3) Spécifier un unique Nom de variable pour le Root de votre webapp, par exemple "myWebapp-instance-Root".

<context-param>
  <param-name>webAppRootKey</param-name>
  <param-value>myWebapp-instance-root</param-value>
</context-param>

4) Ajoutez un Log4jConfigListener :

<listener>
  <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>

Si vous choisissez un nom différent, n'oubliez pas de le modifier également dans log4j-myapp.properties.

Voir mon article (en italien seulement... mais cela devrait être compréhensible) : http://www.megadix.it/content/configurare-path-relativi-log4j-utilizzando-spring

MISE À JOUR (2009/08/01) J'ai traduit mon article en anglais : http://www.megadix.it/node/136

6voto

lizi Points 31

Juste un commentaire sur la solution d'Iker.

ServletContext est une bonne solution pour votre problème. Mais je ne pense pas qu'elle soit bonne pour les entretiens. La plupart du temps, les fichiers journaux doivent être sauvegardés.

Puisque ServletContext crée le fichier sous le fichier déployé, il sera supprimé lorsque le serveur sera redéployé. Nous vous suggérons d'utiliser le dossier parent de rootPath plutôt que le dossier enfant.

5voto

Spencer Kormos Points 3082

Log4j n'utilise-t-il pas simplement le répertoire racine de l'application si vous ne spécifiez pas de répertoire racine dans la propriété path de votre FileAppender ? Vous devriez donc être capable d'utiliser :

log4j.appender.file.File=logs/MyLog.log

Cela fait longtemps que je n'ai pas fait de développement web en Java, mais cela semble être le plus intuitif, et n'entre pas en collision avec d'autres journaux malheureusement nommés écrivant dans le répertoire ${catalina.home}/logs.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X