Skip to content

Commit 6a10d62

Browse files
committed
feat: provide sampling period information
1 parent 0a07404 commit 6a10d62

File tree

4 files changed

+58
-18
lines changed

4 files changed

+58
-18
lines changed

README.md

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,33 @@ without further processing.
77
This project uses [Quarkus](https://quarkus.io), the Supersonic Subatomic Java Framework and comprises 3 modules:
88

99
- `analysis`, which contains utilities helpful to analyze power measures (computations, statistics, histograms, etc…)
10-
- `if-manifest-export`, which provides a means to export a stopped measure as a [Green Software Foundation](https://greensoftware.foundation/) [Impact Framework](https://if.greensoftware.foundation/) manifest
10+
- `if-manifest-export`, which provides a means to export a stopped measure as
11+
a [Green Software Foundation](https://greensoftware.foundation/) [Impact Framework](https://if.greensoftware.foundation/)
12+
manifest
1113
- `measure`, which provides classes to help record and process measures in client applications
1214
- `metadata`, which contains the metadata API that the RESTful server uses to provide information about what is returned
1315
by the power sensors. This artifact contains classes that can be reused in client projects.
1416
- `server` contains the RESTful server, listening by default on port `20432` (as specified
15-
in `[application.properties](https://github.com/metacosm/power-server/blob/87bba3196fa0e552665b4f1d22006377779b0959/server/src/main/resources/application.properties#L1)`)
16-
17-
The server provides two endpoints: `/power/metadata` and `/power/{pid}` where `pid` is a String representation of a
18-
process identifier, identifying a process running on the machine where `power-server` is running.
19-
The metadata endpoint provides information about how measures streamed from the main endpoint is formatted as well as
20-
information about power components. The main endpoint streams `SensorMeasure` objects as defined in the `metadata`
21-
module as an array of double measures. Typically, main sensor components are measured in milli Watts for easier
22-
consumption but clients should check the information provided by the metadata endpoint to learn the layout of the
23-
measures array and which meaning they carry. For example, the macOS implementation provides a decimal percentage measure
24-
of the CPU share of the measured process as part of the returned measure. This information doesn't exist on the Linux
25-
information where the measures are actually energy counters for the whole system, the client being then in charge of
26-
computing the process attribution.
17+
in
18+
`[application.properties](https://github.com/metacosm/power-server/blob/87bba3196fa0e552665b4f1d22006377779b0959/server/src/main/resources/application.properties#L1)`)
19+
20+
The server provides the following endpoints:
21+
22+
- `/power/{pid}` where `pid` is a String representation of a process identifier, identifying a process running on the
23+
machine where `power-server` is running.
24+
- `/power/metadata` provides information about how measures streamed from the main endpoint is formatted as well as
25+
information about power components.
26+
- `/power/sampling` provides the currently configured power measure sampling period, which can be configured using the
27+
`net.laprun.sustainability.power.sampling-period` property, passing it a `String` that can be converted to a Java
28+
`Duration`.
29+
30+
The main endpoint streams `SensorMeasure` objects as defined in the `metadata`module as an array of double measures.
31+
Typically, main sensor components are measured in milli Watts for easier consumption but clients should check the
32+
information provided by the metadata endpoint to learn the layout of the measures array and which meaning they carry.
33+
For example, the macOS implementation provides a decimal percentage
34+
measure of the CPU share of the measured process as part of the returned measure. This information doesn't exist on the
35+
Linux implementation where the measures are actually energy counters for the whole system, the client being then in
36+
charge of computing the process attribution.
2737

2838
Only Linux/amd64 and macOS (amd64/apple silicon) are supported at the moment. Of note, this tool needs to be run
2939
via `sudo` because power consumption information is considered as security sensitive (as it can
@@ -33,7 +43,8 @@ information.
3343
### macOS
3444

3545
Power monitoring is performed using the
36-
bundled `[powermetrics](https://developer.apple.com/library/archive/documentation/Performance/Conceptual/power_efficiency_guidelines_osx/PrioritizeWorkAtTheTaskLevel.html#//apple_ref/doc/uid/TP40013929-CH35-SW10)`
46+
bundled
47+
`[powermetrics](https://developer.apple.com/library/archive/documentation/Performance/Conceptual/power_efficiency_guidelines_osx/PrioritizeWorkAtTheTaskLevel.html#//apple_ref/doc/uid/TP40013929-CH35-SW10)`
3748
tool, which is run with specific parameters and which
3849
output is then parsed into a usable representation.
3950

@@ -69,5 +80,6 @@ Once you've performed a full build, you can also compile the server to a native
6980
Once build, you can run the server as follows:
7081

7182
- JVM mode: `sudo java -jar server/target/quarkus-app/quarkus-run.jar` from the project root
72-
- Dev mode: `cd server; sudo mvn quarkus:dev` or `cd server; sudo quarkus dev` (will only work if `root` has Java properly configured)
83+
- Dev mode: `cd server; sudo mvn quarkus:dev` or `cd server; sudo quarkus dev` (will only work if `root` has Java
84+
properly configured)
7385
- Native mode: `sudo ./server/target/*-runner`

server/src/main/java/net/laprun/sustainability/power/PowerMeasurer.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import jakarta.enterprise.context.ApplicationScoped;
66
import jakarta.inject.Inject;
77

8+
import org.eclipse.microprofile.config.inject.ConfigProperty;
9+
810
import io.smallrye.mutiny.Multi;
911
import io.smallrye.mutiny.infrastructure.Infrastructure;
1012
import net.laprun.sustainability.power.sensors.Measures;
@@ -13,20 +15,23 @@
1315
@ApplicationScoped
1416
public class PowerMeasurer {
1517

16-
public static final int SAMPLING_FREQUENCY_IN_MILLIS = 500;
18+
public static final String DEFAULT_SAMPLING_PERIOD = "PT0.5S";
1719
@Inject
1820
PowerSensor sensor;
1921

22+
@ConfigProperty(name = "net.laprun.sustainability.power.sampling-period", defaultValue = DEFAULT_SAMPLING_PERIOD)
23+
Duration samplingPeriod;
24+
2025
private Multi<Measures> periodicSensorCheck;
2126

2227
public Multi<SensorMeasure> startTracking(String pid) throws Exception {
2328
// first make sure that the process with that pid exists
2429
final var parsedPID = validPIDOrFail(pid);
2530

2631
if (!sensor.isStarted()) {
27-
sensor.start(SAMPLING_FREQUENCY_IN_MILLIS);
32+
sensor.start(samplingPeriod.toMillis());
2833
periodicSensorCheck = Multi.createFrom().ticks()
29-
.every(Duration.ofMillis(SAMPLING_FREQUENCY_IN_MILLIS))
34+
.every(samplingPeriod)
3035
.map(sensor::update)
3136
.broadcast()
3237
.withCancellationAfterLastSubscriberDeparture()
@@ -50,4 +55,8 @@ protected long validPIDOrFail(String pid) {
5055
public SensorMetadata metadata() {
5156
return sensor.metadata();
5257
}
58+
59+
public Duration getSamplingPeriod() {
60+
return samplingPeriod;
61+
}
5362
}

server/src/main/java/net/laprun/sustainability/power/PowerResource.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package net.laprun.sustainability.power;
22

3+
import java.time.Duration;
4+
35
import jakarta.inject.Inject;
46
import jakarta.ws.rs.*;
57
import jakarta.ws.rs.core.MediaType;
@@ -29,4 +31,10 @@ public Multi<SensorMeasure> powerFor(@PathParam("pid") String pid) throws Except
2931
public SensorMetadata metadata() {
3032
return measurer.metadata();
3133
}
34+
35+
@GET
36+
@Path("sampling")
37+
public Duration samplingPeriod() {
38+
return measurer.getSamplingPeriod();
39+
}
3240
}

server/src/test/java/net/laprun/sustainability/power/PowerResourceTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import static io.restassured.RestAssured.given;
44
import static org.junit.jupiter.api.Assertions.*;
55

6+
import java.time.Duration;
67
import java.util.Set;
78

89
import org.junit.jupiter.api.Test;
@@ -24,6 +25,16 @@ public void testPowerEndpoint() {
2425
.statusCode(200);
2526
}
2627

28+
@Test
29+
public void samplingPeriod() {
30+
final Duration duration = given()
31+
.when().get("/power/sampling")
32+
.then()
33+
.statusCode(200)
34+
.extract().body().as(Duration.class);
35+
assertEquals(Duration.parse(PowerMeasurer.DEFAULT_SAMPLING_PERIOD), duration);
36+
}
37+
2738
protected long getPid() {
2839
return ProcessHandle.current().pid();
2940
}

0 commit comments

Comments
 (0)