io.opentelemetry.instrumentation.jmx.engine.MetricRegistrar Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of opentelemetry-jmx-metrics Show documentation
Show all versions of opentelemetry-jmx-metrics Show documentation
Instrumentation of Java libraries using OpenTelemetry.
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.jmx.engine;
import static java.util.logging.Level.INFO;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.metrics.DoubleGaugeBuilder;
import io.opentelemetry.api.metrics.LongCounterBuilder;
import io.opentelemetry.api.metrics.LongUpDownCounterBuilder;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.ObservableDoubleMeasurement;
import io.opentelemetry.api.metrics.ObservableLongMeasurement;
import java.util.Collection;
import java.util.function.Consumer;
import java.util.logging.Logger;
import javax.management.MBeanServer;
import javax.management.ObjectName;
/** A class responsible for maintaining the set of metrics to collect and report. */
class MetricRegistrar {
private static final Logger logger = Logger.getLogger(MetricRegistrar.class.getName());
private final Meter meter;
MetricRegistrar(OpenTelemetry openTelemetry, String instrumentationScope) {
meter = openTelemetry.getMeter(instrumentationScope);
}
/**
* Accepts a MetricExtractor for registration and activation.
*
* @param server the MBeanServer to use to query for metric values
* @param objectNames the Objectnames that are known to the server and that know the attribute
* that is required to get the metric values
* @param extractor the MetricExtractor responsible for getting the metric values
*/
void enrollExtractor(
MBeanServer server,
Collection objectNames,
MetricExtractor extractor,
AttributeInfo attributeInfo) {
// For the first enrollment of the extractor we have to build the corresponding Instrument
DetectionStatus status = new DetectionStatus(server, objectNames);
boolean firstEnrollment;
synchronized (extractor) {
firstEnrollment = extractor.getStatus() == null;
// For successive enrollments, it is sufficient to refresh the status
extractor.setStatus(status);
}
if (firstEnrollment) {
MetricInfo metricInfo = extractor.getInfo();
String metricName = metricInfo.getMetricName();
MetricInfo.Type instrumentType = metricInfo.getType();
String description =
metricInfo.getDescription() != null
? metricInfo.getDescription()
: attributeInfo.getDescription();
String unit = metricInfo.getUnit();
switch (instrumentType) {
// CHECKSTYLE:OFF
case COUNTER:
{
// CHECKSTYLE:ON
LongCounterBuilder builder = meter.counterBuilder(metricName);
if (description != null) {
builder = builder.setDescription(description);
}
if (unit != null) {
builder = builder.setUnit(unit);
}
if (attributeInfo.usesDoubleValues()) {
builder.ofDoubles().buildWithCallback(doubleTypeCallback(extractor));
} else {
builder.buildWithCallback(longTypeCallback(extractor));
}
logger.log(INFO, "Created Counter for {0}", metricName);
}
break;
// CHECKSTYLE:OFF
case UPDOWNCOUNTER:
{
// CHECKSTYLE:ON
LongUpDownCounterBuilder builder = meter.upDownCounterBuilder(metricName);
if (description != null) {
builder = builder.setDescription(description);
}
if (unit != null) {
builder = builder.setUnit(unit);
}
if (attributeInfo.usesDoubleValues()) {
builder.ofDoubles().buildWithCallback(doubleTypeCallback(extractor));
} else {
builder.buildWithCallback(longTypeCallback(extractor));
}
logger.log(INFO, "Created UpDownCounter for {0}", metricName);
}
break;
// CHECKSTYLE:OFF
case GAUGE:
{
// CHECKSTYLE:ON
DoubleGaugeBuilder builder = meter.gaugeBuilder(metricName);
if (description != null) {
builder = builder.setDescription(description);
}
if (unit != null) {
builder = builder.setUnit(unit);
}
if (attributeInfo.usesDoubleValues()) {
builder.buildWithCallback(doubleTypeCallback(extractor));
} else {
builder.ofLongs().buildWithCallback(longTypeCallback(extractor));
}
logger.log(INFO, "Created Gauge for {0}", metricName);
}
}
}
}
/*
* A method generating metric collection callback for asynchronous Measurement
* of Double type.
*/
static Consumer doubleTypeCallback(MetricExtractor extractor) {
return measurement -> {
DetectionStatus status = extractor.getStatus();
if (status != null) {
MBeanServer server = status.getServer();
for (ObjectName objectName : status.getObjectNames()) {
Number metricValue =
extractor.getMetricValueExtractor().extractNumericalAttribute(server, objectName);
if (metricValue != null) {
// get the metric attributes
Attributes attr = createMetricAttributes(server, objectName, extractor);
measurement.record(metricValue.doubleValue(), attr);
}
}
}
};
}
/*
* A method generating metric collection callback for asynchronous Measurement
* of Long type.
*/
static Consumer longTypeCallback(MetricExtractor extractor) {
return measurement -> {
DetectionStatus status = extractor.getStatus();
if (status != null) {
MBeanServer server = status.getServer();
for (ObjectName objectName : status.getObjectNames()) {
Number metricValue =
extractor.getMetricValueExtractor().extractNumericalAttribute(server, objectName);
if (metricValue != null) {
// get the metric attributes
Attributes attr = createMetricAttributes(server, objectName, extractor);
measurement.record(metricValue.longValue(), attr);
}
}
}
};
}
/*
* An auxiliary method for collecting measurement attributes to go along
* the metric values
*/
static Attributes createMetricAttributes(
MBeanServer server, ObjectName objectName, MetricExtractor extractor) {
MetricAttribute[] metricAttributes = extractor.getAttributes();
AttributesBuilder attrBuilder = Attributes.builder();
for (MetricAttribute metricAttribute : metricAttributes) {
String attributeValue = metricAttribute.acquireAttributeValue(server, objectName);
if (attributeValue != null) {
attrBuilder = attrBuilder.put(metricAttribute.getAttributeName(), attributeValue);
}
}
return attrBuilder.build();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy