使用Castle.Facilities.Logging和log4net进行日志记录

时间:2010-02-19 15:11:07

标签: logging log4net castle-windsor log4net-configuration

我正在努力让Castle Windsor的log4net集成工作。我用类型为ILogger的公共属性编写了我的类,并在我的app.config中进行了配置,如下所示。

<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>

在我看来,这应该有效,但事实并非如此。当我设置loggingApi="console"时,它会正确记录。当我将其更改为log4net时,它什么也没做。 log4net配置来自块正在运行的另一个项目。我该怎么做才能使用日志文件?必须有一个特殊的log4net配置吗?

感谢任何提示

鲍里斯

6 个答案:

答案 0 :(得分:9)

将您的log4net配置移动到单独的文件log4net.config,然后从设施配置中引用该文件:

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

如果您想在app.config的一部分中使用log4net配置:

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

然后将设施注册为:

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

答案 1 :(得分:6)

您可以使用App.config进行log4net配置,而无需创建自定义日志记录工厂。只需提供App.config文件作为LoggingFacility构造函数的参数:

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

与Mauricio Scheffer的回答不同,默认工厂有ConfigureAndWatch。虽然我没有在IIS或其他限制权限的操作上运行,但这对我来说对App.config文件来说效果很好。

我在代码中执行此操作是因为您无法可靠地使用Windsor Xml配置从App.config加载log4net配置。这是因为在创建新的AppDomain时可以修改App.config的位置。

使用我的解决方案意味着日志文件配置将被编译到您的代码中。但您可以通过使用Windsor安装程序配置日志记录来缓解此问题,并从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>

如果将来(可能在您的测试用例中)您必须从其他文件加载日志记录配置,并且不能或不想重新编译,只需将Xml更改为指向不同的Windsor安装程序组件:

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

答案 2 :(得分:3)

请注意,您可以在最近的Castle版本中使用以下内容:

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

这将使用Log4net记录并搜索应用程序配置文件中的log4net config部分。

答案 3 :(得分:1)

这是此处给出的样本的完整配置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>

我犯的错误是(正如您可以看到配置文件中注释的部分),尝试通过在城堡中注册组件再次在我的类中分配Logger属性。这不是必需的,因为Castle会自动为您执行此操作。

干杯 巴达尔

答案 4 :(得分:0)

遵循最近的城堡惯例(如果错误,请纠正我),我已经解决了这个问题:

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

我简单地调整了此处提供的方法:http://docs.castleproject.org/Windsor.Windsor-Tutorial-Part-Five-Adding-logging-support.ashx

并使用了接受配置文件参数的UseLog4Net()的重载。

答案 5 :(得分:0)

我错过了以下NuGet包。

Castle.Windsor-log4net的

Install-Package Castle.Windsor-log4net

修正了它。

相关问题