log4net 实战指南:老牌 .NET 日志框架的使用与维护

log4net 中文实战指南:Appender 与 Hierarchy 概念、代码与 XML 两种配置方式、五个日志级别、PatternLayout 模式字符串、RollingFileAppender 轮转、维护现状与迁移建议,以及观测云 DataKit 采集落地方案。

最佳实践
log4net 实战指南:老牌 .NET 日志框架的使用与维护技术指南封面

log4net 是 Apache log4j 的 .NET 移植,是 .NET 平台历史最悠久的日志框架之一,至今仍运行在大量企业存量系统中。本文讲解 log4net 的配置与用法、维护现状评估,以及存量系统的观测云落地方案。

核心要点速览

  • log4net 三大件:Logger(产生日志)、Appender(决定去向)、Layout(决定格式),组合灵活但概念偏老。
  • 项目活跃度低:更新稀少,新系统不建议引入;存量系统继续用是安全的。
  • RollingFileAppender 内建轮转:按大小/日期归档,运维友好。
  • 存量系统照样可观测:JSON 化改造 + 观测云 DataKit 采集,老系统也能拥有现代日志平台能力。

快速上手:代码配置方式

using log4net;
using log4net.Config;
using log4net.Appender;
using log4net.Layout;
using log4net.Repository.Hierarchy;

var hierarchy = (Hierarchy)LogManager.GetRepository();

var consoleAppender = new ConsoleAppender
{
    Layout = new PatternLayout("%date [%thread] %-5level %logger - %message%newline")
};
hierarchy.Root.AddAppender(consoleAppender);
hierarchy.Root.Level = log4net.Core.Level.Info;
BasicConfigurator.Configure(hierarchy);

var logger = LogManager.GetLogger(typeof(Program));
logger.Debug("Debug message");   // 不输出(级别 Info)
logger.Info("应用启动");
logger.Warn("配置缺失");
logger.Error("数据库连接失败", ex);   // 第二个参数传异常,自动带堆栈
logger.Fatal("系统级故障");

五个级别:Debug → Info → Warn → Error → Fatal

XML 配置方式(主流)

log4net 更常见的是 XML 声明式配置:

<log4net>
  <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
    <file value="logs/app.log" />
    <appendToFile value="true" />
    <rollingStyle value="Size" />
    <maxSizeRollBackups value="10" />
    <maximumFileSize value="100MB" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
    </layout>
  </appender>
  <root>
    <level value="INFO" />
    <appender-ref ref="RollingFile" />
  </root>
</log4net>

装配一行:XmlConfigurator.Configure()(或程序集特性 [assembly: XmlConfigurator])。RollingFileAppender 支持按大小、按日期或混合轮转——运维侧无需再依赖系统 logrotate。

PatternLayout 常用占位符

占位符 含义
%date 时间戳(%date{ISO8601} 指定格式)
%-5level 级别(左对齐占 5 字符)
%logger logger 名
%message 消息
%exception 异常堆栈
%property{key} MDC/属性上下文值

上下文与结构化

log4net 的 MDC(log4net.MDC.Set("user", name))提供上下文属性,经 %property{user} 输出。它不是现代意义的结构化 JSON——存量系统要 JSON 输出,可换用 log4net.Ext.Json 等扩展布局,让 DataKit 能自动解析字段。

现状评估与迁移建议

  • 优点:文档与社区资料丰富、Appender 生态全、配置灵活、稳定可靠;
  • 短板:更新频率低、无现代结构化 JSON 原生支持、无消息模板;
  • 建议:存量系统继续维护(配合 JSON 扩展);新系统选 Serilog 或内置 ILogger + Provider 体系;迁移可用"适配器先行"——业务代码面向 ILogger 抽象编程,底层实现随时替换。

观测云落地:log4net 日志采集与分析

  1. 应用侧:换用 JSON 布局扩展(如 log4net.Ext.Json),输出时间、级别、logger、消息、异常与属性字段,写滚动文件或控制台。
  2. DataKit 采集conf.d/log/logging.conflogfiles 指向日志文件,source: dotnet-appservice 标识服务;JSON 自动解析。纯文本 PatternLayout 也能用 Pipeline 的 grok 解析,但 JSON 更省心。
  3. Pipeline 标准化:级别映射标准 status,时间字段解析为 time%property 中的 trace_id 提取为顶层字段。
  4. 检索告警:日志查看器按 status/service 过滤聚类;监控器对 Error/Fatal 设阈值,通知对象发钉钉/企业微信/飞书。
  5. 成本控制:多索引按级别拆分保留策略,历史数据转发归档对象存储。

常见问题(FAQ)

log4net 还安全吗?

框架本身稳定,继续使用没有已知风险;但项目更新稀少,新漏洞响应可能较慢。关注官方公告,核心系统建议规划向 Serilog/ILogger 的演进路线。

为什么我的 log4net 完全没输出?

最常见的三个原因:XmlConfigurator.Configure() 没执行;配置文件没复制到输出目录;root level 设置高于日志级别。log4net 静默失败的特性让这些坑只能靠检查内部调试输出(log4net.Util.LogLog.InternalDebugging = true)定位。

log4net 能多线程/多进程写同一文件吗?

多线程安全;多进程共享同一文件需要 lockingModel 改为 MinimalLock(性能下降)或干脆按进程分文件。IIS 多实例场景尤其注意。

存量 log4net 系统值得迁 Serilog 吗?

看收益:需要结构化 JSON、消息模板、丰富 Sink 时值得。渐进式做法:新代码用 ILogger 抽象 + Serilog Provider,老代码保留 log4net,两者输出统一到同一目录,由 DataKit 一并采集。

系列阅读


获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台