Skip to content

Conversation

@zeitlinger
Copy link
Member

@zeitlinger zeitlinger commented Jan 28, 2026

Summary

No Breaking Changes. This is fully backward compatible:

  • ✅ Existing camelCase properties in files still work
  • ✅ Existing system properties still work
  • ✅ Property precedence maintains existing behavior (external > system > file)
  • ✅ New environment variable layer added between external and system properties

Migration Guide

No migration required. However, to adopt the new features:

  1. To use environment variables: Convert property names to uppercase with underscores

    • io.prometheus.exporter.httpServer.portIO_PROMETHEUS_EXPORTER_HTTP_SERVER_PORT
  2. To use snake_case (recommended): Update properties files

    • io.prometheus.metrics.exemplarsEnabledio.prometheus.metrics.exemplars_enabled
    • Old camelCase names continue to work

Notes

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an environment-variable configuration layer and standardizes property naming to snake_case while preserving backward compatibility via key normalization.

Changes:

  • Introduces PropertySource to unify external, environment, and “regular” (system/file/classpath) properties with defined precedence.
  • Adds environment-variable loading (IO_PROMETHEUS_*) and camelCase→snake_case normalization for file/system/external keys.
  • Updates config docs, test resources, and tests to use the new snake_case property names and new loader APIs.

Reviewed changes

Copilot reviewed 23 out of 23 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PropertySource.java New abstraction for multi-source property lookup with precedence and key transformations.
prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java Loads properties from file/classpath/system, adds env var layer, normalizes keys, validates leftovers.
prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/Util.java Refactors property lookup helpers to read from PropertySource and improve key formatting in errors.
prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/MetricsProperties.java Migrates internal property-name constants to snake_case and updates loading/validation paths.
prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java Switches exporter property keys to snake_case and loads via PropertySource.
prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterHttpServerProperties.java Updates prefix/key naming to snake_case and loads via PropertySource.
prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java Renames filter keys to snake_case and updates loader wiring.
prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterOpenTelemetryProperties.java Renames OTel keys to snake_case and updates loader wiring.
prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterPushgatewayProperties.java Renames pushgateway keys to snake_case and updates loader wiring.
prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java Renames exemplars keys to snake_case and loads via PropertySource.
prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/UtilTest.java Updates tests to use PropertySource-based APIs.
prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesTest.java Updates loading tests to use PropertySource and asserts properties are consumed.
prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesLoaderTest.java Updates loader tests to snake_case keys.
prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/MetricsPropertiesTest.java Updates expected exception messages and property keys to snake_case.
prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterPropertiesTest.java Updates keys and loader helper to use PropertySource.
prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterHttpServerPropertiesTest.java Updates keys and loader helper to use PropertySource.
prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterFilterPropertiesTest.java Updates keys and loader helper to use PropertySource.
prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterOpenTelemetryPropertiesTest.java Updates keys and loader helper to use PropertySource.
prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterPushgatewayPropertiesTest.java Updates loader helper to use PropertySource.
prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExemplarsPropertiesTest.java Updates keys and loader helper to use PropertySource.
prometheus-metrics-config/src/test/resources/prometheus.properties Updates test properties file to snake_case keys.
prometheus-metrics-config/src/test/resources/emptyUpperBounds.properties Updates test properties key to snake_case.
docs/content/config/config.md Documents env var support, precedence, and snake_case naming; updates examples/tables.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
@zeitlinger zeitlinger force-pushed the feature/env-var-properties branch from 1d05224 to 8ee2b21 Compare January 29, 2026 11:51
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 24 out of 24 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +57 to +59
private static String normalize(String metricName) {
return metricName.replace(".", "_");
}
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MetricPropertiesMap.normalize() only replaces '.' with '_' but does not apply the same casing normalization as PrometheusPropertiesLoader.normalizePropertyKey() (which lowercases). With the new loader behavior, metric-specific properties for metrics containing uppercase letters will not be found via getMetricProperties("MyMetric"). Consider making metric-name normalization consistent between storage and lookup (either preserve case throughout, or normalize both sides the same way).

Copilot uses AI. Check for mistakes.
@@ -124,7 +165,7 @@ public Builder defaultMetricsProperties(MetricsProperties defaultMetricsProperti
}

