Skip to content

Added new python profiler for performance testing #89

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

Merged
merged 15 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion performance-tests/Dockerfile-VehicleInventoryService-base
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ COPY ./sample-applications/vehicle-dealership-sample-app/VehicleInventoryApp /ve
COPY ./dist/$DISTRO /vehicle-inventory-app/

# Install dependencies and distro
RUN pip install --upgrade pip && pip install -r requirements.txt && pip install ${DISTRO} --force-reinstall
RUN pip install --upgrade pip && pip install -r requirements.txt && pip install psutil && pip install ${DISTRO} \
--force-reinstall
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ void runAppOnce(TestConfig config, DistroConfig distroConfig) throws Exception {
imageService.start();

GenericContainer<?> vehicleInventoryService =
new VehicleInventoryServiceContainer(NETWORK, collector, distroConfig).build();
new VehicleInventoryServiceContainer(NETWORK, collector, distroConfig, namingConventions)
.build();
long start = System.currentTimeMillis();
vehicleInventoryService.start();
writeStartupTimeFile(distroConfig, start);
Expand All @@ -113,7 +114,7 @@ void runAppOnce(TestConfig config, DistroConfig distroConfig) throws Exception {
}

long testStart = System.currentTimeMillis();
// startRecording(distroConfig, vehicleInventoryService);
startRecording(distroConfig, vehicleInventoryService);

GenericContainer<?> k6 =
new K6Container(NETWORK, distroConfig, config, namingConventions).build();
Expand All @@ -129,15 +130,11 @@ void runAppOnce(TestConfig config, DistroConfig distroConfig) throws Exception {

private void startRecording(
DistroConfig distroConfig, GenericContainer<?> vehicleInventoryService) throws Exception {
Path outFile = namingConventions.container.jfrFile(distroConfig);
String[] command = {
"jcmd",
"1",
"JFR.start",
"settings=/app/overhead.jfc",
"dumponexit=true",
"name=petclinic",
"filename=" + outFile
"sh",
"executeProfiler.sh",
namingConventions.container.performanceMetricsFileWithoutPath(distroConfig),
namingConventions.container.root()
};
vehicleInventoryService.execInContainer(command);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package io.opentelemetry.containers;

import io.opentelemetry.distros.DistroConfig;
import io.opentelemetry.util.NamingConventions;
import io.opentelemetry.util.RuntimeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -28,12 +29,17 @@ public class VehicleInventoryServiceContainer {
private final Network network;
private final Startable collector;
private final DistroConfig distroConfig;
private final NamingConventions namingConventions;

public VehicleInventoryServiceContainer(
Network network, Startable collector, DistroConfig distroConfig) {
Network network,
Startable collector,
DistroConfig distroConfig,
NamingConventions namingConventions) {
this.network = network;
this.collector = collector;
this.distroConfig = distroConfig;
this.namingConventions = namingConventions;
}

public GenericContainer<?> build() {
Expand All @@ -44,9 +50,17 @@ public GenericContainer<?> build() {
.withLogConsumer(new Slf4jLogConsumer(logger))
.withExposedPorts(PORT)
.waitingFor(Wait.forHttp("/vehicle-inventory/health-check").forPort(PORT))
.withFileSystemBind(
namingConventions.localResults(), namingConventions.containerResults())
.withCopyFileToContainer(
MountableFile.forClasspathResource("runVehicleInventory.sh"),
"vehicle-inventory-app/run.sh")
.withCopyFileToContainer(
MountableFile.forClasspathResource("profiler.py"),
"vehicle-inventory-app/profiler.py")
.withCopyFileToContainer(
MountableFile.forClasspathResource("executeProfiler.sh"),
"vehicle-inventory-app/executeProfiler.sh")
.withEnv("DJANGO_SETTINGS_MODULE", "VehicleInventoryApp.settings")
.withEnv("PORT", Integer.toString(PORT))
.withEnv("POSTGRES_DATABASE", PostgresContainer.DATABASE_NAME)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,49 @@ public class AppPerfResults {
final double requestLatencyP90;
final double requestLatencyP99;
final double requestLatencyP100;
final long networkBytesSentAvg;
final long networkBytesSentP0;
final long networkBytesSentP50;
final long networkBytesSentP90;
final long networkBytesSentP99;
final long networkBytesSentP100;
final long networkBytesRecvAvg;
final long networkBytesRecvP0;
final long networkBytesRecvP50;
final long networkBytesRecvP90;
final long networkBytesRecvP99;
final long networkBytesRecvP100;
final double cpuAvg;
final double cpuP0;
final double cpuP50;
final double cpuP90;
final double cpuP99;
final double cpuP100;
final long rssMemAvg;
final long rssMemP0;
final long rssMemP50;
final long rssMemP90;
final long rssMemP99;
final long rssMemP100;
final long vmsMemAvg;
final long vmsMemP0;
final long vmsMemP50;
final long vmsMemP90;
final long vmsMemP99;
final long vmsMemP100;
final long peakThreadCount;
final long startupDurationMs;
final long runDurationMs;
// TODO: cleanup
final long totalGCTime;
final long totalAllocated;
final MinMax heapUsed;
final float maxThreadContextSwitchRate;
final long startupDurationMs;
final long peakThreadCount;
final long averageNetworkRead;
final long averageNetworkWrite;
final float averageJvmUserCpu;
final float maxJvmUserCpu;
final float averageMachineCpuTotal;
final long runDurationMs;
final long totalGcPauseNanos;

private AppPerfResults(Builder builder) {
Expand All @@ -46,18 +77,48 @@ private AppPerfResults(Builder builder) {
this.requestLatencyP90 = builder.requestLatencyP90;
this.requestLatencyP99 = builder.requestLatencyP99;
this.requestLatencyP100 = builder.requestLatencyP100;
this.networkBytesSentAvg = builder.networkBytesSentAvg;
this.networkBytesSentP0 = builder.networkBytesSentP0;
this.networkBytesSentP50 = builder.networkBytesSentP50;
this.networkBytesSentP90 = builder.networkBytesSentP90;
this.networkBytesSentP99 = builder.networkBytesSentP99;
this.networkBytesSentP100 = builder.networkBytesSentP100;
this.networkBytesRecvAvg = builder.networkBytesRecvAvg;
this.networkBytesRecvP0 = builder.networkBytesRecvP0;
this.networkBytesRecvP50 = builder.networkBytesRecvP50;
this.networkBytesRecvP90 = builder.networkBytesRecvP90;
this.networkBytesRecvP99 = builder.networkBytesRecvP99;
this.networkBytesRecvP100 = builder.networkBytesRecvP100;
this.cpuAvg = builder.cpuAvg;
this.cpuP0 = builder.cpuP0;
this.cpuP50 = builder.cpuP50;
this.cpuP90 = builder.cpuP90;
this.cpuP99 = builder.cpuP99;
this.cpuP100 = builder.cpuP100;
this.rssMemAvg = builder.rssMemAvg;
this.rssMemP0 = builder.rssMemP0;
this.rssMemP50 = builder.rssMemP50;
this.rssMemP90 = builder.rssMemP90;
this.rssMemP99 = builder.rssMemP99;
this.rssMemP100 = builder.rssMemP100;
this.vmsMemAvg = builder.vmsMemAvg;
this.vmsMemP0 = builder.vmsMemP0;
this.vmsMemP50 = builder.vmsMemP50;
this.vmsMemP90 = builder.vmsMemP90;
this.vmsMemP99 = builder.vmsMemP99;
this.vmsMemP100 = builder.vmsMemP100;
this.peakThreadCount = builder.peakThreadCount;
this.startupDurationMs = builder.startupDurationMs;
this.runDurationMs = builder.runDurationMs;
this.totalGCTime = builder.totalGCTime;
this.totalAllocated = builder.totalAllocated;
this.heapUsed = builder.heapUsed;
this.maxThreadContextSwitchRate = builder.maxThreadContextSwitchRate;
this.startupDurationMs = builder.startupDurationMs;
this.peakThreadCount = builder.peakThreadCount;
this.averageNetworkRead = builder.averageNetworkRead;
this.averageNetworkWrite = builder.averageNetworkWrite;
this.averageJvmUserCpu = builder.averageJvmUserCpu;
this.maxJvmUserCpu = builder.maxJvmUserCpu;
this.averageMachineCpuTotal = builder.averageMachineCpuTotal;
this.runDurationMs = builder.runDurationMs;
this.totalGcPauseNanos = builder.totalGcPauseNanos;
}

Expand All @@ -73,7 +134,7 @@ private AppPerfResults(Builder builder) {
return bytesToMegs(this.heapUsed.max);
}

private double bytesToMegs(long x) {
public double bytesToMegs(long x) {
return x / (1024.0 * 1024.0);
}

Expand All @@ -97,17 +158,48 @@ static class Builder {
public double requestLatencyP90;
public double requestLatencyP99;
public double requestLatencyP100;
public long networkBytesSentAvg;
public long networkBytesSentP0;
public long networkBytesSentP50;
public long networkBytesSentP90;
public long networkBytesSentP99;
public long networkBytesSentP100;
public long networkBytesRecvAvg;
public long networkBytesRecvP0;
public long networkBytesRecvP50;
public long networkBytesRecvP90;
public long networkBytesRecvP99;
public long networkBytesRecvP100;
public double cpuAvg;
public double cpuP0;
public double cpuP50;
public double cpuP90;
public double cpuP99;
public double cpuP100;
public long rssMemAvg;
public long rssMemP0;
public long rssMemP50;
public long rssMemP90;
public long rssMemP99;
public long rssMemP100;
public long vmsMemAvg;
public long vmsMemP0;
public long vmsMemP50;
public long vmsMemP90;
public long vmsMemP99;
public long vmsMemP100;
public long peakThreadCount;
public long runDurationMs;
// TODO: cleanup
private long totalGCTime;
private long totalAllocated;
private MinMax heapUsed;
private float maxThreadContextSwitchRate;
private long peakThreadCount;
public long averageNetworkRead;
public long averageNetworkWrite;
public float averageJvmUserCpu;
public float maxJvmUserCpu;
public float averageMachineCpuTotal;
public long runDurationMs;
public long totalGcPauseNanos;

AppPerfResults build() {
Expand All @@ -124,6 +216,7 @@ Builder config(TestConfig config) {
return this;
}

// TODO: cleanup
Builder totalGCTime(long totalGCTime) {
this.totalGCTime = totalGCTime;
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

package io.opentelemetry.results;

import static java.util.concurrent.TimeUnit.NANOSECONDS;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
Expand All @@ -23,11 +21,6 @@ class CsvPersister implements ResultsPersister {
private static final List<FieldSpec> FIELDS =
Arrays.asList(
FieldSpec.of("startupDurationMs", r -> r.startupDurationMs),
// FieldSpec.of("minHeapUsed", r -> r.heapUsed.min),
// FieldSpec.of("maxHeapUsed", r -> r.heapUsed.max),
FieldSpec.of("totalAllocatedMB", r -> r.getTotalAllocatedMB()),
FieldSpec.of("totalGCTime", r -> r.totalGCTime),
FieldSpec.of("maxThreadContextSwitchRate", r -> r.maxThreadContextSwitchRate),
FieldSpec.of("requestCount", r -> r.requestCount),
FieldSpec.of("requestRate", r -> r.requestRate),
FieldSpec.of("requestLatencyAvg", r -> r.requestLatencyAvg),
Expand All @@ -36,14 +29,44 @@ class CsvPersister implements ResultsPersister {
FieldSpec.of("requestLatencyP90", r -> r.requestLatencyP90),
FieldSpec.of("requestLatencyP99", r -> r.requestLatencyP99),
FieldSpec.of("requestLatencyP100", r -> r.requestLatencyP100),
FieldSpec.of("netReadAvg", r -> r.averageNetworkRead),
FieldSpec.of("netWriteAvg", r -> r.averageNetworkWrite),
FieldSpec.of("networkBytesSentAvg", r -> r.networkBytesSentAvg),
FieldSpec.of("networkBytesSentP0", r -> r.networkBytesSentP0),
FieldSpec.of("networkBytesSentP50", r -> r.networkBytesSentP50),
FieldSpec.of("networkBytesSentP90", r -> r.networkBytesSentP90),
FieldSpec.of("networkBytesSentP99", r -> r.networkBytesSentP99),
FieldSpec.of("networkBytesSentP100", r -> r.networkBytesSentP100),
FieldSpec.of("networkBytesRecvAvg", r -> r.networkBytesRecvAvg),
FieldSpec.of("networkBytesRecvP0", r -> r.networkBytesRecvP0),
FieldSpec.of("networkBytesRecvP50", r -> r.networkBytesRecvP50),
FieldSpec.of("networkBytesRecvP90", r -> r.networkBytesRecvP90),
FieldSpec.of("networkBytesRecvP99", r -> r.networkBytesRecvP99),
FieldSpec.of("networkBytesRecvP100", r -> r.networkBytesRecvP100),
FieldSpec.of("cpuAvg", r -> r.cpuAvg),
FieldSpec.of("cpuP0", r -> r.cpuP0),
FieldSpec.of("cpuP50", r -> r.cpuP50),
FieldSpec.of("cpuP90", r -> r.cpuP90),
FieldSpec.of("cpuP99", r -> r.cpuP99),
FieldSpec.of("cpuP100", r -> r.cpuP100),
FieldSpec.of("cpuAvg", r -> r.cpuAvg),
FieldSpec.of("cpuP0", r -> r.cpuP0),
FieldSpec.of("cpuP50", r -> r.cpuP50),
FieldSpec.of("cpuP90", r -> r.cpuP90),
FieldSpec.of("cpuP99", r -> r.cpuP99),
FieldSpec.of("cpuP100", r -> r.cpuP100),
FieldSpec.of("rssMemAvg", r -> r.rssMemAvg),
FieldSpec.of("rssMemP0", r -> r.rssMemP0),
FieldSpec.of("rssMemP50", r -> r.rssMemP50),
FieldSpec.of("rssMemP90", r -> r.rssMemP90),
FieldSpec.of("rssMemP99", r -> r.rssMemP99),
FieldSpec.of("rssMemP100", r -> r.rssMemP100),
FieldSpec.of("vmsMemAvg", r -> r.vmsMemAvg),
FieldSpec.of("vmsMemP0", r -> r.vmsMemP0),
FieldSpec.of("vmsMemP50", r -> r.vmsMemP50),
FieldSpec.of("vmsMemP90", r -> r.vmsMemP90),
FieldSpec.of("vmsMemP99", r -> r.vmsMemP99),
FieldSpec.of("vmsMemP100", r -> r.vmsMemP100),
FieldSpec.of("peakThreadCount", r -> r.peakThreadCount),
FieldSpec.of("averageCpuUser", r -> r.averageJvmUserCpu),
FieldSpec.of("maxCpuUser", r -> r.maxJvmUserCpu),
FieldSpec.of("averageMachineCpuTotal", r -> r.averageMachineCpuTotal),
FieldSpec.of("runDurationMs", r -> r.runDurationMs),
FieldSpec.of("gcPauseMs", r -> NANOSECONDS.toMillis(r.totalGcPauseNanos)));
FieldSpec.of("runDurationMs", r -> r.runDurationMs));

private final Path resultsFile;

Expand Down
Loading