The Logger Agent, available from the RMA's tools
menu, allows viewing log messages generated by other agents. There are three
main aspects described below. First there is a brief description of the
Logger Agent's functionality. The next section specifies how to customize
JADE and Jadex agents to generate observable log messages and finally it is
shown how to use the Logger Agent to view log messages from observed
agents.
The implementation of the Logger Agent is based on The
Java™ Logging API (
java.util.logging
). Agents make logging calls on
Logger
objects. These objects allocate
LogRecord
objects which are passed to notifier agents via special
Handler
objects on demand. The notifier agents themselves are
responsible for sending an appropriate ACL message to the Logger Agent for
displaying the log message.
Both loggers and handlers may use logging levels to decide if they are interested in a particular log record. The level gives a rough guide to the importance and urgency of a log message. The Level class defines seven standard log levels, ranging from FINEST (the lowest priority) to SEVERE (the highest priority).
Loggers are organized in a hierarchical namespace and child loggers may inherit some logging properties from their parents in the namespace. Loggers are normally named entities, using dot-separated names such as java package names, but for the agent's purpose they are just named like the agents themselves. Therefore the only parent from which the loggers may inherit logging properties is the root logger (named ""). But Loggers may also be configured to ignore handlers higher up the tree.
There is a default logging configuration that ships with the Java Runtime Environment, and it can be overridden by software vendors, system admins, and end users. The default configuration establishes a single handler on the root logger for sending output to the console with log levels INFO and higher.
The Logger class provides a large set of methods for generating log messages. For convenience, there are methods for each logging level, named after the logging level. There are also methods that take an explicit source class name and source method name to quickly locate the source of any given logging message. Methods without it make a "best effort" to determine which class and method has called it and will add this information into the log record. For further details on Java™ Logging APIs see the corresponding documentation.
The generation of log messages with Jadex agents is quite easy.
First you need a reference to the agent's
Logger
object that
can be acquired from an agent's plan helper method. On this object you can
call logging methods with an associated log level.
// get the agent's logger Logger logger= this.getLogger(); // Log simple INFO message logger.log(Level.INFO, "doing stuff");
For customizing purpose you can define logging properties in the agent description file (ADF). You can set the log level for the agent's logger object and specify if it should inherit the logging properties of the root logger.
<properties> <!-- Request all Details --> <property name = "logging.level">Level.ALL</property> <!-- use Handlers of parent (root) logger --> <property name = "logging.useParentHandlers">true</property> </properties>
For JADE agents there are neither helper methods to get the agent's logger object nor customizing possibilities using property files. But anyways, it is quite simple to use the logging functionality from JADE agents. The following example explains how to use logging methods in JADE.
// get logger with agent's name String name = getName(); logger = Logger.getLogger(name); // Request all Details logger.setLevel(Level.ALL); // use Handlers of parent (root) logger logger.setUseParentHandlers(true); // Log simple INFO message logger.log(Level.INFO, "doing stuff");
For examples of agents with logging functionality see code provided in the
src/examples/logging directory
.
The usage of the Logger Agent is similar to the JADE Sniffer Agent. The Logger Agent can be started either from the tools menu of the RMA or from the command line as follows:
java jade.Boot
{logger:jadex.tools.logger.Logger}
The main window contains four distinct areas, separated by adjustable split panels (cf. Figure B.1, “Main frame of Introspector”) . On the left hand side there is the Selection Agents Window showing the available agents on the platform. This is the place where you can choose the agents you want to observe. Observed agent are presented in the Agent List Window below.
When the user decides to log an agent every log message is tracked and displayed in the Log Table on the upper right hand side. The table's columns showing the properties of each log message created by observed agents. You can adjust column widths by resizing the table's header cells or double-clicking on the right end of them. A right click on the table's header provides a pop-up menu that allows making individual columns visible or invisible. Sorting is activated by clicking on a column header cell. The sort order is indicated by a little arrow. Following data of the log messages are presented in the Log Table. Some of them are suppressed by default:
The sequence property will be initialized with a unique value. Note that these sequence values are allocated in increasing order within a virtual machine (VM), so observing different agents on different containers or platforms may produce duplicated values in the table.
The date/time property will be initialized to the current time when the log message is created.
The given log level for the log message.
The source agent's name.
The message text.
The class name that called into the logging framework.
The method name that called into the logging framework.
The thread ID property will be initialized with a unique ID for the current thread.
The main intention of building the Logger Agent was the ability to provide filter techniques for customizing the view of log messages. Underneath the Log Table you can find the Filter Table which is visually synchronized in terms of column widths and visibility. For each column you can define one or more filter expressions. Any expression in a row is combined with the boolean AND operator and the rows are combined with the boolean OR operator. The whole boolean like expression is displayed in the text field above the table. A single filter expressions is a regular-expression which is matched against the data in the corresponding column. Regular-expressions are case-sensitive and there are several constructs to build patterns. A summary of regular-expression constructs can be found in the java.util.regex.Pattern class. For a short summary consult Table B.1, “Summary of Regular Expressions”
Table B.1. Summary of Regular Expressions
Construct | Matches |
---|---|
x
| The character
x
|
[abc]
|
a ,
b , or
c (simple class)
|
[^abc]
| Any character except
a ,
b , or
c (negation)
|
[a-zA-Z]
|
a through
z or
A
through
Z , inclusive (range)
|
.
| Any character (may or may not match line terminators) |
\d
| A digit:
[0-9]
|
\s
| A whitespace character:
[
\t\n\x0B\f\r]
|
\w
| A word character:
[a-zA-Z_0-9]
|
X
?
|
X , once or not at all
|
X
*
|
X , zero or more times
|
X
+
|
X , one or more times
|
XY
|
X followed by
Y
|
X
|
Y
| Either
X or
Y
|
Examples of regular-expressions | |
LogAgent.*
| Any agent with the name starting with
LogAgent.
|
LogAgent\d+.*
| Any agent with the name starting with LogAgent followed by one or more digits and maybe some more arbitrary characters. |
At the very bottom of the main window a Preload List input field is provided. It can be filled with a list of preload descriptions separated by a semicolon. Each description consists of an agent name match string. If there is no @ in the agent name, it assumes the current HAP for it. There are two characters with special significance. The '?' is a wild-card for any character. And the '*' for any substring (one ore more characters).
LogAgent1;LogAgent2
LogAgent*
*
The same functionality is provided via command line arguments for the Logger Agent.
java jade.Boot
{logger:jadex.tools.logger.Logger(LogAgent*)}
A property file called
logger.properties
may
also be used to control the logger properties. It is looked for in the
current directory, and if not found, the agent looks in the parent
directory and continues this until the file is either found or there isn't
a parent directory. Note that any changes to the Preload List in the GUI
won't change the preload property in the file.
Preload=LogAgent1;LogAgent2
The main window has a toolbar with further options to customize the view of log messages. Although the most buttons are rather self explaining here is a short description of every item.
Table B.2. Main Window Toolbar
| Clears the Log Table erasing all the data stored in memory. |
| Writes a semicolon-separated text file with all the log messages appearing in the Log Table. |
| Starts logging the selected agent(s) from the Selection Agents Window. |
| Stops logging the selected agent(s) from the Selection Agents Window. |
| Enables or disables the filter provided by the Filter Table. |
| Shows or hides the Filter Table to maximize the space for the Log Table. |
| Clears all the data appearing in the Filter Table. |
| Pauses or resumes the displaying of new log messages. If displaying is paused new log messages will be tracked and stored in memory. The new data will be added to the Log Table at once if displaying is resumed. |
| If autoscroll is enabled every new log message added to the Log Table will be selected and the table will scroll to the region making the new data visible. |
| Automatically adjusts all column widths to fit the data in the table. |
| This action allows getting the description of a remote Agent Platform via the remote AMS. After that right click on the added platform in the Agent Selection Window and Refresh Agent List to view the agents on the target platform. This makes it possible to log agents even from a remote Platform. |
| Closes the GUI and kills the Logger Agent. |