diff options
Diffstat (limited to 'include/logger.h')
-rw-r--r-- | include/logger.h | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/include/logger.h b/include/logger.h index 8f030b53b..c4729035c 100644 --- a/include/logger.h +++ b/include/logger.h @@ -14,6 +14,65 @@ #ifndef __LOGMANAGER_H #define __LOGMANAGER_H +/** This class implements a nonblocking writer. + * Most people writing an ircd give little thought to their disk + * i/o. On a congested system, disk writes can block for long + * periods of time (e.g. if the system is busy and/or swapping + * a lot). If we just use a blocking fprintf() call, this could + * block for undesirable amounts of time (half of a second through + * to whole seconds). We DO NOT want this, so we make our logfile + * nonblocking and hook it into the SocketEngine. + * NB: If the operating system does not support nonblocking file + * I/O (linux seems to, as does freebsd) this will default to + * blocking behaviour. + */ +class CoreExport FileWriter : public EventHandler +{ + protected: + /** The creator/owner of this object + */ + InspIRCd* ServerInstance; + /** The log file (fd is inside this somewhere, + * we get it out with fileno()) + */ + FILE* log; + /** Buffer of pending log lines to be written + */ + std::string buffer; + /** Number of write operations that have occured + */ + int writeops; + public: + /** The constructor takes an already opened logfile. + */ + FileWriter(InspIRCd* Instance, FILE* logfile); + /** This returns false, logfiles are writeable. + */ + virtual bool Readable(); + /** Handle pending write events. + * This will flush any waiting data to disk. + * If any data remains after the fprintf call, + * another write event is scheduled to write + * the rest of the data when possible. + */ + virtual void HandleEvent(EventType et, int errornum = 0); + /** Write one or more preformatted log lines. + * If the data cannot be written immediately, + * this class will insert itself into the + * SocketEngine, and register a write event, + * and when the write event occurs it will + * attempt again to write the data. + */ + void WriteLogLine(const std::string &line); + /** Close the log file and cancel any events. + */ + virtual void Close(); + /** Close the log file and cancel any events. + * (indirectly call Close() + */ + virtual ~FileWriter(); +}; + class CoreExport LogStream : public classbase { protected: @@ -25,9 +84,13 @@ class CoreExport LogStream : public classbase this->ServerInstance = Instance; } + virtual ~LogStream() { } + virtual void OnLog(int loglevel, const std::string &type, const std::string &msg) { } }; +typedef std::map<FileWriter*, int> FileLogMap; + class CoreExport LogManager : public classbase { private: @@ -35,6 +98,7 @@ class CoreExport LogManager : public classbase InspIRCd *ServerInstance; std::map<std::string, std::vector<LogStream *> > LogStreams; std::vector<LogStream *> GlobalLogStreams; //holds all logstreams with a type of * + FileLogMap FileLogs; /* Holds all file logs, refcounted */ public: LogManager(InspIRCd *Instance) { @@ -42,6 +106,32 @@ class CoreExport LogManager : public classbase Logging = false; } + void AddLoggerRef(FileWriter* fw) + { + FileLogMap::iterator i = FileLogs.find(fw); + if (i == FileLogs.end()) + { + FileLogs.insert(std::make_pair(fw, 1)); + } + else + { + ++i->second; + } + } + + void DelLoggerRef(FileWriter* fw) + { + FileLogMap::iterator i = FileLogs.find(fw); + if (i == FileLogs.end()) return; /* Maybe should log this? */ + if (--i->second < 1) + { + delete i->first; + FileLogs.erase(i); + } + } + + void OpenSingleFile(FILE* f, const std::string& type, int loglevel); + void OpenFileLogs(); void CloseLogs(); bool AddLogType(const std::string &type, LogStream *l); bool DelLogType(const std::string &type, LogStream *l); |