1 /* +------------------------------------+
2 * | Inspire Internet Relay Chat Daemon |
3 * +------------------------------------+
5 * InspIRCd: (C) 2002-2008 InspIRCd Development Team
6 * See: http://www.inspircd.org/wiki/index.php/Credits
8 * This program is free but copyrighted software; see
9 * the file COPYING for details.
11 * ---------------------------------------------------
14 #ifndef __LOGMANAGER_H
15 #define __LOGMANAGER_H
17 /** This class implements a nonblocking writer.
18 * Most people writing an ircd give little thought to their disk
19 * i/o. On a congested system, disk writes can block for long
20 * periods of time (e.g. if the system is busy and/or swapping
21 * a lot). If we just use a blocking fprintf() call, this could
22 * block for undesirable amounts of time (half of a second through
23 * to whole seconds). We DO NOT want this, so we make our logfile
24 * nonblocking and hook it into the SocketEngine.
25 * NB: If the operating system does not support nonblocking file
26 * I/O (linux seems to, as does freebsd) this will default to
29 class CoreExport FileWriter : public EventHandler
32 /** The creator/owner of this object
34 InspIRCd* ServerInstance;
35 /** The log file (fd is inside this somewhere,
36 * we get it out with fileno())
39 /** Buffer of pending log lines to be written
42 /** Number of write operations that have occured
46 /** The constructor takes an already opened logfile.
48 FileWriter(InspIRCd* Instance, FILE* logfile);
49 /** This returns false, logfiles are writeable.
51 virtual bool Readable();
52 /** Handle pending write events.
53 * This will flush any waiting data to disk.
54 * If any data remains after the fprintf call,
55 * another write event is scheduled to write
56 * the rest of the data when possible.
58 virtual void HandleEvent(EventType et, int errornum = 0);
59 /** Write one or more preformatted log lines.
60 * If the data cannot be written immediately,
61 * this class will insert itself into the
62 * SocketEngine, and register a write event,
63 * and when the write event occurs it will
64 * attempt again to write the data.
66 void WriteLogLine(const std::string &line);
67 /** Close the log file and cancel any events.
70 /** Close the log file and cancel any events.
71 * (indirectly call Close()
73 virtual ~FileWriter();
76 class CoreExport LogStream : public classbase
79 InspIRCd *ServerInstance;
82 LogStream(InspIRCd *Instance, int loglevel) : loglvl(loglevel)
84 this->ServerInstance = Instance;
87 virtual ~LogStream() { }
89 void ChangeLevel(int lvl) { this->loglvl = lvl; } // For on-the-fly change of loglevel.
91 virtual void OnLog(int loglevel, const std::string &type, const std::string &msg) = 0;
94 typedef std::map<FileWriter*, int> FileLogMap;
96 class CoreExport LogManager : public classbase
99 bool Logging; // true when logging, avoids recursion
100 LogStream* noforkstream; // LogStream for nofork.
101 InspIRCd *ServerInstance;
102 std::map<std::string, std::vector<LogStream *> > LogStreams;
103 std::map<LogStream *, int> AllLogStreams; // holds all logstreams
104 std::vector<LogStream *> GlobalLogStreams; //holds all logstreams with a type of *
105 FileLogMap FileLogs; /* Holds all file logs, refcounted */
107 LogManager(InspIRCd *Instance)
109 ServerInstance = Instance;
115 void AddLoggerRef(FileWriter* fw)
117 FileLogMap::iterator i = FileLogs.find(fw);
118 if (i == FileLogs.end())
120 FileLogs.insert(std::make_pair(fw, 1));
128 void DelLoggerRef(FileWriter* fw)
130 FileLogMap::iterator i = FileLogs.find(fw);
131 if (i == FileLogs.end()) return; /* Maybe should log this? */
139 void OpenSingleFile(FILE* f, const std::string& type, int loglevel);
142 bool AddLogType(const std::string &type, LogStream *l, bool autoclose);
143 void DelLogStream(LogStream* l);
144 bool DelLogType(const std::string &type, LogStream *l);
145 void Log(const std::string &type, int loglevel, const std::string &msg);
146 void Log(const std::string &type, int loglevel, const char *fmt, ...);