InspIRCd  3.0
logger.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  * Copyright (C) 2014 Attila Molnar <[email protected]>
5  * Copyright (C) 2012-2013, 2017 Sadie Powell <[email protected]>
6  * Copyright (C) 2012, 2019 Robby <[email protected]>
7  * Copyright (C) 2010 Craig Edwards <[email protected]>
8  * Copyright (C) 2009 Daniel De Graaf <[email protected]>
9  * Copyright (C) 2008, 2012 Robin Burchell <[email protected]>
10  * Copyright (C) 2008 Thomas Stagner <[email protected]>
11  *
12  * This file is part of InspIRCd. InspIRCd is free software: you can
13  * redistribute it and/or modify it under the terms of the GNU General Public
14  * License as published by the Free Software Foundation, version 2.
15  *
16  * This program is distributed in the hope that it will be useful, but WITHOUT
17  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
19  * details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program. If not, see <http://www.gnu.org/licenses/>.
23  */
24 
25 
26 #pragma once
27 
29 enum LogLevel
30 {
31  LOG_RAWIO = 5,
32  LOG_DEBUG = 10,
33  LOG_VERBOSE = 20,
34  LOG_DEFAULT = 30,
35  LOG_SPARSE = 40,
36  LOG_NONE = 50
37 };
38 
41 class CoreExport FileWriter
42 {
43  protected:
47  FILE* log;
48 
51  unsigned int flush;
52 
55  unsigned int writeops;
56 
57  public:
60  FileWriter(FILE* logfile, unsigned int flushcount);
61 
69  void WriteLogLine(const std::string &line);
70 
73  virtual ~FileWriter();
74 };
75 
76 
77 
78 /*
79  * New world logging!
80  * The brief summary:
81  * Logging used to be a simple affair, a FILE * handled by a nonblocking logging class inheriting from EventHandler, that was inserted
82  * into the socket engine, and wrote lines. If nofork was on, it was printf()'d.
83  *
84  * We decided to horribly overcomplicate matters, and create vastly customisable logging. LogManager and LogStream form the visible basis
85  * of the new interface. Basically, a LogStream can be inherited to do different things with logging output. We inherit from it once in core
86  * to create a FileLogStream, that writes to a file, for example. Different LogStreams can hook different types of log messages, and different
87  * levels of output too, for extreme customisation. Multiple LogStreams can hook the same message/levels of output, meaning that e.g. output
88  * can go to a channel as well as a file.
89  *
90  * HOW THIS WORKS
91  * LogManager handles all instances of LogStreams, classes derived from LogStream are instantiated and passed to it.
92  */
93 
96 class CoreExport LogStream : public classbase
97 {
98  protected:
99  LogLevel loglvl;
100  public:
101  static const char LogHeader[];
102 
103  LogStream(LogLevel loglevel) : loglvl(loglevel)
104  {
105  }
106 
107  /* A LogStream's destructor should do whatever it needs to close any resources it was using (or indicate that it is no longer using a resource
108  * in the event that the resource is shared, see for example FileLogStream).
109  */
110  virtual ~LogStream() { }
111 
115  void ChangeLevel(LogLevel lvl) { this->loglvl = lvl; }
116 
121  virtual void OnLog(LogLevel loglevel, const std::string &type, const std::string &msg) = 0;
122 };
123 
124 typedef std::map<FileWriter*, int> FileLogMap;
125 
126 class CoreExport LogManager : public fakederef<LogManager>
127 {
128  private:
131  bool Logging;
132 
135  std::map<std::string, std::vector<LogStream *> > LogStreams;
136 
140  std::map<LogStream *, int> AllLogStreams;
141 
144  std::map<LogStream *, std::vector<std::string> > GlobalLogStreams;
145 
148  FileLogMap FileLogs;
149 
150  public:
151  LogManager();
152  ~LogManager();
153 
158  {
159  FileLogMap::iterator i = FileLogs.find(fw);
160  if (i == FileLogs.end())
161  {
162  FileLogs.insert(std::make_pair(fw, 1));
163  }
164  else
165  {
166  ++i->second;
167  }
168  }
169 
173  {
174  FileLogMap::iterator i = FileLogs.find(fw);
175  if (i == FileLogs.end()) return; /* Maybe should log this? */
176  if (--i->second < 1)
177  {
178  delete i->first;
179  FileLogs.erase(i);
180  }
181  }
182 
185  void OpenFileLogs();
186 
190  void CloseLogs();
191 
199  void AddLogTypes(const std::string &type, LogStream *l, bool autoclose);
200 
208  bool AddLogType(const std::string &type, LogStream *l, bool autoclose);
209 
213  void DelLogStream(LogStream* l);
214 
218  bool DelLogType(const std::string &type, LogStream *l);
219 
225  void Log(const std::string &type, LogLevel loglevel, const std::string &msg);
226 
232  void Log(const std::string &type, LogLevel loglevel, const char *fmt, ...) CUSTOM_PRINTF(4, 5);
233 };
fakederef
Definition: inspircd.h:71
LogManager
Definition: logger.h:126
FileWriter::writeops
unsigned int writeops
Definition: logger.h:55
LogManager::AddLoggerRef
void AddLoggerRef(FileWriter *fw)
Definition: logger.h:157
classbase
Definition: base.h:46
FileWriter::flush
unsigned int flush
Definition: logger.h:51
FileWriter::log
FILE * log
Definition: logger.h:47
LogStream::ChangeLevel
void ChangeLevel(LogLevel lvl)
Definition: logger.h:115
LogStream
Definition: logger.h:96
LogManager::DelLoggerRef
void DelLoggerRef(FileWriter *fw)
Definition: logger.h:172
FileWriter
Definition: logger.h:41