65.9K
CodeProject 正在变化。 阅读更多。
Home

log4net 教程

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.92/5 (433投票s)

2010年12月29日

CPOL

23分钟阅读

viewsIcon

2335377

downloadIcon

58236

学习如何无忧使用 log4net。停止复制配置文件,弄清楚如何让 log4net 完全按照您的意愿工作。

引言

.NET 领域最出色的日志工具之一是 log4net。这款软件是日志记录方式的黄金标准。它简单、强大且可扩展。最棒的是,它是 FOSS 社区的一部分。还有什么能比这更好呢?在我看来,我认为有点不足的一点是,缺少一个关于如何使用 log4net 的直接教程。文档深入介绍了如何使用该软件,但它有点晦涩。基本上,如果您已经知道 log4net 能做什么,并且只想知道语法,那么文档就是为您准备的。现有的教程通常涵盖一个方面或一种系统类型。我希望至少能为现有的教程添砖加瓦,也许我还能为您提供一个完整的教程,包括我遇到的一些问题的解答。以下示例和信息均基于 log4net 团队提供的文档。

视频教程

作为本文的补充,我在 YouTube 上创建了一个视频教程,将涵盖本文中的内容。虽然本文本身是完整的,并且随着 log4net 版本的变化而更新,但我发现有些人不仅需要阅读,还需要观看(我就是其中之一)。因此,创建了视频 C# 中的应用程序日志记录:log4net 教程。希望您喜欢它,以及本文的其余部分。

基础知识

log4net 有三个部分。它们是配置、设置和调用。配置通常在 app.configweb.config 文件中完成。我们将在下面深入介绍这一点。如果您希望通过使用单独的配置文件获得更大的灵活性,请参阅标题为“摆脱 app.config”的部分。无论您选择哪种方式存储配置信息,代码设置基本上是需要调用几行内务处理代码,以便设置和实例化与日志记录器的连接。最后,最简单的部分是调用本身。如果您做得对,这非常简单,也最容易理解。

日志级别

共有七个日志级别,其中五个可以在您的代码中调用。它们如下所示(级别最高的在列表顶部):

  1. OFF - 不记录任何内容(无法调用)
  2. 致命错误
  3. ERROR
  4. WARN
  5. INFO
  6. DEBUG
  7. ALL - 记录所有内容(无法调用)

这些级别将在您的代码和配置文件中多次使用。关于这些级别代表什么(除了第一个和最后一个)没有固定的规则。

配置

设置 log4net 日志记录器的标准方法是在桌面应用程序中使用 app.config 文件,或者在 Web 应用程序中使用 web.config 文件。为了使 log4net 正常工作,需要在 config 文件中放置一些信息。这些部分将告诉 log4net 如何配置自身。这些设置可以在不重新编译应用程序的情况下更改,这就是 config 文件的全部意义。

您需要有一个根部分来存放顶级日志记录器引用。这些日志记录器从您的基本日志记录器(根)继承信息。根部分存放的唯一其他内容是最低日志级别。由于所有内容都继承自根,因此任何附加器都不会记录低于此处指定级别的信息。这是一种快速控制应用程序日志级别的方法。以下是一个示例,默认级别为 INFO(这意味着 DEBUG 消息将被忽略),并引用了两个应在根下启用的附加器。

<root>
  <level value="INFO"/>
  <appender-ref ref="FileAppender"/>
  <appender-ref ref="ConsoleAppender" />
</root>

附加日志记录器

有时您会想了解应用程序的特定部分。log4net 预料到了这一点,它允许您指定除根日志记录器之外的附加日志记录器引用。例如,这是我放在配置文件中的一个附加日志记录器,用于将 OtherClass 类对象内部发生的控制台消息记录下来。

<logger name="Log4NetTest.OtherClass">
  <level value="DEBUG"/>
  <appender-ref ref="ConsoleAppender"/>
</logger>

请注意,日志记录器名称是类的完整名称,包括命名空间。如果您想监控整个命名空间,只需列出您想监控的命名空间即可。我不建议尝试在多个日志记录器中重用附加器。虽然可以做到,但可能会得到一些不可预测的结果。

配置节

在一个配置文件中,如果除了 log4net 配置信息之外,还有(可能)更多信息存储,您需要指定一个节来标识 log4net 配置所在的位置。以下是一个示例节,它指定配置信息将存储在 XML 标签 "log4net" 下。

<configSections>
  <section name="log4net" 
    type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>

附加器(通用)

附加器是记录信息的工具的名称。它指定信息将在何处记录、如何记录以及在何种情况下记录。虽然每个附加器根据数据的去向有不同的参数,但它们有一些共同的元素。第一个是附加器的名称和类型。每个附加器都必须命名(任何您想要的名称)并为其分配一个类型(特定于所需的附加器类型)。以下是附加器条目的示例。

<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">

布局

每个附加器内部必须有一个布局部分。这可能会根据所使用的附加器类型略有不同,但基本原理是相同的。您需要一个指定数据写入方式的类型。有多种选项,但我建议您使用的是模式布局类型。这将允许您指定希望数据如何写入数据仓库。如果您指定模式布局类型,则需要一个指定转换模式的子标签。这是您的数据应该写入数据仓库的模式。我将更详细地描述转换模式的选项,但目前,以下是带有指定模式布局的布局标签示例。

<layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger [%ndc] 
    - %message%newline"/>
    </layout>

转换模式

如我上面提到的,转换模式条目用于模式布局,以告诉附加器如何存储信息。这些模式中可以使用许多不同的关键字以及字符串字面量。在这里,我将指定我认为最有用和最重要的那些。完整列表可以在 log4net 文档中找到。

  • %date - 使用本地时区信息输出日期。此日期可以使用大括号和布局模式进行格式化,例如 %date{MMMM dd, yyyy HH:mm:ss, fff},以输出“January 01, 2011 14:15:43, 767”的值。但是,建议您使用 log4net 日期格式化程序之一(ABSOLUTE、DATE 或 ISO8601),因为它们提供更好的性能。
  • %utcdate - 这与 %date 修饰符相同,但它以通用时间输出。日期/时间的所有修饰符工作方式相同。
  • %exception - 如果传入异常,它将被输入,并在异常后添加一个新行。如果没有传入异常,此条目将被忽略,并且不会添加新行。这通常放在日志条目的末尾,并且通常在异常之前也添加一个新行。
  • %level - 这是您为事件指定的级别(DEBUG、INFO、WARN 等)。
  • %message - 这是您传递给日志事件的消息。
  • %newline - 这是一个新行条目。根据您使用应用程序的平台,这将转换为适当的新行字符。这是输入新行的首选方法,与平台特定的操作符相比,它没有性能问题。
  • %timestamp - 这是应用程序启动以来的毫秒数。
  • %thread - 这将为您提供创建条目的线程的名称(如果线程未命名,则为数字)。

除了这些之外,还有一些可能非常有用但应谨慎使用的功能。它们会对性能产生负面影响,因此应谨慎使用。列表包括:

  • %identity - 这是使用 Principal.Identity.Name 方法获取的当前用户的用户名。
  • %location - 如果您在调试模式下运行,这尤其有用,它会告诉您日志方法是在哪里调用的(行号、方法等)。但是,在发布模式下运行时,信息量会减少,具体取决于系统从编译代码中可以访问的内容。
  • %line - 这是代码条目的行号(参见上面关于位置问题的注释)。
  • %method - 这是调用日志条目的方法(参见上面关于位置问题的注释)。
  • %username - 这输出 WindowsIdentity 属性的值。

您可能会注意到某些配置文件中用字母而不是名称。这些已被弃用,取而代之的是我上面指定的完整单词条目。此外,虽然我在这里不会深入介绍,但请注意,这些条目中的每一个都可以格式化以适应特定的宽度。可以添加空格(到任一侧),并且可以截断值以适应固定宽度的列。基本语法是在 % 符号和名称之间放置一个或多个数字值。以下是修饰符:

  • X - 指定最小字符数。任何字符数少于此的,将在值的左侧添加空格以达到 20 个字符,包括消息。例如,%10message 将给出 " hi"。
  • -X - 与上面相同,只是空格会放在右侧。例如,%-10message 将给出 "hi "。
  • .X - 指定最大字符数。需要注意的是,这将截断字符串的开头,而不是结尾。例如,如果传入的字符串是 "Error entry",则 %.10message 将给我 "rror entry"。

您可以将所有这些组合在一起,例如:"%10.20message",它将指定如果消息长度不足十个字符,则在左侧填充空格使其达到十个字符;但如果消息长度超过 20 个字符,则截断开头使其只剩 20 个字符。

过滤器。

过滤器是任何附加器的另一个重要组成部分。通过过滤器,您可以指定要记录的级别,甚至可以在消息中查找关键字。过滤器可以混合搭配使用,但这样做时需要小心。当消息符合过滤器的标准时,它就会被记录下来,并且过滤器的处理就完成了。这是过滤器最大的陷阱。因此,如果您正在进行复杂的过滤,过滤器的顺序变得非常重要。

字符串匹配过滤器

字符串匹配过滤器旨在查找日志信息中的特定字符串。您可以指定多个字符串匹配过滤器。它们像查询中的 OR 语句一样工作。过滤器将查找第一个字符串,然后查找第二个字符串,依此类推,直到找到匹配项。然而,这里需要注意的重要一点是,未找到指定字符串的匹配项并不会排除一个条目(因为它可能会继续到下一个字符串匹配过滤器)。这意味着,您可能会遇到未找到匹配项的情况。在这种情况下,默认操作是记录该条目。因此,在字符串匹配过滤器集结束时,有必要包含一个拒绝所有过滤器(参见下文),以便在未找到匹配项时拒绝记录该条目。以下是一个示例,展示了如何过滤消息中包含 test 的条目。

<filter type="log4net.Filter.StringMatchFilter">
  <stringToMatch value="test" />
</filter>
级别范围过滤器

级别范围过滤器告诉系统只记录指定范围内的条目。此范围是包含的,因此在下面的示例中,级别为 INFO、WARN、ERROR 或 FATAL 的事件将被记录,但 DEBUG 事件将被忽略。在此条目之后,您不需要拒绝所有过滤器,因为拒绝是隐含的。

<filter type="log4net.Filter.LevelRangeFilter">
  <levelMin value="INFO" />
  <levelMax value="FATAL" />
</filter>
级别匹配过滤器

级别匹配过滤器的工作方式类似于级别范围过滤器,只是它指定了唯一的一个级别来捕获。然而,它没有内置拒绝功能,因此在列出此过滤器之后,您需要指定拒绝所有过滤器。

<filter type="log4net.Filter.LevelMatchFilter">
  <levelToMatch value="ERROR"/>
</filter>
拒绝所有过滤器

如果忘记了此条目,您的附加器可能无法按预期工作。此条目唯一的目的是指定不应进行日志记录。如果这是唯一的过滤器条目,那么将不会记录任何内容。然而,其真正目的是指定不应再记录任何内容(请记住,任何已匹配的内容都已被记录)。

<filter type="log4net.Filter.DenyAllFilter" />

附加器

每种类型的附加器都有其自己的基于数据去向的语法集。最不寻常的是记录到数据库的那些。我将列出我认为最常见的一些。然而,有了上述信息,您应该能够毫无问题地使用在线提供的示例。log4net 网站上有一些不同附加器的出色示例。正如我之前所说,我广泛使用了 log4net 文档,这个领域也不例外。我通常复制他们的示例,然后根据自己的目的进行修改。

