今天看到log4j里的一个工具类,用来监控文件,如有变动就执行特定的操作,简单且有用,只需要实现一个doOnChange()方法即可。
从这个文件可以看出,其实log4j.properties或者log4j.xml是可以实现在线修改的,不用重启服务,只需在web.xml里加一个org.springframework.web.util.Log4jConfigListener,再用
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);
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 {@link #doOnChange} method.
@author Ceki Gülcü
@since 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 {@link
#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();
}
}
}
|