¿Cómo registrar NombreMetodológico al ajustar Log4net?

He envuelto Log4net en un contenedor estático y quiero iniciar sesión

loggingEvent.LocationInformation.MethodName loggingEvent.LocationInformation.ClassName 

Sin embargo, todo lo que obtengo es el nombre de mi envoltorio.

¿Cómo puedo registrar esa información usando un forwardingappender y una clase de contenedor estático como

 Logger.Debug("Logging to Debug"); Logger.Info("Logging to Info"); Logger.Warn("Logging to Warn"); Logger.Error(ex); Logger.Fatal(ex); 

¿Qué pasa con las variables %M y %C ? http://logging.apache.org/log4net/log4net-1.2.11/release/sdk/log4net.Layout.PatternLayout.html

Uso, algo como:

    

¿Eso no hace lo que estás buscando?

Bueno, el error estaba en algún lugar de mi apéndice, pero para completarlo, incluiré la respuesta a mi leal saber y entender:

la fachada que necesita debe envolver ILogger y NO ILog

  public static class Logger { private readonly static Type ThisDeclaringType = typeof(Logger); private static readonly ILogger defaultLogger; static Logger() { defaultLogger = LoggerManager.GetLogger(Assembly.GetCallingAssembly(),"MyDefaultLoggger"); 

  public static void Info(string message) { if (defaultLogger.IsEnabledFor(infoLevel)) { defaultLogger.Log(typeof(Logger), infoLevel, message, null); } } 

Simplemente declare su variable de registro así …

 private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 

Entonces puedes usarlo normalmente.

Esta publicación me ayudó a pensar en cómo escribir mi propio contenedor, a cambio, pensé que te gustaría que mi clase completa envuelva el registrador, que parece funcionar muy bien y que en realidad lleva más de la mitad de tiempo que usar un ILog directamente.

Todo lo que se requiere es el xml apropiado para configurar el registro en el archivo de configuración y

 [assembly: log4net.Config.XmlConfigurator(Watch = true)] 

en su AssemblyInfo.cs y debería funcionar fácilmente.

Una nota: estoy usando Log4NetDash con una configuración muy simple, así que hice trampa y puse algo de información en los campos incorrectos (por ejemplo, seguimiento de la stack en el campo Dominio), esto todavía funciona para mí ya que no me importa dónde está la información. se muestra, pero es posible que desee corregir esto si está configurando cosas correctamente si tiene tiempo libre.

 using System; using System.ComponentModel; using System.Diagnostics; using System.Reflection; using System.Threading; using log4net; using log4net.Core; namespace Utility { public class Logger { static Logger() { LogManager.GetLogger(typeof(Logger)); } public static void Debug(string message, params object[] parameters) { Log(message, Level.Debug, null, parameters); } public static void Info(string message, params object[] parameters) { Log(message, Level.Info, null, parameters); } public static void Warn(string message, params object[] parameters) { Log(message, Level.Warn, null, parameters); } public static void Error(string message, params object[] parameters) { Error(message, null, parameters); } public static void Error(Exception exception) { if (exception==null) return; Error(exception.Message, exception); } public static void Error(string message, Exception exception, params object[] parameters) { string exceptionStack = ""; if (exception != null) { exceptionStack = exception.GetType().Name + " : " + exception.Message + Environment.NewLine; Exception loopException = exception; while (loopException.InnerException != null) { loopException = loopException.InnerException; exceptionStack += loopException.GetType().Name + " : " + loopException.Message + Environment.NewLine; } } Log(message, Level.Error, exceptionStack, parameters); } private static void Log(string message, Level logLevel, string exceptionMessage, params object[] parameters) { BackgroundWorker worker = new BackgroundWorker(); worker.DoWork += LogEvent; worker.RunWorkerAsync(new LogMessageSpec { ExceptionMessage = exceptionMessage, LogLevel = logLevel, Message = message, Parameters = parameters, Stack = new StackTrace(), LogTime = DateTime.Now }); } private static void LogEvent(object sender, DoWorkEventArgs e) { try { LogMessageSpec messageSpec = (LogMessageSpec) e.Argument; StackFrame frame = messageSpec.Stack.GetFrame(2); MethodBase method = frame.GetMethod(); Type reflectedType = method.ReflectedType; ILogger log = LoggerManager.GetLogger(reflectedType.Assembly, reflectedType); Level currenLoggingLevel = ((log4net.Repository.Hierarchy.Logger) log).Parent.Level; if (messageSpec.LogLevel 

Simplemente usaría algo como %stacktrace{2} como un patrón de conversión.

Ejemplo de salida:

MyNamespace.ClassName.Method> Common.Log.Warning

donde MyNamespace.ClassName.Method es un método que llama a mi envoltorio y Common.Log.Warning es un método de la clase contenedora.

Los patrones de conversión se pueden encontrar aquí .

Lo único que se me ocurre hacer (ya que actualmente no uso log4net) es solicitar un stacktrace (nuevo StackTrace) y retroceder un cuadro para obtener la información que necesita. Sin embargo, no estoy seguro del impacto en el rendimiento del tiempo de ejecución de esto.

Escribiré más código de la respuesta correcta de Claus

En la clase de envoltura

 public static class Logger { private static readonly ILogger DefaultLogger; static Logger() { defaultLogger = LoggerManager.GetLogger(Assembly.GetCallingAssembly(), "MyDefaultLoggger"); // MyDefaultLoggger is the name of Logger } public static void LogError(object message) { Level errorLevel = Level.Error; if (DefaultLogger.IsEnabledFor(errorLevel)) { DefaultLogger.Log(typeof(Logger), errorLevel, message, null); } } public static void LogError(object message, Exception exception) { Level errorLevel = Level.Error; if (DefaultLogger.IsEnabledFor(errorLevel)) { DefaultLogger.Log(typeof(Logger), errorLevel, message, exception); } } 

y así sucesivamente para el rest de métodos.

en web.config o app.config log4net.Layout.PatternLayout puede usar algunos patrones de conversión como:

 %location %method %line