控制台附加器

我通常将此附加器用于测试,但它在生产环境中也可能很有用。如果您使用的是控制台应用程序,它会写入输出窗口或命令窗口。这个特定的过滤器会输出一个类似于“2010-12-26 15:41:03,581 [10] WARN Log4NetTest.frmMain - This is a WARN test.”的值。它会在末尾包含一个新行。

<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date{ABSOLUTE} 
    [%thread] %level %logger - %message%newline"/>
  </layout>
  <filter type="log4net.Filter.StringMatchFilter">
    <stringToMatch value="test" />
  </filter>
  <filter type="log4net.Filter.DenyAllFilter" />
</appender>

文件附加器

此附加器将写入文本文件。这里需要注意的主要区别是,我们必须指定文本文件的名称(在本例中,它是一个名为 mylogfile.txt 的文件,将存储在与可执行文件相同的位置),我们已指定应追加到文件中(而不是覆盖它),并且我们已指定 FileAppender 应使用最小锁(Minimal Lock),这将使该文件可供多个附加器使用。

<appender name="FileAppender" type="log4net.Appender.FileAppender">
  <file value="mylogfile.txt" />
  <appendToFile value="true" />
  <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date [%thread] %level %logger - %message%newline" />
  </layout>
  <filter type="log4net.Filter.LevelRangeFilter">
    <levelMin value="INFO" />
    <levelMax value="FATAL" />
  </filter>
</appender>

滚动文件附加器

在可能的情况下,应使用此附加器代替文件附加器。滚动文件附加器的目的是执行与文件附加器相同的功能,但具有附加选项,即在开始新的日志文件之前只存储一定量的数据。这样,您就无需担心系统上的日志随着时间的推移而填满。即使是一个小型应用程序,如果未使用滚动选项,在足够长的时间内写入文本文件也可能使文件系统不堪重负。在此示例中,我以与上述文件附加器类似的方式进行日志记录,但我指定日志文件应上限为 10MB,并且在开始删除它们(最旧的先删除)之前,我应该保留最多 5 个存档文件。存档文件的名称将与文件名称相同,只是后面带有一个点和数字(例如:mylogfile.txt.2 将是第二个日志文件存档)。staticLogFileName 条目确保当前日志文件将始终命名为我在文件标签中指定的名称(在我的情况下是 mylogfile.txt)。

<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
  <file value="mylogfile.txt" />
  <appendToFile value="true" />
  <rollingStyle value="Size" />
  <maxSizeRollBackups value="5" />
  <maximumFileSize value="10MB" />
  <staticLogFileName value="true" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date [%thread] %level %logger - %message%newline" />
  </layout>
</appender>

ADO.NET 附加器

这是一个棘手的。这个特定的示例写入 SQL,但您可以使用此模式写入任何您想要的数据库。请注意,connectionType 基本上是一个连接字符串,因此修改它很简单。指定的 commandText 是一个简单的查询。您可以将其修改为任何类型的 INSERT 查询(或存储过程)。请注意,每个参数都在下面指定并映射到 log4net 变量。可以指定大小以限制放入参数中的信息。此附加器直接复制自 log4net 示例。我不对其拥有任何功劳。我只是将其用作可以实现什么的示例。

快速提示如果您发现 ADO.NET 附加器不起作用,请检查 bufferSize 值。此值包含 log4net 在将所有日志语句写入 SQL 之前将缓存的日志语句数量。log4net 网站上的示例将 bufferSize 设置为 100,这意味着您在测试时可能会因为没有任何内容起作用而感到恐慌。将 bufferSize 值更改为 1,以使日志记录器在收到每个语句时立即写入。

有关此示例及更多信息,请访问以下 URL:https://logging.apache.ac.cn/log4net/release/config-examples.html

