分享
 
 
 

Apache log4net™ 手册——介绍【翻译】

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: |||超大  

原文地址

本文内容概述框架日志(Loggers)和追加器(Appenders)日志层次(Logger hierarchy)追加器(Appenders)筛选(Filters)布局(Layouts)对象渲染(Object Renderers)最近公司有个项目,需要解析三种二进制流,我写其中的两种,最后用一个 Windos 服务来实时处理。之前的项目都只是简单记下,主要是数据库层日志,但针对这个项目,貌似需要点复杂的日志系统,在软件各个层次上都需要日志,否则,出毛病的话,还真看不出来问题在哪,而且调试 Windows 服务也很麻烦~于是,用了 log4net。

本文只是概述,接下来较具体说明 log4net。

Apache log4net™ 手册——介绍【翻译】概述log4net 框架是基于 Apache log4j™,关于 log4j 的更多信息查看 http://logging.apache.org/log4j/。

本文介绍 log4net API,其独特的功能和设计原理。log4net 是一个基于很多作者的工作的开源项目。log4net 允许开发人员用任意粒度控制日志语句的输出。log4net 使用外部配置文件在运行时完全可配置。

几乎每个大型应用程序都包含它自己的日志,或追踪 API。向代码中插入日志语句对于调试程序是一个很低级的方法。这也是唯一一个方法,因为调试器不会总是可靠或可用的。通常是在大规模多线程应用程序和分布式应用程序的情况。

应用程序一旦被部署,使用开发或调试工具将不是不可能的。一个管理员可以使用有效的日志系统来诊断和修复很多配置问题。

经验说明,日志是一个开发周期中很重要的组件。它提供了很多优势。如提供关于应用程序执行的准确的上下文环境(context)。日志一旦插入到代码,日志输出的产生不需要人工干预。此外,日志输出可以保存在永久介质,以在稍后进行研究。除了用在开发周期中,丰富的日志记录包也可以被看作一个审计工具。

日志确实也有它的缺点。它可以减慢应用程序。如果太详细,它可能会导致滚动失败。为缓解这些问题,log4net 被设计成可靠的,快速的和可扩展的。由于日志很少是一个应用程序的主要焦点,因此,log4net API 致力于易于理解和使用。

框架(Frameworks)Log4net 对很多框架可用。如下所示:

Microsoft® .NET Framework 1.0Microsoft .NET Framework 1.1Microsoft .NET Framework 2.0Microsoft .NET Framework 3.5Microsoft .NET Framework 4.0Microsoft .NET Framework 3.5 ClientPRofileMicrosoft .NET Framework 4.0 Client ProfileMicrosoft .NET Compact Framework 1.0Microsoft .NET Compact Framework 2.0Mono 1.0Mono 2.0Microsoft Shared Source CLI 1.0CLI 1.0 Compatible不是所有的框架都是一样的,而且有些功能已经被排除。更多信息可查看 Framework Support。

日志(Loggers)和追加器(Appenders)Log4net 有三个主要组件:loggers,appenders 和 layouts。这三个组件一起工作使得开发者能够根据信息类型和等级(Level)记录信息,以及在运行时控制信息的格式化和信息的写入位置(如控制台,文件,内存,数据库等)。过滤器(filter)帮助这些组件,控制追加器(appender)的行为和把对象转换成字符串的对象渲染。

日志层次(Logger hierarchy)普通的System.Console.WriteLine任何日志记录 API 的第一个也是最重要的优点在于,它可以禁用某些日志语句,而让其他人轻松打印。这个功能假定,日志空间,也就是,所有可能的日志语句的空间,可以根据开发者选择的标准被分类。

日志器(logger)被命名为实体。日志器名称是大小写敏感的,它们遵循以下层次的命名规则:

命名层次

如果后面跟一个点的名字是它后代(descendant )日志器名称的一个前缀,那么,一个日志器被当做是另一个日志器的祖先(ancestor)。如果自身和后代日志器之间没有祖先,那么,一个日志器被当做是一个子记录器的父母。

该层次的工作机制非常类似 .NET 中的命名空间(namespace)和类层次结构(class hierarchy)。我们将会看到,这很方便。

例如,名为“Foo.Bar”的日志器是一个名为“Foo.Bar.Baz”日志器的父。类似的,“System”是“System.Text”的父,以及“System.Text.StringBuilder”的祖先。这种命名方式对很多开发者来说很熟悉。

也就是说,应用程序中每个类,都可能存在一个日志/记录器~那么,接下来,在类的继承层次结构中,如果一个类继承另一个类,那么它们自己的日志器,也会存在一个继承关系。

