C# 使用NLog事件上下文布局渲染器以毫秒精度记录日期时间

C# 使用NLog事件上下文布局渲染器以毫秒精度记录日期时间,c#,sql-server,datetime,nlog,nlog-configuration,C#,Sql Server,Datetime,Nlog,Nlog Configuration,我正在尝试使用NLOG2将一些审核信息记录到SQLServer2008表中。为了能够将参数传递给SQLINSERT查询,我使用了LogEventInfo和 日志记录本身可以工作,但日期时间仅以秒精度存储。我希望能够以毫秒的精度进行存储,但还没有找到任何东西告诉我如何做到这一点 这是我记录事件的C代码: private void LogMessage(DateTime requestDateTime) { LogEventInfo theEvent = new LogEventInfo(L

我正在尝试使用NLOG2将一些审核信息记录到SQLServer2008表中。为了能够将参数传递给SQLINSERT查询,我使用了LogEventInfo和

日志记录本身可以工作,但日期时间仅以秒精度存储。我希望能够以毫秒的精度进行存储,但还没有找到任何东西告诉我如何做到这一点

这是我记录事件的C代码:

private void LogMessage(DateTime requestDateTime)
{
    LogEventInfo theEvent = new LogEventInfo(LogLevel.Debug, "", "Pass my custom value");
    theEvent.Properties["RequestDate"] = requestDateTime;
}
这是我在NLog.config配置中的目标:

<target xsi:type="Database"
      name="SqlLog"
      dbProvider="sqlserver"
      connectionString="server=localhost;database=Test;integrated security=sspi">
  <commandText>
    INSERT [dbo].[ApiLog]
    (
        [ServerName], [RequestDate]
    )
    VALUES (@ServerName, @RequestDate);
  </commandText>
  <parameter name="@ServerName" layout="${machinename}"/>
  <parameter name="@RequestDate" layout="${event-context:item=RequestDate}"/>
</target>

插入[dbo].[ApiLog]
(
[ServerName],[RequestDate]
)
值(@ServerName,@RequestDate);
我发现使用
event.Properties[“RequestDate”]=requestDateTime.ToString(“yyyy-MM-dd HH:MM:ss.fff”)
可以找到一种变通方法,但我不希望这样做,因为这样您可能会遇到日期时间格式和区域性方面的问题


有人知道我可以用NLog.config中的config更改精度的方法吗?

看起来EventContextLayoutRenderer使用的是
Convert.ToString
,这将失去您想要的精度:

public class EventContextLayoutRenderer : LayoutRenderer
{
    //....

    protected override void Append(StringBuilder builder, LogEventInfo logEvent)
    {
        object value;

        if (logEvent.Properties.TryGetValue(this.Item, out value))
        {
            builder.Append(Convert.ToString(value, CultureInfo.InvariantCulture));
        }
    }
}
正如您可能知道的(我不确定它是否对您的情况有帮助),但是有一个日期布局,您可以在其中指定格式和/或LongDate格式,它将提供类似于
2014-01-01 12:12:12.1234

编辑

值得一提的是,您可以非常轻松地添加客户布局渲染器

[LayoutRenderer("event-context-dateTime")]
public class DateTimeContextLayoutRenderer : EventContextLayoutRenderer
{
    protected override void Append(StringBuilder builder, LogEventInfo logEvent)
    {
        object value;

        if (logEvent.Properties.TryGetValue(this.Item, out value))
        {
            //Your code here
        }
    }
}
在您的配置中

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <extensions>
    <add assembly="YourAssembly"/>
  </extensions>
  <targets>
    <target xsi:type="File" name="file"  fileName="c:\temp\NlogLayout.txt" 
     layout="${longdate} ${event-context-dateTime:item=RequestDate}" />
   ...
</nlog>

...

谢谢你,乔。如果我实现自己的LayoutRenderer,那么它仍然使用StringBuilder将日期时间构建为字符串。因此,无法通过NLog将实际日期时间传递到SQL中。我将您的标记为答案,因为它至少提供了一个比必须在调用代码中执行格式化更干净的解决方案。