ejemplo application c# log4net appender

application - log4net implementation in c#



Log4Net, cómo agregar un campo personalizado a mi registro (2)

1) Modifique el texto del comando: INSERT INTO Log4Net ([Date],[Thread],[Level],[Logger],[Message],[Exception],[MyColumn]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception, @CustomColumn)

2) Agregue la definición del parámetro para la columna personalizada:

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

3) Luego use uno de los contextos de log4net para transferir valores al parámetro:

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

Uso el apilador log4net.Appender.AdoNetAppender.
Mi tabla log4net son los siguientes campos [Date],[Thread],[Level],[Logger],[Message],[Exception]

Necesitaría agregar otro campo a la tabla log4net (por ejemplo, SalesId), pero ¿cómo especificaría en mi xml y en el código para registrar el "SalesId" cuando registre un mensaje de error o información?

por ejemplo, log.Info("SomeMessage", SalesId)

Aquí está el 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>


Aquí hay una versión funcional con algunas preferencias personalizadas. Agregué una columna personalizada para almacenar un código de excepción generado.

1) Agregue su columna personalizada (exceptionCode aquí) a la configuración de 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 // ¡Disfruta de tu registrador con una nueva columna! :)

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

referencias:

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