[心缘地方]同学录
首页 | 功能说明 | 站长通知 | 最近更新 | 编码查看转换 | 代码下载 | 常见问题及讨论 | 《深入解析ASP核心技术》 | 王小鸭自动发工资条VBA版
登录系统:用户名: 密码: 如果要讨论问题,请先注册。

[备忘]log4j2.xml里配置日志路径,${webapp.root}不好使的问题

上一篇:[备忘]照片变清晰的厉害软件
下一篇:[备忘]log4j2动态创建Logger

添加日期:2024/2/6 15:43:17 快速返回   返回列表 阅读265次
<Configuration status="info" monitorInterval="120">
    <Properties>
        <Property name="logPath">${sys:webapp2.root}/../data/log</Property>
    </Properties>
-------------
log4j2.xml里如果写固定路径,没有问题。
但是动态拼接${webapp2.root}则不识别,直接在tomcat的bin目录创建了${webapp2.root}这个目录,伤不起。

研究了很久,搜了很久,终于解决了。
----------------------
(1)webapp2.root是web.xml里配置的
    <context-param>
        <param-name>webAppRootKey</param-name>
        <param-value>webapp2.root</param-value>
    </context-param>
这只是一个参数。

(2)还有一个listener
    <listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>
这个listener启动时,会把路径设置到system属性里,大概这样:
String root = servletContext.getRealPath("/");
String param = servletContext.getInitParameter("webAppRootKey");
String key = param != null ? param : "webapp.root";
System.setProperty(key, root);
key就是上一步设置的参数名,不设置就默认是webapp.root。

(3)看起来没有问题,对吧。但是,log4j2.xml里就是不识别。
debug了下,发现log4j2初始化比较早,
public class Log4jServletContainerInitializer implements ServletContainerInitializer 
它是一个ServletContainerInitializer,比Listener先执行。
所以Listener设置的webapp.root属性,前者看不到。

(4)搜了半天,发现可以这样:


public class MyLog4jConfigListener extends Log4jConfigListener {

    @Override
    public void contextInitialized(ServletContextEvent event) {

        super.contextInitialized(event);

        //log4j2初始化较早,这里设置webapp.root系统属性后,需要重载log4j,否则不能识别webapp.root
        org.apache.logging.log4j.core.LoggerContext ctx =
                (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(false);
        ctx.reconfigure();

    }
}


然后web.xml里改成这个listener,也就是设置webapp.root后,重载了下log4j2,就好使了。
(5)或者这样:${sys:catalina.home},这是tomcat根目录,用它拼也行,直接用,省事。
--------------------------------------------------
【结果】
用了MyLog4jConfigListener后,发现有个问题,
log4j2第一次初始化,会在tomcat目录建了data/log目录,
因为{webapp2.root}不识别,所以当前目录是tomcat/bin目录。

然后MyLog4jConfigListener里reconfigure后,才在正确位置创建data/log目录。
虽无大碍,但是感觉不爽。

最后查了半天,发现可以直接用
<Property name="logPath">${web:rootDir}/../data/log</Property>
这是log4j2内置的,哈哈

也不用修改MyLog4jConfigListener进行reconfigure了。
完美。

参考:
https://logging.apache.org/log4j/2.x/manual/webapp.html
https://logging.apache.org/log4j/2.x/manual/lookups.html#WebLookup
大概就是,log4j2,依赖webapp3.0,通过ServletContainerInitializer,实现自身自启动,
并且在spring之前启动,所以才有我那个问题。
自启动可以通过context-param来关闭,但是就得自己来启动,很麻烦。
折腾半天,就为了路径,不值得,直接用${web:rootDir}搞定,完美。


 

评论 COMMENTS
没有评论 No Comments.

添加评论 Add new comment.
昵称 Name:
评论内容 Comment:
验证码(不区分大小写)
Validation Code:
(not case sensitive)
看不清?点这里换一张!(Change it here!)
 
评论由管理员查看后才能显示。the comment will be showed after it is checked by admin.
CopyRight © 心缘地方 2005-2999. All Rights Reserved