Logging in Apama

Logging is a very useful way to understand the internal workings and state of an application, be it debugging information when an action is called, or error information when something has gone wrong. In Apama you can write effective diagnostic information using log statements in all parts of your code (be it EPL or plug-ins) and have log messages written out to a file with a severity and time-stamp. This blog post discusses how to write logging statements in different components of an application, and how to configure what log messages are written to different log files.

Log levels

There are multiple log levels in Apama indicating the severity of a log message. They are, in ascending order of severity, TRACE , DEBUG, INFO, WARN, ERROR, FATAL, CRIT . Log messages in applications have one of these levels associated with it, and via configuration you can set the minimum level to be logged out (either to a file or stdout).

Basic correlator log configuration

There are two basic configuration options that affect logging in the correlator, the log file and the log level. The correlator log file can be set using the -f file or --logfile file options. The default if this is not supplied is to log to stdout. The log level is set using the -v level or --loglevel level . The default log level is INFO if this option is not supplied. These options affect the root or default correlator log which is usually where all log messages are sent. There are further options to allow per package log level setting and to route log messages from packages to different files. These can be set using the YAML correlator configuration file or using the engine_management tool and are discussed later in this post.

If using Designer, you can set the correlator log level and file in the correlator component configuration dialog in the launch configuration.

We strongly suggest the configured log level in production systems is INFO. If set less verbose, important log messages could be missed. If set more verbose, the amount of logging information will impact performance. You cannot set the level to be FATAL or CRIT , it will be reset back to ERROR .

EPL log statement

The EPL log statement writes messages and time stamp information to the correlator’s log file or stdout.

The expression that you log must be of type string. The value is written only if the current logging level in effect is a priority equal to or higher than the log level specified in the log statement. If you do not specify a level, CRIT , the highest priority level, is used.

For example:

log "Your message here" at INFO;

This EPL statement produces a log message that looks like this:

2017-07-11 09:08:49.200 INFO [3716] - MyMonitor[1] Your message here

You use log levels to filter out log strings. If the log level in effect is lower than the log level in the log statement the correlator does not send the string to the log file. For example, if the log level in effect is ERROR and the log level in the log statement is DEBUG the correlator does not send the string to the log file since the log level in effect is lower than the log level in the log statement.

The correlator will skip evaluating the log string statement if it is side effect free (such as toString() ), but suppose the log statement executes an action or has side effects (some expressions can have side effects as they may throw, such as sequence/dictionary look-ups). In this situation, the correlator executes the log statement so that side effects always take place. However, if the log level in effect is lower than the log level in the log statement the correlator still does not send the string to the log file.

Actions on events or monitors are assumed to have side effects. The com.apama.epl.SideEffectFree annotation can be added to an action definition to mark it as side effect free. Note that with this annotation, actions will only be called from log statements if the log statement would write to the log file. This is clearer and more efficient than checking the log level before executing the log statement. If an action marked with com.apama.epl.SideEffectsFree annotation does in fact have side effects, then changing the log level can change the behavior of your program.

Logging in plug-ins

Plug-ins (both EPL and connectivity) can log messages to the correlator log file. For connectivity plug-ins written in both Java and C++ the Abstract base classes all have a logger member which has methods for logging at the different levels. For C++ EPL plug-ins, the EPLPlugin base class also provides a member called logger.

For Java EPL plug-ins, there is the com.apama.util.Logger class. Each plug-in must create a static instance of the Logger using the static getLogger() method. For example:

package test;
import com.apama.util.Logger;
 
public class Plugin
{
    private static final Logger logger = Logger.getLogger(Plugin.class);
    public static void foo()
    {
        logger.info("A string that's logged at INFO");
    }
}

Filtering log messages by package

You can configure per-package logging in two ways:

  • Statically, in the YAML configuration file when starting the correlator.
  • Dynamically, using the following options of the engine_management tool:

--setApplicationLogFile
--setApplicationLogLevel

YAML CONFIGURATION

The YAML configuration is static and only read in when the correlator starts up. To set log files and/or log levels for EPL root, packages, monitors, or events, specify entries in the eplLogging section of the YAML configuration file. The format of the eplLogging section is:

eplLogging:
  NODE:
    file: FILENAME
    level: LOGLEVEL

Replace NODE with the name of the EPL package, monitor, or event for which you are setting the logging attribute or use .root for the root/default log configuration. Replace FILENAME with the name of the log file for the EPL package. No spaces are allowed in the log file name. Replace LOGLEVEL with a valid log level. For example (for the root/default log):

eplLogging:
  .root:
    file: apama/root.log
    level: ERROR

You do not need to specify both a log file and a log level; you can specify one or the other. If you do not specify a log file or log level for the root/default package, it defaults to the correlator’s log file/log level.

Here is an example to route DEBUG and above log messages for the monitor com.myCompany.Client to a file Client.log :

eplLogging:
  com.myCompany.Client:
    file: Client.log
    level: DEBUG

USING ENGINE_MANAGEMENT

You can dynamically update the logging configuration using the engine_management tool while the correlator is running.

To set the log level for a package, monitor or event, invoke the engine_management tool as follows:

engine_management --setApplicationLogLevel [NODE=]LOGLEVEL

Where NODE is optionally the name of a package, monitor or event, and LOGLEVEL is a valid log level. If you do not specify a node name, the tool sets the log level for the root/default package. You can also query the log level or unset the log level for a specific node (or root/default node) with --getApplicationLogLevel [NODE] or --unsetApplicationLogLevel [NODE] respectively.

To set a log file for a package, monitor or event, invoke the engine_management tool as follows:

engine_management --setApplicationLogFile [NODE=]FILENAME

Where NODE is optionally the name of a package, monitor or event, and FILENAME is a path to the log file. If you do not specify a node name, the tool associates the log file with the default package. This command can be used to rotate log files if setup to run periodicaly (using a scheduled task or cron job for instance) and a new FILENAME is given. You can also query the log file or unset the log file for a specific node (or root/default node) with --getApplicationLogFile [NODE] or --unsetApplicationLogFile [NODE] respectively.

Here is an example to dynamically update the log configuration and route DEBUG and above log messages for the monitor com.myCompany.Client to a file Client.log :

engine_management --setApplicationLogFile com.myCompany.Client=Client.log  
engine_management --setApplicationLogLevel com.myCompany.Client=DEBUG

More Info

We hope this gives an insight into how powerful and customizable logging can be in an Apama application. There is more information and examples around log statements and configuration in the Apama documentation. If you intend to make use of anything above, we suggest you fully read the more in-depth documentation.

Disclaimer:
Utilities and samples shown here are not official parts of the Software AG products. These utilities and samples are not eligible for technical support through Software AG Customer Care. Software AG makes no guarantees pertaining to the functionality, scalability, robustness, or degree of testing of these utilities and samples. Customers are strongly advised to consider these utilities and samples as “working examples” from which they should build and test their own solutions