Julian Oes 1a96bd2c94
feat(logger): add SDLOG_ROTATE, disentangle cleanup thresholds
The previous cleanup logic conflated two independent concerns into
SDLOG_MAX_SIZE: the maximum size of a single log file (rotation
trigger) AND the minimum free space to maintain. That was broken:
the 4095 MB default meant "keep 4 GB free", which over-cleaned on
large SD cards and was impossible to satisfy on small flash.

Disentangle the two:

- SDLOG_ROTATE (new, int %, default 90): maximum disk usage percentage.
  Cleanup guarantees at least (100 - SDLOG_ROTATE)% free even during
  writing of a new log file. Setting 0 disables space-based cleanup;
  100 allows filling the disk completely.
- SDLOG_MAX_SIZE (default lowered from 4095 to 1024): pure max file
  size. The value is added on top of the rotate-derived threshold as
  headroom for the next file write, so the rotate guarantee holds
  even mid-write.
- SDLOG_DIRS_MAX: removed. Directory count limits were confusing and
  orthogonal to the space-management goal; free-space cleanup alone
  covers the use case. Drop the param and all remaining overrides
  (rc.board_defaults, rcS, rc.replay, 1002_standard_vtol.hil).

Cleanup threshold is now:
    ((100 - SDLOG_ROTATE)% of disk) + SDLOG_MAX_SIZE

Small-flash boards can override SDLOG_MAX_SIZE to get more retained
logs within the available space. kakuteh7v2 and airbrainh743 drop
their SDLOG_DIRS_MAX overrides accordingly.

Update docs/en/dev_log/logging.md with the new semantics and a
worked example for the typical 8 GB SD case.
2026-04-11 06:35:58 +12:00

13 KiB

Logging

The system logger is able to log any ORB topic with all included fields. Everything necessary is generated from the .msg file, so that only the topic name needs to be specified. An optional interval parameter specifies the maximum logging rate of a certain topic. All existing instances of a topic are logged.

The output log format is ULog.

Encrypted logging is also supported.

Usage

By default, logging is automatically started when arming, and stopped when disarming. A new log file is created for each arming session on the SD card. To display the current state, use logger status on the console. If you want to start logging immediately, use logger on. This overrides the arming state, as if the system was armed. logger off undoes this.

If logging stops due to a write error, or reaching the maximum file size, PX4 will automatically restart logging in a new file.

For a list of all supported logger commands and parameters, use:

logger help

Configuration

The logging system is configured by default to collect sensible logs for flight reporting with Flight Review.

Logging may further be configured using the SD Logging parameters. The parameters you are most likely to change are listed below.

Parameter Description
SDLOG_MODE Logging Mode. Defines when logging starts and stops.
- 0: Log when armed until disarm (default).
- 1: Log from boot until disarm.
- 2: Log from boot until shutdown.
- 3: Log based on the AUX1 RC channel.
- 4: Log from first armed until shutdown.
SDLOG_BACKEND Logging Backend (bitmask). Setting a bit enables the corresponding backend. If no backend is selected, the logger is disabled.
- bit 0: SD card logging.
- bit 1: Mavlink logging.
SDLOG_PROFILE Logging profile. Use this to enable less common logging/analysis (e.g. for EKF2 replay, high rate logging for PID & filter tuning, thermal temperature calibration).
SDLOG_MISSION Create very small additional "Mission Log".
This log can not be used with Flight Review, but is useful when you need a small log for geotagging or regulatory compliance.

Useful settings for specific cases:

Logger module

Developers can further configure what information is logged via the logger module. This allows, for example, logging of your own uORB topics.

SD Card Configuration

