Log4net Edition

이전 Log4net의 정리에 이어 최근 한가할 때 log4net을 봉하여 가능한 요구 사항, 예를 들어 다단계 로그와 다파일 로그를 조사했다.

1. 단일 파일 로그


단일 파일의 로그에 대한 패키지된 코드는 다음과 같습니다.
public enum LogMessageType
{
    Debug,
    Info,
    Warn,
    Error,
    Fatal
}
public sealed class LogProvider
{
    private static readonly ILog provider = GetLogger();
    static LogProvider() { }
    private LogProvider() { }

    public static void Write(string msg, LogMessageType msgType, Exception ex = null)
    {
        WriteLog(msg, msgType, ex);
    }
    public static void InitConfig()
    {
        XmlConfigurator.Configure();
    }
    public static void ShutDown()
    {
        LogManager.Shutdown();
    }

    private static ILog GetLogger()
    {
        InitConfig();
        return LogManager.GetLogger("DefaultLogger");
    }
    private static void WriteLog(string msg, LogMessageType msgType, Exception ex)
    {
        if (provider != null)
        {
            switch (msgType)
            {
                case LogMessageType.Debug:
                    provider.Debug(msg, ex);
                    break;
                case LogMessageType.Info:
                    provider.Info(msg, ex);
                    break;
                case LogMessageType.Warn:
                    provider.Warn(msg, ex);
                    break;
                case LogMessageType.Error:
                    provider.Error(msg, ex);
                    break;
                case LogMessageType.Fatal:
                    provider.Fatal(msg, ex);
                    break;
            }
        }
    }
}
이렇게 로그를 기록할 곳은 LogProvider만 필요합니다.Write("this is Log", LogMessageType.Error);코드 한 줄이면 Log4net 초기화 작업은 초기화기에 봉인되어 있으며, 처음으로 Log4net을 호출할 때 자동으로 초기화됩니다.LogProvider 클래스는 세 가지 정적 방법을 개방한다. 그것이 바로 Write,InitConfig,ShutDown이다. 그 다음에 두 가지는 프로그램에서 Log4net의 열기와 닫기를 수동으로 제어하는 데 사용된다.Write 메서드는 재부팅 효과를 위해 기본 매개 변수를 사용합니다.구성 파일은 다음과 같습니다.
<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="log4net" 
             type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
  </configSections>
  <log4net>
    <logger name="DefaultLogger">
      <level value="ALL"/>
      <appender-ref ref="txtLogger" />
    </logger>
    <appender name="txtLogger" 
              type="log4net.Appender.RollingFileAppender,log4net" >
      <File value="Log\Log.txt" />
      <datePattern value="(yyyyMMdd)"/>
      <appendToFile value="true"/>
      <RollingStyle value="Composite"/>
      <MaxSizeRollBackups value="10"/>
      <maximumFileSize value="1MB"/>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%t]%-5p %c - %m%n"/>
      </layout>
    </appender>
  </log4net>
  <startup/>
</configuration>
유일하게 주의해야 할 것은 이것은 연결에 사용됩니다. 도움말 클래스는 설정 파일과 일치해야 하며, 다른 매개 변수는 이전에 쓴 log4net의 설정을 참조하십시오.

2. 단계별 로그 기록

코드를 재구성할 때 나는 우리의 원래 로그 프레임워크에 서로 다른 단계의 로그를 분리해서 기록하는 기능이 있다는 것을 생각했다. 예를 들어 붕괴와 오류를 한 파일에 기록하고 경고와 정보를 한 파일에 기록하면 문제를 조사할 때 중대한 오류를 먼저 볼 수 있다.이 요구 사항을 조사한 결과 다음과 같이 구성 파일에 구성할 수도 있습니다.
<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="log4net" 
             type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
  </configSections>
  <log4net>
    <logger name="DefaultLogger">
      <level value="ALL"/>
      <appender-ref ref="InfoLoging" />
      <appender-ref ref="ErrorLoging" />
    </logger>
    <!--DefaultLogger Info Log-->
    <appender name="InfoLoging" 
              type="log4net.Appender.RollingFileAppender,log4net" >
      <File value="Log\LogTipMsg.txt" />
      <datePattern value="(yyyyMMdd)"/>
      <appendToFile value="true"/>
      <RollingStyle value="Composite"/>
      <MaxSizeRollBackups value="10"/>
      <maximumFileSize value="1MB"/>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%t]%-5p %c - %m%n"/>
      </layout>
      <filter type="log4net.Filter.LevelRangeFilter">
        <LevelMin value="DEBUG"/>
        <LevelMax value="Warn"/>
      </filter>
    </appender>
    <!--DefaultLogger Error Log-->
    <appender name="ErrorLoging" 
              type="log4net.Appender.RollingFileAppender,log4net" >
      <File value="Log\LogErrorMsg.txt" />
      <datePattern value="(yyyyMMdd)"/>
      <appendToFile value="true"/>
      <RollingStyle value="Composite"/>
      <MaxSizeRollBackups value="10"/>
      <maximumFileSize value="1MB"/>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%t]%-5p %c - %m%n"/>
      </layout>
      <filter type="log4net.Filter.LevelRangeFilter">
        <LevelMin value="ERROR" />
      </filter>
    </appender>
  </log4net>
  <startup/>
</configuration>

3. 업무 논리에 따라 로그를 기록한다.

