Certaines d'entre elles entrent dans la catégorie des conseils généraux sur le NLog (ou la journalisation) plutôt que des suggestions de configuration strictes.
Voici quelques liens généraux sur l'exploitation forestière (vous les avez peut-être déjà vus, en partie ou en totalité) :
log4net vs. Nlog
Meilleures pratiques en matière de journalisation
Quel est l'intérêt d'une façade d'exploitation forestière ?
Pourquoi les bûcherons recommandent-ils d'utiliser un bûcheron par classe ?
Utilisez le modèle commun de nommer votre logger basé sur la classe Logger logger = LogManager.GetCurrentClassLogger()
. Cela vous donne un haut degré de granularité dans vos loggers et vous offre une grande flexibilité dans la configuration des loggers (contrôle global, par espace de noms, par nom de logger spécifique, etc).
Utilisez des enregistreurs non basés sur des noms de classes lorsque cela est approprié. Vous avez peut-être une fonction pour laquelle vous souhaitez vraiment contrôler la journalisation séparément. Vous avez peut-être des préoccupations transversales en matière de journalisation (journalisation des performances).
Si vous n'utilisez pas la journalisation basée sur les noms de classe, pensez à nommer vos enregistreurs selon une structure hiérarchique (peut-être par domaine fonctionnel) afin de conserver une plus grande flexibilité dans votre configuration. Par exemple, vous pourriez avoir un domaine fonctionnel "base de données", un FA "analyse" et un FA "ui". Chacun de ces domaines peut avoir des sous-domaines. Ainsi, vous pourriez 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");
Et ainsi de suite. Avec les enregistreurs hiérarchiques, vous pouvez configurer l'enregistrement de manière globale (l'enregistreur "*" ou Root), par FA (Database, Analysis, UI) ou par sous-domaine (Database.Connect, etc.).
Les enregistreurs disposent 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" />
Voir le Aide NLog pour plus d'informations sur la signification exacte de chacune de ces options. Les éléments les plus remarquables sont probablement la possibilité d'utiliser des règles de journalisation avec caractères génériques, le concept selon lequel plusieurs règles de journalisation peuvent "s'exécuter" pour une seule déclaration de journalisation, et le fait qu'une règle de journalisation peut être marquée comme "finale" afin que les règles suivantes ne s'exécutent pas pour une déclaration de journalisation donnée.
Utilisez le GlobalDiagnosticContext, le MappedDiagnosticContext et le 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 mises en page, puis faire référence à la variable dans la configuration cible plutôt que de spécifier directement la mise en page.
<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 "personnalisé" de propriétés à ajouter à une mise en page.
<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 bien, vous pouvez faire des choses comme créer des moteurs de rendu 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 les 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 lancez votre fichier quotidiennement, chaque fichier pourrait être nommé "Monday.log", "Tuesday.log", etc.
N'ayez pas peur d'écrire votre propre moteur de rendu de mise en page. C'est facile et cela vous permet d'ajouter vos propres informations contextuelles au fichier journal via la configuration. Par exemple, voici un layout renderer (basé sur NLog 1.x, pas 2.0) qui peut ajouter le 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ù se trouvent vos extensions NLog (quel assemblage) comme ceci :
<extensions>
<add assembly="MyNLogExtensions"/>
</extensions>
Utilisez le moteur de 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 des enveloppes de 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. Consultez la documentation du NLog pour plus d'informations à ce sujet.
Dites à NLog de surveiller 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" />
Consultez l'aide de NLog pour plus d'informations.
NLog 2.0 ajoute des wrappers LayoutRenderer qui permettent d'effectuer des traitements supplémentaires sur la sortie d'un layout renderer (comme la suppression des espaces blancs, les majuscules, les minuscules, etc).
N'ayez pas peur d'envelopper le logger si vous voulez isoler votre code d'une dépendance stricte à NLog, mais enveloppez-le correctement. Il y a des exemples sur la façon d'envelopper dans le dépôt github de NLog. Une autre raison d'utiliser le wrap est que vous souhaitez ajouter automatiquement des informations contextuelles spécifiques à chaque message enregistré (en les plaçant dans LogEventInfo.Context).
Il y a des avantages et des inconvénients à envelopper (ou abstraire) NLog (ou tout autre cadre de journalisation d'ailleurs). Avec un peu d'effort, vous pouvez trouver beaucoup d'informations ici sur SO présentant les deux côtés.
Si vous envisagez d'emballer, pensez à utiliser Logging.commun . Cela fonctionne très bien et vous permet de passer facilement à un autre cadre de journalisation si vous le souhaitez. Aussi, si vous envisagez d'envelopper, pensez à la façon dont vous allez gérer les objets de contexte (GDC, MDC, NDC). Common.Logging ne supporte pas actuellement une abstraction pour eux, mais c'est censé être dans la file d'attente des capacités à ajouter.
3 votes
Voici quelques conseils d'optimisation des performances basés sur des tests : deep-depth.blogspot.com/2014/01/