log4net(四) — Logger(记录器)

Sunday, April 29, 2007

前三节主要翻译和学习了配置文件的写法。从这一节将计划翻译Logger(第四节)、记录方式(第五节)、布局(第六节)和过滤器(第七节)。

原文地址:Loggers and Appenders

log4net主要包含三个主要部分,记录器(loggers)、记录方式(appenders)和布局(layouts)。通过这三个部件,开发者可以根据消息类型和等级记录消息,并在运行时刻控制消息的格式和输入方式。这些部件使用过滤器(filters)控制记录方式的行为,使用renderers把对象转换为字符串。

Logger hierarchy(记录器层次结构)

使用记录API相比System.Console.WriteLine最大的优势在于可以禁用某些特定消息并让其他消息畅通无阻。它把所有可能记录的消息按开发者规定的元素进行归类。

记录器是已命名的实体。名字大小写敏感并且遵守夏磊层次命名规则:

如果记录器A的名字以其他记录器B的名字加上.为前缀,那么它就是其他记录器的后代(A是B的后代)。记录器被称为他直接子记录器的父亲。

这个层次结构和.NET中的命名空间、类层次结构类似。在下面我们可以看见这样将非常方便。

例如:名为"Foo.Bar"的记录器是"Foo.Bar.Baz"记录器的父亲。类似的,”System”是"System.Text"的父亲和"System.Text.StringBuilder"的祖先。这种命名方式对于程序来说是相当熟悉的。

根记录器(root logger)位于层次结构的顶端。它在以下三方面表现出特别之处。

1. 它总是存在的。

2. 他不能通过名字获取。

3. 它总被指定在某个等级。

记录器可以通过log4net.LogManger类的静态方法获得。GetLogger方法以欲获取的记录器名称为参数,如下所示:

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

GetLogger方法也可以接受欲获取记录器的完整类型为名称的Type类型参数。

记录器返回ILog接口,它代表了返回给开发者的记录器。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);
    }
}

记录器可以被指定等级。等级是log4net.Core.Level类的实例。下列等级依照递增优先级被定义。

ALL DEBUG INFO WARN ERROR FATAL OFF

如果一个记录器没有被指定等级,那么它继承它最近的父类的等级。

未指定等级的记录器X 继承 从X向上到根记录器的路线中第一个被直接指定等级的记录器的等级。

为了保证所有的记录器能够继承一个等级,所以根记录器总被指定一个等级,默认为DEBUG。下面4个表格是根据上面规则分配和继承等级的例子。

记录器名

被指定等级

继承等级

root

Proot

Proot

X

none

Proot

X.Y

none

Proot

X.Y.Z

none

proot

上面例子中只有根记录器被指定了等级Proot,因此其他记录器X, X.Y, X.Y.Z均继承了等级Proot。

记录器名

被指定等级

继承等级

root

Proot

Proot

X

Px

Px

X.Y

Pxy

Pxy

X.Y.Z

Pxyz

pxyz

上面的例子中,每个记录器都被指定了等级,因此没有继承的等级。

记录器名

被指定等级

继承等级

root

Proot

Proot

X

Px

Px

X.Y

none

Px

X.Y.Z

Pxyz

pxyz

上面的例子中,根记录器、X记录器、X.Y.Z记录器分别被分配了等级Proot、Px、Pxyz。X.Y记录器继承父亲X的等级Px。

记录器名

被指定等级

继承等级

root

Proot

Proot

X

Px

Px

X.Y

none

Px

X.Y.Z

none

Px

上面的例子中,根记录器、X记录器分别被分配了等级Proot、Px。X.Y和X.Y.Z记录器继承它们最近的被指定等级的记录器的等级。

记录请求通过调用记录器实例(使用log4net.ILog)的printing方法调用,printing方法包括Debug, Info, Warn, Error和Fatal。

通常,printing方法决定了记录请求的等级。例如,存在记录器实例log,那么log.Info(“…”)将发出等级为INFO的记录请求。

如果记录请求的等级高于或者等于记录器的等级将被允许。相反,请求将被禁止。没有指定等级的记录器将从层次结构中继承一个。这个规则归纳如下。

L>=K时,等级(指定或者继承)为K的记录器允许等级为L的记录请求。

这条规则是log4net的核心。它基于有序的规则,标准等级规则下,DEBUG<INFO<WARN<ERROR<FATAL。调用使用相同名称为参数的log4net.LogManager.GetLogger方法将返回完全相同的记录器的应用。例如

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

X和y指向完全相同的记录器。

因此,配置一个记录器并在代码中的某个地方不通过传递引用而获取相同的记录器成为可能。与生物学的父亲总是先于后代的基本原理不同,log4net记录器能够以任何顺序被配置。但是,即使父记录器晚于子记录器被配置,他也总是先被找到并链接到它的后代。

log4net环境通常在程序初始化时被配置。通常偏爱使用配置文件的方式,这个将在后面讨论(翻译调换了顺序,配置见前几节

log4net使通过组件命名记录器很简单。它可以通过在每个类中实例化记录器实现,记录器的名字为每个类的完整名称。这是一个定义记录器有用和直接的方法。随着输出的记录带有产生它的记录器的名字,这种命名规则简化了确认记录消息的来源方法。但是,这只是一种普遍的命名记录器的方法。Log4net不限制其他的命名方式。开发人员可以任意给记录器取名。

然而,按所在类命名记录器是目前已知的最好的方法。他给开发者明确指出了记录消息的来源。更重要的是这样可是使用程序的设计来设计记录器的层次结构。希望其中一些思想已进入到程序的设计中。

0 COMMENTS: