Frage

Ich habe eine java-webapp, die bereitgestellt werden entweder Win oder Linux-Rechner.Ich möchte nun hinzufügen, die log4j für die Protokollierung, und ich möchte einen relativen Pfad für die Protokolldatei, die ich nicht wollen, ändern Sie den Pfad der Datei auf jedem deployment.Der container wird dann höchstwahrscheinlich die Tomcat aber nicht unbedingt.

Was ist der beste Weg, dies zu tun?

War es hilfreich?

Lösung 2

Ich habe es schließlich auf diese Weise getan.

ein ServletContextListener hinzugefügt, das macht folgendes:

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

Dann in der Datei log4j.properties:

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

Mit dem auf diese Weise tun Log4j in den richtigen Ordner schreiben, solange Sie ihn nicht verwenden, bevor die „ROOTPATH“ Systemeigenschaft gesetzt wurde. Das bedeutet, dass Sie es nicht aus dem ServletContextListener selbst verwenden können, aber man sollte es benutzen, von irgendwo sonst in der App kann.

Es sollte auf jedem Web-Container und OS arbeiten, wie es auf einem Containerspezifischen Systemeigenschaft nicht abhängig ist und es ist nicht betroffen von OS bestimmten Pfad Probleme. Getestet mit Tomcat und Orion Webcontainern und unter Windows und Linux und es funktioniert so weit in Ordnung.

Was denken Sie?

Andere Tipps

Tomcat setzt catalina.home Systemeigenschaft. Sie können in Ihrer log4j-Eigenschaftsdatei verwenden diese. So etwas wie folgt aus:

log4j.rootCategory=DEBUG,errorfile

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

Unter Debian (einschließlich Ubuntu), wird ${catalina.home} nicht funktionieren, weil die Punkte in / usr / share / tomcat6, die keine Verbindung zu / var / log / tomcat6 hat. Hier nur ${catalina.base} verwenden.

Wenn Ihr einen anderen Behälter verwenden, versuchen, ein ähnliches System Eigenschaft zu finden, oder Ihre eigenen definieren. die Systemeigenschaft Einstellung wird von Plattform und Behälter variieren. Aber für Tomcat unter Linux / Unix würde ich eine setenv.sh im CATALINA_HOME / bin-Verzeichnis erstellen. Es würde enthalten:

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

Dann wird Ihr log4j.properties wäre:

log4j.rootCategory=DEBUG,errorfile

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

Wenn Sie Frühling können Sie:

1) erstellen log4j Konfigurationsdatei, z.B. "/WEB-INF/classes/log4j-myapp.properties" DO Name nicht it "log4j.properties"

Beispiel:

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

Wir definieren "MyWebApp-instance-root" später auf den Punkt (3)

2) Geben Sie config-Standort in web.xml:

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

3) Geben Sie einen unique Variablenname für root Ihre Webapp ist, z.B. "MyWebApp-Instanz-root"

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

4) hinzufügen Log4jConfigListener:

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

Wenn Sie einen anderen Namen wählen, erinnern sie in log4j-myapp.properties zu ändern, auch.

Siehe meinen Artikel (nur auf Italienisch ... aber es sollte verständlich sein): http://www.megadix.it/content/configurare-path -relativi-log4j-utilizzando-Feder

UPDATE (2009/08/01) Ich habe meinen Artikel ins Englische übersetzt: http://www.megadix.it/node/136

Nur ein Kommentar auf Iker s Lösung.

ServletContext ist eine gute Lösung für Ihr problem.Aber ich glaube nicht, dass es gut pflegt.Die meisten der Zeit, die log-Dateien werden benötigt, um gerettet zu werden, für lange Zeit.

Da ServletContext macht die Datei unter den bereitgestellten Datei, es wird entfernt, wenn der server erneut bereitgestellt werden.Meine vorschlagen, gehen mit rootPath stattdessen den übergeordneten Ordner des Kindes ein.

Nicht LOG4J nur das Stammverzeichnis der Anwendung verwenden, wenn Sie ein Stammverzeichnis in Ihrem FileAppender ist nicht Pfad Eigenschaft angeben? So sollten Sie nur in der Lage sein zu verwenden:

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

Es ist schon eine Weile, da habe ich Java Web-Entwicklung getan, aber dies scheint die intuitiv zu sein, und auch mit anderen leider namens logs schriftlich an die $ kollidiert {catalina.home} / logs.

Als weiterer Kommentar über https://stackoverflow.com/a/218037/2279200 - dies kann brechen, wenn die Web-App implizit andere beginnt ServletContextListener die, die früher erhalten genannt können und die bereits versuchen log4j zu verwenden - in diesem Fall wird die log4j Konfiguration gelesen und analysiert bereits vor dem Objekt zu bestimmen das Protokoll Stammverzeichnis gesetzt => die Protokolldateien erscheinen irgendwo wird unterhalb des aktuellen Verzeichnisses (das aktuelle Verzeichnis als tomcat starten).

konnte ich denke nur an dieses Problems folgende Lösung: - Benennen Sie Ihre log4j.properties (oder logj4.xml) etwas Datei, die log4j liest nicht automatisch. - In Ihrem Kontextfilter, nachdem die Eigenschaft festlegen, rufen Sie die DOM / PropertyConfigurator Hilfsklasse, um sicherzustellen, dass Ihre log4j -. {Xml, Eigenschaften} gelesen - die log4j Konfiguration zurücksetzen (IIRC gibt es ein Verfahren, das zu tun)

Das ist ein bisschen brutale Gewalt, aber du dünke, es ist der einzige Weg, um es wasserdicht zu machen.

Falls Sie Maven verwenden Ich habe eine große Lösung für Sie:

  1. Bearbeiten Sie Ihre pom.xml Datei folgende Zeilen enthalten:

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

    Hier definieren Sie logDirectory Eigenschaft speziell auf OS-Familie.

  2. Verwenden Sie bereits definiert logDirectory Eigenschaft in log4j.properties Datei:

    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. Das ist es!

P. S:.. Ich bin sicher, dass dieser Ant mit erreicht werden kann, aber leider habe ich nicht genug Erfahrung damit

Mein Vorschlag ist, sollte die Protokolldatei immer über dem Stammkontext des webApp angemeldet sein, so im Fall wir die webApp umschichten, wir wollen nicht die vorhandenen Protokolldateien zu überschreiben.

Meine Lösung ist ähnlich wie Iker Jimenez Lösung , sondern System.setProperty(...) der Verwendung Ich verwende org.apache.log4j.PropertyConfigurator.configure(Properties). Dafür brauche ich log4j auch nicht in der Lage sein, seine Konfiguration auf seinem eigenen zu finden und ich es manuell laden (beiden beschriebenen Punkte in Wolfgang Liebich beantworten ).

Dies funktioniert für Jetty und Tomcat, von IDE Standalone oder läuft, erfordert keine Konfiguration, ermöglicht es jede App-Protokolle in einem eigenen Ordner zu setzen, egal wie viele Apps im Innern des Behälters (die the Problem mit der System-basierten Lösung). Auf diese Weise man auch die log4j Konfigurationsdatei irgendwo im Web-App setzen kann (zum Beispiel in einem Projekt, das wir hatten alle Konfigurationsdateien innerhalb WEB-INF/).

Details:

  1. Ich habe meine Eigenschaften in der log4j-no-autoload.properties-Datei im Classpath (zum Beispiel in meinem Maven Projekt ursprünglich es in src/main/resources, verpackt wird in WEB-INF/classes)
  2. Es hat die Datei appender wie z konfiguriert.

    log4j.appender.MyAppFileAppender = org.apache.log4j.FileAppender
    log4j.appender.MyAppFileAppender.file = ${webAppRoot}/WEB-INF/logs/my-app.log
    ...
    
  3. Und ich habe einen Kontext Hörer wie folgt aus (wird viel kürzer mit Java 7 des "Try-mit-Ressource" Syntax):

    @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(...)
        }
        ...
    }
    

Sie können relativen Pfad zur Protokolldatei angeben, die Arbeitsverzeichnis mit :

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

Dies ist unabhängig von dem Servlet-Container und erfordert keine benutzerdefinierten Variablen an die Systemumgebung übergeben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top