@@ -35,6 +35,12 @@ import (
3535// sanity checks. If the input contains duplicate metrics or invalid metric or
3636// label names, the conversion will result in invalid text format output.
3737//
38+ // If metric names conform to the legacy validation pattern, they will be placed
39+ // outside the brackets in the traditional way, like `foo{}`. If the metric name
40+ // fails the legacy validation check, it will be placed quoted inside the
41+ // brackets: `{"foo"}`. As stated above, the input is assumed to be santized and
42+ // no error will be thrown in this case.
43+ //
3844// This function fulfills the type 'expfmt.encoder'.
3945//
4046// Note that OpenMetrics requires a final `# EOF` line. Since this function acts
@@ -98,7 +104,7 @@ func MetricFamilyToOpenMetrics(out io.Writer, in *dto.MetricFamily) (written int
98104 if err != nil {
99105 return
100106 }
101- n , err = w . WriteString ( shortName )
107+ n , err = writeName ( w , shortName )
102108 written += n
103109 if err != nil {
104110 return
@@ -124,7 +130,7 @@ func MetricFamilyToOpenMetrics(out io.Writer, in *dto.MetricFamily) (written int
124130 if err != nil {
125131 return
126132 }
127- n , err = w . WriteString ( shortName )
133+ n , err = writeName ( w , shortName )
128134 written += n
129135 if err != nil {
130136 return
@@ -303,21 +309,9 @@ func writeOpenMetricsSample(
303309 floatValue float64 , intValue uint64 , useIntValue bool ,
304310 exemplar * dto.Exemplar ,
305311) (int , error ) {
306- var written int
307- n , err := w .WriteString (name )
308- written += n
309- if err != nil {
310- return written , err
311- }
312- if suffix != "" {
313- n , err = w .WriteString (suffix )
314- written += n
315- if err != nil {
316- return written , err
317- }
318- }
319- n , err = writeOpenMetricsLabelPairs (
320- w , metric .Label , additionalLabelName , additionalLabelValue ,
312+ written := 0
313+ n , err := writeOpenMetricsNameAndLabelPairs (
314+ w , name + suffix , metric .Label , additionalLabelName , additionalLabelValue ,
321315 )
322316 written += n
323317 if err != nil {
@@ -365,27 +359,58 @@ func writeOpenMetricsSample(
365359 return written , nil
366360}
367361
368- // writeOpenMetricsLabelPairs works like writeOpenMetrics but formats the float
369- // in OpenMetrics style.
370- func writeOpenMetricsLabelPairs (
362+ // writeOpenMetricsNameAndLabelPairs works like writeOpenMetricsSample but
363+ // formats the float in OpenMetrics style.
364+ func writeOpenMetricsNameAndLabelPairs (
371365 w enhancedWriter ,
366+ name string ,
372367 in []* dto.LabelPair ,
373368 additionalLabelName string , additionalLabelValue float64 ,
374369) (int , error ) {
375- if len (in ) == 0 && additionalLabelName == "" {
376- return 0 , nil
377- }
378370 var (
379- written int
380- separator byte = '{'
371+ written int
372+ separator byte = '{'
373+ metricInsideBraces = false
381374 )
375+
376+ if name != "" {
377+ // If the name does not pass the legacy validity check, we must put the
378+ // metric name inside the braces, quoted.
379+ if ! model .IsValidLegacyMetricName (model .LabelValue (name )) {
380+ metricInsideBraces = true
381+ err := w .WriteByte (separator )
382+ written ++
383+ if err != nil {
384+ return written , err
385+ }
386+ separator = ','
387+ }
388+
389+ n , err := writeName (w , name )
390+ written += n
391+ if err != nil {
392+ return written , err
393+ }
394+ }
395+
396+ if len (in ) == 0 && additionalLabelName == "" {
397+ if metricInsideBraces {
398+ err := w .WriteByte ('}' )
399+ written ++
400+ if err != nil {
401+ return written , err
402+ }
403+ }
404+ return written , nil
405+ }
406+
382407 for _ , lp := range in {
383408 err := w .WriteByte (separator )
384409 written ++
385410 if err != nil {
386411 return written , err
387412 }
388- n , err := w . WriteString ( lp .GetName ())
413+ n , err := writeName ( w , lp .GetName ())
389414 written += n
390415 if err != nil {
391416 return written , err
@@ -451,7 +476,7 @@ func writeExemplar(w enhancedWriter, e *dto.Exemplar) (int, error) {
451476 if err != nil {
452477 return written , err
453478 }
454- n , err = writeOpenMetricsLabelPairs ( w , e .Label , "" , 0 )
479+ n , err = writeOpenMetricsNameAndLabelPairs ( w , "" , e .Label , "" , 0 )
455480 written += n
456481 if err != nil {
457482 return written , err
0 commit comments