Skip to content

Commit 81909c5

Browse files
author
Arthur Silva Sens
committed
Move OpenMetrics options to a separate struct
Signed-off-by: Arthur Silva Sens <[email protected]>
1 parent aa055d3 commit 81909c5

File tree

7 files changed

+72
-46
lines changed

7 files changed

+72
-46
lines changed

examples/createdtimestamps/main.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,10 @@ func main() {
5151
"/metrics", promhttp.HandlerFor(
5252
registry,
5353
promhttp.HandlerOpts{
54-
EnableOpenMetrics: true,
55-
EnableOpenMetricsCreatedMetrics: true,
54+
OpenMetricsOptions: promhttp.OpenMetricsOptions{
55+
Enable: true,
56+
EnableCreatedTimestamps: true,
57+
},
5658
}),
5759
)
5860
// To test: curl -H 'Accept: application/openmetrics-text' localhost:8080/metrics

examples/exemplars/main.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ func main() {
6161
"/metrics", promhttp.HandlerFor(
6262
registry,
6363
promhttp.HandlerOpts{
64-
EnableOpenMetrics: true,
64+
OpenMetricsOptions: promhttp.OpenMetricsOptions{
65+
Enable: true,
66+
},
6567
}),
6668
)
6769
// To test: curl -H 'Accept: application/openmetrics-text' localhost:8080/metrics

