문제

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

이것을하는 가장 좋은 방법은 무엇입니까?

도움이 되었습니까?

해결책 2

나는 마침내 이런 식으로 그것을했다.

다음을 수행하는 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에서 테스트되었으며 지금까지 잘 작동합니다.

어떻게 생각해?

다른 팁

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

log4j.rootCategory=DEBUG,errorfile

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

데비안 (우분투 포함)에서 ${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

스프링을 사용하면 다음과 같습니다.

1) log4j 구성 파일을 만듭니다. 예를 들어 "/web-inf/classes/log4j-myapp.properties"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) a 독특한 WebApp의 루트의 변수 이름 (예 : "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 's 해결책.

ServletContext 문제에 대한 좋은 해결책입니다. 그러나 나는 그것이 유지하기에 좋다고 생각하지 않습니다. 대부분의 시간 로그 파일은 오랫동안 저장해야합니다.

부터 ServletContext 배포 된 파일 아래 파일을 만들면 서버가 재배치되면 제거됩니다. 내 제안은 Child One 대신 RootPath의 상위 폴더를 사용하는 것입니다.

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

log4j.appender.file.file = logs/mylog.log

Java Web Development를 해낸 이후로 시간이 지났지 만 이것은 가장 직관적 인 것처럼 보이며 불행히도 이름이 지정된 다른 이름의 로그와 충돌하지 않습니다.

추가 의견으로 https://stackoverflow.com/a/218037/2279200 - 웹 앱이 암시 적으로 다른 ServletContextListener를 암시 적으로 시작하면 Log4J를 이미 사용하려고 시도하는 다른 ServletContextListener ' => 로그 파일은 현재 디렉토리 아래 어딘가에 나타납니다 (Tomcat을 시작할 때 현재 디렉토리).

이 문제에 대한 해결책을 다음과 같이 생각할 수 있습니다 .- Log4J.Properties (또는 logj4.xml) 파일의 이름을 Log4J가 자동으로 읽지 않은 것으로 바꿉니다. - 컨텍스트 필터에서 속성을 설정 한 후 DOM/PropertyConfigurator 도우미 클래스를 호출하여 log4J-.

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

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>
    

    여기서 당신은 정의합니다 logDirectory 특히 OS 제품군에 대한 재산.

  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. 그게 다야!

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

내 제안은 로그 파일이 항상 webapp의 루트 컨텍스트 위에 로그인해야하므로 WebApp을 재배치 할 경우 기존 로그 파일을 무시하고 싶지 않습니다.

내 솔루션은 Iker Jimenez와 유사합니다 해결책, 그러나 사용하는 대신 System.setProperty(...) 나는 사용한다 org.apache.log4j.PropertyConfigurator.configure(Properties). 이를 위해서도 자체적으로 구성을 찾을 수 없도록 Log4J가 필요하고 수동으로로드합니다 (Wolfgang Liebich의 두 지점 모두. 대답).

이는 IDE에서 실행되거나 IDE에서 실행되는 Jetty 및 Tomcat에서 작동하며 구성이 없으므로 컨테이너 내부의 앱 수에 관계없이 각 앱의 로그를 자체 폴더에 넣을 수 있습니다. 문제 이랑 System-기반 솔루션). 이 방법으로는 웹 앱 내부에 Log4J 구성 파일을 어디에나 넣을 수 있습니다 (예 : 하나의 프로젝트에는 모든 구성 파일이 내부에 있습니다. WEB-INF/).

세부:

  1. 나는 내 속성이있다 log4j-no-autoload.properties ClassPath의 파일 (예 : Maven Project에서 원래 src/main/resources, 포장됩니다 WEB-INF/classes),
  2. appender 파일은 예를 들어 다음과 같이 구성되었습니다.

    log4j.appender.MyAppFileAppender = org.apache.log4j.FileAppender
    log4j.appender.MyAppFileAppender.file = ${webAppRoot}/WEB-INF/logs/my-app.log
    ...
    
  3. 그리고 나는 이와 같은 컨텍스트 청취자가 있습니다 (Java 7의 "Try-With-Resource"구문으로 훨씬 짧아집니다) :

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

로그 파일에 대한 상대 경로를 작업 디렉토리:

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

이것은 서블릿 컨테이너와 독립적이며 사용자 지정 변수를 시스템 환경에 전달할 필요가 없습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top