Log4Net, cara menambahkan bidang kustom ke logging saya

98

Saya menggunakan appender log4net.Appender.AdoNetAppender.
Tabel log4net saya adalah bidang berikut[Date],[Thread],[Level],[Logger],[Message],[Exception]

Saya perlu menambahkan bidang lain ke tabel log4net (misalnya, SalesId), tetapi bagaimana saya menentukan dalam xml saya dan dalam kode untuk mencatat "SalesId" saat membuat pesan Error atau Info?

misalnya log.Info("SomeMessage", SalesId)

Inilah 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>
Eminem
sumber

Jawaban:

190

1) Ubah teks perintah: INSERT INTO Log4Net ([Date],[Thread],[Level],[Logger],[Message],[Exception],[MyColumn]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception, @CustomColumn)

2) Tambahkan definisi parameter untuk kolom kustom:

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

3) Kemudian gunakan salah satu konteks log4net untuk mentransfer nilai ke parameter:

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

// ...or global properties
log4net.GlobalContext.Properties["CustomColumn"] = "Custom value";
Marcelo De Zen
sumber
2
Dapatkah seseorang menyarankan Konteks mana yang terbaik untuk mencatat kemampuan browser.
VivekDev
1
@DumbDev, biasanya Anda akan menggunakan konteks Thread. GlobalContext berguna untuk mengatur properti yang tidak sering berubah.
Marcelo De Zen
1
Anda harus sangat berhati-hati saat menggunakan ThreadContext dalam Aplikasi Web karena ini cenderung melompati utas dan ThreadContext tidak akan dipindahkan bersamanya.
Robba
4
@theberserker boleh LogicalThreadContextdigunakan dengan Tasks, Namun tidak boleh digunakan ThreadContext, karena selalu dibatasi ke utas tertentu.
Marcelo De Zen
5
Itu pendapat saya, tetapi tampaknya agak aneh dengan cara ini, saya mengharapkan kelebihan beban yang membutuhkan lebih banyak argumen untuk ditambahkan ke contoh LoggingEvent baru ..
A77
6

Tiga jenis konteks pencatatan tersedia di Log4Net.

  1. Log4Net.GlobalContext: - Konteks ini dibagikan ke semua utas aplikasi dan domain. Jika dua utas menyetel properti yang sama di GlobalContext, Satu Nilai akan menimpa yang lain.

  2. Log4Net.ThreadContext: - Lingkup konteks ini terbatas pada thread panggilan. Di sini dua utas dapat menyetel properti yang sama ke nilai berbeda tanpa menimpa satu sama lain.

  3. Log4Net.ThreadLogicalContext: - Konteks ini berperilaku mirip dengan ThreadContext. jika Anda bekerja dengan algoritme kumpulan utas khusus atau menghosting CLR, Anda mungkin menemukan beberapa kegunaan untuk yang satu ini.

Tambahkan kode berikut ke file program.cs Anda:

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) Tambahkan definisi parameter untuk kolom kustom:

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

Ini adalah versi yang berfungsi dengan beberapa preferensi yang dipersonalisasi. Saya menambahkan kolom kustom untuk menyimpan kode pengecualian yang dihasilkan.

1) Tambahkan kolom kustom Anda (exceptionCode di sini) ke konfigurasi 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 // Nikmati logger Anda dengan kolom baru! :)

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

referensi:

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

Ali Karaca
sumber