Log4net 一个 FileAppender 元素,以编程方式记录到多个文件

发布于 2024-12-12 00:24:42 字数 1743 浏览 0 评论 0原文

我的 Web 应用程序支持多个实例,例如实例 1、2,每个实例都通过 log4net 将数据记录到自己的文件中。也就是说,我想以编程方式根据实例 ID 将数据记录到不同的文件中。文件路径应为:

D:\Projects\Log\1\Reporting.log(例如实例 1)

D:\Projects\Log\2\Reporting.log(例如实例 2)

我的 Web 应用程序支持 3 个实例,我是否需要有 3 个记录器在 C# 中,仅日志文件路径不同,如上所示?

下面是Log4Net.config

 <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
      </configSections>
      <log4net>

        <appender name="ExceptionLogFileAppender" type="log4net.Appender.RollingFileAppender">

          <file value=????How to specify this????? />
          <appendToFile value="true" />
          <rollingStyle value="Date" />
          <datePattern value="-yyyy-MM-dd.lo\g" />
          <param name="StaticLogFileName" value="false" />
          <layout type="log4net.Layout.PatternLayout">
            <param name="Header" value="------------------------------------------&#13;&#10;" />
            <param name="Footer" value="------------------------------------------&#13;&#10;" />
            <conversionPattern value="%d|[%t]|%-5p|%c|%m%n"/>
          </layout>
        </appender>
        <!-- Setup the root category, add the appenders and set the default level -->
        <root>
          <level value="ERROR" />
          <appender-ref ref="ExceptionLogFileAppender" />
        </root>

      </log4net>
    </configuration>

UPDATE

实例id必须是1,2等,

以后实例id会超过100。

任何想法将不胜感激!

My web app supports multiple instances, e.g. instance 1, 2, each of which logs data into its own file via log4net. That is I want to log data into different files based on instance id programmatically. The file path should be:

D:\Projects\Log\1\Reporting.log for instance 1

D:\Projects\Log\2\Reporting.log for instance 2

My web app support 3 instances, do I need to have 3 loggers in C#, which ONLY differ by its log file path, as shown above?

Below is Log4Net.config

 <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
      </configSections>
      <log4net>

        <appender name="ExceptionLogFileAppender" type="log4net.Appender.RollingFileAppender">

          <file value=????How to specify this????? />
          <appendToFile value="true" />
          <rollingStyle value="Date" />
          <datePattern value="-yyyy-MM-dd.lo\g" />
          <param name="StaticLogFileName" value="false" />
          <layout type="log4net.Layout.PatternLayout">
            <param name="Header" value="------------------------------------------
" />
            <param name="Footer" value="------------------------------------------
" />
            <conversionPattern value="%d|[%t]|%-5p|%c|%m%n"/>
          </layout>
        </appender>
        <!-- Setup the root category, add the appenders and set the default level -->
        <root>
          <level value="ERROR" />
          <appender-ref ref="ExceptionLogFileAppender" />
        </root>

      </log4net>
    </configuration>

UPDATE

The instance id must be 1,2, etc.

The instance id would have more than 100 in the future.

Any idea would be much appreciated!

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

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

发布评论

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

