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