Let's Log 4 Net
背景简介:
基本概念:
关联与继承:
logger继承示例:
root --- akumaslab.a --- akumaslab.a.b
| /--- akumaslab.a.c
/- anotherLogger
日志级别:
Log4J中每一个logger都有自己的日志级别,默认的级别及优先级为:
Fatal>Error>Warn>Info>Debug
同时每个logger都提供这5个级别的日志写入方法,当应用输入日志信息时,logger会根据自己的级别判断是否将日志发送给appender。示例如下,我们假设log的级别为Warn:
//Error >= log的级别(warn),该日志发给appender处理
log.Error("error message");
// Info < log级别(Warn),该日志被忽略
log.Info("info message:);
除了级别规则之外,logger还默认将有效的日志信息送往自己的父节点处(可设置参数禁止上送)。比如,当前应用中有4个节点"root" "akumaslab.a" "akumaslab.a.b" "another"(如前图),此时如果"akumaslab.a.b"收到一个有效的日志,则该条日志在"root"、"akumaslab.a"两个logger上也会被记录。
实际用例:
//Debug信息
log.Debug("debug message");
// Info,普通信息
log.Info("info message:);
发布程序时,如果要屏蔽掉应用中的全部debug日志,只要设置根logger的级别为Info,则所有Logger都不再打印Debug级别的日志(也可以调整config文件,而不用修改程序)。相反的,在debug时,只要设置为Debug就可打印全部debug日志。
root = Logservice.getRootLogger();
//设置Info级别,则应用中不再打印debug日志
root.Level = LogLevel.Info;
用例2:
当一个应用中有多个模块,或者不同功能的线程同时工作时,如果将日志都打印到一个日志里,由于各模块的日志顺序交错,很难能分辨出单独模块具体的运行流程,而如果为各模块都各打印一个独立日志,则检查应用整体运行状况时,就会很难分析。利用Log4J,我们可以同时实现两种日志,而且不需要增加额外的日志打印指令。
假设我们有两个模块A与B,需要将两个模块的日志分别保存在a.log和b.log,而且还要为应用程序生成一个完整的main.log。首先我们创建两个logger LoggerA、LoggerB,如下:
root ------ LoggerA
|--- LoggerB
然后为a.log b.log main.log生成三个appender,分别绑定到3个Logger上,则关联关系如下:
root(AppenderMain) ------- LoggerA (AppenderA)
|--- LoggerB(AppenderB)
由于默认情况下,logger会将日志信息送到父节点,所以两个模块日志的appender打印情况如下:
模块A:appenderA appenderMain
模块B:appenderB appenderMain
通过这种方式,我们既在a.log b.log中为两个模块保存了各自的日志,又将合并的日志写入到了main.log。
用例3:
由于一个logger可关联多个appender,因此可以使日志同时输出到多个目标设备,包括文件、屏幕、控制台等,这个是log4J的基本功能,以下是我的部分实现代码:
//一个泛型的appender列表
List<ILogAppender> appenderList = new List<ILogAppender>();
...
public void log(LoggerLevel msgLevel, object msg)
{
if (msgLevel>= this.level)
{
...
//日志有效,遍历appender进行输出
foreach (ILogAppender appender in appenderList)
{
appender.wrtieLog(Convert.ToString(level) + ":" + msg);
}