ACDK Logging framework


The ACDK packages follows in may aspects the Java 1.4 java.util.logging package.

Content of this chapter:

   Using Logging in Code
     Named Logger
     Named Parameter
     Quick and dirty via command line
     Configuration via properties file
     Configuration in Source file
     API documentation


The classes for the ACDK Logging are organized in the namespace  acdk::util::logging.

 Using Logging in Code

For minimal overhead and ease to use a few macros are provided to insert logging in our code:

#define ACDK_LOG(level, a1): Use the standard root logger to trace the

void foo()
  ACDK_LOG(Info, "Information about foo");

 Named Logger

By default the ACDK_LOG(...) uses the Root Logger.
Named Logger can be configured in the configuration file (see above in the configuration sample the logger named 'acdk.logger.test').

In the source code you can use the ACDK_NLOG macros:

// retrieve the logger
RLogger log = ::acdk::util::logging::LogManager::getLogger("acdk.logger.test");

// Log 'Bla'
log->log(::acdk::util::logging::Fatal, "Bla", __FILE__, __LINE__);

// Same as above using the LOGNx macro
ACDK_NLOG("acdk.logger.test", Fatal, "Blub");

 Named Parameter

Log message can have named parameters:

// Root log with 2 parameters
ACDK_LOGP(Error, "A Message with 2 parameters", 
                  NamedArg("The Name", (const char*)"Kommer") << 
                  NamedArg("Year", 1966));

RInteger count = new Integer(42);      
// named log with 1 parameter
// RObject's has to be casted to Object* via '&'
ACDK_NLOGP("acdk.logger.test", Error, "A Message with 1 parameters", 
                                      NamedArg("Count", &count));


 Quick and dirty via command line

All acdk programs understand some basic command line options regarding logging configurations.

Optionally a a logging category with -logcat can be passed.
The following -loglevel and -logto options will be used for this category.

The option -loglevel with a following number or log level identifier ajust the lower filter log level.
For example -loglevel Info filters all log entries lower Info (like Trace or Debug) away and only log entries with equal or higher level (like Info, Warn, Error) will be written to a consumer.

Also you need a consumer, which configure where to log the log entries.

At the command line this can be configured with the -logto option.
  • -logto out: Write log entries on System::out in a simple format.
  • -logto err: Write log entries on System::err in a simple format.
  • -logto dbg: Write log entries to the debug out (which is a call to OutputDebugStringA() on Win32 platforms and printf() on others) and in a format, which enables double click in the debuggers windows to jump to corresponding line in the editor.
  • -logto other: all other identifier will be interpreted as file name, and the log entries will be written into this file with the standard log format.

Here some samples:
-loglevel Info -logto out
will set the root logger (all categories) to the log level Info and add a consumer to out.

-logcat acdk.net -loglevel Debug -logto network.log
creates a logger for the category acdk.net set log level to Debug and write the logs into a a file network.

-logcat acdk.net -loglevel Info -logto network.log -logcat acdk.net \
	-loglevel Warn -logto out -logcat acdk.lang.sys -loglevel Debug -logto out
writes Info (and above) for the category acdk.net to the log file network.log, writes Warn (and above) for the category acdk.net to System::out and writes Debug (and above) for the category acdk.lang.sys to System::out.

 Configuration via properties file

More detailed configuration, using different logging formats and consumers can be configured in a configuration file or directly in the source code.

In the the normal ACDK Configuration Properties the Logger of a process can be configured.

# Which message should pass through?
# 'All' All message will be passed
acdk.util.logging.threshold = All

# define a consumer named coutlog of the type acdk.util.logging.ConsoleConsumer
acdk.util.logging.consumer.coutlog = acdk.util.logging.ConsoleConsumer

# define a consumer named stdlogfile of the type acdk.util.logging.FileConsumer
acdk.util.logging.consumer.stdlogfile = acdk.util.logging.FileConsumer

# configure the Formatter of the coutlog consumer
acdk.util.logging.consumer_cfg.coutlog.formatter = acdk.util.logging.SimpleFormatter

# configure the filename stdlogfile Consumer
acdk.util.logging.consumer_cfg.stdlogfile.filename = acdk_util_logging_Test.log

# Configure the Root Logger
# pass all LogRecords Level >= 10
acdk.util.logging.logger.root = 10

# Set consumer 1 to coutlog
acdk.util.logging.logger_cfg.root.consumer1 = coutlog

# Set consumer 2 to stdlogfile
acdk.util.logging.logger_cfg.root.consumer2 = stdlogfile

# Set up a logger named 'acdk.logger.test'
# pass all LogRecords Level >= 10
acdk.util.logging.logger.acdk.logger.test = 10

# Set coutlog as consumer to this logger
acdk.util.logging.logger_cfg.acdk.logger.test.consumer1 = coutlog

 Configuration in Source file

At the startup of the program you can configure the logging also directly in the source file:

  // create  a logger listening all named logging entries starting with "acdkx.rdmi"
 ::acdk::util::logging::RLogger log = ::acdk::util::logging::LogManager::getCreateLogger("acdkx.rdmi");
 // this logs should be written to console with a simplified format
  log->addConsumer(new ::acdk::util::logging::ConsoleConsumer(new ::acdk::util::logging::SimpleFormatter()));
 // set global treshold to debugging
  ::acdk::util::logging::LogManager::MinLevel = ::acdk::util::logging::LogManager::Threshold 
    = ::acdk::util::logging::Debug;

Alternativelly in CfgScript:

using acdk.util.logging;
RLogger log = LogManager::getCreateLogger("acdkx.rdmi");
log->addConsumer(new ConsoleConsumer(new SimpleFormatter()));
LogManager::MinLevel = Debug;
LogManager::Threshold  = Debug;

 API documentation

Please refer to  Logging classes and macros for an overview.