55
66package io .opentelemetry .instrumentation .docs .parsers ;
77
8+ import com .fasterxml .jackson .core .JsonProcessingException ;
89import io .opentelemetry .instrumentation .docs .internal .EmittedMetrics ;
910import io .opentelemetry .instrumentation .docs .utils .FileManager ;
1011import io .opentelemetry .instrumentation .docs .utils .YamlHelper ;
@@ -35,9 +36,24 @@ public class EmittedMetricsParser {
3536 */
3637 public static Map <String , EmittedMetrics > getMetricsFromFiles (
3738 String rootDir , String instrumentationDirectory ) {
38- Map <String , StringBuilder > metricsByWhen = new HashMap <>();
3939 Path telemetryDir = Paths .get (rootDir + "/" + instrumentationDirectory , ".telemetry" );
4040
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 <>();
4157 if (Files .exists (telemetryDir ) && Files .isDirectory (telemetryDir )) {
4258 try (Stream <Path > files = Files .list (telemetryDir )) {
4359 files
@@ -49,52 +65,102 @@ public static Map<String, EmittedMetrics> getMetricsFromFiles(
4965 String when = content .substring (0 , content .indexOf ('\n' ));
5066 String whenKey = when .replace ("when: " , "" );
5167
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:" );
5669 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+ }
6083 }
6184 }
6285 });
6386 } catch (IOException e ) {
6487 logger .severe ("Error reading metrics files: " + e .getMessage ());
6588 }
6689 }
90+ return metricsByWhen ;
91+ }
6792
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 ;
69128 }
70129
71130 /**
72131 * 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.
75134 *
76135 * @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
78139 */
79140 // 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 {
81143 Map <String , EmittedMetrics > metricsMap = new HashMap <>();
82144 for (Map .Entry <String , StringBuilder > entry : input .entrySet ()) {
83145 String when = entry .getKey ();
84146 StringBuilder content = entry .getValue ();
85147
86148 EmittedMetrics metrics = YamlHelper .emittedMetricsParser (content .toString ());
87- if (metrics .getMetrics () == null ) {
149+ if (metrics .getMetricsByScope () == null ) {
88150 continue ;
89151 }
90152
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 ())));
94162 }
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 ));
98164 }
99165 return metricsMap ;
100166 }
0 commit comments