summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/logger.h4
-rw-r--r--src/configreader.cpp3
-rw-r--r--src/logger.cpp106
-rw-r--r--src/modules/m_chanlog.cpp57
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()