diff options
-rw-r--r-- | include/logger.h | 4 | ||||
-rw-r--r-- | src/configreader.cpp | 3 | ||||
-rw-r--r-- | src/logger.cpp | 106 | ||||
-rw-r--r-- | src/modules/m_chanlog.cpp | 57 |
4 files changed, 122 insertions, 48 deletions
diff --git a/include/logger.h b/include/logger.h index c4729035c..c9e9f8c0e 100644 --- a/include/logger.h +++ b/include/logger.h @@ -86,7 +86,7 @@ class CoreExport LogStream : public classbase virtual ~LogStream() { } - virtual void OnLog(int loglevel, const std::string &type, const std::string &msg) { } + virtual void OnLog(int loglevel, const std::string &type, const std::string &msg) = 0; }; typedef std::map<FileWriter*, int> FileLogMap; @@ -97,6 +97,7 @@ class CoreExport LogManager : public classbase bool Logging; // true when logging, avoids recursion InspIRCd *ServerInstance; std::map<std::string, std::vector<LogStream *> > LogStreams; + std::map<LogStream *, int> AllLogStreams; // holds all logstreams std::vector<LogStream *> GlobalLogStreams; //holds all logstreams with a type of * FileLogMap FileLogs; /* Holds all file logs, refcounted */ public: @@ -134,6 +135,7 @@ class CoreExport LogManager : public classbase void OpenFileLogs(); void CloseLogs(); bool AddLogType(const std::string &type, LogStream *l); + void DelLogStream(LogStream* l); bool DelLogType(const std::string &type, LogStream *l); void Log(const std::string &type, int loglevel, const std::string &msg); void Log(const std::string &type, int loglevel, const char *fmt, ...); diff --git a/src/configreader.cpp b/src/configreader.cpp index fe02bc2bd..e0dd021ba 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -1175,6 +1175,9 @@ void ServerConfig::Read(bool bail, User* user, int pass) * stuff. Check that we have at least the required number * of whichever items. This is no longer done first. */ + /* Close all logs at this point and reopen <log method="file"> logs. */ + ServerInstance->Logs->CloseLogs(); + ServerInstance->Logs->OpenFileLogs(); ConfigReader* n = new ConfigReader(ServerInstance); FOREACH_MOD(I_OnReadConfig,OnReadConfig(this, n)); diff --git a/src/logger.cpp b/src/logger.cpp index b8cd3b298..7b0fa1798 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -101,33 +101,21 @@ void LogManager::OpenFileLogs() void LogManager::CloseLogs() { - /* - * This doesn't remove logstreams from the map/vector etc, because if this is called, shit is hitting the fan - * and we're going down anyway - this just provides a "nice" way for logstreams to clean up. -- w - */ - std::map<std::string, std::vector<LogStream *> >::iterator i; - - while (LogStreams.begin() != LogStreams.end()) + std::map<std::string, std::vector<LogStream*> >().swap(LogStreams); /* Clear it */ + std::vector<LogStream*>().swap(GlobalLogStreams); /* Clear it */ + for (std::map<LogStream*, int>::iterator i = AllLogStreams.begin(); i != AllLogStreams.end(); ++i) { - i = LogStreams.begin(); - - while (i->second.begin() != i->second.end()) - { - std::vector<LogStream *>::iterator it = i->second.begin(); - - delete (*it); - i->second.erase(it); - } - - LogStreams.erase(i); + delete i->first; } + std::map<LogStream*, int>().swap(AllLogStreams); /* And clear it */ + /* Now close FileLoggers, for those logstreams that neglected to properly free their stuff. */ - for (FileLogMap::iterator it = FileLogs.begin(); it != FileLogs.end(); ++i) + for (FileLogMap::iterator it = FileLogs.begin(); it != FileLogs.end(); ++it) { delete it->first; } - FileLogMap().swap(FileLogs); /* Swap with empty map to clear */ + FileLogMap().swap(FileLogs); } bool LogManager::AddLogType(const std::string &type, LogStream *l) @@ -146,47 +134,79 @@ bool LogManager::AddLogType(const std::string &type, LogStream *l) if (type == "*") GlobalLogStreams.push_back(l); + std::map<LogStream*, int>::iterator ai = AllLogStreams.find(l); + if (ai == AllLogStreams.end()) + { + AllLogStreams.insert(std::make_pair(l, 1)); + } + else + { + ++ai->second; + } + return true; } -bool LogManager::DelLogType(const std::string &type, LogStream *l) +void LogManager::DelLogStream(LogStream* l) { - std::map<std::string, std::vector<LogStream *> >::iterator i = LogStreams.find(type); - std::vector<LogStream *>::iterator gi = GlobalLogStreams.begin(); - - while (gi != GlobalLogStreams.end()) + for (std::map<std::string, std::vector<LogStream*> >::iterator i = LogStreams.begin(); i != LogStreams.end(); ++i) { - if ((*gi) == l) + std::vector<LogStream*>::iterator it; + while ((it = std::find(i->second.begin(), i->second.end(), l)) != i->second.end()) { - GlobalLogStreams.erase(gi); - break; + if (it == i->second.end()) continue; + i->second.erase(it); } } + std::vector<LogStream *>::iterator gi = std::find(GlobalLogStreams.begin(), GlobalLogStreams.end(), l); + if (gi != GlobalLogStreams.end()) GlobalLogStreams.erase(gi); + std::map<LogStream*, int>::iterator ai = AllLogStreams.begin(); + if (ai == AllLogStreams.end()) return; /* Done. */ + delete ai->first; + AllLogStreams.erase(ai); +} + +bool LogManager::DelLogType(const std::string &type, LogStream *l) +{ + std::map<std::string, std::vector<LogStream *> >::iterator i = LogStreams.find(type); + if (type == "*") + { + std::vector<LogStream *>::iterator gi = std::find(GlobalLogStreams.begin(), GlobalLogStreams.end(), l); + if (gi != GlobalLogStreams.end()) GlobalLogStreams.erase(gi); + } if (i != LogStreams.end()) { - std::vector<LogStream *>::iterator it = i->second.begin(); + std::vector<LogStream *>::iterator it = std::find(i->second.begin(), i->second.end(), l); - while (it != i->second.end()) + if (it != i->second.end()) { - if (*it == l) + i->second.erase(it); + if (i->second.size() == 0) { - i->second.erase(it); - - if (i->second.size() == 0) - { - LogStreams.erase(i); - } - - delete l; - return true; + LogStreams.erase(i); } - - it++; } + else + { + return false; + } + } + else + { + return false; } - return false; + std::map<LogStream*, int>::iterator ai = AllLogStreams.find(l); + if (ai == AllLogStreams.end()) return true; + + if ((--ai->second) < 1) + { + AllLogStreams.erase(ai); + delete l; + } + + return true; } void LogManager::Log(const std::string &type, int loglevel, const char *fmt, ...) diff --git a/src/modules/m_chanlog.cpp b/src/modules/m_chanlog.cpp index 0a189be7f..7d066a6ac 100644 --- a/src/modules/m_chanlog.cpp +++ b/src/modules/m_chanlog.cpp @@ -42,17 +42,66 @@ class ChannelLogStream : public LogStream class ModuleChanLog : public Module { private: - ChannelLogStream *l; + std::vector<ChannelLogStream*> cls; public: ModuleChanLog(InspIRCd* Me) : Module(Me) { - l = new ChannelLogStream(Me, ServerInstance->Config->LogLevel, "#services"); - Me->Logs->AddLogType("*", l); } virtual ~ModuleChanLog() { - delete l; + std::vector<ChannelLogStream*>::iterator i; + while ((i = cls.begin()) != cls.end()) + { + ServerInstance->Logs->DelLogStream(*i); + cls.erase(i); + } + } + + virtual void OnReadConfig(ServerConfig* sc, ConfigReader* Conf) + { + /* Since the CloseLogs prior to this hook just wiped out our logstreams for us, we just need to wipe the vector. */ + std::vector<ChannelLogStream*>().swap(cls); + int index, max = Conf->Enumerate("log"); + cls.reserve(max); + for (index = 0; index < max; ++index) + { + std::string method = Conf->ReadValue("log", "method", index); + if (method != "file") continue; + std::string type = Conf->ReadValue("log", "type", index); + std::string level = Conf->ReadValue("log", "level", index); + int loglevel = DEFAULT; + if (level == "debug") + { + loglevel = DEBUG; + ServerInstance->Config->debugging = true; + } + else if (level == "verbose") + { + loglevel = VERBOSE; + } + else if (level == "default") + { + loglevel = DEFAULT; + } + else if (level == "sparse") + { + loglevel = SPARSE; + } + else if (level == "none") + { + loglevel = NONE; + } + std::string target = Conf->ReadValue("log", "target", index); + ChannelLogStream* c = new ChannelLogStream(ServerInstance, loglevel, target); + irc::commasepstream css(type); + std::string tok; + while (css.GetToken(tok)) + { + ServerInstance->Logs->AddLogType(tok, c); + } + cls.push_back(c); + } } virtual Version GetVersion() |