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

在Blazor Server中通过DI使用两个配置不同的NLog Logger

在Blazor Server中配置并注入两个独立的NLog Logger(数据库+控制台)

问题背景

需要在Blazor Server应用中使用两个配置不同的NLog Logger:一个将日志写入数据库,另一个输出到控制台,并且通过依赖注入将它们作为独立的ILogger实例在服务中使用。

已有的NLog.config配置片段:

<targets>
    <target name="databaseTarget" xsi:type="Database" dbProvider="Oracle.ManagedDataAccess.Client.OracleConnection, Oracle.ManagedDataAccess" connectionString="${configsetting:name=DatabaseConfiguration.ConnectionString}" commandType="Text">
        <commandText>
            INSERT INTO SCHEMA.LOG ("Timestamp", "Level", "Logger", "Message", "Exception", "User", "CustomData") VALUES (
            TO_TIMESTAMP_TZ(:timestamp, 'YYYY-MM-DD HH24:MI:SS.FF3'), :loglevel, :whichlogger, :message, :whatexception, :userx, :customdata)
        </commandText>
        <parameter name=":timestamp" layout="${date:format=yyyy-MM-dd HH\:mm\:ss.fff}" />
        <parameter name=":loglevel" layout="${level}" />
        <parameter name=":whichlogger" layout="${logger}" />
        <parameter name=":message" layout="${message:raw=true}" />
        <parameter name=":whatexception" layout="${exception:tostring}" />
        <parameter name=":userx" layout="${event-properties:item=userx}" />
        <parameter name=":customdata" layout="${event-properties:item=customdata}" />
    </target>
    <target name="consoleTarget" xsi:type="ColoredConsole" layout="${longdate} ${uppercase:${level}} ${message} ${all-event-properties}" />
</targets>
<extensions>
    <add assembly="NLog.Database"/>
    <add assembly="NLog.Web.AspNetCore"/>
</extensions>
<rules>
    <logger name="DatabaseLogger" minlevel="Trace" writeTo="dataBaseTarget" />
    <logger name="ConsoleLogger" minlevel="Trace" writeTo="consoleTarget" />
</rules>

1. 将两个Logger注册到ServiceCollection

基于你提供的初始化代码,需要扩展配置,创建对应NLog规则名称的Logger实例,并注册到依赖注入容器中。

方法一:使用.NET 8+ 键控服务(Keyed Services)

这种方式直接注册ILogger实例,通过键名区分:

builder.Logging.ClearProviders();
builder.Logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
builder.Host.UseNLog(new NLogAspNetCoreOptions());

// 构建临时服务提供者获取LoggerFactory
var tempProvider = builder.Services.BuildServiceProvider();
var loggerFactory = tempProvider.GetRequiredService<ILoggerFactory>();

// 创建对应NLog配置名称的Logger实例
var databaseLogger = loggerFactory.CreateLogger("DatabaseLogger");
var consoleLogger = loggerFactory.CreateLogger("ConsoleLogger");

// 将Logger注册为键控单例服务
builder.Services.AddKeyedSingleton<ILogger>(databaseLogger, "DatabaseLogger");
builder.Services.AddKeyedSingleton<ILogger>(consoleLogger, "ConsoleLogger");

方法二:使用包装类(兼容.NET 7及以下)

如果你的项目基于.NET 7或更早版本,不支持键控服务,可以通过包装类来区分:

第一步:定义Logger包装类

public class DatabaseLoggerWrapper
{
    public ILogger Logger { get; }
    public DatabaseLoggerWrapper(ILoggerFactory loggerFactory)
    {
        Logger = loggerFactory.CreateLogger("DatabaseLogger");
    }
}

public class ConsoleLoggerWrapper
{
    public ILogger Logger { get; }
    public ConsoleLoggerWrapper(ILoggerFactory loggerFactory)
    {
        Logger = loggerFactory.CreateLogger("ConsoleLogger");
    }
}

第二步:注册包装类到DI容器

builder.Logging.ClearProviders();
builder.Logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
builder.Host.UseNLog(new NLogAspNetCoreOptions());

// 注册包装类
builder.Services.AddScoped<DatabaseLoggerWrapper>();
builder.Services.AddScoped<ConsoleLoggerWrapper>();

2. 在服务中注入并使用Logger

根据你选择的注册方式,对应不同的注入方式:

对应键控服务的注入方式

private readonly ILogger _databaseLogger;
private readonly ILogger _consoleLogger;

// 使用[FromKeyedServices]特性指定要注入的Logger键名
public MyService([FromKeyedServices("DatabaseLogger")] ILogger databaseLogger,
                [FromKeyedServices("ConsoleLogger")] ILogger consoleLogger)
{
    _databaseLogger = databaseLogger;
    _consoleLogger = consoleLogger;

    _databaseLogger.LogInformation("这条日志会写入数据库");
    _consoleLogger.LogInformation("这条日志会输出到控制台");
}

对应包装类的注入方式

private readonly ILogger _databaseLogger;
private readonly ILogger _consoleLogger;

public MyService(DatabaseLoggerWrapper databaseLoggerWrapper, ConsoleLoggerWrapper consoleLoggerWrapper)
{
    _databaseLogger = databaseLoggerWrapper.Logger;
    _consoleLogger = consoleLoggerWrapper.Logger;

    _databaseLogger.LogInformation("这条日志会写入数据库");
    _consoleLogger.LogInformation("这条日志会输出到控制台");
}

内容的提问来源于stack exchange,提问作者To Wa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 19:25:52