Question

J'ai une application Web Java qui doit être déployée sur des machines Win ou Linux. Je souhaite maintenant ajouter log4j pour la journalisation et utiliser un chemin relatif pour le fichier journal car je ne souhaite pas modifier le chemin de fichier à chaque déploiement. Le conteneur sera probablement Tomcat mais pas nécessairement.

Quel est le meilleur moyen de le faire?

Était-ce utile?

La solution 2

Je l'ai enfin fait de cette façon.

Ajout d'un ServletContextListener qui effectue les opérations suivantes:

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 ainsi, Log4j écrira dans le bon dossier tant que vous ne l'utilisez pas avant le & root; rootPath " propriété système a été définie. Cela signifie que vous ne pouvez pas l'utiliser à partir de ServletContextListener lui-même, mais vous devriez pouvoir l'utiliser depuis n'importe où ailleurs dans l'application.

Il devrait fonctionner sur tous les conteneurs Web et systèmes d'exploitation, car il ne dépend pas d'une propriété système spécifique à un conteneur et n'est pas affecté par les problèmes de chemin d'accès spécifiques à un système d'exploitation. Testé avec les conteneurs Web Tomcat et Orion, ainsi que sous Windows et Linux, et tout fonctionne correctement jusqu'à présent.

Qu'en pensez-vous?

Autres conseils

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 ça:

log4j.rootCategory=DEBUG,errorfile

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

Sur Debian (y compris Ubuntu), $ {catalina.home} ne fonctionnera pas car cela pointe sur / usr / share / tomcat6 qui n'a pas de lien vers / var / log / tomcat6. Ici, il suffit d'utiliser $ {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 en fonction de la plate-forme et du conteneur. Mais pour Tomcat sous Linux / Unix, je créerais un fichier setenv.sh dans le répertoire CATALINA_HOME / bin. Il contiendrait:

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

Ensuite, votre log4j.properties serait:

log4j.rootCategory=DEBUG,errorfile

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

Si vous utilisez Spring, vous pouvez:

1) créez un fichier de configuration log4j, par exemple. & WEB-INF/classes/log4j-myapp.properties" NE LE NOMMEZ PAS " 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 allons définir "myWebapp-instance-root". plus tard au point (3)

2) Spécifiez l'emplacement de 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écifiez un nom de variable unique pour la racine de votre application Web, 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 uniquement ... 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

Juste un commentaire sur la solution Iker .

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

Etant donné que ServletContext crée le fichier sous le fichier déployé, il sera supprimé lors du redéploiement du serveur. Je suggère d’utiliser le dossier parent de rootPath à la place du premier.

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 pouvoir utiliser:

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

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

En tant que commentaire supplémentaire sur https://stackoverflow.com/a/218037/2279200 - cela peut casser, si l'application Web démarre implicitement avec d'autres ServletContextListener, qui peuvent être appelés plus tôt et qui tentent déjà d'utiliser log4j. Dans ce cas, la configuration log4j sera lue et analysée avant la propriété qui détermine le répertoire racine du journal est définie = > les fichiers journaux apparaîtront quelque part sous le répertoire en cours (le répertoire en cours au démarrage de tomcat).

Je ne pouvais penser qu'à la solution suivante à ce problème: - renommez votre fichier log4j.properties (ou logj4.xml) en quelque chose que log4j ne lira pas automatiquement. - Dans votre filtre de contexte, après avoir défini la propriété, appelez la classe d'assistance DOM / PropertyConfigurator pour vous assurer que votre log4j -. {Xml, properties} est lu. - Réinitialiser la configuration log4j (IIRC il existe une méthode pour le faire)

C’est un peu la force brute, mais il me semble que c’est le seul moyen de le rendre étanche.

