全局声明 log4net 变量并在所有 class 文件中使用它们 c#

Declare log4net variables globally and use them across all class files c#

我有一个用 c# 编写的 class 库。在这个库中,我们使用 log4net 进行日志记录。
class 库有 2-3 个 class files.This class 库正在被一个 windows 服务使用,也是用 c# 编写的。

现在log4net已经通过以下方式实现了。
1. 我为 log4net.
添加了来自 nuget 的参考 2. 在每个 class 文件中,在顶部添加:

private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

3。想要一些额外的细节与默认值一起打印,所以在 log4net.config 文件中添加了一些参数,如下所示:

<parameterName value="@Parameter1"/>
<parameterName value="@Parameter2"/>

布局模式:

<layout type="log4net.Layout.PatternLayout">
     <conversionPattern value="%date{dd/MM/yy HH:mm:ss} [%thread] %level  :: Parameter1 = %property{Parameter1} :: Parameter2 = %property{Parameter2}:: %logger : %message%newline"   />
</layout>

并在 ClassA 中的每个方法中添加了这一行,其中正在进行日志记录:

log4net.GlobalContext.Properties["Parameter1"] = parameter1;
log4net.GlobalContext.Properties["Parameter2"] = parameter2;

现在我面临的问题是,假设我的 class 库中有 2 个 class 文件,名为 Class1Class2。以及 parameter1parameter2ClassA 中的 public 个变量。正如 问题中提到的,我无法访问 ClassB 中的 paramter1parameter2。所以当打印classB方法的日志时,parameter1parameter2总是空的。

那么有没有一种方法可以全局设置一次参数,并且每当打印日志时它都使用相同的变量。

我的代码类似于下面:

public ClassA {
    public string parameter1 { get; set; } = "ABC"
    public string parameter2 { get; set; } = "XYZ"

    private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
    public void SomeMethod(){
        log4net.GlobalContext.Properties["Parameter1"] = parameter1;
        log4net.GlobalContext.Properties["Parameter2"] = parameter2;
        ClassB b = new ClassB();
        log.info("In Some Method");
        b.AnotherMethod();
        LogMessage("After AnotherMethod");  
    }   
}

public class ClassB(){
    private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
    public void AnotherMethod(){        
        log.info("Inside AnotherMethod");       
    }
}

预期输出:

30/10/18 21:57:11 [5] INFO  :: Parameter1 = 'ABC' :: Parameter2 = 'XYZ' :: ClassA : In Some Method
30/10/18 21:57:11 [5] INFO  :: Parameter1 = 'ABC' :: Parameter2 = 'XYZ' :: ClassB : Inside AnotherMethod
30/10/18 21:57:11 [5] INFO  :: Parameter1 = 'ABC' :: Parameter2 = 'XYZ' :: ClassA : After AnotherMethod

实际输出:

30/10/18 21:57:11 [5] INFO  :: Parameter1 = 'ABC' :: Parameter2 = 'XYZ' :: ClassA : In Some Method
30/10/18 21:57:11 [5] INFO  :: Parameter1 = (null) :: Parameter2 = (null) :: ClassB : Inside AnotherMethod
30/10/18 21:57:11 [5] INFO  :: Parameter1 = 'ABC' :: Parameter2 = 'XYZ' :: ClassA : After AnotherMethod

如何使参数 1 和 2 每次都打印或声明它globally.So一旦设置,它必须被所有 log4net 消息使用。

非常感谢这方面的任何帮助。

如果您需要跟踪库中的这些参数,您可以读取和写入设置文件。 https://msdn.microsoft.com/en-us/library/aa730869(v=vs.80).aspx

您代码中的这一行:

log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

您最终得到 2 个不同的记录器,因此您在 ClassA 中为记录器设置的值与 ClassB 中的记录器不同。尝试将这两行更改为:

log4net.LogManager.GetLogger("MyLogger");

它应该可以工作。

如果您通读文档,您会发现当您调用 this 使用类型名称加载记录器的方法时 "The full name of type will be used as the name of the logger to retrieve." 由于您的代码中有两种不同的类型,您最终得到两个不同的记录器。您需要使用通用名称或通用类型来获取相同的记录器实例。

您的另一个选择是在设置文件中设置值,但我猜这对您不起作用,因为它们可能是您需要在 运行 时间设置的值。

如果您在 log4net.GlobalContext 中设置属性,它们应该对所有记录器可用。我不确定您在何处或为何将 parameterName 元素添加到 log4net.config 文件中,但您不需要它们。

通常您会在应用程序启动时设置一次 log4net.GlobalContext 属性。如果您只需要方法持续期间的属性,您可以考虑使用 log4Net.ThreadContext.

This dotnetfiddle 与您的代码相似,并给出您想要的结果。