C#中Serilog日志@t时间戳时区设置问题(TimeWrap已弃用)
解决Serilog CompactJsonFormatter时间戳时区问题(替代已弃用的TimeWrap)
嘿,我之前也碰到过这个问题——CompactJsonFormatter默认输出UTC+0的@t时间戳,而且老的TimeWrap方法已经不能用了。这里有两个靠谱的方案帮你把时间戳改成目标时区:
方案1:通过Enricher调整日志事件的时间戳
你可以在日志配置里,通过WithTimestamp指定自定义的时间戳生成逻辑,直接把UTC时间转换为目标时区的DateTimeOffset:
// 先获取你需要的目标时区,比如中国标准时间(UTC+8) var targetTimeZone = TimeZoneInfo.FindSystemTimeZoneById("China Standard Time"); Log.Logger = new LoggerConfiguration() // 替换默认的UTC时间戳为目标时区时间 .Enrich.WithTimestamp(() => TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, targetTimeZone)) .WriteTo.File(new CompactJsonFormatter(), "app-logs.json") .CreateLogger();
小贴士:可以通过
TimeZoneInfo.GetSystemTimeZones()枚举系统支持的时区ID,比如美国东部时区是"Eastern Standard Time",欧洲中部是"Central European Standard Time"。
方案2:自定义CompactJsonFormatter子类
如果需要更灵活的控制(比如不想修改全局日志事件的时间戳,只在格式化输出时转换),可以继承CompactJsonFormatter并重写时间戳的处理逻辑:
public class TimeZoneAwareCompactJsonFormatter : CompactJsonFormatter { private readonly TimeZoneInfo _targetTimeZone; public TimeZoneAwareCompactJsonFormatter(TimeZoneInfo targetTimeZone) { _targetTimeZone = targetTimeZone ?? throw new ArgumentNullException(nameof(targetTimeZone)); } protected override void WriteEvent(TextWriter output, LogEvent logEvent) { // 将原始UTC时间戳转换为目标时区的DateTimeOffset var localDateTime = TimeZoneInfo.ConvertTimeFromUtc(logEvent.Timestamp.UtcDateTime, _targetTimeZone); var adjustedTimestamp = new DateTimeOffset(localDateTime, _targetTimeZone.GetUtcOffset(localDateTime)); // 创建一个调整了时间戳的新日志事件 var adjustedLogEvent = new LogEvent( adjustedTimestamp, logEvent.Level, logEvent.Exception, logEvent.MessageTemplate, logEvent.Properties.Select(p => new LogEventProperty(p.Key, p.Value)) ); // 调用父类方法输出调整后的事件 base.WriteEvent(output, adjustedLogEvent); } }
使用这个自定义格式化器的方式很简单:
var targetTimeZone = TimeZoneInfo.FindSystemTimeZoneById("China Standard Time"); Log.Logger = new LoggerConfiguration() .WriteTo.File(new TimeZoneAwareCompactJsonFormatter(targetTimeZone), "app-logs.json") .CreateLogger();
两种方案都能让你的@t字段输出带正确时区偏移的时间戳,比如"2020-02-19T21:34:55.6398202+08:00"(对应你示例中的UTC时间转换为UTC+8后的结果)。
内容的提问来源于stack exchange,提问作者Marco Polato
相关产品推荐
相关产品推荐

