File: Logger.h

package info (click to toggle)
tulip 4.8.0dfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 179,264 kB
  • ctags: 64,517
  • sloc: cpp: 600,444; ansic: 36,311; makefile: 22,136; python: 1,304; sh: 946; yacc: 522; xml: 337; pascal: 157; php: 66; lex: 55
file content (272 lines) | stat: -rw-r--r-- 10,418 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
/*
 * $Revision: 3157 $
 *
 * last checkin:
 *   $Author: chimani $
 *   $Date: 2012-12-12 16:49:59 +0100 (Wed, 12 Dec 2012) $
 ***************************************************************/

/** \file
 * \brief Contains logging functionality
 *
 * \author Markus Chimani
 *
 * \par License:
 * This file is part of the Open Graph Drawing Framework (OGDF).
 *
 * \par
 * Copyright (C)<br>
 * See README.txt in the root directory of the OGDF installation for details.
 *
 * \par
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * Version 2 or 3 as published by the Free Software Foundation;
 * see the file LICENSE.txt included in the packaging of this file
 * for details.
 *
 * \par
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * \par
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 * \see  http://www.gnu.org/copyleft/gpl.html
 ***************************************************************/


#ifndef OGDF_LOGGER_H
#define OGDF_LOGGER_H

//#include <ogdf/basic/basic.h>
#include <ogdf/internal/basic/config.h>

namespace ogdf {

//! Centralized global and local logging facility working on streams like cout.
/**
 * The Logger class is a centralized logging environment with 2x2 different use-cases working together.
 * All generated output is sent into the \a world-stream, i.e., \a cout, if not set otherwise.
 *
 * \b Logging \b vs. \b Statistic:
 * The Logger differentiates between \a logging and \a statistic mode.
 * When in logging mode, only the output written via the lout()/slout() commands is
 * written to the world stream (according to loglevels). When in statistic mode,
 * only the output of the sout()/ssout() commands is written.
 * (Sidenote: there is also a \a forced output fout()/sfout() which is written independent on the current mode).
 *
 * The idea of these two modi is that one can augment the code with output which is
 * interesting in the normal computation mode via lout, but the same algorithm can also be run given tabular
 * statistic-lines when e.g. batch-testing the algorithm on a set of benchmark instances.
 *
 * \b Global \b vs. \b Local:
 * You can choose to use the Logging facilities globally via the static outputs (slout(), ssout(), sfout()).
 * Thereby the global log-level and statistic-mode settings are applied.
 * Alternatively you can create your own Logging object with its own parameters only for your algorithm,
 * and use the object methods lout(), sout(), and fout(). This allows you to turn output on for your own
 * (new) algorithm, but keep the rest of the library silent.
 *
 * \b Global \b Settings:
 * The slout command takes an (optional) parameter given the importance of the output (aka. loglevel).
 * The output is written only if the globalLogLevel is not higher. The method globalStatisticMode
 * turn the statistic-mode on and off (thereby disabling or enabling the logging mode).
 *
 * Furthermore, we have a globalMinimumLogLevel. This is used to globally forbid any output
 * with too low importance written by any Logger-objects.
 *
 * \b Local \b Settings:
 * A Logger-object has its own set of settings, i.e., its own localLogLevel and an own localLogMode,
 * which can be any of the following:
 *   - \a LM_LOG: the object is in logging mode, using its own localLogLevel
 *   - \a LM_STATISTIC: the object is in statistic mode
 *   - \a LM_GLOBAL: the object is in the same mode as the static Logger-class (i.e., global settings)
 *   - \a LM_GLOBALLOG: the object is in logging mode, but uses the globalLogLevel
 *
 * \b Typical \b Usage:<br>
 * The simplest but restricted and verbose usage is to write <br>
 * <code><br>
 *    Logger::slout() << "1+2=" << (1+2) << endl;
 * </code>
 *
 * The conceptually easiest and cleanest approach is to augment your algorithm class with a Logger.
 * Multiple inheritance allows this pretty straightforwardly:<br>
 * <code><br>
 *    class MyAlgorithm : public MyBaseClass, protected Logger {<br>
 *    &nbsp;&nbsp;int myMethod();<br>
 *    }<br>
 *    <br>
 *    MyAlgorithm::myMethod() {<br>
 *    &nbsp;&nbsp;lout() << "1+2=" << (1+2) << endl;<br>
 *    }<br>
 * </code>
 *
 *
 *  \b Internal \b Library \b Logging:
 *  Internal Libaries (as, e.g., Abacus) can use their own, global, set of logging functions.
 *  Its LogLevels are parallel and independent of the global LogLevel, but its logging is automatically
 *  turned off whenever the (global/static) Logger is in statistics-mode.
 */

class OGDF_EXPORT Logger {

public:
	//! supported log-levels from lowest to highest importance
	enum Level { LL_MINOR, LL_MEDIUM, LL_DEFAULT, LL_HIGH, LL_ALARM, LL_FORCE };
	//! (local) log-modes (see class description)
	enum LogMode { LM_GLOBAL, LM_GLOBALLOG, LM_LOG, LM_STATISTIC };

