JDK日志框架之实例结合STAF,STAF 日志服务概念的提出,这方面是什么情况呢?让我们首先从什么是STAF开始。
STAF(Software Testing Automation Framework)是一个自动化软件测试框架,它可以实现分布式的自动化软件测试管理。我们可以应用 STAF 库的 Java API 来做基于 STAF 框架的应用,同时 STAF 同时也提供了日志服务。其日志服务是用来记录自动化测试流程中的信息,方便在 24x7 的自动化测试中记录自动化测试的操作,便于发现潜在的自动化测试管理脚本的问题。
既然我们可以用 STAF 的 Java API 来做基于 STAF 的应用,我们也可以将JDK 的日志框架同 STAF 的日志服务接口结合起来。 STAF 的日志服务的 java 接口定义如清单 7 所示:
清单 7 STAFLog 类定义
public class STAFLog
{
public STAFLog(String logType, String logName, STAFHandle handle);
public STAFResult log(int level, String msg)
// Log type constAnts
public static STAFResult log(STAFHandle theHandle, String logType,
String logName, int level, String msg)
public String getName();
public String getLogType();
public int getMonitorMask();
... //other methods
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
从清单 7 我们可以看出,STAFLog 类提供了方法可以将日志信息存储到 STAF 的日志库中, 这个日志库既可以是本地的文件,也可以是另一个 STAF 服务器上的JDK日志库。这是通过本地 STAF 服务器的配置来决定的。而 STAFLog.log() 方法只用于记录日志信息。
将 STAF 日志服务的 java API 同JDK日志框架结合起来需要做如下步骤:
创建 STAF 日志 Handler 类
该类封装了 STAF 日志服务 API 的接口。同时 STAF 的 Java API 需要一个全局的 STAFHandle 对象,用来表示本地的 STAF 服务句柄。这个可以通过建立一个静态的 STAFHandle 对象即可。其代码如下所示,我们定义了一个 STAFHandler 类如清单 8 所示。
清单 8 STAFHandler 类实现
import java.util.logging.*;
import com.ibm.staf.wrapper.STAFLog;
public class STAFHandler extends Handler {
private String logName;
private static STAFHandle stafHandle = null;
public STAFHandler(String name) {
configure();
logName = name;
}
public STAFHandler() {
configure();
}
@Override
public void close() throws SecurityException {
if (stafHandle != null){
try {
stafHandle.unRegister();
} catch (STAFException e) {
//ignore
}
}
}
@Override
public void flush() {
//nothing
}
@Override
public void publish(LogRecord record) {
if (!isLoggable(record)) {
return;
}
String msg;
try {
msg = getFormatter().format(record);
} catch (Exception ex) {
reportError(null, ex, ErrorManager.FORMAT_FAILURE);
return;
}
try {
STAFLog.log(stafHandle, STAFLog.MACHINE,
logName, record.getLevel().getName(), msg);
} catch (Exception ex) {
reportError(null, ex, ErrorManager.WRITE_FAILURE);
}
...
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
在实现 STAFHandler 类时有以下几个要点:
1、由于 STAF API 的调用时需要一个 STAFHandle 的对象来代表本地的 STAF 服务,在该类中声明了一个全局变量用来存储 STAFHandle .
2、close 方法是用来清理系统资源的,上述代码的 close 方法中释放了全局变量 STAFHandle 对象。
3、publish 方法就是获得格式化后的消息后,直接调用 STAF 的日志 API 将日志发送到 STAF 服务中。
但到目前为止,我们还没有给 STAFHandler 类添加一个配置的代码,使之可以支持配置文件。下面我们定义了一个函数 configure,其代码如清单 9 所示。
清单 9 配置函数实现
private void configure() {
if (stafHandle == null) {
try {
stafHandle = new STAFHandle("my application");
} catch (STAFException e) {
reportError("registe staf handle error", e, ErrorManager.OPEN_FAILURE);
}
}
LogManager manager = LogManager.getLogManager();
String cname = getClass().getName();
//set staf log name
logName = manager.getProperty(cname + ".name");
if (logName == null)
logName = "demo.staflog";
//set formatter
String sformatter = manager.getProperty(cname + ".formatter");
Formatter formatter = null;
if (sformatter != null) {
try {
formatter = (Formatter)Class.forName(sformatter).newInstance();
} catch (Exception e) {
//ignore
}
}
setFormatter(formatter == null? new STAFFormatter() : formatter);
//set level
String sLevel = manager.getProperty(cname + ".level");
Level level = null;
if (sLevel != null) {
try {
level = STAFLevel.parse(sLevel);
} catch (Exception e) {
//ignore
}
}
setLevel(level == null? STAFLevel.DEBUG : level);
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
在实现配置文件支持的代码中,有以下几个要点:
1、STAF API 的初始化需要注册 STAFHandle 对象。而且该注册只能执行一次。我们根据全局变量 stafHandle 的值来决定是否注册该对象。
2、JDK的日志框架有一个全局的 singleton 管理类 STAFManager,该类用于管理日志类,并提供了读取日志配置文件的成员函数 getProperty 。在上述的代码中,我们通过 STAFManager.getProperty 方法,从日志配置文件中读取 STAFHandler 对象所设置的 Formatter 类名,然后通过反射生成一个新的 Formatter 对象,设置到 Handler 对象中。
3、对于日志级别也是通过 STAFManager.getProperty 方法。需要注意的是由于我们的日志级别是自定义的级别,所以 Level 对象是由我们自定义的 Level 类 STAFLevel 来生成的。
4、我们也能定义自己需要的属性。比如清单 9 中我们定义了一个 .name 属性,用来存储 STAF 日志名称,通过 getProperty 函数从配置文件中读取 .name 属性。
JDK日志框架之实例结合STAF的情况就介绍到这里,那么关于JDK日志框架之实例结合STAF的更多情况,我们要在学习过程中加以巩固提高。
【编辑推荐】