]log4j FileWatchdog工具类,用来监控文件,如有变动就执行特定的操作

今天看到log4j里的一个工具类,用来监控文件,如有变动就执行特定的操作,简单且有用,只需要实现一个doOnChange()方法即可。

 从这个文件可以看出,其实log4j.properties或者log4j.xml是可以实现在线修改的,不用重启服务,只需在web.xml里加一个org.springframework.web.util.Log4jConfigListener,再用<context-param>配置一个初始属性log4jRefreshInterval,即刷新log4j配置信息的间隔时间,单位是毫秒,如下:

 

?
1
2
3
4
5
6
7
8
9
10
11
< context-param >
         < param-name >log4jConfigLocation</ param-name >
         < param-value >log4j.properties</ param-value >
     </ context-param >
     < context-param >
         < param-name >log4jRefreshInterval</ param-name >
         < param-value >60000</ param-value >
     </ context-param >
     < listener >
         < listener-class >org.springframework.web.util.Log4jConfigListener</ listener-class >
     </ listener >

非web应用的话需要写一个类Foo继承org.apache.log4j.varia.ReloadingPropertyConfigurator,重写doConfigure方法,直接调用org.apache.log4j.PropertyConfigurator.configureAndWatch(String, long);
然后在启动非web应用时加系统属性-Dlog4j.configuratorClass=Foo (这里要全路径),用于指定log4j Configurator的实现类。
我自己写了一个MyLog4jConfigurator,已经测试通过,如下:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.mashiguang;
 
import java.net.URL;
 
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.varia.ReloadingPropertyConfigurator;
 
public class MyLog4jConfigurator extends ReloadingPropertyConfigurator {
     
     PropertyConfigurator delegate = new PropertyConfigurator();
 
     @Override
     public void doConfigure(URL url, LoggerRepository repository) {
         delegate.configureAndWatch(url.getFile(), 1000 );
     }
}

 

 

FileWatchdog源码如下:

/*

  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
  *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
// Contributors:  Mathias Bogaert
 
package org.apache.log4j.helpers;
 
import java.io.File;
import org.apache.log4j.helpers.LogLog;
 
/**
    Check every now and then that a certain file has not changed. If it
    has, then call the {<a href="http://my.oschina.net/link1212" target="_blank" rel="nofollow">@link</a>  #doOnChange} method.
 
 
    <a href="http://my.oschina.net/arthor" target="_blank" rel="nofollow">@author</a>  Ceki G&uuml;lc&uuml;
    <a href="http://my.oschina.net/u/266547" target="_blank" rel="nofollow">@since</a>  version 0.9.1 */
public abstract class FileWatchdog extends Thread {
 
   /**
      The default delay between every file modification check, set to 60
      seconds.  */
   static final public long DEFAULT_DELAY = 60000 ;
   /**
      The name of the file to observe  for changes.
    */
   protected String filename;
   
   /**
      The delay to observe between every check. By default set {<a href="http://my.oschina.net/link1212" target="_blank" rel="nofollow">@link</a>
      #DEFAULT_DELAY}. */
   protected long delay = DEFAULT_DELAY;
   
   File file;
   long lastModif = 0 ;
   boolean warnedAlready = false ;
   boolean interrupted = false ;
 
   protected
   FileWatchdog(String filename) {
     this .filename = filename;
     file = new File(filename);
     setDaemon( true );
     checkAndConfigure();
   }
 
   /**
      Set the delay to observe between each check of the file changes.
    */
   public
   void setDelay( long delay) {
     this .delay = delay;
   }
 
   abstract
   protected
   void doOnChange();
 
   protected
   void checkAndConfigure() {
     boolean fileExists;
     try {
       fileExists = file.exists();
     } catch (SecurityException  e) {
       LogLog.warn( "Was not allowed to read check file existance, file:[" +
           filename+ "]." );
       interrupted = true ; // there is no point in continuing
       return ;
     }
 
     if (fileExists) {
       long l = file.lastModified(); // this can also throw a SecurityException
       if (l > lastModif) {           // however, if we reached this point this
     lastModif = l;              // is very unlikely.
     doOnChange();
     warnedAlready = false ;
       }
     } else {
       if (!warnedAlready) {
     LogLog.debug( "[" +filename+ "] does not exist." );
     warnedAlready = true ;
       }
     }
   }
 
   public
   void run() {   
     while (!interrupted) {
       try {
         Thread.sleep(delay);
       } catch (InterruptedException e) {
     // no interruption expected
       }
       checkAndConfigure();
     }
   }
}

 

猜你喜欢

转载自lihaiming.iteye.com/blog/2254567