Log4Net วิธีเพิ่มฟิลด์ที่กำหนดเองในการบันทึกของฉัน


98

ฉันใช้แอปพลิเคชัน log4net.Appender.AdoNetAppender
ตาราง 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>

คำตอบ:


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 ใน Web Application แม้ว่าสิ่งเหล่านี้มีแนวโน้มที่จะข้ามเธรดและ ThreadContext จะไม่ถูกย้ายไปด้วย
Robba

4
@theberserker LogicalThreadContextสามารถใช้กับ Tasks ได้ แต่ไม่เป็นไรที่จะใช้ThreadContextเพราะมันจะเชื่อมโยงกับเธรดเฉพาะ
Marcelo De Zen

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) เพิ่มคอลัมน์ที่กำหนดเองของคุณ (exceptionCode ที่นี่) ใน Log4net config:

<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.