无需MessageFormat的Serilog日志优化写法问询
结构化日志匿名对象传参方案
针对你想要用匿名对象直接传递日志字段的需求,主流日志框架都有对应的实现方式,以下是具体方案:
1. Serilog(最贴合需求)
Serilog原生支持匿名对象的结构化日志输出,无需额外扩展:
// 初始化Serilog(示例配置) Log.Logger = new LoggerConfiguration() .Enrich.FromLogContext() .WriteTo.Console(new JsonFormatter()) // 输出JSON格式日志 .CreateLogger(); // 日志调用 Log.Information("{@Event}", new { action = "my_action", state = "my_state" });
输出的JSON日志会自动包含timestamp(可通过配置调整格式),以及匿名对象的所有字段,完全符合你想要的格式。
2. Microsoft.Extensions.Logging(ASP.NET Core默认日志)
默认日志框架可通过自定义扩展方法实现匿名对象传参,或利用结构化日志特性:
方法一:自定义扩展方法
public static class LoggerExtensions { public static void LogStructured(this ILogger logger, LogLevel level, object properties) { var props = properties.GetType().GetProperties() .ToDictionary(p => p.Name, p => p.GetValue(properties)); logger.Log(level, "Structured log event", props); } } // 调用示例 logger.LogStructured(LogLevel.Information, new { action = "my_action", state = "my_state" });
方法二:原生结构化日志写法(避免键值脱节)
虽然不是直接传匿名对象,但可以把键值写在一起,同样清晰:
logger.LogInformation("Action: {Action}, State: {State}", "my_action", "my_state");
配合JSON格式的日志输出配置(如使用Microsoft.Extensions.Logging.Json),也能得到你需要的结构化输出。
3. NLog
NLog同样支持匿名对象的结构化日志,配置JSON目标即可输出对应格式:
// NLog配置文件中添加JSON目标(示例) <target name="jsonFile" xsi:type="File" fileName="logs/json.log"> <layout xsi:type="JsonLayout"> <attribute name="timestamp" layout="${longdate}" /> <attribute name="action" layout="${event-properties:action}" /> <attribute name="state" layout="${event-properties:state}" /> </layout> </target> // 日志调用 logger.Info("{@Event}", new { action = "my_action", state = "my_state" });
以上方案都能解决键值脱节的问题,让日志字段和值保持对应,代码更易维护。
内容的提问来源于stack exchange,提问作者Adam Straughan
相关产品推荐
相关产品推荐

