Log4Net, 내 로깅에 사용자 정의 필드를 추가하는 방법


98

log4net.Appender.AdoNetAppender appender를 사용합니다.
내 log4net 테이블은 다음 필드입니다.[Date],[Thread],[Level],[Logger],[Message],[Exception]

log4net 테이블 (예 : SalesId)에 다른 필드를 추가해야하지만 오류 또는 정보 메시지를 기록 할 때 "SalesId"를 기록하기 위해 XML과 코드에서 어떻게 지정해야합니까?

예 : log.Info("SomeMessage", SalesId)

다음은 log4net xml입니다.

  <appender name="SalesDBAppender" type="log4net.Appender.AdoNetAppender">
    <bufferSize value="1" />
    <connectionType value ="System.Data.SqlClient.SqlConnection" />
    <connectionString value="Data Source=..." />
    <commandText value="INSERT INTO Log4Net ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" />
    <parameter>
      <parameterName value="@log_date" />
      <dbType value="DateTime" />
      <layout type="log4net.Layout.RawTimeStampLayout" />
    </parameter>
    <parameter>
      <parameterName value="@thread" />
      <dbType value="String" />
      <size value="255" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%thread" />
      </layout>
    </parameter>
    <parameter>
      <parameterName value="@log_level" />
      <dbType value="String" />
      <size value="50" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%level" />
      </layout>
    </parameter>
    <parameter>
      <parameterName value="@logger" />
      <dbType value="String" />
      <size value="255" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%logger" />
      </layout>
    </parameter>
    <parameter>
      <parameterName value="@message" />
      <dbType value="String" />
      <size value="4000" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%message" />
      </layout>
    </parameter>
    <parameter>
      <parameterName value="@exception" />
      <dbType value="String" />
      <size value="2000" />
      <layout type="log4net.Layout.ExceptionLayout" />
    </parameter>
  </appender>

답변:


190

1) 명령 텍스트를 수정합니다. INSERT INTO Log4Net ([Date],[Thread],[Level],[Logger],[Message],[Exception],[MyColumn]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception, @CustomColumn)

2) 사용자 정의 열에 대한 매개 변수 정의를 추가하십시오.

<parameter>
   <parameterName value="@CustomColumn"/>
   <dbType value="String" />
   <size value="255" />
   <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%property{CustomColumn}" />
  </layout>
</parameter>

3) 그런 다음 log4net의 컨텍스트 중 하나를 사용하여 값을 매개 변수로 전송합니다.

// thread properties...
log4net.LogicalThreadContext.Properties["CustomColumn"] = "Custom value";
log.Info("Message"); 

// ...or global properties
log4net.GlobalContext.Properties["CustomColumn"] = "Custom value";

2
누군가가 브라우저 기능을 로깅하는 데 가장 적합한 컨텍스트를 제안 할 수 있습니까?
VivekDev

1
@DumbDev, 일반적으로 스레드 컨텍스트를 사용합니다. GlobalContext는 자주 변경되지 않는 속성을 설정하는 데 유용합니다.
Marcelo De Zen

1
웹 응용 프로그램에서 ThreadContext를 사용할 때는 스레드를 점프하는 경향이 있고 ThreadContext가 함께 이동되지 않기 때문에 매우주의해야합니다.
Robba

4
@theberserker LogicalThreadContext는 작업과 함께 사용하는 것이 좋지만 ThreadContext항상 특정 스레드에 제한되어 있기 때문에 사용하는 것은 좋지 않습니다 .
마르셀로 데 젠

5
제 의견입니다 만, 이런 식으로 조금 이상해 보입니다. 새 LoggingEvent 인스턴스에 추가하는 데 더 많은 인수가 필요한 오버로드를 예상했습니다.
A77

6

Log4Net에서 사용할 수있는 세 가지 유형의 로깅 컨텍스트.

  1. Log4Net.GlobalContext :-이 컨텍스트는 모든 응용 프로그램 스레드 및 도메인에서 공유됩니다. 두 스레드가 GlobalContext에 동일한 속성을 설정하면 하나의 값이 다른 값을 재정의합니다.

  2. Log4Net.ThreadContext :-이 컨텍스트 범위는 스레드 호출로 제한됩니다. 여기서 두 스레드는 서로 재정의하지 않고 동일한 속성을 다른 값으로 설정할 수 있습니다.

  3. Log4Net.ThreadLogicalContext :-이 컨텍스트는 ThreadContext와 유사하게 작동합니다. 사용자 지정 스레드 풀 알고리즘으로 작업하거나 CLR을 호스팅하는 경우이 알고리즘을 사용할 수 있습니다.

