`

如何通过项目配置文件指定Log4J的配置文件

阅读更多
引言
打造易于部署的WEB应用项目 一文中,我们介绍了如何对WEB项目进行重构,使项目WAR包无状态化,给项目部署升级带来了极大的便利的方法:
   1)首先是将项目配置文件通过JVM系统参数指定,将项目部署文件移出WAR包,使项目WAR包只包含程序,不包含配置信息;
   2)此外,还介绍了在Maven项目中如何通过jetty插件提供JNDI数据源,将数据源配置移出Spring配置文件的方法。
   我们给出的解决办法不但照顾到生产环境项目的可部署性,还兼顾了项目开发环境的可移植性,两者天然统一,真可移为“最佳的项目实践”了 

   但我们还留下了一个未考虑到的重要问题:即如何将项目的日志配置文件(即log4j的配置文件)也移出项目之外?因为,在生产环境下,项目运行性时,我们往往需要对项目的日志行为进行控制:如日志级别、日志文件大小等。

传统Log4J如何配置呢?  

   使用Spring框架的Web项目,一般是在web.xml中通过org.springframework.web.util.Log4jConfigListener配置Log4j的,它通过一个
log4jConfigLocation上下文参数指定log4J配置文件的地址,如下所示:
<context-param>  
    <param-name>log4jConfigLocation</param-name>  
    <param-value>WEB-INF/log4j.properties</param-value>  
</context-param>  
<context-param>  
    <param-name>log4jRefreshInterval</param-name>  
    <param-value>600000</param-value>  
</context-param>  
<listener>  
    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>  
</listener>   

   虽然你可以指定一个独立于WAR的外部log4j配置文件(如f:/conf/log4j.properties),但是,这样一来就限制了生产环境时log4j配置文件的路径的自由性,另外,log4j配置文件独立于Web项目,开发环境就麻烦了。
   我们期望的解决方案,是要统一开发环境又生产环境的便捷性,因此我们希望通过一个项目配置文件的属性定义log4j配置文件。如果一来,在开发环境下将项目配置文件的属性指向项目中的log4j配置文件,而生产环境下,则指向一个外部的log4j配置文件。

最佳实践 

   为了可以通过项目配置文件的属性指定log4j配置文件,我们需要复写org.springframework.beans.factory.config.PropertiesFactoryBean类,以便在加载属性文件时,通过属性值加载log4j配置文件,初始化Log4J日志引擎。
引用
为啥非要找PropertiesFactoryBean开刀呢?因为我们希望尽早初始化log4j引擎,而启动Spring时,加载项目配置文件是第一件来做的事,因此搭这班快车就是再自然不过的了 


完成任务的人    
   来看我们如何复写PropertiesFactoryBean类:
package com.xxx.sys;

import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.util.Assert;
import org.springframework.util.Log4jConfigurer;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.Properties;

/**
 * 加载平台属性文件,同时初始化Log4J引擎
 * @author : chenxh
 * @date: 2015/7/28
 */
public class FrameworkPropertiesFactoryBean extends PropertiesFactoryBean {

    private static final String LOG4J_CONF_LOCATION = "log4j.conf.location";

    private static final int REFRESH_INTERVAL_INSECONDS = 5;
    public static final String REFRESH_INTERVAL = "log4j.conf.refreshInterval";

    @Override
    protected Properties createProperties() throws IOException {
        Properties properties = super.createProperties();

        //①通过项目配置文件初始化Log4J引擎配置
        initLog4j(properties);
        return properties;
    }


    private void initLog4j(Properties properties) throws IOException{
        String confLocation = properties.getProperty(LOG4J_CONF_LOCATION);
        Assert.hasText(confLocation,"配置文件未定义:"+LOG4J_CONF_LOCATION);
        String refreshInterval = properties.getProperty(REFRESH_INTERVAL);
        long refreshIntervalLong = REFRESH_INTERVAL_INSECONDS;
        if (StringUtils.hasText(refreshInterval)) {
            int value = Integer.parseInt(refreshInterval);
            if (value < 2) {
                value = 2;
            }
            refreshIntervalLong = Integer.parseInt(refreshInterval)*1000L;
        }

        //②初始化Log4J引擎的配置
        Log4jConfigurer.initLogging(confLocation,refreshIntervalLong);
    }
}


    使用Spring的org.springframework.util.Log4jConfigurer可轻易初始化Log4J引擎,因为这里我们覆盖PropertiesFactoryBean的createProperties()方法,在加载项目配置文件之后,马上初始化Log4J引擎。


安装它   
   写好FrameworkPropertiesFactoryBean后,我们就要替换Spring配置文件中关于项目属性文件的初始化内容了:
    将以下片段:
<bean id="frameworkConf"
          class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="locations">
            <list>
                <value>#{systemProperties.FRAMEWORK_CONFFILE_PATH}</value>
                <value>classpath*:conf/frameworkVersion.properties</value>
            </list>
        </property>
    </bean>

    替换为:
<bean id="frameworkConf"
          class="com.hsit.tso.framework.web.sys.FrameworkPropertiesFactoryBean">
        <property name="locations">
            <list>
                <value>#{systemProperties.FRAMEWORK_CONFFILE_PATH}</value>
                <value>classpath*:conf/frameworkVersion.properties</value>
            </list>
        </property>
    </bean>

   这样FrameworkPropertiesFactoryBean初始化时,Log4J引擎就初始化就绪了。

项目配置文件相关属性 
   我们是通过项目配置文件的log4j.conf.location及log4j.conf.refreshInterval来定义Log4J配置文件路径及更新刷新周期的。在开发环境下,我们可以这样定义:
#log4j的配置文件路径
#1)文件如果在类路径下,以classpath:为前缀,形如:classpath:conf/log4j.properties
#2)文件如果在文件系统下,则采用文件绝对路径,形如 f:/log4j.properties,/etc/conf/log4j.properties

#①这儿=>开发环境嘛,当然基于类路径了
log4j.conf.location=classpath:conf/log4j.properties
#log4j.conf.location=f:/log4j.properties
#日志配置文件变更扫描刷新周期,单位为秒
log4j.conf.refreshInterval=5

   而生产环境下,我们可以这样定义:
#log4j的配置文件路径
#1)文件如果在类路径下,以classpath:为前缀,形如:classpath:conf/log4j.properties
#2)文件如果在文件系统下,则采用文件绝对路径,形如 f:/log4j.properties,/etc/conf/log4j.properties

#①这儿=>生产环境哦,基于文件系统的路径了
log4j.conf.location=f:/log4j.properties
#log4j.conf.location=f:/log4j.properties
#日志配置文件变更扫描刷新周期,单位为秒
log4j.conf.refreshInterval=5


小结
  为了方便,在生产环境下,建议将Log4J配置文件log4j.properties和项目配置文件放在同一个目录下,这样要更改项目的配置时,只要在这个目录下找到配置文件更改即可。当然了,在开发环境下,也将两者放在一起管理为好,来看我的项目目录结构:


   至此,我们就让WEB项目完全无状态化:项目属性文件,数据源,log4J配置文件都外化管理,项目实施人员升级只管大胆更新WAR包,不想笑都难了。 

以后在此维护新文章:
https://www.jianshu.com/u/d7f090245ddd



 
  • 大小: 70.3 KB
分享到:
评论
2 楼 飞天奔月 2015-08-22  
如果是你文章的需求, 我倒是建议你 继承 Log4jConfigListener 自定义实现

而不是 PropertiesFactoryBean
1 楼 飞天奔月 2015-08-22  
要说 "希望尽早初始化log4j引擎", 那非 Listener不可以了


哥,你应该听说过 org.springframework.web.util.Log4jConfigListener

相关推荐

    log4j配置文件和jar包

    log4j配置文件和jar包是日志的必须的东西,下载之后导入即可使用

    log4j2配置文件,按照文件大小划分日志,保存日期天数内的日志等

    log4j2配置文件,按照文件大小划分日志,保存日期天数内的日志,指纹日志命名规则,日志输出等级等功能

    log4j乱码问题解决办法

    在log4j.properties配置文件中可以指定字符编码: 下面这行配置指定了两个appender: log4j.rootCategory=INFO,appender1的名字,appender2的名字 下面这两行配置将上一行的两个appender的字符编码配置为GBK:

    Log4j日志根据模块不同输出到不同的日志文件开发配置,便于监控项目各功能模块的运行情况

    文件中内容包括模块中某个类单独输出到一个日志文件中、模块中某个package单独输出到一个日志文件中、同一模块不同package输出到一个日志文件中三种情况下log4j.properties配置项配置事例、Java类中代码如何一致编写...

    Log4j学习和详细配置

    Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是...

    Log4J详细文档.doc

    Log4J(Log for java)是Apache的一个开放源代码项目,它是一个日志操作包,通过使用Log4J,可以指定日志信息输出的目的地,如控制台、文件、CUI组件、NT的事件记录器;还可以控制每一条日志输出格式。此外,通过...

    打印日志等异常处理,使用Log4j的配置

    #如果一条日志信息的级别大于等于配置文件的级别,就记录配置输出源所对应的辅助类:log4j.appender.输出源名称=类名,如果输出到文件就写FileAppender #指定文件名 Tomcat的根目录: #指定布局方式(消息放入文件...

    深入学习log4j

    Loggers组件的主要功能是提供相应API,根据不同配置的loggers将不同级别的log输入到控制台或文件,类似于java中经常用到的System.out.println,但是log4j封装后的loggers组件能够输出更丰富的信息,包括时间,线程,...

    log4j(二):动态配置日志输出路径

    NULL 博文链接:https://1017401036.iteye.com/blog/2332210

    重写log4j流记录日志到指定文件

    重写log4j流记录日志到指定文件采用了xml,properties文件配置,日志记录容量达到指定配置文件最大容量大小,自动增加新日志文件,配置简单。只需要把log4.xml,log4j.properties文件复制到src目录中,源码文件放在...

    log4j.xml文件的配置文.pdf

    log4j.xml文件的配置文.pdf

    Log4j日志管理系统简单使用说明

    在实际编程时,要使Log4j真正在系统中运行事先还要对配置文件进行定义。定义步骤就是对Logger、Appender及Layout的分别使用,具体如下:    1、 配置根Logger,其语法为:  log4j.rootLogger = [ level ] , ...

    log4j 不同级别 不同文件 发送邮件配置

    log4j 通过配置完成多级别输出到多文件中,并且可以发送邮件到指定目的地。

    log4j 使用说明 很信息

    Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式...

    Log4j教材

    Log4J是Apache的一个开放源代码项目,它是一个日志操作包,通过使用Log4J,可以指定日志信息输出的目的地,如控制台、文件、CUI组件、NT的事件记录器;还可以控制每一条日志输出格式。此外,通过定义日志信息的...

    log4j 配置日志文件,把日志信息输出到项目的某个文件夹下

    log4j 配置日志文件,把日志信息输出到项目的某个文件夹下,能把当前的日志输出到项目下制定的某文件夹,只要到web.xml配置log4j_save保存日志文件

    详解Log4j 日志文件存放位置设置

    主要介绍了详解Log4j 日志文件存放位置设置,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    守护进程、脚本、指定外部配置文件

    ①守护进程(daemon)是一类在后台运行的特殊进程,用于执行特定的系统任务。很多守护进程在系统引导的时候启动,并且一直运行直到系统关闭。另一些只在需要的时候才...③springboot项目、指定了外部配置文件log4j2.yml

    Log4j 日志文件Linux/Mac/Windows通用存放位置设置方法

    log4j1/log4j2中category的配置以及log的输出位置(windows和linux通用的log输出位置) 一、场景和需求 假设我现在有3个独立的用project(暂时用maven关联起来,当然也可以不用maven),一个是提供公共服务的...

    log4j 文件输出

    写一个动态生成Properties(log4j.properties加载到内存中的形式)的类,指定,可实现动态修改任何东西! ====================== 目录不...你可以将log4j的配置信息写在一个文件中,比如sort.properties 然后利用servlet对

Global site tag (gtag.js) - Google Analytics