关于c#:Log4net一个FileAppender元素,以编程方式记录到多个文件

Log4net one FileAppender element, log to multiple files programmatically

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

D:\\\\ Projects \\\\ Log \\\\ 1 \\
实例1

的eporting.log

D:\\\\ Projects \\\\ Log \\\\ 2 \\
实例2

的eporting.log

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

下面是Log4Net.config

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
      </configSections>
      <log4net>

       

          <file value=????How to specify this????? />
         
          <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" />
         
        </root>

      </log4net>
    </configuration>

更新

实例ID必须为1,2等。

实例ID将来将超过100个。

任何想法将不胜感激!


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

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


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

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

然后删除应该给出的元素:

1
2
3
4
5
6
7
8
9
10
11
12
      <file type="log4net.Util.PatternString">
         <conversionPattern value="log\\%processid\\yourFileName.%date{yyyyMMMdd}.log" />
      </file>
     
      <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进行记录:

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

或者,您可以使pid成为文件名的一部分,而不是其他目录,我可能会建议这样做,这样您就不会乱扔带有多个目录的c:\\\\ log \\\\文件夹:

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

这将为您提供以下文件:

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


这应该可以工作,需要一些工作,并且要基于此处工具包的答案。

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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:

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

至:

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

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

此方法的优点在于,添加将来的属性非常容易,并且只需添加switch语句即可在任何将来的日志文件名/位置中使用。


并非完全是文件系统日志解决方案,但是如何记录到数据库表并包括实例详细信息呢?这样可以轻松区分特定于实例的消息,并且几乎零维护且高度可伸缩。