Skip to content

Releases: memfault/bort

v5.5.0 - December 1, 2025

02 Dec 17:46

Choose a tag to compare

🚀 New Features

  • Added ability to ignore common WTF patterns. These were chosen across multiple
    projects based off of WTF volume and usefulness. Ignoring these will make the
    WTFs that do show up more useful. In addition, introduces new SDK settings to
    control whether these patterns are used, and to add additional WTF ignore
    patterns.
    • The default ignored patterns are:
      • "No service published for: appwidget at
        android.app.SystemServiceRegistry.onServiceNotFound.*"
      • "EXTRA_USER_HANDLE missing or invalid, value=0.*"
      • "Failed to read field SystemLocale.*"
      • "BUG: NetworkAgentInfo.*"
      • "Attempt to decrement existing alarm count 0 by 1 for uid 1000.*"
      • "Removed TIME_TICK alarm.*"
      • "requesting nits when no mapping exists.*"
      • "Could not open /sys/kernel/tracing/instances/bootreceiver/trace_pipe.*"
  • Added Bluetooth quality metrics.
    • bluetooth.ble_scan_result.count tracks the number of BLE devices found in
      each scan
    • bluetooth.ble_scan_result.attribution tracks the initiator of the BLE scan
    • bluetooth.device_rssi.(min|mean|max) tracks the Bluetooth RSSI
      distribution
    • bluetooth.device_rssi.device_id.latest tracks the Bluetooth device
      reporting the RSSI value
    • bluetooth.device_tx_power_level.(min|mean|max) tracks the Bluetooth TX
      power level distribution
    • bluetooth.device_tx_power_level.device_id tracks the Bluetooth device
      reporting the TX power level value
    • bluetooth.quality_report.rssi.(min|mean|max) tracks the Bluetooth RSSI
      distribution reported by the Bluetooth quality report (if available)
    • bluetooth.quality_report.snr.(min|mean|max) tracks the Bluetooth SNR
      distribution reported by the Bluetooth quality report (if available)
    • bluetooth.quality_report.retransmission_count.(mean|max|sum) tracks the
      number of retransmissions reported by the Bluetooth quality report (if
      available).
    • bluetooth.quality_report.reported.latest reports the latest Bluetooth
      quality report.
  • Added heartbeat metrics for any batterystats metrics that were previously only
    used in HRT.
    • camera
      • camera_on_ratio
    • video
      • video_on_ratio
    • flashlight
      • flashlight_on_ratio
    • bluetooth
      • bluetooth_on_ratio
    • usb_data
      • usb_data_on_ratio
    • wake_lock
      • wake_lock_on_ratio
    • wifi_full_lock
      • wifi_full_lock_ratio
    • long_wake_lock
      • long_wake_lock_on_ratio
    • screen_wake
      • screen_wake_count
    • package_install
      • package_install_count
    • phone_connection
      • phone_connection_latest
    • phone_in_call
      • phone_in_call_ratio
    • phone_state
      • phone_state_in_ratio
      • phone_state_out_ratio
      • phone_state_em_ratio
    • cellular_high_tx_power
      • cellular_high_tx_power_on_ratio
    • nr_state
      • nr_state_none_ratio
      • nr_state_restricted_ratio
      • nr_state_not_restricted_ratio
      • nr_state_connected_ratio
  • Added support for reporting USB contaminant events.
    • usb.contaminant_reported.latest
  • Updated existing network metrics to generate a heartbeat metric as well.
    • connectivity.airplane_mode.latest
    • connectivity.internet.latest
    • connectivity.validated.latest
    • connectivity.captive_portal.latest
    • connectivity.roaming.latest
    • connectivity.unmetered_temporarily.latest
  • Added basic IPv4 and IPv6 connectivity metrics.
    • connectivity.ip_version.latest with states "IPv4", "IPv6", "IPv4+IPv6",
      "?"
    • connectivity.ipv4_status.latest with states "Internet Available",
      "Configuration Error", "Not Available"
    • connectivity.ipv6_status.latest with states "Internet Available", "Local
      Only", "Not Available"
  • Added Wi-Fi RSSI time-based moving average metric. This metric is calculated
    from raw values obtained from WifiManager broadcasts using an exponential
    moving average.
    • connectivity.wifi.rssi.moving_avg
  • Added Wi-Fi roaming and channel hop counters.
    • connectivity.wifi.roaming_count increments when connected to the same
      configured network but the connected access point changed
    • connectivity.wifi.channel_hop_count increments when connected to the same
      network, but the channel changed
  • Added metric to distinguish between 2.4/5/6 GHz Wi-Fi frequency bands for
    easier device identification.
    • connectivity.wifi.frequency
    • connectivity.wifi.frequency_band
  • Added count of scanned Wi-Fi networks metric from statsd.
    • connectivity.wifi.scan_network_count
    • connectivity.wifi.scan_network_count.count
    • connectivity.wifi.scan_network_count.mean
  • Added low memory event reporting when low memory is reported by the System
    Server.
    • memory.low_mem_reported
  • Added slow I/O event metrics which contain a 24h count of the slow I/O events
    of a given type.
    • disk.slow_io_(read|write|unmap|sync|unknown)_24h_count
  • Added USB device attached/detached event reports. These will be reported when
    USB devices are attached or detached and will contain the full list of
    connected devices in each category.
    • usb.devices
    • usb.accessories
  • Added Wi-Fi OUI (Organizationally Unique Identifier) support. The OUI is
    queried via the Dumpster service using dumpsys wifi. Memfault will
    automatically calculate the manufacturer of the device based off of its OUI.
    • connectivity.wifi.ap_oui
  • Added Wi-Fi disconnected session metric. The event contains the disconnect
    reason, time connected, last RSSI and link speed as well as channel. These
    metrics are available in Android 12+.
    • wifi_disconnect_session
      • wifi.frequency-band-bucket
      • wifi.frequency-band
      • wifi.failure-code-name
      • wifi.failure-code
      • wifi.last-rssi
      • wifi.last-link-speed
  • Added low memory kill event reporting when applications are killed by the
    system due to low memory.
    • memory.lmk_kill_occurred

