Algumas delas se enquadram na categoria de dicas gerais sobre NLog (ou log), em vez de sugestões estritamente de configuração.
Aqui estão alguns links gerais de registro aqui no SO (você já deve ter visto alguns ou todos esses):
log4net vs. Nlog
Práticas recomendadas de log
Qual o sentido de uma fachada de madeira?
Por que os registradores recomendam o uso de um registrador por classe?
Use o padrão comum de nomear seu criador de logs com base na classe Logger logger = LogManager.GetCurrentClassLogger()
. Isso proporciona um alto grau de granularidade em seus criadores de logs e oferece grande flexibilidade na configuração dos registradores (controle global, por espaço de nome, por nome específico do registrador, etc.).
Use loggers não baseados em nome de classe, quando apropriado. Talvez você tenha uma função para a qual realmente deseja controlar o log separadamente. Talvez você tenha algumas preocupações transversais de log (log de desempenho).
Se você não usar o log baseado em nome de classe, considere nomear seus loggers em algum tipo de estrutura hierárquica (talvez por área funcional), para que você possa manter uma maior flexibilidade em sua configuração. Por exemplo, você pode ter uma área funcional "banco de dados", uma FA "análise" e uma FA "ui". Cada um desses pode ter subáreas. Portanto, você pode 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");
E assim por diante. Com os registradores hierárquicos, você pode configurar o registro globalmente (o "*" ou o registrador raiz), por FA (banco de dados, análise, interface do usuário) ou por subárea (Database.Connect, etc).
Os registradores têm muitas opções de configuração:
<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 a ajuda do NLog para obter mais informações sobre exatamente o que cada uma das opções significa. Provavelmente, os itens mais notáveis aqui são a capacidade de regras do agente curinga, o conceito de que várias regras do agente podem "executar" para uma única instrução de registro e que uma regra do agente pode ser marcada como "final", para que as regras subsequentes não sejam executadas por um dada declaração de log.
Use GlobalDiagnosticContext, MappedDiagnosticContext e NestedDiagnosticContext para adicionar contexto adicional à sua saída.
Use "variável" no seu arquivo de configuração para simplificar. Por exemplo, você pode definir variáveis para seus layouts e depois referenciar a variável na configuração de destino, em vez de especificar o layout diretamente.
<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>
Ou, você pode criar um conjunto "personalizado" de propriedades para adicionar a um layout.
<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 você pode fazer coisas como criar renderizadores de layout "dia" ou "mês" estritamente via configuração:
<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>
Você também pode usar renderizações de layout para definir seu nome de arquivo:
<variable name="day" value="${date:format=dddd}"/>
<targets>
<target name="file" xsi:type="File" layout="${verbose}" fileName="${basedir}/${day}.log" />
</targets>
Se você rolar o arquivo diariamente, cada arquivo poderá ter o nome "Monday.log", "Tuesday.log" etc.
Não tenha medo de escrever seu próprio renderizador de layout. É fácil e permite adicionar suas próprias informações de contexto ao arquivo de log via configuração. Por exemplo, aqui está um renderizador de layout (baseado no NLog 1.x, não 2.0) que pode adicionar Trace.CorrelationManager.ActivityId ao log:
[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;
}
}
Informe ao NLog onde suas extensões do NLog (que montagem) estão assim:
<extensions>
<add assembly="MyNLogExtensions"/>
</extensions>
Use o renderizador de layout personalizado como este:
<variable name="fmt" value="${longdate} | ${ActivityId} | ${message}"/>
Use destinos assíncronos:
<nlog>
<targets async="true">
<!-- all targets in this section will automatically be asynchronous -->
</targets>
</nlog>
E wrappers de destino padrão:
<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>
onde apropriado. Consulte os documentos do NLog para obter mais informações sobre eles.
Diga ao NLog para assistir e recarregar automaticamente a configuração se ela mudar:
<nlog autoReload="true" />
Existem várias opções de configuração para ajudar na solução de problemas do 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 a Ajuda do NLog para obter mais informações.
O NLog 2.0 adiciona wrappers LayoutRenderer que permitem que um processamento adicional seja executado na saída de um renderizador de layout (como aparar espaços em branco, maiúsculas, minúsculas etc.).
Não tenha medo de quebrar o logger se você quiser isolar seu código de uma forte dependência do NLog, mas envolva-o corretamente. Existem exemplos de como agrupar no repositório github do NLog. Outro motivo para quebrar pode ser que você deseja adicionar automaticamente informações de contexto específicas a cada mensagem registrada (colocando-a em LogEventInfo.Context).
Existem prós e contras no empacotamento (ou abstração) do NLog (ou em qualquer outra estrutura de registro para esse assunto). Com um pouco de esforço, você pode encontrar muitas informações aqui, apresentando os dois lados.
Se você estiver pensando em quebrar , considere usar o Common.Logging . Funciona muito bem e permite que você alterne facilmente para outra estrutura de log, se desejar. Além disso, se você estiver pensando em agrupar, pense em como manipulará os objetos de contexto (GDC, MDC, NDC). No momento, o Common.Logging não oferece suporte a uma abstração, mas supostamente está na fila de recursos a serem adicionados.