Si vous utilisez Maven, j'ai une excellente solution pour vous:

  1. Modifiez votre fichier pom.xml pour inclure les lignes suivantes:

    <profiles>
        <profile>
            <id>linux</id>
            <activation>
                <os>
                    <family>unix</family>
                </os>
            </activation>
            <properties>
                <logDirectory>/var/log/tomcat6</logDirectory>
            </properties>
        </profile>
        <profile>
            <id>windows</id>
            <activation>
                <os>
                    <family>windows</family>
                </os>
            </activation>
            <properties>
                <logDirectory>${catalina.home}/logs</logDirectory>
            </properties>
        </profile>
    </profiles>
    

    Vous définissez ici la propriété logDirectory spécifiquement pour la famille de systèmes d'exploitation.

  2. Utilisez la propriété logDirectory déjà définie dans le fichier log4j.properties :

    log4j.appender.FILE=org.apache.log4j.RollingFileAppender
    log4j.appender.FILE.File=${logDirectory}/mylog.log
    log4j.appender.FILE.MaxFileSize=30MB
    log4j.appender.FILE.MaxBackupIndex=10
    log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
    log4j.appender.FILE.layout.ConversionPattern=%d{ISO8601} [%x] %-5p [%t] [%c{1}] %m%n
    
  3. c'est tout!

P.S.: Je suis sûr que cela peut être réalisé avec Ant, mais malheureusement, je n'en ai pas assez d'expérience.

Je suggère que le fichier journal soit toujours enregistré au-dessus du contexte racine de l'application Web. Par conséquent, si vous redéployez l'application Web, vous ne souhaitez pas remplacer les fichiers journaux existants.

Ma solution est similaire à la solution d'Iker Jimenez, mais au lieu d'utiliser System.setProperty (... ) J'utilise org.apache.log4j.PropertyConfigurator.configure (Propriétés) . Pour cela, j’ai également besoin que log4j ne puisse pas trouver sa configuration par elle-même et je la charge manuellement (les deux points décrits dans la réponse de Wolfgang Liebich <> / a>).

Ceci fonctionne pour Jetty et Tomcat, qu'il soit autonome ou exécuté depuis l'IDE, ne nécessite aucune configuration, permet de mettre les journaux de chaque application dans leur propre dossier, quel que soit le nombre d'applications contenues dans le conteneur (ce qui est le problème lié ??au Système . Solution). De cette façon, vous pouvez également placer le fichier de configuration log4j n'importe où dans l'application Web (par exemple, dans un projet, nous avions tous les fichiers de configuration dans WEB-INF / ).

Détails:

  1. Mes propriétés se trouvent dans le fichier log4j-no-autoload.properties du chemin de classe (par exemple, dans mon projet Maven, il se trouve à l'origine dans src / main / resources , get emballé dans WEB-INF / classes ),
  2. L'appender de fichier est configuré comme par exemple:

    log4j.appender.MyAppFileAppender = org.apache.log4j.FileAppender
    log4j.appender.MyAppFileAppender.file = ${webAppRoot}/WEB-INF/logs/my-app.log
    ...
    
  3. Et j'ai un écouteur de contexte comme celui-ci (il est beaucoup plus court avec la syntaxe "try-with-resource" de Java 7):

    @WebListener
    public class ContextListener implements ServletContextListener {
        @Override
        public void contextInitialized(final ServletContextEvent event) {
            Properties props = new Properties();
            InputStream strm =
                ContextListener.class.getClassLoader()
                    .getResourceAsStream("log4j-no-autoload.properties");
            try {
                props.load(strm);
            } catch (IOException propsLoadIOE) {
                throw new Error("can't load logging config file", propsLoadIOE);
            } finally {
                try {
                    strm.close();
                } catch (IOException configCloseIOE) {
                    throw new Error("error closing logging config file", configCloseIOE);
                }
            }
            props.put("webAppRoot", event.getServletContext().getRealPath("/"));
            PropertyConfigurator.configure(props);
            // from now on, I can use LoggerFactory.getLogger(...)
        }
        ...
    }
    

Vous pouvez spécifier un chemin d'accès relatif au fichier journal à l'aide du répertoire de travail :

.
appender.file.fileName = ${sys:user.dir}/log/application.log

Ceci est indépendant du conteneur de servlet et ne nécessite pas la transmission de variable personnalisée à l'environnement système.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top