Apache log4net™ 手册 - 简介

Apache log4net™ 手册 - 简介

这篇文档是基于 Ceki Gülcü 对 log4j 项目的简短介绍.

log4net 框架是基于 apache log4j™ 项目的,请参阅 http://logging.apache.org/log4j/ 在log4j 项目上获取更多信息。log4net框架、源代码、二进制文件、文档、示例和相关材料按 Apache 2.0 协议发布, Version 2.0,该发行版已包含在 LICENSE.txt文件中。

本文档介绍 log4net API 、其独特的特性和设计原理。Log4net 是一个基于许多作者工作的开源项目。它允许开发人员以任意精细度控制输出哪些日志语句。它可以在运行时使用外部配置文件进行完全配置。

几乎每个大型应用程序都有自己的日志记录或跟踪API。在代码中插入日志语句是调试它的一种低技术方法。这也可能是唯一的方法,因为调试器并不总是可用的或适用的。对于多线程应用程序和整个分布式应用程序来说,通常都是这种情况。

一旦部署了应用程序,就可能无法利用开发和调试工具。管理员可以使用有效的日志记录系统来诊断和修复许多配置问题.

经验表明,记录器是开发周期的一个重要组成部分。它提供了几个优点。它提供了精确的语境关于应用程序的执行。一旦插入到代码中,日志输出的生成就不需要人工干预。此外,日志输出可以保存在持久性介质中,供以后研究。除了在开发周期中使用它之外,还可以将足够丰富的日志记录包视为审核工具。

日志记录确实有其缺点。它会减慢应用程序的速度。如果太冗长还会导致记录无法看清。为了解决这些问题,log4net 被设计成可靠的、快速的和可扩展的。由于日志一般不是应用程序的主要关注点,所以 log4netAPI 力求简单易懂和易于使用。

框架

略, 请查看原文

logger 和 appenders

Log4net 有三个主要组件:logger, appenders 和 layouts。这三种类型的组件协同工作,使开发人员能够根据消息类型和级别记录消息,并在运行时控制这些消息的格式化方式和报告位置。这些组件由过滤器(filters)和对象渲染器(object renderers)协助工作,过滤器控制了appender 的操作和将对象转换为字符串的对象渲染器的行为。

记录器层次

The first and foremost advantage of any logging API over plain System.Console.WriteLine resides in its ability to disable certain log statements while allowing others to print unhindered. This capability assumes that the logging space, that is, the space of all possible logging statements, is categorized according to some developer-chosen criteria.

Loggers are named entities. Logger names are case-sensitive and they follow the following hierarchical naming rule:

任何一个记录器API相对于System.Console.WriteLink()方法的的首要优点是于它能够禁用某些日志语句,同时允许其它代码无碍地打印。此功能假定日志空间,即所有可能的日志语句的空间,都是根据某些开发人员选择的标准进行分类的。

Loggers 被命名为实体。Logger 名称区分大小写,它们遵循以下分层命名规则:

命名层次

一个记录器A可以说是另一个记录器B的子级: 如果A的名字是B.A。
一个记录器A可以说是另一个记录器B的父级: 如果B的名子是A.B。
这个层次结构与.NET中的命名空间和类层次结构的工作方式非常相似,这非常方便,我们很快就会看到。

例如,名为“Foo.Bar”是名为“Foo.Bar.Baz”的父级。同样,“System”是”System.Text”父级, “System.Text.StringBuilder”是”System.Text”的子级。大多数开发人员应该熟悉这个命名方案。

root 记录器是驻留在记录器层次结构的顶级。与其它记录器相比, 它在以下三方面都是例外:
- 它总是存在的
- 不能按名称检索
- 它总是有一个指定的级别
记录器在 log4net.LogManager 类中使用静态方法实现。GetLogger()方法将期望的记录器的名称作为参数。在下面列出:

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

