55
66package io .opentelemetry .instrumentation .testing .internal ;
77
8- import static java .nio .charset .StandardCharsets .UTF_8 ;
9-
108import io .opentelemetry .api .common .AttributeType ;
119import io .opentelemetry .api .internal .InternalAttributeKeyImpl ;
1210import io .opentelemetry .api .trace .SpanKind ;
1311import io .opentelemetry .sdk .common .InstrumentationScopeInfo ;
1412import 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 ;
1617import java .io .IOException ;
1718import java .nio .file .FileAlreadyExistsException ;
1819import java .nio .file .Files ;
1920import java .nio .file .Path ;
2021import java .nio .file .Paths ;
22+ import java .util .ArrayList ;
23+ import java .util .LinkedHashMap ;
24+ import java .util .List ;
2125import java .util .Map ;
2226import java .util .Set ;
2327import java .util .UUID ;
28+ import java .util .logging .Logger ;
2429import java .util .regex .Matcher ;
2530import java .util .regex .Pattern ;
2631
3439 */
3540public 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