Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
5a9d8ad
declarative config
zeitlinger Jun 18, 2025
0ea2562
isolate map converter
zeitlinger Jun 18, 2025
c9bd82e
embedded config file
zeitlinger Jun 18, 2025
e0a7971
embedded config file
zeitlinger Jun 18, 2025
9cf25a5
config bridge
zeitlinger Jun 18, 2025
f0536c9
config bridge
zeitlinger Jun 18, 2025
7b97e54
use InstrumentationConfig for encapsulation
zeitlinger Jun 18, 2025
77a983c
use InstrumentationConfig for encapsulation
zeitlinger Jun 18, 2025
c42b4e7
use InstrumentationConfig for encapsulation
zeitlinger Jun 18, 2025
c81136a
use InstrumentationConfig for encapsulation
zeitlinger Jun 18, 2025
7b8dc84
create component loader directly (doesn't work otherwise)
zeitlinger Jun 19, 2025
5d869ee
fix disabled config
zeitlinger Jun 19, 2025
9fe3807
add test
zeitlinger Jun 19, 2025
f390876
add test
zeitlinger Jun 19, 2025
af4f612
add test
zeitlinger Jun 19, 2025
940ea95
add test
zeitlinger Jun 19, 2025
31dec30
add test
zeitlinger Jun 19, 2025
1bbc04d
add test
zeitlinger Jun 19, 2025
b449a38
add test
zeitlinger Jun 19, 2025
deb075c
add test
zeitlinger Jun 19, 2025
b19272e
add test
zeitlinger Jun 19, 2025
9e89e0d
add test
zeitlinger Jun 19, 2025
485d350
cleanup
zeitlinger Jun 19, 2025
9639fde
cleanup
zeitlinger Jun 19, 2025
4232290
format
zeitlinger Jun 19, 2025
c9ba36e
fix rebase
zeitlinger Jun 30, 2025
2614006
fix rebase
zeitlinger Jun 30, 2025
6ac14ab
./gradlew spotlessApply
otelbot[bot] Jun 30, 2025
86f28d3
fix rebase
zeitlinger Jul 7, 2025
cbc3b5c
extract condition
zeitlinger Jul 7, 2025
ea2596d
use _
zeitlinger Jul 8, 2025
10653c6
use declarative config properties
zeitlinger Jul 8, 2025
68ee65e
use declarative config properties
zeitlinger Jul 8, 2025
eb44c90
fix rebase
zeitlinger Aug 15, 2025
bb87169
fix rebase
zeitlinger Aug 16, 2025
dc9ab74
fix rebase
zeitlinger Aug 29, 2025
d04873e
fix rebase
zeitlinger Aug 29, 2025
1c931d5
fix test
zeitlinger Sep 5, 2025
f9d095d
bug was fixed
zeitlinger Sep 17, 2025
e22fb61
add distro
zeitlinger Sep 17, 2025
a7e5252
map default enabled
zeitlinger Sep 17, 2025
e57ac7b
simplify
zeitlinger Sep 29, 2025
0948884
api diff
zeitlinger Sep 29, 2025
6d9261d
fix
zeitlinger Sep 30, 2025
9aa86c0
fix
zeitlinger Sep 30, 2025
9cabd93
add test condition
jaydeluca Oct 7, 2025
8b848f8
reorder
zeitlinger Oct 7, 2025
a027d2b
pr review
zeitlinger Oct 8, 2025
d3787d2
fix rebase
zeitlinger Oct 28, 2025
c70a146
api diff
zeitlinger Oct 29, 2025
7dcf66e
comment
zeitlinger Oct 29, 2025
0a6765c
null check
zeitlinger Oct 29, 2025
7889f04
add nullaway
zeitlinger Oct 29, 2025
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
@@ -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 (-)
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
plugins {
id("otel.library-instrumentation")
id("otel.nullaway-conventions")
}

base.archivesName.set("opentelemetry-spring-boot-autoconfigure")
Expand Down Expand Up @@ -35,6 +36,9 @@ dependencies {
annotationProcessor("org.springframework.boot:spring-boot-autoconfigure-processor:$springBootVersion")
annotationProcessor("org.springframework.boot:spring-boot-configuration-processor:$springBootVersion")
implementation("javax.validation:validation-api")
// snake yaml is already used by "spring-boot-resources"
// and less likely to cause problems compared to jackson
implementation("org.snakeyaml:snakeyaml-engine")

implementation(project(":instrumentation-annotations-support"))
implementation(project(":instrumentation:kafka:kafka-clients:kafka-clients-2.6:library"))
Expand Down Expand Up @@ -65,7 +69,9 @@ dependencies {
library("org.springframework.boot:spring-boot-starter-data-jdbc:$springBootVersion")

implementation("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure")
implementation("io.opentelemetry:opentelemetry-sdk-extension-incubator")
implementation(project(":sdk-autoconfigure-support"))
implementation(project(":declarative-config-bridge"))
compileOnly("io.opentelemetry:opentelemetry-extension-trace-propagators")
compileOnly("io.opentelemetry.contrib:opentelemetry-aws-xray-propagator")
compileOnly("io.opentelemetry:opentelemetry-exporter-logging")
Expand All @@ -80,6 +86,7 @@ dependencies {
testLibrary("org.springframework.boot:spring-boot-starter-test:$springBootVersion") {
exclude("org.junit.vintage", "junit-vintage-engine")
}

testImplementation("javax.servlet:javax.servlet-api:3.1.0")
testImplementation("jakarta.servlet:jakarta.servlet-api:5.0.0")
testRuntimeOnly("com.h2database:h2:1.4.197")
Expand Down Expand Up @@ -173,6 +180,17 @@ testing {
}
}
}

val testDeclarativeConfig by registering(JvmTestSuite::class) {
dependencies {
implementation(project())
implementation("io.opentelemetry:opentelemetry-sdk")
implementation("org.springframework.boot:spring-boot-starter-test:$springBootVersion") {
exclude("org.junit.vintage", "junit-vintage-engine")
}
implementation("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.spring.autoconfigure;

import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import org.snakeyaml.engine.v2.api.Dump;
import org.snakeyaml.engine.v2.api.DumpSettings;
import org.snakeyaml.engine.v2.api.Load;
import org.snakeyaml.engine.v2.api.LoadSettings;
import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertySource;

class EmbeddedConfigFile {

private EmbeddedConfigFile() {
// Utility class
}

private static final Pattern PATTERN =
Pattern.compile(
"^Config resource 'class path resource \\[(.+)]' via location 'optional:classpath:/'$");

static OpenTelemetryConfigurationModel extractModel(ConfigurableEnvironment environment)
throws IOException {
for (PropertySource<?> propertySource : environment.getPropertySources()) {
if (propertySource instanceof OriginTrackedMapPropertySource) {
return getModel(environment, (OriginTrackedMapPropertySource) propertySource);
}
}
throw new IllegalStateException("No application.yaml file found.");
}

private static OpenTelemetryConfigurationModel getModel(
ConfigurableEnvironment environment, OriginTrackedMapPropertySource source)
throws IOException {
Matcher matcher = PATTERN.matcher(source.getName());
if (matcher.matches()) {
String file = matcher.group(1);

try (InputStream resourceAsStream =
environment.getClass().getClassLoader().getResourceAsStream(file)) {
if (resourceAsStream != null) {
return extractOtelConfigFile(resourceAsStream);
} else {
throw new IllegalStateException("Unable to load " + file + " in the classpath.");
}
}
} else {
throw new IllegalStateException(
"No OpenTelemetry configuration found in the application.yaml file.");
}
}

@Nullable
@SuppressWarnings("unchecked")
private static String parseOtelNode(InputStream in) {
Load load = new Load(LoadSettings.builder().build());
Dump dump = new Dump(DumpSettings.builder().build());
for (Object o : load.loadAllFromInputStream(in)) {
Map<String, Object> data = (Map<String, Object>) o;
Map<String, Map<String, Object>> otel = (Map<String, Map<String, Object>>) data.get("otel");
if (otel != null) {
return dump.dumpToString(otel);
}
}
throw new IllegalStateException("No 'otel' configuration found in the YAML file.");
}

private static OpenTelemetryConfigurationModel extractOtelConfigFile(InputStream content) {
String node = parseOtelNode(content);
if (node == null || node.isEmpty()) {
throw new IllegalStateException("otel node is empty or null in the YAML file.");
}

return DeclarativeConfiguration.parse(
new ByteArrayInputStream(node.getBytes(StandardCharsets.UTF_8)));
}
}
Loading
Loading