You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 5中注入不同配置EventLog日志记录器的方法

ASP.NET Core 5 按类型配置Windows EventLog日志实现方案

首先需要提前引入官方NuGet包Microsoft.Extensions.Logging.EventLog,所有涉及自定义编码的部分总代码量不超过50行,支持配置化扩展。


问题1:按注入的ILogger泛型类型自动设置EventLog的Source字段

默认的EventLog日志提供程序会使用统一的Source名称,要实现ILogger<X>对应Source为"X"、ILogger<Y>对应Source为"Y"的效果,只需要实现一个极轻量的自定义日志提供程序,核心逻辑是利用ILogger<T>自带的类别名(即泛型类型T的完全限定名)自动匹配Source:

public class PerTypeEventLogLoggerProvider : ILoggerProvider
{
    private readonly ConcurrentDictionary<string, EventLogLogger> _loggerCache = new();
    private readonly EventLogSettings _globalSettings;

    public PerTypeEventLogLoggerProvider(IOptions<EventLogSettings> globalSettings)
    {
        _globalSettings = globalSettings.Value;
    }

    public ILogger CreateLogger(string categoryName)
    {
        return _loggerCache.GetOrAdd(categoryName, cat =>
        {
            // 取类型名(去掉命名空间)作为默认Source
            var typeShortName = cat.Split('.').Last();
            var perTypeSettings = new EventLogSettings
            {
                LogName = _globalSettings.LogName,
                MachineName = _globalSettings.MachineName,
                Filter = _globalSettings.Filter,
                SourceName = typeShortName
            };
            return new EventLogLogger(typeShortName, Options.Create(perTypeSettings));
        });
    }

    public void Dispose() => _loggerCache.Clear();
}

注册时替换默认的EventLog提供程序即可:

// Program.cs 或 Startup.cs 的ConfigureLogging方法中
logging.ClearProviders(); // 可选,清理不需要的默认提供程序
logging.AddProvider(new PerTypeEventLogLoggerProvider(
    Options.Create(new EventLogSettings { LogName = "Application" })));
  • 注意:自定义Source首次创建需要管理员权限运行一次应用,Windows会自动完成Source注册,后续普通权限运行即可正常写入。

问题2:实现不同类型Logger写入完全独立的Windows EventLog

只需要修改上面自定义提供程序中perTypeSettings的LogName属性,将其和SourceName保持一致(或按需求自定义)即可:

var perTypeSettings = new EventLogSettings
{
    LogName = typeShortName, // 用类型名作为独立日志名
    SourceName = typeShortName,
    MachineName = _globalSettings.MachineName,
    Filter = _globalSettings.Filter
};

配置完成后,ILogger<X>写入的日志会全部存到Windows事件查看器中名为"X"的独立日志节点下,ILogger<Y>写入"Y"节点,完全不需要靠Source字段做区分。自定义日志首次创建同样需要管理员权限执行一次。


问题3:基于appsettings.json的可配置化实现

完全可以把所有映射规则、日志级别等配置放到appsettings.json中,仅保留上述轻量提供程序作为通用适配层,后续新增、修改规则不需要重新编译代码。
首先在appsettings.json的Logging节点添加配置:

{
  "Logging": {
    "PerTypeEventLog": {
      "DefaultLogName": "Application",
      "DefaultSource": "MyAppDefault",
      "LogLevel": {
        "Default": "Information",
        "Microsoft.AspNetCore": "Warning"
      },
      "TypeMappings": {
        "X": {
          "SourceName": "X_BizService",
          "LogName": "X_ServiceLog"
        },
        "Y": {
          "SourceName": "Y_HomeController",
          "LogName": "Y_ControllerLog"
        }
      }
    }
  }
}

然后创建对应的强类型配置类,修改自定义提供程序的逻辑:优先从TypeMappings节点读取对应类型的配置,没有匹配配置的类型就使用默认值即可。
如果不想编写自定义提供程序代码,也可以直接使用Serilog等第三方日志框架,其EventLog扩展原生支持按日志上下文(SourceContext属性,即ILogger的泛型类型)动态配置输出目标和字段,配置灵活度更高,但上述原生实现已经足够满足需求,不需要额外引入第三方依赖。


内容的提问来源于stack exchange,提问作者Mulciber Coder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 12:03:17