LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

log4net 简介以及简单示例

freeflydom
2025年11月1日 15:4 本文热度 262

前言

log4net 是一个广泛使用的、功能强大的日志记录库,专为 .NET 平台设计。

它源自 Java 社区中非常流行的日志框架 log4j,并继承了其灵活、高效和可配置的特点。

log4net 允许开发者在 .net 应用程序(包括 ASP.NET、.NET Core、.NET Framework、Windows Forms、WPF 等)中轻松地添加日志功能。

本文就来进行简单的汇总介绍,供参考。

另外,但由于 log4net 是较老的日志框架,其生态在 .NET Core/.NET 5+ 环境中支持有限,因此使用时需注意兼容性。

其实现在更流行的框架有很多值得推荐,例如 Serilog、Microsoft.Extensions.Logging 等等,博主后续也将进行简单的实践。

一、log4net 基础

log4net 的配置通常放在 log4net.config,app.config, web.config 或一个独立的 .xml 文件中。

下面看下一个简单的配置示例:

<?xml version="1.0" encoding="utf-8" ?>
<log4net>
  <!-- 根日志配置 -->
  <root>
    <level value="DEBUG" />
    <appender-ref ref="FileAppender" />
  </root>
  <!-- 屏蔽 Microsoft 开头的所有日志(包括 Hosting.Lifetime) -->
  <logger name="Microsoft" additivity="false">
    <level value="OFF" />
  </logger>
  <!-- 屏蔽 System 开头的日志(可选) -->
  <logger name="System" additivity="false">
    <level value="OFF" />
  </logger>
  <!-- 文件输出器 -->
  <appender name="FileAppender" type="log4net.Appender.RollingFileAppender">
    <!-- 根据操作系统动态设置日志路径 -->
    <file value="logs/logfile" />
    <datePattern value="yyyy-MM-dd'.log'" />
    <appendToFile value="true" />
    <rollingStyle value="Date" />
    <maxSizeRollBackups value="10" />
    <maximumFileSize value="10MB" />
    <staticLogFileName value="false" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
    </layout>
  </appender>
</log4net>

1.1 配置文件关键节点有哪些?root、logger、appender、level

  • <root>记录器:必要、唯一

<root>是 Logger 层次结构的根节点,所有 Logger 都是它的后代。

必须配置,且只能有一个。

通常在这里设置应用程序的默认日志级别和主要的 Appender。例如:

<!-- 根记录器 (Root Logger) -->
<!-- 这是所有 Logger 的父级,必须存在且唯一 -->
<root>
    <!-- 设置根记录器的日志级别 -->
    <level value="DEBUG" />
    <!-- 引用已定义的 Appender,可以添加多个 -->
    <appender-ref ref="ConsoleTestAppender" />
    <appender-ref ref="ConsoleAppender" />
</root>
  • <logger>记录器:非必要、可多个

用于为特定的命名空间或类创建自定义的 Logger。

name 属性通常使用完整的类名或命名空间名(如 MyApp.Services.UserService)。

可以设置与根记录器不同的 level,也可以引用不同的 appender-ref。

<!-- 根记录器 (Root) -->
<root>
    <level value="DEBUG" />
    <!-- 根记录器使用 ConsoleAppender -->
    <appender-ref ref="ConsoleAppender" />
</root>
<!-- Logger 1: MyApp.Services 命名空间 -->
<logger name="MyApp.Services">
    <level value="INFO" />
    <!-- 关键:设置了 additivity="false" -->
    <additivity value="false" />
    <!-- 只使用 FileAppender -->
    <appender-ref ref="FileAppender" />
</logger>
<!-- Logger 2: MyApp.Data 命名空间 -->
<logger name="MyApp.Data">
    <level value="DEBUG" />
    <!-- 没有设置 additivity,默认为 true -->
    <!-- 使用自己的 Appender 和 继承根记录器的 Appender -->
    <appender-ref ref="FileAppender" />
</logger>

additivity 属性:

true(默认):日志消息会输出到当前 Logger 的【所有 Appender 以及其所有祖先 Logger 的 Appender】。
false:日志消息只输出到当前 Logger 明确引用的 Appender,不会传递给父级 Logger。这在需要隔离日志输出时非常有用。

  • <appender>配置:必要、可多个

name:Appender 的唯一标识符,供 Logger 引用。

type:Appender 的完全限定类型名。

内部的 <layout> 定义了日志的输出格式。PatternLayout 是最灵活的。

conversionPattern 格式化字符串,常用占位符:

占位符含义
%date{格式}时间戳,如 %date{yyyy-MM-dd HH:mm:ss,fff}
%thread线程名
%level日志级别(DEBUG, INFO 等)
%logger{N}Logger 名称,{N} 表示只显示最后 N 段(如 %logger{1} 只显示类名)
%message日志消息
%exception异常堆栈信息
%newline换行
%highlight{pattern}在支持的 Appender(如 ColoredConsoleAppender)中为文本添加颜色

如下示例,包含节点应用和解释(包含文件输出、控制台输出、数据库输出):

