io.quarkus.micrometer.runtime.registry.json.JsonExporter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of quarkus-micrometer Show documentation
Show all versions of quarkus-micrometer Show documentation
Instrument the runtime and your application with dimensional metrics using Micrometer.
package io.quarkus.micrometer.runtime.registry.json;
import static io.quarkus.jsonp.JsonProviderHolder.jsonProvider;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import jakarta.json.JsonObject;
import jakarta.json.JsonObjectBuilder;
import jakarta.json.JsonValue;
import jakarta.json.JsonWriter;
import jakarta.json.stream.JsonGenerator;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.DistributionSummary;
import io.micrometer.core.instrument.FunctionCounter;
import io.micrometer.core.instrument.FunctionTimer;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.LongTaskTimer;
import io.micrometer.core.instrument.Meter;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.TimeGauge;
import io.micrometer.core.instrument.Timer;
import io.micrometer.core.instrument.distribution.HistogramSnapshot;
import io.micrometer.core.instrument.distribution.ValueAtPercentile;
public class JsonExporter {
private static final Map JSON_CONFIG = Collections.singletonMap(JsonGenerator.PRETTY_PRINTING, true);
public JsonExporter() {
}
public StringBuilder exportEverything(JsonMeterRegistry meterRegistry) {
JsonObjectBuilder root = jsonProvider().createObjectBuilder();
List gauges = new ArrayList<>();
List counters = new ArrayList<>();
List timeGauges = new ArrayList<>();
List functionCounters = new ArrayList<>();
List timers = new ArrayList<>();
List longTaskTimers = new ArrayList<>();
List functionTimers = new ArrayList<>();
List distributionSummaries = new ArrayList<>();
List meters = new ArrayList<>();
meterRegistry.getMeters().forEach(meter -> meter.match(gauges::add,
counters::add,
timers::add,
distributionSummaries::add,
longTaskTimers::add,
timeGauges::add,
functionCounters::add,
functionTimers::add,
meters::add));
exportCounters(counters).forEach(root::add);
exportGauges(gauges).forEach(root::add);
exportTimeGauges(timeGauges).forEach(root::add);
exportFunctionCounters(functionCounters).forEach(root::add);
exportTimers(timers).forEach(root::add);
exportLongTaskTimers(longTaskTimers).forEach(root::add);
exportFunctionTimers(functionTimers).forEach(root::add);
exportDistributionSummaries(distributionSummaries).forEach(root::add);
return stringify(root.build());
}
private Map exportGauges(Collection gauges) {
Map result = new HashMap(gauges.size());
for (Gauge g : gauges) {
double value = g.value();
if (Double.isFinite(value)) {
result.put(createExportKey(g.getId()), jsonProvider().createValue(value));
}
}
return result;
}
private Map exportTimeGauges(Collection timeGauges) {
Map result = new HashMap(timeGauges.size());
for (TimeGauge g : timeGauges) {
double value = g.value();
if (Double.isFinite(value)) {
result.put(createExportKey(g.getId()), jsonProvider().createValue(value));
}
}
return result;
}
private Map exportCounters(Collection counters) {
return counters.stream()
.collect(Collectors.toMap(counter -> createExportKey(counter.getId()),
counter -> jsonProvider().createValue(counter.count())));
}
private Map exportFunctionCounters(Collection counters) {
return counters.stream()
.collect(Collectors.toMap(counter -> createExportKey(counter.getId()),
counter -> jsonProvider().createValue(counter.count())));
}
private Map exportTimers(Collection timers) {
Map> groups = timers.stream().collect(Collectors.groupingBy(timer -> timer.getId().getName()));
Map result = new HashMap<>();
for (Map.Entry> group : groups.entrySet()) {
JsonObjectBuilder builder = jsonProvider().createObjectBuilder();
for (Timer timer : group.getValue()) {
builder.add(createExportKey("count", timer.getId()), timer.count());
builder.add(createExportKey("elapsedTime", timer.getId()), timer.totalTime(timer.baseTimeUnit()));
}
result.put(group.getKey(), builder.build());
}
return result;
}
private Map exportLongTaskTimers(Collection timers) {
Map> groups = timers.stream()
.collect(Collectors.groupingBy(timer -> timer.getId().getName()));
Map result = new HashMap<>();
for (Map.Entry> group : groups.entrySet()) {
JsonObjectBuilder builder = jsonProvider().createObjectBuilder();
for (LongTaskTimer timer : group.getValue()) {
builder.add(createExportKey("activeTasks", timer.getId()), timer.activeTasks());
builder.add(createExportKey("duration", timer.getId()), timer.duration(timer.baseTimeUnit()));
builder.add(createExportKey("max", timer.getId()), timer.max(timer.baseTimeUnit()));
builder.add(createExportKey("mean", timer.getId()), timer.mean(timer.baseTimeUnit()));
}
result.put(group.getKey(), builder.build());
}
return result;
}
private Map exportFunctionTimers(Collection timers) {
Map> groups = timers.stream()
.collect(Collectors.groupingBy(timer -> timer.getId().getName()));
Map result = new HashMap<>();
for (Map.Entry> group : groups.entrySet()) {
JsonObjectBuilder builder = jsonProvider().createObjectBuilder();
for (FunctionTimer timer : group.getValue()) {
builder.add(createExportKey("count", timer.getId()), timer.count());
builder.add(createExportKey("elapsedTime", timer.getId()), timer.totalTime(timer.baseTimeUnit()));
}
result.put(group.getKey(), builder.build());
}
return result;
}
private Map exportDistributionSummaries(Collection distributionSummaries) {
Map> groups = distributionSummaries.stream()
.collect(Collectors.groupingBy(summary -> summary.getId().getName()));
Map result = new HashMap<>();
for (Map.Entry> group : groups.entrySet()) {
JsonObjectBuilder builder = jsonProvider().createObjectBuilder();
for (DistributionSummary summary : group.getValue()) {
HistogramSnapshot snapshot = summary.takeSnapshot();
if (summary instanceof JsonDistributionSummary) {
double min = ((JsonDistributionSummary) summary).min();
// if there are no samples yet, show 0 as the min
builder.add(createExportKey("min", summary.getId()), !Double.isNaN(min) ? min : 0);
}
builder.add(createExportKey("count", summary.getId()), snapshot.count());
builder.add(createExportKey("max", summary.getId()), snapshot.max());
builder.add(createExportKey("mean", summary.getId()), snapshot.mean());
for (ValueAtPercentile valueAtPercentile : snapshot.percentileValues()) {
if (Math.abs(valueAtPercentile.percentile() - 0.999) < 0.000001) {
builder.add(createExportKey("p999", summary.getId()),
valueAtPercentile.value());
} else {
builder.add(
createExportKey("p" + (int) Math.floor(valueAtPercentile.percentile() * 100), summary.getId()),
valueAtPercentile.value());
}
}
}
result.put(group.getKey(), builder.build());
}
return result;
}
private StringBuilder stringify(JsonObject obj) {
StringWriter out = new StringWriter();
try (JsonWriter writer = jsonProvider().createWriterFactory(JSON_CONFIG).createWriter(out)) {
writer.writeObject(obj);
}
return new StringBuilder(out.toString());
}
private String createExportKey(Meter.Id id) {
return id.getName() + createTagsString(id.getTags());
}
private String createExportKey(String componentKey, Meter.Id id) {
return componentKey + createTagsString(id.getTags());
}
private String createTagsString(List tags) {
if (tags == null || tags.isEmpty()) {
return "";
} else {
return ";" + tags.stream()
.map(tag -> tag.getKey() + "=" + tag.getValue()
.replace(";", "_"))
.collect(Collectors.joining(";"));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy