java 缓存日志_Java日志缓存机制的实现(3)

清单 7

publicclassMyHandlerextendsHandler{

// 在构造方法中实现 setErrorManager 方法

publicMyHandler(){

......

setErrorManager (newErrorManager() {

publicvoiderror (String msg, Exception ex,intcode) {

System.err.println("Error reported by MyHandler "

+ msg + ex.getMessage());

}

});

}

publicvoidpublish(LogRecord record){

if(!isLoggable(record))return;

try{

// 一些可能会抛出异常的操作

} catch(Exception e) {

reportError ("Error occurs in publish ", e, ErrorManager.WRITE_FAILURE);

}

}

......

}

logging.properties

logging.properties 文件是 Java 日志的配置文件,每一行以“key=value”的形式描述,可以配置日志的全局信息和特定日志配置信息,清单 8 是我们为测试代码配置的 logging.properties。

清单 8. logging.properties 文件示例

#Level 等级 OFF > SEVERE > WARNING > INFO > CONFIG > FINE > FINER > FINEST > ALL

# 为 FileHandler 指定日志级别

java.util.logging.FileHandler.level=WARNING

# 为 FileHandler 指定 formatter

java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter

# 为自定义的 TestMemoryHandler 指定日志级别

com.ibm.test.MemoryHandler.level=INFO

# 设置 TestMemoryHandler 最多记录日志条数

com.ibm.test.TestMemoryHandler.size=1000

# 设置 TestMemoryHandler 的自定义域 useParentLevel

com.ibm.test.TestMemoryHandler.useParentLevel=WARNING

# 设置特定 log 的 handler 为 TestMemoryHandler

com.ibm.test.handlers=com.ibm.test.TestMemoryHandler

# 指定全局的 Handler 为 FileHandler

handlers=java.util.logging.FileHandler

从 清单 8 中可以看出 logging.properties 文件主要是用来给 logger 指定等级(level),配置 handler 和 formatter 信息。

如何监听 logging.properties

如果一个系统对安全性要求比较高,例如系统需要对更改 logging.properties 文件进行日志记录,记录何时何人更改了哪些记录,那么应该怎么做呢?

这里可以利用 JDK 提供的 PropertyChangeListener 来监听 logging.properties 文件属性的改变。

例如创建一个 LogPropertyListener 类,其实现了 java.benas.PropertyChangeListener 接口,PropertyChangeListener 接口中只包含一个 propertyChange(PropertyChangeEvent)方法,该方法的实现如清 9 所示。

清单 9. propertyChange 方法的实现

@Override

publicvoidpropertyChange(PropertyChangeEvent event) {

if(event.getSource()instanceofLogManager){

LogManager manager=(LogManager)event.getSource();

update(manager);

execute();

reset();

}

}

propertyChange(PropertyChangeEvent)方法中首先调用 update(LogManager)方法来找出 logging.properties 文件中更改的,增加的以及删除的项,这部分代码如清单 10 所示;然后调用 execute() 方法来执行具体逻辑,参见 清单 11;最后调用 reset() 方法对相关属性保存以及清空,如 清单 12 所示。

清单 10. 监听改变的条目

public void update(LogManager manager){

Properties logProps = null ;

// 使用 Java 反射机制获取私有属性

try{

Field f = manager.getClass().getDeclaredField("props");

f.setAccessible(true );

logProps=(Properties)f.get(manager);

}catch (Exception e){

logger.log(Level.SEVERE,"Get private field error.", e);

return;

}

Set logPropsName=logProps.stringPropertyNames();

for(String logPropName:logPropsName){

String newVal=logProps.getProperty(logPropName).trim();

// 记录当前的属性

newProps.put(logPropName, newVal);

// 如果给属性上次已经记录过

if(oldProps.containsKey(logPropName)){

String oldVal = oldProps.get(logPropName);

if(newVal== null ?oldVal== null :newVal.equals(oldVal)){

// 属性值没有改变,不做任何操作

}else{

changedProps.put(logPropName, newVal);

}

oldProps.remove(logPropName);

}else{// 如果上次没有记录过该属性,则其应为新加的属性,记录之

changedProps.put(logPropName, newVal);

}

}

}

代码中 oldProps、newProps 以及 changedProps 都是 HashMap类型,oldProps 存储修改前 logging.properties 文件内容,newProps 存储修改后 logging.properties 内容,changedProps 主要用来存储增加的或者是修改的部分。

方法首先通过 Java 的反射机制获得 LogManager 中的私有属性 props(存储了 logging.properties 文件中的属性信息),然后通过与 oldProps 比较可以得到增加的以及修改的属性信息,最后 oldProps 中剩下的就是删除的信息了。

内容导航

第 1 页:清单1-3 第 2 页:清单4-6

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值