program.cs 파일에 다음 코드를 추가합니다.

static void Main( string[] args )
{
    log4net.Config.XmlConfigurator.Configure();
    log4net.ThreadContext.Properties[ "myContext" ] = "Logging from Main";
    Log.Info( "this is an info message" );
    Console.ReadLine();
}

2) 사용자 정의 열에 대한 매개 변수 정의를 추가하십시오.

  <log4net>      
    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%logger (%property{myContext}) [%level]- %message%newline" />
      </layout>
    </appender> 
  </log4net>

3

다음은 몇 가지 개인화 된 기본 설정이있는 작업 버전입니다. 생성 된 예외 코드를 저장하기위한 사용자 지정 열을 추가했습니다.

1) Log4net 구성에 사용자 지정 열 (exceptionCode 여기)을 추가합니다.

<commandText value="INSERT INTO Log([Date],[Thread],[Level],[Logger],[Message],[Exception],[ExceptionCode]) 
VALUES (@log_date, @thread, @log_level, @logger, @message, @exception,@exceptionCode)" />

<parameter>
    <parameterName value="@exceptionCode" />
    <dbType value="String" />
    <size value="11" />
    <layout type="Common.Utils.LogHelper.Log4NetExtentedLoggingPatternLayout">
        <conversionPattern value="%exceptionCode{Code}" />
    </layout>
</parameter>

2) Log4NetExtentedLoggingCustomParameters.cs

namespace Common.Utils.LogHelper
{
    public class Log4NetExtentedLoggingCustomParameters
    {
        public string ExceptionCode { get; set; }

        public string Message { get; set; }

        public override string ToString()
        {
            return Message;
        }
    }
}

3) Log4NetExtentedLoggingPatternConverter.cs

namespace Common.Utils.LogHelper
{
    public class Log4NetExtentedLoggingPatternConverter : PatternConverter
    {
        protected override void Convert(TextWriter writer, object state)
        {
            if (state == null)
            {
                writer.Write(SystemInfo.NullText);
                return;
            }

            var loggingEvent = state as LoggingEvent;
            var messageObj = loggingEvent.MessageObject as Log4NetExtentedLoggingCustomParameters;

            if (messageObj == null)
            {
                writer.Write(SystemInfo.NullText);
            }
            else
            {
                switch (this.Option.ToLower()) //this.Option = "Code"
                {
                    case "code": //config conversionPattern parameter -> %exceptionCode{Code}
                        writer.Write(messageObj.ExceptionCode);
                        break;  
                    default:
                        writer.Write(SystemInfo.NullText);
                        break;
                }
            }
        }
    }
}

4) Log4NetExtentedLoggingPatternLayout.cs

namespace Common.Utils.LogHelper
{
    public class Log4NetExtentedLoggingPatternLayout : PatternLayout
    {
        public Log4NetExtentedLoggingPatternLayout()
        {
            var customConverter = new log4net.Util.ConverterInfo()
            {
                Name = "exceptionCode",
                Type = typeof(Log4NetExtentedLoggingPatternConverter)
            };

            AddConverter(customConverter);
        }
    }
}

5) Logger.cs // 새 열로 로거를 즐기십시오! :)

namespace Common.Utils.LogHelper
{
    public class Logger
    {
        static ILog Logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public static string LogError(string message, Exception exception = null)
        {
            var logWithErrCode = GetLogWithErrorCode(message);
            Logger.Error(logWithErrCode, exception);
            return logWithErrCode.ExceptionCode;
        }

        private static Log4NetExtentedLoggingCustomParameters GetLogWithErrorCode(string message)
        {
            var logWithErrCode = new Log4NetExtentedLoggingCustomParameters();
            logWithErrCode.ExceptionCode = GenerateErrorCode(); //this method is absent for simplicity. Use your own implementation
            logWithErrCode.Message = message;
            return logWithErrCode;
        }
    }
}

참조 :

http://blog.stvjam.es/2014/01/logging-custom-objects-and-fields-with

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.