码迷,mamicode.com
首页 > Web开发 > 详细

Apache log4net™ 概述

时间:2015-06-21 14:25:09      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:

原文地址

Overview


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.0
  • Microsoft .NET Framework 1.1
  • Microsoft .NET Framework 2.0
  • Microsoft .NET Framework 3.5
  • Microsoft .NET Framework 4.0
  • Microsoft .NET Framework 3.5 Client Profile
  • Microsoft .NET Framework 4.0 Client Profile
  • Microsoft .NET Compact Framework 1.0
  • Microsoft .NET Compact Framework 2.0
  • Mono 1.0
  • Mono 2.0
  • Microsoft Shared Source CLI 1.0
  • CLI 1.0 Compatible

不是所有的框架都是一样的,而且有些功能已经被排除。更多信息可查看 Framework Support

日志(Loggers)和追加器(Appenders)


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

日志层次(Logger hierarchy)


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

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

命名层次

A logger is said to be an ancestor of another logger if its name followed by a dot is a prefix of the descendant logger name. A logger is said to be a parent of a child logger if there are no ancestors between itself and the descendant logger.

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

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

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

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

  1. 它总是存在
  2. 它不能通过名称检索
  3. 它总是分配一个等级

使用 log4net.LogManager 类的静态方法来检索日志器。GetLogger 方法采取需要记录日志的类作为参数。如下所示:

namespace log4net
{
    public class LogManager
    {
        public static ILog GetLogger(string name);
        public static ILog GetLogger(Type type);
    }
}

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

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

namespace log4net
{
    public interface ILog
    {
        /* Test if a level is enabled for logging */
        bool IsDebugEnabled { get; }
        bool IsInfoEnabled { get; }
        bool IsWarnEnabled { get; }
        bool IsErrorEnabled { get; }
        bool IsFatalEnabled { get; }
        
        /* Log a message object */
        void Debug(object message);
        void Info(object message);
        void Warn(object message);
        void Error(object message);
        void Fatal(object message);
        
        /* Log a message object and exception */
        void Debug(object message, Exception t);
        void Info(object message, Exception t);
        void Warn(object message, Exception t);
        void Error(object message, Exception t);
        void Fatal(object message, Exception t);
        
        /* Log a message string using the System.String.Format syntax */
        void DebugFormat(string format, params object[] args);
        void InfoFormat(string format, params object[] args);
        void WarnFormat(string format, params object[] args);
        void ErrorFormat(string format, params object[] args);
        void FatalFormat(string format, params object[] args);
        
        /* Log a message string using the System.String.Format syntax */
        void DebugFormat(IFormatProvider provider, string format, params object[] args);
        void InfoFormat(IFormatProvider provider, string format, params object[] args);
        void WarnFormat(IFormatProvider provider, string format, params object[] args);
        void ErrorFormat(IFormatProvider provider, string format, params object[] args);
        void FatalFormat(IFormatProvider provider, string format, params object[] args);
    }
}

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

  • ALL
  • DEBUG
  • INFO
  • WARN
  • ERROR
  • FATAL
  • OFF

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

等级层次(Level Inheritance)

The inherited level for a given logger X, is equal to the first non-null level in the logger hierarchy, starting at X and proceeding upwards in the hierarchy towards the root logger.

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

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

Logger name

Assigned level

Inherited level

root

Proot

Proot

X

none

Proot

X.Y

none

Proot

X.Y.Z

none

Proot

上表的例子,只有 root logger 被分配了一个等级,其他三个 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 level L in a logger with (either assigned or inherited, whichever is appropriate) level K, is enabled if L >= 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 logger X will go to all the appenders in X and its ancestors. This is the meaning of the term "appender additivity".

However, if an ancestor of logger X, say Y, has the additivity flag set to false, then X‘s output will be directed to all the appenders in X and it‘s ancestors up to and including Y but not the appenders in any of the ancestors of Y.

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 to root.
x
A-x1, A-x2 true A1, A-x1, A-x2 Appenders of "x" and root.
x.y none true
A1, A-x1, A-x2
Appenders of "x" and root.
x.y.z A-xyz1
true
A1, A-x1, A-x2, A-xyz1 Appenders in "x.y.z", "x" and root.
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)


More often than not, users wish to customize not only the output destination but also the output format. This is accomplished by associating a layout with an appender. The layout is responsible for formatting the logging request according to the user‘s wishes, whereas an appender takes care of sending the formatted output to its destination. The PatternLayout, part of the standard log4net distribution, lets the user specify the output format according to conversion patterns similar to the C language printf function.

For example, the PatternLayout with the conversion pattern "%timestamp [%thread] %-5level %logger - %message%newline" will output something akin to:

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

The first field is the number of milliseconds elapsed since the start of the program. The second field is the thread making the log request. The third field is the level of the log statement. The fourth field is the name of the logger associated with the log request. The text after the ‘-‘ is the message of the statement.

The following layouts are included in the log4net package:

类型 描述
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)


Just as importantly, log4net will render the content of the log message according to user specified criteria. For example, if you frequently need to log Oranges, an object type used in your current project, then you can register an OrangeRenderer that will be invoked whenever an orange needs to be logged.

Object rendering follows the class hierarchy. For example, assuming oranges are fruits, if you register an FruitRenderer, all fruits including oranges will be rendered by the FruitRenderer, unless of course you registered an orange specific OrangeRenderer.

Object renderers have to implement the log4net.ObjectRenderer.IObjectRenderer interface.

Please note that ObjectRenderers are not used by the DebugFormat, InfoFormat, WarnFormat, ErrorFormat and FatalFormat methods.

Apache log4net™ 概述

标签:

原文地址:http://www.cnblogs.com/liuning8023/p/4591910.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!