La configuración de Log4Net en un archivo externo no funciona
-
22-07-2019 - |
Pregunta
Estamos usando log4net y queremos especificar su configuración en un archivo de configuración externo (como lo hemos hecho con otras secciones). Para hacer esto, hemos cambiado la sección log4net en App.config a:
...
<section name="log4net"
type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
...
<log4net configSource="Log.config" />
...
Y en el archivo Log.Config (mismo directorio que App.config) tenemos:
<log4net>
<appender name="General" type="log4net.Appender.FileAppender">
<file value="myapp.log" />
<layout type="log4net.Layout.SimpleLayout" />
</appender>
<root>
<appender-ref ref="General" />
</root>
</log4net>
Sin embargo, cuando ejecutamos la aplicación, no se crea ningún archivo de registro (y no se realiza ningún registro). No se envían mensajes de error a la consola.
Si volvemos a mover el contenido del archivo Log.config a App.config (reemplazando la primera línea de código anterior), funciona como se esperaba. ¿Alguna idea de por qué no funciona en un archivo externo?
Solución
¿Tiene el siguiente atributo en su archivo AssemblyInfo.cs
:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4Net.config", Watch = true)]
y un código como este al comienzo de cada clase que requiere la funcionalidad de registro:
private static readonly ILog log =
LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
Tengo una publicación de blog que contiene esta y otra información aquí .
Otros consejos
Hay un defecto abierto en este tema. Log4Net no admite el atributo configSource de los elementos de configuración. Para usar una solución de archivo puramente de configuración, use la clave log4net.Config en appSettings.
Paso 1: Incluya la definición de la sección de configuración normal:
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
Paso 2: Use la tecla magic log4net.Config en appSettings.
<appSettings>
<add key="log4net.Config" value="log4net.simple.config" />
</appSettings>
Paso 3: Contribuya con un parche para arreglar el manejo de configSource.
El paso que se ha perdido es
log4net.Config.XmlConfigurator.Configure();
esto hará que se use configSource. Asegúrese de llamarlo una vez antes de llamar a GetLogger ();
Asegúrese de que su archivo log4net.config esté configurado con las siguientes propiedades:
Acción de compilación: contenido
Copiar al directorio de salida: Copiar siempre
O bien,
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<appSettings>
<add key="log4net.Config" value="Log4Net.config" />
</appSettings>
o simplemente,
log4net.Config.XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo("Log4Net.config"));
En ambos casos, el archivo, Log4Net.config, debe estar allí en el directorio de salida. Puede hacerlo configurando las propiedades del archivo Log4Net.config en el explorador de soluciones. Acción de compilación: contenido y copia al directorio de salida: Copiar siempre
Cuidado con este problema ...
En mi caso, todo estaba configurado correctamente. El problema es que usé Web Deploy dentro de Visual Studio 2013 para cargar el sitio en WinHost.com y restableció el ACLs en el servidor. Esto a su vez revocó todos los permisos en carpetas y archivos: log4net no pudo escribir el archivo.
Puedes leer más sobre esto aquí:
Cómo detener Web Deploy / MSBuild de desordenar los permisos del servidor
Le pedí al equipo de soporte que restableciera las ACL y luego log4net comenzó a escupir registros. :)
Suponiendo que tenía un archivo de configuración externo llamado log4net.config que se copia en su directorio de implementación, puede configurarlo así:
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Reflection;
using log4net;
namespace MyAppNamespace {
static class Program {
//declare it as static and public so all classes in the project can access it
//like so: Program.log.Error("got an error");
public static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(Program));
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main() {
//configure it to use external file
log4net.Config.XmlConfigurator.Configure(new Uri(Application.StartupPath + "\\log4net.config"));
//use it
log.Debug("############# STARING APPLICATION #################");
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FormMain());
}
}
}
Tuve el mismo problema, además de tener
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net")]
en el proyecto en ejecución, también tenía la siguiente línea en un proyecto de referencia:
[assembly: log4net.Config.XmlConfigurator]
Cuando eliminé esta línea en los proyectos referenciados, los registros comienzan a aparecer.
También es posible activar un modo de depuración para log4net
. Inserte esto en el archivo App.config:
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add
name="textWriterTraceListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="link\to\your\file.log" />
</listeners>
</trace>
</system.diagnostics>
y al menos obtendrá mensajes de error, de los cuales puede derivar exactamente qué salió mal. En mi caso, simplemente olvidé configurar Copiar al directorio de salida
en Copiar siempre
.
@Mitch, Resulta que hay un archivo con la declaración [ensamblado: ...], pero no tenía la propiedad ConfigFile.
Una vez que lo agregué y lo apunté a Log.config, comenzó a funcionar. Pensé que funcionaría como todas las demás secciones de configuración (es decir, AppSettings) y que aceptaría archivos de configuración externos sin modificación.
No tenemos la segunda declaración que mencionó, ya que la incluimos en un proveedor de registro estático global.
En mi caso recibí este mensaje de error:
log4net: config file [C:\........\bin\Debug\log4net.config] not found.
Y log4net.config
el archivo estaba en el proyecto Visual Studio 2017, pero cuando verifiqué el archivo en bin \ Debug
carpeta que no pude encontrar.
Mi configuración de ensamblaje original era así:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
Después de un tiempo de investigación, lo cambio a lo siguiente y funciona:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = @"..\..\log4net.config", Watch = true)]
- agregue lo siguiente a AssemblyInfo.cs
[ensamblaje: log4net.Config.XmlConfigurator (ConfigFile = " Log4Net.config ")]
- Asegúrese de que log4net.config esté incluido en el proyecto
- En propiedades de log4net.config
cambie Copiar al directorio de salida a Copiar si es más reciente
- Nivel de registro de doble verificación valor de nivel = " TODOS "