是否可以将输出模板中的时间戳记为 DateTimeKind.Utc?

Is it possible to get Timestamp in output template as DateTimeKind.Utc?

目前,当我在 outputTemplate 中使用 {Timestamp} 时,它似乎是由 DateTime.Now 生成的,因此具有 DateTimeKind.Local 风格,因为当我给它一个 "o" 说明符它产生类似于 2016-02-12T09:51:34.4477761-08:00

的输出

对于上面的例子,我想得到的是 2016-02-12T17:51:34.4477761Z,如果 TimestampDateTimeKind.Utc

更新

看起来它实际上是 DateTimeOffset that gets instantiated there so no DateTimeKind is in effect, rather it looks like underlying DateTime is always of DateTimeKind.Unspecified. MSDN 注意到格式化 DateTimeOffsetDateTime 时在行为上存在一些差异,特别是:

"u" -- Converts the DateTimeOffset value to UTC and outputs it using the format yyyy-MM-dd HH:mm:ssZ.

转换正是我想要的,但我还需要分数。

看来 DateTimeOffset 格式的限制会阻碍这一点。

另一种方法(只要额外的 属性 不会在其他地方膨胀输出)是向管道添加 Serilog ILogEventEnricher

class UtcTimestampEnricher : ILogEventEnricher {
  public void Enrich(LogEvent logEvent, ILogEventPropertyFactory lepf) {
    logEvent.AddPropertyIfAbsent(
      lepf.CreateProperty("UtcTimestamp", logEvent.Timestamp.UtcDateTime));
  }
}

然后您可以在输出模板中使用 {UtcTimestamp:o} 来获取您需要的值。

Serilog.Expressions 现在支持将 DateTimeOffset 格式化为 UTC,无需任何额外的改进:

    // dotnet add package serilog.expressions
    .WriteTo.Console(new ExpressionTemplate(
        "[{UtcDateTime(@t):o} {@l:u3}] {@m}\n{@x}",
        theme: TemplateTheme.Code))

请注意,时间戳 属性 现在是 @t,而不是 Timestamp