Skip to content

About

PowerJoular monitors power consumption of multiple platforms and processes, on Windows, Linux and macOS

Topics

Resources

Stars

120 stars

Watchers

4 watching

Forks

Latest commit

Β 

History

245 Commits

Folders and files

Repository files navigation

Joular Project PowerJoular ⚑

License: GPL v3 Ada

PowerJoular Logo

PowerJoular is a command line tool that monitors, in real time, the power consumption of hardware components, processes and software, on Windows, Linux, macOS and FreeBSD.

Detailed documentation (including user and reference guides) is available at: https://joular.github.io/powerjoular/.

πŸš€ Features

  • Monitor the power consumption of the CPU and the GPU of PCs and servers
  • Monitor the power consumption of Raspberry Pi and Asus Tinker Board devices
  • Monitor the power consumption of Macs, Apple Silicon and Intel
  • Monitor the power consumption of one process, or of one application and every process of it
  • Monitor the power consumption from inside a virtual machine
  • Export the power data to the terminal, to CSV files, and to a shared memory ring buffer
  • Ships with a systemd service (daemon) to monitor the machine continuously
  • Low overhead: written in Ada, compiled to native code, one binary with nothing to install alongside it

πŸ“‘ Supported platforms

PowerJoular runs on Linux, macOS, Windows and FreeBSD, on PCs, servers, Macs, and single-board computers.

Component Hardware OS Method
CPU Intel (since Sandy Bridge), AMD (Ryzen, EPYC) Linux RAPL through the powercap sysfs
CPU Intel, AMD Windows RAPL through the Energy Meter Interface (nothing to install), or the RAPL MSR through PawnIO or Hubblo's RAPL driver
CPU Raspberry Pi, Asus Tinker Board Linux Research-based regression power models
CPU Apple Silicon (M series), Intel Macs macOS powermetrics, installed with macOS
CPU Intel, AMD FreeBSD RAPL through the MSR registers, read with the cpuctl(4) driver
GPU Nvidia cards Linux, Windows, FreeBSD NVML, installed with the Nvidia driver
GPU AMD cards Linux amdgpu hwmon sysfs
GPU AMD cards Windows ADLX, installed with the AMD driver
GPU Apple Silicon (M series) macOS powermetrics, installed with macOS
Whole machine Any of the above, from inside a virtual machine Linux, macOS, Windows, FreeBSD A file the host writes the power to

On macOS, both chips are read from powermetrics, which reports the power drawn over each cycle. Apple Silicon Macs give their CPU and the GPU built into the same chip. Intel Macs give the CPU only.

The supported single-board computers are the Raspberry Pi models 5B, 400, 4B, 3B+, 3B, 2B, 1B+, 1B and Zero W, and the Asus Tinker Board (S). Every revision of each model is supported, though the power model was trained on one particular revision, on which the accuracy is at its best.

PowerJoular does the energy and CPU usage measuring through two Ada libraries we developed:

  • Joular Core: for CPU and GPU energy and power consumption.
  • CPU Load: for CPU usage for the whole system, a specific PID, and a specific application (all its PIDs).

Required privileges

  • Linux, PC or server: reading RAPL files needs elevated privileges on the recent kernels (5.10 and newer), so run sudo powerjoular, or give read rights to the files. See this issue.
  • Windows: if using Energy Meter Interface (EMI), then there is no special privileges or driver needed. Otherwise, we need specific RAPL driver, such as PawnIO or Hubblo's RAPL driver. The easiest way to get a signed version installed is through the PawnIO or the Scaphandre installer for Hubblo's driver.
  • macOS: powermetrics only runs as the superuser, so run sudo powerjoular. Without it, the sources are simply reported as not available. Reading the CPU time of a process belonging to another user also needs root, so -p and -a on someone else's process need sudo too.
  • FreeBSD: the RAPL registers are read through the cpuctl(4) driver, a module not in the GENERIC kernel: load it with kldload cpuctl (or cpuctl_load="YES" in /boot/loader.conf), then run sudo powerjoular, or run it as a member of the kmem group.
  • Raspberry Pi and GPU readings: no special privileges needed.

