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

Update handlers in jfr-streaming to match spec #616

Merged
merged 6 commits into from
Nov 29, 2022
Merged
Show file tree
Hide file tree
Changes from 2 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
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@ private Constants() {}

public static final String ONE = "1";
public static final String HERTZ = "Hz";
public static final String BYTES = "B";
public static final String BYTES = "By";
public static final String MILLISECONDS = "ms";
public static final String PERCENTAGE = "%age";
public static final String USER = "user";
public static final String SYSTEM = "system";
public static final String MACHINE = "machine.total";
public static final String G1 = "g1";
public static final String TOTAL_USED = "total.used";
public static final String EDEN_USED = "eden.used";
Expand All @@ -27,24 +26,37 @@ private Constants() {}
public static final String REGION_COUNT = "region.count";
public static final String COMMITTED = "committed";
public static final String RESERVED = "reserved";
public static final String USED = "used";
public static final String COMMITTED_SIZE = "committedSize";

public static final String DAEMON = "daemon";
public static final String HEAP = "heap";

public static final String METRIC_NAME_NETWORK_BYTES = "process.runtime.jvm.network.io";
public static final String METRIC_DESCRIPTION_NETWORK_BYTES = "Network read/write bytes";
public static final String METRIC_NAME_NETWORK_DURATION = "process.runtime.jvm.network.time";
public static final String METRIC_DESCRIPTION_NETWORK_DURATION = "Network read/write duration";
public static final String METRIC_NAME_COMMITTED = "process.runtime.jvm.memory.committed";
public static final String METRIC_DESCRIPTION_COMMITTED = "Measure of memory committed";
public static final String NETWORK_MODE_READ = "read";
public static final String NETWORK_MODE_WRITE = "write";

public static final String METRIC_NAME_MEMORY = "process.runtime.jvm.memory.usage";
public static final String METRIC_NAME_MEMORY_AFTER =
"process.runtime.jvm.memory.usage_after_last_gc";
public static final String METRIC_DESCRIPTION_MEMORY = "Measure of memory used";
public static final String METRIC_DESCRIPTION_MEMORY_AFTER =
"Measure of memory used, as measured after the most recent garbage collection event on this pool";
public static final String METRIC_NAME_MEMORY_ALLOCATION =
"process.runtime.jvm.memory.allocation";
public static final String METRIC_DESCRIPTION_MEMORY_ALLOCATION = "Allocation";

public static final AttributeKey<String> ATTR_THREAD_NAME = AttributeKey.stringKey("thread.name");
public static final AttributeKey<String> ATTR_ARENA_NAME = AttributeKey.stringKey("arena");
public static final AttributeKey<String> ATTR_NETWORK_MODE = AttributeKey.stringKey("mode");
public static final AttributeKey<String> ATTR_USAGE = AttributeKey.stringKey("usage.type");
public static final AttributeKey<String> ATTR_TYPE = AttributeKey.stringKey("type");
public static final AttributeKey<String> ATTR_POOL = AttributeKey.stringKey("pool");
public static final AttributeKey<Boolean> ATTR_DAEMON = AttributeKey.booleanKey(DAEMON);
public static final String UNIT_CLASSES = "{classes}";
public static final String UNIT_THREADS = "{threads}";
public static final String UNIT_UTILIZATION = "1";
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,59 +5,60 @@

package io.opentelemetry.contrib.jfr.metrics.internal.cpu;

import static io.opentelemetry.contrib.jfr.metrics.internal.Constants.ATTR_USAGE;
import static io.opentelemetry.contrib.jfr.metrics.internal.Constants.MACHINE;
import static io.opentelemetry.contrib.jfr.metrics.internal.Constants.PERCENTAGE;
import static io.opentelemetry.contrib.jfr.metrics.internal.Constants.SYSTEM;
import static io.opentelemetry.contrib.jfr.metrics.internal.Constants.USER;
import static io.opentelemetry.contrib.jfr.metrics.internal.Constants.UNIT_UTILIZATION;
import static io.opentelemetry.contrib.jfr.metrics.internal.RecordedEventHandler.defaultMeter;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.DoubleHistogram;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.contrib.jfr.metrics.internal.RecordedEventHandler;
import java.time.Duration;
import java.util.Optional;
import jdk.jfr.consumer.RecordedEvent;

