2010-02-19 17 views
9

Estoy tratando de conseguir la integración de log4net para Castle Windsor. Escribí mi clase con una propiedad pública del tipo ILogger y tomé la configuración en mi app.config de la siguiente manera.Iniciando sesión con Castle.Facilities.Logging y log4net

<configuration> 
    <configsections> 
    <section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" /> 
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" /> 
    </configsections> 

    <castle> 
    <facilities> 
     <facility id="logging" type="Castle.Facilities.Logging.LoggingFacility, Castle.Facilities.Logging" loggingApi="log4net" /> 
    </facilities> 
    <components> 
     <component id="form1" type="WinFormsActiveRecordSample.Form1, WinFormsActiveRecordSample" /> 
    </components> 
    </castle> 
    <log4net> 
    <root> 
     <level value="ALL" /> 
     <appender-ref ref="FileAppender" /> 
    </root> 
    <appender name="FileAppender" type="log4net.Appender.FileAppender"> 
     <file value="main.log" /> 
     <appendToFile value="true" /> 
     <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%date{dd.MM.yy HH:mm:ss} %-5level %logger - %message%newline" /> 
     </layout> 
    </appender> 
    </log4net> 
</configuration> 

En mi opinión esto debería estar funcionando, pero no es así. Cuando configuro loggingApi="console", se registra correctamente. Cuando lo cambio a log4net no hace nada. La configuración de log4net se tomó de otro proyecto donde el bloque está funcionando. ¿Qué debo hacer para que se use el archivo de registro? ¿Debe haber una configuración especial de log4net?

Gracias por cualquier sugerencia

Boris

+0

¿finalmente funcionó? –

+0

Después de un pequeño cambio en mi código, sí lo hace :) – Booser

Respuesta

9

Mueva su configuración de log4net a un log4net.config archivo separado, a continuación, consulte el archivo de configuración de la instalación:

<facility id="loggingfacility" configfile="log4net.config" loggingapi="log4net" type="Castle.Facilities.Logging.LoggingFacility, Castle.Facilities.Logging"/> 

Si usted quiere tener su configuración de log4net en una sección de su app.config:

public class MyLog4NetFactory: Log4netFactory { 
    public MyLog4NetFactory() { 
     XmlConfigurator.Configure(); 
    } 

    public override ILogger Create(String name) { 
     ILog log = LogManager.GetLogger(name); 
     return new Log4netLogger(log.Logger, this); 
    } 

    public override ILogger Create(String name, LoggerLevel level) { 
     throw new NotSupportedException("Logger levels cannot be set at runtime. Please review your configuration file."); 
    } 
} 

continuación, registrar la instalación como:

<facility 
    id="loggingfacility" 
    loggingapi="custom" 
    customLoggerFactory="[fully qualified type name of MyLog4NetFactory]" 
    type="Castle.Facilities.Logging.LoggingFacility, Castle.Facilities.Logging"/> 
+0

Esa es la forma en que estaba pensando pero me gusta la idea de tener la configuración en un solo lugar. Creo que debo buscar en la fábrica para obtener una forma de cargar la configuración desde la aplicación.config ... pero cuando es solo la configuración de registro estática la mayor parte del tiempo ... Gracias por su consejo – Booser

+0

curioso, debe 'configfile =" ... "' * not * ¿la configuración de la aplicación? @Boris, ¿qué sucede si especifica '[application.name] .exe.config' en su lugar? –

+0

@johnnyG: no funcionará –

1

Ésta es la configuración completa de la muestra dada aquí Home » MicroKernel/Windsor » Getting Started » Part 1 - The basics

<configuration> 
    <configSections> 
    <section 
     name="castle" 
     type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" /> 
    </configSections> 


    <castle> 
    <facilities> 
    <facility 
     id="logging" 
     type="Castle.Facilities.Logging.LoggingFacility, Castle.Facilities.Logging" 
     loggingApi="log4net" 
     configFile="D:\\Backup-E\\My Work\\.NET\\CastleWindsorPOC\\CastleWindosorApp\\CastleWindosorApp\\Log4Net.xml" /> 
    </facilities> 
    <components> 
     <component 
      id="httpservicewatcher" 
      type="CastleWindosorApp.HttpServiceWatcher, CastleWindosorApp" > 
     <parameters> 
      <notifiers> 
      <array> 
       <item>${email.notifier}</item> 
       <item>${alarm.notifier}</item> 
      </array> 
      </notifiers> 
      <Url>test url</Url> 
      <!--<Logger>${logger.component}</Logger>--> 
     </parameters> 
     </component> 

     <component 
      id="email.notifier" 
      service="CastleWindosorApp.IFailureNotifier, CastleWindosorApp" 
      type="CastleWindosorApp.EmailFailureNotifier, CastleWindosorApp" /> 

     <component 
      id="alarm.notifier" 
      service="CastleWindosorApp.IFailureNotifier, CastleWindosorApp" 
      type="CastleWindosorApp.AlarmFailureNotifier, CastleWindosorApp" /> 
    <!--<component 
      id="logger.component" 
      service="Castle.Core.Logging.ILogger, Castle.Core" 
      type="Castle.Services.Logging.Log4netIntegration.Log4netLogger, Castle.Services.Logging.Log4netIntegration" />--> 
     <component 
      id="form.component" 
      type="CastleWindosorApp.Form1, CastleWindosorApp" /> 


    </components> 

    </castle> 

