Skip to main content

batterylog

Linux laptop battery logging tool

A simple Python app with few dependencies that reads your sysfs-class-power numbers and records them to a local sqlite3 db with an "event" tag.

It was built to track suspend power usage for Framework laptops, but it should work on other Linux laptops that expose battery data through /sys/class/power_supply.

Install Status

Native Python packaging is the recommended install path:

  • pipx install batterylog
  • uv tool install batterylog
  • pip install batterylog

INSTALL.sh is the legacy install format. It remains supported for existing installs and upgrades.

Existing legacy command behavior is part of the upgrade contract: batterylog.py suspend, batterylog.py resume, and the zero-argument report should keep working for upgraded legacy installs. Existing legacy data is also part of that contract: upgrades should not silently relocate or replace /opt/batterylog/batterylog.db. If schema upgrades are needed in the future, they should happen transparently in place for the active database rather than requiring manual intervention.

Quick Start

Install batterylog, then run:

batterylog

For persistent system hook installs from this repo, the legacy helper still works:

git clone https://github.com/lhl/batterylog.git
cd batterylog
./INSTALL.sh

Usage

The default invocation reports the most recent complete suspend/resume cycle:

batterylog

Recent-cycle views:

batterylog history --limit 10
batterylog summary --limit 10
batterylog history --discharging-only

Administrative commands:

batterylog --help
batterylog --version
sudo batterylog install-hook
sudo batterylog uninstall-hook
batterylog migrate-db --from /opt/batterylog/batterylog.db --to /var/lib/batterylog/batterylog.db

Charging sessions are reported as battery gain instead of negative usage, and suspend/resume rows now record charger-state context for later inspection.

For legacy /opt installs, replace batterylog with /opt/batterylog/batterylog.py.

Data Storage

batterylog stores its data in a local sqlite database.

Default locations:

  • Packaged CLI use without a managed system hook: $XDG_STATE_HOME/batterylog/batterylog.db
  • If XDG_STATE_HOME is not set: ~/.local/state/batterylog/batterylog.db
  • Managed system hook installs from sudo batterylog install-hook: /var/lib/batterylog/batterylog.db
  • Legacy /opt installs: /opt/batterylog/batterylog.db

Path resolution precedence:

  • --db /path/to/batterylog.db
  • BATTERYLOG_DB=/path/to/batterylog.db
  • /etc/batterylog/config.toml written by install-hook
  • legacy sibling path for /opt/batterylog/batterylog.py
  • user default XDG state path

Custom paths:

  • One-off command: batterylog --db /path/to/batterylog.db
  • Per-shell/session override: BATTERYLOG_DB=/path/to/batterylog.db batterylog
  • Managed system hook with a custom DB: sudo batterylog install-hook --db /path/to/batterylog.db

What is stored:

  • one row per suspend or resume event
  • timestamp and battery identifier
  • battery cycle count and raw charge/current/voltage snapshot values
  • derived energy/power values used for reporting
  • battery status and line-power state when available

Automatic schema upgrades run in place on the active database. When a migration changes an existing DB, batterylog leaves a sibling .bak file behind.

Legacy Install

Make sure you meet the requirements, clone the repo, and run INSTALL.sh.

The legacy installer stages or refreshes /opt/batterylog, then runs the managed hook installer with the legacy DB path so logging continues to write to /opt/batterylog/batterylog.db.

Future installer work will keep this path functioning for upgrades and reinstalls, but new packaged releases should eventually be preferred over this legacy flow.

You can run /opt/batterylog/batterylog.py without any parameters and it will calculate the power usage from the last suspend/resume cycle:

$ /opt/batterylog/batterylog.py
Slept for 8.72 hours
Used 6.10 Wh (394.1 mAh), an average rate of 0.70 W (45.2 mA)
For your 53.67 Wh (3467.1 mAh) battery this is 1.30%/hr or 31.29%/day

This script looks for the first battery at /sys/class/power_supply/BAT*. It has currently only been tested with a Framework laptop, and some machines may not expose every value it expects. The tool is intentionally small and CLI-first: it stores the raw suspend/resume history in sqlite and exposes a few practical reporting commands on top.

Reports include secondary mAh and mA figures alongside Wh and W, which makes it easier to compare batterylog output against charge-based tools such as tlp-stat -b.

The new history and summary commands cover the most common review use cases without adding a heavier UI layer.

Native Python Installs

Common install commands:

pipx install batterylog
uv tool install batterylog
pip install batterylog

Ephemeral CLI checks:

uvx batterylog --help

For a persistent system suspend hook from a repo checkout, INSTALL.sh is still the simplest documented setup in this project today.

Requirements

  • Linux with battery data exposed through /sys/class/power_supply
  • systemd
  • Python 3.10+
  • sqlite3 CLI is optional, but useful for manual inspection/debugging

Packaging

  • Arch Linux AUR: batterylog-git packaged by Stetsed
  • Reference AUR packaging for the current tree: packaging/aur/PKGBUILD

Reference

Metadata

Release files for batterylog 0.2.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for batterylog 0.2.2
File Size Uploaded Provenance Actions
batterylog-0.2.2.tar.gz 42.7 kB Without provenance Details for batterylog-0.2.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for batterylog 0.2.2
File Interpreter ABI Platform Actions
batterylog-0.2.2-py3-none-any.whl Python 3 none any Details for batterylog-0.2.2-py3-none-any.whl

Total release size: 72.4 kB

Release files / batterylog-0.2.2.tar.gz

Download URL batterylog-0.2.2.tar.gz
Size 42.7 kB
Tags Source
SHA-256 checksum
How to use checksums
09ac9ae4b5339fd7ba5669d84327790eeb90d8ad80ade371a71755300836bf22
BLAKE2b-256 checksum
How to use checksums
053a2eae380105d1984662499dadb68e6b2f2f29031ad45e577548aef5cda221
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.2

Release files / batterylog-0.2.2-py3-none-any.whl

Download URL batterylog-0.2.2-py3-none-any.whl
Size 29.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0aa857fa4043fe2bba2321a37e88cb8af843a6d1f3cf4ef6f19c70440cf13a24
BLAKE2b-256 checksum
How to use checksums
e9c4553a773e82fbdd2a08feb8aceea637fb20c839c209d09d6e69e4b071caad
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.2

Security for batterylog 0.2.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page