Logging / Error Handling

The OPALS framework provides means to report program progress to the user. Closely connected to this topic is the way OPALS handles errors and supplies respective error objects and messages. These two issues are treated in the following sections.

The logging framework

OPALS reports program progress using log records, where each record is emitted with a set of attributes:

  • level: the importance of the record, which may assume the following values, listed in decreasing order:
    • error: reports a state where program execution cannot proceed, and is thus aborted
      e.g. mandatory parameter not specified, resource unavailable
    • warning: informs about some weird, poor state which can still be handled
      e.g. poor matrix condition, poor data distribution
    • info: logs some progress that may be interesting in everyday-use
      e.g. data import successfully finished, statistics of input data, summary of results
    • verbose: reports something that may help in understanding program internals
      e.g. intermediate results, branching information
    • debug: maximum verbosity
  • time stamp: the point in time when the record was created, defined by the local system clock
  • module name: the name of the invoked module
  • thread id: the id of the program thread where the record was created
  • message: the actual content of the record

Log records are output on up to three channels which either dump data into files or the screen / commmand line shell: 'log file', 'screen', and 'error file'. Their peculiarities are listed in the table below.

Each channel is associated with a minimum level of importance to dump. A log record is output on a certain channel only, if its importance level is higher or equal to the channel's current threshold. The respective defaults may be altered for 'log file' and 'screen' using the parameters 'fileLogLevel' and 'screenLogLevel', respectively. Specify none to suppress all logging output on either or both of these channels.

File paths are defaulted to reside in the current working directory ('<CWD>'), where only the 'log file'-path may be customized. Data is appended to already existing files.

Depending on the channel, log records are formatted differently: while 'screen' and 'error file' export them in human-readable plain text, 'log file' uses a custom XML schema which is thus apt to be interpreted by machines.

OPALS logging channels
Channel Minimum importance level Path Format Description
  Default Parameter Default Parameter    
log file verbose fileLogLevel <CWD>/opalsLog.xml logFile custom XML see Log file
screen info screenLogLevel plain text This channel is open only for executables and Python-modules. To alter the amount of data to be printed on the screen use -screenLogLevel <level> (executables), or screenLogLevel = <level> (Python).
error file error <CWD>/opalsErrors.log plain text Only unrecoverable program errors are dumped here, the importance threshold cannot be altered. The file resides in the working directory and holds a fixed name.

Log file

Featuring the lowest default minimum log level, this channel by default exports the most information.

This channel exports data in a custom XML-schema. Each module invocation appends one Module-node to the XML-tree, and each log record is represented as one LogEntry-node within one of these nodes. In addition to the LogEntry-nodes, each Module-node contains information about the module and parameters used.

As OPALS log files are XML-based, their content is well-suited for parsing, and their content may e.g. be transformed to XHTML using an XSL stylesheet. In fact, such a stylesheet is embedded in each log file. All major web browsers interpret this stylesheet when loading an OPALS log file, and present its content in a pleasing layout, see the figure below. This locally generated XHTML-page provides two dynamic features to filter the content of the presented logging tables using Javascript:

  • Set the minimum importance level for records to be visible (flyout 'Max. Log Level'). By default, only log records of importance 'info' and higher are presented. However, by default, log files also contain records of lower importance, which may be viewed using this switch.
  • Limit the records to be shown to those emitted from certain program threads only (flyout 'Threads shown'). By default, records from all threads are shown.

Furthermore, on the upper left, the page shows a summary of the log file and provides hyperlinks to quickly jump to a certain logging table (flyout 'k records from n runs').

The parameter tables shown for each module invocation present the module-specific parameters (see Parameter Categories) at the start of the module-run. The common and global parameters may be shown by clicking on the respective links ('+ Commons', '+ Globals').

Presentation of an exemplary OPALS log file in a web browser

Kindly notice:

  • The current versions of all major browsers meet the requirements to correctly display OPALS log files (XHTML, XSL, XPATH, CSS). For problems with Chrome, see Having loaded a log file in Chrome, why is the browser window empty, displaying nothing?.
  • For the dynamic features to work, however, Javascript must be enabled.
  • When loading very large log files, browsers may run into performance problems. As each log record is printed on a separate line, such log files may be better viewed in appropriate text editors.

Error handling

At the point when an OPALS module encounters a state that cannot be handled, program execution is aborted and control is returned to the calling application. In order to inform users about the reason for program abortion, concise messages are supplied. Furthermore, OPALS provides means to identify errors programmatically using error codes and custom error objects derived from opals::Exception. While errors are logged like any other log records, albeit with highest importance, the way error information is returned to the calling application depends on the module implementation:

  • executables return an integer value being an opals::ErrorCode. If an error occurs during program execution, this value deviates from zero.
  • Python provides statements to handle exceptions in the Python shell (try/except/finally). As OPALS exposes its exception types to the Python interpreter, each OPALS exception type may be caught and handled separately.
  • Using C++ bindings / dynamic linkage, the C++ - header of OPALS exceptions may directly be used, which allows for handling objects derived from opals::Exception with the conventional C++ try/catch statements.