-
Notifications
You must be signed in to change notification settings - Fork 1k
Spring starter declarative config #14062
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
trask
merged 85 commits into
open-telemetry:main
from
zeitlinger:spring-starter-declarative-config
Nov 16, 2025
Merged
Changes from 70 commits
Commits
Show all changes
85 commits
Select commit
Hold shift + click to select a range
ed766f2
declarative config
zeitlinger 3a3043c
isolate map converter
zeitlinger 044433e
embedded config file
zeitlinger 0972c1e
embedded config file
zeitlinger 8344e12
config bridge
zeitlinger 40e9c0b
config bridge
zeitlinger c968953
use InstrumentationConfig for encapsulation
zeitlinger 5e43d80
use InstrumentationConfig for encapsulation
zeitlinger dfa3a18
use InstrumentationConfig for encapsulation
zeitlinger 84ea974
use InstrumentationConfig for encapsulation
zeitlinger e31415d
create component loader directly (doesn't work otherwise)
zeitlinger 5a74c33
fix disabled config
zeitlinger 6dd4547
add test
zeitlinger 8ba2846
add test
zeitlinger e76e778
add test
zeitlinger f2ce7bb
add test
zeitlinger 20df168
add test
zeitlinger be56cdf
add test
zeitlinger 1711ec0
add test
zeitlinger 5928865
add test
zeitlinger 2ea3d99
add test
zeitlinger 1c84d6d
add test
zeitlinger 83927b1
cleanup
zeitlinger 4aa3f48
cleanup
zeitlinger bd4ae2e
format
zeitlinger 2498d45
fix rebase
zeitlinger f03306c
fix rebase
zeitlinger b6b48ca
./gradlew spotlessApply
otelbot[bot] 1bc33d8
fix rebase
zeitlinger c4ec3a5
extract condition
zeitlinger 9eef35d
use _
zeitlinger 798ac68
use declarative config properties
zeitlinger 4ab0d7f
use declarative config properties
zeitlinger db2f8af
fix rebase
zeitlinger d0fd405
fix rebase
zeitlinger 995ded2
fix rebase
zeitlinger 67d7832
fix rebase
zeitlinger 18b1dbf
fix test
zeitlinger 091f3a1
bug was fixed
zeitlinger 80a4cf4
add distro
zeitlinger 59f2e17
map default enabled
zeitlinger e90fa68
simplify
zeitlinger 38d6858
api diff
zeitlinger 6a04cdf
fix
zeitlinger 3f11e71
fix
zeitlinger 8a2eb52
add test condition
jaydeluca 7cbc109
reorder
zeitlinger 76c195d
pr review
zeitlinger 5bfc03a
fix rebase
zeitlinger aa43d07
api diff
zeitlinger 3055852
comment
zeitlinger f70d4b9
null check
zeitlinger 28fa59c
fix test
zeitlinger 31ab1be
no need to suppress warning
zeitlinger cec9107
support multiple yaml files (for profiles)
zeitlinger 632e596
support multiple yaml files (for profiles)
zeitlinger 51d8834
support multiple yaml files (for profiles)
zeitlinger a83d6ec
support multiple yaml files (for profiles)
zeitlinger 8854dee
local
zeitlinger ecd84ba
support multiple yaml files (for profiles)
zeitlinger 6a19643
support multiple yaml files (for profiles)
zeitlinger 2dd89c8
support multiple yaml files (for profiles)
zeitlinger 02aadd0
support multiple yaml files (for profiles)
zeitlinger 520aa35
spring config provider
zeitlinger 6d031e8
coerce types
zeitlinger 08be383
coerce types
zeitlinger 9b9f4dd
rename
zeitlinger 9e251b8
cleanup
zeitlinger b7cbaa6
fix rebase
zeitlinger d803eb5
cleanup
zeitlinger 11089d0
pr review
zeitlinger 5476821
use access class
zeitlinger c3d8931
pr review
zeitlinger 5bf76ed
pr review
zeitlinger 29012f9
pr review
zeitlinger 65606af
pr review
zeitlinger fa73f33
pr review
zeitlinger bfafc1d
fix
zeitlinger 68ee9a6
fix
zeitlinger 5faacbd
pr review
zeitlinger de5c766
Revert "use access class"
zeitlinger de5c5f6
pr review
zeitlinger 408174d
pr review
zeitlinger 5e5ce22
pr review
zeitlinger f832d8c
Merge branch 'main' into spring-starter-declarative-config
zeitlinger File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
5 changes: 4 additions & 1 deletion
5
docs/apidiffs/current_vs_latest/opentelemetry-spring-boot-autoconfigure.txt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,5 @@ | ||
| Comparing source compatibility of opentelemetry-spring-boot-autoconfigure-2.22.0-SNAPSHOT.jar against opentelemetry-spring-boot-autoconfigure-2.21.0.jar | ||
| No changes. | ||
| === UNCHANGED CLASS: PUBLIC io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration (not serializable) | ||
| === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 | ||
| --- REMOVED ANNOTATION: org.springframework.boot.context.properties.EnableConfigurationProperties | ||
| --- REMOVED ELEMENT: value=io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.OtlpExporterProperties,io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.OtelResourceProperties,io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.OtelSpringProperties (-) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
143 changes: 143 additions & 0 deletions
143
...c/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/EmbeddedConfigFile.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,143 @@ | ||
| /* | ||
| * Copyright The OpenTelemetry Authors | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| package io.opentelemetry.instrumentation.spring.autoconfigure; | ||
|
|
||
| import com.fasterxml.jackson.databind.ObjectMapper; | ||
| import io.opentelemetry.api.incubator.config.DeclarativeConfigException; | ||
| import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration; | ||
| import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; | ||
| import java.lang.reflect.Field; | ||
| import java.util.ArrayList; | ||
| import java.util.HashMap; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.Objects; | ||
| import java.util.regex.Matcher; | ||
| import java.util.regex.Pattern; | ||
| import org.springframework.core.env.ConfigurableEnvironment; | ||
| import org.springframework.core.env.EnumerablePropertySource; | ||
| import org.springframework.core.env.MutablePropertySources; | ||
| import org.springframework.core.env.PropertySource; | ||
|
|
||
| class EmbeddedConfigFile { | ||
|
|
||
| static final Pattern ARRAY_PATTERN = Pattern.compile("(.+)\\[(\\d+)\\]"); | ||
|
|
||
| private EmbeddedConfigFile() { | ||
| // Utility class | ||
| } | ||
|
|
||
| static OpenTelemetryConfigurationModel extractModel(ConfigurableEnvironment environment) { | ||
| Map<String, String> props = extractSpringProperties(environment); | ||
| return convertToOpenTelemetryConfigurationModel(props); | ||
| } | ||
|
|
||
| private static Map<String, String> extractSpringProperties(ConfigurableEnvironment environment) { | ||
| MutablePropertySources propertySources = environment.getPropertySources(); | ||
|
|
||
| Map<String, String> props = new HashMap<>(); | ||
| for (PropertySource<?> propertySource : propertySources) { | ||
| if (propertySource instanceof EnumerablePropertySource<?>) { | ||
| for (String propertyName : | ||
| ((EnumerablePropertySource<?>) propertySource).getPropertyNames()) { | ||
| if (propertyName.startsWith("otel.")) { | ||
| String property = environment.getProperty(propertyName); | ||
| if (Objects.equals(property, "")) { | ||
| property = null; // spring returns empty string for yaml null | ||
| } | ||
| props.put(propertyName.substring("otel.".length()), property); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (props.isEmpty()) { | ||
| throw new IllegalStateException("No application.yaml file found."); | ||
zeitlinger marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| return props; | ||
| } | ||
|
|
||
| static OpenTelemetryConfigurationModel convertToOpenTelemetryConfigurationModel( | ||
| Map<String, String> flatProps) { | ||
| Map<String, Object> nested = convertFlatPropsToNested(flatProps); | ||
|
|
||
| return getObjectMapper().convertValue(nested, OpenTelemetryConfigurationModel.class); | ||
| } | ||
|
|
||
| static ObjectMapper getObjectMapper() { | ||
| try { | ||
| Field field = DeclarativeConfiguration.class.getDeclaredField("MAPPER"); | ||
| field.setAccessible(true); | ||
| return (ObjectMapper) field.get(null); | ||
| } catch (NoSuchFieldException | IllegalAccessException e) { | ||
| throw new DeclarativeConfigException("Failed to access ObjectMapper", e); | ||
| } | ||
| } | ||
zeitlinger marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| /** | ||
| * Convert flat property map to nested structure. e.g. "otel.instrumentation.java.list[0]" = "one" | ||
| * and "otel.instrumentation.java.list[1]" = "two" becomes: {otel: {instrumentation: {java: {list: | ||
| * ["one", "two"]}}}} | ||
| */ | ||
| @SuppressWarnings("unchecked") | ||
| static Map<String, Object> convertFlatPropsToNested(Map<String, String> flatProps) { | ||
| Map<String, Object> result = new HashMap<>(); | ||
|
|
||
| for (Map.Entry<String, String> entry : flatProps.entrySet()) { | ||
| String key = entry.getKey(); | ||
| String value = entry.getValue(); | ||
|
|
||
| // Split the key by dots | ||
| String[] parts = key.split("\\."); | ||
| Map<String, Object> current = result; | ||
|
|
||
| for (int i = 0; i < parts.length; i++) { | ||
| String part = parts[i]; | ||
| boolean isLast = (i == parts.length - 1); | ||
|
|
||
| // Check if this part contains an array index like "list[0]" | ||
| Matcher matcher = ARRAY_PATTERN.matcher(part); | ||
| if (matcher.matches()) { | ||
| String arrayName = matcher.group(1); | ||
| int index = Integer.parseInt(matcher.group(2)); | ||
|
|
||
| // Get or create the list | ||
| if (!current.containsKey(arrayName)) { | ||
| current.put(arrayName, new ArrayList<>()); | ||
| } | ||
| List<Object> list = (List<Object>) current.get(arrayName); | ||
zeitlinger marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| // Ensure the list is large enough | ||
| while (list.size() <= index) { | ||
| list.add(null); | ||
| } | ||
zeitlinger marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| if (isLast) { | ||
| list.set(index, value); | ||
| } else { | ||
| // Need to create a nested map at this index | ||
| if (list.get(index) == null) { | ||
| list.set(index, new HashMap<String, Object>()); | ||
| } | ||
| current = (Map<String, Object>) list.get(index); | ||
zeitlinger marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| } else { | ||
| // Regular property (not an array) | ||
| if (isLast) { | ||
| current.put(part, value); | ||
| } else { | ||
| // Need to create a nested map | ||
| if (!current.containsKey(part)) { | ||
| current.put(part, new HashMap<String, Object>()); | ||
| } | ||
| current = (Map<String, Object>) current.get(part); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.