@@ -25,29 +25,42 @@ import (
25
25
"os"
26
26
"runtime"
27
27
"runtime/metrics"
28
- "strconv"
29
28
"strings"
30
29
"text/template"
31
30
32
31
"github.com/prometheus/client_golang/prometheus"
33
32
"github.com/prometheus/client_golang/prometheus/internal"
33
+
34
+ "github.com/hashicorp/go-version"
34
35
)
35
36
36
37
func main () {
38
+ var givenVersion string
39
+ toolVersion := runtime .Version ()
37
40
if len (os .Args ) != 2 {
38
- log .Fatal ("requires Go version (e.g. go1.17) as an argument" )
41
+ log .Printf ("requires Go version (e.g. go1.17) as an argument. Since it is not specified, assuming %s." , toolVersion )
42
+ givenVersion = toolVersion
43
+ } else {
44
+ givenVersion = os .Args [1 ]
39
45
}
40
- toolVersion := runtime .Version ()
41
- mtv := majorVersion (toolVersion )
42
- mv := majorVersion (os .Args [1 ])
43
- if mtv != mv {
44
- log .Fatalf ("using Go version %q but expected Go version %q" , mtv , mv )
46
+ log .Printf ("given version for Go: %s" , givenVersion )
47
+ log .Printf ("tool version for Go: %s" , toolVersion )
48
+
49
+ tv , err := version .NewVersion (strings .TrimPrefix (givenVersion , "go" ))
50
+ if err != nil {
51
+ log .Fatal (err )
45
52
}
46
- version , err := parseVersion ( mv )
53
+ gv , err := version . NewVersion ( strings . TrimPrefix ( toolVersion , "go" ) )
47
54
if err != nil {
48
- log .Fatalf ("parsing Go version: %v" , err )
55
+ log .Fatal (err )
56
+ }
57
+ if ! gv .Equal (tv ) {
58
+ log .Fatalf ("using Go version %q but expected Go version %q" , tv , gv )
49
59
}
50
60
61
+ v := goVersion (gv .Segments ()[1 ])
62
+ log .Printf ("generating metrics for Go version %q" , v )
63
+
51
64
// Generate code.
52
65
var buf bytes.Buffer
53
66
err = testFile .Execute (& buf , struct {
@@ -56,7 +69,7 @@ func main() {
56
69
Cardinality int
57
70
}{
58
71
Descriptions : metrics .All (),
59
- GoVersion : version ,
72
+ GoVersion : v ,
60
73
Cardinality : rmCardinality (),
61
74
})
62
75
if err != nil {
@@ -70,7 +83,7 @@ func main() {
70
83
}
71
84
72
85
// Write it to a file.
73
- fname := fmt .Sprintf ("go_collector_metrics_%s_test.go" , version .Abbr ())
86
+ fname := fmt .Sprintf ("go_collector_metrics_%s_test.go" , v .Abbr ())
74
87
if err := os .WriteFile (fname , result , 0o644 ); err != nil {
75
88
log .Fatalf ("writing file: %v" , err )
76
89
}
@@ -86,19 +99,6 @@ func (g goVersion) Abbr() string {
86
99
return fmt .Sprintf ("go1%d" , g )
87
100
}
88
101
89
- func parseVersion (s string ) (goVersion , error ) {
90
- i := strings .IndexRune (s , '.' )
91
- if i < 0 {
92
- return goVersion (- 1 ), fmt .Errorf ("bad Go version format" )
93
- }
94
- i , err := strconv .Atoi (s [i + 1 :])
95
- return goVersion (i ), err
96
- }
97
-
98
- func majorVersion (v string ) string {
99
- return v [:strings .LastIndexByte (v , '.' )]
100
- }
101
-
102
102
func rmCardinality () int {
103
103
cardinality := 0
104
104
@@ -123,6 +123,7 @@ func rmCardinality() int {
123
123
name [strings .IndexRune (name , ':' )+ 1 :],
124
124
)
125
125
cardinality += len (buckets ) + 3 // Plus total count, sum, and the implicit infinity bucket.
126
+
126
127
// runtime/metrics bucket boundaries are lower-bound-inclusive, but
127
128
// always represents each actual *boundary* so Buckets is always
128
129
// 1 longer than Counts, while in Prometheus the mapping is one-to-one,
@@ -134,6 +135,12 @@ func rmCardinality() int {
134
135
// We already counted the infinity bucket separately.
135
136
cardinality --
136
137
}
138
+ // Prometheus also doesn't have buckets for -Inf, so they need to be omitted.
139
+ // See the following PR for more information:
140
+ // https://github.com/prometheus/client_golang/pull/1049
141
+ if buckets [0 ] == math .Inf (- 1 ) {
142
+ cardinality --
143
+ }
137
144
}
138
145
139
146
return cardinality
0 commit comments