El error que yo era (como se puede ver las secciones comentadas en el archivo de configuración) , intenté asignar la propiedad Logger una vez más en mi clase registrando el componente en castle. esto no es necesario ya que Castle lo hace automáticamente por usted.

Saludos Badal

6

Puede utilizar App.config para la configuración de log4net sin crear una fábrica de registro personalizado. Sólo es necesario que el archivo app.config como un argumento para el constructor de LoggingFacility:

container 
    .AddFacility("logging", 
     new LoggingFacility(LoggerImplementation.Log4net, 
      System.AppDomain.CurrentDomain.SetupInformation.ConfigurationFile) 
     ) 

A diferencia de la respuesta de Mauricio Scheffer, la fábrica por defecto hace ConfigureAndWatch. Esto funciona bien para mí con el archivo App.config, aunque no estoy ejecutando en IIS o cualquier otra cosa que restrinja los permisos.

Estoy haciendo esto en código porque no puede usar confiablemente la configuración de Windsor Xml para cargar la configuración de log4net desde App.config. Esto se debe a que la ubicación de App.config se puede modificar al crear un nuevo AppDomain.

Usar mi solución significa que la configuración del archivo de registro se compilará en su código. Pero se puede mitigar mediante el uso de un instalador para configurar el registro de Windsor, y especificar el instalador (o el conjunto instalador) del archivo App.config:

public class LoggingInstaller : IWindsorInstaller 
{ 
    public void Install(IWindsorContainer container, IConfigurationStore store) 
    { 
     container 
      .AddFacility("logging", 
       new LoggingFacility(LoggerImplementation.Log4net, 
        System.AppDomain.CurrentDomain.SetupInformation.ConfigurationFile) 
       ); 
    } 
} 

...

<castle> 
    <installers> 
     <install assembly="MyAssemblyName" /> 
    </installers> 
</castle> 

Si en el futuro (tal vez en sus casos de prueba) tiene que cargar la configuración de registro de un archivo diferente, y no puede o no quiere volver a compilar, basta con modificar el XML para apuntar a Windsor instaladores en un montaje diferente:

<castle> 
    <installers> 
     <install assembly="SomeOtherAssemblyName" /> 
    </installers> 
</castle> 
0

siguientes convenciones recientes Castillo (mi si mal corregir), que han resuelto de esta manera:

using Castle.Facilities.Logging; 
using Castle.MicroKernel.Registration; 
using Castle.MicroKernel.SubSystems.Configuration; 
using Castle.Windsor; 

namespace EVRM.Aspects.Container.Installers 
{ 
    public class LoggingInstaller : IWindsorInstaller 
    { 
     public void Install(IWindsorContainer container, IConfigurationStore store) 
     { 
      container.AddFacility<LoggingFacility>(f => f.UseLog4Net(System.AppDomain.CurrentDomain.SetupInformation.ConfigurationFile)); 
     } 
    } 
} 

simplemente he adaptado el método provid ed aquí: http://docs.castleproject.org/Windsor.Windsor-Tutorial-Part-Five-Adding-logging-support.ashx

y usó la sobrecarga de UseLog4Net() que acepta un parámetro de archivo de configuración.

3

Tenga en cuenta que puede utilizar el siguiente en los últimos versiones Castillo:

container.AddFacility<LoggingFacility>(f => f.UseLog4Net().WithAppConfig()); 

Esto utilizará Log4net para el registro y la búsqueda de la sección de configuración de log4net en el archivo de configuración de la aplicación.

0

Me faltaba el siguiente paquete NuGet.

Castle.Windsor-log4net

Install-Package Castle.Windsor-log4net 

arreglaron.