PowerJoular uses Joular Core, which, on Windows, tries the Energy Meter Interface first, then PawnIO, then Hubblo's driver, keeping the first that answers. Nothing has to be configured for that. Setting the JOULARCORE_WINDOWS_RAPL environment variable picks one instead of trying them in turn. Valid options: emi, pawnio or hubblo.

πŸ’‘ Usage

Run powerjoular. With no option, it prints the power of the machine on the terminal, once a second, until Ctrl+C.

sudo powerjoular

The following options are available:

Option What it does
-h Show the help message
-v Show the version number
-t Print the power data on the terminal
-d Print what the machine offers on start up
-p pid Monitor the process with this number
-a appName Monitor this application, and every process of it
-f filename Add the power data to this file
-o filename Keep only the latest power data in this file (the file is overwritten every second)
-r Write the power data to a shared memory ring buffer
-m filename Read the power of this machine from the file the host writes, when running inside a virtual machine
-s format Format of that file, either powerjoular or watts

Options can be mixed, i.e., powerjoular -tp 144 monitors the process 144 and prints it on the terminal.

Monitoring a process or an application writes two CSV files: the given filename for the whole system, and the same name with the process number or the application name added to it for the process or the application.

Exporting to CSV

-f adds a row every second and starts the file with a header:

Timestamp,CPU Usage,Total Power,CPU Power,GPU Power
1756681930,0.2460,18.4500,15.2000,3.2500

The file of a monitored process or application have the CPU usage and the power of that process or application:

Timestamp,CPU Usage,CPU Power
1756681930,0.0310,1.8400

-o writes the latest measurement only: the file is rewritten every second and carries no header, which is a good option for another program polling it for the current value.

The time of the measurement is a Unix timestamp, the same one written to the ring buffer.

PowerJoular refuses to write a CSV file if a symbolic link is already at its path. This is a basic check, not a guarantee, as the link can still be swapped in after the check. When running PowerJoular as root, write the CSV files to a folder only root can write to (such as /run/powerjoular for the service), not to a shared folder such as /tmp.

Both value columns hold -1.0000 for a second where the monitored process could not be read at all: it has stopped, it was never running, or the system does not let us get the information needed. That is not the same as 0.0000, which means a process that was read and used no CPU time.

-a is the exception: an application with no running process at all is reported as 0.0000 and not as -1.0000, because we can't tell apart a name that matches nothing from a name whose processes did not use any CPU time. -1.0000 still appears for -a when a process is found but the system does not let us read it.

Exporting to a shared memory ring buffer

-r writes every measurement to a shared memory ring buffer, that any program on the same machine can read with low latency.

OS Where the area lives
Linux /dev/shm/powerjoular
Windows %PROGRAMDATA%\powerjoular, i.e. C:\ProgramData\powerjoular
macOS /tmp/powerjoular
FreeBSD /tmp/powerjoular

The area is 248 bytes, in the byte order of the machine: a counter of 8 bytes, then 5 entries of 48 bytes each.

Field Type Meaning
timestamp unsigned, 8 bytes Unix time in seconds
cpu_power IEEE double CPU power in watts
gpu_power IEEE double GPU power in watts
total_power IEEE double CPU plus GPU power in watts
cpu_usage IEEE double Load of the machine, from 0.0 to 1.0
pid_app_power IEEE double Power of the monitored process or application in watts, zero when none is monitored, and -1 when the one monitored could not be read

A measurement goes in the entry the counter points at (counter mod 5), and the counter is raised afterwards. A reader follows the counter to know when a new measurement has landed, and the timestamps to know how old each entry is.

