IMP
2.4.0
The Integrative Modeling Platform
IMP Mainpage
Modules
Classes
Examples
include
IMP
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-2015 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
#endif
228
229
#if IMP_HAS_LOG >= IMP_TERSE
230
#define IMP_LOG_TERSE(expr) \
231
if (IMP::base::get_log_level() >= IMP::base::TERSE) { \
232
std::ostringstream oss; \
233
oss << expr; \
234
IMP::base::add_to_log(oss.str()); \
235
}
236
237
#endif
238
239
#if IMP_HAS_LOG >= IMP_VERBOSE
240
#define IMP_LOG_VERBOSE(expr) \
241
if (IMP::base::get_log_level() >= IMP::base::VERBOSE) { \
242
std::ostringstream oss; \
243
oss << expr; \
244
IMP::base::add_to_log(oss.str()); \
245
}
246
#define IMP_LOG_MEMORY(expr) \
247
if (IMP::base::get_log_level() >= IMP::base::MEMORY) { \
248
std::ostringstream oss; \
249
oss << expr; \
250
IMP::base::add_to_log(oss.str()); \
251
}
252
#endif
253
254
#define IMP_ERROR(expr) \
255
{ \
256
std::cerr << "ERROR: " << expr << std::endl; \
257
std::ostringstream oss; \
258
oss << expr; \
259
throw IMP::base::InternalException(oss.str().c_str()); \
260
}
261
262
#endif // log4cxx
263
264
#endif // else on IMP_DXOYGEN
265
266
#define IMP_ERROR_WRITE(expr) \
267
{ \
268
std::ostringstream IMP_STREAM; \
269
expr; \
270
IMP_STREAM << std::endl; \
271
IMP_ERROR(IMP_STREAM.str()); \
272
}
273
274
#define IMP_LOG_WRITE(level, expr) \
275
IMP_IF_LOG(level) { \
276
std::ostringstream IMP_STREAM; \
277
expr; \
278
IMP_STREAM << std::endl; \
279
IMP_LOG(level, IMP_STREAM.str()); \
280
}
281
282
#define IMP_WARN_WRITE(expr) \
283
IMP_IF_LOG(WARNING) { \
284
std::ostringstream IMP_STREAM; \
285
expr; \
286
IMP_STREAM << std::endl; \
287
IMP_WARN(IMP_STREAM.str()); \
288
}
289
290
#if IMP_HAS_LOG
291
292
//! Set the log level to the object's log level.
293
/** All non-trivial Object methods should start with this. It creates a
294
RAII-style object which sets the log level to the local one,
295
if appropriate, until it goes out of scope.
296
*/
297
#define IMP_OBJECT_LOG \
298
IMP::base::SetLogState log_state_guard__(this->get_log_level()); \
299
IMP::base::SetCheckState check_state_guard__(this->get_check_level()); \
300
IMP_CHECK_OBJECT(this); \
301
IMP::base::CreateLogContext log_context__(IMP_CURRENT_FUNCTION, this)
302
303
//! Beginning logging for a non-member function
304
/**
305
*/
306
#define IMP_FUNCTION_LOG \
307
IMP::base::CreateLogContext log_context__(IMP_CURRENT_FUNCTION)
308
309
//! Create a new log context from a streamed name
310
#define IMP_LOG_CONTEXT(name) \
311
IMP::base::CreateLogContext imp_log_context(name, nullptr)
312
313
//! Write a warning once per context object
314
/** Use this macro to, for example, warn on unprocessable fields in a PDB,
315
since they tend to come together. The key is what is tested
316
for uniqueness, the expr is what is output.
317
318
Warnings are only output when the context object is destroyed.
319
*/
320
#define IMP_WARN_ONCE(key, expr, context) \
321
IMP_IF_LOG(WARNING) { \
322
std::ostringstream oss; \
323
oss << expr << std::flush; \
324
context.add_warning(key, oss.str()); \
325
}
326
327
/** Like IMP::base::set_progress_display() but you can use stream operations
328
for the name.*/
329
#define IMP_PROGRESS_DISPLAY(name, steps) \
330
{ \
331
if (IMP::base::get_log_level() >= IMP::base::PROGRESS) { \
332
std::ostringstream oss; \
333
oss << name; \
334
IMP::base::set_progress_display(oss.str(), steps); \
335
} \
336
}
337
338
#else
339
#define IMP_OBJECT_LOG
340
#define IMP_FUNCTION_LOG
341
#define IMP_LOG_CONTEXT(name)
342
#define IMP_WARN_ONCE(key, expr, context)
343
#define IMP_PROGRESS_DISPLAY(name, steps)
344
#endif
345
346
#endif
/* IMPBASE_LOG_MACROS_H */
SetCheckState.h
Checking and error reporting support.
enums.h
Basic types used by IMP.
CreateLogContext.h
Logging and error reporting support.
compiler_macros.h
Various compiler workarounds.
log.h
Logging and error reporting support.