CHashtag

[C#] log4net 사용방법 본문

C#

[C#] log4net 사용방법

HyoSeong 2022. 3. 4. 23:24
반응형

안녕하세요.

 

오늘은 이전 게시글에서 말했듯 로그를 기록하는 방법에 대해 알려드리고자 합니다.

 

자 그럼 시작합니다!!

 

프로젝트 생성 & log4net 설치


시대가 시대이니 만큼 .net project로 생성해주도록 하겠습니다.

저는 .net 6로 프로젝트를 생성하였습니다. (크게 중요하진 않습니다.)

 

우선 Nuget Package Manager에서 "log4net"을 설치해줍니다.

 

Install-Package log4net

 

로그 저장 옵션 구성하기


프로젝트 최상단 depth에 log4net.config 파일을 생성해줍니다.

우선 아래 내용을 그대로 붙여넣으시면 됩니다.

<?xml version="1.0" encoding="utf-8"?>
<!-- 다음은 log4net 설정입니다. log4net 설정은 http://logging.apache.org/log4net/release/manual/configuration.html 의 내용을 참고하십시오. -->
<log4net>
  <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
    <threshold value="All" />
    <encoding value="utf-8" />
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <appendToFile value="true" />
    <rollingStyle value="Size" />
    <maxSizeRollBackups value="15" />
    <maximumFileSize value="64MB" />
    <file type="log4net.Util.PatternString" value="LogPractice.LOG" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date| %-5level| %thread| %logger| %message|%newline"/>
    </layout>
  </appender>
  <root>
    <appender-ref ref="RollingFile" />
  </root>
</log4net>

주의하실 점은 파일의 Properties에 "Copy to Output Directory" 를 Copy always 혹은 Copy if newer로 설정해 주셔야 합니다.

그래야 실행될 exe가 log4net.config파일을 찾을 수 있기 때문이죠.

이와 같은 논리로 프로그램 패키징을 할 때에도 꼭 포함시켜 주셔야 합니다.

 

아래는 log4net.config파일의 값들이 어떤 의미를 담고 있는지 정리한 파일입니다.

(주석이 포함되어 다소 난해해 보일 수 있으니 실제 코드에 넣으실 때는 위의 코드를 넣으시는 걸 추천합니다.)

<?xml version="1.0" encoding="utf-8"?>
<!-- 다음은 log4net 설정입니다. log4net 설정은 http://logging.apache.org/log4net/release/manual/configuration.html 의 내용을 참고하십시오. -->
<log4net>
  <appender name="RollingFile" type="log4net.Appender.RollingFileAppender"> <!-- log 를 기록하는 방식중 하나입니다. 자세한 내용은 https://logging.apache.org/log4net/release/manual/introduction.html 를 참고하십시오. -->
    <threshold value="All" /> <!-- 어느 수준의 로그를 기록할 것인지에 대한 내용을 담습니다. 자세한 내용은 게시글 아래에 정리해 두었습니다. -->
    <encoding value="utf-8" /> 
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <appendToFile value="true" /> <!-- 이 옵션이 false이면 프로그램이 실행될 때마다 새로운 파일에 로그를 기록합니다. 기존에 기록되던 파일은 .1 .2 순으로 밀려나게 됩니다. -->
    <rollingStyle value="Size" /> <!-- 어떤 기준으로 로그 파일을 나누어 저장할것인지에 대한 내용입니다. 프로그램 실행, 사이즈, 날짜 등으로 구성됩니다. 자세한 내용은 https://logging.apache.org/log4net/release/sdk/html/T_log4net_Appender_RollingFileAppender_RollingMode.htm 를 참고하십시오. -->
    <maxSizeRollBackups value="15" /> <!-- 로그 파일의 백업을 최대 몇개까지 저장할지에 대한 내용입니다. xxx.log.1 ~ xxx.log.15 까지 저장됩니다. -->
    <maximumFileSize value="64MB" /> <!-- rollingStyle이 Size일 때 필요한 값입니다. 64MB마다 로그파일이 rolling됩니다. -->
    <file type="log4net.Util.PatternString" value="LogPractice.LOG" />
    <layout type="log4net.Layout.PatternLayout">
      <!-- string format이라고 생각하시면 됩니다. 자세한 내용은 게시글 아래에서 다루도록 하겠습니다. -->
      <!-- 자세한 내용은 https://logging.apache.org/log4net/log4net-1.2.13/release/sdk/log4net.Layout.PatternLayout.html 를 참고하십시오. -->
      <conversionPattern value="%date| %-5level| %thread| %logger| %message|%newline"/>
    </layout>
  </appender>
  <root>
    <appender-ref ref="RollingFile" /> <!-- 만든 appender를 사용하겠다고 선언합니다. -->
  </root>
</log4net>

 

threadhold


threadhold는 이 appender가 어떤 수준의 로그만 기록할 것인지에 대한 값을 가지고 있습니다.

넣을 수 있는 값은 아래와 같고, 각각의 값이 어떤 수준의 로그를 기록할것인지에 대한 정보는 아래와 같습니다.

 ALL    DEBUG   INFO    WARN    ERROR   FATAL   OFF
•All                        
•DEBUG  •DEBUG                  
•INFO   •INFO   •INFO               
•WARN   •WARN   •WARN   •WARN           
•ERROR  •ERROR  •ERROR  •ERROR  •ERROR      
•FATAL  •FATAL  •FATAL  •FATAL  •FATAL  •FATAL  
•OFF    •OFF    •OFF    •OFF    •OFF    •OFF    •OFF
# 출처: https://stackoverflow.com/questions/8926409/log4net-hierarchy-and-logging-levels

threadhold와 appender-ref를 활용하여 모든 로그를 기록하는 log파일과, error만 모아서 기록하는 log파일 두 개를 관리할 수도 있습니다.

이런 식의 구조를 사용하면 오류를 찾고 분석하기 훨씬 쉬울 것입니다.

 

<?xml version="1.0" encoding="utf-8"?>
<!-- 다음은 log4net 설정입니다. log4net 설정은 http://logging.apache.org/log4net/release/manual/configuration.html 의 내용을 참고하십시오. -->
<log4net>
  <appender name="RollingFile" type="log4net.Appender.RollingFileAppender"> <!-- log 를 기록하는 방식중 하나입니다. 자세한 내용은 https://logging.apache.org/log4net/release/manual/introduction.html 를 참고하십시오. -->
    <threshold value="All" /> <!-- 어느 수준의 로그를 기록할 것인지에 대한 내용을 담습니다. 자세한 내용은 게시글 아래에 정리해 두었습니다. -->
    <encoding value="utf-8" /> 
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <appendToFile value="true" /> <!-- 이 옵션이 false이면 프로그램이 실행될 때마다 새로운 파일에 로그를 기록합니다. 기존에 기록되던 파일은 .1 .2 순으로 밀려나게 됩니다. -->
    <rollingStyle value="Size" /> <!-- 어떤 기준으로 로그 파일을 나누어 저장할것인지에 대한 내용입니다. 프로그램 실행, 사이즈, 날짜 등으로 구성됩니다. 자세한 내용은 https://logging.apache.org/log4net/release/sdk/html/T_log4net_Appender_RollingFileAppender_RollingMode.htm 를 참고하십시오. -->
    <maxSizeRollBackups value="15" /> <!-- 로그 파일의 백업을 최대 몇개까지 저장할지에 대한 내용입니다. xxx.log.1 ~ xxx.log.15 까지 저장됩니다. -->
    <maximumFileSize value="64MB" /> <!-- rollingStyle이 Size일 때 필요한 값입니다. 64MB마다 로그파일이 rolling됩니다. -->
    <file type="log4net.Util.PatternString" value="LogPractice.LOG" />
    <layout type="log4net.Layout.PatternLayout">
      <!-- string format이라고 생각하시면 됩니다. 자세한 내용은 게시글 아래에서 다루도록 하겠습니다. -->
      <!-- 자세한 내용은 https://logging.apache.org/log4net/log4net-1.2.13/release/sdk/log4net.Layout.PatternLayout.html 를 참고하십시오. -->
      <conversionPattern value="%date| %-5level| %thread| %logger| %message|%newline"/>
    </layout>
  </appender>
  <appender name="RollingFileOnlyError" type="log4net.Appender.RollingFileAppender">
    <threshold value="Error" />
    <encoding value="utf-8" />
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <appendToFile value="true" />
    <rollingStyle value="Size" />
    <maxSizeRollBackups value="15" />
    <maximumFileSize value="64MB" />
    <file type="log4net.Util.PatternString" value="LogPractice.Error.LOG" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date| %-5level| %thread| %logger| %message| %exception|%newline"/>
    </layout>
  </appender>
  <root>
    <appender-ref ref="RollingFile" /> <!-- 만든 appender를 사용하겠다고 선언합니다. -->
    <appender-ref ref="RollingFileOnlyError" />
  </root>
</log4net>

 

 

만약 config파일 없이 log4net을 사용하고 싶으시다면 아래 게시글을 확인해주세요.

https://chashtag.tistory.com/119

 

[C#] [log4net] config파일없이 log사용하기

안녕하세요. C#에서 Logging을 구현할 때 대부분 라이브러리를 사용하여 구현합니다. 저는 그중에서도 많이 쓰이는 라이브러리인 log4net을 주로 사용하는데, log4net은 config을 참조하여 logging에 관한

chashtag.tistory.com

 

log4net.config파일을 생성했다면 이제 log4net library에서 해당 파일을 참조하여 로그를 기록하도록 매핑을 시켜줘야 합니다.

 

매핑시키는 법은 간단합니다.

AssemblyInfo.cs에 아래 코드를 추가해주시면 됩니다. (마치 테스트 프로젝트를 구성할 때 InternalsVisibleTo를 설정해 주듯이 말이죠)

 

이런 식으로 구성할 수 있기 때문에 다른 이름 혹은 경로를 지정할 수도 있습니다.

 

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config")]

 

하지만 저는 .net project를 생성하였기 때문에 AssemblyInfo.cs가 없습니다.

 

.net project에서 assembly 속성을 추가하는 방법은 간단합니다.

추가하려는 프로젝트의 .csproj에 아래 내용을 추가해주시면 됩니다.

  <ItemGroup>
	<AssemblyAttribute Include="log4net.Config.XmlConfigurator">
	  <ConfigFile>log4net.config</ConfigFile>
    </AssemblyAttribute>
  </ItemGroup>

 

더 자세한 내용을 알고싶으시다면 아래 링크를 확인해주세요.

https://www.meziantou.net/declaring-internalsvisibleto-in-the-csproj.htm

 

Declaring InternalsVisibleTo in the csproj - Gérald Barré

While I prefer testing the public API of an assembly, it's sometimes useful to test the implementation details. So, an attribute that I often use is [assembly: InternalsVisibleTo("MyAssembly.Tests")] to allow the test assembly to use internal classes or me

www.meziantou.net

 

로그 출력하기


거의 다 왔습니다!

 

Program.cs를 아래와 같이 구성해줍니다.

namespace LogPractic
{
    public class Program
    {
        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public static void Main(string[] args)
        {
            log.Info("Hello World!");
        }
    }
}

 

그 후 프로그램을 실행하면,

LogPractice.log 파일이 생성되고 아래와 같은 로그가 기록되었습니다.

 

2022-03-04 21:52:35,185| INFO | 1| LogPractic.Program| Hello World!| |

 

이런 식으로 로그가 기록되는 이유는 위에서 설정했던 log4net.config의 conversionPattern과 관련 있습니다.

 

이런 식으로 말이죠.

2022-03-04 21:52:35,185|    INFO |       1| LogPractic.Program| Hello World!|           |
                  %date| %-5level| %thread|            %logger|     %message| %exception|%newline

더 다양한 값을 제공하니, 자세히 알고 싶으신 분들은 아래 링크를 확인해주세요.

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

 

PatternLayout Class

 

logging.apache.org

 

이런 식으로 로그를 기록하며 프로그램을 더욱 견고하게 만들 수 있습니다.

 

 

전체 코드는 아래 링크에서 확인하실 수 있습니다.

https://github.com/Hyo-Seong/CHashtag/tree/master/LogPractice

 

GitHub - Hyo-Seong/CHashtag: https://chashtag.tistory.com/

https://chashtag.tistory.com/. Contribute to Hyo-Seong/CHashtag development by creating an account on GitHub.

github.com

 

 

다음 게시글에서는 로그를 잘 기록하는 꿀팁에 대해 얘기해보도록 하겠습니다.

 

오늘도 긴 글 읽어주셔서 감사합니다.

도움이 되었길 바랍니다.

반응형