Separately, the list of logged topics can also be customized with a file on the SD card. Create a file etc/logging/logger_topics.txt on the card with a list of topics (For SITL, it's build/px4_sitl_default/rootfs/fs/microsd/etc/logging/logger_topics.txt):

<topic_name> <interval> <instance>

The <interval> is optional, and if specified, defines the minimum interval in ms between two logged messages of this topic. If not specified, the topic is logged at full rate.

The <instance> is optional, and if specified, defines the instance to log. If not specified, all instances of the topic are logged. To specify <instance>, <interval> must be specified. It can be set to 0 to log at full rate

The topics in this file replace all of the default logged topics.

Example :

sensor_accel 0 0
sensor_accel 100 1
sensor_gyro 200
sensor_mag 200 1

This configuration will log sensor_accel 0 at full rate, sensor_accel 1 at 10Hz, all sensor_gyro instances at 5Hz and sensor_mag 1 at 5Hz.

Scripts

There are several scripts to analyze and convert logging files in the pyulog repository.

Log Cleanup

PX4 automatically manages log storage by cleaning up old logs when starting to log. Two parameters control how much space logs may use:

  • SDLOG_ROTATE is the maximum disk usage percentage (default 90). Cleanup ensures at least (100 - SDLOG_ROTATE)% of the disk stays free at all times, even while writing a new log file. Setting it to 0 disables space-based cleanup entirely; setting it to 100 lets logs fill the disk completely.
  • SDLOG_MAX_SIZE is the maximum size of a single log file in MB (default 1024). It also reserves headroom so that a full new file always fits after cleanup.

At log start, the cleanup threshold is ((100 - SDLOG_ROTATE)% of disk) + SDLOG_MAX_SIZE. Oldest logs are deleted until the free space meets this threshold. For example, on an 8 GB card with defaults, cleanup keeps at least 820 + 1024 = ~1.8 GB free at log start, so ~6 GB is usable for logs and disk usage never exceeds 90% during writing. Small flash targets override SDLOG_MAX_SIZE to a smaller value to keep more logs within the available space.

The cleanup algorithm prioritizes deleting logs from the directory naming scheme not currently in use. PX4 uses two directory naming schemes:

  • Session directories (sess001, sess002, etc.) - used when the system doesn't have valid time information
  • Date directories (2024-01-15, 2024-01-16, etc.) - used when the system has valid time (e.g., from GPS)

When cleanup is needed:

  • If the system has valid time (using date directories): old session directories are deleted first
  • If the system doesn't have valid time (using session directories): old date directories are deleted first

This ensures that stale logs from a different time mode are cleaned up before current logs.

File size limitations

The maximum file size depends on the file system and OS. The size limit on NuttX is currently around 2GB.

Dropouts

Logging dropouts are undesired and there are a few factors that influence the amount of dropouts:

  • Most SD cards we tested exhibit multiple pauses per minute. This shows itself as a several 100 ms delay during a write command. It causes a dropout if the write buffer fills up during this time. This effect depends on the SD card (see below).
  • Formatting an SD card can help to prevent dropouts.
  • Increasing the log buffer helps.
  • Decrease the logging rate of selected topics or remove unneeded topics from being logged (info.py <file> is useful for this).

SD Cards

The maximum supported SD card size for NuttX is 32GB (SD Memory Card Specifications Version 2.0). The SanDisk Extreme U3 32GB and Samsung EVO Plus 32 are known to be reliable cards (do not exhibit write-time spikes, and thus virtually no dropouts).

The table below shows the mean sequential write speed [KB/s] / maximum write time per block (average) [ms] for F4- (Pixracer), F7-, and H7-based flight controllers.

SD Card F4 F7 H7
SanDisk Extreme U3 32GB 1500 / 15 1800/10 2900/8
Samsung EVO Plus 32GB 1700/10-60 1800/10-60 1900/9-60
Sandisk Ultra Class 10 8GB 348 / 40 ?/? ?/?
Sandisk Class 4 8GB 212 / 60 ?/? ?/?
SanDisk Class 10 32 GB (High Endurance Video Monitoring Card) 331 / 220 ?/? ?/?
Lexar U1 (Class 10), 16GB High-Performance 209 / 150 ?/? ?/?
Sandisk Ultra PLUS Class 10 16GB 196 /500 ?/? ?/?
Sandisk Pixtor Class 10 16GB 334 / 250 ?/? ?/?
Sandisk Extreme PLUS Class 10 32GB 332 / 150 ?/? ?/?

Logging bandwidth with the default topics is around 50 KB/s, which almost all SD cards satisfy in terms of their mean sequential write speed.

More important than the mean write speed is spikes (or generally high values) in the maximum write time per block (of 4 KB) or fsync times, as a long write time means a larger log buffer is needed to avoid dropouts.

PX4 uses bigger buffers on F7/H7 and read caching, which is enough to compensate for spikes in many poor cards. That said, if your card has an fsync or write duration of several 100ms it is should not be preferred for use with PX4. You can check the value by running sd_bench should be run with more iterations (around 100 should do).

sd_bench -r 100

This defines the minimum buffer size: the larger this maximum, the larger the log buffer needs to be to avoid dropouts. PX4 uses bigger buffers on F7/H7 and read caching to make up for some of these issues.

::: info If you have concerns about a particular card you can run the above test and report the results to https://github.com/PX4/PX4-Autopilot/issues/4634. :::

Log Streaming

The traditional and still fully supported way to do logging is using an SD card on the FMU. However there is an alternative, log streaming, which sends the same logging data via MAVLink. This method can be used for example in cases where the FMU does not have an SD card slot (e.g. Intel® Aero Ready to Fly Drone) or simply to avoid having to deal with SD cards. Both methods can be used independently and at the same time.

The requirement is that the link provides at least ~50KB/s, so for example a WiFi link. And only one client can request log streaming at the same time. The connection does not need to be reliable, the protocol is designed to handle drops.

There are different clients that support ulog streaming:

  • mavlink_ulog_streaming.py script in PX4-Autopilot/Tools.
  • QGroundControl: QGC Log Streaming
  • MAVGCL

Diagnostics

  • If log streaming does not start, make sure the logger is running (see above), and inspect the console output while starting.

  • If it still does not work, make sure that MAVLink 2 is used. MAV_PROTO_VER needs to be set to 2.

  • Log streaming uses a maximum of 70% of the configured MAVLink rate (-r parameter). If more is needed, messages are dropped. The currently used percentage can be inspected with mavlink status (1.8% is used in this example):

    instance #0:
            GCS heartbeat:  160955 us ago
            mavlink chan: #0
            type:           GENERIC LINK OR RADIO
            flow control:   OFF
            rates:
            tx: 95.781 kB/s
            txerr: 0.000 kB/s
            rx: 0.021 kB/s
            rate mult: 1.000
            ULog rate: 1.8% of max 70.0%
            accepting commands: YES
            MAVLink version: 2
            transport protocol: UDP (14556)
    

    Also make sure txerr stays at 0. If this goes up, either the NuttX sending buffer is too small, the physical link is saturated or the hardware is too slow to handle the data.

See Also