JDK日志框架之實(shí)例結(jié)合STAF淺析
JDK日志框架之實(shí)例結(jié)合STAF,STAF 日志服務(wù)概念的提出,這方面是什么情況呢?讓我們首先從什么是STAF開始。
STAF(Software Testing Automation Framework)是一個(gè)自動(dòng)化軟件測(cè)試框架,它可以實(shí)現(xiàn)分布式的自動(dòng)化軟件測(cè)試管理。我們可以應(yīng)用 STAF 庫的 Java API 來做基于 STAF 框架的應(yīng)用,同時(shí) STAF 同時(shí)也提供了日志服務(wù)。其日志服務(wù)是用來記錄自動(dòng)化測(cè)試流程中的信息,方便在 24x7 的自動(dòng)化測(cè)試中記錄自動(dòng)化測(cè)試的操作,便于發(fā)現(xiàn)潛在的自動(dòng)化測(cè)試管理腳本的問題。
既然我們可以用 STAF 的 Java API 來做基于 STAF 的應(yīng)用,我們也可以將JDK 的日志框架同 STAF 的日志服務(wù)接口結(jié)合起來。 STAF 的日志服務(wù)的 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
- }
從清單 7 我們可以看出,STAFLog 類提供了方法可以將日志信息存儲(chǔ)到 STAF 的日志庫中, 這個(gè)日志庫既可以是本地的文件,也可以是另一個(gè) STAF 服務(wù)器上的JDK日志庫。這是通過本地 STAF 服務(wù)器的配置來決定的。而 STAFLog.log() 方法只用于記錄日志信息。
將 STAF 日志服務(wù)的 java API 同JDK日志框架結(jié)合起來需要做如下步驟:
創(chuàng)建 STAF 日志 Handler 類
該類封裝了 STAF 日志服務(wù) API 的接口。同時(shí) STAF 的 Java API 需要一個(gè)全局的 STAFHandle 對(duì)象,用來表示本地的 STAF 服務(wù)句柄。這個(gè)可以通過建立一個(gè)靜態(tài)的 STAFHandle 對(duì)象即可。其代碼如下所示,我們定義了一個(gè) STAFHandler 類如清單 8 所示。
清單 8 STAFHandler 類實(shí)現(xiàn)
- 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);
- }
- ...
在實(shí)現(xiàn) STAFHandler 類時(shí)有以下幾個(gè)要點(diǎn):
1、由于 STAF API 的調(diào)用時(shí)需要一個(gè) STAFHandle 的對(duì)象來代表本地的 STAF 服務(wù),在該類中聲明了一個(gè)全局變量用來存儲(chǔ) STAFHandle .
2、close 方法是用來清理系統(tǒng)資源的,上述代碼的 close 方法中釋放了全局變量 STAFHandle 對(duì)象。
3、publish 方法就是獲得格式化后的消息后,直接調(diào)用 STAF 的日志 API 將日志發(fā)送到 STAF 服務(wù)中。
但到目前為止,我們還沒有給 STAFHandler 類添加一個(gè)配置的代碼,使之可以支持配置文件。下面我們定義了一個(gè)函數(shù) configure,其代碼如清單 9 所示。
清單 9 配置函數(shù)實(shí)現(xiàn)
- 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);
- }
在實(shí)現(xiàn)配置文件支持的代碼中,有以下幾個(gè)要點(diǎn):
1、STAF API 的初始化需要注冊(cè) STAFHandle 對(duì)象。而且該注冊(cè)只能執(zhí)行一次。我們根據(jù)全局變量 stafHandle 的值來決定是否注冊(cè)該對(duì)象。
2、JDK的日志框架有一個(gè)全局的 singleton 管理類 STAFManager,該類用于管理日志類,并提供了讀取日志配置文件的成員函數(shù) getProperty 。在上述的代碼中,我們通過 STAFManager.getProperty 方法,從日志配置文件中讀取 STAFHandler 對(duì)象所設(shè)置的 Formatter 類名,然后通過反射生成一個(gè)新的 Formatter 對(duì)象,設(shè)置到 Handler 對(duì)象中。
3、對(duì)于日志級(jí)別也是通過 STAFManager.getProperty 方法。需要注意的是由于我們的日志級(jí)別是自定義的級(jí)別,所以 Level 對(duì)象是由我們自定義的 Level 類 STAFLevel 來生成的。
4、我們也能定義自己需要的屬性。比如清單 9 中我們定義了一個(gè) .name 屬性,用來存儲(chǔ) STAF 日志名稱,通過 getProperty 函數(shù)從配置文件中讀取 .name 屬性。
JDK日志框架之實(shí)例結(jié)合STAF的情況就介紹到這里,那么關(guān)于JDK日志框架之實(shí)例結(jié)合STAF的更多情況,我們要在學(xué)習(xí)過程中加以鞏固提高。
【編輯推薦】