로그4J, 상대 경로를 사용하도록 웹 앱 구성
-
03-07-2019 - |
문제
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을 사용하는 경우 훌륭한 솔루션이 있습니다.
다음 줄을 포함하도록 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 제품군에 대한 재산.이미 정의 된 사용
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
- 그게 다야!
추신: 나는 이것이 개미를 사용하여 달성 될 수 있다고 확신하지만 불행히도 나는 그것에 대한 경험이 충분하지 않습니다.
내 제안은 로그 파일이 항상 webapp의 루트 컨텍스트 위에 로그인해야하므로 WebApp을 재배치 할 경우 기존 로그 파일을 무시하고 싶지 않습니다.
내 솔루션은 Iker Jimenez와 유사합니다 해결책, 그러나 사용하는 대신 System.setProperty(...)
나는 사용한다 org.apache.log4j.PropertyConfigurator.configure(Properties)
. 이를 위해서도 자체적으로 구성을 찾을 수 없도록 Log4J가 필요하고 수동으로로드합니다 (Wolfgang Liebich의 두 지점 모두. 대답).
이는 IDE에서 실행되거나 IDE에서 실행되는 Jetty 및 Tomcat에서 작동하며 구성이 없으므로 컨테이너 내부의 앱 수에 관계없이 각 앱의 로그를 자체 폴더에 넣을 수 있습니다. 문제 이랑 System
-기반 솔루션). 이 방법으로는 웹 앱 내부에 Log4J 구성 파일을 어디에나 넣을 수 있습니다 (예 : 하나의 프로젝트에는 모든 구성 파일이 내부에 있습니다. WEB-INF/
).
세부:
- 나는 내 속성이있다
log4j-no-autoload.properties
ClassPath의 파일 (예 : Maven Project에서 원래src/main/resources
, 포장됩니다WEB-INF/classes
), appender 파일은 예를 들어 다음과 같이 구성되었습니다.
log4j.appender.MyAppFileAppender = org.apache.log4j.FileAppender log4j.appender.MyAppFileAppender.file = ${webAppRoot}/WEB-INF/logs/my-app.log ...
그리고 나는 이와 같은 컨텍스트 청취자가 있습니다 (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
이것은 서블릿 컨테이너와 독립적이며 사용자 지정 변수를 시스템 환경에 전달할 필요가 없습니다.