root日志器位于日志器层次的最顶部。有三个有点:

它总是存在它不能通过名称检索它总是分配一个等级使用log4net.LogManager类的静态方法来检索日志器。GetLogger方法采取需要记录日志的类作为参数。如下所示:

namespacelog4net

{

publicclassLogManager

{

publicstaticILog GetLogger(stringname);

publicstaticILog GetLogger(Type type);

}

}

GetLogger方法具有一个参数,或是字符串,或是 Type 对象。log4net 用利用反射获取需要写日志的对象。

GetLogger方法都返回一个ILog接口。代表一个传递给开发者的Logger。ILog接口定义如下:

namespacelog4net

{

publicinterfaceILog

{

/* Test if a level is enabled for logging */

boolIsDebugEnabled { get; }

boolIsInfoEnabled { get; }

boolIsWarnEnabled { get; }

boolIsErrorEnabled { get; }

boolIsFatalEnabled { get; }

/* Log a message object */

voidDebug(objectmessage);

voidInfo(objectmessage);

voidWarn(objectmessage);

voidError(objectmessage);

voidFatal(objectmessage);

/* Log a message object and exception */

voidDebug(objectmessage, Exception t);

voidInfo(objectmessage, Exception t);

voidWarn(objectmessage, Exception t);

voidError(objectmessage, Exception t);

voidFatal(objectmessage, Exception t);

/* Log a message string using the System.String.Format syntax */

voidDebugFormat(stringformat,paramsobject[] args);

voidInfoFormat(stringformat,paramsobject[] args);

voidWarnFormat(stringformat,paramsobject[] args);

voidErrorFormat(stringformat,paramsobject[] args);

voidFatalFormat(stringformat,paramsobject[] args);

/* Log a message string using the System.String.Format syntax */

voidDebugFormat(IFormatProvider provider,stringformat,paramsobject[] args);

voidInfoFormat(IFormatProvider provider,stringformat,paramsobject[] args);

voidWarnFormat(IFormatProvider provider,stringformat,paramsobject[] args);

voidErrorFormat(IFormatProvider provider,stringformat,paramsobject[] args);

voidFatalFormat(IFormatProvider provider,stringformat,paramsobject[] args);

}

}

Loggers 会分配一个等级。等级是log4net.Core.Level类的一个实例。下面是按优先级递增的定义的等级:

ALLDEBUGINFOWARNERRORFATALOFF如果一个给定的记录器没有被分配一个级别,那么,它将继承它最近的、并已分配值的祖先。更正式地说:

等级层次(Level Inheritance)

Theinherited levelfor a given loggerX, is equal to the first non-null level in the logger hierarchy, starting atXand proceeding upwards in the hierarchy towards therootlogger.

为了确保所有日志器最终都继承一个等级,root日志器总是具有一个已分配的等级。root日志器的默认值是DEBUG。

根据上面规则,下面四个表是各种分配的值和继承的值。

Logger name

Assigned level

Inherited level

root

Proot

Proot

X

none

Proot

X.Y

none

Proot

X.Y.Z

none

Proot

上表的例子,只有rootlogger 被分配了一个等级,其他三个 X、X.Y 和 X.Y.Z 的继承值都是 Proot。

Logger name

Assigned level

Inherited level

root

Proot

Proot

X

Px

Px

X.Y

Pxy

Pxy

X.Y.Z

Pxyz

Pxyz

上表的例子,所有的日志器都分配了一个等级。这样,不需要继承值。

Logger name

Assigned level

Inherited level

root

Proot

Proot

X

Px

Px

X.Y

none

Px

X.Y.Z

Pxyz

Pxyz

上表的例子,日志器root、X 和 X.Y.Z 被分别分配等级值 Proot、Px 和 Pxyz。日志器 X.Y 会从它的父 X 继承等级值。

Logger name

Assigned level

Inherited level

root

Proot

Proot

X

Px

Px

X.Y

none

Px

X.Y.Z

none

Px

上表的例子,日志器root和 X 等级值分别分配为 Proot 和 Px。日志器 X.Y 和 X.Y.Z 会从离它最近的,并已分配值的父来继承。

日志请求是通过调用一个日志实例的打印方法(log4net.ILog)完成。这些打印方法是Debug、Info、Warn、Error和Fatal。

根据定义,打印方法决定日志请求的等级。例如,如果 log 是一个日志器的实例,那么,语句 log.Info("..") 是等级为 INFO 的日志请求。

