Log4J 在系统运行时更改log4j的配置

一、使用log4j自带的动态更新配置文件的方法

使用log4j自带的动态更新配置很简单,只要调用 PropertyConfigurator 或者 DOMConfigurator类的 configureAndWatch(String configFileName)或者 configureAndWatch(String configFileName, long delay)方法就可以了。
 
实现的原理

在调用PropertyConfigurator 或者 DOMConfigurator类的configureAndWatch方法时log4j会创建一个线程,定时的去检查配置文件是否改变,如果改变的话就重新加载配置文件。

configureAndWatch方法参数的介绍:

String configFileName:配置文件的路径加文件名。

long delay:扫描配置文件是否改变的间隔时间。默认值是 60 秒。

注意:在log4j中每调用一次configureAndWatch方法都会启动一个新的扫描线程。
实例代码:

package com.kun;
 
import org.apache.log4j.Logger;

import org.apache.log4j.PropertyConfigurator;
 
public class TestLog4j
{
    public static Logger logger = Logger.getLogger(TestLog4j.class);
    static
    {
        PropertyConfigurator.configureAndWatch("./log4j.properties", 60000);
    }
    public static void printLog()
    {
        if (logger.isDebugEnabled())
        {
            logger.debug("debug!!");
        }
        if (logger.isInfoEnabled())
        {
            logger.info("info!!");
        }
        logger.error("error!!");
    }
    public static void main(String[] args)
    {
        while (!Thread.interrupted())
        {
            TestLog4j.printLog();
            try
            {
                Thread.sleep(1000);
            } catch (InterruptedException e)
            {
            }
        }
    }
}


二、自己创建动态更新配置文件的类和方法

     在第一章中我们可以通过PropertyConfigurator的 configureAndWatch(String configFileName, long delay)方法来进行动态的改变log4j的配置,但是他采用了轮询方式来实现的,现在我们需要触发机制来完成这个功能。

实现的原理

    开始的思考中,认为应该通过自定义一套log4j的配置信息,然后启动log4j的同时启动一个server ,socket或者web service一类的服务,然后再通过消息来进行log4j的配置。后来发现当调用PropertyConfigurator对象的configure(String configFilename)方法时就可以重新配置log4j。

    但是我们还不能确定log4j系统正在运行时,再次调用configure(String configFilename)方法,会不会对系统运行的产生其他的影响?当查看log4j源码后这个问题被解决了。因为 PropertyConfigurator的 configureAndWatch(String configFileName, long delay)方法就是启动一个线程并在这个线程中反复的实例化一个PropertyConfigurator对象,并调用他的 doConfigure(String configFileName, LoggerRepository hierarchy)方法,而PropertyConfigurator对象的configure(String configFilename)也是实例化一个PropertyConfigurator对象,并调用他的doConfigure(String configFileName, LoggerRepository hierarchy)方法。所以可以确定在log4j运行时调用configure(String configFilename)方法是不会对系统造成什么不良影响的,除非log4j本身就存在问题。

     现在问题就比较简单了,就是如何调用configure(String configFilename)方法了。这个当然就和实际的业务分不开了,如果是一个web应用,那当然是通过页面来调用。如果是web service应用,那当然是使用开发的服务来调用。这个就要根据实际的应用来确定了。

实例代码:
这是一个WEB方式的调用代码:
TestLog4jReload.java:

package com.kun;
 
import org.apache.log4j.PropertyConfigurator;
 
public class TestLog4jReload
{
     public static void reloadLog4jConfig()
    {
        PropertyConfigurator.configure("./log4j.properties");
    } 
}

TestLog4jReload.jsp:

<%@ page contentType = "text/html;charset=UTF-8" language = "java" %>
<%@ page import = "java.util.*, java.io.*" %>
<%@ page import = "com.kun.TestLog4jReload %>

<%
    String state = request.getParameter("state");
    if(state != null && state.trim().equals("start"))
    {
        TestLog4jReload.reloadLog4jConfig();
    }
%>
<HTML>
 <HEAD>
  <TITLE> 动态更新log4j配置 </TITLE>
 </HEAD>
 <BODY>
  <A href="TestLog4jReload.jsp?state=start">开始</A>
 </BODY>
</HTML>

相关推荐