C# 全局声明log4net变量,并在所有类文件中使用它们#
我有一个用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
类库有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");