为什么记录器建议每个类使用一个记录器?
根据 NLog 的文档:
大多数应用程序将为每个类使用一个记录器,其中记录器的名称与类的名称相同。
这与 log4net 的操作方式相同。为什么这是一个好的做法?
As per NLog's documentation:
Most applications will use one logger per class, where the name of the logger is the same as the name of the class.
This is the same way that log4net operates. Why is this a good practice?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
使用 log4net,每个类使用一个记录器可以轻松捕获日志消息的来源(即写入日志的类)。如果每个类没有一个记录器,而是整个应用程序有一个记录器,则需要采用更多反射技巧来了解日志消息的来源。
比较以下内容:
每个类记录
每个应用程序一个记录器(或类似)
使用第二个示例,记录器需要构建堆栈跟踪以查看谁在调用它,否则您的代码将始终必须传入调用者。使用 logger-per-class 风格,您仍然可以这样做,但是您可以为每个类执行一次而不是每次调用一次,从而消除严重的性能问题。
With log4net, using one logger per class makes it easy to capture the source of the log message (ie. the class writing to the log). If you don't have one logger per class, but instead have one logger for the entire app, you need to resort to more reflection tricks to know where the log messages are coming from.
Compare the following:
Log per class
One logger per app (or similar)
Using the second example, the Logger would need to build a stack trace to see who was calling it or your code would always have to pass in the caller. With the logger-per-class style, you still do this, but you can do it once per class instead of once per call and eliminate a serious performance problem.
在 NLog 中使用“每个文件记录器”的优点:您可以按命名空间和类名管理/过滤日志。示例:
NLogger 有一个非常有用的代码片段来执行此操作。
nlogger
片段将创建以下代码:因此只需几次击键,每个类就有记录器。它将使用命名空间和类名作为记录器的名称。要为类记录器设置不同的名称,您可以使用以下命令:
并且,正如 @JeremyWiebe 所说,您不必使用技巧来获取尝试记录消息的类的名称:记录器的名称(其中通常是类的名称)可以通过在布局中使用
${logger}
轻松记录到文件(或其他目标)。Advantage for using "logger per file" in NLog: you have possibility to manage/filter logs by namespace and class name. Example:
NLogger has a very useful code snippet to do this. The
nlogger
snippet will create the following code:So only few keystrokes and you have logger per class. It will use namespace and class name as the name of the logger. To set different name to your class logger, you can use this:
And, as @JeremyWiebe said, you don't have to use tricks to get the name of the class which is trying to log a message: Name of the logger (which is usually the name of the class) can be easy logged to file (or other target) by using
${logger}
in layout.我可以看到做出这个选择的几个原因。
I can see a few reasons for this choice.
NLog 还具有性能优势。大多数用户将使用
从堆栈跟踪查找当前类需要一些(但不多)性能。
There is also a performance benefit in the case of NLog. Most users will use
Looking up the current class from stack trace take some (but not much) performance.
在大多数情况下,类的名称为记录器提供了一个好的名称。扫描日志文件时,您可以看到日志消息并将其直接与一行代码关联起来。
Hibernate 的 SQL 日志就是一个很好的例子,但这并不是最好的方法。有一个名为“Hibernate.SQL”或类似名称的共享记录器,其中许多不同的类将原始 SQL 写入单个记录器类别。
In most cases, the name of the class provides a good name for the logger. When scanning the log files, you can see the log message and associate it directly with a line of code.
A good example where this is not the best approach, is Hibernate's SQL logs. There is a shared logger named "Hibernate.SQL" or something like that, where a number of different classes write raw SQL out to a single logger category.
我立即想到两个原因:
Two reasons immediately spring to mind:
从开发的角度来看,如果不必每次都创建记录器对象,这是最简单的。另一方面,如果您不这样做,而是使用反射动态创建它,则会降低性能。为了解决这个问题,您可以使用以下代码来动态异步创建记录器:
From a development standpoint, it's easiest if you don't have to create a logger object each time. On the other hand, if you don't, but rather you create it dynamically using reflection, it'll slow down performance. To solve this, you can use the following code which creates the logger dynamically asynchronously:
可能是因为您希望能够记录仅对该类可见的方法而不破坏封装,这也使得您可以轻松地在另一个应用程序中使用该类,而不会破坏日志记录功能。
Probably because you want to be able to log methods that are only visible to the class without breaking encapsulation, this also makes it easy to use the class in another application without breaking the logging functionality.
可以轻松地按命名空间或类配置附加程序。
Makes it easy to configure appenders by namespace or class.
如果您使用 NLOG,您可以在配置中指定调用点,这将记录日志记录语句所在的类名和方法。
然后,您可以使用常量作为记录器名称或程序集名称。
免责声明:我不知道 NLOG 如何收集这些信息,我的猜测是反射,因此您可能需要考虑性能。如果您不使用 NLOG v4.4 或更高版本,异步方法会出现一些问题。
If you are using NLOG you can specify the callsite in the config, this will record the class name and method where the logging statement was located.
You could then use a constant for your logger name or the assembly name.
Disclaimer: I don't know how NLOG collects this information, my guess would be reflection so you may need to consider the performance. There are a few issues with Async methods if you are not using NLOG v4.4 or later.