본문 바로가기

IT 살이/04. 기술 - 프로그래밍

log4net 정리 & 예제

개발을 하다 보면 로그 모듈을 제작해야 하는 경우가 많다. 때로는 개인적인 디버깅 목적으로 때로는 시스템의 일부로서. 

그럴때마다 제작해야 하는 것이 귀찮을때도 있고, 기간이 정해진 프로젝트라면 일정때문에 안정된 모듈을 찾는 경우도 있다.  

log4net 라이브러리는 라이센스 제약도 거의 없고, 여러가지 장점들이 있는 듯하다.

이번에 사용할 기회가 생겨 메모를 좀 해 두려한다.


log4Net 모듈 개요


1) config를 통해서 다양한 로그 저장소를 "설정"할 수 있다. 

참고) 로그 저장소에 로그를 남기는 log4Net의 소위 "Appender"들이 이미 구현되어 있다.

2) "설정"한 로그 저장소중에서 필요한 저장소를 시나리오에 따라서 "선택"할 수 있다. "선택"또한 config를 통해서 할 수 있다.

3) 필요로 하는 다양한 로깅 시나리오에 대응할 수 있다.  

예, "모든 로그는 데이터베이스에 저장하고, 오류는 메일로도 함께 전달해달라"

참고) 로그 레벨 

1. Debug

2. Information

3. Warnings

4. Error

5. Fatal

4) 내부적으로 성능도 충분히 고려하고 있는 듯 하다.

예를 들어, 로그 저장소에 로그를 보내기전에 메모리 버퍼 크기 등을 둬서 I/O를 줄여줄 수 있는 config를 구성할 수도 있다. 


■ configuration


거의 모든 요구조건을 config로 해결할 수 있다. 예를 들어, 프로그램에서는 logger.Info(), logger.Warn(),logger.Error() 처럼 메소드만 호출하고, 나머지 로깅에 필요한 것은 모두 config에서 설정할 수 있다.

log4Net 모듈에 대한 설정은 <log4net>...</log4net> 섹션에 모두 포함된다.

<log4net> 섹션은 .net 어플리케이션의 config파일( web.config, exe.config)의 일부 섹션으로 포함될 수도 있고, 별도의 독립된 파일로 구성할 수도 있다. 다만, .net 어플리케이션의 섹션으로 포함될때는 그 섹션을 해석할 수 있는 모듈을 .net에 알려줘야 한다. 


<log4net/> 섹션


다음은 <log4net>섹션을 구성한 예이다.( 첨부된 예제 프로그램의 구조이다)


<log4net>

  

  <!-- 파일시스템용-->

  <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">

    ...

  </appender>

  <!-- SMTP용-->

  <appender name="SmtpAppender" type="log4net.Appender.SmtpAppender,log4net">

   ...

  </appender>


  <!-- MS SQL용-->

  <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">

   ...

  </appender>


  <root>

    <appender-ref ref="RollingFile" />

    <appender-ref ref="AdoNetAppender"/>

    <appender-ref ref="SmtpAppender" />

  </root>

</log4net>


몇 가지 로그 저장소용 appender를 "설정"하고 <root>에서 어떤 appender를 사용할지 선택할 수 있다. 위 confi는 3개의 appender를 사용하겠다고 선택한 예이다. 이렇게 하면 모든 appender에 로그 메시지가 전달된다. 그러나 설정한 로그 레벨에 따라서 로그로 남지 않을 수도 있다. 로그 레벨은 appender별로도 지정할 수 있고, <root>에 설정해서 전체 appender에 지정할 수도 있다.


appender에 지정하는 방법


  <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">

    <evaluator type="log4net.Core.LevelEvaluator,log4net">

      <threshold value="INFO"/>

    </evaluator>

    ... 


위 코드는 레벨이 "INFO" 이상인 로그 메시지만 남기게 된다. 이렇게 appender별로 로그 레벨을 달리 지정하는 방법을 사용하면 예를 들어 오류만 메일로 전달받는 구조를 구성할 수 있다.


전체 appender에 지정하는 방법


    <root>

        <level value="DEBUG" />

        <appender-ref ref="SmtpAppender" />

        <appender-ref ref="RollingFile" />

    </root>

   

.net 어플리케이션에 <log4net> 포함시키기


<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <configSections>

    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>

  </configSections>

  <log4net>

  ...

  </log4net>


<log4net/> 섹션을 파싱할 수 있는 log4net 모듈을 <configSections>에 지정하고 있다. 

<section/>의 name값과 <log4net>의 태그명이 동일해야 한다.


독립된 파일 "log4net.xml"로 저장하기


<?xml version="1.0" encoding="utf-8" ?>

<log4net>

...

</log4net>


기타 자세한 configuration 설명은 아래 링크를 참조한다.

http://logging.apache.org/log4net/release/manual/configuration.html


■ 프로그램에서 로그 남기기


config 파일 읽어 들이기


//exe.config에서 설정 가져옴

log4net.Config.XmlConfigurator.Configure();


//log4net.xml에서 설정 가져옴

log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo("log4net.xml"));


log4net의 config 파일을 읽어오는 코드는 한번만 실행되면 된다. .net 어플리케이션이 살아있는 동안 계속 사용할 수 있다. 그래서 웹 어플리케이션이라면 Global.asax같은 Application_Start 이벤트 핸들러에 두면 적당할 것이다.


로그 메시지 남기기



log4net.ILog logger = log4net.LogManager.GetLogger(typeof(Program));


logger.Info("디버깅 정보 출력합니다.");

logger.Warn("경고 출력합니다. ");

logger.Error("오류 출력합니다.");


이렇게 호출하면 로그 레벨에 따라서 config된 내용대로 적절한 appender를 사용해서 적절한 저장소로 남게 된다. 

GetLogger()의 파라미터로 로거의 이름을 제공하는데, 이렇게 풀클래스명을 제공해도 되지만 문자열("로그")로 제공해도 된다. 

이름에 해당하는 로거가 없으면 등록하고 해당 인스턴스를 반환한다. 

conversion pattern을 이용하면 로거의 이름도 로그의 항목으로 남게 할 수 있다.

https://logging.apache.org/log4net/log4net-1.2.13/release/sdk/log4net.Layout.PatternLayout.html


■ 테스트 코드


테스트했던 소스 코드 첨부한다.

Log4NetTester.zip