examples/gocollector/main.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@ func main() {
4747
http.Handle("/metrics", promhttp.HandlerFor(
4848
reg,
4949
promhttp.HandlerOpts{
50-
// Opt into OpenMetrics to support exemplars.
51-
EnableOpenMetrics: true,
50+
OpenMetricsOptions: promhttp.OpenMetricsOptions{
51+
// Opt into OpenMetrics to support exemplars.
52+
Enable: true,
53+
},
5254
},
5355
))
5456
fmt.Println("Hello world from new Go Collector!")

examples/random/main.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,10 @@ func main() {
134134
http.Handle("/metrics", promhttp.HandlerFor(
135135
reg,
136136
promhttp.HandlerOpts{
137-
// Opt into OpenMetrics to support exemplars.
138-
EnableOpenMetrics: true,
137+
OpenMetricsOptions: promhttp.OpenMetricsOptions{
138+
// Opt into OpenMetrics to support exemplars.
139+
Enable: true,
140+
},
139141
// Pass custom registry
140142
Registry: reg,
141143
},

go.mod

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
module github.com/prometheus/client_golang
22

3-
go 1.20
3+
go 1.21
44

55
require (
66
github.com/beorn7/perks v1.0.1
77
github.com/cespare/xxhash/v2 v2.2.0
88
github.com/davecgh/go-spew v1.1.1
99
github.com/json-iterator/go v1.1.12
1010
github.com/prometheus/client_model v0.6.0
11-
github.com/prometheus/common v0.48.0
11+
github.com/prometheus/common v0.49.0
1212
github.com/prometheus/procfs v0.12.0
1313
golang.org/x/sys v0.17.0
1414
google.golang.org/protobuf v1.33.0
@@ -21,13 +21,11 @@ require (
2121
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
2222
github.com/modern-go/reflect2 v1.0.2 // indirect
2323
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
24-
golang.org/x/net v0.20.0 // indirect
25-
golang.org/x/oauth2 v0.16.0 // indirect
24+
golang.org/x/net v0.21.0 // indirect
25+
golang.org/x/oauth2 v0.17.0 // indirect
2626
golang.org/x/text v0.14.0 // indirect
2727
google.golang.org/appengine v1.6.7 // indirect
2828
gopkg.in/yaml.v2 v2.4.0 // indirect
2929
)
3030

3131
exclude github.com/prometheus/client_golang v1.12.1
32-
33-
replace github.com/prometheus/common => github.com/ArthurSens/common v0.0.0-20240202142709-6a6b93b6b111

go.sum

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
github.com/ArthurSens/common v0.0.0-20240202142709-6a6b93b6b111 h1:W9c8LaygwdqrtdNxx7rtjuMjZVolfG3bV12TVpW7ob8=
2-
github.com/ArthurSens/common v0.0.0-20240202142709-6a6b93b6b111/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ=
31
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
42
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
53
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
@@ -13,7 +11,8 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS
1311
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
1412
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
1513
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
16-
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
14+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
15+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
1716
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
1817
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
1918
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
@@ -35,19 +34,22 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
3534
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
3635
github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos=
3736
github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8=
37+
github.com/prometheus/common v0.49.0 h1:ToNTdK4zSnPVJmh698mGFkDor9wBI/iGaJy5dbH1EgI=
38+
github.com/prometheus/common v0.49.0/go.mod h1:Kxm+EULxRbUkjGU6WFsQqo3ORzB4tyKvlWFOE9mB2sE=
3839
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
3940
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
4041
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
4142
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
43+
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
4244
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
4345
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
4446
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
4547
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
4648
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
47-
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
48-
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
49-
golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ=
50-
golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o=
49+
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
50+
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
51+
golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ=
52+
golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA=
5153
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
5254
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
5355
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
@@ -65,5 +67,6 @@ google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGm
6567
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
6668
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
6769
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
70+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
6871
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
6972
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=

prometheus/promhttp/http.go

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ func HandlerForTransactional(reg prometheus.TransactionalGatherer, opts HandlerO
160160
}
161161

162162
var contentType expfmt.Format
163-
if opts.EnableOpenMetrics {
163+
if opts.EnableOpenMetrics || opts.OpenMetricsOptions.Enable {
164164
contentType = expfmt.NegotiateIncludingOpenMetrics(req.Header)
165165
} else {
166166
contentType = expfmt.Negotiate(req.Header)
@@ -181,7 +181,7 @@ func HandlerForTransactional(reg prometheus.TransactionalGatherer, opts HandlerO
181181
}
182182

183183
var enc expfmt.Encoder
184-
if opts.EnableOpenMetricsCreatedMetrics {
184+
if opts.OpenMetricsOptions.EnableCreatedTimestamps {
185185
enc = expfmt.NewEncoder(w, contentType, expfmt.WithCreatedLines())
186186
} else {
187187
enc = expfmt.NewEncoder(w, contentType)
@@ -366,31 +366,11 @@ type HandlerOpts struct {
366366
// away). Until the implementation is improved, it is recommended to
367367
// implement a separate timeout in potentially slow Collectors.
368368
Timeout time.Duration
369-
// If true, the experimental OpenMetrics encoding is added to the
370-
// possible options during content negotiation. Note that Prometheus
371-
// 2.5.0+ will negotiate OpenMetrics as first priority. OpenMetrics is
372-
// the only way to transmit exemplars. However, the move to OpenMetrics
373-
// is not completely transparent. Most notably, the values of "quantile"
374-
// labels of Summaries and "le" labels of Histograms are formatted with
375-
// a trailing ".0" if they would otherwise look like integer numbers
376-
// (which changes the identity of the resulting series on the Prometheus
377-
// server).
369+
// Deprecated: Use OpenMetricsOptions.Enable instead.
378370
EnableOpenMetrics bool
379-
// If 'EnableOpenMetrics' is true, 'EnableOpenMetricsCreatedMetrics' allows
380-
// to add extra '_created' lines for counters, histograms and summaries,
381-
// as defined in the OpenMetrics specification (see
382-
// https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#counter-1).
383-
// Created timestamps are used to improve the accuracy of reset detection,
384-
// but be aware that it also increases the size of the payload.
385-
//
386-
// Prometheus introduced the feature flag 'created-timestamp-zero-ingestion'
387-
// in version 2.50.0, but with support limited to the Prometheus protobuf
388-
// format. Starting in Prometheus XXXX, the feature flag will be extended
389-
// to the OpenMetrics text format. If using Prometheus XXXX or later, it
390-
// is recommended to enable the feature flag in Prometheus, otherwise enabling
391-
// _created lines will result in increased cardinality and no improvements
392-
// in reset detection.
393-
EnableOpenMetricsCreatedMetrics bool
371+
// OpenMetricsOptions holds settings for the experimental OpenMetrics encoding.
372+
// It can be used to enable OpenMetrics encoding and for setting extra options.
373+
OpenMetricsOptions OpenMetricsOptions
394374
// ProcessStartTime allows setting process start timevalue that will be exposed
395375
// with "Process-Start-Time-Unix" response header along with the metrics
396376
// payload. This allow callers to have efficient transformations to cumulative
@@ -401,6 +381,43 @@ type HandlerOpts struct {
401381
ProcessStartTime time.Time
402382
}
403383

384+
type OpenMetricsOptions struct {
385+
// Enable specifies if the experimental OpenMetrics encoding is added to the
386+
// possible options during content negotiation.
387+
//
388+
// Note that Prometheus 2.5.0+ might negotiate OpenMetrics Text format
389+
// as first priority unless user uses custom scrape protocol prioritization or
390+
// histograms feature is enabled (then Prometheus proto format is prioritized,
391+
// which client_golang supports).
392+
//
393+
// Keep in mind that the move to OpenMetrics is not completely transparent. Most notably,
394+
// the values of "quantile" labels of Summaries and "le" labels of Histograms are
395+
// formatted with a trailing ".0" if they would otherwise look like integer numbers
396+
// (which changes the identity of the resulting series on the Prometheus
397+
// server).
398+
//
399+
// See other options in OpenMetricsOptions to learn how to enable some special
400+
// features e.g. potentially dangerous created timestamp series.
401+
Enable bool
402+
// EnableCreatedTimestamps specifies if this handler should add, extra, synthetic
403+
// Created Timestamps for counters, histograms and summaries, which for the current
404+
// version of OpenMetrics are defined as extra series with the same name and "_created"
405+
// suffix. See also the OpenMetrics specification for more details
406+
// https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#counter-1
407+
//
408+
// Created timestamps are used to improve the accuracy of reset detection,
409+
// but the way it's designed in OpenMetrics 1.0 it also dramatically increases cardinality
410+
// if the scraper does not handle those metrics correctly (converting to created timestamp
411+
// instead of leaving those series as-is). New OpenMetrics versions might improve
412+
// this situation.
413+
//
414+
// Prometheus introduced the feature flag 'created-timestamp-zero-ingestion'
415+
// in version 2.50.0, but only for the Prometheus protobuf format. Starting in
416+
// future Prometheus version, the feature flag will be extended to the OpenMetrics
417+
// text format, thus safe to be enabled to improve accuracy of counters in Prometheus.
418+
EnableCreatedTimestamps bool
419+
}
420+
404421
// gzipAccepted returns whether the client will accept gzip-encoded content.
405422
func gzipAccepted(header http.Header) bool {
406423
a := header.Get(acceptEncodingHeader)

0 commit comments

Comments
 (0)