Logging client messages in the z/OSMF log

z/OSMF provides a client side logging framework, which you can use to log your plug-in's client messages in the z/OSMF log. Using the client side logger helps simplify debugging activities because messages for all z/OSMF plug-ins are included in the same log.

For more information about the z/OSMF log, including how to access and view the log, see the topic about working with z/OSMF runtime log files in IBM z/OS Management Facility Configuration Guide.

Setting up client side logging

To implement client side logging, add code to your plug-in that:

  • Specifies the name and location of the Dojo package that contains the client side logger.
  • Imports the client side logger package.
  • Creates an instance of the client side logger, and assigns a unique identifier to the logger. To uniquely identify your plug-in's client side logger, include the name of your company, product, and module in the identifier, and specify "ui" as the lower level qualifier. For example, com.ibm.zosmf.NavigationTree.ui.
  • Defines the methods for the logging levels to be included in the z/OSMF log. The logging levels include: FINE, FINER (trace), FINEST (debug), INFO, WARNING, and SEVERE (fatal).
    To help you identify your plug-in's messages in the log, append a prefix to each message that contains the module name, package name, and method name.
    Figure 1. Sample code for creating a log prefix
    var LOGPREFIX=MODULE+" "+PACKAGE_NAME+" "+methodName+": ";
    LOGGER.entering(LOGPREFIX+"entry stuff");

    For sample log data, see Sample z/OSMF client side log data.

  • Issues JavaScript log statements that match the logging levels you specified. When issued, the client side logger stores the statements in a message queue until the interval, threshold, or trigger is activated, as follows:
    interval 
    By default, the client side logger sends the queued messages to the z/OSMF log every 60 seconds.
    threshold
    By default, the message queue can contain a maximum of 50 JavaScript log statements. When this threshold is reached, the client side logger sends the queued messages to the z/OSMF log.
    trigger
    By default, the push level for the client side logger is INFO. When the severity of a JavaScript log statement equals or exceeds the push level, the client side logger sends the queued messages to the z/OSMF log.
    Note: To prevent denial of service attacks or filling the log with useless data, the client side logger logs only messages that your plug-in issues on behalf of z/OSMF authenticated users.

Sample code for setting up client side logging

Figure 2 provides sample code that you can use as a reference when setting up the client side logger.

Figure 2. Sample code for setting up client side logging
var dojoConfig = {
isDebug:      false,
parseOnLoad:  false,
usePlainJson: true,
async: true,

//Specify the name and location of the client side logger package.
packages: [{name: "izuLogger", location: "/zosmf/IzuUICommon/js"}]
};

//Import the client side logger package.
require(["izuLogger/izuUILogger/log4js17"],
	  
function(log4js){
    //Create an instance of the client side logger.
    var LOGGER = log4js.getLogger("com.mycompany.myproduct.mymodule.ui");
    var MODULE = "MYMODULE";
    var PACKAGE_NAME = "MYPACKAGE.jsp";

    //Define methods for logging messages.
    function init(){
        var methodName="init";
        var LOGPREFIX=MODULE+" "+PACKAGE_NAME+" "+methodName+": ";
        LOGGER.entering(LOGPREFIX+"entry stuff");
        LOGGER.finest(LOGPREFIX+"finest stuff");
        LOGGER.finer(LOGPREFIX+"finer stuff");
        LOGGER.info(LOGPREFIX+"info stuff");
        LOGGER.warning(LOGPREFIX+"warning stuff");
        LOGGER.severe(LOGPREFIX+"severe stuff");
        LOGGER.exiting(LOGPREFIX+"exiting stuff");
    }
});

Methods provided for the client side logger

Table 1 lists the methods you can use when setting up the client side logger, and provides summary descriptions and sample JavaScript code for each method.

Table 1. Methods provided for the client side logger
Method Description Sample Code
log4js.getLogger(logger-ID); Creates an instance of the client side logger for your plug-in, and assigns a unique identifier (logger-ID) to the logger.
var LOGGER = log4js.getLogger(
             "com.ibm.zosmf.NavigationTree.ui");
loggerName.log-level(param); Defines the log levels (log-level) you want the specified logger (loggerName) to include in the z/OSMF log, and takes a single string parameter (param) that specifies the information to log for each message.

For the loggerName.severe(param) method, the client side logger automatically flushes messages to the z/OSMF log.

LOGGER.warning(LOGPREFIX+"Test warning message");
LOGGER.severe(LOGPREFIX+" Exception: " + text);
loggerName.entering(params); Logs the entry point of each method, and takes zero or more comma-separated parameters (params).
LOGGER.entering(LOGPREFIX+"entry stuff");
loggerName.exiting(params); Logs the exit point of each method, and takes zero or more comma-separated parameters (params).
LOGGER.exiting(LOGPREFIX+"exiting stuff");
loggerName.logp(Level.log-level, params) Allows you to specify the parameters (params) to include in the z/OSMF log for the specified log level (log-level). This method takes a variable number of comma-separated parameters, and is an alternative to the loggerName.log-level(param) method.
LOGGER.logp(Level.WARNING, PACKAGE_NAME, MODULE, 
   methodName, msg, " targetid=", targetid); 
