@@ -72,7 +72,7 @@ type StatExporter interface {
7272 from time.Time ,
7373 to time.Time ,
7474 queries []AggQuery ,
75- benchmarkFns ... func (map [string ]StatSummary ) ( string , float64 ) ,
75+ benchmarkFns ... func (map [string ]StatSummary ) * roachtestutil. AggregatedMetric ,
7676 ) (* ClusterStatRun , error )
7777}
7878
@@ -93,8 +93,9 @@ type StatSummary struct {
9393// stat information collected during the run. This struct is mirrored in
9494// cockroachdb/roachperf for deserialization.
9595type ClusterStatRun struct {
96- Total map [string ]float64 `json:"total"`
97- Stats map [string ]StatSummary `json:"stats"`
96+ Total map [string ]float64 `json:"total"`
97+ Stats map [string ]StatSummary `json:"stats"`
98+ BenchmarkMetrics map [string ]roachtestutil.AggregatedMetric `json:"-"` // Not serialized to JSON
9899}
99100
100101// statsWriter writes the stats buffer to the file. This is used in unit test
@@ -137,13 +138,47 @@ func (r *ClusterStatRun) serializeOpenmetricsOutRun(
137138 return statsWriter (ctx , t , c , report , dest )
138139}
139140
141+ // createReport returns a ClusterStatRun struct that encompases the results of
142+ // the run.
143+ func createReport (
144+ summaries map [string ]StatSummary ,
145+ summaryStats map [string ]float64 ,
146+ benchmarkMetrics map [string ]roachtestutil.AggregatedMetric ,
147+ ) * ClusterStatRun {
148+ testRun := ClusterStatRun {
149+ Stats : make (map [string ]StatSummary ),
150+ BenchmarkMetrics : benchmarkMetrics ,
151+ }
152+
153+ for tag , summary := range summaries {
154+ testRun .Stats [tag ] = summary
155+ }
156+ testRun .Total = summaryStats
157+ return & testRun
158+ }
159+
160+ // serializeOpenmetricsReport serializes the passed in statistics into an openmetrics
161+ // parseable performance artifact format.
140162func serializeOpenmetricsReport (r ClusterStatRun , labelString * string ) (* bytes.Buffer , error ) {
141163 var buffer bytes.Buffer
142164
143165 // Emit summary metrics from Total
144166 for metricName , value := range r .Total {
145167 buffer .WriteString (roachtestutil .GetOpenmetricsGaugeType (metricName ))
146- buffer .WriteString (fmt .Sprintf ("%s{%s} %f %d\n " , util .SanitizeMetricName (metricName ), * labelString , value , timeutil .Now ().UTC ().Unix ()))
168+
169+ // Add labels from benchmark metrics if available
170+ additionalLabels := ""
171+ if benchmarkMetric , ok := r .BenchmarkMetrics [metricName ]; ok {
172+ additionalLabels += fmt .Sprintf (",unit=\" %s\" " , util .SanitizeValue (benchmarkMetric .Unit ))
173+ additionalLabels += fmt .Sprintf (",is_higher_better=\" %t\" " , benchmarkMetric .IsHigherBetter )
174+ }
175+
176+ buffer .WriteString (fmt .Sprintf ("%s{%s%s} %f %d\n " ,
177+ util .SanitizeMetricName (metricName ),
178+ * labelString ,
179+ additionalLabels ,
180+ value ,
181+ timeutil .Now ().UTC ().Unix ()))
147182 }
148183
149184 // Emit histogram metrics from Stats
@@ -179,20 +214,6 @@ func serializeOpenmetricsReport(r ClusterStatRun, labelString *string) (*bytes.B
179214 return & buffer , nil
180215}
181216
182- // createReport returns a ClusterStatRun struct that encompases the results of
183- // the run.
184- func createReport (
185- summaries map [string ]StatSummary , summaryStats map [string ]float64 ,
186- ) * ClusterStatRun {
187- testRun := ClusterStatRun {Stats : make (map [string ]StatSummary )}
188-
189- for tag , summary := range summaries {
190- testRun .Stats [tag ] = summary
191- }
192- testRun .Total = summaryStats
193- return & testRun
194- }
195-
196217// Export collects, serializes and saves a roachperf file, with statistics
197218// collect from - to time, for the AggQuery(s) given. The format is described
198219// in the doc.go and the AggQuery definition. In addition to the AggQuery(s),
@@ -208,20 +229,37 @@ func (cs *clusterStatCollector) Export(
208229 from time.Time ,
209230 to time.Time ,
210231 queries []AggQuery ,
211- benchmarkFns ... func (summaries map [string ]StatSummary ) ( string , float64 ) ,
232+ benchmarkFns ... func (summaries map [string ]StatSummary ) * roachtestutil. AggregatedMetric ,
212233) (testRun * ClusterStatRun , err error ) {
213234 l := t .L ()
214235 summaries := cs .collectSummaries (ctx , l , Interval {From : from , To : to }, queries )
215236
216- summaryValues := make (map [string ]float64 )
217- for _ , scalarFn := range benchmarkFns {
218- t , result := scalarFn (summaries )
219- summaryValues [t ] = result
237+ // Cache this value to avoid calling the function multiple times
238+ isOpenMetricsEnabled := t .ExportOpenmetrics ()
239+
240+ // Initialize benchmarkMetrics as nil when OpenMetrics is disabled
241+ var benchmarkMetrics map [string ]roachtestutil.AggregatedMetric
242+ if isOpenMetricsEnabled {
243+ benchmarkMetrics = make (map [string ]roachtestutil.AggregatedMetric )
244+ }
245+
246+ // Summary values for total are always collected
247+ summaryValues := map [string ]float64 {}
248+ for _ , benchMarkFn := range benchmarkFns {
249+ benchmarkMetric := benchMarkFn (summaries )
250+ if benchmarkMetric != nil {
251+ summaryValues [benchmarkMetric .Name ] = float64 (benchmarkMetric .Value )
252+
253+ // Only populate BenchmarkMetrics when OpenMetrics export is enabled
254+ if isOpenMetricsEnabled {
255+ benchmarkMetrics [benchmarkMetric .Name ] = * benchmarkMetric
256+ }
257+ }
220258 }
221259
222- testRun = createReport (summaries , summaryValues )
260+ testRun = createReport (summaries , summaryValues , benchmarkMetrics )
223261 if ! dryRun {
224- err = testRun .SerializeOutRun (ctx , t , c , t . ExportOpenmetrics () )
262+ err = testRun .SerializeOutRun (ctx , t , c , isOpenMetricsEnabled )
225263 }
226264 return testRun , err
227265}
0 commit comments