Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: use power-server for power measurements #26

Merged
merged 22 commits into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
9550c7c
wip: attempting to access power server via REST
metacosm Nov 30, 2023
f9ac875
refactor: isolate sensor retrieval logic behind Sampler interface
metacosm Dec 1, 2023
e2a9f16
feat: add ServerSampler retrieving power data from power-server
metacosm Dec 1, 2023
ea795c9
wip: add DualSampler to compare local and remote measures
metacosm Dec 1, 2023
b5c4bfd
chore: remove unused and not really useful JMXCPUSensor
metacosm Dec 18, 2023
76b70fc
refactor: simplify OngoingPowerMeasure
metacosm Dec 18, 2023
6259daf
fix: ignore update that doesn't have any data
metacosm Dec 21, 2023
c1907e7
refactor: move PowerMeasure implementations to better package
metacosm Jan 30, 2024
11a7657
wip: attempt to test power-server client
metacosm Feb 1, 2024
fd3254e
fix: make things more easily testable, disable failing test due to setup
metacosm Mar 1, 2024
cd4e741
fix: re-activate workflows
metacosm Mar 1, 2024
37e46a8
chore(build): manage power-server dependency, update to 0.0.2
metacosm Mar 1, 2024
e5ee50a
chore: switch to version 0.0.1-SNAPSHOT
metacosm Mar 1, 2024
5c3d629
fix: should also work in the absence of injection
metacosm Mar 1, 2024
b2c39d6
fix: use proper dependencies
metacosm Mar 27, 2024
831c32c
feat: make it clearer that power-server needs to run
metacosm Mar 28, 2024
7a0a889
fix: set up GraalVM
metacosm Mar 29, 2024
156050f
feat: run on all supported platforms (macos-14 for Apple Silicon supp…
metacosm Mar 29, 2024
2276a79
fix: native build
metacosm Mar 29, 2024
5aae39e
feat: remove all local sensor code
metacosm Mar 29, 2024
1fa9cac
chore: update to power-server 0.0.7
metacosm Mar 29, 2024
24fc568
docs: improve README to account for power-server use
metacosm Mar 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions .github/disabled/build.yml → .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ on:
- '.all-contributorsrc'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
group: '${{ github.workflow }}-${{ github.ref }}'
cancel-in-progress: true

defaults:
Expand All @@ -36,17 +36,17 @@ jobs:
strategy:
fail-fast: false
matrix:
# os: [windows-latest, macos-latest, ubuntu-latest]
os: [macos-latest]
os: [macos-latest, macos-14, ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Prepare git
run: git config --global core.autocrlf false
if: startsWith(matrix.os, 'windows')

- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
Expand All @@ -55,5 +55,12 @@ jobs:
- name: Build with Maven
run: mvn -B clean install -Dno-format

- uses: graalvm/setup-graalvm@v1
with:
java-version: '17'
distribution: 'graalvm'
github-token: ${{ secrets.GITHUB_TOKEN }}
native-image-job-reports: 'true'

- name: Build with Maven (Native)
run: mvn -B install -Dnative -Dquarkus.native.container-build -Dnative.surefire.skip
run: mvn -B package -Dnative -Dnative.surefire.skip
File renamed without changes.
42 changes: 15 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,36 @@
This extension is an experiment to measure and display the power consumption of your application as it runs in Dev mode.
Only Linux/amd64 and macOS (amd64/apple silicon) are supported at the moment. See below for platform-specific
requirements.

## Requirements

### macOS

The power monitoring is performed using the bundled `powermetrics` tool, which requires `sudo` access. For convenience
and security, it's recommended you add your user to the `sudoers` file, giving it passwordless access
to `/usr/bin/powermetrics` (and possibly, only that).

### Linux

The extension makes use of the RAPL information accessible under the `/sys/class/powercap/intel-rapl` directory. For
security purposes, some of that information is only readable by root, in particular the values that we need to get the
power consumption, currently:
## Requirements

- /sys/class/powercap/intel-rapl/intel-rapl:1/energy_uj (if available)
- /sys/class/powercap/intel-rapl/intel-rapl:0/energy_uj
- /sys/class/powercap/intel-rapl/intel-rapl:0/intel-rapl:0:2/energy_uj
### power-server

For the extension to work properly, these files need to be readable by the current user, which you can accomplish by
running the provided `make_power_readable.sh` script. Note that this change will only persist until the next restart.
This extension relies on retrieving power consumption measurements from an application
called [power-server](https://github.com/metacosm/power-server). This application needs to be run using `sudo` to get
access to the underlying OS' power reporting layer. Please download the appropriate version for your OS from
the [release page](https://github.com/metacosm/power-server/releases/). Once downloaded, you can unpack
the archive and navigate to the `bin` directory to find the `power-server` binary that you can then run
using: `sudo power-server`.

## Usage

To use the extension:

1. Clone this repository locally
2. Build the code using `mvn install`
3. Add the extension to the application which energy consumption you wish to measure. Since the extension is not yet
released, you will need to add it manually as a dependency to your application:
1. Add the extension to the application which energy consumption you wish to measure. You can add it as a dependency to
your application:
```xml
<dependency>
<groupId>io.quarkiverse.power</groupId>
<artifactId>quarkus-power</artifactId>
<version>${project.version}</version>
</dependency>
```
4. Start your application in dev mode: `quarkus dev`
5. Enter the dev mode terminal by pressing `:` (column)
6. You should have a new `power` command available, type `power -h` for more information
7. You can start power measurement with `power start` and stop it with `power stop`, at which time the power consumption
2. Start your application in dev mode: `quarkus dev`
3. Enter the dev mode terminal by pressing `:` (column)
4. You should have a new `power` command available, type `power -h` for more information
5. You can start power measurement with `power start` and stop it with `power stop`, at which time the power consumption
of your app will be displayed.
8. You can also ask for power to be measured for a given duration by using the `-s` option when
6. You can also ask for power to be measured for a given duration by using the `-s` option when
calling `power start`. In this case, there's no need to call `power stop`, the energy consumed during the specified
time will be automatically displayed once the time period is elapsed.
15 changes: 14 additions & 1 deletion deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>io.quarkiverse.power</groupId>
<artifactId>quarkus-power-parent</artifactId>
<version>999-SNAPSHOT</version>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>quarkus-power-deployment</artifactId>
<name>Quarkus Power - Deployment</name>
Expand All @@ -14,6 +14,14 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest-client-jackson-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest-jackson-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkiverse.power</groupId>
<artifactId>quarkus-power</artifactId>
Expand All @@ -24,6 +32,11 @@
<artifactId>quarkus-junit5-internal</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.laprun.sustainability</groupId>
<artifactId>power-server</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.quarkiverse.power.deployment;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.net.URI;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkiverse.power.runtime.PowerMeasurer;
import io.quarkiverse.power.runtime.ServerSampler;
import io.quarkus.test.QuarkusUnitTest;
import io.quarkus.test.common.http.TestHTTPResource;
import net.laprun.sustainability.power.PowerResource;

public class PowerMeasurerTest {
@TestHTTPResource
URI uri;

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.withApplicationRoot((jar) -> jar.addClasses(PowerResource.class, TestPowerMeasurer.class, TestPowerSensor.class));

@Test
void startShouldAccumulateOverSpecifiedDurationAndStop() throws Exception {
final var measurer = new PowerMeasurer<>(new ServerSampler(uri));

measurer.start(1, 100);
measurer.onCompleted(measure -> {
assertEquals(10, measure.numberOfSamples());
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.quarkiverse.power.deployment;

import io.quarkus.test.Mock;
import net.laprun.sustainability.power.PowerMeasurer;

@Mock
public class TestPowerMeasurer extends PowerMeasurer {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.quarkiverse.power.deployment;

import io.quarkus.test.Mock;

@Mock
public class TestPowerSensor extends net.laprun.sustainability.power.sensors.test.TestPowerSensor {
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusDevModeTest;

@Disabled
public class PowerDevModeTest {

// Start hot reload (DevMode) test with your extension loaded
Expand Down
4 changes: 2 additions & 2 deletions integration-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>io.quarkiverse.power</groupId>
<artifactId>quarkus-power-parent</artifactId>
<version>999-SNAPSHOT</version>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>quarkus-power-integration-tests</artifactId>
<name>Quarkus Power - Integration Tests</name>
Expand All @@ -15,7 +15,7 @@
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
<artifactId>quarkus-rest</artifactId>
</dependency>
<dependency>
<groupId>io.quarkiverse.power</groupId>
Expand Down
36 changes: 34 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@
</parent>
<groupId>io.quarkiverse.power</groupId>
<artifactId>quarkus-power-parent</artifactId>
<version>999-SNAPSHOT</version>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Quarkus Power - Parent</name>
<modules>
<module>deployment</module>
<module>runtime</module>
<!-- <module>docs</module>-->
</modules>
<scm>
<connection>scm:git:git@github.com:quarkiverse/quarkus-power.git</connection>
Expand All @@ -28,6 +27,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus.version>3.9.1</quarkus.version>
<power-server.version>0.0.7</power-server.version>
</properties>
<dependencyManagement>
<dependencies>
Expand All @@ -38,6 +38,17 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>net.laprun.sustainability</groupId>
<artifactId>power-server-metadata</artifactId>
<version>${power-server.version}</version>
</dependency>
<dependency>
<groupId>net.laprun.sustainability</groupId>
<artifactId>power-server</artifactId>
<version>${power-server.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
Expand All @@ -48,6 +59,27 @@
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<dependencies>
<dependency>
<groupId>me.fabriciorby</groupId>
<artifactId>maven-surefire-junit5-tree-reporter</artifactId>
<version>1.2.1</version>
</dependency>
</dependencies>
<configuration>
<reportFormat>plain</reportFormat>
<consoleOutputReporter>
<disable>true</disable>
</consoleOutputReporter>
<statelessTestsetInfoReporter
implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5StatelessTestsetInfoTreeReporter">
<theme>UNICODE</theme>
</statelessTestsetInfoReporter>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
Expand Down
19 changes: 18 additions & 1 deletion runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,26 @@
<parent>
<groupId>io.quarkiverse.power</groupId>
<artifactId>quarkus-power-parent</artifactId>
<version>999-SNAPSHOT</version>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>quarkus-power</artifactId>
<name>Quarkus Power - Runtime</name>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest-client-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jackson</artifactId>
</dependency>
<dependency>
<groupId>net.laprun.sustainability</groupId>
<artifactId>power-server-metadata</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
Expand All @@ -24,6 +36,11 @@
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-test-common</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package io.quarkiverse.power.runtime.sensors;
package io.quarkiverse.power.runtime;

import java.util.List;

import io.quarkiverse.power.runtime.PowerMeasure;
import io.quarkiverse.power.runtime.SensorMetadata;

abstract class AbstractPowerMeasure implements PowerMeasure {
private final SensorMetadata sensorMetadata;
private final List<double[]> measures;
Expand Down
Loading
Loading