LOGGER.logp(Level.SEVERE, PACKAGE_NAME, MODULE, 
   methodName, "Exception received attempting 
   to authenticate user", userid, exception); 
loggerName.isLoggable(Level.log-level) Verifies that the specified log level (log-level) is currently being logged.
if(LOGGER.isLoggable(Level.FINEST)){ 
  LOGGER.finest(LOGPREFIX+ "FTP Host : " 
  + dojo.byId('<%= HADDataAdaptor.FTPHOSTNAME %>').
  value);
}
loggerName.logMessage("msgID", msgvars); Logs the message ID as well as the values that were substituted for each parameter. The values are stored as an array.
var msgvars = ["tkdole", 10, "try again"]; 
LOGGER.logMessage("IZUG400E", msgvars);
loggerName.turnOnTracing(); Enables tracing by setting the log level to FINER.
LOGGER.turnOnTracing();
loggerName.turnOffTracing(); Disables tracing, and sets the log level to its initial level.
LOGGER.turnOffTracing();
loggerName.turnOnPopup(); Appends messages to a popup window. The default log level is FINEST.

You can also append messages to a popup window by setting the setpopup property to true. For more details, see Logging messages to a popup window.

LOGGER.turnOnPopup();
loggerName.turnOffPopup(); Stops appending messages to a popup window (default), and closes the popup window. You can also stop appending messages to a popup window by setting the setpopup property to false. For more details, see Logging messages to a popup window.
LOGGER.turnOffPopup();
loggerName.setLogToConsole(true | false); If set to true, the client side logger appends the messages to the browser console, for example, Firebug. If set to false (default), the messages are not appended to the browser console.
LOGGER.setLogToConsole(true);
LOGGER.setLogToConsole(false);
loggerName.flush(); Sends the queued messages to the z/OSMF log. You can also use the push property to push queued messages to the z/OSMF log. For more details, see Pushing messages to the z/OSMF log.
LOGGER.flush();

Sample z/OSMF client side log data

The message entries in the z/OSMF log have a uniform structure, which is depicted in Figure 3.

Figure 3. Sample z/OSMF client side log data
2009-04-29T22:08:09.609Z|00000031|com.ibm.zoszmf.util.log.servlet.UILoggerServlet|UILoggerServlet::doPost()
FINER: [2009-04-29T22:07:13.938Z] ENTRY MYMODULE MYPACKAGE.jsp init: entry stuff
[tx0000000000002183:zosmfad@localhost (POST) /zosmf/IzuUICommon/UILoggerServlet?preventCache=1240947046138]
2009-04-29T22:08:09.609Z|00000031|com.ibm.zoszmf.util.log.servlet.UILoggerServlet|UILoggerServlet::doPost()
FINER: [2009-04-29T22:07:13.474Z] RETURN MYMODULE MYPACKAGE.jsp init: exiting stuff
[tx0000000000002184:zosmfad@localhost (POST) /zosmf/IzuUICommon/UILoggerServlet?preventCache=1240946722135]
The first line of a log record contains the following data:
  • Date and time the message was added to the log in ISO8601 format, set to UTC timezone. Example: 2009-04-29T22:08:09.609Z.
  • Thread ID as an 8 digit hex number. Example: 00000031.
  • Class name. Example: com.ibm.zoszmf.util.log.servlet.UILoggerServlet.
  • Method name. Example: UILoggerServlet::doPost().
The next line of a log record contains the following data:
  • Logging level. Possible logging levels include FINE, FINER, FINEST, INFO, WARNING, and SEVERE.
  • Date and time the message occurred in ISO8601 format, set to UTC timezone. Example: [2009-04-29T22:07:13.938Z].
  • Indicator of the beginning (ENTRY) or end (RETURN) of a routine if the logging level is FINER.
  • Log prefix if a prefix was specified for the logging level.
  • Message ID and message text. Message IDs that begin with "IZU" are part of the z/OSMF product.

If the log record includes an exception, the exception class and the message text are logged next followed by the traceback information that is embedded in the exception. If the exception has attached causes, each cause is also logged with "+->" indicating the start of an attached cause.

The final line of a log record contains the following data:
  • Transaction ID, which is an internal counter that applies to all actions between a specific set and is clear of a context.
  • User ID of the user who was logged into z/OSMF when the message was issued.
  • Host name of the system where the user logged into z/OSMF.
  • Servlet "verb". Examples include (GET) and (POST).
  • URL of the request and query string.