Skip to content

Commit e3236b1

Browse files
committed
embedded config file
1 parent 780435d commit e3236b1

File tree

4 files changed

+92
-58
lines changed

4 files changed

+92
-58
lines changed
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
Comparing source compatibility of opentelemetry-spring-boot-autoconfigure-2.17.0-SNAPSHOT.jar against opentelemetry-spring-boot-autoconfigure-2.16.0.jar
2-
No changes.
2+
=== UNCHANGED CLASS: PUBLIC io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration (not serializable)
3+
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
4+
--- REMOVED ANNOTATION: org.springframework.boot.context.properties.EnableConfigurationProperties
5+
--- 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 (-)

instrumentation/spring/spring-boot-autoconfigure/build.gradle.kts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ dependencies {
3636
annotationProcessor("org.springframework.boot:spring-boot-autoconfigure-processor:$springBootVersion")
3737
annotationProcessor("org.springframework.boot:spring-boot-configuration-processor:$springBootVersion")
3838
implementation("javax.validation:validation-api")
39-
implementation("com.fasterxml.jackson.core:jackson-core")
39+
// snake yaml is already used by "spring-boot-resources"
40+
// and less likely to cause problems compared to jackson
41+
implementation("org.snakeyaml:snakeyaml-engine")
4042

4143
implementation(project(":instrumentation-annotations-support"))
4244
implementation(project(":instrumentation:kafka:kafka-clients:kafka-clients-2.6:library"))
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,104 @@
11
package io.opentelemetry.instrumentation.spring.autoconfigure;
22

3-
import com.fasterxml.jackson.databind.JsonNode;
4-
import com.fasterxml.jackson.databind.ObjectMapper;
5-
import io.opentelemetry.api.GlobalOpenTelemetry;
6-
import io.opentelemetry.api.incubator.config.GlobalConfigProvider;
7-
import io.opentelemetry.sdk.OpenTelemetrySdk;
83
import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration;
9-
import io.opentelemetry.sdk.extension.incubator.fileconfig.SdkConfigProvider;
104
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel;
11-
import org.springframework.boot.env.OriginTrackedMapPropertySource;
12-
import org.springframework.core.env.ConfigurableEnvironment;
13-
import org.springframework.core.env.PropertySource;
145
import java.io.ByteArrayInputStream;
156
import java.io.IOException;
167
import java.io.InputStream;
178
import java.nio.charset.StandardCharsets;
9+
import java.util.Map;
1810
import java.util.regex.Matcher;
1911
import java.util.regex.Pattern;
12+
import javax.annotation.Nullable;
13+
import org.snakeyaml.engine.v2.api.Dump;
14+
import org.snakeyaml.engine.v2.api.DumpSettings;
15+
import org.snakeyaml.engine.v2.api.Load;
16+
import org.snakeyaml.engine.v2.api.LoadSettings;
17+
import org.springframework.boot.env.OriginTrackedMapPropertySource;
18+
import org.springframework.core.env.ConfigurableEnvironment;
19+
import org.springframework.core.env.PropertySource;
2020

2121
class EmbeddedConfigFile {
2222

23-
private static final Pattern PATTERN = Pattern.compile(
24-
"^Config resource 'class path resource \\[(.+)]' via location 'optional:classpath:/'$"
25-
);
23+
private EmbeddedConfigFile() {
24+
// Utility class
25+
}
26+
27+
private static final Pattern PATTERN =
28+
Pattern.compile(
29+
"^Config resource 'class path resource \\[(.+)]' via location 'optional:classpath:/'$");
2630

2731
static OpenTelemetryConfigurationModel extractModel(ConfigurableEnvironment environment)
2832
throws IOException {
2933
for (PropertySource<?> propertySource : environment.getPropertySources()) {
3034
if (propertySource instanceof OriginTrackedMapPropertySource) {
31-
OriginTrackedMapPropertySource source = (OriginTrackedMapPropertySource) propertySource;
32-
String name = source.getName();
33-
System.out.println("Property Source: " + name); // todo remove
34-
Matcher matcher = PATTERN.matcher(name);
35-
if (matcher.matches()) {
36-
String file = matcher.group(1);
37-
System.out.println("Found application.yaml: " + file);
35+
return getModel(environment, (OriginTrackedMapPropertySource) propertySource);
36+
}
37+
}
38+
throw new IllegalStateException("No application.yaml file found.");
39+
}
40+
41+
private static OpenTelemetryConfigurationModel getModel(
42+
ConfigurableEnvironment environment, OriginTrackedMapPropertySource source)
43+
throws IOException {
44+
String name = source.getName();
45+
System.out.println("Property Source: " + name); // todo remove
46+
Matcher matcher = PATTERN.matcher(name);
47+
if (matcher.matches()) {
48+
String file = matcher.group(1);
49+
System.out.println("Found application.yaml: " + file);
3850

39-
try (InputStream resourceAsStream =
40-
environment.getClass().getClassLoader().getResourceAsStream(file)) {
41-
// Print the contents of the application.yaml file
42-
if (resourceAsStream != null) {
43-
String content = new String(resourceAsStream.readAllBytes());
44-
System.out.println("Contents of " + file + ":"); // todo remove
45-
System.out.println(content); // todo remove
51+
try (InputStream resourceAsStream =
52+
environment.getClass().getClassLoader().getResourceAsStream(file)) {
53+
// Print the contents of the application.yaml file
54+
if (resourceAsStream != null) {
55+
// String content = new String(resourceAsStream.readAllBytes());
56+
// System.out.println("Contents of " + file + ":"); // todo remove
57+
// System.out.println(content); // todo remove
4658

47-
extractOtelConfigFile(content);
48-
} else {
49-
System.out.println("Could not find the application.yaml file in the classpath."); // todo remove
50-
}
51-
}
59+
return extractOtelConfigFile(resourceAsStream);
60+
} else {
61+
throw new IllegalStateException("Unable to load " + file + " in the classpath.");
5262
}
5363
}
64+
} else {
65+
throw new IllegalStateException(
66+
"No OpenTelemetry configuration found in the application.yaml file.");
67+
}
68+
}
69+
70+
@Nullable
71+
@SuppressWarnings("unchecked")
72+
private static String parseOtelNode(InputStream in) {
73+
Load load = new Load(LoadSettings.builder().build());
74+
Dump dump = new Dump(DumpSettings.builder().build());
75+
for (Object o : load.loadAllFromInputStream(in)) {
76+
Map<String, Object> data = (Map<String, Object>) o;
77+
Map<String, Map<String, Object>> otel = (Map<String, Map<String, Object>>) data.get("otel");
78+
if (otel != null) {
79+
return dump.dumpToString(otel);
80+
}
5481
}
82+
throw new IllegalStateException("No 'otel' configuration found in the YAML file.");
5583
}
5684

57-
private static void extractOtelConfigFile(String content) throws IOException {
85+
private static OpenTelemetryConfigurationModel extractOtelConfigFile(InputStream content) {
5886
//
5987
// https://github.com/open-telemetry/opentelemetry-configuration/blob/c205770a956713e512eddb056570a99737e3383a/examples/kitchen-sink.yaml#L11
6088

6189
// 1. read to yaml tree in jackson
62-
ObjectMapper yamlMapper = new ObjectMapper(new YAMLFactory());
63-
JsonNode rootNode = yamlMapper.readTree(content);
90+
// ObjectMapper yamlMapper = new ObjectMapper(new YAMLFactory());
91+
// JsonNode rootNode = yamlMapper.readTree(content);
6492

65-
// 2. find the "otel" node
66-
JsonNode otelNode = rootNode.get("otel");
67-
if (otelNode == null) {
68-
System.out.println("No 'otel' configuration found in the YAML file."); // todo remove
69-
return;
93+
String node = parseOtelNode(content);
94+
if (node == null || node.isEmpty()) {
95+
throw new IllegalStateException("otel node is empty or null in the YAML file.");
7096
}
7197

72-
String str = yamlMapper.writeValueAsString(otelNode);
73-
74-
OpenTelemetryConfigurationModel model =
75-
DeclarativeConfiguration.parse(
76-
new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8)));
77-
OpenTelemetrySdk sdk =
78-
DeclarativeConfiguration.create(model); // can pass ComponentLoader as second arg
79-
80-
Runtime.getRuntime().addShutdownHook(new Thread(sdk::close));
81-
82-
GlobalOpenTelemetry.set(sdk);
83-
GlobalConfigProvider.set(SdkConfigProvider.create(model));
98+
System.out.println("OpenTelemetry configuration file content:"); // todo remove
99+
System.out.println(node); // todo remove
84100

85-
System.out.println("OpenTelemetry SDK initialized with configuration from: " + sdk); // todo remove
86-
System.out.println("OpenTelemetry configuration file content:"); // todo remove
87-
System.out.println(str); // todo remove
101+
return DeclarativeConfiguration.parse(
102+
new ByteArrayInputStream(node.getBytes(StandardCharsets.UTF_8)));
88103
}
89104
}

instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfiguration.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55

66
package io.opentelemetry.instrumentation.spring.autoconfigure;
77

8+
import io.opentelemetry.api.GlobalOpenTelemetry;
89
import io.opentelemetry.api.OpenTelemetry;
10+
import io.opentelemetry.api.incubator.config.GlobalConfigProvider;
911
import io.opentelemetry.api.trace.TracerProvider;
1012
import io.opentelemetry.instrumentation.api.internal.EmbeddedInstrumentationProperties;
1113
import io.opentelemetry.instrumentation.sdk.DeclarativeConfigPropertiesBridge;
@@ -17,6 +19,7 @@
1719
import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.SpringConfigProperties;
1820
import io.opentelemetry.instrumentation.spring.autoconfigure.internal.resources.DistroVersionResourceProvider;
1921
import io.opentelemetry.instrumentation.spring.autoconfigure.internal.resources.SpringResourceProvider;
22+
import io.opentelemetry.sdk.OpenTelemetrySdk;
2023
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
2124
import io.opentelemetry.sdk.autoconfigure.internal.AutoConfigureUtil;
2225
import io.opentelemetry.sdk.autoconfigure.internal.ComponentLoader;
@@ -25,6 +28,7 @@
2528
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
2629
import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties;
2730
import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration;
31+
import io.opentelemetry.sdk.extension.incubator.fileconfig.SdkConfigProvider;
2832
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel;
2933
import java.io.IOException;
3034
import java.util.Collections;
@@ -68,7 +72,7 @@ public OpenTelemetryAutoConfiguration() {}
6872
static class OpenTelemetrySdkConfig {
6973

7074
@Bean
71-
public OpenTelemetrySdkComponentLoader openTelemetrySdkComponentLoader(
75+
public ComponentLoader openTelemetrySdkComponentLoader(
7276
ApplicationContext applicationContext) {
7377
return new OpenTelemetrySdkComponentLoader(applicationContext);
7478
}
@@ -154,7 +158,17 @@ public OpenTelemetryConfigurationModel openTelemetryConfigurationModel(
154158
}
155159

156160
@Bean
157-
public OpenTelemetry openTelemetry() {
161+
public OpenTelemetry openTelemetry(OpenTelemetryConfigurationModel model, ComponentLoader componentLoader) {
162+
OpenTelemetrySdk sdk =
163+
DeclarativeConfiguration.create(model, componentLoader);
164+
165+
Runtime.getRuntime().addShutdownHook(new Thread(sdk::close));
166+
167+
GlobalOpenTelemetry.set(sdk);
168+
GlobalConfigProvider.set(SdkConfigProvider.create(model));
169+
170+
System.out.println(
171+
"OpenTelemetry SDK initialized with configuration from: " + sdk); // todo remove
158172

159173
// todo declarative configuration
160174
// todo map converter not needed here, because the declarative configuration is not using

0 commit comments

Comments
 (0)