Only one PowerJoular should write to the ring buffer at the same time. Two runs using -r at once each keep a counter of their own, so a reader sees the entries of both interleaved and the counter moving backwards. The ring buffer is created every time PowerJoular starts: a file left at that path, by an earlier run or by anyone else, is deleted first, so PowerJoular never writes into a file it did not create. It is readable by everyone and writable only by the user running PowerJoular. A reader that mapped the file has to map it again when PowerJoular restarts. When the file cannot be created, PowerJoular carries on without the ring buffer.

Monitoring inside a virtual machine

The hardware cannot be measured from inside a virtual machine, so the power value has to come from the host, with these steps:

  • On the host, monitor power consumption of the virtual machine itself, and write its power to a file shared with the guest. You can use any program to monitor the VM's power consumption, but also PowerJoular.
  • In the guest, run PowerJoular with -m pointing at the file the host writes and -s indicating the file format.

The two formats -s takes:

  • powerjoular: the three column CSV that -o writes for a monitored process, timestamp, CPU load and power, where the power is the third column.
  • watts: a file holding the power in watts and nothing else.

-s says what is inside the file, so it goes together with the program the host runs.

A negative power in the file, such as the -1.0000 PowerJoular writes for a process it cannot read, is ignored: the last power read is kept, as it is when the file cannot be read at all.

With PowerJoular on the host. Monitor the specific process of the virtual machine, and not the whole system:

powerjoular -p 1234 -o /shared/vm-power.csv

This writes two files, and the one to share is the one with the process number: it alone holds the power of the virtual machine, while the other one holds the power of the whole host.

powerjoular -m /shared/vm-power.csv-1234.csv -s powerjoular -t

With another program on the host. Have it write the power in watts and nothing else, then read that file with the watts format:

powerjoular -m /shared/vm-power.txt -s watts -t

πŸ“¦ Installation

PowerJoular is one binary that can be copied to any machine of the same architecture and run as it is.

Ready-made packages (binaries, RPM and DEB packages) are released in our repository release page and in the build workflow.

Easy-to-use installation scripts are also available in the installer folder:

  • installer/bash-installer/build-install.sh: builds the program and installs the binary in /usr/bin along with the systemd service.
  • installer/bash-installer/uninstall.sh: removes both again.

Those scripts and the packages are for Linux. On macOS, the build workflow publishes one binary per chip, powerjoular-macos-arm64 for Apple Silicon and powerjoular-macos-x86_64 for Intel Macs: take the one of your Mac and copy it where you want it, or build it as described below. On FreeBSD, it publishes powerjoular-freebsd-amd64, built on FreeBSD 14 so it also runs on FreeBSD 15.

Which Linux build to use

PowerJoular binary runs on the glibc version it was build on or a new one (but not and older one), so more than one build is published and every file says which glibc version was used:

File Architectures Runs on
powerjoular-glibc-2.35, powerjoular-glibc-2.35_*.deb, powerjoular-glibc-2.35-*.rpm x86_64 and aarch64 Ubuntu 22.04 and newer, Debian 12 and newer, Raspberry Pi OS bookworm and newer, Fedora 36 and newer
powerjoular-glibc-2.34, powerjoular-glibc-2.34_*.deb, powerjoular-glibc-2.34-*.rpm x86_64 only The same, and also RHEL 9, AlmaLinux 9, Rocky 9 and CentOS Stream 9

Take the 2.34 build if you are unsure, or if the other version gives you an version 'GLIBC_2.35' not found. Both are the exact same program with the only difference being the C library (glibc) they were linked against.

πŸ’Ύ Compilation

PowerJoular is written in Ada and needs a modern Ada compiler such as GNAT, together with the Joular Core and CPU Load libraries.

With Alire

Alire fetches the two libraries on its own, so this is the shortest way:

alr build

The binary lands in bin/powerjoular.

With GNAT and GPRBuild

Check out the two libraries next to this repository, then point GPRBuild at them:

