使用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