Skip to content
Leanid Astrakou edited this page Jan 17, 2020 · 11 revisions

zlux-shared provides a logging utility for use by both dataservices and web content for a Zowe App.

  1. Logging Objects

  2. Logger IDs

  3. Accessing Logger Objects

    1. Logger
      1. App Server
      2. Web
    2. Component Logger
      1. App Server
      2. Web
  4. Using Logger Objects

    1. Logger Message Substitution (using IDs)
    2. Logger Messages Storage
  5. Logger API

  6. Component Logger API

  7. Log Levels

  8. Logging Verbosity

    1. Configuring Logging Verbosity
      1. Server Startup Logging Configuration

Logging Objects

This logging utility is based on three objects:

  • Component Loggers: Objects which log messages for an individual component of the environment, such as a REST API for an App or to log user access.
  • Destinations: Objects which are called when a component logger requests a message to be logged. Destinations determine how something is logged, for example, to a file or to a console, and what formatting is applied.
  • Logger: Central logging object which can spawn component loggers and attach destinations

Logger IDs

Because Zowe Apps have unique identifiers, both dataservices and App's web content are provided with a component logger that knows this unique ID such that messages logged can be prefixed with that ID. With the association of logging to IDs, verbosity of logs can be controlled by setting log verbosity by ID.

Accessing Logger Objects

Logger

The core logger object is attached as a global for low-level access.

App Server

NodeJS uses global as its global object, so the logger is attached to: global.COM_RS_COMMON_LOGGER

Web

Browsers use window as the global object, so the logger is attached to: window.COM_RS_COMMON_LOGGER as well as window.ZoweZLUX.logger

Component Logger

Component loggers are created from the core logger object, but when working with an App, you should allow the App framework to create these loggers for you. An App's component logger is presented to dataservices or web content as follows

App Server

Dataservice Context Object

Web

Angular App Instance Injectible

Using Logger Objects

Logger message substitution (using IDs)

To allow for easier technical support, it is good practice to create IDs for common logger messages/errors. For example, instead of logging with a code format similar to this:

this.log.info("Application created.")

which compiles to:

DATE TIME:TIME:TIME.TIME <ZWED:> username INFO (org.zowe.app.name,:) Application created.

We can instead use this:

this.log.info("Z0001")

which could compile to:

DATE TIME:TIME:TIME.TIME <ZWED:> username INFO (org.zowe.app.name,:) Z0001 - Application created.

OR depending on the desktop language (for example: Russian):

DATE TIME:TIME:TIME.TIME <ZWED:> username INFO (org.zowe.app.name,:) Z0001 - Приложение создано.

Note: This requires message asset files that hold values for the message substitutions (see section below). Substitution has two main benefits: one being easier technical support by allowing for quicker questions and assistance when known error IDs are being discussed, and an easy interface for logging with internationalization.

Logger Messages Storage

The standard format for a message file is an id:value JSON file in the format:

{ "id1": "value1", "id2": "value2" [...] }

The standard location for message files to be read by a web logger is \src\assets\i18n\log\messages_{language}.json

The standard location for message files to be read by an app server logger is \lib\assets\i18n\log\messages_{language}.json

Logger API

The following constants and functions are available on the central logging object

Attribute Type Description Arguments
makeComponentLogger function Creates a component logger - Automatically done by the App framework for dataservices and web content componentIDString
setLogLevelForComponentName function Sets the verbosity of an existing component logger componentIDString, logLevel

Component Logger API

The following constants and functions are available to each component logger

Attribute Type Description Arguments
CRITICAL const Is a const for logLevel
SEVERE const Is an alias for CRITICAL
WARN const Is a const for logLevel
WARNING const Is an alias for WARN
INFO const Is a const for logLevel
DEBUG const Is a const for logLevel
FINE const Is an alias for DEBUG
FINER const Is a const for logLevel
TRACE const Is a const for logLevel
FINEST const Is an alias for TRACE
log function Used to write a log, specifying the log level logLevel, messageString
critical function Used to write a CRITICAL log. messageString
severe function Used to write a SEVERE log. messageString
warn function Used to write a WARN log. messageString
info function Used to write an INFO log. messageString
debug function Used to write a DEBUG log. messageString
trace function Used to write a TRACE log. messageString
makeSublogger function Creates a new component logger with an ID appended by the string given componentNameSuffix

Log Levels

An enum, LogLevel, exists for specifying the verbosity level of a logger. The mapping is:

Level Number
CRITICAL 0
WARNING 1
INFO 2
DEBUG 3
FINER 4
TRACE 5

NOTE: The default log level for any logger is INFO.

Logging Verbosity

Using the component logger API above, loggers can dictate at which level of verbosity a log message should be visible. The end user can configure the server or client to show more or less verbose messages by using the core logger's API objects.

Example: You want to set the verbosity of the org.zowe.foo App's dataservice, bar to show debugging info. logger.setLogLevelForComponentName('org.zowe.foo.bar',LogLevel.DEBUG)

Configuring Logging Verbosity

The App framework provides ways to specify what component loggers you would like to set default verbosity for, such that you can easily turn logging on or off as an end-user.

Server Startup Logging Configuration

The server configuration file, allows for specification of default log levels, as a top-level attribute logLevels, which takes key-value pairs where the key is a regex pattern for component IDs, and the value is an integer for the log levels.

Example:

"logLevels": {
    "org.zowe.configjs.data.access": 2,
    //the string given is a regex pattern string, so .* at the end here will cover that service and its subloggers.
    "org.zowe.myplugin.myservice.*": 4
    //
    // '_' char reserved, and '_' at beginning reserved for server. Just as we reserve
    // '_internal' for plugin config data for config service.
    // _unp = universal node proxy core logging
    //"_unp.dsauth": 2
  },