首页 文章

Log4Net,如何在我的日志记录中添加自定义字段

提问于
浏览
84

我使用log4net.Appender.AdoNetAppender appender .
我的log4net表是以下字段 [Date],[Thread],[Level],[Logger],[Message],[Exception]

我需要在log4net表中添加另一个字段(例如SalesId),但是如何在我的xml和代码中指定在记录错误或信息消息时记录“SalesId”?

例如 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>

3 回答

  • 171

    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";
    
  • 0

    Log4Net中有三种类型的日志记录上下文 .

    • Log4Net.GlobalContext: - 此上下文在所有应用程序线程和域之间共享 . 如果两个线程在GlobalContext上设置相同的属性,则One Value将覆盖另一个 .

    • Log4Net.ThreadContext: - 此上下文范围仅限于调用线程 . 这里有两个线程可以将相同的属性设置为不同的值,而不会相互覆盖 .

    • 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>
    
  • 1

    这是一个具有一些个性化偏好的工作版本 . 我添加了一个自定义列来存储生成的异常代码 .

    1)将自定义列(此处为exceptionCode)添加到Log4net配置:

    <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 //使用新专栏享受您的 Logger ! :)

    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

相关问题