🚧 Fixes

  • Coalesced consecutive logcat "switch to" separators. This should reduce the
    spam where multiple log lines in a row are just buffer switches.
  • Fixed incorrect session end time. The session end will now be recorded when
    end is called, instead of at the heartbeat collection time.
  • Cleaned up continuous logcat "switch to" buffer logs to always append a
    newline. This avoids the "switch to" lines intermixing with normal output.
  • Fixed invalid boot id parsing in Bort Lite. Returns a zero'd UUID instead of
    "unknown" for the Linux boot id. Also, falls back to "reboot,permissiondenied"
    instead of "reboot,bort_unknown" for better clarity.
  • Fixed potential memory leak in UsageReporter found by LeakCanary.
  • Fixed session deadlock when the sessions rate limit is hit.
  • Increased rate limit defaults.
    • The Sessions rate limit was thought to be 125 every day, but ended up being
      125, and then 1 back every day due to the token bucket algorithm.
    • Similarly, the mar_file/client server mar file rate limit implied 500 files
      per hour but ended up being 24 a day once the limit was hit.
  • Ignored potential Room database migration failures. Fallback to destructive
    migration if the database migration fails on downgrade.

📈 Improvements

  • Bumped to reporting library 1.6.0.
  • Added support for Gradle testFixtures.
  • Changed Android Studio default project. Load the project root in Android
    Studio instead of MemfaultPackages/. MemfaultDumpstateRunner,
    MemfaultDumpster, and MemfaultStructuredLogd will now be visible in the
    IDE.
  • Updated MAR unspooling to use new data_upload_start_date device config
    variable to control what data should be uploaded.
  • Added leakcanary to the Bort, OTA, and Reporter apps to check for leaks.
  • Enabled Android lint.
  • Deleted log_buffer_expired counter metric. This was too spammy.

