Rules for printout from algorithms running in production
applications
- All printout must go via the Gaudi message service
- Usage of std::cout or std::cerr is forbidden. This is because in
some environments (in the HLT farm, in Dirac) these standard streams may
have a special meaning. Using the Gaudi message service ensures that all
printout from the application can be controlled in a consistent way in
all environments
- Explicit creation of MsgStream is discouraged
- It is recommended to use the predefined MsgStreams debug(),
info(),
warning() etc., or the corresponding Print(), Warning() etc. methods
- All MsgStreams must be terminated by the keyword endmsg; do
not use endreq, which is obsolete
- Messages like "Welcome (Goodbye)" or "initialized (finalized)
successfully" must not be printed when running an application with default
settings (MsgLevel = 3). The only exception is the application itself (e.g.
"Welcome to Brunel"), since this message is needed by the production tools
when parsing the log files.
- info() printout from algorithms and tools is only allowed during
initialize() and finalize(). Such printout should be limited
to information that could be useful for understanding the behaviour of the
application.
- In the event loop, all printout above debug() is FORBIDDEN,
with the following exceptions
- You MUST print an Error() if execute() returns
StatusCode::FAILURE to stop the processing (see
rules for return status)
- You may print a Warning() is there is a failure affecting the
event.
- Any such printout must use a CONSTANT string (i.e. not
containing data that can change each time). This ensures that a given
message is printed only a limited number of times (10 is the default)
before being switched off. See example below.
- In the event loop, all printout below info() should be protected by an
if clause, to prevent evaluation of the MsgStream even when it is not going
to be printed. See example below
- Take care when using the MsgStream::format() function. This
function is only evaluated once per MsgStream, so must only appear once. If
you need to use it more than once, separate the MsgStreams with endmsg
directives, or use boost::format instead.
Example
Consider the following code:
if ( sc.isFailure() ) {
error() << "Non-positive cov. matrix in smoother for z = " <<
thisNode.z()
<< " thisNodeC = "
<< thisNodeC << endmsg;
return StatusCode::FAILURE;
}
The error message will be printed out every time the error occurs, because
the error() method is used. Even if Error() were used, it would never be
switched off because the message string contains the values of thisNode.z() and
thisNodeC, which change each time.
The code should be changed to something like:
if ( sc.isFailure() ) {
// print error message
Error( "Non-positive cov. matrix in smoother. More details in debug()").ignore();
// test message level before evaluating MsgStream
if( msgLevel( MSG::DEBUG ) ) {
// give a more detailed explanation
debug() << "z = " << thisNode.z() << " thisNodeC = " << thisNodeC
<< endmsg;
}
return StatusCode::FAILURE ;
}
The advantage of this is that, in normal production, one would just see the
error printout 10 times, and then a summary of the number of errors at the end.
The experts who need to see the details of the failure can can run with
OutputLevel = 2 for this particular tool. Note that the functions Warning(),
Error() etc. return a StatusCode. This can be useful as it can
be used as the return StatusCode of the function where the error occurs; most
often though, the StatusCode can be ignored, this should be be done explicitly:
Error("Some error occurred").ignore();