2010-02-19 11 views
9

J'essaie d'obtenir l'intégration de log4net pour Castle Windsor. J'ai écrit ma classe avec une propriété publique de type ILogger et j'ai pris la configuration dans mon app.config comme suit.Connexion avec Castle.Facilities.Logging et 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> 

Dans mes yeux cela devrait fonctionner, mais il ne fonctionne pas. Lorsque je définis loggingApi="console", il se connecte correctement. Quand je le change en log4net il ne fait rien. La configuration de log4net a été prise à partir d'un autre projet où le bloc fonctionne. Que dois-je faire pour que le fichier journal soit utilisé? Doit-il y avoir une configuration spéciale de log4net?

Merci pour tout soupçon

Boris

+0

a-t-il finalement fonctionné? –

+0

Après un petit changement dans mon code, oui c'est le cas :) – Booser

Répondre

9

Déplacez votre configuration log4net à un log4net.config de fichier séparé, reportez-vous ensuite ce fichier à partir de la configuration de l'installation:

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

Si vous voulez avoir votre configuration log4net dans une section de votre application.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."); 
    } 
} 

puis enregistrer l'installation comme:

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

C'est comme ça que je pensais mais j'aime l'idée d'avoir la configuration en un seul endroit. Ithink je dois regarder dans l'usine pour obtenir un moyen de charger la configuration de l'app.config ... mais quand c'est seulement la configuration de l'enregistrement qui est statique la plupart du temps ... Merci pour votre conseil – Booser

+0

curieux, doit 'configfile =" ... "* pas * être la configuration de l'application? @Boris que se passe-t-il si vous spécifiez '[application.name] .exe.config' à la place? –

+0

@johnnyG: ne fonctionnera pas –

1

Ceci est la configuration entière pour l'échantillon donné ici 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> 

L'erreur que je l'ai été (comme vous pouvez voir les sections commentées dans le fichier de configuration) , a essayé d'assigner la propriété Logger une fois de plus dans ma classe en enregistrant le composant dans Castle. Ce n'est pas obligatoire car Castle le fait automatiquement pour vous.

Vive Badal

6

Vous pouvez utiliser App.config pour votre configuration log4net sans créer une usine d'enregistrement personnalisé. Il suffit de fournir le fichier App.config comme argument au constructeur LoggingFacility:

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

Contrairement à la réponse de Mauricio Scheffer, l'usine par défaut ne ConfigureAndWatch. Cela fonctionne très bien pour moi avec le fichier App.config, même si je ne suis pas en cours d'exécution sur IIS ou toute autre chose qui limite les autorisations.

Je le fais dans le code parce que vous ne pouvez pas utiliser de manière fiable la configuration Windsor Xml pour charger la configuration de log4net depuis App.config. C'est parce que l'emplacement de App.config peut être modifié lors de la création d'un nouveau AppDomain. L'utilisation de ma solution signifie que la configuration du fichier journal sera compilée dans votre code. Mais vous pouvez atténuer cela en utilisant un Windsor Installer pour configurer la journalisation et spécifiez le programme d'installation (ou un ensemble d'installation) à partir du fichier 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 dans l'avenir (peut-être dans vos cas de test) vous devez charger la configuration de l'enregistrement à partir d'un autre fichier, et ne peut pas ou ne veulent pas recompiler, il suffit de changer le Xml pour pointer vers Windsor installateurs dans un autre assemblage:

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

récentes conventions de la suite du château (me corriger si mal), j'ai résolu de cette façon:

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

J'ai simplement adapté la méthode pROVID ed ici: http://docs.castleproject.org/Windsor.Windsor-Tutorial-Part-Five-Adding-logging-support.ashx

et utilisé la surcharge de UseLog4Net() qui accepte un paramètre de fichier de configuration.

3

Notez que vous pouvez utiliser les éléments suivants dans les dernières versions du château:

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

Cela utilisera Log4net pour l'enregistrement et la recherche de la section de configuration log4net dans le fichier de configuration de l'application.

0

Il me manquait le paquet NuGet suivant.

Castle.Windsor-log4net

Install-Package Castle.Windsor-log4net 

le fixe.