🏠 Internal

  • Fixed MetricsIntegrationTest race condition.

v5.4.2 - August 4, 2025

05 Aug 20:17

Choose a tag to compare

🚧 Fixes

  • Fixed a bug where bugreports would not always be cleaned up due to incorrect
    file permissions in the Bort app.

📈 Improvements

  • Refactored the device config handlers into clearer interfaces and
    implementations.
  • Added several more bugreport reply broadcasts (OK_REQUESTED, OK_GENERATING,
    OK_GENERATED, ERROR_GENERATED_TIMEOUT).
  • Added optional constraints on bugreport requests through a multibind
    interface.

v5.4.1 - July 22, 2025

05 Aug 20:24

Choose a tag to compare

Pre-release

🚀 New Features

  • Added new SDK Setting to upload collected Android Bugreports immediately
    outside of the periodic MAR batch task. Added new trace_id and extra_info
    fields to BugReportRequests.

🚧 Fixes

  • Fixed reporting of the new Wi-Fi metrics to visualize on the device timeline
    more appropriately. Fixed an error when recording null per second metrics.

📈 Improvements

  • Added some bort_cli.py comments.
  • Deleted unused code in Logger.kt.
  • Refactored Bugreport Intent logic.

v5.4.0 - July 1, 2025

05 Aug 20:24

Choose a tag to compare

v5.4.0 - July 1, 2025 Pre-release
Pre-release

🚀 New Features

  • Added 3 more logs-to-metrics parser types.
    • sum_matching captures 1 integer, and sums all captured values in the
      heartbeat.
    • distribution_minmeanmax captures 1 double, and generates a min/mean/max
      distribution for all captured values in the heartbeat.
    • string_property captures 1 string, and reports the latest value for that
      string.
  • Added tracking of the metered, temporarily unmetered, and roaming network
    capabilities in HRT.
    • Added a connectivity.metered.latest heartbeat metric for tracking metered
      network usage.
  • Added new disk wear and disk write Device Vital heartbeat metrics. eMMC/UFS
    lifetime estimation and version stats are collected from the Health HAL
    implementation, falling back to a hardcoded UFS or eMMC filepath if not
    implemented. Bytes written each heartbeat is collected by reading the sectors
    written value from /proc/diskstats for matching physical devices in
    /sys/block multiplied by the sector size to get a value in bytes.
    • disk_wear.<source>.lifetime_remaining_pct.latest captures the lifetime
      remaining estimation for type A flash in increments of 10%. The source can
      be one of: "mmc0", "624000.ufshc", or "HealthHAL".
    • disk_wear.<source>.lifetime_b_remaining_pct.latest captures the lifetime
      remaining estimation for type B flash in increments of 10%. The source can
      be one of: "mmc0", "624000.ufshc", or "HealthHAL".
    • disk_wear.pre_eol.latest captures the pre-EOL status of consumed reserved
      blocks, as "Normal", "Warning", or "Urgent".
    • disk_wear.version.latest captures the version as described from the vendor
      implementation of the Health HAL.
    • disk_wear.vdc.bytes_written captures the bytes written for that heartbeat.
  • Added per-app CPU usage metrics. The CPU usage percentage for each heartbeat
    is collected by parsing /proc/<pid>/stat/ for system and user time
    (stime + utime) divided by the total usage (sum of all fields from
    /proc/stat).
    • By default, the SDK will only create heartbeat metrics for a defined set of
      "interesting" processes. Please reach out to customer support to configure
      this set.
    • Otherwise, the top 10 processes exceeding the 50% CPU usage threshold will
      also be recorded. Please reach out to customer support to configure these
      thresholds.
  • Added support for Android 15.