	// CONSTRUCTORS //////////////////////////////////////
	//! creates a new Logger-object with LM_GLOBAL and local log-level equal globalLogLevel
	Logger() :
		m_loglevel(m_globalloglevel), m_logmode(LM_GLOBAL) {}
	//! creates a new Logger-object with given log-mode and local log-level equal globalLogLevel
	Logger(LogMode m) :
		m_loglevel(m_globalloglevel), m_logmode(m) {}
	//! creates a new Logger-object with LM_GLOBAL and given local log-level
	Logger(Level l) :
		m_loglevel(l), m_logmode(LM_GLOBAL) {}
	//! creates a new Logger-object with given log-mode and given local log-level
	Logger(LogMode m, Level l) :
		m_loglevel(l), m_logmode(m) {}

	// USAGE //////////////////////////////////////
	//! returns true if such an lout command will result in text being printed
	bool is_lout(Level l = LL_DEFAULT) const {
		return ((!m_globalstatisticmode && m_logmode==LM_GLOBAL) || m_logmode==LM_GLOBALLOG)
						? ( (l >= m_globalloglevel) ? true : false )
						: ( (m_logmode==LM_LOG && l >= m_loglevel && l >= m_minimumloglevel) ? true : false );
	}
	//! stream for logging-output (local)
	std::ostream& lout(Level l = LL_DEFAULT) const {
		return (is_lout(l)) ? *world : nirvana;
	}
	//! stream for statistic-output (local)
	std::ostream& sout() const {
		return ((m_globalstatisticmode && m_logmode==LM_GLOBAL) || (m_logmode == LM_STATISTIC)) ? *world : nirvana;
	}
	//! stream for forced output (local)
	std::ostream& fout() const {
		return sfout();
	}

	// STATIC USAGE ///////////////////////////////
	//! returns true if such an slout command will result in text being printed
	static bool is_slout(Level l = LL_DEFAULT) {
		return ((!m_globalstatisticmode) && l >= m_globalloglevel) ? true : false;
	}
	//! stream for logging-output (global)
	static std::ostream& slout(Level l = LL_DEFAULT) {
		return (is_slout(l)) ? *world : nirvana;
	}
	//! stream for statistic-output (global)
	static std::ostream& ssout() {
		return (m_globalstatisticmode) ? *world : nirvana;
	}
	//! stream for forced output (global)
	static std::ostream& sfout() {
		return *world;
	}

	// STATIC INTERNAL_LIBRARY_USAGE ///////////////////////////////
	//! stream for logging-output (global; used by internal libraries, e.g. Abacus)
	//! returns true if such an ilout command will result in text being printed
	static bool is_ilout(Level l = LL_DEFAULT) {
		return ((!m_globalstatisticmode) && l >= m_globallibraryloglevel) ? true : false;
	}
	static std::ostream& ilout(Level l = LL_DEFAULT) {
		return (is_ilout(l)) ? *world : nirvana;
	}

	//! stream for forced output (global; used by internal libraries, e.g. Abacus)
	static std::ostream& ifout() {
		return *world;
	}

	// LOCAL //////////////////////////////////////
	//! gives the local log-level
	Level localLogLevel() const {
		return m_loglevel;
	}
	//! sets the local log-level
	void localLogLevel(Level l) {
		m_loglevel = l;
	}
	//! gives the local log-mode
	LogMode localLogMode() const {
		return m_logmode;
	}
	//! sets the local log-mode
	void localLogMode(LogMode m) {
		m_logmode = m;
	}

	// GLOBAL //////////////////////////////////////
	//! gives the global log-level
	static Level globalLogLevel() { return m_globalloglevel; }
	//! sets the global log-level
	static void globalLogLevel(Level l) {
		m_globalloglevel = l;
		if( m_globalloglevel < m_minimumloglevel )
			m_minimumloglevel = m_globalloglevel;
	}

	//! gives the internal-library log-level
	static Level globalInternalLibraryLogLevel() { return m_globallibraryloglevel; }
	//! sets the internal-library log-level
	static void globalInternalLibraryLogLevel(Level l) { m_globallibraryloglevel = l; }

	//! gives the globally minimally required log-level
	static Level globalMinimumLogLevel() { return m_minimumloglevel; }
	//! sets the globally minimally required log-level
	static void globalMinimumLogLevel(Level l) {
		m_minimumloglevel = l;
		if( m_globalloglevel < m_minimumloglevel )
			m_globalloglevel = m_minimumloglevel;
	}

	//! returns true if we are globally in statistic mode
	static bool globalStatisticMode() { return m_globalstatisticmode; }
	//! sets whether we are globally in statistic mode
	static void globalStatisticMode(bool s) { m_globalstatisticmode = s; }

	//! change the stream to which allowed output is written (by default: cout)
	static void setWorldStream(std::ostream& o) { world = &o; }

	// EFFECTIVE //////////////////////////////////////
	//! obtain the effective log-level for the Logger-object (i.e., resolve the dependencies on the global settings)
	Level effectiveLogLevel() const {
		if(m_logmode==LM_GLOBAL || m_logmode==LM_GLOBALLOG)
			return m_globalloglevel;
		else
			return (m_loglevel > m_minimumloglevel) ? m_loglevel : m_minimumloglevel;
	}

	//! returns true if the Logger-object is effectively in statistic-mode (as this might be depending on the global settings)
	bool effectiveStatisticMode() const {
		return m_logmode==LM_STATISTIC || (m_logmode==LM_GLOBAL && m_globalstatisticmode);
	}


private:
	static std::ostream nirvana;
	static std::ostream* world;

	static Level m_globalloglevel;
	static Level m_globallibraryloglevel;
	static Level m_minimumloglevel;
	static bool m_globalstatisticmode;

	Level m_loglevel;
	LogMode m_logmode;
};

}

#endif // OGDF_LOGGER_H