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

如何在Main方法中为NLog.config传入PostgreSQL连接串与日志目录?

在Main方法中传递配置给NLog.Config的正确姿势

看起来你遇到的问题核心是NLog在Main方法中初始化时,还没拿到你在Startup里设置的变量——因为Main是程序的入口点,执行顺序早于Startup,这时候你在Startup里修改的NLog配置变量还没生效,自然会导致Main里的日志输出异常(比如数据库连接失败、日志路径错误之类的)。

下面是具体的解决方案,分两种场景(传统Main方法和.NET 6+顶级语句)来演示:

一、传统.NET Core项目(带Main方法的Program.cs)

你需要在Main方法里先加载应用配置,再初始化NLog并设置变量,确保NLog在创建Logger之前就拿到正确的配置值:

using Microsoft.Extensions.Configuration;
using NLog;
using System.IO;

namespace YourProjectNamespace
{
    public class Program
    {
        public static void Main(string[] args)
        {
            // 第一步:加载应用配置(从appsettings.json)
            var configBuilder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
            
            IConfigurationRoot appConfig = configBuilder.Build();

            // 第二步:加载NLog配置并设置变量
            var nlogConfig = LogManager.LoadConfiguration("nlog.config");
            // 设置PostgreSQL连接字符串变量
            nlogConfig.Variables["connectionString"] = appConfig.GetConnectionString("databaseConnectionString");
            // 设置日志目录变量
            nlogConfig.Variables["configDir"] = appConfig.GetValue<string>("Logging:LogFilePath");
            // 让NLog使用更新后的配置
            LogManager.Configuration = nlogConfig;

            // 现在创建Logger并记录日志,变量已经生效了
            var logger = LogManager.GetCurrentClassLogger();
            logger.Info("Main方法中的日志:连接字符串和日志路径已正确配置!");

            // 第三步:创建并启动WebHost
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                })
                .UseNLog(); // 集成NLog到Host
    }
}

二、.NET 6+ 顶级语句版本的Program.cs

如果你的项目用了.NET 6及以上的顶级语句,代码会更简洁:

using Microsoft.Extensions.Configuration;
using NLog;

var builder = WebApplication.CreateBuilder(args);

// 直接从builder.Configuration读取配置值
var connectionString = builder.Configuration.GetConnectionString("databaseConnectionString");
var logDir = builder.Configuration.GetValue<string>("Logging:LogFilePath");

// 加载并更新NLog配置
var nlogConfig = LogManager.LoadConfiguration("nlog.config");
nlogConfig.Variables["connectionString"] = connectionString;
nlogConfig.Variables["configDir"] = logDir;
LogManager.Configuration = nlogConfig;

// 清除默认日志提供器,添加NLog
builder.Logging.ClearProviders();
builder.Logging.AddNLog();

var app = builder.Build();

// 这里可以添加你的中间件配置...

app.Run();

关键注意事项

  1. 确保NLog.Config中已定义对应变量
    你的nlog.config里需要先声明这些变量,这样即使配置加载失败也有默认值兜底,比如:

    <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        
        <!-- 提前声明变量,设置默认值 -->
        <variable name="connectionString" value="default_connection_string"/>
        <variable name="configDir" value="./logs"/>
    
        <!-- 后续的targets和rules可以直接使用这些变量 -->
        <targets>
            <target xsi:type="Database" name="db"
                    connectionString="${var:connectionString}"
                    ... />
            <target xsi:type="File" name="file"
                    fileName="${var:configDir}/log-${shortdate}.txt"
                    ... />
        </targets>
    </nlog>
    
  2. 避免重复配置
    既然已经在Main/顶级语句里设置了NLog变量,就不需要再在Startup.cs里重复执行LogManager.Configuration.Variables[...]的代码了,否则可能导致配置冲突。

  3. 使用NLog官方集成包
    确保你已经安装了NLog.Web.AspNetCore(ASP.NET Core项目)或者NLog.Extensions.Logging(通用.NET项目),这样NLog才能和.NET的日志系统无缝集成。

内容的提问来源于stack exchange,提问作者Salih H.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:38:34