Log4j, configurazione di un'app Web per utilizzare un percorso relativo
-
03-07-2019 - |
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?
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:
-
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. -
Utilizza la proprietà
logDirectory
già definita nel filelog4j.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
- 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:
- Ho le mie proprietà nel file
log4j-no-autoload.properties
nel percorso di classe (ad es. nel mio progetto Maven è originariamente insrc / main / resources
, ottiene impacchettato inWEB-INF / classes
), -
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 ...
-
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.