给微软的日志框架写一个基于委托的日志提供者
程序员文章站
2024-01-29 23:53:46
动手造*:给微软的日志框架写一个基于委托的日志提供者 Intro 微软的日志框架现在已经比较通用,有时候我们不想使用外部的日志提供者,但又希望提供一个比较简单的委托就可以实现日志记录,于是就有了后面的探索和实现。 Solution 基于委托的 实现代码: 自定义 Logger 微软的日志框架中记录 ......
动手造*:给微软的日志框架写一个基于委托的日志提供者
intro
微软的日志框架现在已经比较通用,有时候我们不想使用外部的日志提供者,但又希望提供一个比较简单的委托就可以实现日志记录,于是就有了后面的探索和实现。
solution
基于委托的 loggerprovider
实现代码:
自定义 logger
微软的日志框架中记录日志是通过 ilogger
来做的,扩展支持其他日志框架的时候也需要实现相应的 ilogger
来适配
iloggerprovider
会需要实现创建 ilogger
的接口 createlogger(string categoryname)
,所以我们可以先来实现对应的 ilogger
,实现如下:
这里的实现简单化处理,默认处理所有级别的日志,如果要设定日志级别可以通过日志的 fliter 来做,这里就不做检查和限制了
private class delegatelogger : ilogger { private readonly string _categoryname; private readonly action<string, loglevel, exception, string> _logaction; public delegatelogger(string categoryname, action<string, loglevel, exception, string> logaction) { _categoryname = categoryname; _logaction = logaction; } public void log<tstate>(loglevel loglevel, eventid eventid, tstate state, exception exception, func<tstate, exception, string> formatter) { if (null != _logaction) { var msg = formatter(state, exception); _logaction.invoke(_categoryname, loglevel, exception, msg); } } public bool isenabled(loglevel loglevel) { return true; } public idisposable beginscope<tstate>(tstate state) { return nullscope.instance; } }
自定义 iloggerprovider
有了 ilogger
之后接着我们来定义我们的 iloggerprovider
,这里我们针对 logger 名称(categoryname)做了区分,如果不关注 logger 名称的话也可以使用同一个
logger 这样就不需要下面的并发字典了,只用一个 ilogger
对象就可以了,可以根据自己的需要进行定制
实现代码如下:
[provideralias("delegate")] public class delegateloggerprovider : iloggerprovider { private readonly action<string, loglevel, exception, string> _logaction; private readonly concurrentdictionary<string, delegatelogger> _loggers = new concurrentdictionary<string, delegatelogger>(); public delegateloggerprovider(action<string, loglevel, exception, string> logaction) { _logaction = logaction; } public void dispose() { _loggers.clear(); } public ilogger createlogger(string categoryname) { return _loggers.getoradd(categoryname, category => new delegatelogger(category, _logaction)); } }
定义扩展方法
为了方便使用,我们需要定义两个扩展方法来优化我们使用的方式:
定义 iloggerfactory
的扩展方法:
/// <summary> /// adddelegateloggerprovider /// </summary> /// <param name="loggerfactory">loggerfactory</param> /// <param name="logaction">logaction</param> /// <returns>loggerfactory</returns> public static iloggerfactory adddelegatelogger(this iloggerfactory loggerfactory, action<string, loglevel, exception, string> logaction) { loggerfactory.addprovider(new delegateloggerprovider(logaction)); return loggerfactory; }
定义 iloggingbuilder
的扩展方法:
public static iloggingbuilder adddelegatelogger(this iloggingbuilder loggingbuilder, action<string, loglevel, exception, string> logaction) { return loggingbuilder.addprovider(new delegateloggerprovider(logaction)); }
使用示例
iloggerfactory loggerfactory = new loggerfactory(); //loggerfactory.addconsole(); loggerfactory.adddelegatelogger( (category, loglevel, exception, msg) => { console.writeline($"{category}:[{loglevel}] {msg}\n{exception}"); } );
日志输出效果如下:
reference
上一篇: python 自动去除空行的实例
下一篇: python文件中的小事