Java Web应用部署Tomcat后java.util.logging.FileHandler不生效
问题根因
Eclipse中运行正常是因为Eclipse直接以当前登录用户身份启动应用JVM,会自动加载项目内的logging.properties配置。部署到独立Tomcat 9后日志不写文件,核心诱因有三个:
- Tomcat采用自定义类加载机制加载JUL(
java.util.logging)日志实现,默认优先读取Tomcat全局conf/logging.properties配置,Web应用内的logging.properties不会被自动加载,配置不生效 - 配置同时声明了JDK原生
java.util.logging.FileHandler和Tomcat自定义org.apache.juli.FileHandler两个文件处理器,但未给Juli的FileHandler配置任何初始化参数,两个handler冲突导致文件写入逻辑初始化失败 - 运行身份与路径解析不匹配:如果Tomcat以Windows服务方式启动,运行身份是SYSTEM系统用户,
%h路径变量指向的是C:\Windows\System32\config\systemprofile而非普通用户的C:\Users\XXX目录;同时如果Tomcat进程对目标日志目录没有文件写入权限,会出现能创建目录、但无法生成日志文件的现象。
排查解决步骤
- 修正
logging.properties配置,移除冲突的handler配置,调整不合理的切分参数:
# 移除未配置参数的org.apache.juli.FileHandler,避免handler冲突 handlers=java.util.logging.FileHandler,java.util.logging.ConsoleHandler java.util.logging.ConsoleHandler.level = INFO java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter java.util.logging.FileHandler.level = INFO # 初期测试建议先写绝对路径,比如Windows下写C:/tomcat_logs/DemoWebApp/DemoWebApp%u%g.log,确认正常后再换回%h变量,避免路径解析问题 java.util.logging.FileHandler.pattern =%h/DemoWebAppLogs/DemoWebApp%u%g.log java.util.logging.FileHandler.append=true # 原配置limit=5000即5KB就切分日志、保留5000个切片的配置不合理,调整为50MB切分、保留10个历史日志,可按需修改 java.util.logging.FileHandler.limit = 52428800 java.util.logging.FileHandler.count = 10 java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
- 主动加载应用内的日志配置,避免被Tomcat全局配置覆盖。将修正后的
logging.properties放到项目WEB-INF/classes目录下,新增ServletContextListener在应用启动时主动加载JUL配置:
import java.io.InputStream; import java.util.logging.LogManager; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; @WebListener public class JulConfigLoader implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { try (InputStream configStream = Thread.currentThread().getContextClassLoader() .getResourceAsStream("logging.properties")) { LogManager.getLogManager().readConfiguration(configStream); } catch (Exception e) { // 启动时打印配置加载错误,方便排查 e.printStackTrace(); } } @Override public void contextDestroyed(ServletContextEvent sce) {} }
如果项目未使用Servlet 3.0+注解配置,在WEB-INF/web.xml中注册该监听器:
<listener> <listener-class>com.your.project.package.JulConfigLoader</listener-class> </listener>
- 排查权限与路径问题
- 不要直接以Windows服务方式启动Tomcat做测试,先进入Tomcat的
bin目录双击startup.bat前台启动,确认当前用户对日志目录有完整读写权限,排除SYSTEM用户路径不匹配问题 - 临时将日志路径改为Tomcat自身日志目录
${catalina.base}/logs/DemoWebApp%u%g.log测试,Tomcat进程默认对该目录有完整读写权限,可快速定位是否为路径/权限问题 - Linux环境下执行
chown -R 运行tomcat的用户名:运行tomcat的用户组 日志目录路径,给Tomcat进程分配目录读写权限
- 不要直接以Windows服务方式启动Tomcat做测试,先进入Tomcat的
- 检查Tomcat全局配置冲突
打开Tomcat目录下conf/logging.properties,确认没有配置org.apache.catalina.core.ContainerBase.[Catalina].[localhost]./[你的应用上下文].level = OFF这类屏蔽应用日志的配置,移除和应用内日志配置冲突的自定义handler规则。 - 错误定位
重启Tomcat后优先查看logs/catalina.out、logs/localhost.对应日期.log文件,搜索FileHandler相关的报错信息,常见的有AccessDeniedException(权限不足)、FileNotFoundException(路径不存在),根据报错信息针对性调整即可。
内容的提问来源于stack exchange,提问作者Mahmud Mridul
相关产品推荐
相关产品推荐