gprbuild -P powerjoular.gpr -aP../joularcore -aP../cpuload -p

To build for another OS than the one you are on, set PJ_OS to linux, macos, windows or freebsd:

gprbuild -P powerjoular.gpr -aP../joularcore -aP../cpuload -XPJ_OS=windows -p

Linux, macOS, Windows and FreeBSD are each detected on their own, from the target GPRBuild identifies.

On FreeBSD, pkg install gprbuild brings GPRBuild and GNAT, whose folder /usr/local/gnat12/bin has to be added to PATH.

A binary with no dependencies at all

By default the Ada runtime and libgcc are carried inside the binary, which is enough to copy it to another machine of the same architecture and run it there. To leave nothing at all outside it, including the C library:

gprbuild -P powerjoular.gpr -aP../joularcore -aP../cpuload -XPOWERJOULAR_LINKING=full -p

On Linux and FreeBSD, a fully static binary cannot load a library while it runs, so the Nvidia graphic card readings, which do exactly that, are lost with this option. The processor readings are not affected, and PowerJoular carries on without the GPU rather than failing.

On macOS, Apple ships no static C library, so this option does nothing: the binary is built the same way it is by default, which already carries the Ada runtime and libgcc inside it.

βŒ› Systemd service (Linux only)

A systemd service is provided in the systemd folder, and is installed by the Linux packages. It runs PowerJoular with -o, writing the latest power data to /run/powerjoular/powerjoular-service.csv. The folder is made by systemd when the service starts and removed when it stops, and anyone can read the file in it.

sudo systemctl start powerjoular.service
sudo systemctl enable powerjoular.service

✨ What changed in version 2

Version 2 does the measuring using the Joular Core and CPU Load libraries instead of its own code, which also include macOS, Windows and FreeBSD support.

  • New: -r writes the power data to a shared memory ring buffer.
  • Removed: -k, which measured a process from its threads. It was experimental, and the process readings no longer need it.
  • Removed: -l, which picked the linear power models of the single-board computers, has been removed. The default and only models used now are the polynomial models, which are much more accurate and their overhead is minimal.

Other main differences:

  • The CSV files hold four digits after the dot instead of the fourteen. The columns and the header have been renamed, with Timestamp and CPU Usage.
  • The energy a RAPL processor reports is divided by how long the cycle actually took, rather than assumed to be exactly one second. On a machine running late, the watts reported are now the watts drawn.
  • A file that cannot be written to, a power source that stops answering, or a ring buffer that cannot be opened is reported once and the monitoring continues.

πŸ“‘ Cite this work

To cite our work in a research paper, please cite our paper in the 18th International Conference on Intelligent Environments (IE2022).

  • PowerJoular and JoularJX: Multi-Platform Software Power Monitoring Tools. Adel Noureddine. In the 18th International Conference on Intelligent Environments (IE2022). Biarritz, France, 2022.
@inproceedings{noureddine-ie-2022,
  title = {PowerJoular and JoularJX: Multi-Platform Software Power Monitoring Tools},
  author = {Noureddine, Adel},
  booktitle = {18th International Conference on Intelligent Environments (IE2022)},
  address = {Biarritz, France},
  year = {2022},
  month = {Jun},
  keywords = {Power Monitoring; Measurement; Power Consumption; Energy Analysis}
}

πŸ“° License

PowerJoular is licensed under the GNU GPL 3 license only (GPL-3.0-only).

Copyright (c) 2020-2026, Adel Noureddine. All rights reserved. This program and the accompanying materials are made available under the terms of the GNU General Public License v3.0 only (GPL-3.0-only) which accompanies this distribution, and is available at: https://www.gnu.org/licenses/gpl-3.0.en.html

Author : Prof. Adel Noureddine

About

PowerJoular monitors power consumption of multiple platforms and processes, on Windows, Linux and macOS

Topics

Resources

Stars

120 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages