]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/logger.h
New mode stuff. Note, the framework is now here so that every mode handler can state...
[user/henk/code/inspircd.git] / include / logger.h
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2008 InspIRCd Development Team
6  * See: http://www.inspircd.org/wiki/index.php/Credits
7  *
8  * This program is free but copyrighted software; see
9  *            the file COPYING for details.
10  *
11  * ---------------------------------------------------
12  */
13
14 #ifndef __LOGMANAGER_H
15 #define __LOGMANAGER_H
16
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
27  * blocking behaviour.
28  */
29 class CoreExport FileWriter : public EventHandler
30 {
31  protected:
32         /** The creator/owner of this object
33          */
34         InspIRCd* ServerInstance;
35         /** The log file (fd is inside this somewhere,
36          * we get it out with fileno())
37          */
38         FILE* log;
39         /** Buffer of pending log lines to be written
40          */
41         std::string buffer;
42         /** Number of write operations that have occured
43          */
44         int writeops;
45  public:
46         /** The constructor takes an already opened logfile.
47          */
48         FileWriter(InspIRCd* Instance, FILE* logfile);
49         /** This returns false, logfiles are writeable.
50          */
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.
57          */
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.
65          */
66         void WriteLogLine(const std::string &line);
67         /** Close the log file and cancel any events.
68          */
69         virtual void Close();
70         /** Close the log file and cancel any events.
71          * (indirectly call Close()
72          */
73         virtual ~FileWriter();
74 };
75
76 class CoreExport LogStream : public classbase
77 {
78  protected:
79         InspIRCd *ServerInstance;
80         int loglvl;
81  public:
82         LogStream(InspIRCd *Instance, int loglevel) : loglvl(loglevel)
83         {
84                 this->ServerInstance = Instance;
85         }
86
87         virtual ~LogStream() { }
88
89         virtual void OnLog(int loglevel, const std::string &type, const std::string &msg) = 0;
90 };
91
92 typedef std::map<FileWriter*, int> FileLogMap;
93
94 class CoreExport LogManager : public classbase
95 {
96  private:
97         bool Logging; // true when logging, avoids recursion
98         InspIRCd *ServerInstance;
99         std::map<std::string, std::vector<LogStream *> > LogStreams;
100         std::map<LogStream *, int> AllLogStreams; // holds all logstreams
101         std::vector<LogStream *> GlobalLogStreams; //holds all logstreams with a type of *
102         FileLogMap FileLogs; /* Holds all file logs, refcounted */
103  public:
104         LogManager(InspIRCd *Instance)
105         {
106                 ServerInstance = Instance;
107                 Logging = false;
108         }
109
110         void AddLoggerRef(FileWriter* fw)
111         {
112                 FileLogMap::iterator i = FileLogs.find(fw);
113                 if (i == FileLogs.end())
114                 {
115                         FileLogs.insert(std::make_pair(fw, 1));
116                 }
117                 else
118                 {
119                         ++i->second;
120                 }
121         }
122
123         void DelLoggerRef(FileWriter* fw)
124         {
125                 FileLogMap::iterator i = FileLogs.find(fw);
126                 if (i == FileLogs.end()) return; /* Maybe should log this? */
127                 if (--i->second < 1)
128                 {
129                         delete i->first;
130                         FileLogs.erase(i);
131                 }
132         }
133
134         void OpenSingleFile(FILE* f, const std::string& type, int loglevel);
135         void OpenFileLogs();
136         void CloseLogs();
137         bool AddLogType(const std::string &type, LogStream *l);
138         void DelLogStream(LogStream* l);
139         bool DelLogType(const std::string &type, LogStream *l);
140         void Log(const std::string &type, int loglevel, const std::string &msg);
141         void Log(const std::string &type, int loglevel, const char *fmt, ...);
142 };
143
144 #endif