Device info Ledger

This project stores device information like debugging logs and other device information in Ledger.

Overview

One of the commonly used troubleshooting tools is the USB serial debug log. One issue is that the logs tend to be large and verbose, so it's not practical to send entire logs in real time to the cloud. Plus, if the issue is with connectivity, the cloud won't be available at the time.

To help solve two common issues, this example can store a small portion of the log in two common scenarios:

  • For the network and cloud connection process, for debugging intermittent connectivity issues.
  • Right before the most recent reboot, for help in isolating a SOS panic reset.

The configuration, including what to include and how much log information to save, can be configured three ways:

  • Locally, on device, in C++ code.
  • Cloud configuration of product default settings via Ledger.
  • Cloud configuration overrides for a specific device via Ledger.

For example, you could include minimal log information by default, but increase the information when troubleshooting issues on a specific device.

Finally, the device information is saved in Ledger. A sample log is shown here, and there is a tool below for viewing the information for devices in your product.

Sample log

Creating a product

This example requires device-side Ledger, which requires Device OS 6.1.0 or later. Additionally, it can only be used with devices in a product, and only developer sandbox products (not organization products).

If running the example, we recommend that you create a new product for testing, adding a device or two to the test product, then removing the devices and product when done testing. This will reduce the likelihood of breaking a working product.

Device type  


Create Ledgers

This example uses up to three Ledgers. The default names are included here, but they can be changed, though you must also modify the firmware to use the new names.

Device information Ledger

This Ledger stores the data generated by the device so you can view it from the cloud. There is an interactive tool to view this data below, you can view it in JSON format in the console, or you can access the data using the Particle cloud API.

Name Description
Ledger Name device-info
Direction Device to cloud

This Ledger is required. Without it, there would be no purpose to this feature as the data would not be stored anywhere!

Each instance of this Ledger is device that has stored its device information.

Default configuration Ledger

This Ledger stores the default configuration for devices in your product. You can either store the default configuration in the cloud, or you can store it in code in firmware.

Name Description
Ledger Name device-info-defaults
Direction Cloud to device
Scope Product

This Ledger is optional, and if you do not create it, you will need to embed the default configuration in the firmware code.

Each instance of this Ledger corresponds to a product default configuration. You must specify all configuration fields in the JSON; if you specify a cloud configuration it will not merge with a local configuration.

If you are using cloud default configuration, you should create an instance for your test product and set the JSON to this using the Advanced tab:

{
    "lastRunLog": 1024,
    "connectionLog": 2048,
    "includeGeneral": true,
    "includeDiag": true,
    "includeTower": true,
    "logLevel": "INFO",
    "logFilters": {},
}

Device configuration Ledger

This Ledger allows you to override configuration for a specific device in your product. You might use this to adjust the log sizes and levels to better troubleshoot a problem with a specific device, for example.

Name Description
Ledger Name device-info-config
Direction Cloud to device
Scope Device

This Ledger is optional, and if you do not create it, you will not be able to override the configuration on a per-device basis.

Each instance of this Ledger corresponds to a single device override. The value is JSON and only needs to specify the fields you want to override.

Project source

   

     

Library information

This project uses the DeviceInfoLedger library, which makes it easy to:

  • Store cloud-based configuration for devices (DeviceConfigLedger)
  • Store Particle device log data and device information in Ledger (DeviceInfoLedger)

Viewing data

The tool below can be used to view the logs once they've been uploaded to the cloud.

Configuration

Default configuration in Ledger

You can configure the product defaults and device overrides in the cloud using Ledger using setup() code like this:

// This sets up remote configuration
DeviceConfigLedger::instance()
    .withConfigDefaultLedgerName("device-info-defaults")
    .withConfigDeviceLedgerName("device-info-config")
    .setup();

// This sets up the device information in ledger
DeviceInfoLedger::instance()
    .withInfoLedgerName("device-info")
    .withRetainedBuffer(retainedLogs, sizeof(retainedLogs))
    .setup(); 

If you don't want the device-specific override ledger, remove the withConfigDeviceLedgerName() line.

Device overrides in Ledger

You can create an instance in the device-info-config Ledger for a specific Device ID. This only needs to set the overrides to the default configuration (either cloud or local).

For example, this JSON will increase the size of the connection log and set it to trace mode.

{
    "connectionLog": 4096,
    "logLevel": "TRACE",
    "logFilters": {},
}

This is an example using log filters to set the level for specific categories:

{
    "logLevel": "WARN",
    "logFilters": {
        "app": "INFO",
        "app.network": "TRACE"
    }
}

This is similar to the JSON configuration equivalent to this setup in C++ code:

SerialLogHandler logHandler(LOG_LEVEL_WARN, { // Logging level for non-application messages
    { "app", LOG_LEVEL_INFO }, // Default logging level for all application messages
    { "app.network", LOG_LEVEL_TRACE } // Logging level for networking messages
});

Log settings in the cloud only affect the cloud logs, however, not the local USB serial logs. You can specify different settings for SerialLogHandler.