Skip to content
James Edmondson edited this page Jul 7, 2018 · 5 revisions

C++ Guides: GAMS Primer | Creating Algorithms | Creating Platforms | Debugging


Introduction

GAMS provides many debugging features. The most powerful of these is a configurable logging system based on the MADARA Logger. Additionally, GAMS exposes a KnowledgeBase and special status variables and containers that track interactions between algorithms and platforms.


Table of Contents


Logging

Logging is the practice of printing messages to an output sink, usually to help with tracing execution of software. GAMS supports logging internal messages to any combination of terminal windows, system loggers, and files.


Logging Targets

Targets for GAMS logging are set in the same way that they are set for any MADARA Logger.

All MADARA loggers start with an output target of stderr. To add or remove targets, you can use any of the functions on the com.gams.logger.GlobalLogger instance.

import com.gams.loggers.GlobalLogger;

// Clear all logging targets (this would remove terminal output as well)
GlobalLogger.clear ();

// Add a file output of "some_file.txt" to the logger
GlobalLogger.add_file ("some_file.txt");

// Add the terminal back to logging targets
GlobalLogger.add_term ();

Logging Levels

MADARA loggers allow you to set a logging level that generally goes from high priority (0) to low priority (6+). This is an inverted scale of priority that has helpful enums already setup in the LogLevels namespace. The GAMS levels in LogLevels are the following:

LOG_NOTHING   // (-1) log messages start at level 0. Setting to -1 means nothing logs.
LOG_EMERGENCY // (0) use this log level if someone is an emergency
LOG_ALWAYS    // (0) the same log level as EMERGENCY
LOG_ERROR     // (1) print error information. This is the default log level.
LOG_WARNING   // (2) print warning information
LOG_MAJOR     // (3) major event information
LOG_MINOR     // (4) minor event information
LOG_TRACE     // (5) trace information through functions, rarely used
LOG_DETAILED  // (6) detailed information about execution. The most verbose logging level in GAMS

To set a log level, the GlobalLogger provides the setLevel function.

// Sets the logging level to LOG_MAJOR (any major events in GAMS)
GlobalLogger.setLevel (com.gams.loggers.LogLevels.LOG_MAJOR.value());

MADARA Logger

In addition to GAMS logging, MADARA logging is also available. This logger is separate from the GAMS logger and has more fine-grained logging information available, including network transport related logging, knowledge retrieval and container usage. The MADARA logger, by default, is located at com.madara.logger.GlobalLogger.

import com.gams.logger.GlobalLogger;
import com.madara.logger.LogLevels;

// Sets the MADARA logging to detailed
com.madara.logger.GlobalLogger.setLevel(LogLevels.LOG_DETAILED.value());

// Sets the GAMS logging to minor (notice this is different from the MADARA logging level)
GlobalLogger.setLevel(LogLevels.LOG_MINOR.value());

// Save MADARA messages to a file called "madara.txt"
com.madara.logger.GlobalLogger.addFile("madara.txt");

// Save GAMS messages to a file called "gams.txt"
GlobalLogger.setLevel(LogLevels.LOG_MINOR.value());
com.madara.logger.GlobalLogger.addFile("gams.txt");

// Note that because we did not clear either logger, the loggers will print to their files and stderr

Custom Loggers

Developers can create their own MADARA loggers with their own custom log levels. Creating such a custom logger in no way interferes with the GAMS or MADARA loggers, so developers are free to have multiple levels of simultaneous logging for MADARA, GAMS and custom loggers.

To create your own MADARA logger, you simply create an instance of the MADARA Logger class. For instance, if you wanted to create a logger for a custom algorithm and a separate logger for a custom platform, you could do so like this:

import com.gams.logger.GlobalLogger;
import com.madara.logger.LogLevels;
import com.madara.logger.Logger;

// passing false to constructor means to not add stderr to the logger
Logger algorithmLogger = new Logger();
Logger platformLogger = new Logger();

// clear the loggers to start with a fresh set of outputs
algorithmLogger.clear();
platformLogger.clear();

// add only file output to the loggers
algorithmLogger.add_file ("my_algorithm_debug.txt");
platformLogger .add_file ("my_platform_debug.txt");

// logging can be done with the log method, which uses printf syntax and special characters
algorithmLogger.log (5, "Testing algorithm logger.\n");
platformLogger.log (4, "Testing platform logger.\n");