Debugging

Two features of OpenGate let you run your own JavaScript inside the platform: connector functions, which translate what devices say, and rules, which react to what arrives. Both run server-side, on events you did not trigger, which makes the usual debugging reflexes useless — there is no console to watch.

This section is that console.

How it works

flowchart LR
    JS["Your JavaScript<br>connector function or rule"] -->|"logger.info(...)"| SVC["Functions logger<br>service"]
    SVC -->|"WebSocket stream"| YOU["Your terminal<br>or application"]

    classDef mine fill:#addcf8,stroke:#2b7cb8,color:#000
    class JS mine

Two halves, one page each:

Half What it is Page
Writing The logger object your script calls: trace, debug, info, warn, error JS Logging API
Reading A WebSocket you open to stream those traces live, filtered by level Functions Logger Service

It covers rules too

The service exposes one endpoint family per subject, and the only difference is the path and the identifier:

Subject Endpoint Identifier
Connector functions .../functions-logger/connectorFunctions/organizations/{org}/channels/{channel}/{cf-id} The connector function id
Rules .../functions-logger/rules/organizations/{org}/channels/{channel}/{rf-id} The rule id

Everything else — the mandatory X-ApiKey parameter, the level filter and the message format — is identical for both. See Functions Logger Service for the complete URIs.

Debugging in practice

A workflow rather than a list of features:

  1. Start with the script disabled. A connector function’s operationalStatus exists precisely so a half-written script never touches production devices: create it DISABLED, move to TEST against a test device, and only then to PRODUCTION.
  2. Log the inputs you did not expect, not the ones you did. The payload your script receives is whatever the device really sent, which is rarely what the datasheet promised.
  3. Subscribe at TRACE while you iterate, then raise the level. Each level includes the ones above it: WARN delivers ERROR and WARN, and nothing below.
  4. Remember the REST API barely parses your JavaScript. A script that was accepted at creation can still fail at runtime, and this is where you find out.
Levels filter delivery, not writing

level controls what the service sends you, not what your script writes. Leaving logger.trace calls in place costs nothing once you stop subscribing at TRACE, so there is no reason to strip them out when you are done debugging.

Subsections of Debugging

Functions Logger Service

Logger Websocket endpoints

Connector functions logger feature is available on this URL: wss://api.opengate.es/north/functions-logger/connectorFunctions/organizations/{organization_name}/channels/{channel_name}/{cf-id}

Rules logger feature is available on this URL: wss://api.opengate.es/north/functions-logger/rules/organizations/{organization_name}/channels/{channel_name}/{rf-id}

Websocket requires mandatory X-ApiKey url parameter to work

Another parameter to be set is logging level, used to define which traces must be sent to the client. This parameter is not mandatory and by default the INFO level will be used.

Here is a complete URI example for the connector functions logger:

wss://api.opengate.es/north/functions-logger/connectorFunctions/organizations/{organization_name}/channels/{channel_name}/{cf-id}?X-ApiKey={your-api-key}&level={logging-level}

Where:

  • organization_name: Organization name.
  • channel_name: Channel name.
  • cf-id: Connector function identifier.
  • your-api-key: API key of a valid user with permissions over the defined function.
  • logging-level: Specify logging granularity. Valid logging levels: ERROR, WARN, INFO, DEBUG, TRACE. If incorrect value is defined, INFO level will be used by Functions Logger service. Same level or higher level messages will be received. For example if WARN is defined in the path, ERROR and WARN traces will be received, but not INFO, DEBUG or TRACE.

After opening Websocket connection, the client will receive log messages with following format:

{
    "message": "message.",
    "level": "INFO",
    "timestamp": 1607108000000
}

Where

  • message: Printed trace in connector function.
  • level: Trace level. Possible values: ERROR, WARN, INFO, DEBUG, TRACE.
  • timestamp: Trace UTC timestamp in milliseconds.

JS Logging API

JS API guide for logging

This file provides methods to write logging traces.

Logger Object

The logger object is the main object for logging functions.

logger.trace(…msg)

Creates TRACE level logging messages. It concatenates msg parameters to compound message to be logged.

Kind: global function
Returns: Void

Param Type Description
…msg any The function takes as parameters a list of elements to be concatenated to generate the string message to be printed.

Example of use:

logger.trace('Operation sent to', host_var, ' and port ', port_var, '. Operation content: ', operation_var);

logger.debug(…msg)

Creates DEBUG level logging messages. It concatenates msg parameters to compound message to be logged.

Kind: global function
Returns: Void

Param Type Description
…msg any The function takes as parameters a list of elements to be concatenated to generate the string message to be printed.

Example of use:

logger.debug('Operation sent to', host_var, ' and port ', port_var, '. Operation content: ', operation_var);

logger.info(…msg)

Creates INFO level logging messages. It concatenates msg parameters to compound message to be logged.

Kind: global function
Returns: Void

Param Type Description
…msg any The function takes as parameters a list of elements to be concatenated to generate the string message to be printed.

Example of use:

logger.info('Operation sent to', host_var, ' and port ', port_var, '. Operation content: ', operation_var);

logger.warn(…msg)

Creates WARN level logging messages. It concatenates msg parameters to compound message to be logged.

Kind: global function
Returns: Void

Param Type Description
…msg any The function takes as parameters a list of elements to be concatenated to generate the string message to be printed.

Example of use:

logger.warn('Operation sent to', host_var, ' and port ', port_var, '. Operation content: ', operation_var);

logger.error(…msg)

Creates ERROR level logging messages. It concatenates msg parameters to compound message to be logged.

Kind: global function
Returns: Void

Param Type Description
…msg any The function takes as parameters a list of elements to be concatenated to generate the string message to be printed.

Example of use:

logger.error('Error connecting to host ', host_var, ' and port ', port_var, '. Stop processing');