[C#/NLog] NLog 타겟이 Exception을 출력할 때 새로운 줄에 출력하도록 하기(newline)

NLog

NLog. 정말 좋습니다. 예전 회사에 다닐 때엔 자바를 사용하며 log4j를 썼는데, 퇴사 후 C#으로 넘어오면서 log4j같은 것, 혹은 그보다 좋은 라이브러리가 없을까 하며 찾아보니 처음에는 log4net이, 그 다음에 바로 NLog가 눈에 들어오더군요.

그때 당시에는 제가 못 찾은건지 모르겠지만 log4net이 제대로 업데이트가 되고 있지 않아보였기에 NLog를 주력 로깅 라이브러리로 선택해 아직까지 잘 사용중입니다.

LayoutRenderer 지원

NLog는 LayoutRenderer를 통한 다이나믹 로깅을 지원합니다. 예를 들어,

<target layout="${longdate} ${level:uppercase=true} [${threadid}/${threadname}] ${logger}.${callsite:methodName=true} - ${message}" />

위와 같은 레이아웃을 지닌 타겟은, 다음과 같은 형태의 로그를 출력하게 됩니다.

2020-12-15 11:50:34.4618 INFO [1/] HSUpdateUploaderGUI.MainWindow.HSUpdateUploaderGUI.MainWindow.Window_Loaded - Application is loaded.

Exception 객체 지원

위와 같은 레이아웃 렌더러를 통해 예외 출력도 마음대로 설정할 수 있습니다. 기본적으로 ${exception} 렌더러를 사용합니다.

해당 렌더러는 NLog.Logger.(Trace|Debug|Info|Warn|Error|Fatal) 메서드의 첫 번째 인자로 Exception 객체가 주어졌을 때 해당 Exception 객체의 내용을 렌더러의 설정에 따라 출력합니다. 반대로, Exception 객체가 null일 경우에는 아무것도 출력하지 않고요.

하지만 여기서 문제가 생깁니다. 만약 예외 메세지를 다른 라인에 출력하고 싶다면?

Exception 내용을 새 줄에 출력. Exception이 null이라면 새 줄 출력 안 함

제가 처음에 시도했던 레이아웃을 써보겠습니다.

${logger} - ${message}${newline}${exception:format=ToString}

딱 봐도 문제가 보이시죠? 위 레이아웃은 예외 객체가 전달됐든 아니든 상관없이 항상 로그의 끝에 새 줄이 추가됩니다. 즉 예외가 있으면 정상적으로 보이지만, 예외가 없는 다른 로그들은 한 줄 건너 한 줄씩 출력된다는 얘기죠.

그래서 NLog 프로젝트 페이지를 보니 onexception 렌더러가 보이더라고요.

Only outputs the inner layout when exception has been defined for log message.

로그 메세지에 예외가 있을 때에만 내부 레이아웃이 출력된다? 바로 제가 찾던 기능입니다. 사용법도 간단합니다.

layout="${longdate} ${message}${onexception:${newline}${exception:format=ToString,StackTrace,Data:maxInnerExceptionLevel=20:Separator=\r\n:exceptionDataSeparator=\r\n}}"

로그에 예외가 있을 경우(onexception), 우선 새 줄을 출력하고(newline) 예외를 (exception) 지정한 형식으로(format=…) 최대 내부 예외를 20개까지(maxInnerExceptionLevel=20) 출력하라는 레이아웃입니다.

위에서 보이듯, onexception 렌더러의 내부에서도 또다른 렌더러를 사용할 수 있기에(newline, exception) 이러한 처리가 가능하게 된 것이죠.

이렇게 하면 일반 로그가 더이상 한 줄 건너 한 줄 출력되지도 않고, 예외는 다음 줄에 출력되게 할 수 있습니다.

댓글

이 블로그의 인기 게시물

C# 남아도는 메모리에도 불구하고 OutOfMemoryException이 발생한다면?

USB를 뒤는 괜찮은데 앞에 꽂으면 인식이 힘들다?

MySQL 데이터 타입과 Java 데이터 타입 비교/매칭