Деякі з них відносяться до категорії загальних порад NLog (або ведення журналів), а не суто пропозицій щодо конфігурації.
Ось декілька загальних посилань на реєстрацію звідси на SO (ви, можливо, вже бачили деякі чи всі):
log4net проти Nlog
Реєстрація найкращих практик
У чому сенс фасаду лісозаготівлі?
Чому лісоруби рекомендують використовувати реєстратор для кожного класу?
Використовуйте загальну схему іменування вашого реєстратора на основі класу Logger logger = LogManager.GetCurrentClassLogger()
. Це дає вам високу ступінь деталізації у ваших реєстраторах та дає велику гнучкість у конфігурації реєстраторів (керуйте глобально, за простором імен, за конкретним іменем реєстратора тощо).
Використовуйте некласові реєстратори, де це доречно. Можливо, у вас є одна функція, за якою ви дійсно хочете окремо контролювати ведення журналу. Можливо, у вас є проблеми щодо наскрізного ведення журналів (реєстрація продуктивності).
Якщо ви не використовуєте журнал на основі класів, розгляньте, як назвати ваші реєстратори в якійсь ієрархічній структурі (можливо, за функціональною областю), щоб ви могли підтримувати більшу гнучкість у своїй конфігурації. Наприклад, у вас може бути функціональна область "бази даних", ФА "аналіз" та ФА "ui". Кожна з них може мати підрозділи. Отже, ви можете запитати такі реєстратори:
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");
І так далі. За допомогою ієрархічних реєстраторів ви можете налаштувати ведення журналу глобально ("*" або кореневий реєстратор), за допомогою FA (база даних, аналіз, інтерфейс користувача) або підрайон (Database.Connect тощо).
Лісоруби мають багато варіантів конфігурації:
<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" />
Докладніше про те, що означає кожен із варіантів, див. У довідці NLog . Напевно, найпомітніші пункти тут - це можливість підкреслити правила реєстрації підручних даних, концепція того, що кілька правил реєстратора можуть "виконати" для одного оператора реєстрації, і що правило реєстратора можна позначити як "остаточне", тому наступні правила не виконуватимуться для заданий запис протоколу.
Використовуйте GlobalDiagnosticContext, MappedDiagnosticContext і NestedDiagnosticContext, щоб додати додатковий контекст до свого результату.
Використовуйте "змінну" у своєму конфігураційному файлі для спрощення. Наприклад, ви можете визначити змінні для своїх макетів, а потім посилатися на змінну в цільовій конфігурації, а не вказувати макет безпосередньо.
<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>
Або ви можете створити "спеціальний" набір властивостей, який потрібно додати до макета.
<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}"/>
Або ви можете робити такі речі, як створити "денний" або "місячний" рендері строго за допомогою конфігурації:
<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>
Ви також можете використовувати візуалізацію макета, щоб визначити своє ім'я файлу:
<variable name="day" value="${date:format=dddd}"/>
<targets>
<target name="file" xsi:type="File" layout="${verbose}" fileName="${basedir}/${day}.log" />
</targets>
Якщо ви робите щодня файл, кожен файл може бути названий "Monday.log", "Tuesday.log" тощо.
Не бійтеся написати власний макет рендерінга. Це легко і дозволяє додавати власну інформацію про контекст у файл журналу за допомогою конфігурації. Наприклад, ось рендеринг макета (заснований на NLog 1.x, а не 2.0), який може додати Trace.CorrelationManager.ActivityId до журналу:
[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;
}
}
Скажіть NLog, де ваші розширення NLog (яка збірка) так:
<extensions>
<add assembly="MyNLogExtensions"/>
</extensions>
Використовуйте рендерінг власного макета таким чином:
<variable name="fmt" value="${longdate} | ${ActivityId} | ${message}"/>
Використовуйте цілі асинхронізації:
<nlog>
<targets async="true">
<!-- all targets in this section will automatically be asynchronous -->
</targets>
</nlog>
І цільові обгортки за замовчуванням:
<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>
де це доречно. Докладніші відомості про них див. У документах NLog.
Скажіть NLog переглянути і автоматично перезавантажте конфігурацію, якщо вона зміниться:
<nlog autoReload="true" />
Існує кілька варіантів конфігурації, які допоможуть вирішити проблеми з NLog
<nlog throwExceptions="true" />
<nlog internalLogFile="file.txt" />
<nlog internalLogLevel="Trace|Debug|Info|Warn|Error|Fatal" />
<nlog internalLogToConsole="false|true" />
<nlog internalLogToConsoleError="false|true" />
Додаткову інформацію див. У довідці NLog.
NLog 2.0 додає обгортки LayoutRenderer, які дозволяють виконувати додаткову обробку на виході рендерінгу макета (наприклад, обрізка пробілів, верхнє обшивання, нижнє обшивання тощо).
Не бійтеся загортати реєстратор, якщо хочете ізолювати свій код від жорсткої залежності від NLog, але загорніть правильно. Є приклади, як загорнутись у сховище github NLog. Ще однією причиною обговорення може бути те, що ви хочете автоматично додавати конкретну інформацію про контекст до кожного зареєстрованого повідомлення (розміщуючи його в LogEventInfo.Context).
Існують плюси і мінуси для обгортання (або абстрагування) NLog (або будь-якої іншої рамки ведення журналу з цього приводу). Трохи доклавши зусиль, ви можете знайти багато інформації тут на SO, представляючи обидві сторони.
Якщо ви розглядаєте обгортання, подумайте про використання Common.Logging . Він працює досить добре і дозволяє вам легко перейти на інший режим реєстрації, якщо ви цього хочете. Крім того, якщо ви плануєте обгортання, подумайте, як ви будете обробляти контекстні об'єкти (GDC, MDC, NDC). Common.Logging наразі не підтримує абстракцію для них, але це, мабуть, у черзі можливостей додати.