home
about
news
download
doc
source
systems
tests
bugs
contact
IMP Reference Guide
develop.63b38c487d,2024/12/26
The Integrative Modeling Platform
IMP Manual
Reference Guide
Tutorial Index
Modules
Classes
Examples
include
IMP
version 20241226.develop.63b38c487d
log_macros.h
Go to the documentation of this file.
1
/**
2
* \file IMP/log_macros.h
3
* \brief Logging and error reporting support.
4
*
5
* Copyright 2007-2022 IMP Inventors. All rights reserved.
6
*
7
*/
8
9
#ifndef IMPKERNEL_LOG_MACROS_H
10
#define IMPKERNEL_LOG_MACROS_H
11
12
#include <IMP/kernel_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_KERNEL_HAS_LOG4CXX
22
#include <log4cxx/logger.h>
23
#endif
24
25
#if !defined(IMP_HAS_LOG)
26
#error "IMP_HAS_LOG is not defined, compilation is broken"
27
#endif
28
29
#if !defined(IMP_SILENT)
30
#error "IMP_SILENT is not defined, compilation is broken"
31
#endif
32
33
#if defined(IMP_DOXYGEN)
34
//! Execute the code block if a certain level of logging is on
35
/**
36
The next code block (delimited by { }) is executed if
37
get_log_level() >= level.
38
39
\code
40
IMP_IF_LOG(VERBOSE) {
41
Floats testp(input.begin(), input.end());
42
std::sort(testp.begin(), testp.end());
43
IMP_LOG_VERBOSE( "Sorted order is ");
44
IMP_LOG_WRITE(VERBOSE, std::copy(testp.begin(), testp.end(),
45
std::ostream_iterator<double>(IMP_STREAM, " ")));
46
}
47
\endcode
48
*/
49
#define IMP_IF_LOG(level)
50
51
//! Write a warning to a log.
52
/** \param[in] expr An expression to be output to the log. It is prefixed
53
by "WARNING"
54
*/
55
#define IMP_WARN(expr)
56
57
//! Write a warning to standard error.
58
/** \param[in] expr An expression to be output to std::cerr. It is prefixed
59
by "ERROR"
60
*/
61
#define IMP_ERROR(expr)
62
63
/** \param[in] expr A stream expression to be sent to the output stream if the
64
log level is at least TERSE.
65
66
Usage:
67
\code
68
IMP_LOG_VERBOSE( "Hi there, I'm very talkative. My favorite numbers are "
69
<< 1 << " " << 2 << " " << 3);
70
\endcode
71
*/
72
#define IMP_LOG_TERSE(expr)
73
74
/** \param[in] expr A stream expression to be sent to the output stream if the
75
log level is at least VERBOSE.
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_VERBOSE(expr)
84
85
/** \param[in] expr A stream expression to be sent to the output stream if the
86
log level is at least PROGRESS.
87
88
Usage:
89
\code
90
IMP_LOG_PROGRESS( "Hi there, I'm very talkative. My favorite numbers are "
91
<< 1 << " " << 2 << " " << 3);
92
\endcode
93
*/
94
#define IMP_LOG_PROGRESS(expr)
95
96
/** Mark a variable as one that is only used in logging. This disables
97
unused variable warnings on it in fast mode.
98
*/
99
#define IMP_LOG_VARIABLE(variable)
100
101
#else // IMP_DOXYGEN
102
103
#define IMP_LOG(level, expr) \
104
{ \
105
switch (level) { \
106
case IMP::SILENT: \
107
break; \
108
case IMP::PROGRESS: \
109
IMP_LOG_PROGRESS(expr); \
110
break; \
111
case IMP::TERSE: \
112
IMP_LOG_TERSE(expr); \
113
break; \
114
case IMP::WARNING: \
115
IMP_WARN(expr); \
116
break; \
117
case IMP::VERBOSE: \
118
IMP_LOG_VERBOSE(expr); \
119
break; \
120
case IMP::MEMORY: \
121
IMP_LOG_MEMORY(expr); \
122
break; \
123
case IMP::DEFAULT: \
124
case IMP::ALL_LOG: \
125
default: \
126
IMP_ERROR( \
127
"Unknown log level " << boost::lexical_cast<std::string>(level)); \
128
} \
129
}
130
131
#if IMP_HAS_LOG < IMP_PROGRESS
132
#define IMP_IF_LOG(level) if (false)
133
#define IMP_LOG_PROGRESS(expr)
134
#define IMP_WARN(expr) \
135
if (false) std::cout << expr;
136
#define IMP_LOG_VARIABLE(variable) IMP_UNUSED(variable)
137
#else
138
#define IMP_LOG_VARIABLE(variable)
139
#endif
140
141
#if IMP_HAS_LOG < IMP_TERSE
142
#define IMP_LOG_TERSE(expr)
143
#endif
144
145
#if IMP_HAS_LOG < IMP_VERBOSE
146
#define IMP_LOG_VERBOSE(expr)
147
#define IMP_LOG_MEMORY(expr)
148
#endif
149
150
#if IMP_KERNEL_HAS_LOG4CXX
151
152
// figure out later
153
154
#if IMP_HAS_LOG >= IMP_PROGRESS
155
#define IMP_IF_LOG(level) if (true)
156
#define IMP_LOG_PROGRESS(expr) \
157
{ \
158
using IMP::internal::log::operator<<; \
159
LOG4CXX_INFO(IMP::get_logger(), expr); \
160
}
161
#define IMP_WARN(expr) \
162
{ \
163
using IMP::internal::log::operator<<; \
164
LOG4CXX_WARN(IMP::get_logger(), expr); \
165
}
166
#endif
167
168
#if IMP_HAS_LOG >= IMP_TERSE
169
#define IMP_LOG_TERSE(expr) \
170
{ \
171
using IMP::internal::log::operator<<; \
172
LOG4CXX_INFO(IMP::get_logger(), expr); \
173
}
174
#endif
175
176
#if IMP_HAS_LOG >= IMP_VERBOSE
177
#define IMP_LOG_VERBOSE(expr) \
178
{ \
179
using IMP::internal::log::operator<<; \
180
LOG4CXX_DEBUG(IMP::get_logger(), expr); \
181
}
182
183
#define IMP_LOG_MEMORY(expr) \
184
{ \
185
using IMP::internal::log::operator<<; \
186
LOG4CXX_TRACE(IMP::get_logger(), expr); \
187
}
188
#endif
189
190
#define IMP_ERROR(expr) \
191
{ \
192
using IMP::internal::log::operator<<; \
193
LOG4CXX_ERROR(IMP::get_logger(), expr << std::endl); \
194
}
195
196
#else // log4cxx
197
198
#if IMP_HAS_LOG > IMP_SILENT
199
#define IMP_IF_LOG(level) \
200
if (level <= ::IMP::get_log_level())
201
#define IMP_LOG_PROGRESS(expr) \
202
if (IMP::get_log_level() >= IMP::PROGRESS) { \
203
std::ostringstream oss; \
204
oss << expr; \
205
IMP::add_to_log(oss.str()); \
206
}
207
208
#define IMP_WARN(expr) \
209
if (IMP::get_log_level() >= IMP::WARNING) { \
210
std::ostringstream oss; \
211
oss << "WARNING " << expr << std::flush; \
212
IMP::add_to_log(oss.str()); \
213
};
214
#endif
215
216
#if IMP_HAS_LOG >= IMP_TERSE
217
#define IMP_LOG_TERSE(expr) \
218
if (IMP::get_log_level() >= IMP::TERSE) { \
219
std::ostringstream oss; \
220
oss << expr; \
221
IMP::add_to_log(oss.str()); \
222
}
223
224
#endif
225
226
#if IMP_HAS_LOG >= IMP_VERBOSE
227
#define IMP_LOG_VERBOSE(expr) \
228
if (IMP::get_log_level() >= IMP::VERBOSE) { \
229
std::ostringstream oss; \
230
oss << expr; \
231
IMP::add_to_log(oss.str()); \
232
}
233
#define IMP_LOG_MEMORY(expr) \
234
if (IMP::get_log_level() >= IMP::MEMORY) { \
235
std::ostringstream oss; \
236
oss << expr; \
237
IMP::add_to_log(oss.str()); \
238
}
239
#endif
240
241
#define IMP_ERROR(expr) \
242
{ \
243
std::cerr << "ERROR: " << expr << std::endl; \
244
std::ostringstream oss; \
245
oss << expr; \
246
throw IMP::InternalException(oss.str().c_str()); \
247
}
248
249
#endif // log4cxx
250
251
#endif // else on IMP_DXOYGEN
252
253
#define IMP_ERROR_WRITE(expr) \
254
{ \
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::SetLogState log_state_guard__(this->get_log_level()); \
286
IMP::SetCheckState check_state_guard__(this->get_check_level()); \
287
IMP_CHECK_OBJECT(this); \
288
IMP::CreateLogContext log_context__(IMP_CURRENT_FUNCTION, this)
289
290
//! Beginning logging for a non-member function
291
/**
292
*/
293
#define IMP_FUNCTION_LOG \
294
IMP::CreateLogContext log_context__(IMP_CURRENT_FUNCTION)
295
296
//! Create a new log context from a streamed name
297
#define IMP_LOG_CONTEXT(name) \
298
IMP::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) \
308
IMP_IF_LOG(WARNING) { \
309
std::ostringstream oss; \
310
oss << expr << std::flush; \
311
context.add_warning(key, oss.str()); \
312
}
313
314
/** Like IMP::set_progress_display() but you can use stream operations
315
for the name.*/
316
#define IMP_PROGRESS_DISPLAY(name, steps) \
317
{ \
318
if (IMP::get_log_level() >= IMP::PROGRESS) { \
319
std::ostringstream oss; \
320
oss << name; \
321
IMP::set_progress_display(oss.str(), steps); \
322
} \
323
}
324
325
#else
326
#define IMP_OBJECT_LOG
327
#define IMP_FUNCTION_LOG
328
#define IMP_LOG_CONTEXT(name)
329
#define IMP_WARN_ONCE(key, expr, context)
330
#define IMP_PROGRESS_DISPLAY(name, steps)
331
#endif
332
333
#endif
/* IMPKERNEL_LOG_MACROS_H */
SetCheckState.h
Checking and error reporting support.
enums.h
Basic enumeration types used by IMP.
CreateLogContext.h
Logging and error reporting support.
compiler_macros.h
Various compiler workarounds.
log.h
Logging and error reporting support.