java - Tomcat WebApp 中的 log4j2:意外的日志轮换
问题描述
当我将 log4j2 与运行在Apache Tomcat/8.0.32 (Ubuntu)
. 似乎日志在新的一天开始时被旋转并用 gzip 打包,并且没有创建新的普通日志文件。
Appender 配置在 Web 应用程序的上下文中不使用时可以正常工作。
是什么导致了日志轮换以及如何修复它?是否与Tomcat 的内部日志记录机制冲突?
我创建了一个 SSCCE:
src/test/log4j/listener/StartStopListener.java
package test.log4j.listener;
import javax.servlet.ServletContextEvent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.web.Log4jServletContextListener;
import test.log4j.logger.BaseLogger;
import test.log4j.logger.BaseLoggerSetup;
public class StartStopListener extends Log4jServletContextListener{
@Override
public void contextInitialized(ServletContextEvent sce){
super.contextInitialized(sce);
System.setProperty("java.util.logging.manager",
"org.apache.logging.log4j.jul.LogManager");
System.setProperty("log4j.skipJansi",
"true");
try{
new BaseLoggerSetup();
BaseLogger.getLogger().info("Servlet starts ...");
}
catch(Exception e){
BaseLogger.getLogger().catching(e);
}
BaseLogger.getLogger().info("Servlet started");
}
@Override
public void contextDestroyed(ServletContextEvent sce){
BaseLogger.getLogger().info("Servlet terminates ...");
LogManager.shutdown();
super.contextDestroyed(sce);
}
}
src/test/log4j/logger/BaseLogger.java
package test.log4j.logger;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.util.StackLocatorUtil;
public interface BaseLogger{
public static Logger getLogger(){
return LogManager.getLogger(StackLocatorUtil.getCallerClass(2));
}
}
src/test/log4j/logger/BaseLoggerSetup.java
package test.log4j.logger;
import java.net.URL;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
public class BaseLoggerSetup implements BaseLogger{
public BaseLoggerSetup() throws Exception{
this("/META-INF/log4j.properties");
}
public BaseLoggerSetup(String internalProperties) throws Exception{
URL url = BaseLoggerSetup.class.getResource(internalProperties);
if (System.getProperty("log4j.configurationFile") == null){
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
ctx.setConfigLocation(url.toURI());
}
}
}
资源/META-INF/log4j.properties
name=testlogger
status=debug
dest=err
appender.test.type=RollingFile
appender.test.name=test
appender.test.fileName=${sys:user.dir}/logs${web:contextPath}/test.log
appender.test.filePattern=${sys:user.dir}/logs${web:contextPath}/test.%i.log.gz
appender.test.layout.type=PatternLayout
appender.test.layout.pattern=%d - %-5p - [%t] - (%C::%M[%L]) - %notEmpty{%marker: }%m%n
appender.test.policies.type=Policies
appender.test.policies.size.type=SizeBasedTriggeringPolicy
appender.test.policies.size.size=50000KB
appender.test.strategy.type=DefaultRolloverStrategy
appender.test.strategy.max=10
appender.test_error.type=RollingFile
appender.test_error.name=test_error
appender.test_error.fileName=${sys:user.dir}/logs${web:contextPath}/test_error.log
appender.test_error.filePattern=${sys:user.dir}/logs${web:contextPath}/test_error.%i.log.gz
appender.test_error.layout.type=PatternLayout
appender.test_error.layout.pattern=%d - %-5p - [%t] - (%C::%M[%L]) - %notEmpty{%marker: }%m%n
appender.test_error.policies.type=Policies
appender.test_error.policies.size.type=SizeBasedTriggeringPolicy
appender.test_error.policies.size.size=50000KB
appender.test_error.strategy.type=DefaultRolloverStrategy
appender.test_error.strategy.max=10
rootLogger.level=info
rootLogger.appenderRefs=test test_error
rootLogger.appenderRef.test.level=info
rootLogger.appenderRef.test.ref=test
rootLogger.appenderRef.test_error.level=error
rootLogger.appenderRef.test_error.ref=test_error
资源/log4j2.component.properties
Log4jContextSelector=org.apache.logging.log4j.core.selector.JndiContextSelector
WEB_INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
<display-name>Test Log4j Web</display-name>
<listener>
<listener-class>
test.log4j.listener.StartStopListener
</listener-class>
</listener>
<filter>
<filter-name>log4jServletFilter</filter-name>
<filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>log4jServletFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
<dispatcher>ASYNC</dispatcher><!-- Servlet 3.0 w/ disabled auto-initialization only; not supported in 2.5 -->
</filter-mapping>
<context-param>
<param-name>isLog4jAutoInitializationDisabled</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>isLog4jContextSelectorNamed</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>log4jContextName</param-name>
<param-value>testLog4j</param-value>
</context-param>
</web-app>
构建.gradle
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'war'
group = 'test.log4j.service'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
compile group: 'org.apache.tomcat', name: 'tomcat-servlet-api', version: '8.0.53'
compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.11.1'
compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.11.1'
compile group: 'org.apache.logging.log4j', name: 'log4j-jul', version: '2.11.1'
compile group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.11.1'
compile group: 'org.apache.logging.log4j', name: 'log4j-web', version: '2.11.1'
}
sourceSets {
main {
java {
srcDirs = ['src']
}
resources {
srcDirs = ['resources']
}
}
test {
java {
srcDirs = ['src', 'test']
}
resources {
srcDirs = ['resources']
}
}
}
war{
webInf {
from("WEB_INF")
include "web.xml"
}
metaInf {
from("resources/META_INF")
include "*"
}
}
编辑:我将 Tomcat 的日志系统从 JUL 切换到 log4j2(请参阅Log4j App Server Integration),现在这个问题也会影响 Tomcat 的日志。
Edit2:这似乎是 Ubuntu 对 tomcat8 的 logrotate 配置的问题。编辑 logrotate 配置后问题消失。
解决方案
推荐阅读
- javascript - 模块导出对象搜索和获取项目 node.js
- python - 蛮力产生可能的排列
- c# - C#比较2天,分钟没有正确比较
- angular - ngrok 不适用于浏览器中的路径(Angular Webserver)
- azure - Azure ML Studio ML Pipeline - 异常:未找到临时文件
- c# - 将自定义字体加载到控制台 C# .Net Framework
- reactjs - 状态改变时,下一个 JS 不会重新渲染元素
- microsoft-teams - microsoft-teams:我们如何更新所有用户的应用程序?缺乏功能加上问题
- openssl - 包含 openssl 时,cgo CFLAGS 不起作用
- utf-8 - Linux - GREP 打印带有特殊字符的行