또 다른 시나리오는 다음과 같은 구성을 통해 비즈니스 모듈별로 다른 파일에 기록되는 것입니다.
<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="log4net"
             type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
  </configSections>
  <log4net>
    <logger name="DefaultLogger">
      <level value="ALL"/>
      <appender-ref ref="InfoLoging" />
      <appender-ref ref="ErrorLoging" />
    </logger>
    <logger name="OtherCustomerLogger">
      <level value="Info"/>
      <appender-ref ref="OtherInfoLoging" />
    </logger>
    <!--DefaultLogger Info Log-->
    <appender name="InfoLoging" 
              type="log4net.Appender.RollingFileAppender,log4net" >
      <File value="Log\LogTipMsg.txt" />
      <datePattern value="(yyyyMMdd)"/>
      <appendToFile value="true"/>
      <RollingStyle value="Composite"/>
      <MaxSizeRollBackups value="10"/>
      <maximumFileSize value="1MB"/>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%t]%-5p %c - %m%n"/>
      </layout>
      <filter type="log4net.Filter.LevelRangeFilter">
        <LevelMin value="DEBUG"/>
        <LevelMax value="Warn"/>
      </filter>
    </appender>
    <!--DefaultLogger Error Log-->
    <appender name="ErrorLoging" 
              type="log4net.Appender.RollingFileAppender,log4net" >
      <File value="Log\LogErrorMsg.txt" />
      <datePattern value="(yyyyMMdd)"/>
      <appendToFile value="true"/>
      <RollingStyle value="Composite"/>
      <MaxSizeRollBackups value="10"/>
      <maximumFileSize value="1MB"/>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%t]%-5p %c - %m%n"/>
      </layout>
      <filter type="log4net.Filter.LevelRangeFilter">
        <LevelMin value="ERROR" />
      </filter>
    </appender>
    <!--OtherCustomerLogger OtherInfo Log-->
    <appender name="OtherInfoLoging" 
              type="log4net.Appender.RollingFileAppender,log4net" >
      <File value="Log\LogOtherInfoLoging.txt" />
      <datePattern value="(yyyyMMdd)"/>
      <appendToFile value="true"/>
      <RollingStyle value="Composite"/>
      <MaxSizeRollBackups value="10"/>
      <maximumFileSize value="1MB"/>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%t]%-5p %c - %m%n"/>
      </layout>
    </appender>
  </log4net>
  <startup/>
</configuration>
이때 도움말 클래스는 적절하게 조정해야 한다. 코드는 다음과 같다.
public enum LogicType
{
    DefaultLogger,
    OtherCustomerLogger
}
public enum LogMessageType
{
    Debug,
    Info,
    Warn,
    Error,
    Fatal
}
public sealed class LogProvider
{
    static LogProvider() { }
    private LogProvider() { }

    private static readonly Dictionary<string, ILog> dicLoggers = GetLoggers();

    public static void Write(string msg, LogMessageType msgType, Exception ex = null)
    {
        WriteLog(msg, msgType, ex);
    }
    public static void Write(string msg, 
        LogMessageType msgType, LogicType logicType, Exception ex = null)
    {
        WriteLog(msg, msgType, ex, logicType.ToString());
    }
    public static void InitConfig()
    {
        XmlConfigurator.Configure();
    }
    public static void ShutDown()
    {
        LogManager.Shutdown();
    }

    static Dictionary<string, ILog> GetLoggers()
    {
        InitConfig();
        ILog[] allLoggers = LogManager.GetCurrentLoggers();
        Dictionary<string, ILog> dicLoggers = new Dictionary<string, ILog>();
        foreach (var logger in allLoggers)
        {
            dicLoggers.Add(logger.Logger.Name, logger);
        }
        return dicLoggers;
    }
    static void WriteLog(string msg, 
        LogMessageType msgType, Exception ex, string logicType = "DefaultLogger")
    {
        if (dicLoggers != null && dicLoggers[logicType] != null)
        {
            switch (msgType)
            {
                case LogMessageType.Debug:
                    dicLoggers[logicType].Debug(msg, ex);
                    break;
                case LogMessageType.Info:
                    dicLoggers[logicType].Info(msg, ex);
                    break;
                case LogMessageType.Warn:
                    dicLoggers[logicType].Warn(msg, ex);
                    break;
                case LogMessageType.Error:
                    dicLoggers[logicType].Error(msg, ex);
                    break;
                case LogMessageType.Fatal:
                    dicLoggers[logicType].Fatal(msg, ex);
                    break;
            }
        }
    }
}
LogicType이라는 매거진을 추가하여 특정 업무 논리 로그를 기록할 때 LogProvider.Write("this is Other Info", LogMessageType.Info, LogicType.OtherCustomerLogger).실제 조작은 업무 논리에 따라 이 매거를 확충하는 것이다.
이로써 이 버전은 프로젝트에 직접 사용할 수 있으며 설정만 하면 되며 코드를 추가로 변경할 필요가 없습니다.
후기: 포장 과정에서 몇 가지 문제에 부딪혔다. 예를 들어readonly와 정적 구조 함수에 대한 문제는 당시에 그에 대한 이해가 철저하지 못해서 한참을 의심했고 나중에 틈이 나면 함께 정리했다.종결판이라 프로젝트의 안정적인 버전이 될 수 있지만 부족한 부분도 있다. 예를 들어 6개월 동안 로그를 스크롤해서 저장하고 싶은데 지금은 로그4net이 실현될 수 있을지 모르겠다(또는 어떻게 실현될 수 있는지, 만약에 내가 실현시키면 나는 매일 한 번씩 라인만 쓸 수 있고 6개월 전의 로그가 있으면 삭제할 수 있다).독자들에게 도움이 되었으면 좋겠습니다. 만약 무슨 잘못이나 생각이 있으면 아낌없이 가르쳐 주시기 바랍니다. 전재는 원문 링크를 보존해 주십시오.
소스 코드 다운로드

좋은 웹페이지 즐겨찾기