Repository navigation
support environment variables in properties - #1828
Conversation
There was a problem hiding this comment.
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
PropertySourceto 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.
1d05224 to
8ee2b21
Compare
There was a problem hiding this comment.
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.
| private static void validateAllPropertiesProcessed(PropertySource propertySource) { | ||
| for (String key : propertySource.getRemainingKeys()) { | ||
| if (key.startsWith("io.prometheus") || key.startsWith("io_prometheus")) { | ||
| throw new PrometheusPropertiesException(key + ": Unknown property"); |
There was a problem hiding this comment.
i know this isn't new behavior, but I found this to be surprising that we would throw for this condition as opposed to just logging a warning. For example, if we deprecate a property and someone forgets to remove it from their config, their service will crash?
There was a problem hiding this comment.
Fail early is an idiom in this library (@fstab probably has more background info). That means that we have to be very careful with removing - probably only in a major release.
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>
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
ffd74a0 to
16923c7
Compare
## Problem Since 1.5.0, metric-specific properties are ignored when the metric name has an uppercase letter. With ```properties io.prometheus.metrics.myLatency.histogram_classic_upper_bounds=.005, .01, .015 ``` a histogram named `myLatency` keeps the default buckets. `normalizePropertyKey()`, added in #1828 to accept camelCase property names, lowercases the whole key including the metric name. The settings are stored under `my_latency`, while `StatefulMetric` looks them up as `myLatency` and gets `null`. There is no "Unknown property" error because the key was consumed. In 1.4.3 the same config (with `histogramClassicUpperBounds`) applies to `myLatency`; I ran both versions to check. An automated review comment on #1828 pointed this out, but metric names are still lowercased on main. ## Fix In `io.prometheus.metrics.<metric>.<property>` keys only the property name is normalized, so `io.prometheus.metrics.myLatency.histogramNativeOnly` becomes `io.prometheus.metrics.myLatency.histogram_native_only`. Default metric keys and exporter keys are normalized as before, and environment variables are not affected. A key written with uppercase letters for a lowercase metric, like `io.prometheus.metrics.My_metric.histogram_native_only` for `my_metric`, no longer applies. That matches 1.4.x. ## How tested New `PrometheusPropertiesLoaderTest.metricSpecificPropertiesShouldKeepMetricNameCase` fails on main with a `NullPointerException` because `getMetricProperties("myLatency")` returns `null`, and passes with this change. I also added a case to `normalizePropertyKeyShouldConvertCamelCaseToSnakeCase`. `prometheus-metrics-config` (62 tests, coverage check) and `prometheus-metrics-core` (178 tests) pass on JDK 25. google-java-format 1.37.0 and checkstyle are clean on the changed files. I did not run `mise run lint` or the exporter modules. @zeitlinger this changes the key normalization from #1828. Signed-off-by: Tanishq Choudhary <tanishqchoudhary007@gmail.com>
Summary
No Breaking Changes. This is fully backward compatible:
Migration Guide
No migration required. However, to adopt the new features:
To use environment variables: Convert property names to uppercase with underscores
io.prometheus.exporter.httpServer.port→IO_PROMETHEUS_EXPORTER_HTTP_SERVER_PORTTo use snake_case (recommended): Update properties files
io.prometheus.metrics.exemplarsEnabled→io.prometheus.metrics.exemplars_enabledNotes