Overlock client library for Python

The Overlock python library has been created to allow rapidly adding logging, state management and error tracking to your IoT program. It sends data to the Overlock agent, which keeps a rolling cache of recent events and sends them up to the Overlock platform in the event of an error.

NOTE: Before the Client will work, please see information about installing the Overlock agent!

Installation

The Overlock Python library is compatible with Python 2.6+ and 3.3+, and can be installed with pip, either on the command line or through requirements.txt:

pip install overlock
# requiements.txt
overlock==1.*.*

Quickstart

First, the library has to be installed in each application which is going to log diagnostics information. This only has to be done once per application. The second step is to import the logger using overlock.OverlockLogger(), which must be done after the call to install and is a drop-in replacement for Python logging with several additional features.

The third step is to add instrumentation to the code. The most useful functions for this are update_state() which is used to store program variable and application state, and info() and error() which are used to log debug statements and track errors and exceptions respectively.

from overlock import install, OverlockLogger

install(
    # The name of the application program, defaults to "unknown"
    process_name="sensor-reader", 
    # Any custom metadata for the app can be added here
    metadata={
        "version": "2.0.1",
        "hardware_revision": get_hardware_version()
    },
)

# Import the logger
ol = OverlockLogger() 

def read_sensor():
    try:
        value = read_sensor()
        # Use set_state to add state to the store
        ol.update_state({"sensor_value": value})
        # Add a log message
        ol.info("got a new reading for the sensor")
        return value
    except SensorReadException as e:
        ol.update_state({"sensor_value": "unknown"})
        # Log an exception
        ol.error("Error trying to get sensor value!", exc_info=True)

Methods

install

Sets configuration options for the client library so it can interact with the Overlock agent. Must be called once per application before using OverlockLogger.

Arguments:

  • process_name: name of the current process (string)
  • metadata: initial metadata (dict, optional)
  • serialiser: custom JSON serialiser for sending messages (function, optional)
  • agent_host: set the agent host (string, optional, default "127.0.0.1")
  • agent_port: set the agent port (int or string, optional, default 6837)

Example:

install(
    process_name="simple-server",
    metadata={
        "release": "0.8.2",
        "device_type": get_device_type()
    },
    agent_host="agent",
    agent_port=6000
)

OverlockLogger

Returns the logger object, compatible with Python logging.

Arguments: none

Example:

ol = OverlockLogger()

debug, info, warning, error, critical

Sends a log message to the agent with varying levels of severity. By default, messages with a severity of error or higher are sent by the agent to the platform and raised as a new issue.

Arguments:

  • message: log text (string)
  • *args: arguments to insert in the message (optional)
  • related: ids for nodes relating to the messgae (string or [string], optional)
  • exc_info: include information about the last exception raised (bool)
  • node_id: id of another node to log on behalf of (string, optional)

Example:

try:
    send_data(node="abc123", data=data)
    ol.info("Sent data: %s", data, related="abc123")
    send_data(node="def456", data=data)
    ol.info("Sent data: %s", data, related="def456")
except BadException:
    ol.error("A bad exception happened", related=["abc123","def456"], exc_info=True)

lifecycle_event

Add an event to the device lifecycle

Arguments:

  • key_type: type of key (string)
  • comment: value of key (string)
  • node_id: id of another node to log on behalf of (string, optional)

Example:

ol.lifecycle_event("readings", "started")

update_state

Updates the state object which is sent to the platform with every issue.

Arguments:

  • new_state: dictionary of the new state (dict)
  • node_id: id of another node to update the state of (string, optional)

Example:

ol.update_state({
    "simple_example": 1,
    "nested_example": {
        "key": "value"
    }
}, node_id="abc123")

update_metadata

Update the metadata object originally set in the install method

Arguments

  • new_metadata: Dictionary of new metadata (dict)
  • node_id: id of another node to update the metadata of (string, optional)

Example:

ol.update_metadata({
    "release": "1.0.1"
}, node_id="abc123")

log_as

Context manager to log all messages as another node, equivalent to adding node_id to all function calls.

Arguments:

  • node_id: id of the node to log as

Example:

with ol.log_as("abc123"):
    ol.info("Message was %s", message)

The full source of the library can be found on Github.

For any general problems, head over to the community forums or for specific problems, check the github issues.