我的问题是关于库类的记录(库内部使用的类),
我们目前正在使用log4cxx
,但log4j
库实现了相同的概念。
假设我有一个包含多个实体A,B和C的进程。每个实体都使用许多不同的类和函数,在代码中明确分开。
A,B和C使用许多库类,函数,对象,资源,有时甚至是全局(遗留代码,我无能为力......) - 让我们称之为foo
记录A,B和C结果是性能问题,当我们将日志级别设置为debug时,日志会被激活。在查看我们的系统后,我们得出了以下结论:
foo
打印到日志时,我们需要查看哪个实体称为A,B或C. foo
我们希望能够为每个foo
分别更改调试级别foo
应被视为公共库,不能直接依赖于A,B或C. foo
的相同实例(例如,我们的资源处理类的相同实例使用A,B和C),在日志中我们希望看到哪个类使用foo
。这是我们到目前为止所提出的 -
A,B和C将有单独的记录器。全局变量(保存在具有所有日志记录助手和包装器的不同库中)将始终保持当前日志报告。每次实体开始处理它的逻辑时,它都会将全局变量设置为正确的记录器。当foo
想要向日志报告时,它会通过全局变量报告并将其名称(和上下文)添加到日志消息。
问题是,感觉必须有一些东西可以做到这一点,解决方案感觉不干净,持有像这样的全局变量......
我们在这里做错了吗? 有更好的解决方案吗?
答案 0 :(得分:5)
我不知道现有的解决方案。我可能会想出一个带有如下界面的记录器(无论是独立实现还是现有的包装):
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);
不确定这样的界面是否符合您的目的。无论如何,我总是认为接口是一个很好的方法。一旦你有了一个清晰的界面,实现它应该是一件容易的事。
答案 1 :(得分:1)
如果单独的库本身是一个类,则可以使用库中的类级变量来保存记录器实例引用。我不经常使用C ++或Java编程,但我认为类级变量在C ++和Java中是“静态的”。
它仍然是一个全局变量,但至少它是类范围的全局变量(就像一个名为debugLog.log
的类变量,其中debugLog
是类名。)