使用LogKit進行日誌操作
1. 概述
不論什麽一個系統中,日誌都是必不可少的。如今Apache提供了兩套日誌工具,一個就是Log4j。還有一個是本文要給出樣例的LogKit。
Log4j和LogKit有非常多類似的地方。比方,Log4j提供5級日誌:DEBUG、INFO、WARN、ERROR和FATAL。LogKit也提供5級日誌:DEBUG、INFO、WARN、ERROR和FATAL-ERROR。除了級別5的命名不一樣,實質是一樣的。
LogKit相同提供文件夾功能,而對日誌格式的控制,在Log4j中是使用Layout。而在LogKit中使用的是Formatter。對於日誌輸出,Log4j使用的是Appender,LogKit則使用了更為直接的名字:Target。
這個文章當然不是用來對照LogKit和Log4j的不同的。而是想說明。為什麽在有了Log4j這種日誌工具以後,還須要使用LogKit。
使用LogKit的原因是:Context和LogTargets。
使用Log4j的時候,日誌的內容僅僅能是一句話,而使用LogKit,你能夠記錄非常多項內容,甚至能夠各項內容記錄到相應的數據庫字段中。
假設使用Log4j存儲日誌到不同的存儲介質。如數據庫,須要使用Appender。而LogKit已經能夠支持多種存儲目標。
以下的程序將用一個產品檢測線(ProductChecker)作為示範。
2. 一個樣例
產品檢測線是用來檢查產品是否合格使用的,要求記錄產品編號、產品是否通過檢測、簡要說明三個項目。
而LogKit會把級別、時間和信息也記錄下作為參考。
在免費的Mysql數據庫上建立logkitexample表的sql語句:
create table logkigexample
(
logmessage varcher(1000),
logpriority varchar(20),
logtime datetime,
productnumber varchar(100),
productpass varchar(10),
productexplain varchar(100)
)
在這個產品檢測線中。產品是否通過分三種情況:ok、soso和bad。
當中,ok代表產品質量好,soso代表質量一般。bad代表沒有通過檢查,須要又一次制造。
代碼例如以下:
package logkitexample;
import java.lang.*;
import java.util.*;
import org.apache.log.*;
import org.apache.log.output.db.*;
public class ProductChecker
{
static private org.apache.log.Logger LoggerProductChecker;
public static void main(String[] argv)
{
ProductChecker _p = new ProductChecker();
_p.initLogKit();
//模擬產品檢查的結果
Random _checkrandom = new Random();
int _checkresult;
for (int i = 1; i <= 20; i++)
{
_checkresult = (int)(_checkrandom.nextFloat() * 3);
switch (_checkresult)
{
case 0:
ContextMap.bind(_p.getProductCheckerMap("no." + String.valueOf(i), "ok", "ok"));
LoggerProductChecker.info("ProductChecker Pass");
break;
case 1:
ContextMap.bind(_p.getProductCheckerMap("no." + String.valueOf(i), "soso", "check again"));
LoggerProductChecker.warn("ProductChecker No Good");
break;
case 2:
ContextMap.bind(_p.getProductCheckerMap("no." + String.valueOf(i), "bad", "redo"));
LoggerProductChecker.error("ProductChecker Bad");
break;
}
}
}
private void initLogKit()
{
try
{
//登記使用的數據源
Class.forName("org.gjt.mm.mysql.Driver");
DefaultDataSource _dataSource = new DefaultDataSource("jdbc:mysql://localhost/logkitexample" , "root", "");
//登記相應的列映射關系
ColumnInfo[] _columeProductChecker = {
new ColumnInfo( "logmessage", ColumnType.MESSAGE, null ),
new ColumnInfo( "logpriority", ColumnType.PRIORITY, null ),
new ColumnInfo( "logtime", ColumnType.TIME, null ),
new ColumnInfo( "productnumber", ColumnType.CONTEXT,"productnumber" ),
new ColumnInfo( "productpass", ColumnType.CONTEXT,"productpass" ),
new ColumnInfo( "productexplain", ColumnType.CONTEXT,"productexplain" ),
};
//登記JDBCTarget
DefaultJDBCTarget _targetProductChecker =
new DefaultJDBCTarget(_dataSource, "logkitexample", _columeProductChecker);
//登記日誌的層次
org.apache.log.Hierarchy _hierarchy = new org.apache.log.Hierarchy();
LoggerProductChecker = _hierarchy.getLoggerFor("logkitexample");
//設置ProductChecker的日誌記錄器使用的Target
LoggerProductChecker.setLogTargets(
new LogTarget[] {_targetProductChecker});
//設置日誌級別為DEBUG
LoggerProductChecker.setPriority(org.apache.log.Priority.DEBUG);
}
catch (Exception e)
{
System.out.println("LogKitinit error");
}
}
/** 獲得產品日誌的ContextMap */
private org.apache.log.ContextMap getProductCheckerMap(String _ProductNumber, String _ProductPass, String _ProductExplain)
{
org.apache.log.ContextMap _cm = new org.apache.log.ContextMap();
_cm.set("productnumber", _ProductNumber);
_cm.set("productpass", _ProductPass);
_cm.set("productexplain", _ProductExplain);
return (_cm);
}
}
3. LogKit的存儲目標
LogKit支持多種不同的日誌存儲目標,稱為LogTargets。包含有文件、數據庫、IRC頻道、JMS,甚至是隨意的Sockets定義。
LogKit中一個日誌記錄器能夠相應不同的LogTargets,使用Filter能夠依據不同的日誌級別記錄到不同的LogTargets中。比方日誌都是存放早數據庫的,可是FATAL_ERROR要存放在文本文件,由於這種情況下。非常可能數據庫都是不可用的。
LogKit還支持異步的LogTargets,適用於不能實時響應的LogTargets,如郵件系統等。
4. 參考資料
LogKit項目主頁:http://jakarta.apache.org/avalon/logkit/index.html
使用LogKit進行日誌操作