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

发布于 2024-08-22 08:45:52 字数 1553 浏览 8 评论 0原文

我正在尝试让温莎城堡的 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 配置吗?

感谢

鲍里斯的任何提示

I'm trying to get log4net integration for Castle Windsor working. I wrote my class with an public property of type ILogger and took the configuration in my app.config like following.

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

In my eyes this should be working, but it doesn't. When I set loggingApi="console" it logs correctly. When I change it to log4net it does nothing. The log4net configuration was taken from another project where the block is working. What do I have to do that the log file is used? Must there be a special log4net configuration?

Thanks for any hint

Boris

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

风苍溪 2024-08-29 08:45:52

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

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

如果您希望将 log4net 配置放在 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.");
    }
}

则将该设施注册为:

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

Move your log4net configuration to a separate file log4net.config, then refer that file from the facility configuration:

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

If you want to have your log4net configuration in a section of your 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.");
    }
}

then register the facility as:

<facility 
  id="loggingfacility" 
  loggingapi="custom" 
  customLoggerFactory="[fully qualified type name of MyLog4NetFactory]" 
  type="Castle.Facilities.Logging.LoggingFacility, Castle.Facilities.Logging"/>
可爱暴击 2024-08-29 08:45:52

您可以使用 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>

You can use App.config for your log4net configuration without creating a custom logging factory. Simply provide the App.config file as an argument to the LoggingFacility constructor:

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

Unlike Mauricio Scheffer's answer, the default factory does ConfigureAndWatch. This works just fine for me with the App.config file, though I'm not running on IIS or anything else that restricts permissions.

I'm doing this in code because you can't reliably use the Windsor Xml configuration to load log4net configuration from App.config. This is because the location of App.config can be modified when creating a new AppDomain.

Using my solution means the log file configuration will be compiled into your code. But you can mitigate this by using a Windsor Installer to configure logging, and specify the installer (or installer assembly) from the App.config file:

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>

If in the future (maybe in your test cases) you have to load the logging configuration from a different file, and can't or don't want to recompile, simply change the Xml to point to Windsor Installers in a different assembly:

<castle>
    <installers>
        <install assembly="SomeOtherAssemblyName" />
    </installers>
</castle>
流年已逝 2024-08-29 08:45:52

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

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

这将使用 Log4net 进行日志记录并在应用程序配置文件中搜索 log4net 配置部分。

Note that you can use the following in recent Castle versions:

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

This will use Log4net for logging and search for the log4net config section in the application configuration file.

简单气质女生网名 2024-08-29 08:45:52

这是此处给出的示例的完整配置 主页 » MicroKernel/Windsor » 入门» 第 1 部分 - 基础知识

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

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

干杯
巴达尔

This is the entire configuration for the sample given here 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>

The mistake I did was (as you can see the sections commented in the config file), tried to assign the Logger property once again in my class by registering the component in castle. this is not required as Castle does this automatically for you.

Cheers
Badal

你在看孤独的风景 2024-08-29 08:45:52

遵循最近的 Castle 约定(如果错误请纠正我),我已经这样解决了:

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() 的重载。

Following recent Castle conventions (correct me if wrong), I have solved it this way:

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

I have simply adapted the method provided here: http://docs.castleproject.org/Windsor.Windsor-Tutorial-Part-Five-Adding-logging-support.ashx

and used the overload of UseLog4Net() that accepts an configuration file parameter.

临走之时 2024-08-29 08:45:52

我缺少以下 NuGet 包。

Castle.Windsor-log4net

Install-Package Castle.Windsor-log4net

修复了它。

I was missing the following NuGet package.

Castle.Windsor-log4net

Install-Package Castle.Windsor-log4net

Fixed it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文