Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,39 @@
public class OpenMetrics2Properties {

private static final String PREFIX = "io.prometheus.openmetrics2";
private static final String ENABLED = "enabled";
private static final String CONTENT_NEGOTIATION = "content_negotiation";
private static final String COMPOSITE_VALUES = "composite_values";
private static final String EXEMPLAR_COMPLIANCE = "exemplar_compliance";
private static final String NATIVE_HISTOGRAMS = "native_histograms";

@Nullable private final Boolean enabled;
@Nullable private final Boolean contentNegotiation;
@Nullable private final Boolean compositeValues;
@Nullable private final Boolean exemplarCompliance;
@Nullable private final Boolean nativeHistograms;

private OpenMetrics2Properties(
@Nullable Boolean enabled,
@Nullable Boolean contentNegotiation,
@Nullable Boolean compositeValues,
@Nullable Boolean exemplarCompliance,
@Nullable Boolean nativeHistograms) {
this.enabled = enabled;
this.contentNegotiation = contentNegotiation;
this.compositeValues = compositeValues;
this.exemplarCompliance = exemplarCompliance;
this.nativeHistograms = nativeHistograms;
}

/**
* Enable the OpenMetrics 2.0 text format writer. When {@code true}, the OM2 writer is used
* instead of OM1 for OpenMetrics responses. Default is {@code false}.
*/
public boolean getEnabled() {
return enabled != null && enabled;
}

/** Gate OM2 features behind content negotiation. Default is {@code false}. */
public boolean getContentNegotiation() {
return contentNegotiation != null && contentNegotiation;
Expand All @@ -56,12 +68,13 @@ public boolean getNativeHistograms() {
*/
static OpenMetrics2Properties load(PropertySource propertySource)
throws PrometheusPropertiesException {
Boolean enabled = Util.loadBoolean(PREFIX, ENABLED, propertySource);
Boolean contentNegotiation = Util.loadBoolean(PREFIX, CONTENT_NEGOTIATION, propertySource);
Boolean compositeValues = Util.loadBoolean(PREFIX, COMPOSITE_VALUES, propertySource);
Boolean exemplarCompliance = Util.loadBoolean(PREFIX, EXEMPLAR_COMPLIANCE, propertySource);
Boolean nativeHistograms = Util.loadBoolean(PREFIX, NATIVE_HISTOGRAMS, propertySource);
return new OpenMetrics2Properties(
contentNegotiation, compositeValues, exemplarCompliance, nativeHistograms);
enabled, contentNegotiation, compositeValues, exemplarCompliance, nativeHistograms);
}

public static Builder builder() {
Expand All @@ -70,13 +83,20 @@ public static Builder builder() {

public static class Builder {

@Nullable private Boolean enabled;
@Nullable private Boolean contentNegotiation;
@Nullable private Boolean compositeValues;
@Nullable private Boolean exemplarCompliance;
@Nullable private Boolean nativeHistograms;

private Builder() {}

/** See {@link #getEnabled()} */
public Builder enabled(boolean enabled) {
this.enabled = enabled;
return this;
}

/** See {@link #getContentNegotiation()} */
public Builder contentNegotiation(boolean contentNegotiation) {
this.contentNegotiation = contentNegotiation;
Expand All @@ -103,6 +123,7 @@ public Builder nativeHistograms(boolean nativeHistograms) {

/** Enable all OpenMetrics 2.0 features */
public Builder enableAll() {
this.enabled = true;
this.contentNegotiation = true;
this.compositeValues = true;
this.exemplarCompliance = true;
Expand All @@ -112,7 +133,7 @@ public Builder enableAll() {

public OpenMetrics2Properties build() {
return new OpenMetrics2Properties(
contentNegotiation, compositeValues, exemplarCompliance, nativeHistograms);
enabled, contentNegotiation, compositeValues, exemplarCompliance, nativeHistograms);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,8 @@ public Builder exporterOpenTelemetryProperties(
}

public Builder enableOpenMetrics2(Consumer<OpenMetrics2Properties.Builder> configurator) {
OpenMetrics2Properties.Builder openMetrics2Builder = OpenMetrics2Properties.builder();
OpenMetrics2Properties.Builder openMetrics2Builder =
OpenMetrics2Properties.builder().enabled(true);
configurator.accept(openMetrics2Builder);
this.openMetrics2Properties = openMetrics2Builder.build();
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ void load() {
load(
new HashMap<>(
Map.of(
"io.prometheus.openmetrics2.enabled",
"true",
"io.prometheus.openmetrics2.content_negotiation",
"true",
"io.prometheus.openmetrics2.composite_values",
Expand All @@ -23,6 +25,7 @@ void load() {
"true",
"io.prometheus.openmetrics2.native_histograms",
"true")));
assertThat(properties.getEnabled()).isTrue();
assertThat(properties.getContentNegotiation()).isTrue();
assertThat(properties.getCompositeValues()).isTrue();
assertThat(properties.getExemplarCompliance()).isTrue();
Expand All @@ -31,6 +34,11 @@ void load() {

@Test
void loadInvalidValue() {
assertThatExceptionOfType(PrometheusPropertiesException.class)
.isThrownBy(
() -> load(new HashMap<>(Map.of("io.prometheus.openmetrics2.enabled", "invalid"))))
.withMessage(
"io.prometheus.openmetrics2.enabled: Expecting 'true' or 'false'. Found: invalid");
assertThatExceptionOfType(PrometheusPropertiesException.class)
.isThrownBy(
() ->
Expand Down Expand Up @@ -79,11 +87,13 @@ private static OpenMetrics2Properties load(Map<String, String> map) {
void builder() {
OpenMetrics2Properties properties =
OpenMetrics2Properties.builder()
.enabled(true)
.contentNegotiation(true)
.compositeValues(false)
.exemplarCompliance(true)
.nativeHistograms(false)
.build();
assertThat(properties.getEnabled()).isTrue();
assertThat(properties.getContentNegotiation()).isTrue();
assertThat(properties.getCompositeValues()).isFalse();
assertThat(properties.getExemplarCompliance()).isTrue();
Expand All @@ -93,6 +103,7 @@ void builder() {
@Test
void builderEnableAll() {
OpenMetrics2Properties properties = OpenMetrics2Properties.builder().enableAll().build();
assertThat(properties.getEnabled()).isTrue();
assertThat(properties.getContentNegotiation()).isTrue();
assertThat(properties.getCompositeValues()).isTrue();
assertThat(properties.getExemplarCompliance()).isTrue();
Expand All @@ -102,6 +113,7 @@ void builderEnableAll() {
@Test
void defaultValues() {
OpenMetrics2Properties properties = OpenMetrics2Properties.builder().build();
assertThat(properties.getEnabled()).isFalse();
assertThat(properties.getContentNegotiation()).isFalse();
assertThat(properties.getCompositeValues()).isFalse();
assertThat(properties.getExemplarCompliance()).isFalse();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,7 @@ public ExpositionFormatWriter findWriter(@Nullable String acceptHeader) {
}

private boolean isOpenMetrics2Enabled() {
OpenMetrics2Properties props = openMetrics2TextFormatWriter.getOpenMetrics2Properties();
return props.getContentNegotiation()
|| props.getCompositeValues()
|| props.getExemplarCompliance()
|| props.getNativeHistograms();
return openMetrics2TextFormatWriter.getOpenMetrics2Properties().getEnabled();
}

public PrometheusProtobufWriter getPrometheusProtobufWriter() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,77 +119,51 @@ void testOM2DisabledByDefault() {
}

@Test
void testOM2EnabledWithContentNegotiation() {
void testOM2EnabledOnly() {
PrometheusProperties props =
PrometheusProperties.builder()
.openMetrics2Properties(
OpenMetrics2Properties.builder().contentNegotiation(true).build())
.openMetrics2Properties(OpenMetrics2Properties.builder().enabled(true).build())
.build();
ExpositionFormats formats = ExpositionFormats.init(props);
ExpositionFormatWriter writer = formats.findWriter("application/openmetrics-text");
// When contentNegotiation is enabled, should return OM2 writer
assertThat(writer).isInstanceOf(OpenMetrics2TextFormatWriter.class);
}

@Test
void testOM2EnabledWithCompositeValues() {
PrometheusProperties props =
PrometheusProperties.builder()
.openMetrics2Properties(OpenMetrics2Properties.builder().compositeValues(true).build())
.build();
ExpositionFormats formats = ExpositionFormats.init(props);
ExpositionFormatWriter writer = formats.findWriter("application/openmetrics-text");
assertThat(writer).isInstanceOf(OpenMetrics2TextFormatWriter.class);
}

@Test
void testOM2EnabledWithExemplarCompliance() {
void testOM2NotEnabledByFeatureFlagAlone() {
// Feature flags without enabled=true should not activate the OM2 writer
PrometheusProperties props =
PrometheusProperties.builder()
.openMetrics2Properties(
OpenMetrics2Properties.builder().exemplarCompliance(true).build())
.build();
ExpositionFormats formats = ExpositionFormats.init(props);
ExpositionFormatWriter writer = formats.findWriter("application/openmetrics-text");
// When exemplarCompliance is enabled, should return OM2 writer
assertThat(writer).isInstanceOf(OpenMetrics2TextFormatWriter.class);
}

@Test
void testOM2EnabledWithNativeHistograms() {
PrometheusProperties props =
PrometheusProperties.builder()
.openMetrics2Properties(OpenMetrics2Properties.builder().nativeHistograms(true).build())
OpenMetrics2Properties.builder().contentNegotiation(true).build())
.build();
ExpositionFormats formats = ExpositionFormats.init(props);
ExpositionFormatWriter writer = formats.findWriter("application/openmetrics-text");
// When nativeHistograms is enabled, should return OM2 writer
assertThat(writer).isInstanceOf(OpenMetrics2TextFormatWriter.class);
assertThat(writer).isInstanceOf(OpenMetricsTextFormatWriter.class);
}

@Test
void testOM2EnabledWithMultipleFlags() {
void testOM2EnabledWithFeatureFlags() {
PrometheusProperties props =
PrometheusProperties.builder()
.openMetrics2Properties(
OpenMetrics2Properties.builder()
.enabled(true)
.contentNegotiation(true)
.compositeValues(true)
.nativeHistograms(true)
.build())
.build();
ExpositionFormats formats = ExpositionFormats.init(props);
ExpositionFormatWriter writer = formats.findWriter("application/openmetrics-text");
// When multiple OM2 flags are enabled, should return OM2 writer
assertThat(writer).isInstanceOf(OpenMetrics2TextFormatWriter.class);
}

@Test
void testProtobufWriterTakesPrecedence() {
PrometheusProperties props =
PrometheusProperties.builder()
.openMetrics2Properties(
OpenMetrics2Properties.builder().contentNegotiation(true).build())
.openMetrics2Properties(OpenMetrics2Properties.builder().enabled(true).build())
.build();
ExpositionFormats formats = ExpositionFormats.init(props);
ExpositionFormatWriter writer =
Expand Down
Loading