Skip to content

Commit

Permalink
[Metric Framework] Adds support for Histogram metric
Browse files Browse the repository at this point in the history
Signed-off-by: Gagan Juneja <[email protected]>
  • Loading branch information
Gagan Juneja committed Jan 29, 2024
1 parent 1ec5305 commit d5239fe
Show file tree
Hide file tree
Showing 14 changed files with 260 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ public Counter createUpDownCounter(String name, String description, String unit)
return metricsTelemetry.createUpDownCounter(name, description, unit);
}

@Override
public Histogram createHistogram(String name, String description, String unit) {
return metricsTelemetry.createHistogram(name, description, unit);
}

@Override
public void close() throws IOException {
metricsTelemetry.close();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.telemetry.metrics;

import org.opensearch.common.annotation.ExperimentalApi;
import org.opensearch.telemetry.metrics.tags.Tags;

/**
* Histogram records the value for an existing metric.
* {@opensearch.experimental}
*/
@ExperimentalApi
public interface Histogram {

/**
* record value.
* @param value value to be added.
*/
void record(double value);

/**
* record value along with the attributes.
*
* @param value value to be added.
* @param tags attributes/dimensions of the metric.
*/
void record(double value, Tags tags);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.telemetry.metrics;

/**
* Histogram type, primarily depends on bucketing strategy.
*/
public enum HistogramType {
/**
* Fixed buckets.
*/
FIXED_BUCKET,
/**
* Buckets will be defined dynamically based on the value distribution.
*/
DYNAMIC;
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,14 @@ public interface MetricsRegistry extends Closeable {
* @return counter.
*/
Counter createUpDownCounter(String name, String description, String unit);

/**
* Creates the histogram type of Metric.
*
* @param name name of the histogram.
* @param description any description about the metric.
* @param unit unit of the metric.
* @return histogram.
*/
Histogram createHistogram(String name, String description, String unit);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.telemetry.metrics.noop;

import org.opensearch.common.annotation.InternalApi;
import org.opensearch.telemetry.metrics.Histogram;
import org.opensearch.telemetry.metrics.tags.Tags;

/**
* No-op {@link Histogram}
* {@opensearch.internal}
*/
@InternalApi
public class NoopHistogram implements Histogram {

/**
* No-op Histogram instance
*/
public final static NoopHistogram INSTANCE = new NoopHistogram();

private NoopHistogram() {}

@Override
public void record(double value) {

}

@Override
public void record(double value, Tags tags) {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import org.opensearch.common.annotation.InternalApi;
import org.opensearch.telemetry.metrics.Counter;
import org.opensearch.telemetry.metrics.Histogram;
import org.opensearch.telemetry.metrics.MetricsRegistry;

import java.io.IOException;
Expand Down Expand Up @@ -38,6 +39,11 @@ public Counter createUpDownCounter(String name, String description, String unit)
return NoopCounter.INSTANCE;
}

@Override
public Histogram createHistogram(String name, String description, String unit) {
return NoopHistogram.INSTANCE;
}

@Override
public void close() throws IOException {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ public List<Setting<?>> getSettings() {
OTelTelemetrySettings.TRACER_EXPORTER_DELAY_SETTING,
OTelTelemetrySettings.TRACER_EXPORTER_MAX_QUEUE_SIZE_SETTING,
OTelTelemetrySettings.OTEL_TRACER_SPAN_EXPORTER_CLASS_SETTING,
OTelTelemetrySettings.OTEL_METRICS_EXPORTER_CLASS_SETTING
OTelTelemetrySettings.OTEL_METRICS_EXPORTER_CLASS_SETTING,
OTelTelemetrySettings.OTEL_METRICS_HISTOGRAM_EXPONENTIAL_MAX_SCALE,
OTelTelemetrySettings.OTEL_METRICS_HISTOGRAM_EXPONENTIAL_MAX_BUCKETS,
OTelTelemetrySettings.OTEL_METRICS_HISTOGRAM_FIXED_BUCKETS
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Arrays;
import java.util.List;

import io.opentelemetry.exporter.logging.LoggingMetricExporter;
import io.opentelemetry.exporter.logging.LoggingSpanExporter;
Expand Down Expand Up @@ -110,4 +112,37 @@ private OTelTelemetrySettings() {}
Setting.Property.NodeScope,
Setting.Property.Final
);

/**
* Max scale setting for the {@link io.opentelemetry.sdk.metrics.internal.view.Base2ExponentialHistogramAggregation}
*/
public static final Setting<Integer> OTEL_METRICS_HISTOGRAM_EXPONENTIAL_MAX_SCALE = Setting.intSetting(
"telemetry.otel.metrics.histogram.exponential.max.scale",
20,
-10,
Setting.Property.NodeScope,
Setting.Property.Final
);

/**
* Max buckets setting for the {@link io.opentelemetry.sdk.metrics.internal.view.Base2ExponentialHistogramAggregation}
*/
public static final Setting<Integer> OTEL_METRICS_HISTOGRAM_EXPONENTIAL_MAX_BUCKETS = Setting.intSetting(
"telemetry.otel.metrics.histogram.exponential.max.buckets",
160,
1,
Setting.Property.NodeScope,
Setting.Property.Final
);

/**
* Explicit bucket list setting for the {@link io.opentelemetry.sdk.metrics.internal.view.ExplicitBucketHistogramAggregation}
*/
public static final Setting<List<Double>> OTEL_METRICS_HISTOGRAM_FIXED_BUCKETS = Setting.listSetting(
"telemetry.otel.metrics.histogram.fixed.buckets",
Arrays.asList("0", "5", "10", "25", "50", "75", "100", "250", "500", "750", "1000", "2500", "5000", "7500", "10000"),
Double::parseDouble,
Setting.Property.NodeScope,
Setting.Property.Final
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.telemetry.metrics;

import org.opensearch.telemetry.OTelAttributesConverter;
import org.opensearch.telemetry.metrics.tags.Tags;

import io.opentelemetry.api.metrics.DoubleHistogram;

/**
* OTel aware implementation {@link Histogram}
*/
class OTelHistogram implements Histogram {

private final DoubleHistogram otelDoubleHistogram;

/**
* Constructor
* @param otelDoubleCounter delegate counter.
*/
public OTelHistogram(DoubleHistogram otelDoubleCounter) {
this.otelDoubleHistogram = otelDoubleCounter;
}

@Override
public void record(double value) {
otelDoubleHistogram.record(value);
}

@Override
public void record(double value, Tags tags) {
otelDoubleHistogram.record(value, OTelAttributesConverter.convert(tags));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.security.PrivilegedAction;

import io.opentelemetry.api.metrics.DoubleCounter;
import io.opentelemetry.api.metrics.DoubleHistogram;
import io.opentelemetry.api.metrics.DoubleUpDownCounter;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.MeterProvider;
Expand Down Expand Up @@ -68,6 +69,22 @@ public Counter createUpDownCounter(String name, String description, String unit)
return new OTelUpDownCounter(doubleUpDownCounter);
}

/**
* Creates the Otel Histogram. It created the default version. In {@link org.opensearch.telemetry.tracing.OTelResourceProvider}
* we can configure the bucketing strategy through view.
* @param name name of the histogram.
* @param description any description about the metric.
* @param unit unit of the metric.
* @return histogram
*/
@Override
public Histogram createHistogram(String name, String description, String unit) {
DoubleHistogram doubleHistogram = AccessController.doPrivileged(
(PrivilegedAction<DoubleHistogram>) () -> otelMeter.histogramBuilder(name).setUnit(unit).setDescription(description).build()
);
return new OTelHistogram(doubleHistogram);
}

@Override
public void close() throws IOException {
meterProvider.close();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
package org.opensearch.telemetry.tracing;

import org.opensearch.common.settings.Settings;
import org.opensearch.telemetry.OTelTelemetrySettings;
import org.opensearch.telemetry.TelemetrySettings;
import org.opensearch.telemetry.metrics.HistogramType;
import org.opensearch.telemetry.metrics.exporter.OTelMetricsExporterFactory;
import org.opensearch.telemetry.tracing.exporter.OTelSpanExporterFactory;
import org.opensearch.telemetry.tracing.sampler.ProbabilisticSampler;
Expand All @@ -23,8 +25,13 @@
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.metrics.InstrumentSelector;
import io.opentelemetry.sdk.metrics.InstrumentType;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.sdk.metrics.View;
import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader;
import io.opentelemetry.sdk.metrics.internal.view.Base2ExponentialHistogramAggregation;
import io.opentelemetry.sdk.metrics.internal.view.ExplicitBucketHistogramAggregation;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
Expand Down Expand Up @@ -92,9 +99,29 @@ private static SdkMeterProvider createSdkMetricProvider(Settings settings, Resou
.setInterval(TelemetrySettings.METRICS_PUBLISH_INTERVAL_SETTING.get(settings).getSeconds(), TimeUnit.SECONDS)
.build()
)
.registerView(InstrumentSelector.builder().setType(InstrumentType.HISTOGRAM).build(), createHistogramTypeView(settings))
.build();
}

private static View createHistogramTypeView(Settings settings) {
if (HistogramType.DYNAMIC == TelemetrySettings.METRICS_HISTOGRAM_TYPE.get(settings)) {
return View.builder()
.setAggregation(
Base2ExponentialHistogramAggregation.create(
OTelTelemetrySettings.OTEL_METRICS_HISTOGRAM_EXPONENTIAL_MAX_BUCKETS.get(settings),
OTelTelemetrySettings.OTEL_METRICS_HISTOGRAM_EXPONENTIAL_MAX_SCALE.get(settings)
)
)
.build();
} else {
return View.builder()
.setAggregation(
ExplicitBucketHistogramAggregation.create(OTelTelemetrySettings.OTEL_METRICS_HISTOGRAM_FIXED_BUCKETS.get(settings))
)
.build();
}
}

private static SdkTracerProvider createSdkTracerProvider(
Settings settings,
SpanExporter spanExporter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,7 @@ public void apply(Settings value, Settings current, Settings previous) {
TelemetrySettings.TRACER_ENABLED_SETTING,
TelemetrySettings.TRACER_SAMPLER_PROBABILITY,
TelemetrySettings.METRICS_PUBLISH_INTERVAL_SETTING,
TelemetrySettings.METRICS_HISTOGRAM_TYPE,
TelemetrySettings.TRACER_FEATURE_ENABLED_SETTING,
TelemetrySettings.METRICS_FEATURE_ENABLED_SETTING
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.opensearch.common.settings.Setting;
import org.opensearch.common.settings.Settings;
import org.opensearch.common.unit.TimeValue;
import org.opensearch.telemetry.metrics.HistogramType;

/**
* Wrapper class to encapsulate tracing related settings
Expand Down Expand Up @@ -64,6 +65,17 @@ public class TelemetrySettings {
Setting.Property.Final
);

/**
* Histogram type to be used for {@link org.opensearch.telemetry.metrics.Histogram} metric.
*/
public static final Setting<HistogramType> METRICS_HISTOGRAM_TYPE = new Setting<>(
"telemetry.histogram.type",
HistogramType.FIXED_BUCKET.toString(),
HistogramType::valueOf,
Setting.Property.NodeScope,
Setting.Property.Final
);

private volatile boolean tracingEnabled;
private volatile double samplingProbability;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
import org.opensearch.telemetry.Telemetry;
import org.opensearch.telemetry.TelemetrySettings;
import org.opensearch.telemetry.metrics.Counter;
import org.opensearch.telemetry.metrics.Histogram;
import org.opensearch.telemetry.metrics.MetricsTelemetry;
import org.opensearch.telemetry.metrics.noop.NoopCounter;
import org.opensearch.telemetry.metrics.noop.NoopHistogram;
import org.opensearch.telemetry.tracing.TracingTelemetry;
import org.opensearch.test.telemetry.tracing.MockTracingTelemetry;

Expand Down Expand Up @@ -46,6 +48,11 @@ public Counter createUpDownCounter(String name, String description, String unit)
return NoopCounter.INSTANCE;
}

@Override
public Histogram createHistogram(String name, String description, String unit) {
return NoopHistogram.INSTANCE;
}

@Override
public void close() {

Expand Down

0 comments on commit d5239fe

Please sign in to comment.