Overview
PowerJoular is a command line software to monitor, in real time, the power consumption of software and hardware components, across multiple platforms and virtual machines.
PowerJoular is part of the
project.
PowerJoular can monitor the power consumption, in real time, of the CPU and the GPU in general, and also for a specific application (through its name or PID). It works on Linux, Windows, macOS and FreeBSD, on multiple architectures (x86_64, ARM) and devices (computers, servers, Macs, Raspberry Pi, etc.).
The official website of PowerJoular is: https://www.noureddine.org/research/joular/powerjoular.
Features
- Monitor power consumption of CPU and GPU of PC/servers
- Monitor power consumption of Macs, Apple Silicon and Intel
- Monitor power consumption of Raspberry Pi and Asus Tinker Board devices
- Monitor power consumption inside virtual machines
- Monitor power consumption of individual applications or processes
- Expose power consumption to the terminal, CSV files, and a shared memory ring buffer
- Provides a systemd service (daemon) to continuously monitor power of devices on Linux
- Low overhead (written in Ada and compiled to native code, one binary with nothing to install alongside it)
What changed in version 2
Version 2 does the measuring using two Ada libraries we developed, Joular Core and CPU Load, instead of its own code.
This also brings Windows, macOS and FreeBSD support, and AMD graphic cards (Nvidia cards are now read through NVML instead of nvidia-smi).
- New:
-rwrites 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. The polynomial models are now the only ones used, as they are much more accurate and their overhead is minimal. - Removed:
-c, which wrote the timestamps in milliseconds.
Other main differences:
- The CSV files start with a Unix timestamp in seconds instead of a date and time, and hold four digits after the dot instead of fourteen. The columns and the header have been renamed, with Timestamp and CPU Usage.
- The terminal no longer shows the difference of power consumption from the last metric, and Ctrl+C no longer prints the total energy consumed.
- On Linux, the CPU power is the RAPL package domain only. Version 1 used the Psys domain when there was one, or added the DRAM domain to the package, so the values can be lower than with version 1.
- 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 busy machine where a cycle takes longer than one second, the watts reported are now the watts drawn.
- A file that cannot be written to, or a ring buffer that cannot be opened, is reported once and the monitoring continues. A power source that stops answering reads 0 until it answers again.
- The systemd service writes to
/run/powerjoular/powerjoular-service.csvinstead of/tmp, and runs with reduced privileges.
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 : Adel Noureddine
Supported Platforms
PowerJoular monitors the following platforms:
- PC/Servers using a RAPL supported Intel processor (since Sandy Bridge) or a RAPL supported AMD processor (since Ryzen, including EPYC), and optionally an Nvidia or an AMD graphic card.
- Macs, with Apple Silicon (M series) or Intel processors.
- Raspberry Pi devices (multiple models) and Asus Tinker Board.
- Inside virtual machines in all supported host platforms.
PowerJoular works on Linux, Windows, macOS and FreeBSD.
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 of the whole system, of a specific PID, and of a specific application (all its PIDs).
On Linux PC/Servers, PowerJoular uses powercap Linux interface to read RAPL (Running Average Power Limit) energy consumption, for Intel and AMD processors.
PowerJoular reads the RAPL package domain (cores, integrated graphics, memory controller and last level caches). On a server with several sockets, only the first one is measured.
On Windows PC/Servers, PowerJoular reads the same RAPL package counter in one of three ways, and keeps the first one that answers:
- The Energy Meter Interface (EMI), built into Windows 11. Nothing to install.
- The RAPL registers through the PawnIO driver.
- The RAPL registers through Hubblo’s RAPL driver.
Setting the JOULARCORE_WINDOWS_RAPL environment variable to emi, pawnio or hubblo picks one instead of trying them in turn. Nothing has to be configured otherwise.
On FreeBSD PC/Servers, PowerJoular reads the same RAPL package counter from the registers of the processor, through the cpuctl(4) driver.
On macOS, PowerJoular uses powermetrics, which is installed with macOS and 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 whole chip: cores, integrated graphics and system agent).
For the GPU, PowerJoular supports:
- Nvidia graphic cards on Linux, Windows and FreeBSD, through NVML, which is installed with the Nvidia driver.
- AMD graphic cards on Linux, through the hwmon sysfs of the amdgpu driver.
- AMD graphic cards on Windows, through ADLX, which is installed with the AMD driver.
- The GPU of Apple Silicon Macs, through
powermetrics.
On virtual machines, PowerJoular requires two steps:
- Installing PowerJoular itself or another power monitoring tool in the host machine. Then monitoring the virtual machine power consumption every second and writing it to a file (to be shared with the guest VM).
- Installing PowerJoular in the guest VM, then running PowerJoular while specifying the path of the power file shared with the host and its format.
On Raspberry Pi and Asus Tinker Board, PowerJoular uses its own research-based empirical regression models to estimate the power consumption of the ARM processor.
The supported list of Raspberry Pi and Asus Tinker Board models are listed below. We support all revisions of each model lineup. However, the model is generated and trained on a specific revision (listed between brackets), and the accuracy is best on this particular revision.
We currently support the following Raspberry Pi models and Asus Tinker Board models:
- Model Zero W (rev 1.1), for 32 bits OS
- Model 1 B (rev 2), for 32 bits OS
- Model 1 B+ (rev 1.2), for 32 bits OS
- Model 2 B (rev 1.1), for 32 bits OS
- Model 3 B (rev 1.2), for 32 bits OS
- Model 3 B+ (rev 1.3), for 32 bits OS
- Model 4 B (rev 1.1, and rev 1.2), for both 32 bits and 64 bits OS
- Model 400 (rev 1.0), for 64 bits OS
- Model 5 B (rev 1.0), for 64 bits OS
- Asus Tinker Board (S)
The models listed for 32 bits OS are also used on a 64 bits OS.
| Platform | Supported OS | Based on | Supported Architecture |
|---|---|---|---|
| Raspberry Pi | Linux | Our regression models | ARM |
| Asus Tinker Board | Linux | Our regression models | ARM |
| Linux PC/Server | Linux | RAPL (using powercap), Nvidia NVML, AMD hwmon sysfs | x86, x86_64 |
| Windows PC/Server | Windows | RAPL (using EMI, PawnIO or Hubblo’s driver), Nvidia NVML, AMD ADLX | x86_64 |
| FreeBSD PC/Server | FreeBSD | RAPL (using cpuctl), Nvidia NVML | x86_64 |
| Mac | macOS | powermetrics | Apple Silicon (ARM), Intel (x86_64) |
| Virtual Machine | Linux, Windows, macOS or FreeBSD guest, any host | Host’s architecture (RAPL, regression models, others) | x86, x86_64, ARM |
Required privileges
Without the privileges below, and with no graphic card to read, PowerJoular finds no power source and stops. With a graphic card, it carries on and the CPU power reads 0 (-d shows what can be measured).
- 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: with the Energy Meter Interface (EMI), no special privileges or driver are needed. Otherwise, a RAPL driver is needed: PawnIO, which needs PowerJoular to run from a terminal with administrative rights, or Hubblo’s RAPL driver, which does not. The easiest way to get a signed version of Hubblo’s driver is through the Scaphandre installer. Reading the CPU time of a process belonging to another user also needs a terminal with administrative rights, so
-pand-aon someone else’s process need it too. - macOS:
powermetricsonly runs as the superuser, so runsudo powerjoular. Without it, PowerJoular finds no power source and stops. Reading the CPU time of a process belonging to another user also needs root, so-pand-aon someone else’s process needsudotoo. - FreeBSD: the RAPL registers are read through the
cpuctl(4)driver, a module not in the GENERIC kernel: load it withkldload cpuctl(orcpuctl_load="YES"in/boot/loader.conf), then runsudo powerjoular, or run it as a member of thekmemgroup. - Raspberry Pi, and GPU readings on Linux, Windows and FreeBSD: no special privileges needed.
Installation
PowerJoular is written in Ada and can be easily compiled, and its unique binary added to your system PATH. The binary can be copied to any machine of the same architecture and run as it is.
Ready-made binaries and packages are released in our GitHub repository release page and in the build workflow:
- Linux: binaries, Debian installation packages (.deb, for Debian, Ubuntu, Raspberry Pi OS, etc.) and RPM packages (.rpm, for Fedora, RHEL, etc.), for x86_64 and aarch64.
- Windows:
powerjoular.exe, for x86_64. - macOS: one binary per chip,
powerjoular-macos-arm64for Apple Silicon andpowerjoular-macos-x86_64for Intel Macs. Take the one of your Mac, copy it where you want it, and make it executable withchmod +x. - FreeBSD:
powerjoular-freebsd-amd64, for x86_64, built on FreeBSD 14 so it also runs on FreeBSD 15. Copy it where you want it, and make it executable withchmod +x.
Which Linux build to use
The PowerJoular binary runs on the glibc version it was built on or a newer one (but not an 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 one gives you a version 'GLIBC_2.35' not found error.
Both are built from the same code, the difference being the C library (glibc) they were linked against.
On a 32 bits ARM board or OS (such as the Raspberry Pi Zero W, 1 and 2, the Asus Tinker Board, or a 32 bits Raspberry Pi OS), no ready-made build is published, so compile PowerJoular (see Compilation).
The Linux packages install the binary in /usr/bin along with the systemd service (see Systemd Service).
Installation scripts
Easy-to-use installation scripts are available in the installer/bash-installer folder.
Just open the folder and run the appropriate file to build and install, or uninstall, the program and systemd service.
build-install.sh: will build (using Alire if it is installed, otherwisegprbuild) and install the program binary to/usr/binand the systemd service. It requires having installed Alire, or GNAT and gprbuild with the Joular Core and CPU Load repositories checked out next to the PowerJoular folder (see Compilation).uninstall.sh: stops the systemd service, and deletes the program binary and the systemd service.
These scripts and the packages are for Linux. A PKGBUILD for Arch Linux is also available in the installer/aur folder.
Quick Usage
To use PowerJoular, just run the command powerjoular (or powerjoular.exe on Windows).
On Linux PC/servers, PowerJoular uses Intel’s RAPL through the Linux powercap sysfs, and therefore requires root/sudo access on the latest Linux kernels (5.10 and newer): sudo powerjoular.
On macOS, powermetrics also requires root/sudo access: sudo powerjoular.
On FreeBSD, reading RAPL needs the cpuctl module (kldload cpuctl) and root/sudo access: sudo powerjoular.
On Windows and Raspberry Pi, no special access is needed, except with the PawnIO driver on Windows, which needs a terminal with administrative rights (see Supported Platforms).
By default, the software will show the total power consumption, and the power of the CPU and of the GPU (when there is one), on the terminal, every second, until Ctrl+C:
Total Power: 18.45 Watts (CPU: 15.20 W, GPU: 3.25 W)
To monitor a specific application, just run PowerJoular with the -a appName parameter, or with -p pid for a specific process.
The terminal then shows the CPU usage and the CPU power of the application or the process, with the ones of the whole system between brackets:
Application monitoring: CPU: 3.10 % (24.60 %) 1.92 Watts (15.20 Watts)
To save the power data to a CSV file, add -f filename, or -o filename to keep only the latest values in the file.
When a file (or the ring buffer, with -r) is given, PowerJoular no longer prints on the terminal: add -t to print there too.
PowerJoular is a powerful tool with many functionalities that can be accessed using specific parameters. Check the Command Line Options page for the detailed list.
Compilation
PowerJoular is written with Ada, and requires a modern Ada compiler, such as GNAT, together with the Joular Core and CPU Load libraries.
PowerJoular depends on the following libraries and tools for certain of its functions, but can function without them:
- Linux powercap with RAPL support: for monitoring power consumption of Intel and AMD processors
- The Energy Meter Interface, PawnIO or Hubblo’s RAPL driver: for monitoring power consumption of Intel and AMD processors on Windows
- The
cpuctldriver (kldload cpuctl): for monitoring power consumption of Intel and AMD processors on FreeBSD powermetrics(installed with macOS): for monitoring power consumption of Macs- NVML (installed with the Nvidia driver): for monitoring power consumption of Nvidia graphic cards
- The amdgpu driver (its hwmon sysfs files): for monitoring power consumption of AMD graphic cards on Linux
- ADLX (installed with the AMD driver): for monitoring power consumption of AMD graphic cards on Windows
None of them is needed to compile PowerJoular: they are looked for when PowerJoular starts.
On a modern Linux distribution, just install the GNAT compiler (and GPRBuild), usually available from the distribution’s repositories:
Fedora:
sudo dnf install fedora-gnat-project-common gprbuild gcc-gnat
Debian, Ubuntu or Raspberry Pi OS:
sudo apt install gnat gprbuild
For other distributions, use their package manager to download the compiler, or check this article for easy instruction for various distributions, including RHEL and its clones which does not ship with Ada support in GCC.
On FreeBSD, use GNAT 15 or newer, which Alire also takes from PATH: pkg install gprbuild gnat15 brings GPRBuild and GNAT 15, whose folder /usr/local/gnat15/bin has to be added to PATH. GNAT 12, which pkg install gprbuild uses, crashes while compiling Joular Core.
On Windows and macOS, the easiest way is to install Alire, which also downloads the GNAT compiler and GPRBuild.
Compilation with the GNAT compiler and GPRBuild
Check out the Joular Core and CPU Load repositories next to the PowerJoular folder, then point GPRBuild at them:
gprbuild -P powerjoular.gpr -aP../joularcore -aP../cpuload -p
The PowerJoular binary will be created in the bin/ folder.
Linux, macOS, Windows and FreeBSD are each detected on their own, from the target GPRBuild identifies.
To build for another OS than the one you are on, use a cross compiler for that OS (given to GPRBuild with --target), and set PJ_OS to linux, macos, windows or freebsd:
gprbuild -P powerjoular.gpr -aP../joularcore -aP../cpuload -XPJ_OS=windows -p
Compilation with Alire
If you have Alire installed, you can use it to build PowerJoular with:
alr build
Alire fetches the two libraries on its own, so this is the shortest way.
The PowerJoular binary will be created in the bin/ folder.
Static and dynamic linking
By default, the project will statically link the Ada runtime and libgcc inside the binary, and therefore the PowerJoular binary can be copied to any compatible system and used as-is.
To build with dynamic linking of the Ada runtime, replace the static switch with the shared one in the powerjoular.gpr file (removing it is not enough, as GNAT links its runtime statically by default):
package Binder is
for Switches ("Ada") use ("-shared");
end Binder;
To leave nothing at all outside the binary, including the C library, build with POWERJOULAR_LINKING set to full:
gprbuild -P powerjoular.gpr -aP../joularcore -aP../cpuload -XPOWERJOULAR_LINKING=full -p
On Linux and FreeBSD, a fully static binary cannot reliably load a library while it runs, so the Nvidia graphic card readings, which load NVML while running, can’t be counted on 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.
Command Line Options
To use PowerJoular, just run the command powerjoular.
On Linux PC/servers, PowerJoular uses Intel’s RAPL through the Linux powercap sysfs, and therefore requires root/sudo access on the latest Linux kernels (5.10 and newer): sudo powerjoular.
On macOS, powermetrics also requires root/sudo access: sudo powerjoular.
On FreeBSD, reading RAPL needs the cpuctl module (kldload cpuctl) and root/sudo access: sudo powerjoular.
By default, the software will show the total power consumption, and the power of the CPU and of the GPU (when there is one), on the terminal, every second, until Ctrl+C.
The following options are available:
-h: show the help message-v: show version number-p pid: specify a particular PID to monitor-a appName: specify a particular application name to monitor (will monitor all PIDs of the application)-f filename: save monitoring data to the given filename path, in CSV format-o filename: save only last monitoring data to the given filename path (file overwritten with only latest power measures)-t: print the power data to the terminal-d: print the available hardware components on start up (the versions of PowerJoular and its libraries, whether the CPU and the GPU can be measured, and the path of the ring buffer with-r)-r: write the power data to a shared memory ring buffer, for another program to read with low latency-m filename: specify a filename for the power consumption of the virtual machine (written by the host)-s format: specify the format of the VM power, eitherpowerjoularformat (generated with the-ooption for a monitored process: 3 columns csv file with the 3rd containing the power consumption of the VM), orwattsformat (1 column containing just the power consumption of the VM)
You can mix options, i.e., powerjoular -tp 144 will monitor PID 144 and will print to the terminal.
A few rules apply when mixing them:
-pand-acannot be used together.- With
-f,-oor-r, the terminal is only used if-tis also given. -mand-sgo together, and the file given to-mmust already hold a power value in that format when PowerJoular starts.
When monitoring a process (-p) or an application (-a), -f and -o write two CSV files: the given filename for the whole system, and the same name with the PID or the application name added to it, for the process or the application.
For example, powerjoular -p 144 -f power.csv writes power.csv and power.csv-144.csv.
See Exporting Power Data for the content of the CSV files and of the ring buffer.
On Windows, the JOULARCORE_WINDOWS_RAPL environment variable picks how the RAPL counter is read (emi, pawnio or hubblo), instead of trying the three in turn (see Supported Platforms).
Exporting Power Data
PowerJoular exports its power data to the terminal, to CSV files, and to a shared memory ring buffer.
The CSV files and the ring buffer can be used at the same time, and with the terminal when -t is given.
Terminal
With no option, PowerJoular prints the power of the machine on the terminal, once a second, on the same line:
Total Power: 18.45 Watts (CPU: 15.20 W, GPU: 3.25 W)
The GPU is only shown when one was found.
When monitoring a process (-p) or an application (-a), the terminal shows its CPU usage and its CPU power, with the CPU usage and the CPU power of the whole system between brackets (the GPU is not shown):
PID monitoring: CPU: 3.10 % (24.60 %) 1.92 Watts (15.20 Watts)
Application monitoring: CPU: 3.10 % (24.60 %) 1.92 Watts (15.20 Watts)
n/a is shown when the process or the application could not be read.
When the output is not a terminal (a file or a pipe), each measurement is printed on its own line.
CSV files
-f adds a row every second to the file, and starts a new or empty file with a header (an existing file is added to, not emptied):
Timestamp,CPU Usage,Total Power,CPU Power,GPU Power
1756681930,0.2460,18.4500,15.2000,3.2500
The time of the measurement is a Unix timestamp in seconds, the CPU usage goes from 0.0 to 1.0, and the power is in watts.
When monitoring a process or an application, a second file is written, with the PID or the application name added to the given filename (power.csv-144.csv for -p 144 -f power.csv).
It has the CPU usage and the power of that process or application:
Timestamp,CPU Usage,CPU Power
1756681930,0.0310,1.9154
-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.
Both value columns of the process file 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 processes of the application are found but the system does not let us read any of them.
A process we cannot read is left out of the sum when others of the application can be read, so the value is then short by what that process used.
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.
A file that cannot be written to is reported once, and the monitoring goes on: PowerJoular tries the file again every second, and writes to it again once it can.
Shared memory ring buffer
-r writes every measurement to a shared memory ring buffer, which 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 288 bytes, in the byte order of the machine: a counter of 8 bytes, then 5 entries of 56 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 | CPU power of the monitored process or application in watts, zero when none is monitored, and -1 when the one monitored could not be read |
pid_app_usage | IEEE double | Load of the monitored process or application, from 0.0 to 1.0, 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.
On Linux, macOS and FreeBSD, a second run using -r replaces the file, and the first one keeps writing to the old file, which only the readers that mapped it before still see.
On Windows, the second run cannot replace the file the first one holds open, and carries on without the ring buffer.
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. On Windows, the reader has to close the file first, otherwise PowerJoular cannot replace it and carries on without the ring buffer. The file is left in place when PowerJoular stops, so the last entries can still be read. When the file cannot be created, PowerJoular carries on without the ring buffer.
Systemd Service
A systemd service is provided for Linux and can be installed (by copying powerjoular.service in systemd folder to /usr/lib/systemd/system/ or /etc/systemd/system/).
The service runs /usr/bin/powerjoular, so copy the binary there too, or change ExecStart in the service.
The service will run the program with the -o option (which only saves the latest power data) and saves data to /run/powerjoular/powerjoular-service.csv.
The /run/powerjoular folder is made by systemd when the service starts and removed when it stops, and anyone can read the file in it.
The service runs as root, as reading the energy counters needs it, but with most of the other privileges taken away (it only reads the energy counters and the CPU load, and writes one file in its own folder).
If it stops on its own (not through systemctl), it is restarted after 30 seconds.
The service can be started, and enabled to run automatically on boot, with:
sudo systemctl start powerjoular.service
sudo systemctl enable powerjoular.service
The systemd service is automatically installed (but not enabled) when installing PowerJoular using the installer script or the Linux packages.
Version 1 installed the service in /etc/systemd/system/, which takes precedence over the one now installed in /usr/lib/systemd/system/.
If you installed version 1 with the installer script, delete /etc/systemd/system/powerjoular.service and run sudo systemctl daemon-reload.
Integration with Systems and Tools
PowerJoular exports its power data to CSV files and to a shared memory ring buffer, or prints the values directly on the terminal. As such, PowerJoular can be used in IDEs, integration systems CI/CD, or alongside other profilers or debugging tools.
All what is needed is to start PowerJoular and read the generated CSV files.
PowerJoular can write these CSV files in overwrite mode, and thus reducing the overhead and size of these files.
For a program running on the same machine, the ring buffer (-r) is the fastest way: the program maps the shared memory area once, and reads the latest measurement whenever it needs it, with no file to open or parse.
See Exporting Power Data for the format of the CSV files and the layout of the ring buffer.
With the systemd service provided, PowerJoular can run automatically on startup and write power consumption to /run/powerjoular folder (which can be changed in the service: the service can only write in its own folder, so a new folder also needs a ReadWritePaths= line there).
Therefore, offering an automatic way for multiple tools and dashboards to get accurate and real-time power metrics in multiple platforms.
Virtual Machines
PowerJoular also works inside virtual machines, with a Linux, Windows, macOS or FreeBSD guest. All its functionalities (such as monitoring a PID or an application) work the same inside a virtual machine as with bare metal installation.
In virtual machines, PowerJoular in the guest OS needs to get the power consumption of the virtual machine instance itself. This can only be done by installing on the host OS, a power monitoring tool (such as PowerJoular itself or other ones), and monitoring the power consumption of the specific guest virtual machine process.
The power data of the VM process need to be written to a shared file between the host and the guest. Inside the guest, PowerJoular will read this file continuously and use the reported power value as the CPU power of the entire virtual machine. A GPU passed through to the virtual machine is still measured directly, as on bare metal.
PowerJoular is agnostic to what power tools are installed in the host and can work with any available tool that is capable of monitoring the VM process.
The file can have one of two formats, given with the -s option:
powerjoular: the 3 columns CSV file that-owrites for a monitored process (timestamp, CPU usage and power), where the power is the third column.watts: a file holding the power in watts and nothing else.
PowerJoular reads the first line of the file.
When PowerJoular starts, the file must already be there and hold a power value, otherwise PowerJoular stops with an error, so start the host side first.
Afterwards, 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.
Use case example with PowerJoular on host and guest
A use case example is using PowerJoular on both the host and the guest.
In the host OS
- Install PowerJoular
- Run PowerJoular while specifying the PID of the virtual machine of the guest OS, and writing the power data in a CSV file in overwrite mode.
- For instance, you can run PowerJoular with the following command:
powerjoular -p $VM_PID -o /home/vm/vm.csv - This writes two files:
/home/vm/vm.csvwith the power of the whole host, and/home/vm/vm.csv-$VM_PID.csvwith the power of the virtual machine process. - Share the
/home/vm/vm.csv-$VM_PID.csvbetween the host OS and the guest OS (read-only for the guest, as PowerJoular on the host usually runs as root)
In the guest OS
- Install PowerJoular
- Share the
/home/vm/vm.csv-$VM_PID.csvbetween the host OS and the guest OS, potentially having a different path of the file inside the guest. For instance,/opt/vm/vm.csv - Run PowerJoular with the -m and -s options to specify the file and the power data format.
- For example, in our use case example:
powerjoular -m /opt/vm/vm.csv -s powerjoular - You can add other options for your needs, such as -p or -a to monitor a specific process or application inside your virtual machine.
Use case example with another tool on the host
Have the tool on the host write the power of the virtual machine in watts, and nothing else, to the shared file.
Then read that file in the guest with the watts format: powerjoular -m /opt/vm/vm-power.txt -s watts
How PowerJoular Works
PowerJoular monitors the CPU and GPU power consumption in computers and servers. It is written in Ada in order to provide a low-impact tool as Ada is constantly ranked among the most energy efficient programming languages, while also improving code maintainability and safety.
PowerJoular is aimed to software developers, system administrators and to automated tools, with a goal to help these users understand the power consumption of their devices and software, and to build more in-depth tools using our proposed platform.
Since version 2, PowerJoular measures the hardware through our Joular Core library, and the CPU usage through our CPU Load library. Both are written in Ada too, and PowerJoular is compiled with them into one binary.
PowerJoular’s power monitoring is based on the Intel RAPL through the Linux Power Capping Framework on Linux, through the Energy Meter Interface, PawnIO or Hubblo’s driver on Windows, and through the cpuctl driver on FreeBSD.
On macOS, it is based on Apple’s powermetrics.
For the GPU, it optionally uses NVIDIA’s Management Library (NVML), and AMD’s hwmon sysfs (Linux) or ADLX (Windows).
PowerJoular automatically detects the computer configuration and supported modules, and provides power data accordingly.
On Raspberry Pi and Asus Tinker Board (and similar devices), PowerJoular uses its own research-based empirical regression models to estimate the power consumption of the ARM processor.
CPU Power Monitoring
For the CPU, PowerJoular uses the Intel RAPL power data through the Linux powercap interface by reading the appropriate system files (or our regression models on Raspberry Pi and similar devices).
It reads the Pkg domain, which is supported since Intel Sandy Bridge CPUs (and on AMD Ryzen and EPYC), and provides energy consumption for the CPU cores, integrated graphics, memory controller and last level caches. On a server with several sockets, only the first one is read.
On Windows, the same Pkg counter is read through the Energy Meter Interface built into Windows 11, or through the PawnIO driver or Hubblo’s driver, whichever answers first.
On FreeBSD, the same Pkg counter is read from the registers of the processor, through the cpuctl driver.
RAPL gives an energy counter that only counts up, and Joular Core turns it into the energy consumed since the last reading. PowerJoular divides it by how long the cycle actually took, rather than assuming it was exactly one second, so the watts reported are the watts drawn, even on a busy machine where a cycle takes longer than one second. RAPL counters wrap when they fill, and Joular Core corrects that, as long as the counter is read before it fills half of its range, which is the case with a reading every second.
On macOS, powermetrics is asked for a sample on every cycle, so each value is the average power since the previous cycle.
On Apple Silicon, it gives the CPU and the GPU of the chip from the same sample. On Intel Macs, it gives the whole chip (cores, integrated graphics and system agent), and no GPU.
On Raspberry Pi and similar devices, PowerJoular uses regression models we developed (which provides high accuracy, and publish in this repository).
The model uses CPU utilization (calculated from CPU cycles statistics from the /proc/stat file), and the board is detected from /proc/device-tree/model.
GPU Power Monitoring
For the GPU, PowerJoular checks if the Nvidia driver is installed, then uses its NVML library to verify if GPU power monitoring is supported to the specific graphic card, and to read GPU power consumption every second.
When there is no Nvidia card, it looks for an AMD card: through the hwmon sysfs of the amdgpu driver on Linux, and through ADLX, which comes with the AMD driver, on Windows.
On Apple Silicon Macs, the GPU power comes from powermetrics, with the CPU power.
Only the first graphic card found is read.
Finally, PowerJoular aggregates power readings from all supported components to provide an overall power consumption. For instance, if both Intel RAPL and NVML are supported, the tool will provide an aggregated power value for both CPU and GPU.
Monitoring a PID
For monitoring a specific process through its ID (PID), PowerJoular reads the CPU time used by the process and by the whole system (/proc/stat and /proc/pid/stat on Linux, proc_pidinfo and host_statistics on macOS, GetProcessTimes and GetSystemTimes on Windows, kern.proc and kern.cp_time on FreeBSD), and calculates the proportion of CPU cycles used by the process, and thus calculates the power consumed by the process accordingly:
process power = CPU power × process CPU usage / system CPU usage
The process power is never more than the CPU power, and the GPU power is not shared out to processes.
When the process cannot be read (it has stopped, or the system does not allow it), its usage and power are written as -1 in the CSV file and the ring buffer (and shown as n/a on the terminal), and not as 0.
Monitoring an application by its name
PowerJoular monitors an application by searching for all its PIDs, on every monitoring cycle (every second) because an application can create or destroy process during its runtime.
Then, PowerJoular applies the same approach to monitor a PID, but by summing the CPU time of all the application’s PIDs and calculating the power from that sum.
An application with no running process is reported as 0, and not as -1.
A process is part of the application when the program it runs has that exact name (without its folder, in any case), so firefox finds every process of Firefox, its content processes included.
On macOS, the name is the one of the program inside the bundle, and every program inside Firefox.app is found too, as Firefox runs its content processes (plugin-container) from a helper bundle inside it. On Windows a trailing .exe is ignored.
Systemd service
PowerJoular also provides a systemd service which writes power consumption to the /run/powerjoular folder, allowing it to bypass the added restrictions on reading powercap energy meters to non-privileged users in Intel CPUs.
The restriction was added due to the recently discovered PLATYPUS vulnerability.
However, the systemd service still requires privileged access (root/sudo) to be enabled, and the data provided is the runtime power consumption (every second) from aggregate sources (CPU and GPU when available).