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:
- Reporting reboot events to Memfault.
- Reporting Metrics.
- Over-the-air (OTA) updates.
Useful links
- The source for the Memfault Linux SDK. Make sure to use the branch matching the Yocto release that you are using.
- A sample integration using Yocto.
- Reference documentation for:
memfaultd
Configuration file.memfaultctl
CLI.
Assumptions and dependencies
- Currently, our SDK is centered around Yocto and is verified to work on these releases of Yocto:
- Your project uses
systemd
as the init system.
Optionally, as requirements of plugins:
- For OTA:
- For Custom Metrics:
- collectd to collect and upload metrics.
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
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 tomemfaultd
).
memfaultd
is required for integration.
- Yocto
- Other
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 = ""
Grab a copy of the source code for memfaultd
and build
using cargo
. The included builtin.conf
contains built-in defaults for
/etc/memfaultd.conf
and is not meant to be changed. See
the section on /etc/memfaultd.conf
to
learn how to configure memfaultd
on the target device.
cd /path/to/source
cargo build
(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:
swupdate
: used for OTA management.reboot
: used for reboot reason tracking.collectd
: used for collection of metrics.coredump
: used for collection of coredumps.logging
: used to collect and upload logs.
- Yocto
- Other
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"
The included plugins can be configured using Cargo features:
cargo build --no-default-features --feature swupdate reboot collectd coredump logging
Add a memfault-device-info
executable to your build
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
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 "Setenable_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.