Domanda

Ho una webapp java che deve essere distribuita su macchine Win o Linux. Ora voglio aggiungere log4j per la registrazione e vorrei utilizzare un percorso relativo per il file di registro poiché non desidero modificare il percorso del file su ogni distribuzione. Il contenitore sarà molto probabilmente Tomcat ma non necessariamente.

Qual è il modo migliore per farlo?

È stato utile?

Soluzione 2

Finalmente l'ho fatto in questo modo.

Aggiunto un ServletContextListener che procede come segue:

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

Quindi nel file log4j.properties:

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

In questo modo Log4j scriverà nella cartella giusta fintanto che non lo utilizzerai prima di " rootPath " la proprietà di sistema è stata impostata. Ciò significa che non puoi usarlo dal ServletContextListener stesso ma dovresti essere in grado di usarlo da qualsiasi altra parte dell'app.

Dovrebbe funzionare su ogni contenitore Web e sistema operativo in quanto non dipende da una proprietà di sistema specifica del contenitore e non è interessato da problemi di percorso specifici del sistema operativo. Testato con i contenitori Web Tomcat e Orion e su Windows e Linux e funziona bene finora.

Cosa ne pensi?

Altri suggerimenti

Tomcat imposta una proprietà di sistema catalina.home. Puoi usarlo nel tuo file delle proprietà log4j. Qualcosa del genere:

log4j.rootCategory=DEBUG,errorfile

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

Su Debian (incluso Ubuntu), $ {catalina.home} non funzionerà perché indica / usr / share / tomcat6 che non ha link a / var / log / tomcat6. Qui usa $ {catalina.base} .

Se stai usando un altro contenitore, prova a trovare una proprietà di sistema simile o definisci la tua. L'impostazione della proprietà di sistema varia in base alla piattaforma e al contenitore. Ma per Tomcat su Linux / Unix avrei creato un setenv.sh nella directory CATALINA_HOME / bin. Conterrebbe:

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

Quindi il tuo log4j.properties sarebbe:

log4j.rootCategory=DEBUG,errorfile

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

Se usi Spring puoi:

1) crea un file di configurazione log4j, ad es. & Quot; /WEB-INF/classes/log4j-myapp.properties" NON nominarlo " log4j.properties "

Esempio:

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

Definiremo " myWebapp-instance-root " più avanti il ??punto (3)

2) Specifica la posizione di configurazione in web.xml:

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

3) Specifica un univoco nome variabile per la radice della tua webapp, ad es. & Quot; MyWebApp-instance-root "

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

4) Aggiungi un Log4jConfigListener:

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

Se scegli un nome diverso, ricordati di cambiarlo anche in log4j-myapp.properties.

Vedi il mio articolo (solo in italiano ... ma dovrebbe essere comprensibile): http://www.megadix.it/content/configurare-path -relativi-log4j-utilizzando-primavera

AGGIORNAMENTO (2009/08/01) Ho tradotto il mio articolo in inglese: http://www.megadix.it/node/136

Solo un commento sulla soluzione di Iker .

ServletContext è una buona soluzione per il tuo problema. Ma non penso che sia buono per le cure. I file di registro per la maggior parte del tempo devono essere salvati per molto tempo.

Poiché ServletContext crea il file nel file distribuito, verrà rimosso quando il server viene ridistribuito. Il mio suggerimento è di andare con la cartella principale di rootPath invece che con quella secondaria.

log4j non utilizza semplicemente la directory principale dell'applicazione se non si specifica una directory principale nella proprietà del percorso di FileAppender? Quindi dovresti essere in grado di usare:

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

È passato un po 'di tempo da quando ho fatto lo sviluppo web Java, ma questo sembra essere il più intuitivo, e inoltre non si scontra con altri log sfortunatamente scritti nella directory $ {catalina.home} / logs.

Come ulteriore commento su https://stackoverflow.com/a/218037/2279200 - potrebbe non funzionare, se l'app Web avvia implicitamente altri ServletContextListener, che potrebbero essere chiamati in precedenza e che già provano a utilizzare log4j - in questo caso, la configurazione di log4j verrà letta e analizzata già prima che la proprietà che determina la directory root del registro sia impostata = > i file di registro appariranno da qualche parte sotto la directory corrente (la directory corrente all'avvio di tomcat).

Potevo solo pensare alla seguente soluzione a questo problema: - rinomina il tuo file log4j.properties (o logj4.xml) in qualcosa che log4j non leggerà automaticamente. - Nel filtro di contesto, dopo aver impostato la proprietà, chiama la classe helper DOM / PropertyConfigurator per assicurarti che log4j -. {Xml, properties} sia letto - Ripristina la configurazione di log4j (IIRC esiste un metodo per farlo)

Questa è una forza un po 'bruta, ma penso che sia l'unico modo per renderlo a tenuta stagna.

Nel caso in cui stai usando Maven, ho un'ottima soluzione per te:

  1. Modifica il tuo file pom.xml per includere le seguenti righe:

    <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>
    

    Qui si definisce la proprietà logDirectory specificatamente per la famiglia di sistemi operativi.

  2. Utilizza la proprietà logDirectory già definita nel file 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. Questo è tutto!

P.S .: Sono sicuro che questo può essere ottenuto usando Ant ma sfortunatamente non ho abbastanza esperienza con esso.

Il mio suggerimento è che il file di registro debba sempre essere registrato sopra il contesto radice della webApp, quindi nel caso in cui ridistribuiamo la webApp, non vogliamo sovrascrivere i file di registro esistenti.

La mia soluzione è simile alla soluzione di Iker Jimenez , ma invece di utilizzare System.setProperty (... ) Uso org.apache.log4j.PropertyConfigurator.configure (Proprietà) . Per questo ho anche bisogno che log4j non riesca a trovare la sua configurazione da solo e lo carico manualmente (entrambi i punti descritti nella risposta di Wolfgang Liebich / a>).

Funziona con Jetty e Tomcat, autonomo o eseguito da IDE, non richiede alcuna configurazione, consente di inserire i registri di ciascuna app nella propria cartella, indipendentemente dal numero di app all'interno del contenitore (ovvero il problema con il System -based soluzione). In questo modo si può anche posizionare il file di configurazione log4j in qualsiasi punto all'interno dell'app Web (ad es. In un progetto avevamo tutti i file di configurazione in WEB-INF / ).

dettagli:

  1. Ho le mie proprietà nel file log4j-no-autoload.properties nel percorso di classe (ad es. nel mio progetto Maven è originariamente in src / main / resources , ottiene impacchettato in WEB-INF / classes ),
  2. Ha il file appender configurato come ad es .:

    log4j.appender.MyAppFileAppender = org.apache.log4j.FileAppender
    log4j.appender.MyAppFileAppender.file = ${webAppRoot}/WEB-INF/logs/my-app.log
    ...
    
  3. E ho un ascoltatore di contesto come questo (diventa molto più breve con la sintassi "prova-con-risorsa" di 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(...)
        }
        ...
    }
    

Puoi specificare il percorso relativo al file di registro, usando la directory di lavoro :

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

Questo è indipendente dal contenitore servlet e non richiede il passaggio di variabili personalizzate all'ambiente di sistema.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top