Logging

Comprehensive description of Spotflow logging including technical details.

Spotflow provides an end-to-end logging solution designed specifically for embedded devices.

This page walks you through all the aspects related to Spotflow logging, from integrating it into devices, through understanding the transport protocol, to analyzing and troubleshooting logs in the web application.

Getting Started with Device Integration

Guide: Zephyr or Nordic nRF Connect SDK

Spotflow offers native integration for devices running Zephyr and Nordic nRF Connect SDK through a lightweight software module. This module integrates seamlessly with your existing logging infrastructure - simply add it as a dependency and use the standard logging macros you're already familiar with.

Guide: MQTT

For devices running other platforms or when you cannot use Spotflow device module, integration is also possible via standard MQTT interface. Spotflow platform exposes scalable MQTT broker accessible anywhere from the Internet that can be used to ingest logs. See Transport Protocol section for details.

Transport Protocol

Spotflow uses an optimized transport protocol based on TCP, MQTT and TLS and two serialization formats (CBOR and JSON).

MQTT over TLS

All log transmission uses MQTT over TLS (MQTTS) for secure, reliable communication:

  • TLS Version: 1.2 or higher
  • Certificate: Let's Encrypt ISRG Root X1 (pre-installed on many systems or included in Spotflow SDKs)
  • Authentication: Devices authenticate using ingest keys as MQTT passwords and their unique device IDs as MQTT usernames.

Serialization format

There are two flavours of the protocol, differing in their serialization format:

  • CBOR-based: recommended for maximum memory and bandwidth efficiency. Used by Spotflow Zephyr Module.
  • JSON-based: recommended for maximum simplicity and interoperability between platforms.

Log Message Format - CBOR

CBOR (Concise Binary Object Representation) is very memory and bandwidth efficient binary serialization format. We recommend using CBOR to achieve maximum efficiency for embedded devices with limited bandwidth and processing power.

Spotflow Zephyr module uses CBOR to serialize log messages with optimized, single byte field identifiers and constant values to reduce overhead.

The log messages follow the following CDDL schema:

log-message = {
    ? 1 => tstr,                  ; body: fully interpolated log line string (optional when bodyTemplate is used)
    ? (
        2 => tstr,                ; bodyTemplate (optional): printf-like interpolation string
        3 => body-template-values ; bodyTemplateValues (optional): values for interpolation
    ),
    ? 4 => severity,              ; severity (recommended)
    ? 5 => labels,                ; labels (optional): user-defined key-value pairs for additional context
    ? 6 => uint,                  ; deviceUptimeMs (optional): device uptime in milliseconds in range [0, 2^63 - 1]
    ? 7 => uint                   ; deviceTimestampMs (optional): device timestamp in milliseconds in range [0, 2^63 - 1]
}

labels = {* (tstr => (tstr / int / float / bool))} ; Strongly typed key-value pairs

; Integer severity values
debug-severity = 30
info-severity = 40
warning-severity = 50
error-severity = 60
critical-severity = 70
severity = (debug-severity / info-severity / warning-severity / error-severity / critical-severity)

; A strongly typed array of values, or an array of byte string representations (big-endian) of the values
body-template-values = [ * (tstr / int / float / bool / null) ] / [ * bstr ]

Log Message Format - JSON

JSON (JavaScript Object Notation) is a lightweight data interchange format that's easy for humans to read and write. While not as efficient as CBOR, JSON is widely used and supported across different platforms.

We recommend using JSON for custom MQTT implementations, when maximum simplicity and interoperability is required while higher bandwidth is acceptable.

The log messages follow the following JSON structure:

{
    // Fully interpolated log line string (optional when bodyTemplate is used)
    "body": "SmartLock was Unlocked",

    // (Optional) printf-like interpolation string for the log line
    "bodyTemplate": "SmartLock was %s",

    // (Optional) array of values for interpolation in the bodyTemplate
    "bodyTemplateValues": ["Unlocked"],

    // (Recommended) Log severity, possible values: "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"
    "severity": "INFO",

    // (Optional) device uptime when the log was generated (milliseconds since the device booted)
    "deviceUptimeMs": 23455,

    // (Optional) time when the log was generated (milliseconds since the UNIX epoch)
    "deviceTimestampMs": 1748530133808,

    // (Optional) you can add extra metadata to your logs
    "labels": {
        "initiatorKind": "MobileApp",
        "userId": "1234567890"
    }
}

Device ID

Ideally, each physical device should use its own unique device ID for log ingestion (possibly even its own Ingestion Key). However, we know that mistakes in device provisioning and configuration can happen so our transmission protocol is robust to multiple devices using the same device ID at the same time. In such cases, the devices will still to send logs to Spotflow without disruption.

At least once delivery

Once a log message is ingested by our MQTT broker, we guarantee that the message will be processed and made available for querying. No data loss is tolerated after acceptance. However, depending on the MQTT QoS level used for publishing, some messages might get lost before they are ingested by the broker.

If these trade-offs are not acceptable for your use-case, please open a Feature request or let us know via email hello@spotflow.io or our Discord. We will be happy to work with you to incorporate necessary changes to the platform or find other suitable solution.

Analyze Logs in the Web Application

Once your device is integrated and sending logs, you can analyze them in the web application. The main entry point is the Events page, which gives you a comprehensive view of all events collected from your devices. There, you can filter logs by their content, device ID, severity, and other metadata.

Spotflow Web Application Screenshot
The Events page displays all logs with filtering and search capabilities.

You can click on individual log messages to see their details, and it is possible to drill down into specific events by matching their metadata.

Detail a single log message.
It is possible to query logs based on metadata of a particular log message.

Learn more

How is this guide?