评论(4

想挽留 2024-12-19 00:24:42

好吧,我想不出一种方法来记录每个实例(1、2、3),但您可以轻松地通过它们的 PID 来记录它们。我将 元素更改为:

<file type="log4net.Util.PatternString">
    <conversionPattern value="log\%processid\yourFileName.%date{yyyyMMMdd}.log" />
</file>

然后删除该元素,这应该给出:

 <appender name="ExceptionLogFileAppender" type="log4net.Appender.RollingFileAppender">    
      <file type="log4net.Util.PatternString">
         <conversionPattern value="log\%processid\yourFileName.%date{yyyyMMMdd}.log" />
      </file>
      <appendToFile value="true" />
      <rollingStyle value="Date" />
      <param name="StaticLogFileName" value="false" />
      <layout type="log4net.Layout.PatternLayout">
          <param name="Header" value="------------------------------------------
" />
          <param name="Footer" value="------------------------------------------
" />
          <conversionPattern value="%d|[%t]|%-5p|%c|%m%n"/>
      </layout>
  </appender>

然后,每个实例应该根据它的 PID 进行记录:

c:\log\13242\yourFileName.20111025.log

或者,您可以将 pid 设为文件的一部分name 而不是不同的目录,我可能会推荐这样做,这样您就不会在 c:\log\ 文件夹中乱扔多个目录:

<file type="log4net.Util.PatternString">
    <conversionPattern value="log\yourFileName.%processid.%date{yyyyMMMdd}.log" />
</file>

这将为您提供如下文件:

c:\log\yourFileName.13142.20111025.log
c:\log\yourFileName.13152.20111025.log

Well, I can't think of a way to log each instance (1, 2, 3), but you can easily log them by their PID. I'd change the <file> element to:

<file type="log4net.Util.PatternString">
    <conversionPattern value="log\%processid\yourFileName.%date{yyyyMMMdd}.log" />
</file>

Then remove the element, that should give:

 <appender name="ExceptionLogFileAppender" type="log4net.Appender.RollingFileAppender">    
      <file type="log4net.Util.PatternString">
         <conversionPattern value="log\%processid\yourFileName.%date{yyyyMMMdd}.log" />
      </file>
      <appendToFile value="true" />
      <rollingStyle value="Date" />
      <param name="StaticLogFileName" value="false" />
      <layout type="log4net.Layout.PatternLayout">
          <param name="Header" value="------------------------------------------
" />
          <param name="Footer" value="------------------------------------------
" />
          <conversionPattern value="%d|[%t]|%-5p|%c|%m%n"/>
      </layout>
  </appender>

Then, each instance should log according to it's PID:

c:\log\13242\yourFileName.20111025.log

Or, you can make the pid part of the file name instead of a different directory, which I'd probably recommend so you don't litter the c:\log\ folder with multiple directories:

<file type="log4net.Util.PatternString">
    <conversionPattern value="log\yourFileName.%processid.%date{yyyyMMMdd}.log" />
</file>

This will give you files like:

c:\log\yourFileName.13142.20111025.log
c:\log\yourFileName.13152.20111025.log
梦回旧景 2024-12-19 00:24:42

请参阅此示例。基本上,如果实例的数量是可管理的且有限的,您可以为每个实例创建一个日志附加程序。然后,为每个过滤器添加一个过滤器,并将每个过滤器的 StringToMatch 属性设置为实例 ID。

请注意,这并不是完全动态的,因为您需要提前指定每个附加程序。

See this example. Basically, if the number of instances is manageable and finite, you can create a log appender for each one. Then, you add a filter to each one, and set the StringToMatch property for each one to the instance ID.

Note that this is not completely dynamic in that you will need to specify each of these appenders ahead of time.

好菇凉咱不稀罕他 2024-12-19 00:24:42

这应该可行,需要一些工作,并且基于套件 此处

在调用 XmlConfigurator.Configure(); 之前添加

ConverterRegistry.AddConverter(typeof(InstancePatternString), typeof(InstancePatternStringConverter));

然后将以下类添加到您的解决方案中:

public class InstancePatternString  : PatternString
{
    public InstancePatternString(string pattern): base(pattern)
    {
    }

    public override void ActivateOptions()
    {
        AddConverter("cs", typeof(InstancePatternConverter));
        base.ActivateOptions();
    }
}

public class InstancePatternConverter  : PatternConverter 
{
    override protected void Convert(TextWriter writer, object state) 
    {
        switch(Option)
        {
            case "instance":
                writer.Write(MyContext.Instance);
                break;
        }
    }
}

public class InstancePatternStringConverter : IConvertTo, IConvertFrom
{
    public bool CanConvertFrom(Type sourceType)
    {
        return sourceType == typeof(string);
    }

    public bool CanConvertTo(Type targetType)
    {
        return typeof(string).IsAssignableFrom(targetType);
    }

    public object ConvertFrom(object source)
    {
        var pattern = source as string;
        if (pattern == null)
            throw ConversionNotSupportedException.Create(typeof(InstancePatternString), source);
        return new InstancePatternString(pattern);
    }

    public object ConvertTo(object source, Type targetType)
    {
        var pattern = source as PatternString;
        if (pattern == null || !CanConvertTo(targetType))
            throw ConversionNotSupportedException.Create(targetType, source);
        return pattern.Format();
    }
}

确保将此处的 MyContext.Instance 更改为代表您的实例的静态可访问属性。

最后将您的 web.config 从: 更改

<file value=????How to specify this????? />

为:

<file type="ConsoleApp.InstancePatternString, ConsoleApp" value="%cs{instance}\Reporting.log" />

其中 ConsoleApp 是您添加这些类的程序集。这将导致在单独的实例目录中创建日志文件。即 1\Reporting.log、2\Reporting.log 等。

这种方法的优点是添加未来的属性非常容易,只需要添加到 switch 语句即可在任何未来的日志文件名/位置中使用。

This should work, it's a bit of work and it's based on the answer by kit here.

Before calling XmlConfigurator.Configure(); add

ConverterRegistry.AddConverter(typeof(InstancePatternString), typeof(InstancePatternStringConverter));

Then add the following classes to your solution:

public class InstancePatternString  : PatternString
{
    public InstancePatternString(string pattern): base(pattern)
    {
    }

    public override void ActivateOptions()
    {
        AddConverter("cs", typeof(InstancePatternConverter));
        base.ActivateOptions();
    }
}

public class InstancePatternConverter  : PatternConverter 
{
    override protected void Convert(TextWriter writer, object state) 
    {
        switch(Option)
        {
            case "instance":
                writer.Write(MyContext.Instance);
                break;
        }
    }
}

public class InstancePatternStringConverter : IConvertTo, IConvertFrom
{
    public bool CanConvertFrom(Type sourceType)
    {
        return sourceType == typeof(string);
    }

    public bool CanConvertTo(Type targetType)
    {
        return typeof(string).IsAssignableFrom(targetType);
    }

    public object ConvertFrom(object source)
    {
        var pattern = source as string;
        if (pattern == null)
            throw ConversionNotSupportedException.Create(typeof(InstancePatternString), source);
        return new InstancePatternString(pattern);
    }

    public object ConvertTo(object source, Type targetType)
    {
        var pattern = source as PatternString;
        if (pattern == null || !CanConvertTo(targetType))
            throw ConversionNotSupportedException.Create(targetType, source);
        return pattern.Format();
    }
}

Make sure to change MyContext.Instance here to a statically accessible property representing your instance.

Finally change your web.config from:

<file value=????How to specify this????? />

to:

<file type="ConsoleApp.InstancePatternString, ConsoleApp" value="%cs{instance}\Reporting.log" />

Where ConsoleApp is the assembly in which you've added these classes. This will result in log files being created in seperate instance directories. i.e. 1\Reporting.log, 2\Reporting.log, etc.

The advantage of this approach is that adding future properties is quite easy and just requires an addition to the switch statement to be usable within any future log filenames / locations.

戏舞 2024-12-19 00:24:42

不完全是文件系统日志解决方案,但是记录到数据库表并包含实例详细信息怎么样?这使得区分特定于实例的消息变得容易,并且几乎是零维护并且具有高度可扩展性。

Not precisely a file system log solution, but what about logging to a DB table and including the instance detail? This would make it easy to differentiate instance-specific messages, and is almost zero maintenance and highly scaleable.

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