EDepSimLog.hh
Go to the documentation of this file.
1 #ifndef EDepSim_LogManager_hxx_seen
2 #define EDepSim_LogManager_hxx_seen
3 
4 #include <iostream>
5 #include <iomanip>
6 #include <string>
7 #include <map>
8 
9 /// Provide control over log and error output. The EDepSim::LogManager class
10 /// provides a set of static methods which control the amount of output from
11 /// the logging macros. These macros come in two varieties (logging macros,
12 /// and error reporting macros). The level of output from the logging and
13 /// error macros is controlled separately.
14 ///
15 /// The logging macros print the output to the log file with a simple header
16 /// which allows them to be located using a search tool (like grep). All of
17 /// these macros accept a \ref streamish and can produce multiple lines of
18 /// output. The logging macros are:
19 ///
20 /// - EDepSimLog() -- Print output at the LogLevel output level. This is for
21 /// messages that should be written to the output file during
22 /// production.
23 /// - EDepSimInfo() -- Print output at the InfoLevel output level.
24 /// - EDepSimVerbose() -- Print output at the VerboseLevel output level.
25 ///
26 /// The indentation levels of log messages can be controlled using the
27 /// EDepSim::LogManager::IncreaseIndentation() and
28 /// EDepSim::LogManager::DecreaseIndentation() static methods. These should
29 /// be used in pairs.
30 ///
31 /// The error macros print output to the error file with a header indicating
32 /// the error level (ERROR, SEVERE, WARN, DEBUG, or TRACE), the file and the
33 /// line of code where the message originated. Error macros should be used to
34 /// report any problem found during execution. They are particularly useful
35 /// for debugging. The syntax for the error macros is the same as for the
36 /// logging macros. The error macros are:
37 ///
38 /// - EDepSimError() -- Print output at the ErrorLevel output level. This
39 /// should be reserved for messages printed right before you expect the
40 /// program to crash.
41 /// - EDepSimSevere() -- Print output at the SevereLevel output level. This
42 /// should be reserved for error conditions where event data is going to be
43 /// lost, or the event will contain incorrect information.
44 /// - EDepSimWarn() -- Print output at the WarnLevel output level. This should
45 /// be used when a correctable, but unexpected, problem is found with an
46 /// event.
47 /// - EDepSimDebug() -- Print output at the DebugLevel output level. This
48 /// should be used for general debugging output.
49 /// - EDepSimTrace() -- Print output at the TraceLevel output level. This
50 /// should be used for very verbose debugging output.
51 ///
52 /// In addition to the default logging and error macros, there are macros that
53 /// take a "trace" name. The level of output from each type of trace can be
54 /// controlled separately. The named variety of macro takes two arguments (a
55 /// \ref trace and a \ref streamish). The named macros are EDepSimNamedLog(),
56 /// EDepSimNamedInfo(), EDepSimNamedVerbose(), EDepSimNamedError(),
57 /// EDepSimNamedSevere(), EDepSimNamedWarn(), EDepSimNamedDebug(), and
58 /// EDepSimNamedTrace().
59 ///
60 /// \section defaultLogging Using the Default Logging Macros
61 ///
62 /// The logging (and error) output macros are used like functions, except
63 /// they take arguments that can be output to a stream variable (a so called
64 /// \ref streamish).
65 ///
66 /// \code
67 /// int i = 42;
68 /// double pi = 3.1415;
69 ///
70 /// EDepSimLog("The answer is " << i);
71 /// EDepSimInfo("Multi-line output is" << std::endl << " very useful.");
72 /// EDepSimVerbose("Have a piece of " << pi);
73 /// \endcode
74 ///
75 /// If the logging level is set to EDepSim::LogManager::LogLevel produces:
76 ///
77 /// \code
78 /// % The answer is 42.
79 /// \endcode
80 ///
81 /// But if the logging level is set to EDepSim::LogManager::VerboseLevel, this
82 /// writes:
83 ///
84 /// \code
85 /// % The answer is 42.
86 /// %% Multi-line output is
87 /// very useful.
88 /// %%% Have a piece of 3.1415
89 /// \endcode
90 ///
91 /// The logging level can be set using the "edeplog.config" file (see \ref
92 /// edeplogConfig) to define a log level
93 ///
94 /// \code
95 /// log.default.level = VerboseLevel # also LogLevel or InfoLevel
96 /// \endcode
97 ///
98 /// \section namedLogging Using the Named Logging Macros
99 ///
100 /// The named logging macros are used in the same way as the unnamed macros,
101 /// except that you must provide a string as the first argument. This string
102 /// is then used to define a "trace" which can be turned on explicitly without
103 /// causing output from other logging statements.
104 ///
105 /// \code
106 /// int i = 42;
107 /// double pi = 3.1415;
108 ///
109 /// EDepSimNamedLog("traceName",
110 /// "The answer is " << i
111 /// << ". So we might as well have " << pi);
112 /// EDepSimNamedInfo("traceName",
113 /// "Multi-line output is" << std::endl
114 /// << " very useful.");
115 /// EDepSimNamedInfo("anotherTrace","Won't be printed");
116 /// \endcode
117 ///
118 /// If the "traceName" logging level is set to EDepSim::LogManager::InfoLevel
119 /// or above, this produces:
120 ///
121 /// \code
122 /// # The answer is 42. So we might as well have 3.1415
123 /// # Multi-line output is
124 /// very useful.
125 /// \endcode
126 ///
127 /// The logging level for traceName can be set using the configuration file
128 /// statement.
129 ///
130 /// \code
131 /// log.traceName.level = InfoLevel
132 /// \endcode
133 ///
134 /// \section edeplogConfig The EDepSim::LogManager Configuration File
135 ///
136 /// The configuration of the EDepSim::LogManager object can be handled using
137 /// static methods, or using a configuration file that is read by a call to
138 /// the EDepSim::LogManager::Configure() method. When the
139 /// EDepSim::LogManager::Configure() method is called, it will first try to
140 /// read "edeplog.config" in the local directory. If
141 /// EDepSim::LogManager::Configure() is called with a file name, the named
142 /// configuration file will be read after the edeplog.config file and can
143 /// override any settings.
144 ///
145 /// The EDepSim::LogManager configuration file uses a simple line oriented
146 /// syntax.
147 ///
148 /// - Comments are begun with "#"
149 /// - Configuration statements are case-sensitive
150 /// - Each line has one configuration statement
151 /// - The configuration statement syntax is
152 /// - a field name (defined below)
153 /// - an equal sign
154 /// - a field value
155 ///
156 /// The legal field names are
157 ///
158 /// - log.file -- The name of a log file. This can be either a string
159 /// enclosed in double quotes, STDCOUT, or STDCERR. If the file exists, then
160 /// output will be appended to the end. If the file doesn't exist, it will
161 /// be created.
162 ///
163 /// - error.file -- The name of the error file. This has the same syntax as
164 /// log.file. If an error file isn't provided, then the error output
165 /// will go to the same destination as the logging output.
166 ///
167 /// - log.default.level -- The default logging level. This accepts the name
168 /// of a logging level (QuietLevel, LogLevel, InfoLevel, or VerboseLevel).
169 ///
170 /// - error.default.level -- The default error level. This accepts the
171 /// name of a error level (SilentLevel, ErrorLevel, SevereLevel,
172 /// WarnLevel, DebugLevel, TraceLevel).
173 ///
174 /// - log.[trace].level -- Set the logging level for the named trace. The
175 /// level names are the same as log.default.level.
176 ///
177 /// - error.[trace].level -- Set the error level for the named trace. The
178 /// level names are the same as error.default.level.
179 ///
180 /// An example of the edeplog.config file shows how it might be used. This
181 /// file causes the log messages to be printed in "output.log", and the error
182 /// messages to be printed in "output.err". The default log level is set to
183 /// EDepSim::LogManager::InfoLevel so that messages are written from all
184 /// EDepSimLog(), EDepSimNamedLog(), EDepSimInfo(), and EDepSimNamedInfo()
185 /// macros. The default error level is set to
186 /// EDepSim::LogManager::SevereLevel so messages are written from all
187 /// EDepSimError(), EDepSimNamedError(), EDepSimSevere(), and
188 /// EDepSimNamedSevere() macros. The error level for the "myTrace" trace is
189 /// set to EDepSim::LogManager::DebugLevel, so messages are written for any
190 /// EDepSimNamedWarn() and EDepSimNamedDebug() macro which has a trace
191 /// argument of "myTrace" (e.g. EDepSimNamedWarn("myTrace","some output") will
192 /// write "some output" into the log file).
193 ///
194 /// \code
195 /// # An atypical example edeplog.config
196 /// log.file = "output.log" # Set the name of the output file.
197 /// error.file = "output.err" # Set the name of the error file.
198 ///
199 /// log.default.level = InfoLevel
200 /// error.default.level = SevereLevel
201 ///
202 /// error.myTrace.level = DebugLevel # set myTrace to use TraceLevel.
203 ///
204 /// # End of edeplog.config
205 /// \endcode
206 ///
207 /// Here is an example of a typical edeplog.config file that would be used
208 /// during debuging. This assumes that your routine is using the \ref trace
209 /// MyRoutine (a bad name!), and prints all of the error messages to the
210 /// terminal.
211 ///
212 /// \code
213 /// # A Typical edeplog.config file. Copy this into your directory as you
214 /// # are debugging a program.
215 ///
216 /// # Uncomment the next line to save the log and debugging output to
217 /// # output.log.
218 /// # log.file = "output.log"
219 ///
220 /// # Print all of the possible log messages.
221 /// log.default.level = VerboseLevel
222 ///
223 /// # Only print error messages of WarnLevel or above.
224 /// error.default.level = WarnLevel
225 ///
226 /// # Print all of the debugging messages from my code.
227 /// error.MyRoutine.level = TraceLevel
228 ///
229 /// # End of edeplog.config
230 /// \endcode
231 ///
232 /// \section logLevel Log Levels
233 ///
234 /// The available log output levels are:
235 ///
236 /// - EDepSim::LogManager::QuietLevel -- No log output.
237 ///
238 /// - EDepSim::LogManager::LogLevel -- This is for messages that should be
239 /// printed in the log file. Messages from EDepSimLog(), and
240 /// EDepSimNamedLog() will be printed.
241 ///
242 /// - EDepSim::LogManager::InfoLevel -- This is for messages that will be
243 /// useful in log files, but may be skipped during large production jobs.
244 /// Messages from EDepSimInfo(), and EDepSimNamedInfo() will be printed.
245 ///
246 /// - EDepSim::LogManager::VerboseLevel -- This is for messages that curious
247 /// users can use to track the progress of local jobs, but which do not
248 /// belong in a production log file. Messages from EDepSimVerbose(), and
249 /// EDepSimNamedVerbose() will be printed.
250 ///
251 /// \section debugLevel Error Levels
252 ///
253 /// The available error levels are:
254 ///
255 /// - EDepSim::LogManager::SilentLevel -- No error output. Exception: Message
256 /// from EDepSimError() are not suppressed even when the error output level
257 /// is set to SilentLevel. These messages can be suppressed by defining
258 /// EDEPSIM_ERROR_OUTPUT to false in the source code
259 ///
260 /// - EDepSim::LogManager::ErrorLevel -- This should be reserved for messages
261 /// that are printed just before you expect a program to crash, and which
262 /// should never be supressed. Messages from EDepSimError() and
263 /// EDepSimNamedError() are printed at this level.
264 ///
265 /// - EDepSim::LogManager::SevereLevel -- This is for messages that are
266 /// printed when an event has triggered a problem where the code is going to
267 /// produce an incorrect result, but probably won't crash. Messages from
268 /// EDepSimSevere() and EDepSimNamedSevere() are printed.
269 ///
270 /// - EDepSim::LogManager::WarnLevel -- This is for messages printed when a
271 /// problem has been found, but it is unlikely to cause significant problems
272 /// in the analysis. Messages from EDepSimWarn() and EDepSimNamedWarn() are
273 /// printed.
274 ///
275 /// - EDepSim::LogManager::DebugLevel -- This is for general debugging
276 /// messages. Messages from EDepSimDebug() and EDepSimNamedDebug() are
277 /// printed.
278 ///
279 /// - EDepSim::LogManager::TraceLevel -- This is for really verbose debugging
280 /// messages. Messages from EDepSimTrace() and EDepSimNamedTrace() are
281 /// printed.
282 ///
283 /// EDepSim::LogManager is singleton class that controls the level of output
284 /// from the error and logging statements. All of the user visible functions
285 /// are static.
286 ///
287 /// \section trace Trace Name
288 ///
289 /// A "trace name" is a string that can be used to define a group of log (or
290 /// error) messages that will be printed at the same logging (or error) level.
291 /// These are used with the "Named" variant of the log macros:
292 ///
293 /// \code
294 /// EDepSimNamedLog("traceArgument","some output");
295 /// \endcode
296 ///
297 /// \section streamish Streamish Argument
298 ///
299 /// A "streamish argument" is an argument to a logging macro that can be
300 /// compiled into a stream output statement. For example, a call
301 ///
302 /// \code EDepSimLog("The answer is " << 42); \endcode
303 ///
304 /// has one streamish argument, and will print "A streamish argument" into the
305 /// log file. The EDepSim::LogManager macros will accept any set of <<
306 /// operator arguments that could be printed to std::cout. NOTE: the
307 /// streamish argument doesn't start with a << operator.
308 ///
309 /// \section logRationale Rationale
310 ///
311 /// Writing messages to track the progress of a job, or to help debug software
312 /// has a few specific requirements. In particular, it needs to meet (at
313 /// least) the following desiderata.
314 ///
315 /// -# The amount of output should be controllable at run-time.
316 ///
317 /// -# The generated code should be very efficient and impose as small a CPU
318 /// requirement as possible.
319 ///
320 /// -# When a message is "switched off" at run-time, the text for the message
321 /// should not be formatted and none of the routines required to generate the
322 /// text should be called.
323 ///
324 /// -# It must be possible for the log writing code to be removed at
325 /// compilation time so that it will have no affect on critical sections of
326 /// code.
327 ///
328 /// -# It must be possible to direct log and error output to separate streams.
329 ///
330 /// -# The type safety and formating of the normal C++ stream operators should
331 /// be leveraged.
332 ///
333 /// These desiderata basically the usual log/error output scheme where the
334 /// basic log code looks like this:
335 ///
336 /// \code
337 /// #ifdef INCLUDE_DEBUGGING_CODE
338 /// if (0<outputLevel) {
339 /// myStream << "debugging output " << slowFunction() << std::endl;
340 /// }
341 /// #endif
342 /// \endcode
343 ///
344 /// where outputLevel and myStream are global variables. This meets the first
345 /// requirement since outputLevel is a global variable that can be changed at
346 /// run-time. The second requirement is met since slowFunction is only called
347 /// when outputLevel is greater than zero. The second requirement is met
348 /// since code is only generated when INCLUDE_DEBUGGING_CODE is set.
349 ///
350 /// The final desiderata implies that the ideal source code interface would
351 /// result in code something like:
352 ///
353 /// \code
354 /// logStream << "A log message" << std::endl;
355 /// debugStream << "An informational message" << std::endl;
356 /// infoStream << "Result of a function " << SlowFunction() << std::endl;
357 /// \endcode
358 ///
359 /// Unfortunately, the way C++ processes streams means that this type of
360 /// interface can't mean the disiderata "2.1", and "3". For instance, even if
361 /// the run-time verbosity is set so that infoStream will not generate output,
362 /// the function "SlowFunction()" will be called. It's also not possible for
363 /// this sort of code to be removed during compilation.
364 ///
365 /// While C Macros are generally discouraged in C++, they provide the only
366 /// mechanism that meets the design requirements for logging. This results in
367 /// an interface similar to the one defined by EDepSim::LogManager.
368 ///
369 /// \subsection logRationaleOther Why not use package X?
370 ///
371 /// There are several log writing packages available for C++, so why not use
372 /// one of them? It turns out that several (for an example, google "log4cpp")
373 /// define an unsatisfactory streams based interface. Other packages I'm
374 /// aware of tend to have very rich features and a very large number of lines
375 /// (i.e. log4cplus has 11 KLOC). Many of these packages also bring
376 /// significant build requirements. By comparison, EDepSim::LogManager is
377 /// less than 700 lines of code (1200 with comments).
378 ///
379 namespace EDepSim {class LogManager;}
381 public:
382  ~LogManager();
383 
384  typedef enum {SilentLevel,
390 
391  typedef enum {QuietLevel,
395 
396  /// Cause the logging and error output streams to be initialized.
397  /// Basic configuration for logging occurs automatically, so this need not
398  /// be called. If this is called, then it first trys to read the
399  /// edeplog.config file in the current directory. If Configure is called
400  /// with an argument, then the named file will be read after reading the
401  /// local configuration file. If Configure is called with a named file
402  /// then that file must exist. The \ref edeplogConfig syntax is
403  /// described elsewhere.
404  static void Configure(const char* conf=NULL);
405 
406  /// Set the output stream to be used for error messages.
407  static void SetDebugStream(std::ostream* err);
408 
409  /// Set the default debugging level. The level parameter takes a value
410  /// with type EDepSim::LogManager::ErrorPriority.
411  static void SetDebugLevel(ErrorPriority level) {fErrorPriority = level;}
412 
413  /// Set the debugging level for a particular trace.
414  static void SetDebugLevel(const char* trace, ErrorPriority level);
415 
416  /// Get the current debugging level;
417  static ErrorPriority GetDebugLevel() {return fErrorPriority;}
418 
419  /// Get the current debugging level for a named trace.
420  static ErrorPriority GetDebugLevel(const char* trace);
421 
422  /// Set the output stream to be used for log messages.
423  static void SetLogStream(std::ostream* log);
424 
425  /// Set the default logging level.
426  static void SetLogLevel(LogPriority level) {fLogPriority = level;}
427 
428  /// Set the logging level for a named trace.
429  static void SetLogLevel(const char* trace, LogPriority level);
430 
431  /// Get the current logging level;
432  static LogPriority GetLogLevel() {return fLogPriority;}
433 
434  /// Get the current logging level;
435  static LogPriority GetLogLevel(const char* trace);
436 
437  /// Return the stream associated with the error file.
438  static std::ostream& GetDebugStream();
439 
440  /// Return the stream associated with the log file.
441  static std::ostream& GetLogStream();
442 
443  /// Set the indentation level for a log message.
444  static void SetIndentation(int i);
445 
446  /// Increase the indentation level.
447  static void IncreaseIndentation();
448 
449  /// Decrease the indentation level.
450  static void DecreaseIndentation();
451 
452  /// Reset the indentation to zero.
453  static void ResetIndentation();
454 
455  /// [Internal method] Make an indentation for a log message.
456  static std::string MakeIndent();
457 
458 private:
459  static ErrorPriority fErrorPriority;
460  static LogPriority fLogPriority;
461  static std::ostream* fDebugStream;
462  static std::ostream* fLogStream;
463  static std::map<std::string,ErrorPriority> fErrorTraces;
464  static std::map<std::string,LogPriority> fLogTraces;
465  static int fIndentation;
466 
468 };
469 
470 /// INTERNAL: A macro to handle the output of an error message. This is used
471 /// by the user visible macros.
472 #ifndef _EDEPSIM_OUTPUT_ERROR
473 # define _EDEPSIM_OUTPUT_ERROR(trace,outStream) \
474  do { \
475  std::ios::fmtflags save \
476  = EDepSim::LogManager::GetDebugStream().flags(); \
477  EDepSim::LogManager::GetDebugStream() << trace << __FILE__ \
478  << ":" << __LINE__ << ": " \
479  << outStream \
480  << std::setprecision(6) \
481  << std::setw(0) \
482  << std::setfill(' ') \
483  << std::endl; \
484  EDepSim::LogManager::GetDebugStream().flags(save); \
485  } while (0)
486 #endif
487 
488 /// Set this to false if the error output code should not be included in
489 /// the executable. This can be redefined in user code and depends on the
490 /// optimizers to not emit code a constant contitionals (that's the usual
491 /// behavior for a compiler).
492 #ifndef EDEPSIM_ERROR_OUTPUT
493 # define EDEPSIM_ERROR_OUTPUT true
494 #endif
495 
496 #ifndef EDepSimError
497 /// Print an error message that cannot be suppressed by changing the error
498 /// output level. The use of EDepSimError() can generated a lot of chatter,
499 /// so it should be reserved to cases where you expect the program to crash
500 /// (for example, the next line is a call to abort()), and prefer the
501 /// EDepSimSevere macro. The EDepSimError macro takes one \ref streamish
502 /// providing the error message.
503 # define EDepSimError(outStream) \
504  do { \
505  if (EDEPSIM_ERROR_OUTPUT) { \
506  _EDEPSIM_OUTPUT_ERROR("ERROR: ",outStream); \
507  } \
508  } while (0)
509 #else
510 #warning EDepSimError has been redefined and unexpected behaviour may result.
511 #endif
512 
513 #ifndef EDepSimNamedError
514 /// Print an named error message that appears at the default error output
515 /// level. The use of EDepSimNamedError() should generally be reserved to
516 /// cases where you expect the program to crash, or for which data is going to
517 /// be lost. This macro takes two arguments: The first argument must be a
518 /// \ref trace (a string). The second argument is a \ref streamish providing
519 /// the error message.
520 # define EDepSimNamedError(trace,outStream) \
521  do { \
522  if (EDEPSIM_ERROR_OUTPUT) { \
523  if (EDepSim::LogManager::ErrorLevel \
524  <= EDepSim::LogManager::GetDebugLevel(trace)) \
525  _EDEPSIM_OUTPUT_ERROR("ERROR[" trace "]: ", outStream); \
526  } \
527  } while (0)
528 #else
529 #warning EDepSimNamedError has been redefined and unexpected behaviour \
530  may result.
531 #endif
532 
533 #ifndef EDepSimSevere
534 /// Print an error message that appears at the
535 /// EDepSim::LogManager::SevereLevel of error output. This macro should be
536 /// reserved for error conditions where event data is going to be lost, or
537 /// where the event might contain incorrect information. This macro takes one
538 /// \ref streamish providing the error message.
539 # define EDepSimSevere(outStream) \
540  do { \
541  if (EDEPSIM_ERROR_OUTPUT) { \
542  if (EDepSim::LogManager::SevereLevel \
543  <= EDepSim::LogManager::GetDebugLevel()) \
544  _EDEPSIM_OUTPUT_ERROR("SEVERE: ",outStream); \
545  } \
546  } while (0)
547 #else
548 #warning EDepSimSevere has been redefined and unexpected behaviour may result.
549 #endif
550 
551 #ifndef EDepSimNamedSevere
552 /// Print an error message that appears at the
553 /// EDepSim::LogManager::SevereLevel of error output. This macro should be
554 /// reserved for error conditions where event data is going to be lost, or
555 /// where the event might contain incorrect information. This macro takes two
556 /// arguments: The first argument must be a \ref trace (a string). The second
557 /// argument is a \ref streamish providing the error message.
558 # define EDepSimNamedSevere(trace,outStream) \
559  do { \
560  if (EDEPSIM_ERROR_OUTPUT) { \
561  if (EDepSim::LogManager::SevereLevel \
562  <= EDepSim::LogManager::GetDebugLevel(trace)) \
563  _EDEPSIM_OUTPUT_ERROR("SEVERE[" trace "]: ", outStream); \
564  } \
565  } while (0)
566 #else
567 #warning EDepSimNamedSevere has been redefined and unexpected behaviour \
568  may result.
569 #endif
570 
571 #ifndef EDepSimWarn
572 /// Print an error message that appears at the EDepSim::LogManager::WarnLevel
573 /// of error output. This macro should be used when a correctable, but
574 /// unexpected, problem is found with an event. This macro takes one \ref
575 /// streamish providing the error message.
576 # define EDepSimWarn(outStream) \
577  do { \
578  if (EDEPSIM_ERROR_OUTPUT) { \
579  if (EDepSim::LogManager::WarnLevel \
580  <= EDepSim::LogManager::GetDebugLevel()) \
581  _EDEPSIM_OUTPUT_ERROR("WARNING: ",outStream); \
582  } \
583  } while (0)
584 #else
585 #warning EDepSimWarn has been redefined and unexpected behaviour may result.
586 #endif
587 
588 #ifndef EDepSimNamedWarn
589 /// Print an error message that appears at the EDepSim::LogManager::WarnLevel
590 /// of error output. This macro should be used when a correctable, but
591 /// unexpected, problem is found with an event. This macro takes two
592 /// arguments: The first argument must be a \ref trace (a string). The second
593 /// argument is a \ref streamish providing the error message.
594 # define EDepSimNamedWarn(trace,outStream) \
595  do { \
596  if (EDEPSIM_ERROR_OUTPUT) { \
597  if (EDepSim::LogManager::WarnLevel \
598  <= EDepSim::LogManager::GetDebugLevel(trace)) \
599  _EDEPSIM_OUTPUT_ERROR("WARNING[" trace "]: ", outStream); \
600  } \
601  } while (0)
602 #else
603 #warning EDepSimNamedWarn has been redefined and unexpected behaviour may \
604  result.
605 #endif
606 
607 #ifndef EDepSimDebug
608 /// Print an debugging message that appears at the
609 /// EDepSim::LogManager::DebugLevel of error output. This macro should be
610 /// used to print output needed during the debugging. The EDepSimTrace()
611 /// macro should be used during debugging to provide traces of the code
612 /// execution. This macro takes one \ref streamish providing the error
613 /// message.
614 #define EDepSimDebug(outStream) \
615  do { \
616  if (EDEPSIM_ERROR_OUTPUT) { \
617  if (EDepSim::LogManager::DebugLevel \
618  <= EDepSim::LogManager::GetDebugLevel()) \
619  _EDEPSIM_OUTPUT_ERROR("DEBUG: ",outStream); \
620  } \
621  } while (0)
622 #else
623 #warning EDepSimDebug has been redefined and unexpected behaviour may result.
624 #endif
625 
626 #ifndef EDepSimNamedDebug
627 /// Print an debugging message that appears at the
628 /// EDepSim::LogManager::DebugLevel of error output. This macro should be
629 /// used to print output needed during the debugging. The EDepSimTrace()
630 /// macro should be used during debugging to provide traces of the code
631 /// execution. This macro takes two arguments: The first argument must be a
632 /// \ref trace (a string). The second argument is a \ref streamish providing
633 /// the error message.
634 #define EDepSimNamedDebug(trace,outStream) \
635  do { \
636  if (EDEPSIM_ERROR_OUTPUT) { \
637  if (EDepSim::LogManager::DebugLevel \
638  <= EDepSim::LogManager::GetDebugLevel(trace)) \
639  _EDEPSIM_OUTPUT_ERROR("DEBUG[" trace "]: ", outStream); \
640  } \
641  } while (0)
642 #else
643 #warning EDepSimNamedDebug has been redefined and unexpected behaviour \
644  may result.
645 #endif
646 
647 #ifndef EDepSimTrace
648 /// Print an debugging message that appears at the
649 /// EDepSim::LogManager::TraceLevel of error output. This macro should be
650 /// used to print short messages that trace the execution of code being
651 /// debugged. This macro takes one \ref streamish providing the error
652 /// message.
653 # define EDepSimTrace(outStream) \
654  do { \
655  if (EDEPSIM_ERROR_OUTPUT) { \
656  if (EDepSim::LogManager::TraceLevel \
657  <= EDepSim::LogManager::GetDebugLevel()) \
658  _EDEPSIM_OUTPUT_ERROR("TRACE:",outStream); \
659  } \
660  } while (0)
661 #else
662 #warning EDepSimTrace has been redefined and unexpected behaviour may result.
663 #endif
664 
665 #ifndef EDepSimNamedTrace
666 /// Print an debugging message that appears at the
667 /// EDepSim::LogManager::TraceLevel of error output. This macro should be
668 /// used to print short messages that trace the execution of code being
669 /// debugged. This macro takes two arguments: The first argument must be a
670 /// \ref trace (a string). The second argument is a \ref streamish providing
671 /// the error message.
672 #define EDepSimNamedTrace(trace,outStream) \
673  do { \
674  if (EDEPSIM_ERROR_OUTPUT) { \
675  if (EDepSim::LogManager::TraceLevel \
676  <= EDepSim::LogManager::GetDebugLevel(trace)) \
677  _EDEPSIM_OUTPUT_ERROR("TRACE[" trace "]: ", outStream); \
678  } \
679  } while (0)
680 #else
681 #warning EDepSimNamedTrace has been redefined and unexpected behaviour \
682  may result.
683 #endif
684 
685 /// INTERNAL: A macro to handle the output of a log message. This is used
686 /// by the user visible macros.
687 #ifndef _EDEPSIM_OUTPUT_LOG
688 # define _EDEPSIM_OUTPUT_LOG(trace,outStream) \
689  do { \
690  std::ios::fmtflags save \
691  = EDepSim::LogManager::GetLogStream().flags(); \
692  EDepSim::LogManager::GetLogStream() \
693  << trace \
694  << EDepSim::LogManager::MakeIndent() \
695  << outStream \
696  << std::setprecision(6) \
697  << std::setw(0) \
698  << std::setfill(' ') \
699  << std::endl; \
700  EDepSim::LogManager::GetLogStream().flags(save); \
701  } while (0)
702 #endif
703 
704 /// Set this to false if the logging output code should not be included in
705 /// the executable. This can be redefined in user code and depends on the
706 /// optimizers to not emit code a constant contitionals (that's the usual
707 /// behavior for a compiler).
708 #ifndef EDEPSIM_LOG_OUTPUT
709 # define EDEPSIM_LOG_OUTPUT true
710 #endif
711 
712 #ifndef EDepSim_Log
713 /// Print a message to the log that appears at the
714 /// EDepSim::LogManager::LogLevel of output. This should be reserved for log
715 /// messages that should appear during production. This macro takes one \ref
716 /// streamish providing the log message.
717 #define EDepSimLog(outStream) \
718  do { \
719  if (EDEPSIM_LOG_OUTPUT) { \
720  if (EDepSim::LogManager::LogLevel \
721  <= EDepSim::LogManager::GetLogLevel()) \
722  _EDEPSIM_OUTPUT_LOG("% ",outStream); \
723  } \
724  } while (0)
725 #else
726 #warning EDepSim_Log has been redefined and unexpected logging \
727  behaviour may result.
728 #endif
729 
730 #ifndef EDepSimNamedLog
731 /// Print a message to the log that appears at the
732 /// EDepSim::LogManager::LogLevel of output. This macro takes two arguments:
733 /// The first argument must be a \ref trace (a string). The second argument
734 /// is a \ref streamish providing the log message.
735 #define EDepSimNamedLog(trace,outStream) \
736  do { \
737  if (EDEPSIM_LOG_OUTPUT) { \
738  if (EDepSim::LogManager::LogLevel \
739  <= EDepSim::LogManager::GetLogLevel(trace)) \
740  _EDEPSIM_OUTPUT_LOG("% [" trace "] ",outStream); \
741  } \
742  } while (0)
743 #else
744 #warning EDepSimNamedLog has been redefined and unexpected logging \
745  behaviour may result.
746 #endif
747 
748 #ifndef EDepSimInfo
749 /// Print a message to the log that appears at the
750 /// EDepSim::LogManager::InfoLevel of output. This macro takes one \ref
751 /// streamish providing the log message.
752 # define EDepSimInfo(outStream) \
753  do { \
754  if (EDEPSIM_LOG_OUTPUT) { \
755  if (EDepSim::LogManager::InfoLevel \
756  <= EDepSim::LogManager::GetLogLevel()) \
757  _EDEPSIM_OUTPUT_LOG("%% ",outStream); \
758  } \
759  } while (0)
760 #else
761 #warning EDepSimInfo has been redefined and unexpected logging \
762  behaviour may result.
763 #endif
764 
765 #ifndef EDepSimNamedInfo
766 /// Print a message to the log that appears at the
767 /// EDepSim::LogManager::InfoLevel of output. This macro takes two arguments:
768 /// The first argument must a \ref trace (a string). The second argument is a
769 /// \ref streamish providing the log message.
770 # define EDepSimNamedInfo(trace,outStream) \
771  do { \
772  if (EDEPSIM_LOG_OUTPUT) { \
773  if (EDepSim::LogManager::InfoLevel \
774  <= EDepSim::LogManager::GetLogLevel(trace)) \
775  _EDEPSIM_OUTPUT_LOG("%% [" trace "] ",outStream); \
776  } \
777  } while (0)
778 #else
779 #warning EDepSimNamedInfo has been redefined and unexpected logging \
780  behaviour may result.
781 #endif
782 
783 #ifndef EDepSimVerbose
784 /// Print a message to the log that appears at the
785 /// EDepSim::LogManager::VerboseLevel of output. This macro takes one \ref
786 /// streamish providing the log message.
787 # define EDepSimVerbose(outStream) \
788  do { \
789  if (EDEPSIM_LOG_OUTPUT) { \
790  if (EDepSim::LogManager::VerboseLevel \
791  <= EDepSim::LogManager::GetLogLevel()) \
792  _EDEPSIM_OUTPUT_LOG("%%% ",outStream); \
793  } \
794  } while (0)
795 #else
796 #warning EDepSimVerbose has been redefined and unexpected logging \
797  behaviour may result.
798 #endif
799 
800 #ifndef EDepSimNamedVerbose
801 /// Print a message to the log that appears at the
802 /// EDepSim::LogManager::VerboseLevel of output. This macro takes two
803 /// arguments: The first argument must be a \ref trace (a string). The second
804 /// argument is a \ref streamish providing the log message.
805 # define EDepSimNamedVerbose(trace,outStream) \
806  do { \
807  if (EDEPSIM_LOG_OUTPUT) { \
808  if (EDepSim::LogManager::VerboseLevel \
809  <= EDepSim::LogManager::GetLogLevel(trace)) \
810  _EDEPSIM_OUTPUT_LOG("%%% [" trace "] ",outStream); \
811  } \
812  } while (0)
813 #else
814 #warning EDepSimNamedVerbose has been redefined and unexpected logging \
815  behaviour may result.
816 #endif
817 
818 #endif
819 
820 // Local Variables:
821 // mode:c++
822 // c-basic-offset:4
823 // End:
static void SetIndentation(int i)
Set the indentation level for a log message.
static ErrorPriority GetDebugLevel()
Get the current debugging level;.
Definition: EDepSimLog.hh:417
static std::ostream & GetLogStream()
Return the stream associated with the log file.
static void SetLogLevel(LogPriority level)
Set the default logging level.
Definition: EDepSimLog.hh:426
static ErrorPriority fErrorPriority
Definition: EDepSimLog.hh:459
static std::map< std::string, ErrorPriority > fErrorTraces
Definition: EDepSimLog.hh:463
static std::string MakeIndent()
[Internal method] Make an indentation for a log message.
std::string string
Definition: nybbler.cc:12
Definition: conf.py:1
static std::map< std::string, LogPriority > fLogTraces
Definition: EDepSimLog.hh:464
static LogPriority fLogPriority
Definition: EDepSimLog.hh:460
static void ResetIndentation()
Reset the indentation to zero.
static std::ostream * fLogStream
Definition: EDepSimLog.hh:462
M::value_type trace(const M &m)
Construct a module from components.
Definition: TG4HitSegment.h:10
static void SetLogStream(std::ostream *log)
Set the output stream to be used for log messages.
static void DecreaseIndentation()
Decrease the indentation level.
void err(const char *fmt,...)
Definition: message.cpp:226
static void SetDebugLevel(ErrorPriority level)
Definition: EDepSimLog.hh:411
static void IncreaseIndentation()
Increase the indentation level.
static std::ostream & GetDebugStream()
Return the stream associated with the error file.
static void SetDebugStream(std::ostream *err)
Set the output stream to be used for error messages.
static LogPriority GetLogLevel()
Get the current logging level;.
Definition: EDepSimLog.hh:432
static int fIndentation
Definition: EDepSimLog.hh:465
static void Configure(const char *conf=NULL)
static std::ostream * fDebugStream
Definition: EDepSimLog.hh:461