Certains d'entre eux entrent dans la catégorie des conseils NLog (ou de journalisation) généraux plutôt que des suggestions de configuration strictes.
Voici quelques liens de journalisation généraux d'ici chez SO (vous en avez peut-être déjà vu certains ou tous):
log4net contre Nlog
Journalisation des meilleures pratiques
Quel est l'intérêt d'une façade forestière?
Pourquoi les enregistreurs recommandent-ils d'utiliser un enregistreur par classe?
Utilisez le modèle courant pour nommer votre enregistreur en fonction de la classe Logger logger = LogManager.GetCurrentClassLogger()
. Cela vous donne un degré élevé de granularité dans vos enregistreurs et vous donne une grande flexibilité dans la configuration des enregistreurs (contrôle global, par espace de noms, par nom de enregistreur spécifique, etc.).
Utilisez des enregistreurs non basés sur le nom de classe, le cas échéant. Peut-être avez-vous une fonction pour laquelle vous voulez vraiment contrôler la journalisation séparément. Vous avez peut-être des problèmes de journalisation intersectoriels (journalisation des performances).
Si vous n'utilisez pas la journalisation basée sur le nom de classe, pensez à nommer vos enregistreurs dans une sorte de structure hiérarchique (peut-être par domaine fonctionnel) afin de conserver une plus grande flexibilité dans votre configuration. Par exemple, vous pouvez avoir un domaine fonctionnel "base de données", un FA "analyse" et un FA "ui". Chacun de ces éléments peut avoir des sous-zones. Vous pouvez donc demander des enregistreurs comme celui-ci:
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");
Etc. Avec les enregistreurs hiérarchiques, vous pouvez configurer la journalisation de manière globale (le "*" ou enregistreur racine), par FA (Database, Analysis, UI) ou par sous-zone (Database.Connect, etc.).
Les enregistreurs ont de nombreuses options de configuration:
<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" />
Consultez l' aide de NLog pour plus d'informations sur la signification exacte de chacune des options. Les éléments les plus notables ici sont probablement la possibilité de joker des règles de journalisation, le concept selon lequel plusieurs règles de journalisation peuvent "s'exécuter" pour une seule instruction de journalisation, et qu'une règle de journalisation peut être marquée comme "finale" afin que les règles suivantes ne s'exécutent pas pour un compte rendu de consignation donné.
Utilisez GlobalDiagnosticContext, MappedDiagnosticContext et NestedDiagnosticContext pour ajouter un contexte supplémentaire à votre sortie.
Utilisez "variable" dans votre fichier de configuration pour simplifier. Par exemple, vous pouvez définir des variables pour vos présentations, puis référencer la variable dans la configuration cible plutôt que de spécifier directement la présentation.
<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>
Vous pouvez également créer un ensemble de propriétés "personnalisé" à ajouter à une présentation.
<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}"/>
Ou, vous pouvez faire des choses comme créer des rendus de mise en page "jour" ou "mois" strictement via la configuration:
<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>
Vous pouvez également utiliser des rendus de mise en page pour définir votre nom de fichier:
<variable name="day" value="${date:format=dddd}"/>
<targets>
<target name="file" xsi:type="File" layout="${verbose}" fileName="${basedir}/${day}.log" />
</targets>
Si vous faites rouler votre fichier quotidiennement, chaque fichier pourrait être nommé "Monday.log", "Tuesday.log", etc.
N'ayez pas peur d'écrire votre propre rendu de mise en page. Il est facile et vous permet d'ajouter vos propres informations de contexte au fichier journal via la configuration. Par exemple, voici un rendu de mise en page (basé sur NLog 1.x et non 2.0) qui peut ajouter Trace.CorrelationManager.ActivityId au journal:
[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;
}
}
Dites à NLog où vos extensions NLog (quel assemblage) comme ceci:
<extensions>
<add assembly="MyNLogExtensions"/>
</extensions>
Utilisez le rendu de mise en page personnalisé comme ceci:
<variable name="fmt" value="${longdate} | ${ActivityId} | ${message}"/>
Utilisez des cibles asynchrones:
<nlog>
<targets async="true">
<!-- all targets in this section will automatically be asynchronous -->
</targets>
</nlog>
Et les wrappers cibles par défaut:
<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>
le cas échéant. Voir les documents NLog pour plus d'informations à ce sujet.
Dites à NLog de regarder et de recharger automatiquement la configuration si elle change:
<nlog autoReload="true" />
Il existe plusieurs options de configuration pour faciliter le dépannage de NLog
<nlog throwExceptions="true" />
<nlog internalLogFile="file.txt" />
<nlog internalLogLevel="Trace|Debug|Info|Warn|Error|Fatal" />
<nlog internalLogToConsole="false|true" />
<nlog internalLogToConsoleError="false|true" />
Voir l'aide de NLog pour plus d'informations.
NLog 2.0 ajoute des wrappers LayoutRenderer qui permettent d'effectuer un traitement supplémentaire sur la sortie d'un rendu de mise en page (comme le découpage des espaces blancs, les majuscules, les minuscules, etc.).
N'ayez pas peur d'envelopper l'enregistreur si vous voulez isoler votre code d'une forte dépendance à NLog, mais envelopper correctement. Il y a des exemples de comment encapsuler dans le référentiel github de NLog. Une autre raison pour encapsuler peut être que vous souhaitez ajouter automatiquement des informations de contexte spécifiques à chaque message enregistré (en les plaçant dans LogEventInfo.Context).
Il y a des avantages et des inconvénients à encapsuler (ou à résumer) NLog (ou tout autre cadre de journalisation d'ailleurs). Avec un petit effort, vous pouvez trouver ici de nombreuses informations sur SO présentant les deux côtés.
Si vous envisagez d' habiller , pensez à utiliser Common.Logging . Cela fonctionne assez bien et vous permet de basculer facilement vers un autre cadre de journalisation si vous le souhaitez. De plus, si vous envisagez d'habiller, pensez à la façon dont vous allez gérer les objets de contexte (GDC, MDC, NDC). Common.Logging ne prend actuellement pas en charge une abstraction pour eux, mais il est censé être dans la file d'attente des capacités à ajouter.