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

如何根据IIS上下文配置Serilog实现不同日志输出目标?

实现Serilog按IIS/非IIS环境切换日志输出

要实现IIS环境下仅写入文件、其他环境仅输出到控制台的需求,你可以通过动态检测运行环境,再针对性配置Serilog的Sink来实现,具体步骤如下:

1. 添加环境检测方法

在Program类中添加一个辅助方法,用于判断应用是否运行在IIS上下文:

private static bool IsRunningInIis()
{
    // 检测两种典型IIS进程,或IIS集成环境变量
    var currentProcess = System.Diagnostics.Process.GetCurrentProcess().ProcessName;
    bool isIisProcess = currentProcess.Equals("w3wp", StringComparison.OrdinalIgnoreCase) || 
                        currentProcess.Equals("iisexpress", StringComparison.OrdinalIgnoreCase);
    
    bool hasIisEnvVar = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("ASPNETCORE_IIS_INTEGRATION_ENABLED"));

    return isIisProcess || hasIisEnvVar;
}

2. 修改Serilog配置逻辑

不再直接从配置文件加载所有日志输出目标,而是先加载基础配置(日志级别、增强器等),再根据环境动态添加对应的Sink:

修改Main方法中的Serilog初始化代码:

public static void Main(string[] args)
{
    Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
    Config.Load();

    // 初始化基础日志配置(级别、增强器、全局属性等)
    var loggerConfig = new LoggerConfiguration()
        .ReadFrom.Configuration(Configuration)
        .Filter.ByExcluding("RequestPath in ['/healthcheck', '/favicon.ico']");

    // 清空配置文件中预定义的WriteTo节点,避免重复输出
    loggerConfig = loggerConfig.WriteTo.Clear();

    bool isRunningInIis = IsRunningInIis();

    if (isRunningInIis)
    {
        // 从配置文件读取文件Sink参数并添加
        var fileSinkSettings = Configuration.GetSection("Serilog:WriteTo")
            .GetChildren()
            .FirstOrDefault(s => s.GetValue<string>("Name") == "File");
        
        if (fileSinkSettings != null)
        {
            var args = fileSinkSettings.GetSection("Args").Get<Dictionary<string, object>>();
            loggerConfig = loggerConfig.WriteTo.File(
                outputTemplate: args["outputTemplate"].ToString(),
                path: args["path"].ToString(),
                rollingInterval: (RollingInterval)Enum.Parse(typeof(RollingInterval), args["rollingInterval"].ToString())
            );
        }
    }
    else
    {
        // 从配置文件读取控制台Sink参数并添加
        var consoleSinkSettings = Configuration.GetSection("Serilog:WriteTo")
            .GetChildren()
            .FirstOrDefault(s => s.GetValue<string>("Name") == "Console");
        
        if (consoleSinkSettings != null)
        {
            var args = consoleSinkSettings.GetSection("Args").Get<Dictionary<string, object>>();
            loggerConfig = loggerConfig.WriteTo.Console(
                outputTemplate: args["outputTemplate"].ToString()
            );
        }
    }

    Log.Logger = loggerConfig.CreateLogger();

    // 后续主机构建逻辑保持不变
    var host = Host.CreateDefaultBuilder(args)
        .UseSerilog()
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.ConfigureKestrel((context, options) =>
            {
                options.Limits.MaxRequestBodySize = Config.MaxRequestSize;
            })
            .UseIISIntegration()
            .UseStartup<Startup>()
            .CaptureStartupErrors(true);
        }).Build();

    var logger = host.Services.GetRequiredService<ILogger<ReverseProxyModule>>();
    ReverseProxyModule.InitializeConcurrentRequestLogging(logger);

    host.Run();
}

3. 保留原配置文件内容

你的appsettings.json无需修改,其中的WriteTo节点仅作为参数来源,不会直接生效(因为我们用WriteTo.Clear()清空了预配置的输出目标)。

关键说明

  • 环境检测逻辑覆盖了正式IIS(w3wp.exe)和IIS Express开发环境,同时通过环境变量兜底,确保检测准确性。
  • 从配置文件读取Sink参数的方式,让你仍能通过配置文件灵活调整输出模板、日志路径等细节,无需硬编码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 17:16:12