How to - Use log functions
Most OpenAF code needs somehow to log it’s activity. The usual obvious choice is to use the print functions but once you start logging production code the requirements usually go beyond just simply outputing a string to the console/stdout.
To encapsule this extra functionality and, at the same time, keep the simplicity of the print functions OpenAF provides the log functions:
Function | Quick description |
---|---|
log(msg, options) | Logs the mgs as a normal information (INFO) message. One-time options can also be provided. |
logErr(msg, options) | Logs the mgs as an error (ERROR) message. One-time options can also be provided. |
logWarn(msg, options) | Logs the mgs as a warning (WARN) message. One-time options can also be provided. |
lognl(msg, options) | Same as the log function but won’t end with a new-line. |
Examples:
log("This is a test")
// 2020-01-02 12:13:14.567 | INFO | This is a test
logErr("Hups! There was an error!")
// 2020-01-02 12:13:16.765 | ERROR | Hups! There was an error!
logWarn("Be careful...")
// 2020-01-02 12:13:18.555 | WARN | Be careful...
As you might have noticed, for simplicity, there are 3 main loggging levels: INFO, ERROR and WARN.
Template-based log functions
Equivalent to the log* functions OpenAF also provides template-based (using the ow.template internal library) equivalent functions:
Function |
---|
tlog(msg, data, options) |
tlogErr(msg, data, options) |
tlogWarn(msg, data, options) |
tlognl(msg, data, options) |
The main difference is the extra data map-type parameter. This should be a map with the data to be used on the provided template on the msg parameter.
Simple example:
tlog("The current version is: {{version}}", { version: getVersion() })
// 2020-01-03 13:14:15.678 | INFO | The current version is: 20200102
If no data map is provided the current scope will be used:
var distribution = getDistribution()
tlog("The current distribution is: {{distribution}}")
// 2020-01-03 13:14:17.876 | INFO | The current distribution is: nightly
Log functions options
As described previously each log function can have one-time options provided but you can also change the current settings used using the function setLog(aOptionsMap).
The options available are:
Option | Type | Default | Description |
---|---|---|---|
off | boolean | false | If true no stdout/stderr output attempt will be executed |
offInfo | boolean | false | If true all INFO type messages won’t be output. |
offError | boolean | false | If true all ERROR type messages won’t be output. |
offWarn | boolean | false | If true all WARN type messages won’t be output. |
dateFormat | string | “yyyy-MM-dd HH:mm:ss.SSS” | This a ow.format.fromDate date format to be used. |
dateTZ | string | The time zone to use (refer to ow.format.fromDate). If not defined it will use the current Java | |
separator | string | ”|” | The log fields separator to use (when using the default “human” format) |
async | boolean | true | If false logging will stop the execution to output the log message. |
asyncLevel | number | 3 | When async is true the asyncLevel determines the maximum number of queued log messages for logging. When the maximum number is reached the current execution will wait for log execution until the queued level is re-established. |
profile | boolean | false | Whenever a log message is captured the current Java memory and system load stats will also be gathered. |
format | string | “human” | This allows to change the stdout/stderr output format to other alternatives (e.g. json, slon) |
Example setting global options:
setLog({ offInfo: true })
logWarn("The INFO messages are off")
// 2020-01-01 12:13:14.567 | WARN | The INFO messages are off
log("this is just a info message")
setLog({ offInfo: false })
logWarn("The INFO messages are now on")
// 2020-01-01 12:13:14.678 | WARN | The INFO messages are now on
log("this is just an info message")
// 2020-01-01 12:13:15.123 | INFO | this is just an info message
Example setting an on-time option:
logWarn("POINT OF NO RETURN!", { async: false })
// 2020-01-02 12:13:14.123 | WARN | POINT OF NO RETURN!
Logging to an OpenAF channel
It’s also possible to configure OpenAF to log to an OpenAF channel. This allows logging to fully use the OpenAF channels functionality including output to external targets like ElasticSearch and others.
To start the functionality you just need to use the function startLog(anOpenAFChannelSubscribeFunction, keepItems). The numeric keepItems argument (which defaults to 100) determines how many entries to keep internally (in memory) for the OpenAF channel functionality (if you specify -1 no life-cycle will be used).
The anOpenAFChannelSubscribeFunction will receive a key and a value map for each logged entry:
Key:
Field | Type | Description |
---|---|---|
n | number | Current system time in nanoseconds (nowNano()) |
t | string | The logging level (e.g. INFO, WARN, ERROR) |
Value:
Field | Type | Description |
---|---|---|
n | number | Current system time in nanoseconds (nowNano()) |
d | date | The javascript date |
t | string | The logging level (e.g. INFO, WARN, ERROR) |
m | string | The logged message |
freeMem | number | (if the option profile is true) the current Java free memory |
totalMem | number | (if the option profile is true) the current Java total memory |
systemLoad | number | (if the option profile is true) the current operating system load |
If there is a need to stop the output of log messages to an OpenAF channel you can simply execute the function stopLog.
Example:
// Executes a custom function with the log data
startLog((aCh, aOp, aKey, aVal) => { if (aOp == "set") print(aVal.t + " --> " + aVal.m) })
// Turns off the standard stdout/stderr output
setLog({ off: true })
log("Script started")
// INFO --> Script started
// ...
log("Script ended")
// INFO --> Script ended
stopLog()
Check also
- How to log to files with automated compression of old files and life-cycle/house-keeping management.