Logging

Problem

Your plugin needs to log different types of information to support debugging or usage metrics.

Solution

Use the OpenSphere logging framework. There are three parts to enable this - adding the logger, using the logger, and adding the applicable goog.require entries.

Logging Cookbook example - requires
1
2
3
const log = goog.require('goog.log');
const Level = goog.require('goog.log.Level');
const Logger = goog.requireType('goog.log.Logger');
Logging Cookbook example - adding the logger
1
2
3
4
5
/**
 * Logger.
 * @type {Logger}
 */
const logger = log.getLogger('plugin.cookbook_logging.CookbookLogging');
Logging Cookbook example - using the logger
1
2
3
4
5
6
  init() {
    log.info(logger, 'Visible at INFO or below');
    log.warning(logger, 'Visible at WARN or below');
    log.log(logger, Level.FINEST, 'Visible only at FINEST or ALL');
    log.error(logger, 'ALWAYS VISIBLE!');
  }

Discussion

The OpenSphere logging framework is mostly based on the Closure logging library functions. The code above shows the two required argument form (which allows logging at error, warning, info and fine levels) as well as the three required argument goog.log.log form (which allows specifying of the log level for more options). Historically OpenSphere has only used the two required argument form (roughly half of the logging using goog.log.error, with goog.log.warning, goog.log.info and goog.log.fine sharing the other half reasonably evenly).

Tip

If you do need the goog.log.log form, use goog.debug.Logger.Level instead of goog.log.Level to specify the level, in order to avoid logging that works in a debug environment and throws exceptions in a production (minified / compiled) environment.

Having adding logging support to your plugin, you can access logs from within OpenSphere from the Support menu, using the View Logs entry:

../../_images/SupportMenuViewLog.png

Each logger that has been added will appear in the Options menu. The entries for our logger appear as:

../../_images/SetupLogLevels.png

Note that there are entries for plugin.cookbook_logging and plugin.cookbook_logging.CookbookLogging. This makes it easy to configure the appropriate logging levels for your plugin, and for lower level namespaces as needed.

Full code

Logging Cookbook example - Full code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
goog.declareModuleId('plugin.cookbook_logging.CookbookLogging');

import AbstractPlugin from 'opensphere/src/os/plugin/abstractplugin.js';
import PluginManager from 'opensphere/src/os/plugin/pluginmanager.js';

const log = goog.require('goog.log');
const Level = goog.require('goog.log.Level');
const Logger = goog.requireType('goog.log.Logger');


/**
 * Cookbook example of logging.
 */
export default class CookbookLogging extends AbstractPlugin {
  /**
   * Constructor.
   */
  constructor() {
    super();
    this.id = ID;
    this.errorMessage = null;
  }

  /**
   * @inheritDoc
   */
  init() {
    log.info(logger, 'Visible at INFO or below');
    log.warning(logger, 'Visible at WARN or below');
    log.log(logger, Level.FINEST, 'Visible only at FINEST or ALL');
    log.error(logger, 'ALWAYS VISIBLE!');
  }
}

/**
 * Logger.
 * @type {Logger}
 */
const logger = log.getLogger('plugin.cookbook_logging.CookbookLogging');

/**
 * @type {string}
 */
export const ID = 'cookbook_logging';

// add the plugin to the application
PluginManager.getInstance().addPlugin(new CookbookLogging());