Skip to main content

Integration Guide

This tutorial will cover integrating the Memfault Linux SDK into your system. This getting-started guide is designed with systems in mind that are built using Yocto, but generic instructions are included for other setups.

After you're done, you should have a basic integration setup that can talk to the Memfault cloud, enabling one or more of the following features:

Assumptions and dependencies

Optionally, as requirements of plugins:

Integration steps

Create a Project and get a Project Key

Go to app.memfault.com and from the "Select A Project" dropdown, click on "Create Project" to setup your first project such as "smart-sink-dev".

Once you've created your project, you'll be automatically taken to an page that includes your project key. Copy the key and follow the rest of this guide.

Include memfaultd in your build

tip

Keep meta-memfault-example open as a reference implementation. Your integration should look similar to it once you're done following the steps in this tutorial.

The memfaultd service is the main orchestrator of the subsystems that conform and are used by the Memfault Linux SDK. As with all our SDKs, its source code is available on GitHub.

Among its responsibilities are:

  • Keeping a queue of items to be uploaded to the Memfault cloud.
  • Uploading that data at a specified interval, and recovering from network failures using an exponential back-off system, independent of the regular refresh interval.
  • Controlling whether data is allowed to be collected (e.g. by user consent) from a device or not.
  • Interacting with and configuring subsystems such as SWUpdate and collectd.
  • Providing configuration access via memfaultctl (memfaultctl is a symbolic link to memfaultd).

memfaultd is required for integration.

Add memfaultd and dependencies to your Yocto project

Include the meta-memfault layer in your bblayers.conf file, alongside dependencies:

# Apart from other layers you may already depend on:
BBLAYERS ?= " \
${YOCTOROOT}/sources/memfault-linux-sdk/meta-memfault \
${YOCTOROOT}/sources/meta-openembedded/meta-oe \
${YOCTOROOT}/sources/meta-swupdate \
"

You can grab a copy of meta-swupdate from the source repository. Note that meta-oe is a dependency of meta-swupdate.

Since memfaultd has a commercial license, you'll need to add an exception for it, for example in your local.conf:

LICENSE_FLAGS_ACCEPTED:append = " commercial_memfaultd commercial_memfault-core-handler"

Add the necessary dependencies to your image file (note that collectd is provided by meta-oe):

IMAGE_INSTALL:append = " \
u-boot-env \
u-boot-fw-utils \
collectd \
"

Finally, to use systemd as an init system (using poky):

DISTRO_FEATURES:append = " systemd"
DISTRO_FEATURES:remove = "sysvinit"
VIRTUAL-RUNTIME_init_manager = "systemd"
DISTRO_FEATURES_BACKFILL_CONSIDERED:append = "sysvinit"
VIRTUAL-RUNTIME_initscripts = ""

(Optional) Opt out of memfaultd built-in plugins

The `memfaultd` daemon has a plugin system. All plugins are included by default, so you don't need to do anything if you want them in. However, you can control which plugins are included at build time.

The available plugins are:

Set PACKAGECONFIG for the memfaultd package to control which plugins are included in the memfaultd build. For example, you can add a memfaultd.bbappend recipe with the following contents:

PACKAGECONFIG := "plugin_swupdate plugin_reboot plugin_collectd plugin_coredump plugin_logging"

Alternatively, in your local.conf file:

PACKAGECONFIG:pn_memfaultd := "plugin_swupdate plugin_reboot plugin_collectd plugin_coredump plugin_logging"

Add a memfault-device-info executable to your build

tip

You may want to copy over the entire memfault-device-info recipe from our examples to get started. Make sure to edit its contents following the steps in this section.

The memfaultd daemon expects to find a memfault-device-info executable in $PATH. The memfault-device-info executable is created by you during integration and is meant to provide device-specific information in order to identify it in Memfault services. The expected output is in the following format:

