An attempt to get rid of lazy log instantiation boilerplate
#define LAZY_LOG_GETTER(fnx, name) \
LogModule* fnx() { static LogModule* module = LogModule::CreateModule(name); return module; }
LAZY_LOG_GETTER(GetFooLog, "foo");
// ...
MOZ_LOG(GetFooLog(), LogLevel::Debug, ("Debugging the foo!"));
Or perhaps a nice way w/o macros (I'm not sure how we'd get name
in there though)
struct LazyLogModule<name> {
operator LogModule*() {
static LogModule* module = LogModule::CreateModule(name); return module;
}
};
LazyLogModule<"Foo"> gFooLog;
// ...
MOZ_LOG(gFooLog, LogLevel::Debug, ("Debugging the foo!"));
Rough draft of LogModule and LogManager
class LogModule {
public:
static LogModule* CreateModule(const nsAString& name, LogLevel level = LogLevel::Disabled);
bool ShouldLog(LogLevel aLevel);
PRLogModule* GetPRModule();
LogLevel GetLevel();
private:
LogModule(PRLogModule aModule, LogLevel level);
LogModule(LogModule&) = delete;
LogModule& operator=(const LogModule&) = delete;
LogLevel mLevel; // mozilla log level
PRLogModule* mModule; // non-owning
}
// Handles registration, pref updates
class LogManager
{
public:
static LogManager& GetManager();
private:
Lock tableLock;
Table moduleTable;
};
LogModule* CreateModule(const nsAString& name, LogLevel level = LogLevel::Disabled)
{
AutoLock guard(tableLock);
// check our table
LogModule* module = table.find(name);
if (!module) {
PRLogModuleInfo* pr = PR_NewLogModule(name);
module = new Module(pr, std::max(level, pr->level));
table.insert(name, module);
}
return module;
}