Fork me on GitHub

log4net 自定义Layout日志字段

最近在使用log4net的时候有一个简单的需求,就是自定义个格式化输出符。这个输出符是专门用来帮我记录下业务ID、业务类型的。比如,“businessID:328593,businessType: orderID”。类似这样的输出日志。这些日志会被elk agent提取送到日志中心ES中,用来进行辅助排障。

简单的看了下log4net的PatternLayout和PatternConverter两个对象的作用,实现起来也是非常方便的。log4net有一组global的PatternLayout,这些全局的格式化对象是默认构造的时候就存在了,我们只需要提供对我们来说特殊场景的实现即可。

1

你所使用的所有常规的格式化输出都在全局的注册了。我们来实现自己的特殊用途的PatternLayout和PatternConverter,除此之外你还需要一个日志信息的载体对象,这里我使用BusinessIDLog类来存放。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using System.IO;
using log4net.Layout.Pattern;
using log4net.Core;
 
namespace log4net.appender.demo
{
    public class BusinessIDPatternConvert : PatternLayoutConverter
    {
        protected override void Convert(TextWriter writer, LoggingEvent loggingEvent)
        {
            var businessID = loggingEvent.MessageObject as BusinessIDLog;
            if (businessID == null) return;
 
            writer.Write(string.Format(" businessID:{0},businessType:{1}", businessID.ID,businessID.BusinessType));
        }
    }
}

  

在log4net里面,每一个特殊的格式符都是一个converter。明白了这个就很容易理解为什么配置一个格式化的字符串就可以得到自己的想要的文本。

1
2
3
4
5
6
7
8
9
10
namespace log4net.appender.demo
{
    public class BusinessIDPatternLayout : log4net.Layout.PatternLayout
    {
       public BusinessIDPatternLayout()
        {
            this.AddConverter("businessID", typeof(BusinessIDPatternConvert));
        }
    }
}

 

实现一个PatternLayout就可以接管所有的格式化。这里的this.AddConverter,是将我们的businessID的Converter放入当前instance的作用域内。它不是全局的,而是当前实例局部的。

2

然后在你的log4net的配置文件中配置你自定义的PatternLayout。

<!--日志格式--> 
      <layout type="log4net.appender.demo.BusinessIDPatternLayout"> 
        <conversionPattern value="%date [%t]%-5level %c [%businessID] %n"/> 
      </layout>

用户使用的时候需要传入BusinessIDLog对象,要不然我们的Converter对象无法获取到数据对象。

1
2
3
4
5
6
7
8
9
10
11
12
namespace log4net.appender.demo
{
    class Program
    {
        static void Main(string[] args)
        {
            var loger = LogManager.GetLogger(typeof(Program));
 
            loger.Info(new BusinessIDLog() { ID = "25434535", BusinessType = "orderID" });
        }
    }
}

这样就OK了。

3

是不是很方便。

posted @   王清培  阅读(6788)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
历史上的今天:
2013-11-20 .NET项目开发—浅谈面向对象的纵横向关系、多态入口,单元测试(项目小结)
点击右上角即可分享
微信分享提示