D0 GROUP LEVEL3
ONLINE LESSONS

Gustaaf Brooijmans

Fermilab, MS # 357
Tel: +1 (630) 840 4269 
Last Update:
1/31/2001
by Gustaaf Brooijmans

Episode XII
Error Logging by Level 3 Tools

by Gustaaf Brooijmans

This episode will tell you how you should set up your tool for error logging.  It will tell you what you have to implement in your tool, how you should make errors known to the program, and how you can test this part of your tool's functionality.

The basics first though: the level 3 filtering program will use a combination of two ZOOM packages to handle errorlogging: ErrorLogger and Exceptions.   Why two?  Because only the combination of both gives us all the functionality we are looking for.  So what are these requirements?  Well, it has to

Implementation in Tools

This is the part where "easy to use" comes in!  These are the steps I recommend you follow:
  1. Have an instance of ErrorLog as a private member : ErrorLog  _myToolLog;  (choose your own name)
This implies you have to #include "ErrorLogger/ErrorLog.h".
  1. In the MakeMe() method, tell your ErrorLog instance who you are: _myToolLog.setPackage("myTool's name") (this isn't functional yet - 10-Feb-99 - but will be soon)
  2. In the MakeMe() method, tell Exceptions about your logger: L3ZMxel::setLogger(ZMexErrorLog(_myToolLog) );
You'll have to #include "l3utilities/L3ZMxel.hpp" and #include "ZMtools/ZMexErrorLog.h" to get that one right.
That's it!

No kidding?   But how do I tell the program I have an Error??
 

Sending Error Messages

This part's really easy: to flag an error, you start by creating an error object:

ErrorObj  myerror( ELwarning, " Negative ET !?");

where ELwarning is a severity level (#include "ErrorLogger/ELseverityLevel.h" -follow this link for a list of the available severity levels and their meaning in level 3), and the second argument is  some text which effectively becomes the error identifier (in this case it's Negative ET !?).  So if later in the code you want to record more errors with the same ID, you want to use the same text there.
After that, you can still add more text to the error message (but this doesn't add to the identifier):

myerror << " and this crazy ET value is " << _ET << endmsg;

and you can go on this way until you end the message with endmsg (or by starting a new error).  Once you're finished, you send the error to the logger using the instruction

_myToolLog(myerror);

Ok, but what if my error is so bad that we should stop processing the event (or worse, restart the program)?
 

Throwing Exceptions

When you decide this event shouldn't be processed further (because the data is corrupted for example), or worse, the program should stop (the geometry is corrupted for example), then you should "throw" the error, rather than just logging it.
Create an ErrorObj just like you do for errors that aren't as bad, but with severity ELsevere or ELsevere2 (to stop processing an event) or ELabort or ELfatal (to stop the program), and instead of sending it to the logger throw it:

// Construct ErrorObj
ErrorObj  myerror( ELsevere, " Raw Data Corrupted ! " );
// Throw
ZMthrow( L3ZMxel ( myerror ));

(you'll need to #include Exceptions/ZMthrow.h).
This will stop execution dead in its tracks and delete all the local variables from the stack.  We'll catch this higher up in the program and move to the next event or stop and restart, depending on the severity.
 

What Happens Behind My Back?

The tools that are instantiated first are ErrorHandling tools, of which there may be one or more.  Each of these correspond to a particular destination the error messages are sent to (which can be the Significant Event Server, a file on the node, etc.).  It logs the messages above a certain severity level and keeps statistics on the number of occurrences of each message.  It also keeps the most recent errors in a buffer (not implemented yet), allowing trace-back.
 

How Do I Test This Stuff?

For all of this to work in your component and integrated tests, you want to instantiate an L3ErrHandlingTool (Otherwise your messages will not be going anywhere!).  For an example, look at l3exceptions/src/L3ErrHandleTool_t.cpp (the corresponding trigger list is L3Err.lst), or the trigger lists in the l3ftools component tests (but unfortunately not the integrated test) - I put in comments showing how things are done.  It's also a simple example of how you can test a tool (component test only though).
 

As usual: comments, questions?  -> Feel free to contact me.
 
 
Main Page Next Episode