I do not know of an existing solution. I would probably come up with a logger with an interface like the following (whether it is a standalone implementation or just a wrapper on your existing one):
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);
...
};
The main deviation from common log libraries are the context-sensitive module filter. We may have setups like the following to set different levels according to who makes the call (the 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);
Then, the call flow will be like:
// In entity A
Logger::Instance()->SetThreadLocalContext("A");
// Call function foo
Logger::Instance()->Log(log_level, "foo", log_msg);
Not sure whether such an interface meets your purpose. Anyway, I always regard interface first a good approach. Once you have a clear interface, implementing it should be an easy job.