Skip to content

Commit e5e161c

Browse files
authored
Capture CPU and memory metrics (#54)
1 parent 28f8a88 commit e5e161c

File tree

6 files changed

+103
-2
lines changed

6 files changed

+103
-2
lines changed

pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@
4949
<artifactId>spring-retry</artifactId>
5050
<version>[2.0.0,3.0.0)</version>
5151
</dependency>
52+
<dependency>
53+
<groupId>com.github.oshi</groupId>
54+
<artifactId>oshi-core</artifactId>
55+
<version>6.9.2</version>
56+
</dependency>
5257
<dependency>
5358
<groupId>com.github.spotbugs</groupId>
5459
<artifactId>spotbugs-annotations</artifactId>

src/main/java/io/apitally/common/ApitallyClient.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ public enum HubRequestStatus {
7272
public final ValidationErrorCounter validationErrorCounter;
7373
public final ServerErrorCounter serverErrorCounter;
7474
public final ConsumerRegistry consumerRegistry;
75+
public final ResourceMonitor resourceMonitor;
7576

7677
private final Queue<SyncData> syncDataQueue = new ConcurrentLinkedQueue<SyncData>();
7778
private final Random random = new Random();
@@ -87,6 +88,7 @@ public ApitallyClient(String clientId, String env, RequestLoggingConfig requestL
8788
this.validationErrorCounter = new ValidationErrorCounter();
8889
this.serverErrorCounter = new ServerErrorCounter();
8990
this.consumerRegistry = new ConsumerRegistry();
91+
this.resourceMonitor = new ResourceMonitor();
9092
}
9193

9294
public boolean isEnabled() {
@@ -149,7 +151,8 @@ private void sendSyncData() {
149151
requestCounter.getAndResetRequests(),
150152
validationErrorCounter.getAndResetValidationErrors(),
151153
serverErrorCounter.getAndResetServerErrors(),
152-
consumerRegistry.getAndResetConsumers());
154+
consumerRegistry.getAndResetConsumers(),
155+
resourceMonitor.getCpuMemoryUsage());
153156
syncDataQueue.offer(data);
154157

155158
int i = 0;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package io.apitally.common;
2+
3+
import io.apitally.common.dto.ResourceUsage;
4+
import oshi.SystemInfo;
5+
import oshi.software.os.OSProcess;
6+
7+
public class ResourceMonitor {
8+
private final SystemInfo systemInfo = new SystemInfo();
9+
private OSProcess previousSnapshot;
10+
11+
public ResourceUsage getCpuMemoryUsage() {
12+
try {
13+
int pid = (int) ProcessHandle.current().pid();
14+
OSProcess currentProcess = systemInfo.getOperatingSystem().getProcess(pid);
15+
if (currentProcess == null) {
16+
return null;
17+
}
18+
19+
if (previousSnapshot == null) {
20+
previousSnapshot = currentProcess;
21+
return null;
22+
}
23+
24+
double cpuPercent =
25+
100.0 * currentProcess.getProcessCpuLoadBetweenTicks(previousSnapshot);
26+
long memoryRss = currentProcess.getResidentSetSize();
27+
previousSnapshot = currentProcess;
28+
29+
return new ResourceUsage(cpuPercent, memoryRss);
30+
} catch (Exception e) {
31+
return null;
32+
}
33+
}
34+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package io.apitally.common.dto;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
5+
public class ResourceUsage {
6+
private final double cpuPercent;
7+
private final long memoryRss;
8+
9+
public ResourceUsage(double cpuPercent, long memoryRss) {
10+
this.cpuPercent = cpuPercent;
11+
this.memoryRss = memoryRss;
12+
}
13+
14+
@JsonProperty("cpu_percent")
15+
public double getCpuPercent() {
16+
return cpuPercent;
17+
}
18+
19+
@JsonProperty("memory_rss")
20+
public long getMemoryRss() {
21+
return memoryRss;
22+
}
23+
}

src/main/java/io/apitally/common/dto/SyncData.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.apitally.common.dto;
22

33
import com.fasterxml.jackson.annotation.JsonIgnore;
4+
import com.fasterxml.jackson.annotation.JsonInclude;
45
import com.fasterxml.jackson.annotation.JsonProperty;
56
import java.util.List;
67
import java.util.UUID;
@@ -13,20 +14,23 @@ public class SyncData extends BaseDto {
1314
private final List<ValidationErrors> validationErrors;
1415
private final List<ServerErrors> serverErrors;
1516
private final List<Consumer> consumers;
17+
private final ResourceUsage resources;
1618

1719
public SyncData(
1820
UUID instanceUuid,
1921
List<Requests> requests,
2022
List<ValidationErrors> validationErrors,
2123
List<ServerErrors> serverErrors,
22-
List<Consumer> consumers) {
24+
List<Consumer> consumers,
25+
ResourceUsage resources) {
2326
this.timestamp = System.currentTimeMillis() / 1000.0;
2427
this.instanceUuid = instanceUuid;
2528
this.messageUuid = UUID.randomUUID();
2629
this.requests = requests;
2730
this.validationErrors = validationErrors;
2831
this.serverErrors = serverErrors;
2932
this.consumers = consumers;
33+
this.resources = resources;
3034
}
3135

3236
@JsonProperty("timestamp")
@@ -64,6 +68,12 @@ public List<Consumer> getConsumers() {
6468
return consumers;
6569
}
6670

71+
@JsonProperty("resources")
72+
@JsonInclude(JsonInclude.Include.NON_NULL)
73+
public ResourceUsage getResources() {
74+
return resources;
75+
}
76+
6777
@JsonIgnore
6878
public double getAgeInSeconds() {
6979
return System.currentTimeMillis() / 1000.0 - timestamp;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package io.apitally.common;
2+
3+
import static org.junit.jupiter.api.Assertions.assertNotNull;
4+
import static org.junit.jupiter.api.Assertions.assertNull;
5+
import static org.junit.jupiter.api.Assertions.assertTrue;
6+
7+
import io.apitally.common.dto.ResourceUsage;
8+
import org.junit.jupiter.api.Test;
9+
10+
class ResourceMonitorTest {
11+
12+
@Test
13+
void testGetCpuMemoryUsage() throws InterruptedException {
14+
ResourceMonitor resourceMonitor = new ResourceMonitor();
15+
16+
ResourceUsage firstResult = resourceMonitor.getCpuMemoryUsage();
17+
assertNull(firstResult);
18+
19+
Thread.sleep(100);
20+
21+
ResourceUsage secondResult = resourceMonitor.getCpuMemoryUsage();
22+
assertNotNull(secondResult);
23+
assertTrue(secondResult.getCpuPercent() >= 0);
24+
assertTrue(secondResult.getMemoryRss() > 0);
25+
}
26+
}

0 commit comments

Comments
 (0)