Skip to content

Commit 56b3b94

Browse files
authored
Use Jackson for telemetry files (#15319)
1 parent 73e41e6 commit 56b3b94

File tree

3 files changed

+169
-89
lines changed

3 files changed

+169
-89
lines changed

instrumentation-docs/src/main/java/io/opentelemetry/instrumentation/docs/parsers/EmittedSpanParser.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ public static Map<String, EmittedSpans> getSpansByScopeFromFiles(
6464
}
6565
});
6666
} catch (IOException e) {
67-
logger.severe("Error reading span files: " + e.getMessage());
67+
logger.severe(
68+
"Error reading span files from " + instrumentationDirectory + ": " + e.getMessage());
6869
}
6970
}
7071

instrumentation-docs/src/main/java/io/opentelemetry/instrumentation/docs/parsers/SpanParser.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public class SpanParser {
2626
// We want to ignore test related attributes
2727
private static final List<String> EXCLUDED_ATTRIBUTES =
2828
List.of(
29+
"asdf",
2930
"x-test-",
3031
"test-baggage-",
3132
"test_message",

testing-common/src/main/java/io/opentelemetry/instrumentation/testing/internal/MetaDataCollector.java

Lines changed: 166 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,27 @@
55

66
package io.opentelemetry.instrumentation.testing.internal;
77

8-
import static java.nio.charset.StandardCharsets.UTF_8;
9-
108
import io.opentelemetry.api.common.AttributeType;
119
import io.opentelemetry.api.internal.InternalAttributeKeyImpl;
1210
import io.opentelemetry.api.trace.SpanKind;
1311
import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
1412
import io.opentelemetry.sdk.metrics.data.MetricData;
15-
import java.io.BufferedWriter;
13+
import io.opentelemetry.testing.internal.jackson.annotation.JsonProperty;
14+
import io.opentelemetry.testing.internal.jackson.dataformat.yaml.YAMLFactory;
15+
import io.opentelemetry.testing.internal.jackson.dataformat.yaml.YAMLGenerator;
16+
import io.opentelemetry.testing.internal.jackson.dataformat.yaml.YAMLMapper;
1617
import java.io.IOException;
1718
import java.nio.file.FileAlreadyExistsException;
1819
import java.nio.file.Files;
1920
import java.nio.file.Path;
2021
import java.nio.file.Paths;
22+
import java.util.ArrayList;
23+
import java.util.LinkedHashMap;
24+
import java.util.List;
2125
import java.util.Map;
2226
import java.util.Set;
2327
import java.util.UUID;
28+
import java.util.logging.Logger;
2429
import java.util.regex.Matcher;
2530
import java.util.regex.Pattern;
2631

@@ -34,10 +39,20 @@
3439
*/
3540
public final class MetaDataCollector {
3641

42+
private static final Logger logger = Logger.getLogger(MetaDataCollector.class.getName());
43+
3744
private static final String TMP_DIR = ".telemetry";
3845
private static final Pattern MODULE_PATTERN =
3946
Pattern.compile("(.*?/instrumentation/.*?)(/javaagent|/library|/testing)");
4047

48+
private static final YAMLMapper YAML =
49+
YAMLMapper.builder(
50+
YAMLFactory.builder()
51+
.disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER)
52+
.enable(YAMLGenerator.Feature.MINIMIZE_QUOTES)
53+
.build())
54+
.build();
55+
4156
public static void writeTelemetryToFiles(
4257
String path,
4358
Map<InstrumentationScopeInfo, Map<String, MetricData>> metricsByScope,
@@ -85,53 +100,53 @@ private static void writeSpanData(
85100
Path spansPath =
86101
Paths.get(instrumentationPath, TMP_DIR, "spans-" + UUID.randomUUID() + ".yaml");
87102

88-
try (BufferedWriter writer = Files.newBufferedWriter(spansPath.toFile().toPath(), UTF_8)) {
89-
String config = System.getProperty("metadataConfig");
90-
String when = "default";
91-
if (config != null && !config.isEmpty()) {
92-
when = config;
103+
String config = System.getProperty("metadataConfig");
104+
String when = (config != null && !config.isEmpty()) ? config : "default";
105+
106+
SpanData spanData = new SpanData();
107+
spanData.when = when;
108+
spanData.spansByScope = new ArrayList<>();
109+
110+
for (Map.Entry<
111+
InstrumentationScopeInfo,
112+
Map<SpanKind, Map<InternalAttributeKeyImpl<?>, AttributeType>>>
113+
entry : spansByScopeAndKind.entrySet()) {
114+
InstrumentationScopeInfo scope = entry.getKey();
115+
Map<SpanKind, Map<InternalAttributeKeyImpl<?>, AttributeType>> spansByKind = entry.getValue();
116+
117+
ScopeSpans scopeSpans = new ScopeSpans();
118+
scopeSpans.scope = scope.getName();
119+
scopeSpans.spans = new ArrayList<>();
120+
121+
for (Map.Entry<SpanKind, Map<InternalAttributeKeyImpl<?>, AttributeType>> kindEntry :
122+
spansByKind.entrySet()) {
123+
SpanKind spanKind = kindEntry.getKey();
124+
Map<InternalAttributeKeyImpl<?>, AttributeType> attributes = kindEntry.getValue();
125+
126+
Span span = new Span();
127+
span.spanKind = spanKind.toString();
128+
span.attributes = new ArrayList<>();
129+
130+
attributes.forEach(
131+
(key, value) -> {
132+
AttributeInfo attr = new AttributeInfo();
133+
attr.name = key.getKey();
134+
attr.type = key.getType().toString();
135+
span.attributes.add(attr);
136+
});
137+
138+
scopeSpans.spans.add(span);
93139
}
94140

95-
writer.write("when: " + when + "\n");
96-
97-
writer.write("spans_by_scope:\n");
98-
99-
for (Map.Entry<
100-
InstrumentationScopeInfo,
101-
Map<SpanKind, Map<InternalAttributeKeyImpl<?>, AttributeType>>>
102-
entry : spansByScopeAndKind.entrySet()) {
103-
InstrumentationScopeInfo scope = entry.getKey();
104-
Map<SpanKind, Map<InternalAttributeKeyImpl<?>, AttributeType>> spansByKind =
105-
entry.getValue();
106-
107-
writer.write(" - scope: " + scope.getName() + "\n");
108-
writer.write(" spans:\n");
109-
110-
for (Map.Entry<SpanKind, Map<InternalAttributeKeyImpl<?>, AttributeType>> kindEntry :
111-
spansByKind.entrySet()) {
112-
SpanKind spanKind = kindEntry.getKey();
113-
Map<InternalAttributeKeyImpl<?>, AttributeType> attributes = kindEntry.getValue();
114-
115-
writer.write(" - span_kind: " + spanKind.toString() + "\n");
116-
writer.write(" attributes:\n");
117-
attributes.forEach(
118-
(key, value) -> {
119-
try {
120-
writer.write(" - name: " + key.getKey() + "\n");
121-
writer.write(" type: " + key.getType().toString() + "\n");
122-
} catch (IOException e) {
123-
throw new IllegalStateException(e);
124-
}
125-
});
126-
}
127-
}
141+
spanData.spansByScope.add(scopeSpans);
128142
}
143+
144+
YAML.writeValue(spansPath.toFile(), spanData);
129145
}
130146

131147
private static void writeMetricData(
132148
String instrumentationPath,
133-
Map<InstrumentationScopeInfo, Map<String, MetricData>> metricsByScope)
134-
throws IOException {
149+
Map<InstrumentationScopeInfo, Map<String, MetricData>> metricsByScope) {
135150

136151
if (metricsByScope.isEmpty()) {
137152
return;
@@ -140,46 +155,54 @@ private static void writeMetricData(
140155
Path metricsPath =
141156
Paths.get(instrumentationPath, TMP_DIR, "metrics-" + UUID.randomUUID() + ".yaml");
142157

143-
try (BufferedWriter writer = Files.newBufferedWriter(metricsPath.toFile().toPath(), UTF_8)) {
158+
try {
144159
String config = System.getProperty("metadataConfig");
145-
String when = "default";
146-
if (config != null && !config.isEmpty()) {
147-
when = config;
148-
}
149-
150-
writer.write("when: " + when + "\n");
160+
String when = (config != null && !config.isEmpty()) ? config : "default";
151161

152-
writer.write("metrics_by_scope:\n");
162+
MetricsData metricsData = new MetricsData();
163+
metricsData.when = when;
164+
metricsData.metricsByScope = new ArrayList<>();
153165

154166
for (Map.Entry<InstrumentationScopeInfo, Map<String, MetricData>> entry :
155167
metricsByScope.entrySet()) {
156168
InstrumentationScopeInfo scope = entry.getKey();
157169
Map<String, MetricData> metrics = entry.getValue();
158170

159-
writer.write(" - scope: " + scope.getName() + "\n");
160-
writer.write(" metrics:\n");
171+
ScopeMetrics scopeMetrics = new ScopeMetrics();
172+
scopeMetrics.scope = scope.getName();
173+
scopeMetrics.metrics = new ArrayList<>();
161174

162175
for (MetricData metric : metrics.values()) {
163-
writer.write(" - name: " + metric.getName() + "\n");
164-
writer.write(" description: " + metric.getDescription() + "\n");
165-
writer.write(" type: " + metric.getType().toString() + "\n");
166-
writer.write(" unit: " + sanitizeUnit(metric.getUnit()) + "\n");
167-
writer.write(" attributes: \n");
176+
Metric metricInfo = new Metric();
177+
metricInfo.name = metric.getName();
178+
metricInfo.description = metric.getDescription();
179+
metricInfo.type = metric.getType().toString();
180+
metricInfo.unit = sanitizeUnit(metric.getUnit());
181+
metricInfo.attributes = new ArrayList<>();
182+
168183
metric.getData().getPoints().stream()
169184
.findFirst()
170-
.get()
171-
.getAttributes()
172-
.forEach(
173-
(key, value) -> {
174-
try {
175-
writer.write(" - name: " + key.getKey() + "\n");
176-
writer.write(" type: " + key.getType().toString() + "\n");
177-
} catch (IOException e) {
178-
throw new IllegalStateException(e);
179-
}
180-
});
185+
.ifPresent(
186+
point ->
187+
point
188+
.getAttributes()
189+
.forEach(
190+
(key, value) -> {
191+
AttributeInfo attr = new AttributeInfo();
192+
attr.name = key.getKey();
193+
attr.type = key.getType().toString();
194+
metricInfo.attributes.add(attr);
195+
}));
196+
197+
scopeMetrics.metrics.add(metricInfo);
181198
}
199+
200+
metricsData.metricsByScope.add(scopeMetrics);
182201
}
202+
203+
YAML.writeValue(metricsPath.toFile(), metricsData);
204+
} catch (Exception e) {
205+
logger.warning("Failed to write metric data: " + e.getMessage());
183206
}
184207
}
185208

@@ -193,32 +216,87 @@ private static void writeScopeData(
193216

194217
Path outputPath =
195218
Paths.get(instrumentationPath, TMP_DIR, "scope-" + UUID.randomUUID() + ".yaml");
196-
try (BufferedWriter writer = Files.newBufferedWriter(outputPath.toFile().toPath(), UTF_8)) {
197-
writer.write("scopes:\n");
198-
for (InstrumentationScopeInfo scope : instrumentationScopes) {
199-
writer.write(" - name: " + scope.getName() + "\n");
200-
writer.write(" version: " + scope.getVersion() + "\n");
201-
writer.write(" schemaUrl: " + scope.getSchemaUrl() + "\n");
202-
if (scope.getAttributes() != null && !scope.getAttributes().isEmpty()) {
203-
writer.write(" attributes:\n");
204-
scope
205-
.getAttributes()
206-
.forEach(
207-
(key, value) -> {
208-
try {
209-
writer.write(" " + key + ": " + value + "\n");
210-
} catch (IOException e) {
211-
throw new IllegalStateException(e);
212-
}
213-
});
214-
}
219+
220+
ScopesData scopesData = new ScopesData();
221+
scopesData.scopes = new ArrayList<>();
222+
223+
for (InstrumentationScopeInfo scope : instrumentationScopes) {
224+
ScopeInfo scopeInfo = new ScopeInfo();
225+
scopeInfo.name = scope.getName();
226+
scopeInfo.version = scope.getVersion();
227+
scopeInfo.schemaUrl = scope.getSchemaUrl();
228+
229+
if (scope.getAttributes() != null && !scope.getAttributes().isEmpty()) {
230+
scopeInfo.attributes = new LinkedHashMap<>();
231+
scope
232+
.getAttributes()
233+
.forEach((key, value) -> scopeInfo.attributes.put(key.getKey(), value.toString()));
215234
}
235+
236+
scopesData.scopes.add(scopeInfo);
216237
}
238+
239+
YAML.writeValue(outputPath.toFile(), scopesData);
217240
}
218241

219242
private static String sanitizeUnit(String unit) {
220243
return unit == null ? null : unit.replace("{", "").replace("}", "");
221244
}
222245

223246
private MetaDataCollector() {}
247+
248+
static class SpanData {
249+
public String when;
250+
251+
@JsonProperty("spans_by_scope")
252+
public List<ScopeSpans> spansByScope;
253+
}
254+
255+
static class ScopeSpans {
256+
public String scope;
257+
public List<Span> spans;
258+
}
259+
260+
static class Span {
261+
@JsonProperty("span_kind")
262+
public String spanKind;
263+
264+
public List<AttributeInfo> attributes;
265+
}
266+
267+
static class MetricsData {
268+
public String when;
269+
270+
@JsonProperty("metrics_by_scope")
271+
public List<ScopeMetrics> metricsByScope;
272+
}
273+
274+
static class ScopeMetrics {
275+
public String scope;
276+
public List<Metric> metrics;
277+
}
278+
279+
static class Metric {
280+
public String name;
281+
public String description;
282+
public String type;
283+
public String unit;
284+
public List<AttributeInfo> attributes;
285+
}
286+
287+
static class ScopesData {
288+
public List<ScopeInfo> scopes;
289+
}
290+
291+
static class ScopeInfo {
292+
public String name;
293+
public String version;
294+
public String schemaUrl;
295+
public Map<String, String> attributes;
296+
}
297+
298+
static class AttributeInfo {
299+
public String name;
300+
public String type;
301+
}
224302
}

0 commit comments

Comments
 (0)