我的问题涉及库类(在库中使用的类)的日志记录,
我们目前正在使用 log4cxx
,但 log4j
库实现了相同的概念。
假设我有一个包含多个实体 A、B 和 C 的流程。它们中的每一个都使用许多不同的类和函数,在代码中清楚地分开。
A、B 和 C 使用许多库类、函数、对象、资源,有时甚至是全局变量(遗留代码,对此我无能为力......)- 让我们称它们为 foo
记录 A、B 和 C 结果是一个性能问题,当我们将日志级别设置为调试时,日志会被破坏。查看我们的系统后,我们得出以下结论:
- 我们希望一次只能更改其中一个类(或所有类,使用 root)的调试级别
- 当所有类型的
foo
打印到日志中时,我们需要查看哪个实体调用了它,A、B 或 C。 - 由于有很多
foo
,我们希望能够为每个foo
分别更改调试级别 foo
应该被视为一个公共(public)库,它不能直接依赖于 A、B 或 C。- A、B 和 C 可能使用相同的
foo
实例(例如,我们的资源处理类的相同实例使用 A、B 和 C),在日志中我们希望查看哪个类使用了foo
。 - A 可以使用 B(或 C),但我们不必在日志中看到它...
这是我们到目前为止想出的 -
A、B 和 C 将有单独的记录器。全局变量(与我们所有的日志助手和包装器保存在不同的库中)将始终保持当前日志报告。每次实体开始处理它的逻辑时,它都会将全局变量设置为适当的记录器。当 foo
想要向日志报告时,它会通过全局变量报告并将其名称(和上下文)添加到日志消息中。
问题是,感觉好像已经有什么东西可以做到这一点,解决方案感觉不干净,持有这样的全局变量......
我们是不是做错了什么? 有更好的解决方案吗?
最佳答案
我不知道现有的解决方案。我可能会想出一个具有如下接口(interface)的记录器(无论它是独立实现还是只是对现有实现的包装):
class Logger {
public:
enum Level {
...
};
static Logger* Instance();
void Log(Level level, const char* module, const char* msg);
void AddModuleFilter(const char* context, const char* module, Level level);
void SetThreadLocalContext(const char* context);
...
};
与常见日志库的主要区别是上下文相关的模块过滤器。我们可能有如下设置,根据调用者(上下文)设置不同级别:
// foo calls by entity A have the DEBUG log level
Logger::Instance()->AddModuleFilter("A", "foo", Logger::DEBUG);
// foo calls by entity B have the WARNING log level
Logger::Instance()->AddModuleFilter("B", "foo", Logger::WARNING);
然后,调用流程将是这样的:
// In entity A
Logger::Instance()->SetThreadLocalContext("A");
// Call function foo
Logger::Instance()->Log(log_level, "foo", log_msg);
不确定这样的接口(interface)是否符合你的目的。不管怎样,我总是把界面放在首位是一个好方法。有了清晰的界面后,实现它应该很容易。
关于java - 与库一起使用的不同记录器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20830673/