C# Log4Net,如何将自定义字段添加到我的日志记录中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12139486/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 22:13:20  来源:igfitidea点击:

Log4Net, how to add a custom field to my logging

c#log4netappender

提问by Eminem

I use the log4net.Appender.AdoNetAppender appender.
My log4net table are the following fields [Date],[Thread],[Level],[Logger],[Message],[Exception]

我使用 log4net.Appender.AdoNetAppender 附加程序。
我的 log4net 表是以下字段[Date],[Thread],[Level],[Logger],[Message],[Exception]

I would need to add another field to the log4net table (e.g SalesId), but how would I specify in my xml and in code to log the "SalesId" when logging a Error or Info message?

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

e.g. log.Info("SomeMessage", SalesId)

例如 log.Info("SomeMessage", SalesId)

Here's the log4net xml

这是 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>

采纳答案by Marcelo De Zen

1) Modify the command text: INSERT INTO Log4Net ([Date],[Thread],[Level],[Logger],[Message],[Exception],[MyColumn]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception, @CustomColumn)

1)修改命令文本: INSERT INTO Log4Net ([Date],[Thread],[Level],[Logger],[Message],[Exception],[MyColumn]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception, @CustomColumn)

2) Add the parameter definition for the custom column:

2)添加自定义列的参数定义:

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

3) Then use one of log4net's contexts to transfer values to the parameter:

3)然后使用log4net的上下文之一将值传输到参数:

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

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

回答by Ali Karaca

Here is a working version with some personalized preferences. I added a custom column for storing a generated exception code.

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

1) Add your custom column(exceptionCode here) to Log4net config:

1)将您的自定义列(此处的异常代码)添加到 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

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

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

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 // Enjoy your logger with new column! :)

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;
        }
    }
}

references:

参考:

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

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

回答by piyush gupta

Three types of logging context available in Log4Net.

Log4Net 中可用的三种类型的日志记录上下文。

  1. Log4Net.GlobalContext :- This context shared across all application threads and domains.If two threads set the same property on GlobalContext, One Value will override the other.

  2. Log4Net.ThreadContext :- This context scope limited to calling thread. Here two threads can set same property to different values without overriding to each other.

  3. Log4Net.ThreadLogicalContext :- This context behaves similarly to the ThreadContext. if you're working with a custom thread pool algorithm or hosting the CLR, you may find some use for this one.

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

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

  3. Log4Net.ThreadLogicalContext :- 此上下文的行为类似于 ThreadContext。如果您正在使用自定义线程池算法或托管 CLR,您可能会发现该算法有一些用处。

Add the following code to your program.cs file:

将以下代码添加到您的 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) Add the parameter definition for the custom column:

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>