public final class OverallCPULoadHandler implements RecordedEventHandler {
private static final String METRIC_NAME = "process.runtime.jvm.cpu.used";
private static final String METRIC_DESCRIPTION = "CPU Utilization";
private static final String METRIC_NAME_PROCESS = "process.runtime.jvm.cpu.utilization";
private static final String METRIC_NAME_MACHINE = "process.runtime.jvm.system.cpu.utilization";
private static final String METRIC_DESCRIPTION_PROCESS = "Recent CPU utilization for the process";
private static final String METRIC_DESCRIPTION_MACHINE =
"Recent CPU utilization for the whole system";

private static final String EVENT_NAME = "jdk.CPULoad";
private static final String JVM_USER = "jvmUser";
private static final String JVM_SYSTEM = "jvmSystem";
private static final String MACHINE_TOTAL = "machineTotal";

private static final Attributes ATTR_USER = Attributes.of(ATTR_USAGE, USER);
private static final Attributes ATTR_SYSTEM = Attributes.of(ATTR_USAGE, SYSTEM);
private static final Attributes ATTR_MACHINE = Attributes.of(ATTR_USAGE, MACHINE);

private DoubleHistogram histogram;
private volatile double process = 0;
private volatile double machine = 0;

public OverallCPULoadHandler() {
initializeMeter(defaultMeter());
}

@Override
public void initializeMeter(Meter meter) {
histogram =
meter
.histogramBuilder(METRIC_NAME)
.setDescription(METRIC_DESCRIPTION)
.setUnit(PERCENTAGE)
.build();
meter
.gaugeBuilder(METRIC_NAME_PROCESS)
.setDescription(METRIC_DESCRIPTION_PROCESS)
.setUnit(UNIT_UTILIZATION)
.buildWithCallback(
measurement -> {
measurement.record(process);
});
meter
.gaugeBuilder(METRIC_NAME_MACHINE)
.setDescription(METRIC_DESCRIPTION_MACHINE)
.setUnit(UNIT_UTILIZATION)
.buildWithCallback(
measurement -> {
measurement.record(machine);
});
}

@Override
public void accept(RecordedEvent ev) {
if (ev.hasField(JVM_USER)) {
histogram.record(ev.getDouble(JVM_USER), ATTR_USER);
}
if (ev.hasField(JVM_SYSTEM)) {
histogram.record(ev.getDouble(JVM_SYSTEM), ATTR_SYSTEM);
if (ev.hasField(JVM_USER) && ev.hasField(JVM_SYSTEM)) {
process = ev.getDouble(JVM_USER) + ev.getDouble(JVM_SYSTEM);
}
if (ev.hasField(MACHINE_TOTAL)) {
histogram.record(ev.getDouble(MACHINE_TOTAL), ATTR_MACHINE);
machine = ev.getDouble(MACHINE_TOTAL);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,19 @@

package io.opentelemetry.contrib.jfr.metrics.internal.memory;

import static io.opentelemetry.contrib.jfr.metrics.internal.Constants.ATTR_USAGE;
import static io.opentelemetry.contrib.jfr.metrics.internal.Constants.ATTR_POOL;
import static io.opentelemetry.contrib.jfr.metrics.internal.Constants.ATTR_TYPE;
import static io.opentelemetry.contrib.jfr.metrics.internal.Constants.BYTES;
import static io.opentelemetry.contrib.jfr.metrics.internal.Constants.EDEN_SIZE;
import static io.opentelemetry.contrib.jfr.metrics.internal.Constants.EDEN_SIZE_DELTA;
import static io.opentelemetry.contrib.jfr.metrics.internal.Constants.EDEN_USED;
import static io.opentelemetry.contrib.jfr.metrics.internal.Constants.REGION_COUNT;
import static io.opentelemetry.contrib.jfr.metrics.internal.Constants.SURVIVOR_SIZE;
import static io.opentelemetry.contrib.jfr.metrics.internal.Constants.HEAP;
import static io.opentelemetry.contrib.jfr.metrics.internal.Constants.METRIC_DESCRIPTION_MEMORY;
import static io.opentelemetry.contrib.jfr.metrics.internal.Constants.METRIC_DESCRIPTION_MEMORY_AFTER;
import static io.opentelemetry.contrib.jfr.metrics.internal.Constants.METRIC_NAME_MEMORY;
import static io.opentelemetry.contrib.jfr.metrics.internal.Constants.METRIC_NAME_MEMORY_AFTER;
import static io.opentelemetry.contrib.jfr.metrics.internal.RecordedEventHandler.defaultMeter;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.LongHistogram;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.contrib.jfr.metrics.internal.RecordedEventHandler;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import jdk.jfr.consumer.RecordedEvent;

Expand All @@ -30,38 +28,49 @@
public final class G1HeapSummaryHandler implements RecordedEventHandler {
private static final Logger logger = Logger.getLogger(G1HeapSummaryHandler.class.getName());

private static final String METRIC_NAME_MEMORY = "process.runtime.jvm.memory.used";
private static final String METRIC_DESCRIPTION_MEMORY = "Heap utilization";
private static final String EVENT_NAME = "jdk.G1HeapSummary";
private static final String BEFORE = "Before GC";
private static final String AFTER = "After GC";
private static final String GC_ID = "gcId";
private static final String EDEN_USED_SIZE = "edenUsedSize";
private static final String SURVIVOR_USED_SIZE = "survivorUsedSize";
private static final String WHEN = "when";
private static final Attributes ATTR_MEMORY_EDEN_USED = Attributes.of(ATTR_USAGE, EDEN_USED);
private static final Attributes ATTR_MEMORY_EDEN_SIZE = Attributes.of(ATTR_USAGE, EDEN_SIZE);
private static final Attributes ATTR_MEMORY_EDEN_SIZE_DELTA =
Attributes.of(ATTR_USAGE, EDEN_SIZE_DELTA);
private static final Attributes ATTR_MEMORY_SURVIVOR_SIZE =
Attributes.of(ATTR_USAGE, SURVIVOR_SIZE);
private static final Attributes ATTR_MEMORY_REGIONS = Attributes.of(ATTR_USAGE, REGION_COUNT);
private static final Attributes ATTR_MEMORY_EDEN_USED =
Attributes.of(ATTR_TYPE, HEAP, ATTR_POOL, "G1 Eden Space");
private static final Attributes ATTR_MEMORY_SURVIVOR_USED =
Attributes.of(ATTR_TYPE, HEAP, ATTR_POOL, "G1 Survivor Space");
// private static final Attributes ATTR_MEMORY_OLD_USED =
// Attributes.of(ATTR_TYPE, HEAP, ATTR_POOL, "G1 Old Gen"); // TODO needs jdk JFR support

private final Map<Long, RecordedEvent> awaitingPairs = new HashMap<>();

private LongHistogram memoryHistogram;
private volatile long usageEden = 0;
private volatile long usageEdenAfter = 0;
private volatile long usageSurvivor = 0;
private volatile long usageSurvivorAfter = 0;

public G1HeapSummaryHandler() {
initializeMeter(defaultMeter());
}

@Override
public void initializeMeter(Meter meter) {
memoryHistogram =
meter
.histogramBuilder(METRIC_NAME_MEMORY)
.setDescription(METRIC_DESCRIPTION_MEMORY)
.setUnit(BYTES)
.ofLongs()
.build();
meter
.upDownCounterBuilder(METRIC_NAME_MEMORY)
.setDescription(METRIC_DESCRIPTION_MEMORY)
.setUnit(BYTES)
.buildWithCallback(
measurement -> {
measurement.record(usageEden, ATTR_MEMORY_EDEN_USED);
measurement.record(usageSurvivor, ATTR_MEMORY_SURVIVOR_USED);
});
meter
.upDownCounterBuilder(METRIC_NAME_MEMORY_AFTER)
.setDescription(METRIC_DESCRIPTION_MEMORY_AFTER)
.setUnit(BYTES)
.buildWithCallback(
measurement -> {
measurement.record(usageEdenAfter, ATTR_MEMORY_EDEN_USED);
measurement.record(usageSurvivorAfter, ATTR_MEMORY_SURVIVOR_USED);
});
}

@Override
Expand All @@ -87,37 +96,24 @@ public void accept(RecordedEvent ev) {
logger.fine(String.format("G1 GC Event seen without GC ID: %s", ev));
return;
}
long gcId = ev.getLong(GC_ID);
recordValues(ev, when != null ? when.equals(BEFORE) : false);
roberttoyonaga marked this conversation as resolved.
Show resolved Hide resolved
}

var pair = awaitingPairs.remove(gcId);
if (pair == null) {
awaitingPairs.put(gcId, ev);
} else {
if (when.equals(BEFORE)) {
recordValues(ev, pair);
} else { // i.e. when.equals(AFTER)
recordValues(pair, ev);
private void recordValues(RecordedEvent event, boolean before) {
if (event.hasField(EDEN_USED_SIZE)) {
if (before) {
usageEden = event.getLong(EDEN_USED_SIZE);
} else {
usageEdenAfter = event.getLong(EDEN_USED_SIZE);
}
}
}

private void recordValues(RecordedEvent before, RecordedEvent after) {
if (after.hasField("edenUsedSize")) {
memoryHistogram.record(after.getLong("edenUsedSize"), ATTR_MEMORY_EDEN_USED);
if (before.hasField("edenUsedSize")) {
memoryHistogram.record(
after.getLong("edenUsedSize") - before.getLong("edenUsedSize"),
ATTR_MEMORY_EDEN_SIZE_DELTA);
if (event.hasField(SURVIVOR_USED_SIZE)) {
if (before) {
usageSurvivor = event.getLong(SURVIVOR_USED_SIZE);
} else {
usageSurvivorAfter = event.getLong(SURVIVOR_USED_SIZE);
}
}
if (after.hasField("edenTotalSize")) {
memoryHistogram.record(after.getLong("edenTotalSize"), ATTR_MEMORY_EDEN_SIZE);
}
if (after.hasField("survivorUsedSize")) {
memoryHistogram.record(after.getLong("survivorUsedSize"), ATTR_MEMORY_SURVIVOR_SIZE);
}
if (after.hasField("numberOfRegions")) {
memoryHistogram.record(after.getLong("numberOfRegions"), ATTR_MEMORY_REGIONS);
}
}
}
Loading