<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
  <bufferSize value="100" />
  <connectionType value="System.Data.SqlClient.SqlConnection, 
   System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  <connectionString value="data source=[database server];
    initial catalog=[database name];integrated security=false;
    persist security info=True;User ID=[user];Password=[password]" />
  <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],
    [Message],[Exception]) VALUES (@log_date, @thread, @log_level, 
    @logger, @message, @exception)" />
  <parameter>
    <parameterName value="@log_date" />
    <dbType value="DateTime" />
    <layout type="log4net.Layout.RawTimeStampLayout" />
  </parameter>
  <parameter>
    <parameterName value="@thread" />
    <dbType value="String" />
    <size value="255" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%thread" />
    </layout>
  </parameter>
  <parameter>
    <parameterName value="@log_level" />
    <dbType value="String" />
    <size value="50" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%level" />
    </layout>
  </parameter>
  <parameter>
    <parameterName value="@logger" />
    <dbType value="String" />
    <size value="255" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%logger" />
    </layout>
  </parameter>
  <parameter>
    <parameterName value="@message" />
    <dbType value="String" />
    <size value="4000" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%message" />
    </layout>
  </parameter>
  <parameter>
    <parameterName value="@exception" />
    <dbType value="String" />
    <size value="2000" />
    <layout type="log4net.Layout.ExceptionLayout" />
  </parameter>
</appender>

代码

一旦您的应用程序中引用了 log4net DLL,您就需要了解三行代码。第一行是一次性条目,需要放置在您的类之外。我通常将其放在 Program.cs 文件中 using 语句的正下方。您可以复制粘贴此代码,因为它可能永远不需要更改(除非您对 config 文件做了一些不寻常的操作)。代码如下:

[assembly: log4net.Config.XmlConfigurator(Watch = true)]

下一个条目每个类只执行一次。它创建一个变量(在本例中称为 "log"),该变量将用于调用 log4net 方法。此代码也是您可以复制粘贴的代码(除非您使用的是 Compact Framework)。它执行 System.Reflection 调用以获取当前类信息。这很有用,因为它允许我们在所有地方使用此代码,但在每个类中传入特定信息。代码如下:

