Einige davon fallen eher in die Kategorie der allgemeinen NLog- (oder Protokollierungs-) Tipps als in reine Konfigurationsvorschläge.
Hier sind einige allgemeine Protokollierungslinks von hier bei SO (möglicherweise haben Sie einige oder alle bereits gesehen):
log4net vs. Nlog
Best Practices für die Protokollierung
Was bringt eine Holzfassade?
Warum empfehlen Logger die Verwendung eines Loggers pro Klasse?
Verwenden Sie das allgemeine Muster für die Benennung Ihres Loggers basierend auf der Klasse Logger logger = LogManager.GetCurrentClassLogger()
. Dies gibt Ihnen ein hohes Maß an Granularität in Ihren Loggern und bietet Ihnen große Flexibilität bei der Konfiguration der Logger (Steuerung global, nach Namespace, nach spezifischem Loggernamen usw.).
Verwenden Sie gegebenenfalls nicht auf Klassennamen basierende Logger. Möglicherweise haben Sie eine Funktion, für die Sie die Protokollierung wirklich separat steuern möchten. Möglicherweise haben Sie einige Probleme mit der Protokollierung (Leistungsprotokollierung).
Wenn Sie keine auf Klassennamen basierende Protokollierung verwenden, sollten Sie Ihre Protokollierer in einer hierarchischen Struktur (möglicherweise nach Funktionsbereich) benennen, damit Sie Ihre Konfiguration flexibler gestalten können. Beispielsweise könnten Sie einen Funktionsbereich "Datenbank", einen FA "Analyse" und einen FA "UI" haben. Jeder von diesen kann Unterbereiche haben. Sie können also folgende Logger anfordern:
Logger logger = LogManager.GetLogger("Database.Connect");
Logger logger = LogManager.GetLogger("Database.Query");
Logger logger = LogManager.GetLogger("Database.SQL");
Logger logger = LogManager.GetLogger("Analysis.Financial");
Logger logger = LogManager.GetLogger("Analysis.Personnel");
Logger logger = LogManager.GetLogger("Analysis.Inventory");
Und so weiter. Mit hierarchischen Protokollierern können Sie die Protokollierung global ("*" oder Root-Protokollierer), nach FA (Datenbank, Analyse, Benutzeroberfläche) oder nach Unterbereich (Database.Connect usw.) konfigurieren.
Logger haben viele Konfigurationsoptionen:
<logger name="Name.Space.Class1" minlevel="Debug" writeTo="f1" />
<logger name="Name.Space.Class1" levels="Debug,Error" writeTo="f1" />
<logger name="Name.Space.*" writeTo="f3,f4" />
<logger name="Name.Space.*" minlevel="Debug" maxlevel="Error" final="true" />
Weitere Informationen dazu, was die einzelnen Optionen bedeuten, finden Sie in der NLog-Hilfe . Die wahrscheinlich bemerkenswertesten Elemente sind die Möglichkeit, Protokollierungsregeln mit Platzhaltern zu versehen, das Konzept, dass mehrere Protokollierungsregeln für eine einzelne Protokollierungsanweisung "ausgeführt" werden können und dass eine Protokollierungsregel als "endgültig" markiert werden kann, sodass nachfolgende Regeln für a nicht ausgeführt werden Protokollierungsanweisung gegeben.
Verwenden Sie GlobalDiagnosticContext, MappedDiagnosticContext und NestedDiagnosticContext, um Ihrer Ausgabe zusätzlichen Kontext hinzuzufügen.
Verwenden Sie zur Vereinfachung "Variable" in Ihrer Konfigurationsdatei. Beispielsweise können Sie Variablen für Ihre Layouts definieren und dann auf die Variable in der Zielkonfiguration verweisen, anstatt das Layout direkt anzugeben.
<variable name="brief" value="${longdate} | ${level} | ${logger} | ${message}"/>
<variable name="verbose" value="${longdate} | ${machinename} | ${processid} | ${processname} | ${level} | ${logger} | ${message}"/>
<targets>
<target name="file" xsi:type="File" layout="${verbose}" fileName="${basedir}/${shortdate}.log" />
<target name="console" xsi:type="ColoredConsole" layout="${brief}" />
</targets>
Sie können auch einen "benutzerdefinierten" Satz von Eigenschaften erstellen, um ihn einem Layout hinzuzufügen.
<variable name="mycontext" value="${gdc:item=appname} , ${mdc:item=threadprop}"/>
<variable name="fmt1withcontext" value="${longdate} | ${level} | ${logger} | [${mycontext}] |${message}"/>
<variable name="fmt2withcontext" value="${shortdate} | ${level} | ${logger} | [${mycontext}] |${message}"/>
Oder Sie können beispielsweise "Tag" - oder "Monat" -Layout-Renderer ausschließlich über die Konfiguration erstellen:
<variable name="day" value="${date:format=dddd}"/>
<variable name="month" value="${date:format=MMMM}"/>
<variable name="fmt" value="${longdate} | ${level} | ${logger} | ${day} | ${month} | ${message}"/>
<targets>
<target name="console" xsi:type="ColoredConsole" layout="${fmt}" />
</targets>
Sie können auch Layout-Renderings verwenden, um Ihren Dateinamen zu definieren:
<variable name="day" value="${date:format=dddd}"/>
<targets>
<target name="file" xsi:type="File" layout="${verbose}" fileName="${basedir}/${day}.log" />
</targets>
Wenn Sie Ihre Datei täglich rollen, kann jede Datei den Namen "Monday.log", "Tuesday.log" usw. haben.
Haben Sie keine Angst, Ihren eigenen Layout-Renderer zu schreiben. Es ist einfach und ermöglicht es Ihnen, Ihre eigenen Kontextinformationen über die Konfiguration zur Protokolldatei hinzuzufügen. Hier ist beispielsweise ein Layout-Renderer (basierend auf NLog 1.x, nicht 2.0), der die Trace.CorrelationManager.ActivityId zum Protokoll hinzufügen kann:
[LayoutRenderer("ActivityId")]
class ActivityIdLayoutRenderer : LayoutRenderer
{
int estimatedSize = Guid.Empty.ToString().Length;
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
{
builder.Append(Trace.CorrelationManager.ActivityId);
}
protected override int GetEstimatedBufferSize(LogEventInfo logEvent)
{
return estimatedSize;
}
}
Teilen Sie NLog mit, wo Ihre NLog-Erweiterungen (welche Assembly) folgendermaßen aussehen:
<extensions>
<add assembly="MyNLogExtensions"/>
</extensions>
Verwenden Sie den benutzerdefinierten Layout-Renderer wie folgt:
<variable name="fmt" value="${longdate} | ${ActivityId} | ${message}"/>
Verwenden Sie asynchrone Ziele:
<nlog>
<targets async="true">
<!-- all targets in this section will automatically be asynchronous -->
</targets>
</nlog>
Und Standard-Ziel-Wrapper:
<nlog>
<targets>
<default-wrapper xsi:type="BufferingWrapper" bufferSize="100"/>
<target name="f1" xsi:type="File" fileName="f1.txt"/>
<target name="f2" xsi:type="File" fileName="f2.txt"/>
</targets>
<targets>
<default-wrapper xsi:type="AsyncWrapper">
<wrapper xsi:type="RetryingWrapper"/>
</default-wrapper>
<target name="n1" xsi:type="Network" address="tcp://localhost:4001"/>
<target name="n2" xsi:type="Network" address="tcp://localhost:4002"/>
<target name="n3" xsi:type="Network" address="tcp://localhost:4003"/>
</targets>
</nlog>
gegebenenfalls. Weitere Informationen hierzu finden Sie in den NLog-Dokumenten.
Weisen Sie NLog an, die Konfiguration zu überwachen und automatisch neu zu laden, wenn sie sich ändert:
<nlog autoReload="true" />
Es gibt verschiedene Konfigurationsoptionen, die bei der Fehlerbehebung bei NLog helfen
<nlog throwExceptions="true" />
<nlog internalLogFile="file.txt" />
<nlog internalLogLevel="Trace|Debug|Info|Warn|Error|Fatal" />
<nlog internalLogToConsole="false|true" />
<nlog internalLogToConsoleError="false|true" />
Weitere Informationen finden Sie in der NLog-Hilfe.
NLog 2.0 fügt LayoutRenderer-Wrapper hinzu, mit denen zusätzliche Verarbeitungen für die Ausgabe eines Layout-Renderers durchgeführt werden können (z. B. Trimmen von Leerzeichen, Groß- und Kleinschreibung usw.).
Haben Sie keine Angst, den Logger zu verpacken, wenn Sie Ihren Code von einer harten Abhängigkeit von NLog isolieren möchten, aber verpacken Sie ihn korrekt. Es gibt Beispiele für das Einschließen in das Github-Repository des NLog. Ein weiterer Grund für den Wrap könnte sein, dass Sie jeder protokollierten Nachricht automatisch bestimmte Kontextinformationen hinzufügen möchten (indem Sie sie in LogEventInfo.Context einfügen).
Das Umschließen (oder Abstrahieren) von NLog (oder eines anderen Protokollierungsframeworks) hat Vor- und Nachteile. Mit ein wenig Aufwand finden Sie hier viele Informationen zu SO, die beide Seiten präsentieren.
Wenn Sie ein Wrapping in Betracht ziehen, sollten Sie Common.Logging verwenden . Es funktioniert ziemlich gut und ermöglicht es Ihnen, einfach zu einem anderen Protokollierungsframework zu wechseln, wenn Sie dies wünschen. Überlegen Sie auch, wie Sie mit den Kontextobjekten (GDC, MDC, NDC) umgehen, wenn Sie über das Umbrechen nachdenken. Common.Logging unterstützt derzeit keine Abstraktion für sie, befindet sich jedoch angeblich in der Warteschlange der hinzuzufügenden Funktionen.