<!-- ============ 定义 Appender (输出目标) ============ -->
<!-- Appender 1: 滚动文件输出器 -->
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
    <!-- 日志文件的路径和名称 -->
    <file value="logs\\application.log" />
    <!-- 是否追加到现有文件 -->
    <appendToFile value="true" />
    <!-- 滚动方式: Size(按大小) 或 Date(按日期) -->
    <rollingStyle value="Size" />
    <!-- 最多保留的备份文件数量 -->
    <maxSizeRollBackups value="5" />
    <!-- 单个日志文件的最大大小 -->
    <maximumFileSize value="10MB" />
    <!-- 归档后文件名是否保持不变 -->
    <staticLogFileName value="true" />
    <!-- 归档模式 -->
    <countDirection value="1" />
    <!-- 布局 (Layout): 定义日志格式 -->
    <layout type="log4net.Layout.PatternLayout">
        <!-- 转换模式 (Conversion Pattern) -->
        <conversionPattern value="%date{yyyy-MM-dd HH:mm:ss,fff} [%thread] %-5level %logger{1} - %message%newline%exception" />
    </layout>
</appender>
<!-- Appender 2: 控制台输出器 -->
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
    <!-- 使用彩色输出 -->
    <target value="Console.Out" />
    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%highlight{%-5level} %logger{1} - %message%newline" />
    </layout>
</appender>
<!-- Appender 3: 数据库输出器 (示例) -->
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
    <bufferSize value="1" />
    <connectionType value="System.Data.SqlClient.SqlConnection, System.Data" />
    <connectionString value="Data Source=.;Initial Catalog=MyAppLogs;Integrated Security=True;" />
    <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>
  • <level>配置:

在 <root> 或 <logger> 内部使用。

value 属性设置具体的级别 (DEBUG, INFO, WARN, ERROR, FATAL, OFF, ALL)。

1.2 layout 中有哪些固有参数

参数含义示例其他要点
%m 或 %message日志消息(loggingEvent.MessageObject)用户登录成功 
%n换行符(平台相关:Windows 是 \r\n,Unix 是 \n)换行 
%t 或 %thread线程名MainThread 
%p 或 %level日志级别(Level)INFO, ERROR%-5level:左对齐,最小宽度 5(如 INFO )
%5level:右对齐,最小宽度 5(如  INFO)
%c 或 %logger记录器名称(Logger Name)MyApp.Services.UserService%.10logger:最多显示 logger 的前 10 个字符
%-40[ %logger{1} ]:左对齐 40 字符,只显示 logger 最后一级
%C调用者类名(需要 StackTrace 支持,性能较差)UserService 
%M调用者方法名(同上,需 StackTrace)Login 
%F调用者源文件名(需调试信息 .pdb)UserService.cs 
%L调用者行号(需 .pdb)45 
%l完整位置信息 = %F:%LUserService.cs:45 
%d 或 %date日期时间%d{yyyy-MM-dd HH:mm:ss} → 2025-10-14 23:30:00%d{yyyy-MM-dd HH:mm:ss.fff}
%date{ISO8601}
%r从程序启动到记录日志所经过的毫秒数12345 
%P当前进程 ID1234 
%x 或 %ndcNDC(Nested Diagnostic Context)栈内容User123 
%X{key}MDC(Mapped Diagnostic Context)中的键值%X{userid} → 123 
%exception异常信息(包括类型、消息、堆栈)System.NullReferenceException: Object reference not set... 
%property{key}Log4net 全局属性或日志事件属性%property{hostname}, %property{ThreadName} 
%newline换行符(同 %n)换行 
%type日志事件的类型(通常是 LoggingEvent)log4net.Core.LoggingEvent 
%location位置信息(等价于 %C.%M(%F:%L))UserService.Login(UserService.cs:45) 
转换符注意事项
%C, %M, %F, %L, %l, %location需要生成 StackTrace,影响性能,建议仅在调试环境使用
%X{key}, %property{key}可用于添加上下文信息(如用户ID、请求ID)
%exception只有当 exception 不为 null 时才输出

二、简单示例测试

2.1 打印出各个级别的日志信息

1)首先引用两个依赖包:log4netMicrosoft.Extensions.Logging.Log4Net.AspNetCore

image

2)在项目主目录下添加配置文件 log4net.config:

<?xml version="1.0" encoding="utf-8" ?>
<log4net>
  <!-- 根日志配置 -->
  <root>
    <level value="DEBUG" />
    <appender-ref ref="FileAppender" />
  </root>
  <!-- 屏蔽 Microsoft 开头的所有日志(包括 Hosting.Lifetime) -->
  <logger name="Microsoft" additivity="false">
    <level value="OFF" />
  </logger>
  <!-- 屏蔽 System 开头的日志(可选) -->
  <logger name="System" additivity="false">
    <level value="OFF" />
  </logger>
  <!-- 文件输出器 -->
  <appender name="FileAppender" type="log4net.Appender.RollingFileAppender">
    <!-- 根据操作系统动态设置日志路径 -->
    <file value="logs/logfile" />
    <datePattern value="yyyy-MM-dd'.log'" />
    <appendToFile value="true" />
    <rollingStyle value="Date" />
    <maxSizeRollBackups value="10" />
    <maximumFileSize value="10MB" />
    <staticLogFileName value="false" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
    </layout>
  </appender>
</log4net>

3)在 Program.cs 文件中添加一行代码builder.Logging.AddLog4Net("log4net.config");

作用是,将 log4net 日志框架集成到 .NET 的内置日志系统(Microsoft.Extensions.Logging)中,并使用指定的配置文件进行初始化。

var builder = WebApplication.CreateBuilder(args);
builder.Logging.AddLog4Net("log4net.config"); // 此行
// Add services to the container.
builder.Services.AddControllers();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseAuthorization();
app.MapControllers();
app.Run();

4)最后,在控制器中如下配置,进行日志记录:

using log4net;
using Microsoft.AspNetCore.Mvc;
namespace Test.WebAPI._8._0.Log4net.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private readonly ILogger<WeatherForecastController> _logger;
        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }
        [HttpGet]
        public void Get()
        {
            _logger.LogInformation("信息");
            _logger.LogError("错误");
            _logger.LogWarning("警告");
            _logger.LogDebug("调试");
        }
    }
}

5)验证

启动项目,并通过第三方接口测试应用,调用 Get 接口,触发日志记录。

2025-10-09 21:51:04,811 [12] INFO  Test.WebAPI._8._0.Log4net.Controllers.WeatherForecastController - 信息
2025-10-09 21:51:04,839 [12] ERROR Test.WebAPI._8._0.Log4net.Controllers.WeatherForecastController - 错误
2025-10-09 21:51:04,841 [12] WARN  Test.WebAPI._8._0.Log4net.Controllers.WeatherForecastController - 警告
2025-10-09 21:51:04,842 [12] DEBUG Test.WebAPI._8._0.Log4net.Controllers.WeatherForecastController - 调试

2.2 如何输出 json 格式的字符串

其实实现起来很简单,就是创建自定义 PatternLayoutConverter 并注册到 Layout。

作用就是,把需要输出的内容进行格式化,转义成字符串,避免把这个信息塞进 json 的一个字段后出现格式校验失败。

如下一个转换器的示例:

using log4net.Core;
using log4net.Layout;
using log4net.Layout.Pattern;
using System.Web;
namespace Test.WebAPI._8._0.Log4net.PublicClass
{
    public class JsonPatternLayout : PatternLayout
    {
        public JsonPatternLayout()
        {
            // 注册自定义转换器名称,在配置文件中使用这个 %escapedmessage 来指代要记录的日志内容
            this.AddConverter("escapedmessage", typeof(EscapedMessagePatternConverter));
        }
    }
    public class EscapedMessagePatternConverter : PatternLayoutConverter
    {
        protected override void Convert(TextWriter writer, LoggingEvent loggingEvent)
        {
            string message = loggingEvent.RenderedMessage ?? string.Empty;
            // 使用 JavaScriptStringEncode 进行转义,适合嵌入 JSON
            string escapedMessage = HttpUtility.JavaScriptStringEncode(message);
            writer.Write(escapedMessage);
        }
    }
}

然后在 log4net.config 配置文件中,把日志的输出格式变更下:

<layout type="Test.WebAPI._8._0.Log4net.PublicClass.JsonPatternLayout">
   <conversionPattern value="{&quot;time&quot;:&quot;%date{yyyy-MM-dd HH:mm:ss}&quot;, &quot;level&quot;:&quot;%level&quot;, &quot;message&quot;:&quot;%escapedmessage&quot;, &quot;logger&quot;:&quot;%logger&quot;}%n"/>
</layout>

注意其中的自定义参数引用:%escapedmessage。

如下是输出示例:

{"time":"2025-10-14 21:56:43", "level":"INFO", "message":"信息", "logger":"Test.WebAPI._8._0.Log4net.Controllers.WeatherForecastController"}
{"time":"2025-10-14 21:58:16", "level":"ERROR", "message":"错误", "logger":"Test.WebAPI._8._0.Log4net.Controllers.WeatherForecastController"}
{"time":"2025-10-14 21:58:17", "level":"WARN", "message":"警告", "logger":"Test.WebAPI._8._0.Log4net.Controllers.WeatherForecastController"}
{"time":"2025-10-14 21:58:18", "level":"DEBUG", "message":"调试", "logger":"Test.WebAPI._8._0.Log4net.Controllers.WeatherForecastController"}

参考:https://blog.csdn.net/qq_61632126/article/details/136475013

三、遇到的一些问题

3.1 Debug 日志没有打印出来,其他级别正常

主要是因为项目配置里的信息,默认为 Information,此级别高于 Debug,因此需要如下修改。

// appsetting.json
{
  "Logging": {
    "LogLevel": {
      "Default": "Information", // 注意这里,配置需改为 Debug
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}
// appsettings.Development.json
{
  "Logging": {
    "LogLevel": {
      "Default": "Information", // 注意这里,配置需改为 Debug
      "Microsoft.AspNetCore": "Warning"
    }
  }
}

 转自https://www.cnblogs.com/hnzhengfy/p/19121607/log4net


该文章在 2025/11/1 15:04:11 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved