1. 개요
로깅 서비스를 통합관리하는 시스템으로 편리하게 소프트웨어 로깅을 기록하자.
2. 소개
여기에서는 .Net에서 사용할 수 있는 로깅 서비스로 NLog를 사용하려고 한다
간단한 설정에서 Dependency Injection 을 활용할 예정이다.
3. 구현하기
우선 Package 는 NLog와 NLog.Extension.Logging이 필요하다.
NLog를 사용하기 위해서 Configuration 파일을 등록해야하는데 두가지 방법을 사용할 수 있다.
# Configuration
Config | NLog (nlog-project.org)
NLog.config vs. appsettings.json
작성하는 방식의 차이일뿐 큰차이는 없다. 다만 NLog.config 를 사용할 경우에는 복잡한 layout 을 구성하기에 용이하며 json은 간단한 형태의 target을 구성하기에 좋다.
<NLog.config>
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<extensions>
<add assembly="MyNamespace"/>
</extensions>
<targets>
<target name="logfile" xsi:type="File" fileName="app-nlog-${shortdate}.log" />
<target name="logconsole" xsi:type="Console" />
<target name="Debugger" xsi:type="Debugger" layout="${logger}:${callsite:className=false:fileName=false:includeSourcePath=false:methodName=true} | ${message}" />
<target name="wpfLogger" xsi:type="WpfLogger" layout="${logger}::${message}"/>
<target name="throttle_log4view" type="AsyncWrapper" timeToSleepBetweenBatches="100" batchSize="1" overflowAction="Block">
<target name="log4view" type="NLogViewer" address="tcp://127.0.0.1:5001" newline="true" layout ="${logger}:${callsite:className=false:fileName=false:includeSourcePath=false:methodName=true} | ${message}"/>
</target>
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="logconsole" />
<logger name="*" minlevel="Info" writeTo="logfile" />
<!-- <logger name="*" minlevel="Trace" writeTo="debugger" /> -->
<logger name="*" minlevel="Trace" writeTo="wpfLogger" />
<logger name="*" minlevel="Trace" writeTo="throttle_log4view" />
</rules>
</nlog>
다만, NLog.config 프로그램 실행시 자동으로 지정된 경로에 있는 파일을 로드하여 configuration 을 수행하지만, appsettings.json 은 직접 ConfigurationBuilder 를 수행해야한다.
var config = new ConfigurationBuilder()
.SetBasePath(System.IO.Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.Build();
# LogLevel
설정파일에서 입력한 minlevel, maxlevel 에서 사용되는 메시지로 log 에서 입력되는 메시지 종류에 따라서 출력되는 메시지가 결정된다
# Writing Log Messages
Configuration 을 통해서 Logger 와 Target을 지정했다면 LogManager를 통해서 logger instance 를 생성하여 메시지를 출력할 수 있다.
Tutorial · NLog/NLog Wiki (github.com)
public static class Program
{
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
public static void Main()
{
try
{
Logger.Info("Hello world");
System.Console.ReadKey();
}
catch (Exception ex)
{
Logger.Error(ex, "Goodbye cruel world");
}
}
}
# Dependency Injection
NLog는 Microsoft.Extensions.DependencyInjection (DI)를 이용하여 Microsoft.Extensions.Logging 패키지의 ILogger Injection으로 logger 객체를 관리할 수 있다.
NLog GetCurrentClassLogger and Microsoft ILogger · NLog/NLog.Extensions.Logging Wiki (github.com)
ServiceCollection 에 AddLogging를 이용해서 NLog를 등록한다.
var servicesProvider = new ServiceCollection()
.AddTransient<Runner>() // Runner is the custom class
.AddLogging(loggingBuilder =>{ loggingBuilder.AddNLog();}).BuildServiceProvider();
등록이 완료되면 Logger를 injection 할 클래스의 생성자에서는 해당 클래스의 type을 갖는 ILogger를 매개변수로 선언하여 instance에 접근할 수 있다.
public class Runner
{
private readonly ILogger<Runner> _logger;
public Runner(ILogger<Runner> logger)
{
_logger = logger;
}
public void DoAction(string name)
{
_logger.LogDebug(20, "Doing hard work! {Action}", name);
}
}
NLog vs. Microsoft.Extensions.Logging
NLog Pros
Pros of using NLog directly
- Best performance by remove layer of indirection and allowing deferred formatting.
- More options with the logger API, e.g. Logger.WithProperty(..)
- Works in all platforms
- No Dependency Injection needed which saves complexity.
Pros Microsoft.Extensions.Logging
Pros of using NLog via Microsoft.Extensions.Logging:
- Fully integrated with ASP.NET Core, e.g. Microsoft also writes to the logger API and that will be also captured (and possible filtered) by NLog
- Writing to the logging abstraction will make your code log-library independent.
- Works well with .NET Core Dependency injection
- Load NLog configuration from appsettings.json, instead of using XML file NLog.config.
# NLogViewer
위의 Configuration 에서 작성한 Target에서 NLogViewer가 있다. 이는 log4jxml 데이터 구조를 바탕으로 Network 기반으로 메시지를 모니터링 할 수 있도록 한다.
Tools · NLog/NLog Wiki (github.com)
NLogViewer를 사용할 수 있는 프로그램이 여러개 있는데 그 중에서 Lgazmic 이 UI 적으로 MahApps.Metro 를 사용해서 만든거라 친숙하다.
마침글
NLog 를 활용하는데 개인적으로는 NLog.config 파일의 설정과 ILogging 방식을 이용하여 구현하는 것이 코드적으로 깔끔한것 같다.
그리고 layout 구성을 잘하면 출력되는 target별로 원하는 정보를 별도로 표시 할 수 있어서 잘 분석해서 쓰면 활용성이 높은것 같다.
또한, TargetWithLayout 클래스를 활용하여 Custom Target을 구성하여 별도의 Logging 출력 화면을 구성할 수 있는 것도 잘 쓰면 좋을것 같다.