2014-02-19 5 views
6

Ich versuche, einige Audit-Informationen zu einer SQL Server 2008-Tabelle mit NLog 2 zu protokollieren. Um Parameter an die SQL-einfügen-Abfrage übergeben zu können, verwende ich LogEventInfo und die Event Context Layout Renderer.Protokollieren von datetime mit ms-Genauigkeit mit NLog-Ereigniskontext Layout-Renderer

Die Protokollierung selbst funktioniert, aber die Datetime wird nur mit zweiter Genauigkeit gespeichert. Ich möchte in der Lage sein, mit Millisekunden Genauigkeit zu speichern, habe aber nichts gefunden, was mir zeigt, wie das geht.

Dies ist der C# -Code, wo ich das Ereignisprotokoll:

private void LogMessage(DateTime requestDateTime) 
{ 
    LogEventInfo theEvent = new LogEventInfo(LogLevel.Debug, "", "Pass my custom value"); 
    theEvent.Properties["RequestDate"] = requestDateTime; 
} 

Dies ist das Ziel ich in meiner NLog.config Konfiguration haben:

<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> 

Es gibt eine Abhilfe, die ich gefunden haben, mit theEvent.Properties["RequestDate"] = requestDateTime.ToString("yyyy-MM-dd HH:mm:ss.fff") aber ich würde es vorziehen, dies nicht zu tun, denn dann könnte es zu Problemen bei der Datumsformatierung und Kultur kommen.

Kennt jemand eine Möglichkeit, dass ich die Genauigkeit mit Config in NLog.config ändern kann?

Antwort

1

Es sieht aus wie der EventContextLayoutRenderer verwendet Convert.ToString die die Präzision verlieren Sie suchen:

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)); 
     } 
    } 
} 

Wie Sie wahrscheinlich wissen (und ich bin nicht sicher, ob es in Ihrer Situation hilfreich ist), aber es ist ein Datum Layout, in dem Sie das Format und/oder eine Longdate definieren können, die so etwas wie 2014-01-01 12:12:12.1234

EDIT

Für das, was bieten wird es lohnt sich, Sie

[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 
     } 
    } 
} 

Und in Ihrer Konfiguration

<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> 
+0

Dank Joe sehr leicht einen Kunden Layout-Renderer hinzufügen können. Wenn ich meinen eigenen LayoutRenderer implementiere, verwendet er immer noch einen StringBuilder, um die DateTime als String aufzubauen. Es gibt also keine Möglichkeit, eine tatsächliche DateTime über NLog an SQL zu übergeben. Ich habe Ihre als die Antwort markiert, weil es zumindest eine sauberere Lösung bietet, als die Formatierung im aufrufenden Code durchführen zu müssen. –