如何将域名作为Serilog日志文件名的组成部分?
解决方案
针对你在IIS中多站点共享物理目录、需将域名纳入Serilog日志文件名的场景,提供两种可行方案:
方案一:利用IIS站点环境变量(支持启动阶段日志)
该方案无需依赖请求上下文,启动时即可获取站点标识,能覆盖所有日志场景(包括应用启动时的初始化日志)。
实现步骤
- 在
SerilogConfig.Configure方法中,读取IIS自动注入的站点环境变量:
public static void Configure(IServiceCollection serviceCollection, IConfiguration configuration) { // 原有配置代码... // 获取IIS站点名称(IIS托管时自动注入的环境变量) var iisSiteName = Environment.GetEnvironmentVariable("ASPNETCORE_IIS_SITE_NAME"); var siteDomain = string.IsNullOrEmpty(iisSiteName) ? "unknown" : iisSiteName.Split('.').Length >= 2 ? iisSiteName.Split('.')[1] : iisSiteName; // 注:可根据你IIS站点的命名规则调整域名提取逻辑,比如站点名称直接设为site1/site2则无需拆分 // 构造包含域名的日志文件名 var appLogName = $"{appName}-{deploymentMode.ToLower()}-{siteDomain}"; var detailedLogFile = Path.Combine(baseLogPath, $"{appLogName}-{DateTime.Now:yyyy-MM-dd}.log"); // 后续Serilog配置代码... }
- 配置说明:
ASPNETCORE_IIS_SITE_NAME是IIS托管ASP.NET Core应用时自动设置的环境变量,值为你在IIS中创建的站点名称;- 若你的IIS站点名称直接使用
site1/site2,可直接跳过域名拆分逻辑,直接使用iisSiteName作为标识。
方案二:通过请求上下文获取域名(仅支持请求相关日志)
该方案严格基于用户请求的域名生成日志文件,但应用启动阶段的日志(无请求上下文)会归入默认标识文件。
实现步骤
- 注册HttpContextAccessor(用于获取请求上下文):
在Startup.cs的ConfigureServices中添加:
services.AddHttpContextAccessor();
- 创建日志属性增强器,提取请求域名:
public class SiteDomainEnricher : ILogEventEnricher { private readonly IHttpContextAccessor _httpContextAccessor; public SiteDomainEnricher(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) { var host = _httpContextAccessor.HttpContext?.Request.Host.Host; // 提取域名中的site1/site2部分,可根据实际域名调整拆分规则 var siteDomain = string.IsNullOrEmpty(host) ? "unknown" : host.Split('.').Length >= 2 ? host.Split('.')[1] : host; logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("SiteDomain", siteDomain)); } }
- 修改Serilog配置,按域名分文件输出:
先安装Serilog.Sinks.Map包,再在SerilogConfig.Configure中配置:
public static void Configure(IServiceCollection serviceCollection, IConfiguration configuration) { // 原有配置代码... // 注册域名增强器 serviceCollection.AddSingleton<ILogEventEnricher, SiteDomainEnricher>(); var loggerConfig = new LoggerConfiguration() .ReadFrom.Configuration(configuration) .Enrich.FromLogContext() .Enrich.With<SiteDomainEnricher>() // 按SiteDomain属性映射到不同日志文件 .WriteTo.Map( keyPropertyName: "SiteDomain", defaultKey: "unknown", (domain, writeTo) => writeTo.File( path: Path.Combine(baseLogPath, $"{appName}-{deploymentMode.ToLower()}-{domain}-{DateTime.Now:yyyy-MM-dd}.log"), outputTemplate: outputTemplate ) ) // 保留原有Rollbar配置 .WriteTo.Rollbar(rollbarAccessToken); Log.Logger = loggerConfig.CreateLogger(); }
注意事项
- 方案一适合需要区分启动日志的场景,依赖IIS站点名称的命名规范;
- 方案二更贴合实际请求域名,但启动阶段日志会进入
unknown文件; - 始终使用
Path.Combine拼接日志路径,避免因系统分隔符差异导致的路径错误; - 确保IIS应用程序池拥有日志目录的写入权限。
内容的提问来源于stack exchange,提问作者Sebastian
相关产品推荐
相关产品推荐

