2011-04-09 19 views
7

Estoy usando log4net para iniciar sesión en mi aplicación. Mi FileAppender funciona bien, pero tengo problemas con MemoryAppender.log4net MemoryAppender no funciona

Aquí está mi archivo de configuración.

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <configSections> 
     <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" /> 
    </configSections> 
<log4net> 
<appender name="LogFileAppender" type="log4net.Appender.FileAppender"> 
    <param name="File" value="Envision.log" /> 
    <param name="AppendToFile" value="true" /> 
    <layout type="log4net.Layout.PatternLayout"> 
    <param name="Header" value="" /> 
    <param name="Footer" value="" /> 
    <param name="ConversionPattern" value="%d [%t] %-5p %m%n" /> 
    </layout> 
</appender> 
<appender name="MemoryAppender" type="log4net.Appender.MemoryAppender"> 

</appender> 
<root> 
    <level value="ALL" /> 
    <appender-ref ref="LogFileAppender" /> 
    <appender-ref ref="MemoryAppender" /> 
</root> 
</log4net> 
</configuration> 

Utilizo este código para configurar el archivo de configuración.

FileInfo file = new FileInfo(configPath); 
log4net.Config.XmlConfigurator.Configure(file); 
file = null; 

Como he dicho, FileAppender funciona muy bien. Pero parece que no puedo obtener ningún evento. He intentado utilizar algo como esto para obtener el MemoryAppender.

Hierarchy hierarchy = LogManager.GetRepository() as Hierarchy; 
MemoryAppender mappender = hierarchy.Root.GetAppender("MemoryAppender") as MemoryAppender; 

He intentado usar:

var events = mappender.GetEvents() 

después de entrar algo, y eventos es siempre vacío. Intenté configurar el FileAppender y el MemoryAppender en el código en lugar de usar el archivo de configuración, y me sale igual, el FileAppender funciona bien, pero parece que no puedo obtener ningún evento de MemoryAppender. Curioso si entiendo MemoryAppender ¿verdad? También intenté configurar un hilo que revisa si GetEvents no está vacío y, al cerrar la sesión, siempre vuelve vacío. Intenté configurar el umbral en Core.Level.All en el MemoryAppender pero eso no cambió nada.

Gracias por cualquier dirección. He mirado alrededor, y de los sitios que he visto, no puedo decir qué estoy haciendo diferente.

Incluso algo tan simple como esto no funciona. la duración de los eventos es siempre cero;

public partial class MainWindow : Window { 
    public MainWindow() { 
     InitializeComponent(); 

     MemoryAppender appender = new MemoryAppender(); 
     ILog logger = LogManager.GetLogger("foo"); 
     BasicConfigurator.Configure(appender); 

     logger.Error("Should work"); 
     var events = appender.GetEvents(); 
    } 
} 

Respuesta

1

Me di cuenta. Estaba usando Compact Framework .dll por error. Una vez que me di cuenta de que cambié a la versión .net 2.0, lo que causó un problema con el espacio de nombres log4net no se encontró, entonces hice una búsqueda sobre eso y me di cuenta de que necesitaba cambiar mi perfil de cliente de .NET Framework 4 a .NET Framework 4. Ahora estoy recibiendo los eventos como se esperaba.

1

El código de ejemplo simple que registró me da buenos resultados usando log4net 1.2.10.0.

Recomendaría descargar la fuente y recorrerla en un depurador. Puede parecer un poco desalentador al principio, pero te acostumbras a su código bastante rápido y no es difícil de seguir. He hecho esto muchas veces cuando tuve problemas con restricciones y apéndices personalizados. Realmente ayuda a resolver problemas rápidamente y le da una mejor comprensión de cómo funciona log4net.

9

Para aquellos que lo necesitan, aquí está cómo hacerlo mediante programación en C#:

var memoryAppender = new MemoryAppender(); 
var repository = (log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository(); 
repository.Root.AddAppender(memoryAppender); 
var events = memoryAppender.GetEvents(); 
+1

Brillante, gracias!Solo quería capturar líneas de registro (sin agregar un marco de burla a mi proyecto) para pruebas unitarias, así que adapté tu código – CZahrobsky

1

que utiliza código de Ralph por encima de mi unidad de pruebas:

using log4net; 
using log4net.Appender; 
// ... 
internal static MemoryAppender GetMemoLog<T>() where T: class 
{ 
    var memoLog = new MemoryAppender(); 
    ILog appendableLog = LogManager.GetLogger(typeof(T).Assembly, typeof(T)); 
    var repository = (log4net.Repository.Hierarchy.Hierarchy)appendableLog.Logger.Repository; 
    repository.Root.AddAppender(memoLog);    
    var logField = typeof(T).GetField("Log", BindingFlags.Static | BindingFlags.NonPublic); 
    if (logField != null) logField.SetValue(null, appendableLog); 
    return memoLog; 
} 

Esto supone que tiene una estática privada Entrar campo en su clase:

private static readonly ILog Log = LogManager.GetLogger(typeof(MyClass)); 

por lo tanto, en la prueba, es simplemente:

var memoLog = GetMemoLog<MyClass>(); 
// followed by test logic, and then... 
var events = memoLog.GetEvents();