C# 全局声明log4net变量,并在所有类文件中使用它们#

C# 全局声明log4net变量,并在所有类文件中使用它们#,c#,log4net,C#,Log4net,我有一个用c写的类库。在此库中,我们使用log4net进行日志记录。 类库有2-3个类文件。该类库正由一个同样用c#编写的windows服务使用 现在,log4net已按以下方式实现。 1.我添加了nuget对log4net的引用 2.在每个类文件的顶部添加以下内容: private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMeth

我有一个用c写的类库。在此库中,我们使用log4net进行日志记录。
类库有2-3个类文件。该类库正由一个同样用c#编写的windows服务使用

现在,log4net已按以下方式实现。
1.我添加了nuget对
log4net
的引用
2.在每个类文件的顶部添加以下内容:

private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
三,。希望打印一些额外的细节以及默认值,因此在log4net.config文件中添加了一些参数,如下所示:

<parameterName value="@Parameter1"/>
<parameterName value="@Parameter2"/>
现在我面临的问题是,假设我的类库中有两个类文件,分别名为
Class1
Class2
。而
parameter1
parameter2
ClassA
中的公共变量。如前所述,我无法访问
ClassB
中的
parameter1
parameter2
。因此,当打印
classB
方法的日志时,
parameter1
parameter2
始终为空

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

我的代码如下所示:

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每次打印或全局声明。因此,一旦设置,所有log4net消息都必须使用它


非常感谢您在这方面提供的任何帮助。

若您需要在整个库中跟踪这些参数,您可以读写设置文件

代码中的这一行:

log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
最终会有两个不同的记录器,因此在
ClassA
中为记录器设置的值与
ClassB
中的记录器不同。尝试将这两行更改为类似以下内容:

log4net.LogManager.GetLogger("MyLogger");
它应该会起作用

如果您通读文档,您将看到,当您调用使用类型名称加载记录器的方法时,“类型的全名将用作要检索的记录器的名称”。由于代码中有两种不同的类型,您最终会遇到两个不同的记录器。您需要使用公共名称或公共类型来获取相同的记录器实例


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

如果您在
log4net.GlobalContext
中设置属性,则所有记录器都应该可以使用它们。我不确定您在哪里或为什么向log4net.config文件中添加了
parameterName
元素,但您不需要它们

通常,您会在应用程序启动时设置一次
log4net.GlobalContext
属性。如果只希望在方法的持续时间内使用属性,则可以考虑使用<代码> Log4NET.thRealEngule
与您的代码类似,并给出您想要的结果。

嘿,这对我来说很有效,值也保留在ClassB中。但之前,在我的日志中,它用于打印ClassA和ClassB。现在它打印我的日志。还有什么我可以打印ClassA和ClassB而不是MyLogger的吗?@CrazyCoder-对不起,错过了你也打印出了logger的名字。我不认为两种方法都可以,但是必须检查所有的格式参数,看看是否可以自动填充类名。问题是,如果你给一个不同的记录器名称,那么它就是一个不同的记录器。我想,我将不得不为类名添加额外的参数以及参数1和parameter2@CrazyCoder-对于
类型
,有一个模式布局说明符,但文档警告它速度慢(我希望是这样,就像我假设它在引擎盖下使用反射一样)——@CrazyCoder我认为%stacktrace是你正在搜索的。至少它没有关于“速度慢”的警告.嘿,谢谢你的回复。我使用的类库没有你在fiddler中提到的任何main。你认为我应该在哪里全局声明它?只需要在你第一次尝试登录之前全局声明它。具体位置取决于你的应用程序/库。例如,你可以创建一个帮助器类,确保设置了globalcontext属性,并从记录的每个类调用它。或者为log4net创建一个包装器类,执行相同的操作。
log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
log4net.LogManager.GetLogger("MyLogger");