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