Logging

The most important aspect of Overlock is being able to locally log information to the local agent which monitors and uploads information to the Overlock platform whenever a problem occurs.

The most important rule of local logging is that anything that would help you solve a problem can be logged without concern for bandwidth usage! Overlock will only send the most recent and pertinent data when a problem occurs, rather than uploading everything all the time.

With the Overlock agent installed, you can use one of the client libraries for your programming language to gather logs from all your devices. Where a standard logging library exists for a platform, Overlock is normally compatible with it.

Example - Logging

Logging lets you capture a trail of your programs execution when a problem occurs:


from overlock import OverlockLogger
ol = OverlockLogger() # 1 - Import the logger

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

In this example...

  1. The OverlockLogger is imported and can then be used like python's logging interface. the OverlockLogger is a drop-in replacement for python logging with some additional features.
  2. The Overlock state is a dictionary which can be arbitrarily updated to allow storing program and sensor variables to aid with working out what went wrong after a problem.
  3. Regular log messages work as you'd expect. In the case of the ol.exception the python exception and traceback will be handled for you.

Example - Lifecycle

Lifecycle methods allow capturing of high level events, such as when a particularly important thing happens, such as an alarm state. These events can also be much more mundane, such as simply reporting when an update has finished or other information which should be reported to the device timeline.

The benefit of separating these out is that lifecycle logs provide an "at-a-glance" view of your system.


def check_alarm():

    if window.break_detected():
        ol.lifecycle_event("ALARM", "window broken!")
        alarm.enable()

In this example, the Overlock library is used to add a report of the event to the device timeline. It's likely that this information would also be reported to your IoT platform, however the independent trail in Overlock helps provide a view which is digestible by customer service roles.