IMP
2.1.0
The Integrative Modeling Platform
IMP Mainpage
All IMP Modules
Related Pages
Modules
Namespaces
Classes
Files
Examples
Indexes
File List
File Members
base/log_macros.h
Go to the documentation of this file.
1
/**
2
* \file IMP/base/log_macros.h
3
* \brief Logging and error reporting support.
4
*
5
* Copyright 2007-2013 IMP Inventors. All rights reserved.
6
*
7
*/
8
9
#ifndef IMPBASE_LOG_MACROS_H
10
#define IMPBASE_LOG_MACROS_H
11
12
#include <IMP/base/base_config.h>
13
#include "
enums.h
"
14
#include "
log.h
"
15
#include "
CreateLogContext.h
"
16
#include "
compiler_macros.h
"
17
#include "
SetCheckState.h
"
18
#include "internal/log.h"
19
#include <sstream>
20
21
#if IMP_BASE_HAS_LOG4CXX
22
#include <log4cxx/logger.h>
23
#endif
24
25
#ifndef IMP_DOXYGEN
26
#define IMP_LOG_USING \
27
using IMP::base::VERBOSE; \
28
using IMP::base::TERSE; \
29
using IMP::base::SILENT; \
30
using IMP::base::WARNING; \
31
using IMP::base::PROGRESS; \
32
using IMP::base::MEMORY
33
34
#endif
35
36
#if !defined(IMP_HAS_LOG)
37
#error "IMP_HAS_LOG is not defined, compilation is broken"
38
#endif
39
40
#if !defined(IMP_SILENT)
41
#error "IMP_SILENT is not defined, compilation is broken"
42
#endif
43
44
#if defined(IMP_DOXYGEN)
45
//! Execute the code block if a certain level of logging is on
46
/**
47
The next code block (delimited by { }) is executed if
48
get_log_level() >= level.
49
50
\code
51
IMP_IF_LOG(VERBOSE) {
52
Floats testp(input.begin(), input.end());
53
std::sort(testp.begin(), testp.end());
54
IMP_LOG_VERBOSE( "Sorted order is ");
55
IMP_LOG_WRITE(VERBOSE, std::copy(testp.begin(), testp.end(),
56
std::ostream_iterator<double>(IMP_STREAM, " ")));
57
}
58
\endcode
59
*/
60
#define IMP_IF_LOG(level)
61
62
//! Write a warning to a log.
63
/** \param[in] expr An expression to be output to the log. It is prefixed
64
by "WARNING"
65
*/
66
#define IMP_WARN(expr)
67
68
//! Write a warning to standard error.
69
/** \param[in] expr An expression to be output to std::cerr. It is prefixed
70
by "ERROR"
71
*/
72
#define IMP_ERROR(expr)
73
74
/** \param[in] expr A stream expression to be sent to the output stream if the
75
log level is at least TERSE.
76
77
Usage:
78
\code
79
IMP_LOG_VERBOSE( "Hi there, I'm very talkative. My favorite numbers are "
80
<< 1 << " " << 2 << " " << 3);
81
\endcode
82
*/
83
#define IMP_LOG_TERSE(expr)
84
85
/** \param[in] expr A stream expression to be sent to the output stream if the
86
log level is at least TERSE.
87
88
Usage:
89
\code
90
IMP_LOG_VERBOSE( "Hi there, I'm very talkative. My favorite numbers are "
91
<< 1 << " " << 2 << " " << 3);
92
\endcode
93
*/
94
#define IMP_LOG_VERBOSE(expr)
95
96
/** \param[in] expr A stream expression to be sent to the output stream if the
97
log level is at least PROGRESS.
98
99
Usage:
100
\code
101
IMP_LOG_VERBOSE( "Hi there, I'm very talkative. My favorite numbers are "
102
<< 1 << " " << 2 << " " << 3);
103
\endcode
104
*/
105
#define IMP_LOG_PROGRESS(expr)
106
107
/** Mark a variable as one that is only used in logging. This disables
108
unused variable warnings on it in fast mode.
109
*/
110
#define IMP_LOG_VARIABLE(variable)
111
112
#else // IMP_DOXYGEN
113
114
#define IMP_LOG(level, expr) \
115
{ \
116
IMP_LOG_USING; \
117
switch (level) { \
118
case SILENT: \
119
break; \
120
case PROGRESS: \
121
IMP_LOG_PROGRESS(expr); \
122
break; \
123
case TERSE: \
124
IMP_LOG_TERSE(expr); \
125
break; \
126
case WARNING: \
127
IMP_WARN(expr); \
128
break; \
129
case VERBOSE: \
130
IMP_LOG_VERBOSE(expr); \
131
break; \
132
case MEMORY: \
133
IMP_LOG_MEMORY(expr); \
134
break; \
135
case IMP::base::DEFAULT: \
136
case IMP::base::ALL_LOG: \
137
default: \
138
IMP_ERROR( \
139
"Unknown log level " << boost::lexical_cast<std::string>(level)); \
140
} \
141
}
142
143
#if IMP_HAS_LOG < IMP_PROGRESS
144
#define IMP_IF_LOG(level) if (false)
145
#define IMP_LOG_PROGRESS(expr)
146
#define IMP_WARN(expr) \
147
if (false) std::cout << expr;
148
#define IMP_LOG_VARIABLE(variable) IMP_UNUSED(variable)
149
#else
150
#define IMP_LOG_VARIABLE(variable)
151
#endif
152
153
#if IMP_HAS_LOG < IMP_TERSE
154
#define IMP_LOG_TERSE(expr)
155
#endif
156
157
#if IMP_HAS_LOG < IMP_VERBOSE
158
#define IMP_LOG_VERBOSE(expr)
159
#define IMP_LOG_MEMORY(expr)
160
#endif
161
162
#if IMP_BASE_HAS_LOG4CXX
163
164
// figure out later
165
166
#if IMP_HAS_LOG >= IMP_PROGRESS
167
#define IMP_IF_LOG(level) if (true)
168
#define IMP_LOG_PROGRESS(expr) \
169
{ \
170
using IMP::base::internal::log::operator<<; \
171
LOG4CXX_INFO(IMP::base::get_logger(), expr); \
172
}
173
#define IMP_WARN(expr) \
174
{ \
175
using IMP::base::internal::log::operator<<; \
176
LOG4CXX_WARN(IMP::base::get_logger(), expr); \
177
}
178
#endif
179
180
#if IMP_HAS_LOG >= IMP_TERSE
181
#define IMP_LOG_TERSE(expr) \
182
{ \
183
using IMP::base::internal::log::operator<<; \
184
LOG4CXX_INFO(IMP::base::get_logger(), expr); \
185
}
186
#endif
187
188
#if IMP_HAS_LOG >= IMP_VERBOSE
189
#define IMP_LOG_VERBOSE(expr) \
190
{ \
191
using IMP::base::internal::log::operator<<; \
192
LOG4CXX_DEBUG(IMP::base::get_logger(), expr); \
193
}
194
195
#define IMP_LOG_MEMORY(expr) \
196
{ \
197
using IMP::base::internal::log::operator<<; \
198
LOG4CXX_TRACE(IMP::base::get_logger(), expr); \
199
}
200
#endif
201
202
#define IMP_ERROR(expr) \
203
{ \
204
using IMP::base::internal::log::operator<<; \
205
LOG4CXX_ERROR(IMP::base::get_logger(), expr << std::endl); \
206
}
207
208
#else // log4cxx
209
210
#if IMP_HAS_LOG > IMP_SILENT
211
#define IMP_IF_LOG(level) \
212
IMP_LOG_USING; \
213
if (level <= ::IMP::base::get_log_level())
214
#define IMP_LOG_PROGRESS(expr) \
215
if (IMP::base::get_log_level() >= IMP::base::PROGRESS) { \
216
std::ostringstream oss; \
217
oss << expr; \
218
IMP::base::add_to_log(oss.str()); \
219
}
220
221
#define IMP_WARN(expr) \
222
if (IMP::base::get_log_level() >= IMP::base::WARNING) { \
223
std::ostringstream oss; \
224
oss << "WARNING " << expr << std::flush; \
225
IMP::base::add_to_log(oss.str()); \
226
} \
227
;
228
#endif
229
230
#if IMP_HAS_LOG >= IMP_TERSE
231
#define IMP_LOG_TERSE(expr) \
232
if (IMP::base::get_log_level() >= IMP::base::TERSE) { \
233
std::ostringstream oss; \
234
oss << expr; \
235
IMP::base::add_to_log(oss.str()); \
236
}
237
238
#endif
239
240
#if IMP_HAS_LOG >= IMP_VERBOSE
241
#define IMP_LOG_VERBOSE(expr) \
242
if (IMP::base::get_log_level() >= IMP::base::VERBOSE) { \
243
std::ostringstream oss; \
244
oss << expr; \
245
IMP::base::add_to_log(oss.str()); \
246
}
247
#define IMP_LOG_MEMORY(expr) \
248
if (IMP::base::get_log_level() >= IMP::base::MEMORY) { \
249
std::ostringstream oss; \
250
oss << expr; \
251
IMP::base::add_to_log(oss.str()); \
252
}
253
#endif
254
255
#define IMP_ERROR(expr) \
256
{ \
257
std::cerr << "ERROR: " << expr << std::endl; \
258
throw IMP::base::InternalException("Failure"); \
259
}
260
261
#endif // log4cxx
262
263
#endif // else on IMP_DXOYGEN
264
265
#define IMP_ERROR_WRITE(expr) \
266
{ \
267
std::ostringstream IMP_STREAM; \
268
expr; \
269
IMP_STREAM << std::endl; \
270
IMP_ERROR(IMP_STREAM.str()); \
271
}
272
273
#define IMP_LOG_WRITE(level, expr) \
274
IMP_IF_LOG(level) { \
275
std::ostringstream IMP_STREAM; \
276
expr; \
277
IMP_STREAM << std::endl; \
278
IMP_LOG(level, IMP_STREAM.str()); \
279
}
280
281
#define IMP_WARN_WRITE(expr) \
282
IMP_IF_LOG(WARNING) { \
283
std::ostringstream IMP_STREAM; \
284
expr; \
285
IMP_STREAM << std::endl; \
286
IMP_WARN(IMP_STREAM.str()); \
287
}
288
289
#if IMP_HAS_LOG
290
291
//! Set the log level to the object's log level.
292
/** All non-trivial Object methods should start with this. It creates a
293
RAII-style object which sets the log level to the local one,
294
if appropriate, until it goes out of scope.
295
*/
296
#define IMP_OBJECT_LOG \
297
IMP::base::SetLogState log_state_guard__(this->get_log_level()); \
298
IMP::base::SetCheckState check_state_guard__(this->get_check_level()); \
299
IMP_CHECK_OBJECT(this); \
300
IMP::base::CreateLogContext log_context__(IMP_CURRENT_FUNCTION, this)
301
302
//! Beginning logging for a non-member function
303
/**
304
*/
305
#define IMP_FUNCTION_LOG \
306
IMP::base::CreateLogContext log_context__(IMP_CURRENT_FUNCTION)
307
308
//! Create a new log context from a streamed name
309
#define IMP_LOG_CONTEXT(name) \
310
IMP::base::CreateLogContext imp_log_context(name, nullptr)
311
312
//! Write a warning once per context object
313
/** Use this macro to, for example, warn on unprocessable fields in a PDB,
314
since they tend to come together. The key is what is tested
315
for uniqueness, the expr is what is output.
316
317
Warnings are only output when the context object is destroyed.
318
*/
319
#define IMP_WARN_ONCE(key, expr, context) \
320
IMP_IF_LOG(WARNING) { \
321
std::ostringstream oss; \
322
oss << expr << std::flush; \
323
context.add_warning(key, oss.str()); \
324
}
325
326
/** Like IMP::base::set_progress_display() but you can use stream operations
327
for the name.*/
328
#define IMP_PROGRESS_DISPLAY(name, steps) \
329
{ \
330
if (IMP::base::get_log_level() >= IMP::base::PROGRESS) { \
331
std::ostringstream oss; \
332
oss << name; \
333
IMP::base::set_progress_display(oss.str(), steps); \
334
} \
335
}
336
337
#else
338
#define IMP_OBJECT_LOG
339
#define IMP_FUNCTION_LOG
340
#define IMP_LOG_CONTEXT(name)
341
#define IMP_WARN_ONCE(key, expr, context)
342
#define IMP_PROGRESS_DISPLAY(name, steps)
343
#endif
344
345
#endif
/* IMPBASE_LOG_MACROS_H */
compiler_macros.h
Various compiler workarounds.
SetCheckState.h
Checkging and error reporting support.
CreateLogContext.h
Logging and error reporting support.
enums.h
Basic types used by IMP.
log.h
Logging and error reporting support.