是否可以直接获取ILogger实例的当前LogLevel?
解决方案
.NET 官方的ILogger抽象本身没有提供直接获取当前生效日志级别的公开属性,核心原因是日志级别支持多维度配置:同个ILogger实例可以对不同的日志输出提供程序设置不同的启用级别,同时配置来源支持多源覆盖(appsettings.json、环境变量、命令行、配置中心等优先级叠加),直接读取配置源无法拿到准确的生效级别。
以下是两种可行的实现方案:
方案1:基于默认日志实现读取内部配置(不推荐跨版本使用)
该方法仅适用于微软官方默认的Microsoft.Extensions.Logging实现,依赖内部私有字段,跨.NET版本可能出现兼容性问题。
using System.Reflection; using Microsoft.Extensions.Logging; public static LogLevel? GetConfiguredMinLogLevel(ILogger logger) { var loggerType = logger.GetType(); // 读取默认Logger实现的内部_loggers字段 var loggersField = loggerType.GetField("_loggers", BindingFlags.Instance | BindingFlags.NonPublic); if (loggersField == null) return null; var loggers = loggersField.GetValue(logger) as Array; if (loggers == null || loggers.Length == 0) return null; var minLevel = LogLevel.Critical; foreach (var loggerInfo in loggers) { var levelProp = loggerInfo.GetType().GetProperty("MinLevel", BindingFlags.Instance | BindingFlags.Public); if (levelProp == null) continue; var currentLevel = (LogLevel)levelProp.GetValue(loggerInfo); if (currentLevel < minLevel) minLevel = currentLevel; } return minLevel; }
方案2:通用兼容方案(推荐)
该方案通过遍历所有LogLevel枚举值获取实际生效的最小级别,仅需遍历6个枚举值,性能损耗几乎可以忽略,兼容所有ILogger实现,且不受配置源类型的影响,返回的是当前实际生效的级别。
using Microsoft.Extensions.Logging; public static LogLevel? GetEffectiveMinLogLevel(ILogger logger) { // 按级别从低到高遍历,第一个启用的级别就是实际生效的最小级别 foreach (LogLevel level in Enum.GetValues(typeof(LogLevel))) { if (level == LogLevel.None) continue; if (logger.IsEnabled(level)) { return level; } } // 返回null代表所有级别日志都被禁用 return null; }
内容的提问来源于stack exchange,提问作者Juan Zamudio
相关产品推荐
相关产品推荐