如果它的等级大于等于它日志器的等级,那么日志请求就被认为已启用。否则,请求被认为禁用。没有分配等级的日志器将从层次上继承。规则如下:

Basic Selection Rule

A log request of levelLin a logger with (either assigned or inherited, whichever is appropriate) levelK, is enabled ifL >= K.

该规则是 log4net 的核心。它假设等级是有序的。对于标准等级,具有 DEBUG < INFO < WARN < ERROR < FATAL。

用相同的参数调用 log4net.LogManager.GetLogger 方法总是返回引用一个完全相同 logger 对象。如下所示:

ILog x = LogManager.GetLogger("wombat");

ILog y = LogManager.GetLogger("wombat");

x 和 y 完全引用一个相同的 logger 对象。

因此,有可能配置一个日志器,然后在代码中的任何地方都可以检索到相同的实例。在生物学上,父母总是先于它们的孩子,而 log4net 日志器可以以任何顺序创建和配置。具体地说,一个“父”日志器将发现和链接到它的后代,即使它在它的后代之后才实例化。

log4net 环境的配置通常是在应用程序初始化。优先的方法是读取一个配置文件。

追加器(Appenders)基于日志器选择启用或禁用日志请求的能力仅仅是其一部分。log4net 允许日志请求打印到多个目的地。按 log4net 的定义,一个输出目的地被称为附加器(appender)。追加器必须实现 log4net.Appenders.IAppender 接口。

下面是 log4net 定义的追加器:

类型

描述

log4net.Appender.AdoNetAppender

把日志事件写到数据库,通过语句或存储过程。

log4net.Appender.AnsiColorTerminalAppender

把按颜色高亮标记的日志事件写到 ANSI 终端窗口。

log4net.Appender.aspNetTraceAppender

把日志事件写到 ASP 跟踪环境。之后,就可以在 ASP 页面底部或跟踪页面呈现。

log4net.Appender.BufferingForwardingAppender

在把日志转发给子追加器之前,缓冲区记录事件。

log4net.Appender.ColoredConsoleAppender

把日志事件写到应用程序控制台。可以写到标准输出流或 error 流。可以为每个等级定义文本和颜色。

log4net.Appender.ConsoleAppender

把日志事件写到应用程序控制台。可以写到标准输出流或 error 流。

log4net.Appender.DebugAppender

把日志事件写到 .NET 系统。

log4net.Appender.EventLogAppender

把日志事件写到 Windows Event Log。

log4net.Appender.FileAppender

把日志事件写到文件系统的一个文件。

log4net.Appender.ForwardingAppender

把日志事件转发给子追加器。

log4net.Appender.LocalSyslogAppender

把日志事件写到 local syslog service(仅针对 Unix)。

log4net.Appender.MemoryAppender

把日志事件存储在内存缓存。

log4net.Appender.NetSendAppender

把日志事件写到 Windows Messenger service。这些信息显示在一个用户终端的对话框。

log4net.Appender.OutputDebugStringAppender

把日志事件写到调试器。如果应用程序没有调试器,那么系统调试器会显示字符串。如果应用程序没有调试器,并且系统调试器不活跃,那么消息会被忽略。

log4net.Appender.RemoteSyslogAppender

把日志事件通过 UDP 网络写到一个 remoting syslog service。

log4net.Appender.RemotingAppender

把日志事件通过 .NET remoting 写到一个 remoting sink。

log4net.Appender.RollingFileAppender

把日志事件写到文件系统中的一个文件。RollingFileAppender 可以被配置,基于日期或大小约束写入到多个文件。

log4net.Appender.SmtpAppender

把日志事件发送到一个 email 地址。

log4net.Appender.SmtpPickupDirAppender

把日志事件写成 SMTP 消息到一个文件拾取目录。这些文件可以被 SMTP 代理读取或发送,如 IIS SMTP 代理。

log4net.Appender.TelnetAppender

客户端通过 Telnet 连接,来接受日志事件。

log4net.Appender.TraceAppender

把日志事件写到 .NET trace system。

log4net.Appender.UdpAppender

使用 UdpClient 把日志事件作为无连接 UDP 数据发送到一个远程主机或多播组。

日志器可以采用多个追加器。

对于给定的日志器,每个启用日志请求都将被转发到所有追加器,以及层次结构中更高的追加器。也就是说,追加器是从日志器层次结构中相加继承的(inherited additively)。例如,如果一个 console appender 被添加到 root 日志器,那么,所有启用日志请求都将至少打印到控制台上。如果再添加一个文件追加器,那么,对于 X,对 X 和 X 的子,启用日志请求将打印到一个文件和控制台上。覆盖此默认行为也是可以的,通过在日志器中设置相加标识为 false,追加器积累将不再相加。

管理附加器相加(additivity )的规则如下。

Appender Additivity

The output of a log statement of loggerXwill go to all the appenders inXand its ancestors. This is the meaning of the term "appender additivity".

However, if an ancestor of loggerX, sayY, has the additivity flag set to false, thenX's output will be directed to all the appenders inXand it's ancestors up to and includingYbut not the appenders in any of the ancestors ofY.

Loggers have their additivity flag set to true by default.

下表列出一个例子:

Logger Name

Added Appenders

Additivity Flag

Output Targets

Comment

root

A1

not applicable

A1

There is no default appender attached toroot.

x

A-x1, A-x2

true

A1, A-x1, A-x2

Appenders of "x" androot.

x.y

none

true

A1, A-x1, A-x2

Appenders of "x" androot.

x.y.z

A-xyz1

true

A1, A-x1, A-x2, A-xyz1

Appenders in "x.y.z", "x" androot.

security

A-sec

false

A-sec

No appender accumulation since the additivity flag is set to false.

security.access

none

true

A-sec

Only appenders of "security" because the additivity flag in "security" is set to false.

筛选(Filters)

追加器可以筛选被传递给它们的事件。在配置中指定过滤器,允许更好地控制通过不同的追加器记录的事件。

控制的最简单形式是在追加器中指定阈值。

更复杂的和自定义事件过滤可以使用每个追加器中定义的过滤器链来完成。过滤器必须实现 log4net.Filter.IFilter 接口。

下表列出 log4net 中定义的过滤器:

类型

描述

log4net.Filter.DenyAllFilter

丢弃所有日志事件。

log4net.Filter.LevelMatchFilter

准确匹配事件等级。

log4net.Filter.LevelRangeFilter

匹配一个范围的等级。

log4net.Filter.LoggerMatchFilter

匹配一个日志器名字的开始。

log4net.Filter.PropertyFilter

匹配指定属性名称的子字符串。

log4net.Filter.StringMatchFilter

匹配事件消息的子字符串。

过滤器可以被配置为根据匹配接受或拒绝事件。

布局(Layouts)很多时候,用户不仅希望自定义输出目的地,还要定义输出格式。这是通过与追加器相关的布局(layout)来实现的。布局负责根据用户意愿格式化日志请求,而一个追加器负责发送已格式化的输出到目的地。 PatternLayout,是标准的 log4net 的一部分,让用户根据转换模式指定数据格式,类似于 C 语言 printf。

例如,带转换模式的 PatternLayout "%timestamp [%thread] %-5level %logger - %message%newline" 将会输出:

176 [main] INFO Com.Foo.Bar - Located nearest gas station.

第一个域是流逝毫秒时间;第二个域是日志请求的线程;第三个域日志语句等级,如 INFO、WARN、ERROR 等;第四个域是与日志请求相关的日志器的名称。“-”后面的文本是具体消息。

下表是 log4net 中定义的布局:

类型

描述

log4net.Layout.ExceptionLayout

Renders the exception text from the logging event.

log4net.Layout.PatternLayout

Formats the logging event according to a flexible set of formatting flags.

log4net.Layout.RawTimeStampLayout

Extracts the timestamp from the logging event.

log4net.Layout.RawUtcTimeStampLayout

Extracts the timestamp from the logging event in Universal Time.

log4net.Layout.SimpleLayout

Formats the logging event very simply: [level] - [message]

log4net.Layout.xmlLayout

Formats the logging event as an XML element.

log4net.Layout.XmlLayoutSchemaLog4j

Formats the logging event as an XML element that complies with the log4j event dtd.

对象渲染(Object Renderers)同样重要的是,log4net 会根据用户指定的标准呈现日志消息的内容。例如,如果你经常需要记录 Oranges,它是你项目中使用的一个对象类型,那么,你可以注册一个 OrangeRenderer,这样无论何时需要记录 Orange 就可以调用。

对象渲染按照类的层次结构。例如,假设橙子是水果,如果你注册一个 FruitRenderer,所有的水果,包括橙子,将按 FruitRenderer 渲染,除非你已经注册一个橙子的 OrangeRenderer。

对象渲染器必须实现log4net.ObjectRenderer.IObjectRenderer接口。

注意,DebugFormat、InfoFormat、WarnFormat、ErrorFormat和FatalFormat方法不使用ObjectRenderers。

 

Apache log4net™ 手册——介绍【翻译】

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有