Algunos de estos entran en la categoría de consejos generales de NLog (o registro) en lugar de estrictamente sugerencias de configuración.
Aquí hay algunos enlaces de registro generales desde aquí en SO (puede que ya haya visto algunos o todos estos):
log4net vs. Nlog
Registro de mejores prácticas
¿Cuál es el punto de una fachada de tala?
¿Por qué los registradores recomiendan usar un registrador por clase?
Use el patrón común de nombrar su registrador en función de la clase Logger logger = LogManager.GetCurrentClassLogger()
. Esto le brinda un alto grado de granularidad en sus registradores y le brinda una gran flexibilidad en la configuración de los registradores (control global, por espacio de nombres, por nombre de registrador específico, etc.).
Utilice registradores que no estén basados en el nombre de clase cuando corresponda. Tal vez tenga una función para la que realmente quiera controlar el registro por separado. Tal vez tenga algunas preocupaciones transversales de registro (registro de rendimiento).
Si no utiliza el registro basado en el nombre de clase, considere nombrar sus registradores en algún tipo de estructura jerárquica (tal vez por área funcional) para que pueda mantener una mayor flexibilidad en su configuración. Por ejemplo, puede tener un área funcional de "base de datos", un FA de "análisis" y un FA "ui". Cada uno de estos puede tener subáreas. Por lo tanto, puede solicitar registradores como este:
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");
Y así. Con los registradores jerárquicos, puede configurar el registro globalmente (el "*" o registrador raíz), por FA (Base de datos, Análisis, UI) o por subárea (Database.Connect, etc.).
Los registradores tienen muchas opciones de configuración:
<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" />
Consulte la ayuda de NLog para obtener más información sobre exactamente lo que significa cada una de las opciones. Probablemente, los elementos más notables aquí son la capacidad de comodín de las reglas de registro, el concepto de que varias reglas de registro pueden "ejecutarse" para una sola declaración de registro, y que una regla de registro puede marcarse como "final" para que las reglas posteriores no se ejecuten para un declaración de registro dada.
Use GlobalDiagnosticContext, MappedDiagnosticContext y NestedDiagnosticContext para agregar contexto adicional a su salida.
Use "variable" en su archivo de configuración para simplificar. Por ejemplo, puede definir variables para sus diseños y luego hacer referencia a la variable en la configuración de destino en lugar de especificar el diseño directamente.
<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>
O bien, puede crear un conjunto de propiedades "personalizadas" para agregar a un diseño.
<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}"/>
O bien, puede hacer cosas como crear representadores de diseño "día" o "mes" estrictamente a través de la configuración:
<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>
También puede usar renders de diseño para definir su nombre de archivo:
<variable name="day" value="${date:format=dddd}"/>
<targets>
<target name="file" xsi:type="File" layout="${verbose}" fileName="${basedir}/${day}.log" />
</targets>
Si enrolla su archivo diariamente, cada archivo podría llamarse "Monday.log", "Tuesday.log", etc.
No tenga miedo de escribir su propio renderizador de diseño. Es fácil y le permite agregar su propia información de contexto al archivo de registro a través de la configuración. Por ejemplo, aquí hay un renderizador de diseño (basado en NLog 1.x, no 2.0) que puede agregar Trace.CorrelationManager.ActivityId al registro:
[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;
}
}
Dígale a NLog dónde están sus extensiones de NLog (qué ensamblaje) de esta manera:
<extensions>
<add assembly="MyNLogExtensions"/>
</extensions>
Utilice el renderizador de diseño personalizado de esta manera:
<variable name="fmt" value="${longdate} | ${ActivityId} | ${message}"/>
Use objetivos asíncronos:
<nlog>
<targets async="true">
<!-- all targets in this section will automatically be asynchronous -->
</targets>
</nlog>
Y envoltorios de destino predeterminados:
<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>
donde corresponda. Consulte los documentos de NLog para obtener más información al respecto.
Dígale a NLog que mire y vuelva a cargar automáticamente la configuración si cambia:
<nlog autoReload="true" />
Hay varias opciones de configuración para ayudar a solucionar problemas 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" />
Consulte la Ayuda de NLog para obtener más información.
NLog 2.0 agrega envoltorios LayoutRenderer que permiten que se realice un procesamiento adicional en la salida de un renderizador de diseño (como recortar espacios en blanco, mayúsculas, minúsculas, etc.).
No tenga miedo de envolver el registrador si desea aislar su código de una dependencia dura de NLog, pero ajústelo correctamente. Hay ejemplos de cómo envolver en el repositorio github de NLog. Otra razón para ajustar puede ser que desee agregar automáticamente información de contexto específica a cada mensaje registrado (poniéndolo en LogEventInfo.Context).
Existen ventajas y desventajas para envolver (o abstraer) NLog (o cualquier otro marco de registro para el caso). Con un poco de esfuerzo, puede encontrar mucha información aquí sobre SO presentando ambos lados.
Si está considerando envolver, considere usar Common.Logging . Funciona bastante bien y le permite cambiar fácilmente a otro marco de registro si lo desea. Además, si está considerando ajustar, piense cómo manejará los objetos de contexto (GDC, MDC, NDC). Common.Logging actualmente no admite una abstracción para ellos, pero supuestamente está en la cola de capacidades para agregar.