GetLogger()的类型参数使用完全限定类型名称作为要检索的记录器的名称。
这些GetLogger()方法返回 ILOG 类型的接口。这个Logger回传给开发者的形式。ILOG接口定义如下:

namespace log4net
{
    public interface ILog
    {
        /* 测试一个记录器的调试等级是否有效 */
        bool IsDebugEnabled { get; }
        bool IsInfoEnabled { get; }
        bool IsWarnEnabled { get; }
        bool IsErrorEnabled { get; }
        bool IsFatalEnabled { get; }

        /* 记录一个消息,参数: object */
        void Debug(object message);
        void Info(object message);
        void Warn(object message);
        void Error(object message);
        void Fatal(object 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);

        /* 使用 System.String.Format 表达式记录消息 */
        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);

        /* 使用 System.String.Format 表达式记录消息 */
        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.

To ensure that all loggers can eventually inherit a level, the root logger always has an assigned level. The default value for the root logger is DEBUG.

Below are four tables with various assigned level values and the resulting inherited levels according to the above rule.

等级遗传

对于给定的记录器X遗传等级,等于记录器层次结构中, 从X开始并向root logger方向向上的第一个非空等级.
请确信所有记录器最终都可以继承到一个级别,根记录器(root logger)总是有一个指定的级别。根记录器的默认级别为DEBUG.
下面是四个表,它们具有不同的赋值级别值,以及根据上述规则得到的继承级别。(已经讲得很清楚了, 表内容略, 请查看原文 https://logging.apache.org/log4net/release/manual/introduction.html)

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.

This rule is at the heart of log4net. It assumes that levels are ordered. For the standard levels, we have DEBUG < INFO < WARN < ERROR < FATAL.

Calling the log4net.LogManager.GetLogger method with the same name will always return a reference to the exact same logger object.

For example, in:

基本选择规则

一个日志的等级是K 对于记录请求级别是L的情况, 如果L>=K, 则日志记录有效. 这个规则是 log4net 的核心。它假定级别是有序的。标准的等级是 DEBUG < INFO < WARN < ERROR < FATAL .
使用相同的名子作为参数调用log4net.LogManager.GetLogger方法, 将始终返回对完全相同的记录器对象的引用。
例如,下面两行代码返回的是对同一个记录器引用:

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

因此,无需通过传递引用的方法, 就可以通过先配置记录器然后在代码中的任何其他地方检索相同的实例。在生物亲子关系的基本矛盾中, 父母总是先于子女,因此log4net记录器可以按任何顺序创建和配置。特别是“父”记录器即使在它们后面实例化,也会找到并链接到它的后代。

log4net环境的配置通常在应用程序初始化时完成。首选的方法是读取配置文件。不久将讨论这一办法。

Log4net 很容易通过软件组件来命名记录器。这可以通过在每个类中静态实例化记录器来实现,日志记录器名称等于类的完全限定名。这是定义记录器的一种有用且直接的方法。由于日志输出带有记录器的名称,因此这种命名策略可以很容易地识别日志消息的起源。然而,这只是一种常见的命名记录器的策略的可能。Log4net 不限制设置记录器的可能方式。开发者可以自由地根据需要命名记录器。

尽管如此,以它们所在的类命名记录器似乎是迄今为止已知的最佳策略。对于开发人员来说,每个日志消息的来源都很简单。最重要的是,它利用应用程序的设计来生成记录器层次结构的设计。希望在应用程序的设计中已经有了一些想法。

Appenders

根据日志记录程序有选择地启用或禁用日志记录请求的能力只是描述的一部分。Log4net允许日志记录请求打印到多个目的地。在 log4net中,输出目的地称为appender。Appenders必须实现 log4net.Appenders.IAppender 接口。

log4net包中定义了以下appender:
(略, 请查看原文, 或这篇文章与这个表是一样的)

Each enabled logging request for a given logger will be forwarded to all the appenders in that logger as well as the appenders higher in the hierarchy. In other words, appenders are inherited additively from the logger hierarchy. For example, if a console appender is added to the root logger, then all enabled logging requests will at least print on the console. If in addition a file appender is added to a logger, say X, then enabled logging requests for X and X’s children will print on a file and on the console. It is possible to override this default behavior so that appender accumulation is no longer additive by setting the additivity flag on the logger to false.

The rules governing appender additivity are summarized below.

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.

The table below shows an example:

为给定记录器启用的每个日志记录请求都将被转发给该记录器中的所有appenders以及层次结构中更高的appenders。换句话说,appenders是从记录器层次结构中附加继承的。例如,如果console appender被添加到根记录器中,则所有启用的日志记录请求至少将在console中打印出来。此外,如果向记录器中添加了一个file appender,假设X,那么启用X和X的子日志记录请求将在文件和控制台上同时打印。可以重写此默认行为,从而通过将记录器上的 additivity 标记设置为 false,使appender不再逐一附加累积。

下面总结了有关appender的additivity的执行规则。

appender 的 additivity 标志

记录器X的日志输出语句log(), 将遍历所有X和X的子级记录器。这就是“additivity”一词的意思。

但是,如果一个记录器X的父级,假设是Y,已经将“additivity”标志设置为false,然后X的输出将指向X和X父级的appenders, 这也包括Y的appenders. 但不再包括Y的父级.

默认情况下, 记录器的 additivity 标志设置true。

Filters

Appenders可以过滤传递给他们的事件。可以在配置中指定筛选器,以便对通过不同 Appenders 的记录事件进行精细控制。

最简单的控制形式是在Appenders上指定门限。这是通过只记录级别大于或等于阈值的事件来实现的。

更复杂和自定义的事件过滤可以使用在每个Appenders上定义的过滤器链来完成。过滤器必须实现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:

通常,用户不仅希望自定义输出目的地,还希望定制输出格式, 这是通过appender的layout属性来完成的。布局负责根据用户的意愿格式化日志记录请求,而appender则负责将格式化的输出发送到其目的地。PatternLayout是标准log4net发行版的一部分,允许用户根据类似于C语言的printf函数样式来指定输出格式打印字符功能。

例如,带有转换模式 “%timestamp [%thread] %-5level %logger - %message%newline”的 PatternLayout将输出类似于:
176 [main] INFO Com.Foo.Bar - Located nearest gas station.

第一个字段是程序启动以来经过的毫秒数。第二个字段是发出日志请求的线程。第三个字段是log语句的级别。第四个字段是与日志请求关联的记录器的名称。“-” 后面的文本是语句的信息和换行符。

log4net包中包括以下布局:

log4net.Layout.ExceptionLayout 呈现日志事件的异常文本。
log4net.Layout.PatternLayout 根据一组灵活的格式化标志对日志事件进行格式化。
log4net.Layout.RawTimeStampLayout 从日志事件中提取时间戳。
log4net.Layout.RawUtcTimeStampLayout 以Universal Time格式从日志事件中提取时间戳。
log4net.Layout.SimpleLayout 格式化日志事件为简单模式:[level] - [message]
log4net.Layout.XmlLayout 将日志事件格式化为XML元素。
log4net.Layout.XmlLayoutSchemaLog4j 将日志事件格式化为符合log4j事件dtd的XML元素。

Object Renderers (对象渲染器)

同样重要的是,log4net将根据用户指定的标准渲染(Renderers)日志消息的内容。例如,如果经常需要记录橙子对象类型,则可以在当前项目中注册OrangeRenderer, 那么每当需要记录桔子时,都会调用它。

对象 rendering 遵循类层次结构。例如,假设橙子是水果,如果您注册了FruitRenderer,所有水果,包括橙子,都将由FruitRenderer渲染,当然,除非你已经注册了 OrangeRenderer.

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

请注意,ObjectRenderers没有被DebugFormat, InfoFormat, WarnFormat, ErrorFormat and FatalFormat 方法使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值