📈 Improvements

  • Added parsers for more HRT batterystats data.
    • screen_doze captures whether the display is dozing in a low power state
      (link).
    • flashlight captures whether the flashlight was turned on.
    • bluetooth captures whether Bluetooth was enabled.
    • usb_data captures whether a USB connection was established (as reported by
      android.hardware.usb.action.USB_STATE).
    • cellular_high_tx_power captures whether the modem spent more of its time
      at the highest power level versus any other level.
    • nr_state captures the service level of the 5G network that's connected
      (link).
  • Updated comments on various batterystats fields. More improvements to come in
    clarifying the name and use of batterystats metrics!
  • Dumped any existing logs when continuous logging starts, to retain logs
    captured from before a reboot.
  • Added control over the maximum age of sampled data, to match the controls over
    unsampled data.
  • Added support for parsing the binary log buffers (events, security, stats)
    with continuous logs.
  • Modified dumpstate to write bugreports to /data/misc/MemfaultBugReports
    instead of to Bort's app dir. This is necessary for Android 15 support and CTS
    compliance to work around neverallow sepolicy rules. This also allowed
    deleting the custom bort_app_data_file app label for the Bort app.

🚧 Fixes

  • Added explicit Android System AID mappings for more consistent system UID
    attribution in tombstone and network stats parsing.
  • Added VPN and USB as explicitly defined network types using
    connectivity.network.
  • Fixed a bug in PhoneState where the unknown ??? state was reported as
    null.
  • Added exponential backoff for EAGAIN errors in continuous logs. Each write is
    fsync'd immediately after write to reduce the likelihood of data loss.
  • Added missing ignore.cil files for SDKs 32, 33, and 34.

🏠 Internal

  • Stopped running unit tests on release sources.
  • Migrated the SDK to communicate over a named domain (*.memfault.test) rather
    than localhost for local development.
  • Removed unneeded mockk init calls.
  • Added some tests for unknown fields in device config.
  • Refactored the unsampled holding area logic into a single class.
  • Differentiated some continuous logging logs for easier debugging.

v5.3.0 - February 14, 2025

01 Jul 22:31

Choose a tag to compare

🚀 New Features

  • Added new per-component total storage metrics. The total storage used
    (apps+cache+data+external) by an application can be recorded as a
    storage_<package>_bytes metric. Please feel free to contact us if you would
    like this enabled for applications in your project.
  • Added new mechanism to group operational crashes by package. The existing
    operational_crashes core metric can be divided into
    operational_crashes_<group> metrics, based off of the package names of the
    crashes. Please feel free to contact us if you would like this enabled for
    your project.
  • Added new DropBox count core metrics. The number of DropBox entries processed
    each heartbeat, grouped by Issue type, is now recorded as a
    drop_box_<type>_count metric. This makes identifying crashy devices even
    easier.
  • Added new .mean_time_in_state metric alongside .total_secs when the
    TIME_TOTALS aggregation is used with StateTrackers. The existing
    .total_secs metric is truncated between heartbeats, so it is only useful as
    a rough percentage comparison versus other states. The new
    .mean_time_in_state metric can be used to track the absolute time spent in a
    state, even across heartbeats, so its value can be used as an absolute number.

📈 Improvements

  • Returned a Session object when startSession is called to improve the API
    usability.
  • Removed SYSTEM_BOOT from the default list of 'other' collected DropBox
    Entries. After some field testing, this DropBox Entry was not consistently
    collected and did not contain useful information.
  • Silenced tags in continuous logs that did not match the filter spec.

🚧 Fixes

  • Fixed a logs-to-metrics bug where it could not parse logcat tags with spaces.
  • Fixed a harmless SELinux violation where memfault_structured_app could not
    access its own data directory.
  • Fixed a bug in bort_cli.py's validation-sdk-integration command where it
    wouldn't check the right location for system_ext sepolicy.
  • Fixed a continuous log bug where spaces in the tag would break parsing.

🏠 Internal

  • Migrated off junit5/jupiter back to junit4, at least until it has first party
    support from the Android team/
  • Added minio to the debug network security config for local development.

