5
5
6
6
package io .opentelemetry .instrumentation .docs .parsers ;
7
7
8
+ import com .fasterxml .jackson .core .JsonProcessingException ;
8
9
import io .opentelemetry .instrumentation .docs .internal .EmittedMetrics ;
9
10
import io .opentelemetry .instrumentation .docs .utils .FileManager ;
10
11
import io .opentelemetry .instrumentation .docs .utils .YamlHelper ;
@@ -35,9 +36,24 @@ public class EmittedMetricsParser {
35
36
*/
36
37
public static Map <String , EmittedMetrics > getMetricsFromFiles (
37
38
String rootDir , String instrumentationDirectory ) {
38
- Map <String , StringBuilder > metricsByWhen = new HashMap <>();
39
39
Path telemetryDir = Paths .get (rootDir + "/" + instrumentationDirectory , ".telemetry" );
40
40
41
+ Map <String , List <EmittedMetrics .MetricsByScope >> metricsByWhen =
42
+ parseAllMetricFiles (telemetryDir );
43
+
44
+ return aggregateMetricsByScope (metricsByWhen );
45
+ }
46
+
47
+ /**
48
+ * Parses all metric files in the given .telemetry directory and returns a map where the key is
49
+ * the 'when' condition and the value is a list of metrics grouped by scope.
50
+ *
51
+ * @param telemetryDir the path to the .telemetry directory
52
+ * @return a map of 'when' to list of metrics by scope
53
+ */
54
+ private static Map <String , List <EmittedMetrics .MetricsByScope >> parseAllMetricFiles (
55
+ Path telemetryDir ) {
56
+ Map <String , List <EmittedMetrics .MetricsByScope >> metricsByWhen = new HashMap <>();
41
57
if (Files .exists (telemetryDir ) && Files .isDirectory (telemetryDir )) {
42
58
try (Stream <Path > files = Files .list (telemetryDir )) {
43
59
files
@@ -49,52 +65,102 @@ public static Map<String, EmittedMetrics> getMetricsFromFiles(
49
65
String when = content .substring (0 , content .indexOf ('\n' ));
50
66
String whenKey = when .replace ("when: " , "" );
51
67
52
- metricsByWhen .putIfAbsent (whenKey , new StringBuilder ("metrics:\n " ));
53
-
54
- // Skip the metric label ("metrics:") so we can aggregate into one list
55
- int metricsIndex = content .indexOf ("metrics:\n " );
68
+ int metricsIndex = content .indexOf ("metrics_by_scope:" );
56
69
if (metricsIndex != -1 ) {
57
- String contentAfterMetrics =
58
- content .substring (metricsIndex + "metrics:\n " .length ());
59
- metricsByWhen .get (whenKey ).append (contentAfterMetrics );
70
+ String yaml = "when: " + whenKey + "\n " + content .substring (metricsIndex );
71
+ EmittedMetrics parsed ;
72
+ try {
73
+ parsed = YamlHelper .emittedMetricsParser (yaml );
74
+ } catch (Exception e ) {
75
+ logger .severe (
76
+ "Error parsing metrics file (" + path + "): " + e .getMessage ());
77
+ return ;
78
+ }
79
+ if (parsed .getMetricsByScope () != null ) {
80
+ metricsByWhen .putIfAbsent (whenKey , new ArrayList <>());
81
+ metricsByWhen .get (whenKey ).addAll (parsed .getMetricsByScope ());
82
+ }
60
83
}
61
84
}
62
85
});
63
86
} catch (IOException e ) {
64
87
logger .severe ("Error reading metrics files: " + e .getMessage ());
65
88
}
66
89
}
90
+ return metricsByWhen ;
91
+ }
67
92
68
- return parseMetrics (metricsByWhen );
93
+ /**
94
+ * Aggregates metrics under the same scope for each 'when' condition, deduplicating metrics by
95
+ * name.
96
+ *
97
+ * @param metricsByWhen map of 'when' to list of metrics by scope
98
+ * @return a map of 'when' to aggregated EmittedMetrics
99
+ */
100
+ private static Map <String , EmittedMetrics > aggregateMetricsByScope (
101
+ Map <String , List <EmittedMetrics .MetricsByScope >> metricsByWhen ) {
102
+ Map <String , EmittedMetrics > result = new HashMap <>();
103
+ for (Map .Entry <String , List <EmittedMetrics .MetricsByScope >> entry : metricsByWhen .entrySet ()) {
104
+ String when = entry .getKey ();
105
+ List <EmittedMetrics .MetricsByScope > allScopes = entry .getValue ();
106
+ Map <String , Map <String , EmittedMetrics .Metric >> metricsByScopeName = new HashMap <>();
107
+
108
+ for (EmittedMetrics .MetricsByScope scopeEntry : allScopes ) {
109
+ String scope = scopeEntry .getScope ();
110
+ metricsByScopeName .putIfAbsent (scope , new HashMap <>());
111
+ Map <String , EmittedMetrics .Metric > metricMap = metricsByScopeName .get (scope );
112
+
113
+ for (EmittedMetrics .Metric metric : scopeEntry .getMetrics ()) {
114
+ metricMap .put (metric .getName (), metric ); // deduplicate by name
115
+ }
116
+ }
117
+
118
+ List <EmittedMetrics .MetricsByScope > mergedScopes = new ArrayList <>();
119
+ for (Map .Entry <String , Map <String , EmittedMetrics .Metric >> scopeEntry :
120
+ metricsByScopeName .entrySet ()) {
121
+ mergedScopes .add (
122
+ new EmittedMetrics .MetricsByScope (
123
+ scopeEntry .getKey (), new ArrayList <>(scopeEntry .getValue ().values ())));
124
+ }
125
+ result .put (when , new EmittedMetrics (when , mergedScopes ));
126
+ }
127
+ return result ;
69
128
}
70
129
71
130
/**
72
131
* Takes in a raw string representation of the aggregated EmittedMetrics yaml map, separated by
73
- * the ` when` , indicating the conditions under which the metrics are emitted. deduplicates the
74
- * metrics by name and then returns a new map of EmittedMetrics objects.
132
+ * the {@code when} , indicating the conditions under which the metrics are emitted. Deduplicates
133
+ * the metrics by name and then returns a new map of EmittedMetrics objects.
75
134
*
76
135
* @param input raw string representation of EmittedMetrics yaml
77
- * @return {@code Map<String, EmittedMetrics>} where the key is the `when` condition
136
+ * @return map where the key is the {@code when} condition and the value is the corresponding
137
+ * EmittedMetrics
138
+ * @throws JsonProcessingException if parsing fails
78
139
*/
79
140
// visible for testing
80
- public static Map <String , EmittedMetrics > parseMetrics (Map <String , StringBuilder > input ) {
141
+ public static Map <String , EmittedMetrics > parseMetrics (Map <String , StringBuilder > input )
142
+ throws JsonProcessingException {
81
143
Map <String , EmittedMetrics > metricsMap = new HashMap <>();
82
144
for (Map .Entry <String , StringBuilder > entry : input .entrySet ()) {
83
145
String when = entry .getKey ();
84
146
StringBuilder content = entry .getValue ();
85
147
86
148
EmittedMetrics metrics = YamlHelper .emittedMetricsParser (content .toString ());
87
- if (metrics .getMetrics () == null ) {
149
+ if (metrics .getMetricsByScope () == null ) {
88
150
continue ;
89
151
}
90
152
91
- Map <String , EmittedMetrics .Metric > deduplicatedMetrics = new HashMap <>();
92
- for (EmittedMetrics .Metric metric : metrics .getMetrics ()) {
93
- deduplicatedMetrics .put (metric .getName (), metric );
153
+ List <EmittedMetrics .MetricsByScope > deduplicatedScopes = new ArrayList <>();
154
+ for (EmittedMetrics .MetricsByScope scopeEntry : metrics .getMetricsByScope ()) {
155
+ String scope = scopeEntry .getScope ();
156
+ Map <String , EmittedMetrics .Metric > dedupedMetrics = new HashMap <>();
157
+ for (EmittedMetrics .Metric metric : scopeEntry .getMetrics ()) {
158
+ dedupedMetrics .put (metric .getName (), metric );
159
+ }
160
+ deduplicatedScopes .add (
161
+ new EmittedMetrics .MetricsByScope (scope , new ArrayList <>(dedupedMetrics .values ())));
94
162
}
95
-
96
- List <EmittedMetrics .Metric > uniqueMetrics = new ArrayList <>(deduplicatedMetrics .values ());
97
- metricsMap .put (when , new EmittedMetrics (when , uniqueMetrics ));
163
+ metricsMap .put (when , new EmittedMetrics (when , deduplicatedScopes ));
98
164
}
99
165
return metricsMap ;
100
166
}
0 commit comments