如何按日志所在类拆分Serilog日志输出至对应独立文件?
动态为脚本类生成独立日志文件的Serilog配置方案
核心思路
不用提前给每个脚本手动配置日志接收器,而是利用Serilog的日志上下文属性+动态路径占位符,让脚本运行时带上专属标识,自动把日志路由到对应的数据文件夹里。
具体实现步骤
更新全局Serilog配置
首先要启用日志上下文,然后添加一个带过滤的文件接收器,用占位符动态生成日志文件路径。完整配置代码如下:Log.Logger = new LoggerConfiguration() .Enrich.FromLogContext() // 必须加这个,才能让上下文属性生效 .WriteTo.File("./Logs/Log-.log", rollingInterval: RollingInterval.Day, outputTemplate: "{Timestamp:HH:mm:ss.fff} [{Level:u3}] {Message}{NewLine}{Exception}") .WriteTo.Debug() .WriteTo.Console() // 脚本专属日志输出配置 .WriteTo.Logger(lc => lc .Filter.ByIncludingOnly(Matching.WithProperty("ScriptName")) // 只处理带ScriptName属性的日志 .WriteTo.File("./Scripts/{ScriptName}/Logs/Log-.log", rollingInterval: RollingInterval.Day, outputTemplate: "{Timestamp:HH:mm:ss.fff} [{Level:u3}] {Message}{NewLine}{Exception}")) .MinimumLevel.Debug() .CreateLogger();在脚本执行时注入上下文属性
当你动态加载并运行脚本类时,在执行逻辑外面套一个LogContext.PushProperty的using块,把当前脚本的类名(或者你用来命名数据文件夹的标识)传进去:// 假设scriptInstance是你动态加载的脚本类实例 var scriptIdentifier = scriptInstance.GetType().Name; // 用类名做标识,对应数据文件夹名称 using (LogContext.PushProperty("ScriptName", scriptIdentifier)) { // 这里执行脚本的核心逻辑 scriptInstance.Run(); // 比如脚本里的Log.Information("Finished task #1...")会自动输出到对应文件夹的日志里 }
关键细节
- Serilog会自动创建
./Scripts/{ScriptName}/Logs这类不存在的目录,不用手动写创建文件夹的代码。 - 如果你的数据文件夹不是用类名命名的,把
ScriptName换成你实际用的文件夹标识(比如ScriptDataDir),同时修改日志路径里的占位符就行。 - using块能确保这个上下文属性只作用于当前脚本的执行周期,不会和其他脚本的日志混在一起。
内容的提问来源于stack exchange,提问作者NinjaPedroX
相关产品推荐
相关产品推荐

