@@ -34,7 +34,7 @@ type MetricDefinition struct {
3434// definition file. When the override path argument is empty, the function will load metrics from
3535// the file associated with the platform's architecture found in the provided metadata. When
3636// a list of metric names is provided, only those metric definitions will be loaded.
37- func LoadMetricDefinitions (metricDefinitionOverridePath string , selectedMetrics []string , uncollectableEvents [] string , metadata Metadata ) (metrics []MetricDefinition , err error ) {
37+ func LoadMetricDefinitions (metricDefinitionOverridePath string , selectedMetrics []string , metadata Metadata ) (metrics []MetricDefinition , err error ) {
3838 var bytes []byte
3939 if metricDefinitionOverridePath != "" {
4040 if bytes , err = os .ReadFile (metricDefinitionOverridePath ); err != nil {
@@ -56,20 +56,6 @@ func LoadMetricDefinitions(metricDefinitionOverridePath string, selectedMetrics
5656 if err = json .Unmarshal (bytes , & metricsInFile ); err != nil {
5757 return
5858 }
59- // remove "metric_" prefix from metric names
60- for i := range metricsInFile {
61- metricsInFile [i ].Name = strings .TrimPrefix (metricsInFile [i ].Name , "metric_" )
62- }
63- // remove metrics from list that use uncollectable events
64- for _ , uncollectableEvent := range uncollectableEvents {
65- for i := 0 ; i < len (metricsInFile ); i ++ {
66- if strings .Contains (metricsInFile [i ].Expression , uncollectableEvent ) {
67- slog .Debug ("removing metric that uses uncollectable event" , slog .String ("metric" , metricsInFile [i ].Name ), slog .String ("event" , uncollectableEvent ))
68- metricsInFile = append (metricsInFile [:i ], metricsInFile [i + 1 :]... )
69- i --
70- }
71- }
72- }
7359 // if a list of metric names provided, reduce list to match
7460 if len (selectedMetrics ) > 0 {
7561 // confirm provided metric names are valid (included in metrics defined in file)
@@ -102,7 +88,7 @@ func LoadMetricDefinitions(metricDefinitionOverridePath string, selectedMetrics
10288// ConfigureMetrics prepares metrics for use by the evaluator, by e.g., replacing
10389// metric constants with known values and aligning metric variables to perf event
10490// groups
105- func ConfigureMetrics (metrics []MetricDefinition , evaluatorFunctions map [string ]govaluate.ExpressionFunction , metadata Metadata ) (err error ) {
91+ func ConfigureMetrics (loadedMetrics []MetricDefinition , uncollectableEvents [] string , evaluatorFunctions map [string ]govaluate.ExpressionFunction , metadata Metadata ) (metrics [] MetricDefinition , err error ) {
10692 // get constants as strings
10793 tscFreq := fmt .Sprintf ("%f" , float64 (metadata .TSCFrequencyHz ))
10894 tsc := fmt .Sprintf ("%f" , float64 (metadata .TSC ))
@@ -112,54 +98,70 @@ func ConfigureMetrics(metrics []MetricDefinition, evaluatorFunctions map[string]
11298 hyperThreadingOn := fmt .Sprintf ("%t" , metadata .ThreadsPerCore > 1 )
11399 threadsPerCore := fmt .Sprintf ("%f" , float64 (metadata .ThreadsPerCore ))
114100 // configure each metric
115- for metricIdx := range metrics {
101+ for metricIdx := range loadedMetrics {
102+ tmpMetric := loadedMetrics [metricIdx ]
103+ // abbreviate event names in metric expressions to match abbreviations used in uncollectableEvents
104+ tmpMetric .Expression = abbreviateEventName (tmpMetric .Expression )
105+ tmpMetric .ExpressionTxn = abbreviateEventName (tmpMetric .ExpressionTxn )
106+ // skip metrics that use uncollectable events
107+ foundUncollectable := false
108+ for _ , uncollectableEvent := range uncollectableEvents {
109+ if strings .Contains (tmpMetric .Expression , uncollectableEvent ) {
110+ slog .Warn ("removing metric that uses uncollectable event" , slog .String ("metric" , tmpMetric .Name ), slog .String ("event" , uncollectableEvent ))
111+ foundUncollectable = true
112+ break
113+ }
114+ }
115+ if foundUncollectable {
116+ continue
117+ }
116118 // swap in per-txn metric definition if transaction rate is provided
117- if flagTransactionRate != 0 && metrics [ metricIdx ] .ExpressionTxn != "" {
118- metrics [ metricIdx ] .Expression = metrics [ metricIdx ] .ExpressionTxn
119- metrics [ metricIdx ] .Expression = strings .ReplaceAll (metrics [ metricIdx ] .Expression , "[TXN]" , fmt .Sprintf ("%f" , flagTransactionRate ))
120- metrics [ metricIdx ] .Name = metrics [ metricIdx ] .NameTxn
119+ if flagTransactionRate != 0 && tmpMetric .ExpressionTxn != "" {
120+ tmpMetric .Expression = tmpMetric .ExpressionTxn
121+ tmpMetric .Expression = strings .ReplaceAll (tmpMetric .Expression , "[TXN]" , fmt .Sprintf ("%f" , flagTransactionRate ))
122+ tmpMetric .Name = tmpMetric .NameTxn
121123 }
124+ // remove "metric_" prefix from metric names
125+ tmpMetric .Name = strings .TrimPrefix (tmpMetric .Name , "metric_" )
122126 // transform if/else to ?/:
123127 var transformed string
124- if transformed , err = transformConditional (metrics [ metricIdx ] .Expression ); err != nil {
128+ if transformed , err = transformConditional (tmpMetric .Expression ); err != nil {
125129 return
126130 }
127- if transformed != metrics [ metricIdx ] .Expression {
128- slog .Debug ("transformed metric" , slog .String ("original" , metrics [ metricIdx ] .Name ), slog .String ("transformed" , transformed ))
129- metrics [ metricIdx ] .Expression = transformed
131+ if transformed != tmpMetric .Expression {
132+ slog .Debug ("transformed metric" , slog .String ("original" , tmpMetric .Name ), slog .String ("transformed" , transformed ))
133+ tmpMetric .Expression = transformed
130134 }
131135 // replace constants with their values
132- metrics [metricIdx ].Expression = strings .ReplaceAll (metrics [metricIdx ].Expression , "[SYSTEM_TSC_FREQ]" , tscFreq )
133- metrics [metricIdx ].Expression = strings .ReplaceAll (metrics [metricIdx ].Expression , "[TSC]" , tsc )
134- metrics [metricIdx ].Expression = strings .ReplaceAll (metrics [metricIdx ].Expression , "[CORES_PER_SOCKET]" , coresPerSocket )
135- metrics [metricIdx ].Expression = strings .ReplaceAll (metrics [metricIdx ].Expression , "[CHAS_PER_SOCKET]" , chasPerSocket )
136- metrics [metricIdx ].Expression = strings .ReplaceAll (metrics [metricIdx ].Expression , "[SOCKET_COUNT]" , socketCount )
137- metrics [metricIdx ].Expression = strings .ReplaceAll (metrics [metricIdx ].Expression , "[HYPERTHREADING_ON]" , hyperThreadingOn )
138- metrics [metricIdx ].Expression = strings .ReplaceAll (metrics [metricIdx ].Expression , "[CONST_THREAD_COUNT]" , threadsPerCore )
139- // abbreviate event names
140- metrics [metricIdx ].Expression = abbreviateEventName (metrics [metricIdx ].Expression )
141- metrics [metricIdx ].ExpressionTxn = abbreviateEventName (metrics [metricIdx ].ExpressionTxn )
136+ tmpMetric .Expression = strings .ReplaceAll (tmpMetric .Expression , "[SYSTEM_TSC_FREQ]" , tscFreq )
137+ tmpMetric .Expression = strings .ReplaceAll (tmpMetric .Expression , "[TSC]" , tsc )
138+ tmpMetric .Expression = strings .ReplaceAll (tmpMetric .Expression , "[CORES_PER_SOCKET]" , coresPerSocket )
139+ tmpMetric .Expression = strings .ReplaceAll (tmpMetric .Expression , "[CHAS_PER_SOCKET]" , chasPerSocket )
140+ tmpMetric .Expression = strings .ReplaceAll (tmpMetric .Expression , "[SOCKET_COUNT]" , socketCount )
141+ tmpMetric .Expression = strings .ReplaceAll (tmpMetric .Expression , "[HYPERTHREADING_ON]" , hyperThreadingOn )
142+ tmpMetric .Expression = strings .ReplaceAll (tmpMetric .Expression , "[CONST_THREAD_COUNT]" , threadsPerCore )
142143 // get a list of the variables in the expression
143- metrics [ metricIdx ] .Variables = make (map [string ]int )
144+ tmpMetric .Variables = make (map [string ]int )
144145 expressionIdx := 0
145146 for {
146- startVar := strings .IndexRune (metrics [ metricIdx ] .Expression [expressionIdx :], '[' )
147+ startVar := strings .IndexRune (tmpMetric .Expression [expressionIdx :], '[' )
147148 if startVar == - 1 { // no more vars in this expression
148149 break
149150 }
150- endVar := strings .IndexRune (metrics [ metricIdx ] .Expression [expressionIdx :], ']' )
151+ endVar := strings .IndexRune (tmpMetric .Expression [expressionIdx :], ']' )
151152 if endVar == - 1 {
152- err = fmt .Errorf ("didn't find end of variable indicator (]) in expression: %s" , metrics [ metricIdx ] .Expression [expressionIdx :])
153+ err = fmt .Errorf ("didn't find end of variable indicator (]) in expression: %s" , tmpMetric .Expression [expressionIdx :])
153154 return
154155 }
155156 // add the variable name to the map, set group index to -1 to indicate it has not yet been determined
156- metrics [ metricIdx ] .Variables [metrics [ metricIdx ] .Expression [expressionIdx :][startVar + 1 :endVar ]] = - 1
157+ tmpMetric .Variables [tmpMetric .Expression [expressionIdx :][startVar + 1 :endVar ]] = - 1
157158 expressionIdx += endVar + 1
158159 }
159- if metrics [ metricIdx ] .Evaluable , err = govaluate .NewEvaluableExpressionWithFunctions (metrics [ metricIdx ] .Expression , evaluatorFunctions ); err != nil {
160- slog .Error ("failed to create evaluable expression for metric" , slog .String ("error" , err .Error ()), slog .String ("metric name" , metrics [ metricIdx ] .Name ), slog .String ("metric expression" , metrics [ metricIdx ] .Expression ))
160+ if tmpMetric .Evaluable , err = govaluate .NewEvaluableExpressionWithFunctions (tmpMetric .Expression , evaluatorFunctions ); err != nil {
161+ slog .Error ("failed to create evaluable expression for metric" , slog .String ("error" , err .Error ()), slog .String ("metric name" , tmpMetric .Name ), slog .String ("metric expression" , tmpMetric .Expression ))
161162 return
162163 }
164+ metrics = append (metrics , tmpMetric )
163165 }
164166 return
165167}
0 commit comments