private static readonly log4net.ILog log = log4net.LogManager.GetLogger
    (System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

最后一段代码是实际调用以记录某些信息。这可以使用以下代码完成:

log.Info("Info logging");

请注意,您可以在末尾添加一个可选参数,以包含应记录的异常。如果您想使用此选项,请包含整个异常对象。调用非常相似,看起来像这样:

log.Error("This is my error", ex);

ex 是异常对象。请记住,您需要在附加器中使用 %exception 模式变量来实际捕获此异常信息。

记录额外数据

log4net 中的基本配置通常包含足够的信息用于典型应用程序。但是,有时您希望以标准方式记录更多信息。例如,如果您使用 ADO.NET 附加器,您可能希望添加一个用于应用程序用户名的字段,而不是仅仅将其包含在消息字段中。没有与应用程序用户名匹配的转换模式。但是,您可以使用 Context 属性来指定可以在附加器中访问的自定义属性。以下是如何在代码中进行设置的示例:

log4net.GlobalContext.Properties["testProperty"] = "This is my test property information";

有几点需要注意。首先,我将属性命名为 "testProperty"。我可以将其命名为任何名称。但是,请小心,因为如果您使用已在使用的名称,您可能会覆盖它。这引出了第二点。我引用了 GlobalContext,但有四个上下文可以利用。它们基于线程。全局上下文在应用程序中的任何位置都可用,而 Thread、Logical Thread 和 Event 则进一步限制了范围。您可以使用它根据日志记录器调用的上下文存储不同的信息。但是,如果您的两个属性具有相同的名称,则范围较窄的属性将获胜。再看第一点,我们可以看到这可能导致的问题。如果我们声明一个与现有 ThreadContext 具有相同属性名称的 GlobalContext 属性,我们可能不会看到我们期望的属性值,因为现有值。因此,我建议开发您自己的命名方案,以免与任何其他名称冲突。

以下是如何在我们的附加器中捕获此属性的示例:

<layout type="log4net.Layout.PatternLayout">
  <conversionPattern value="%date{ABSOLUTE} [%thread] %level 
                            %logger - %message%newlineExtra Info: %property{
                            testProperty}%newline%exception"/>
</layout>

有关不同上下文的更多信息,请参阅 log4net 文档中有关此主题的内容:https://logging.apache.ac.cn/log4net/release/manual/contexts.html

摆脱 app.config/web.config

您可能会遇到需要使用单独文件存储 log4net 配置信息的情况。事实上,您可能会发现这是存储配置信息的最佳方式,因为您可以手头保留不同标准配置的副本,以便将其放入您的项目中。这可以缩短开发时间,并允许您标准化日志信息。要进行此设置,您只需更改应用程序的两个部分。您需要做的第一件事是将配置保存到另一个文件中。格式将相同,布局也将相同。布局中唯一真正会改变的是它不再位于 app.configweb.config 文件的中间。您需要进行的第二个更改是在应用程序中的一次设置调用中。您需要添加有关文件位置的信息,如下所示:

[assembly: log4net.Config.XmlConfigurator(ConfigFile = 
                "MyStandardLog4Net.config", Watch = true)]

也可以简单地通过在上面一行中使用“ConfigFileExtension”而不是“ConfigFile”来选择此文件的不同扩展名。如果您这样做,您需要将您的配置文件命名为您的程序集名称(包括扩展名),并且它需要具有您指定的扩展名。以下是一个更直观的解释示例:

[assembly: log4net.Config.XmlConfigurator(ConfigFileExtension = "mylogger", Watch = true)]

在上面的例子中,如果我们的应用程序是 test.exe,那么 log4net 的配置文件应该命名为 text.exe.mylogger

VB.NET

对于那些希望在 VB.NET 应用程序中使用 log4net 的人来说,有几点需要注意。config 文件保持不变,引用的 DLL 相同,日志记录调用也完全相同(只需去掉末尾的分号),但设置调用不同。第一个设置命令是引用程序集。这只需要在应用程序中全局放置一次(在类之外)。命令如下:

'Standard Configuration
<Assembly: log4net.Config.XmlConfigurator(Watch:=True)>

'Using a config file besides app.config/web.config
<Assembly: log4net.Config.XmlConfigurator(
      ConfigFile:="MyStandardLog4Net.config", Watch:=True)>

下一个更改是在每个类中设置的引用变量。此更改,与上一个一样,只是从 C# 到 VB.NET 语法的直接转换:

Private Shared ReadOnly log As log4net.ILog = log4net.LogManager.GetLogger(_
        System.Reflection.MethodBase.GetCurrentMethod().DeclaringType)

只进行这么一点代码转换,就能将其转换为 VB.NET 项目。我已经更新了下载内容,其中包含 C# 项目和 VB.NET 项目,这样您就可以尝试任何一个。我在用 VB.NET 创建自己的项目时遇到了两个小问题,可能会让您感到困惑。我发现的第一个问题是,他们将 框架 选择隐藏在属性菜单深处。请记住,我们需要将目标 框架 从“.NET 框架 4 Client Profile”更改为“.NET 框架 4”,以便 log4net 正常工作(注意:最新版本的 log4net 已不再需要这样做)。要找到它,请打开项目属性页。在“编译”选项卡下,底部有一个名为“高级编译选项...”的按钮。单击此按钮,您将获得更改目标 框架 的选项。我发现的另一个问题是,我无法添加 app.config 文件,因为它说我已有一个。我必须单击“显示所有文件”按钮才能看到我的(现有)app.config 文件。由于您需要修改此特定文件,请确保找到正确的文件。别忘了您可以将 config 文件从 C# 项目复制粘贴过来而不会出现问题。log4net 的 config 文件是独立于语言的。

配置文件模板

虽然您可以查看我发布的示例代码以了解配置文件的实际运行情况,但鉴于人们遇到的一些困难,我决定发布一个配置文件模板,以帮助读者直观地了解每个配置文件部分的放置位置。我在下面为您提供了一个空白模板。我还为每个部分标记了其所在的级别,这样,即使格式不明显,您也知道每个项目与树中所有其他项目之间的关系。

<!--This is the root of your config file-->
<configuration> <!-- Level 0 -->
  <!--This specifies what the section name is-->
  <configSections> <!-- Level 1 -->
    <section name="log4net" 
      type="log4net.Config.Log4NetConfigurationSectionHandler, 
            log4net"/> <!-- Level 2 -->
  </configSections>
  <log4net> <!-- Level 1 -->
    <appender>  <!-- Level 2 -->
      <layout>  <!-- Level 3 -->
        <conversionPattern />  <!-- Level 4 -->
      </layout>
      <filter>  <!-- Level 3 -->
      </filter>
    </appender>
    <root> <!-- Level 2 -->
      <level /> <!-- Level 3 -->
      <appender-ref /> <!-- Level 3 -->
    </root>
    <logger> <!-- Level 2 -->
      <level /> <!-- Level 3 -->
      <appender-ref /> <!-- Level 3 -->
    </logger>
  </log4net>
</configuration>

常见问题解答

  1. 为什么我无法写入我的文本文件? log4net 在活动用户的权限下运行。请确保活动用户具有创建/修改/删除指定文本文件的权限。
  2. 为什么某些事件没有被记录? 很可能,这是因为您设置了过滤器。请记住,根条目可以有一个整体的最低日志过滤器,指定低于此级别的事件不会被记录。实际的附加器也可以有一个级别过滤器,或者您可能过早地设置了“拒绝所有”过滤器。
  3. 为什么我会记录到不想要的事件? 很可能是您设置过滤器不正确。要么您忘记了拒绝所有过滤器,要么您首先包含了级别范围过滤器。
  4. 为什么我会收到编译错误? 如果您收到类似“引用的程序集 'log4net' 无法解析,因为它依赖于 'System.Web, Version=4.0.0.0 ...'”的错误,那么您尚未将目标 框架 更改为“.NET 框架 4”。更改它后,此错误以及由此引发的其他错误都将消失。  注意:这在 log4net 的新版本中已修复。您应该不再需要这样做。
  5. 如何在 ASP.NET 中使用它? 在 ASP.NET 中使用此信息与在桌面应用程序中使用它相同。主要区别在于 config 文件是 web.config 文件而不是 app.config 文件。
  6. 为什么我的 ADO.NET 附加器无法记录任何内容? 如果您检查了所有设置并且它们看起来都正确,那么很可能您正在经历 bufferSize 配置带来的痛苦。将 bufferSize 更改为 1,它将尝试立即记录您发送的每条消息。如果这仍然不起作用,问题出在您的配置。

结论

希望您觉得这个教程很有用。我相信我已经涵盖了您开始无忧使用 log4net 所需的所有信息。如果您希望我详细阐述上面列出的任何区域,或者您在使用 log4net 时遇到问题,请告诉我。有关完整示例,请查看我提供的源代码。它是一个关于如何使用 log4net 的工作示例。您可以将其用作配置文件的测试平台。使用它来确保您以预期的方式记录条目,然后再将配置文件信息复制到您的生产应用程序中。

历史

  • 2010年12月26日:初始版本。
  • 2010年12月31日:添加了 VB.NET 部分,进行了各种语法更改和小的澄清。
  • 2011年2月1日:添加了关于日志记录器、属性和替代日志文件的高级信息,澄清了完整的配置文件布局,并添加了关于 ADO.NET 陷阱的信息。
  • 2012年6月19日:微小更新以反映 log4net 新版本。
  • 2015年9月4日:添加了视频教程部分
© . All rights reserved.