Serilog WriteTo.Conditional在Azure函数中无日志输出求助
问题描述
开发基于.NET 6.0独立版的C# HTTP触发Azure函数,尝试通过Serilog将日志输出到控制台、文件、两个数据库表这多个目标。单独测试WriteTo.Console、WriteTo.File、WriteTo.MSSqlServer均正常,但使用WriteTo.Conditional按日志级别配置条件输出后,所有目标均无日志输出。已开启Serilog Self Log但未捕获到任何信息。
相关代码如下:
Program.cs配置
var logger = new LoggerConfiguration() .MinimumLevel.Debug() .WriteTo.Conditional( ev => { bool isDebug = ev.Equals(LogEventLevel.Debug); if (isDebug) { return true; } return false; }, wt => wt .Console() ) .WriteTo.Conditional( ev => { bool isDebug = ev.Equals(LogEventLevel.Debug); if (isDebug) { return true; } return false; }, wt => wt .File("log.txt") ) .WriteTo.Conditional( ev => { bool isInformation = ev.Equals(LogEventLevel.Information); if (isInformation) { return true; } return false; }, wt => wt .MSSqlServer( connectionString: dbConnection, sinkOptions: sinkOptsHead, columnOptions: columnOptsHead ) ) .WriteTo.Conditional( ev => { bool isWarning = ev.Equals(LogEventLevel.Warning); if (isWarning) { return true; } return false; }, wt => wt .MSSqlServer( connectionString: dbConnection, sinkOptions: sinkOptsDetails, columnOptions: columnOptsDetails ) ) .CreateLogger();
Serilog Self Log配置
Serilog.Debugging.SelfLog.Enable(msg => { Debug.Print(msg); Debugger.Break(); });
函数内日志调用代码
logger.LogDebug("C# HTTP trigger function processed a request."); logger.LogInformation("{GLOBAL_UUID}{USE_CASE}{ORDER_STATUS}{TIMESTAMP}", guid, useCase, orderStatus, DateTime.Now); logger.LogWarning("{GLOBAL_UUID}{USE_CASE}{REQUEST_UUID}{SERVICE}{END_SYSTEM}{STATE}{PAYLOAD}{TIMESTAMP}{LEVEL_TYPE}", guid, useCase, Guid.NewGuid(), service, context.GetType, orderStatus, req.Body, DateTime.Now, levelType);
解决思路
核心问题在于WriteTo.Conditional的条件判断逻辑错误:
Conditional委托的参数ev是**LogEvent对象**,不是LogEventLevel枚举值。直接用ev.Equals(LogEventLevel.Debug)做判断,永远会返回false,导致所有条件分支都不触发日志输出。
修改方法是通过LogEvent的Level属性来判断日志级别,修正后的配置代码如下:
var logger = new LoggerConfiguration() .MinimumLevel.Debug() .WriteTo.Conditional( ev => ev.Level == LogEventLevel.Debug, wt => wt.Console() ) .WriteTo.Conditional( ev => ev.Level == LogEventLevel.Debug, wt => wt.File("log.txt") ) .WriteTo.Conditional( ev => ev.Level == LogEventLevel.Information, wt => wt.MSSqlServer( connectionString: dbConnection, sinkOptions: sinkOptsHead, columnOptions: columnOptsHead ) ) .WriteTo.Conditional( ev => ev.Level == LogEventLevel.Warning, wt => wt.MSSqlServer( connectionString: dbConnection, sinkOptions: sinkOptsDetails, columnOptions: columnOptsDetails ) ) .CreateLogger();
额外优化建议:
- 合并相同级别的条件输出,减少重复代码:比如将Debug级别的控制台和文件输出放在同一个
Conditional中,通过Sink组合多个目标
.WriteTo.Conditional( ev => ev.Level == LogEventLevel.Debug, wt => wt.Sink(new ConsoleSink()) .Sink(new FileSink("log.txt", new JsonFormatter())) )
- 确保Azure函数的文件输出路径有效:可以使用函数根目录路径避免权限问题
var logFilePath = Path.Combine(Environment.GetEnvironmentVariable("HOME") ?? "", "log.txt"); // 将logFilePath传入WriteTo.File
内容的提问来源于stack exchange,提问作者user3120487
相关产品推荐
相关产品推荐