public Builder metricProperties(Map<String, MetricsProperties> metricProperties) {
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Builder.metricProperties(...) now merges the provided map into the existing MetricPropertiesMap instead of replacing it. If callers invoke metricProperties(...) multiple times, they can no longer override/clear earlier entries. If the prior behavior was “setter” semantics, consider restoring replacement semantics (e.g., by clearing first) or renaming the method to make additive behavior explicit.

Suggested change
public Builder metricProperties(Map<String, MetricsProperties> metricProperties) {
public Builder metricProperties(Map<String, MetricsProperties> metricProperties) {
this.metricProperties.clear();

Copilot uses AI. Check for mistakes.
Comment on lines 5 to +10
/** Properties starting with io.prometheus.exporter.httpServer */
public class ExporterHttpServerProperties {

private static final String PORT = "port";
private static final String PREFER_UNCOMPRESSED_RESPONSE = "preferUncompressedResponse";
private static final String PREFIX = "io.prometheus.exporter.httpServer";
private static final String PREFER_UNCOMPRESSED_RESPONSE = "prefer_uncompressed_response";
private static final String PREFIX = "io.prometheus.exporter.http_server";
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The class-level comment still says properties start with io.prometheus.exporter.httpServer, but the effective prefix is now io.prometheus.exporter.http_server (with camelCase supported only via normalization). Please update the Javadoc to reflect the current canonical property name/prefix to avoid confusing users.

Copilot uses AI. Check for mistakes.
io.prometheus.metrics.http_duration_seconds.histogramClassicUpperBounds = .005, .01, .015, .02
io.prometheus.metrics.summaryQuantiles = 0.5, 0.95, 0.99
io.prometheus.metrics.summaryQuantileErrors = 0.01, 0.01, 0.001
io.prometheus.metrics.histogram_classic_upper_bounds = .005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test properties file dropped the last default classic histogram bound (", 10"). That also forces multiple tests to switch from expecting 11 to 10 bounds, which seems unrelated to adding env-var support and diverges from the documented/default bucket list. If this was accidental, restore the trailing 10 and keep the existing expectations.

Suggested change
io.prometheus.metrics.histogram_classic_upper_bounds = .005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5
io.prometheus.metrics.histogram_classic_upper_bounds = .005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10

Copilot uses AI. Check for mistakes.
void testPrometheusConfig() {
PrometheusProperties result = PrometheusProperties.get();
assertThat(result.getDefaultMetricProperties().getHistogramClassicUpperBounds()).hasSize(11);
assertThat(result.getDefaultMetricProperties().getHistogramClassicUpperBounds()).hasSize(10);
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assertion was updated to expect 10 classic upper bounds, which is driven by the change in src/test/resources/prometheus.properties dropping one bound. If the intent is only to rename keys / add env-var support, consider restoring the original bounds list and keeping this expectation at 11 to avoid an unrelated behavioral change in the test fixture.

Suggested change
assertThat(result.getDefaultMetricProperties().getHistogramClassicUpperBounds()).hasSize(10);
assertThat(result.getDefaultMetricProperties().getHistogramClassicUpperBounds()).hasSize(11);

Copilot uses AI. Check for mistakes.
PrometheusProperties prometheusProperties = PrometheusPropertiesLoader.load();
assertThat(prometheusProperties.getDefaultMetricProperties().getHistogramClassicUpperBounds())
.hasSize(11);
.hasSize(10);
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test now expects 10 default histogram classic upper bounds because the test classpath prometheus.properties dropped one entry. If the bound removal wasn’t intentional, restore the original list (including 10) and keep the expectation at 11 so the test continues to validate the full default bucket set.

Suggested change
.hasSize(10);
.hasSize(11);

Copilot uses AI. Check for mistakes.
Comment on lines +81 to 90
// Package-private constructor for PrometheusPropertiesLoader and Builder
PrometheusProperties(
MetricsProperties defaultMetricsProperties,
Map<String, MetricsProperties> metricProperties,
MetricPropertiesMap metricProperties,
ExemplarsProperties exemplarProperties,
ExporterProperties exporterProperties,
ExporterFilterProperties exporterFilterProperties,
ExporterHttpServerProperties httpServerConfig,
ExporterPushgatewayProperties pushgatewayProperties,
ExporterOpenTelemetryProperties otelConfig) {
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PrometheusProperties constructor is no longer public (now package-private). That is a source/binary breaking API change for any users instantiating PrometheusProperties directly, and it also conflicts with the PR description claiming “No Breaking Changes”. Consider keeping this constructor public, or update the public API/docs to provide an alternative migration path and call out the breaking change explicitly.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants