前言——尴尬
笔者本想将内容全部放到一篇文章中,没想到内容太多出现了413错误,又懒得去修改配置,所以就将内容分为了上下两篇。
创建 RabbitLoggerProvider实现ILoggerProvider 接口
RabbitLoggerProvider 负责创建 RabbitLogger,笔者的日志组件需要支持 日志作用域,所以我们还需实现ISupportExternalScope接口。在RabbitLoggerProvider的构造函数中接收IOptionsMonitor<RabbitLoggerOptions> rabbitLoggerOptions 和 ILoggerPersistence loggerPersistence 两个参数,下面是核心代码:
/// <summary> /// /// </summary> public class RabbitLoggerProvider : ILoggerProvider, ISupportExternalScope { /// <summary> /// /// </summary> private readonly ConcurrentDictionary<string, RabbitLogger> _loggers; /// <summary> /// /// </summary> private readonly IOptionsMonitor<RabbitLoggerOptions> _RabbitLoggerOptions; /// <summary> /// /// </summary> private readonly ILoggerPersistence _LoggerPersistence; /// <summary> /// /// </summary> private IExternalScopeProvider _scopeProvider; /// <summary> /// /// </summary> /// <param name="rabbitLoggerOptions"></param> public RabbitLoggerProvider(IOptionsMonitor<RabbitLoggerOptions> rabbitLoggerOptions, ILoggerPersistence loggerPersistence) { _loggers = new ConcurrentDictionary<string, RabbitLogger>(); _RabbitLoggerOptions = rabbitLoggerOptions; _LoggerPersistence = loggerPersistence; ReloadLoggerOptions(_RabbitLoggerOptions.CurrentValue); } /// <summary> /// /// </summary> /// <param name="categoryName"></param> /// <returns></returns> public ILogger CreateLogger(string categoryName) { return _loggers.GetOrAdd(categoryName, loggerName => new RabbitLogger(categoryName, _LoggerPersistence) { Options = _RabbitLoggerOptions.CurrentValue, ScopeProvider = _scopeProvider }); } /// <summary> /// /// </summary> /// <param name="scopeProvider"></param> public void SetScopeProvider(IExternalScopeProvider scopeProvider) { _scopeProvider = scopeProvider; } }
创建 IServiceCollection 扩展方法 AddIMLogger
定义一个静态类,添加 IServiceCollection类的扩展方法 AddIMLogger,这样在Startup的ConfigureServices方法中就可以使用 services.AddIMLogger 的形式注册我们写的组件。核心代码如下:
/// <summary> /// /// </summary> public static class LoggerServiceCollectionExtensions { /// <summary> /// /// </summary> /// <param name="services"></param> /// <returns></returns> private static IServiceCollection AddIMLogger(this IServiceCollection services) { services.AddOptions(); services.AddSingleton<ILoggerPersistence, RabbitLoggerPersistence>(); services.AddLogging(t => { t.AddIMLogger(); }); return services; } /// <summary> /// 所有的配置都从配置文件读取 /// </summary> /// <param name="services"></param> /// <param name="configuration"></param> /// <returns></returns> public static IServiceCollection AddIMLogger(this IServiceCollection services, IConfiguration configuration) { services.Configure<RabbitLoggerOptions>(configuration); services.Configure<RabbitConnectOptions>(configuration.GetSection("RabbitMQ")); services.AddIMLogger(); return services; } }
Startup 注册服务
services.AddIMLogger(Configuration.GetSection("Logging"));
appsetting.json 配置
"Logging": { "LogLevel": { "Default": "Information", "System": "Error", "Microsoft": "Error" }, "IncludeScopes": true, "EnableAsync": true, "ApplicationName": "测试", "MinLevel": "Trace", "RabbitMQ": { "HostName": "127.0.0.1", "Port": 5672, "UserName": "guest", "Password": "guest", "ExChange": "log", "RoutingKey": "log", "Queue": "log", "IsDurable": true, "RetryInterval": 10, "EnableBuffer": true } },
我们组件的配置和Core内置的日记配置都放到 Logging Key下,这样方便管理和移植。
Controller 中使用
[Route("api/[controller]")] [ApiController] public class ValuesController : ControllerBase { private ILogger _Logger; public ValuesController(ILogger<ValuesController> logger) { this._Logger = logger; } // GET api/values [HttpGet] public ActionResult<IEnumerable<string>> Get() { // 具有作用域的使用示例 using (_Logger.BeginScope("测试啦。。")) { _Logger.LogInformation("LogInformation233333333333"); _Logger.LogDebug("Debug级别日志"); _Logger.LogWarning("Warning级别日志。。。"); } return new string[] { "value1", "value2" }; }
组件支持功能及优势
到此我们的组件已经开发完成了,现在来讲讲该组件的优势:
1.支持appsetting.json 配置变更后自动应用新更改。如 将MinLevel改成Error后在程序不重启的情况下只会记录大于Error级别的日志。
2.支持日志类别的过滤,缩小输出日志的范围。比如在 Loglevel key下增加一项 "Glodon.IM.Logger.Test.Controllers" :"Trace",那么将输出该类下所有大于Trace级别的埋点日志,这对调试非常有用。
3.支持日志作用域。笔者暂时没体验到爽的地方。
4.支持同步和异步记录日志。异步时支持缓冲池。
5.使用方式和Core的方式一样。
评论列表
评论内容: