[java] Log4j, 상대 경로를 사용하도록 웹앱 구성

Win 또는 Linux 시스템에 배포해야하는 Java 웹 응용 프로그램이 있습니다. 이제 로깅을 위해 log4j를 추가하고 모든 배포에서 파일 경로를 변경하고 싶지 않기 때문에 로그 파일의 상대 경로를 사용하고 싶습니다. 컨테이너는 Tomcat 일 가능성이 높지만 반드시 그런 것은 아닙니다.

이를 수행하는 가장 좋은 방법은 무엇입니까?



답변

Tomcat은 catalina.home 시스템 속성을 설정합니다. log4j 속성 파일에서 이것을 사용할 수 있습니다. 이 같은:

log4j.rootCategory=DEBUG,errorfile

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

Debian (Ubuntu 포함)에서는 ${catalina.home}/ var / log / tomcat6에 대한 링크가없는 / usr / share / tomcat6을 가리 키므로 작동하지 않습니다. 여기에서 ${catalina.base}.

다른 컨테이너를 사용하는 경우 유사한 시스템 속성을 찾거나 직접 정의하십시오. 시스템 속성 설정은 플랫폼 및 컨테이너에 따라 다릅니다. 그러나 Linux / Unix의 Tomcat의 경우 CATALINA_HOME / bin 디렉토리에 setenv.sh를 만듭니다. 다음이 포함됩니다.

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

그러면 log4j.properties는 다음과 같습니다.

log4j.rootCategory=DEBUG,errorfile

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


답변

마침내 이런 식으로 해냈습니다.

다음을 수행하는 ServletContextListener를 추가했습니다.

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

그런 다음 log4j.properties 파일에서 :

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

이렇게하면 “rootPath”시스템 속성이 설정되기 전에 사용하지 않는 한 Log4j는 올바른 폴더에 기록합니다. 즉, ServletContextListener 자체에서는 사용할 수 없지만 앱의 다른 곳에서는 사용할 수 있어야합니다.

컨테이너 별 시스템 속성에 의존하지 않고 OS 별 경로 문제의 영향을받지 않으므로 모든 웹 컨테이너 및 OS에서 작동해야합니다. Tomcat 및 Orion 웹 컨테이너와 Windows 및 Linux에서 테스트되었으며 지금까지 잘 작동합니다.

어떻게 생각해?


답변

Spring을 사용하면 다음을 수행 할 수 있습니다.

1) “/WEB-INF/classes/log4j-myapp.properties”와 같은 log4j 구성 파일을 만듭니다. 이름을 “log4j.properties”로 지정하지 마십시오.

예:

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

나중에 (3)에서 “myWebapp-instance-root”를 정의 할 것입니다.

2) web.xml에서 구성 위치를 지정하십시오.

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

3) 웹앱의 루트에 고유 한 변수 이름을 지정 하십시오. 예 : “myWebapp-instance-root”

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

4) Log4jConfigListener 추가 :

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

다른 이름을 선택하는 경우 log4j-myapp.properties에서도 변경해야합니다.

내 기사를 참조하십시오 (이탈리아어 만 …하지만 이해할 수 있어야 함) :
http://www.megadix.it/content/configurare-path-relativi-log4j-utilizzando-spring

업데이트 (2009/08/01)
내 기사를 영어로 번역했습니다 :
http://www.megadix.it/node/136


답변

Iker의 솔루션 에 대한 의견입니다 .

ServletContext문제에 대한 좋은 해결책입니다. 하지만 유지 관리에는 좋지 않다고 생각합니다. 대부분의 경우 로그 파일은 오랫동안 저장해야합니다.

이후 ServletContext배포 된 파일에서 파일을 만들어 서버가 재배치 될 때, 그것은 제거됩니다. 내 제안은 자식 폴더 대신 rootPath의 부모 폴더를 사용하는 것입니다.


답변

FileAppender의 경로 속성에 루트 디렉터리를 지정하지 않으면 log4j가 응용 프로그램 루트 디렉터리를 사용하지 않습니까? 따라서 다음을 사용할 수 있어야합니다.

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

Java 웹 개발을 한 지 오래되었지만 가장 직관적 인 것 같고 $ {catalina.home} / logs 디렉토리에 쓰는 다른 이름의 로그와 충돌하지 않습니다.


답변

https://stackoverflow.com/a/218037/2279200 에 대한 추가 의견으로 , 웹 앱이 다른 ServletContextListener를 암시 적으로 시작하여 이전에 호출 될 수 있고 이미 log4j를 사용하려고 시도하는 경우 중단 될 수 있습니다. log4j 구성은 로그 루트 디렉토리를 결정하는 속성이 설정되기 전에 이미 읽고 구문 분석됩니다 => 로그 파일은 현재 디렉토리 (톰캣을 시작할 때 현재 디렉토리) 아래 어딘가에 나타납니다.

이 문제에 대한 해결책은 다음과 같을뿐입니다.-log4j.properties (또는 logj4.xml) 파일의 이름을 log4j가 자동으로 읽지 않는 이름으로 바꿉니다. -컨텍스트 필터에서 속성을 설정 한 후 DOM / PropertyConfigurator 도우미 클래스를 호출하여 log4j-. {xml, properties}를 읽었는지 확인합니다.-log4j 구성 재설정 (IIRC에는이를 수행하는 방법이 있습니다)

이것은 약간의 무자비한 힘이지만, 그것이 방수로 만드는 유일한 방법입니다.


답변

Maven을 사용하는 경우 훌륭한 솔루션이 있습니다.

  1. 다음 행을 포함하도록 pom.xml 파일을 편집하십시오.

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

    여기서 logDirectoryOS 제품군에 대한 속성을 특별히 정의 합니다.

  2. 파일에 이미 정의 된 logDirectory속성 사용 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. 그게 다야!

추신 : 나는 이것이 Ant를 사용하여 달성 될 수 있다고 확신하지만 불행히도 그것에 대한 충분한 경험이 없습니다.