在生产上使用日志有利于我们查找问题。我们可以降低日志记录级别,但是,找到问题后,我们必须把日志级别提供,否则会产生很多日志。
在log4j中,提供了内部类FileWatchDog,启动一个线程,来检查log4j.properties 文件最后更改时间来重新加载配置文件。
/**
* Check every now and then that a certain file has not changed. If it has, then
* call the {@link #doOnChange} method.
*/
//使用一个线程来监视log4j.properties文件的更改
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) {
super("FileWatchdog");
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();
}
}
}
class PropertyWatchdog extends FileWatchdog
{
PropertyWatchdog(String filename) {
super(filename);
}
public void doOnChange() {
new PropertyConfigurator().doConfigure(filename, LogManager.getLoggerRepository());
}
}