v5.2.0 - November 15, 2024

01 Jul 22:30

Choose a tag to compare

🚀 New Features

  • Logs to Metrics: Bort can scan all captured log files (including those not
    uploaded) for patterns, and record metrics based on the results. These can be
    configured in the dashboard. See
    documentation.
  • New Core Metric for CPU usage (cpu_usage_pct).
  • New Core Metrics for memory usage (memory_pct, memory_pct_max).
  • New Core Metric for storage usage (storage_used_pct).
  • New Core Metrics for network Usage (connectivity_*). These replace the
    previous network.* metrics - those will no longer be collected, unless the
    Network Usage: Collect Legacy Metrics is enabled in the dashboard.
  • New Core Metrics for thermals (thermal_*). These replace the previous
    temp.* metrics - those will no longer be collected, unless the
    Collect legacy thermal metrics is enabled in the dashboard.
  • Added a min_battery_voltage metric to report the lowest observed voltage.
  • New metric to capture the battery charge cycle count
    (battery.charge_cycle_count.latest) - this only works on Android 14+. Note
    that the previous metric added in 4.18.0 did not work.
  • New metrics (thermal_status_*) to capture thermal mitigation status.
  • New HRT metric (device-powered) capturing device shutdown/startup events.

📈 Improvements

  • Update the target SDK version to 34 (Android 14).
  • Updated to the default hardware version (ro.product.model) and software
    version (ro.build.version.incremental) to match current defaults for new
    projects.
  • Improve battery use attribution (including where usage would have previously
    been assigned to unknown).
  • Added dashboard controls for mar upload job constraints (battery, charging
    state).
  • Modified sepolicy to fix some memfault_structured_app violations.
  • Removed validation of the OTA application ID being configured, if OTA is not
    being used (if TARGET_USES_MFLT_OTA is unset).
  • reporting-lib-kotlin supports asynchronous usage, when constructing a
    ReportingClient.

🚧 Fixes

  • Fixed an issue which caused COUNT aggregations on non-numeric metric values
    to always return zero. This was introduced in 4.17.0.
  • Fixed a bug in the SDK validation tool (bort_cli.py) which caused it to fail
    when running on Windows.
  • Fixed a bug where the software/hardware version and device serial sysprops
    would not be updated immediately if changed remotely via SDK settings (a
    reboot may have been required for them to take effect).
  • MemfaultStructuredLogdApp will not crash if sepolicy is incorrectly
    configured.
  • Always captured metrics for app versions/sysprops, in an edge-case where the
    software version sysprop changed.

🏠 Internal

  • Updated mockk.
  • Removed bort internal log-to-disk functionality (this was not used).
  • Removed local storage from DevicePropertiesStore - forward all internal
    metrics using public APIs.
  • Bort no longer writes to the event log.
  • Refactored use of WorkManager.
  • Updated ktlint and reformatted some code.
  • Inject coroutine dispatchers in more places.
  • Record internal metrics for WorkManager job timing.
  • Fixed a flaky unit test (DevicePropertiesStoreTest).
  • Record zero values for per-app battery usage, for designated apps, instead of
    ignoring them (currently, Bort SDK apps only).

5.1.0

21 Oct 15:26

Choose a tag to compare

🚧 Fixes

  • Fixed Stability Device Vitals: a change to the way metrics are collected in
    Bort 4.17.0 meant that operational_hours would erroneously be set to zero,
    resulting in incorrect Stability Vital charts.

📈 Improvements

  • Added new screen on/off battery drain metrics:
    battery_screen_on_discharge_duration_ms, battery_screen_on_soc_pct_drop,
    battery_screen_off_discharge_duration_ms, battery_screen_off_soc_pct_drop.
    These will replace screen_off_battery_drain_%/hour/
    screen_on_battery_drain_%/hour in the future, once they are supported in the
    Memfault dashboard (to more accurately track battery drain across the fleet).