log4net:在哪里放置静态 LogManger 对象? (在解决方案的不同项目中使用它,每个项目都有一个单独的配置文件)
log4net: Where to place static LogManger object? (using it in different projects of a solution, each having an individual config-file)
到目前为止我还没有接触过配置文件。因此,与此相关,我想我在第一次使用 log4net 时错过了一些要完全理解的基础知识。
这是我已经读过的内容:
https://stackify.com/log4net-guide-dotnet-logging
https://csharp.today/log4net-tutorial-great-library-for-logging
log4net configuration with [assembly:]
假设我们在一个解决方案中有三种不同类型的项目,每个项目都附加了 log4net:
- 中级项目:.NET Framework 4.6.1(使用 LowLevel)
- 低级别项目:.NET Standard 2.0
- 项目应用:.NET Framework 4.6.1(使用 LowLevel 和 MidLevel)
1) 我应该把下面几行放在哪里?在每个 class 我要登录的地方?
private static readonly log4net.ILog log
= log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
2) 我想知道如何在我想使用它的任何地方获取静态对象。所以我在 LowLevel 项目中添加了如下所示的 class,希望 'using' 能有所帮助。
using System;
using System.Collections.Generic;
using System.Text;
using log4net;
namespace LowLevel.NuGet.Log4Net
{
public class Log4Net
{
// Avoiding overhead by logging, reducing use of CPU via static LogManager object.
private static readonly log4net.ILog _log
= log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
//
// Properties
//
public static log4net.ILog Log { get => _log; }
}
}
但我建议我不会工作,因为 .NET Standard 2.0 项目没有自己的配置文件。
- 我说的对吗? (当然我也会自己检查这个。但是如果你提前指出我目前缺少的知识可能会有所帮助。)
- 如何只创建一个静态 LogManager 对象,并在每个项目中使用它?
- 提到的静态 LogManger 对象会使用每个单独项目的不同配置文件吗?如果没有,如何实现?
非常感谢。
第 1 部分:LogManager.GetLogger
private static readonly log4net.ILog log =
log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
我真的不知道为什么马特会提出这种可憎的观点(恕我直言)。是的,您可以简单地将其复制并粘贴到您想要记录的每个 class 中,但反射是 慢 .
尽管 LogManager 应该为相同的 class 提供相同的 Logger
实例,但 建议将其设为静态, 以避免调用 LogManager。这应该会提高性能,特别是如果您有经常实例化的日志记录 classes。
在 log4net 文档(以及我自然会做的)中,另一种方法是这样做:
private static readonly ILog log = LogManager.GetLogger(typeof(ClassName));
缺点:你有一个 classname 在那里,所以没有简单的 C&P。
如果您使用重构功能更改 class 名称,BUT Visual Studio 将更改它,您可以定义 shortcut/templates 来填写class 名称自动。但即使你手动完成,我仍然更喜欢这个而不是反射。
供参考:typeof operator and lang-reference: typeof
第 2 部分:配置
使用库进行日志记录配置没有任何意义。他们不会被执行 "standalone"。您要做的是利用名称空间。
假设您有库 A 和 B,具有命名空间 "my.prj.A" 和 "my.prj.B" 以及一个 "Main" 应用程序 "my.prj.App",那么您将在应用程序。但是,您仍然可以应用不同的设置/附加程序:
log4net 跨越配置继承树(如他们的 "configuration" 和 "getting started" 文档中所述)。因此,您将始终 拥有根记录器。如果没有其他记录器适用,这是默认值或回退。
然后你可以定义子记录器(我的术语,不知道他们怎么称呼它们),例如:
logger "my.prj" 如果没有更具体的记录器适用,它将应用于从 typeof(my.prj.*.SomeClass)
创建的所有记录器。没有意义?是的,它会 - 它 不会 适用于例如第 3 方库。如果他们碰巧使用log4net,他们将回退到root。
logger "my.prj.A" 将应用于库 A 中的所有 classes。
- logger "my.prj.B.SomeFeatureNamespace" 将应用于库 B 中
FeatureNamespace
的所有 classes。
...你明白要点了。
顺便说一句: 使用 ... = LogManager.GetLogger("MySuperSpecialLogger");
你可以为 "MySuperSpecialLogger" 定义一个配置,这在调试时会派上用场,因为你可以 "follow" 一些流经 classes 并且可以通过记录器名称轻松过滤日志或将其写入不同的文件等
或者您可以聚合登录输入以获取文档。例如,您有 3 种登录方法,但您需要记录尝试和成功/失败的日志:您可以为此创建一个命名记录器并将其连接到自己的附加程序,在 3 种实现中获取它,写入日志登录输出 attempts/success/fail - 完成。
没有配置库也有一些其他影响:
- 如果您真的重用它们,每个解决方案都可以为它们定义不同的日志记录配置。
- 您可以关闭单元测试项目中的日志记录。
- 如果您(或其他人)在使用不同日志框架的项目中使用它们,您可能仍然能够记录,但配置可能来自外观或适配器.
到目前为止我还没有接触过配置文件。因此,与此相关,我想我在第一次使用 log4net 时错过了一些要完全理解的基础知识。
这是我已经读过的内容:
https://stackify.com/log4net-guide-dotnet-logging
https://csharp.today/log4net-tutorial-great-library-for-logging
log4net configuration with [assembly:]
假设我们在一个解决方案中有三种不同类型的项目,每个项目都附加了 log4net:
- 中级项目:.NET Framework 4.6.1(使用 LowLevel)
- 低级别项目:.NET Standard 2.0
- 项目应用:.NET Framework 4.6.1(使用 LowLevel 和 MidLevel)
1) 我应该把下面几行放在哪里?在每个 class 我要登录的地方?
private static readonly log4net.ILog log
= log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
2) 我想知道如何在我想使用它的任何地方获取静态对象。所以我在 LowLevel 项目中添加了如下所示的 class,希望 'using' 能有所帮助。
using System;
using System.Collections.Generic;
using System.Text;
using log4net;
namespace LowLevel.NuGet.Log4Net
{
public class Log4Net
{
// Avoiding overhead by logging, reducing use of CPU via static LogManager object.
private static readonly log4net.ILog _log
= log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
//
// Properties
//
public static log4net.ILog Log { get => _log; }
}
}
但我建议我不会工作,因为 .NET Standard 2.0 项目没有自己的配置文件。
- 我说的对吗? (当然我也会自己检查这个。但是如果你提前指出我目前缺少的知识可能会有所帮助。)
- 如何只创建一个静态 LogManager 对象,并在每个项目中使用它?
- 提到的静态 LogManger 对象会使用每个单独项目的不同配置文件吗?如果没有,如何实现?
非常感谢。
第 1 部分:LogManager.GetLogger
private static readonly log4net.ILog log =
log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
我真的不知道为什么马特会提出这种可憎的观点(恕我直言)。是的,您可以简单地将其复制并粘贴到您想要记录的每个 class 中,但反射是 慢 .
尽管 LogManager 应该为相同的 class 提供相同的 Logger
实例,但 建议将其设为静态, 以避免调用 LogManager。这应该会提高性能,特别是如果您有经常实例化的日志记录 classes。
在 log4net 文档(以及我自然会做的)中,另一种方法是这样做:
private static readonly ILog log = LogManager.GetLogger(typeof(ClassName));
缺点:你有一个 classname 在那里,所以没有简单的 C&P。
如果您使用重构功能更改 class 名称,BUT Visual Studio 将更改它,您可以定义 shortcut/templates 来填写class 名称自动。但即使你手动完成,我仍然更喜欢这个而不是反射。
供参考:typeof operator and lang-reference: typeof
第 2 部分:配置
使用库进行日志记录配置没有任何意义。他们不会被执行 "standalone"。您要做的是利用名称空间。
假设您有库 A 和 B,具有命名空间 "my.prj.A" 和 "my.prj.B" 以及一个 "Main" 应用程序 "my.prj.App",那么您将在应用程序。但是,您仍然可以应用不同的设置/附加程序:
log4net 跨越配置继承树(如他们的 "configuration" 和 "getting started" 文档中所述)。因此,您将始终 拥有根记录器。如果没有其他记录器适用,这是默认值或回退。
然后你可以定义子记录器(我的术语,不知道他们怎么称呼它们),例如:
logger "my.prj" 如果没有更具体的记录器适用,它将应用于从
typeof(my.prj.*.SomeClass)
创建的所有记录器。没有意义?是的,它会 - 它 不会 适用于例如第 3 方库。如果他们碰巧使用log4net,他们将回退到root。logger "my.prj.A" 将应用于库 A 中的所有 classes。
- logger "my.prj.B.SomeFeatureNamespace" 将应用于库 B 中
FeatureNamespace
的所有 classes。
...你明白要点了。
顺便说一句: 使用 ... = LogManager.GetLogger("MySuperSpecialLogger");
你可以为 "MySuperSpecialLogger" 定义一个配置,这在调试时会派上用场,因为你可以 "follow" 一些流经 classes 并且可以通过记录器名称轻松过滤日志或将其写入不同的文件等
或者您可以聚合登录输入以获取文档。例如,您有 3 种登录方法,但您需要记录尝试和成功/失败的日志:您可以为此创建一个命名记录器并将其连接到自己的附加程序,在 3 种实现中获取它,写入日志登录输出 attempts/success/fail - 完成。
没有配置库也有一些其他影响:
- 如果您真的重用它们,每个解决方案都可以为它们定义不同的日志记录配置。
- 您可以关闭单元测试项目中的日志记录。
- 如果您(或其他人)在使用不同日志框架的项目中使用它们,您可能仍然能够记录,但配置可能来自外观或适配器.