MEMFAULT_DEVICE_ID=<device-id>
MEMFAULT_HARDWARE_VERSION=<hardware-version>

Read more about Device ID, Software Versions, and Hardware Versions to better understand these core Memfault platform concepts.

Here's an example memfault-device-info shell script one might add to /usr/bin/memfault-device-info:

#!/bin/sh
echo MEMFAULT_DEVICE_ID=$(cat /etc/machine-id)
echo MEMFAULT_HARDWARE_VERSION=$(dmidecode -s system-product-name)

The script would output something like this:

$ memfault-device-info
MEMFAULT_DEVICE_ID=4a7d5d74-e8f0-471f-9f8c-23e3dd5ce18c
MEMFAULT_HARDWARE_VERSION=some-board-rev-1.3

If you added a recipe named memfault-device-info, don't forget to add it to your image dependencies:

IMAGE_INSTALL:append = " \
memfault-device-info \
u-boot-env \
u-boot-fw-utils \
"

Add /etc/memfaultd.conf to your build

tip

Find a full reference on /etc/memfaultd.conf here. You may want to copy over the entire memfaultd.bbappend recipe from our examples to get started. Make sure to edit its contents following the steps in this section.

A default memfaultd.conf (called builtin.conf in the source files) is embedded within the memfaultd binary, and the daemon will fall back to it if /etc/memfaultd.conf does not provide an override for a specific key. All values in it can be overwritten by adding an /etc/memfaultd.conf file to your build, e.g. using a bbappends recipe for memfaultd (see an example). You may copy parts of the built-in config (or the whole file) to customize configuration on your target device.

Note that while the sample file has reasonable defaults for most keys, it cannot guess a value for some fields such as software_version, software_type or project_key. Hence, a minimal /etc/memfaultd.conf file should look like this:

{
"software_version": "1.0.0",
"software_type": "main",
"project_key": "<YOUR_PROJECT_KEY>"
}

Note that /etc/memfaultd.conf is designed to be in a read-only filesystem.

Read more about Software Versions and Hardware Versions to better understand these core Memfault platform concepts.

Configure a persistent storage directory for memfaultd

In /etc/memfaultd.conf:

{
"software_version": "1.0.0",
"software_type": "main",
"project_key": "<YOUR_PROJECT_KEY>",
"data_dir": "<YOUR_PERSISTENT_STORAGE_DIR>"
}

By default it will be a directory in /media. You will most likely need to change this to wherever your device stores data in a persistent manner. Requirements for this directory are:

  • That it is writable to by memfaultd.
  • That its data persists after firmware upgrades.

Your data_dir will be read from or written to for the following reasons:

  • It will be read every refresh_interval_seconds, in order to check the status of the queue,
  • written to whenever an event occurs that we track in that queue, such as reboot events and when a coredump is captured (see Linux Coredumps), and
  • written to whenever configuration is changed at runtime, for example by using memfaultctl {enable,disable}-data-collection (see "Set enable_data_collection").

Note that the collectd_plugin.interval_seconds does not affect reads or writes to data_dir, unless you've configured collectd to write there, too. By default, collectd will store metrics in memory.

See our configuration reference for more context.

Set enable_data_collection

By default, enable_data_collection is false (see the default configuration). This is to enable asking end users for consent before collecting or transmitting any data to Memfault services.

Once the end user has given their consent, you can enable data collection like so:

$ memfaultctl enable-data-collection

To disable it:

$ memfaultctl disable-data-collection

The memfaultd service will restart automatically whenever you run either of those commands if called with a value different from the current configuration.

Take a look at the /etc/memfaultd.conf reference for more information.

Test the integration

If you've included the reboot reasons plugin, you can test your integration by rebooting your test device. Then, on the Memfault app, open Fleet -> Devices and check that your device shows up. If you open the specific device, you should be able to find its reboot events under the Reboots tab.

Integrate with our OTA subsystem

Follow our Embedded Linux OTA Integration Guide.