@@ -185,7 +185,7 @@ func HandlerForTransactional(reg prometheus.TransactionalGatherer, opts HandlerO
185
185
}
186
186
187
187
var contentType expfmt.Format
188
- if opts .EnableOpenMetrics {
188
+ if opts .EnableOpenMetrics || opts . OpenMetricsOptions . Enable {
189
189
contentType = expfmt .NegotiateIncludingOpenMetrics (req .Header )
190
190
} else {
191
191
contentType = expfmt .Negotiate (req .Header )
@@ -207,7 +207,13 @@ func HandlerForTransactional(reg prometheus.TransactionalGatherer, opts HandlerO
207
207
if encodingHeader != string (Identity ) {
208
208
rsp .Header ().Set (contentEncodingHeader , encodingHeader )
209
209
}
210
- enc := expfmt .NewEncoder (w , contentType )
210
+
211
+ var enc expfmt.Encoder
212
+ if opts .OpenMetricsOptions .EnableCreatedTimestamps {
213
+ enc = expfmt .NewEncoder (w , contentType , expfmt .WithCreatedLines ())
214
+ } else {
215
+ enc = expfmt .NewEncoder (w , contentType )
216
+ }
211
217
212
218
// handleError handles the error according to opts.ErrorHandling
213
219
// and returns true if we have to abort after the handling.
@@ -398,16 +404,11 @@ type HandlerOpts struct {
398
404
// away). Until the implementation is improved, it is recommended to
399
405
// implement a separate timeout in potentially slow Collectors.
400
406
Timeout time.Duration
401
- // If true, the experimental OpenMetrics encoding is added to the
402
- // possible options during content negotiation. Note that Prometheus
403
- // 2.5.0+ will negotiate OpenMetrics as first priority. OpenMetrics is
404
- // the only way to transmit exemplars. However, the move to OpenMetrics
405
- // is not completely transparent. Most notably, the values of "quantile"
406
- // labels of Summaries and "le" labels of Histograms are formatted with
407
- // a trailing ".0" if they would otherwise look like integer numbers
408
- // (which changes the identity of the resulting series on the Prometheus
409
- // server).
407
+ // Deprecated: Use OpenMetricsOptions.Enable instead.
410
408
EnableOpenMetrics bool
409
+ // OpenMetricsOptions holds settings for the experimental OpenMetrics encoding.
410
+ // It can be used to enable OpenMetrics encoding and for setting extra options.
411
+ OpenMetricsOptions OpenMetricsOptions
411
412
// ProcessStartTime allows setting process start timevalue that will be exposed
412
413
// with "Process-Start-Time-Unix" response header along with the metrics
413
414
// payload. This allow callers to have efficient transformations to cumulative
@@ -418,6 +419,43 @@ type HandlerOpts struct {
418
419
ProcessStartTime time.Time
419
420
}
420
421
422
+ type OpenMetricsOptions struct {
423
+ // Enable specifies if the experimental OpenMetrics encoding is added to the
424
+ // possible options during content negotiation.
425
+ //
426
+ // Note that Prometheus 2.5.0+ might negotiate OpenMetrics Text format
427
+ // as first priority unless user uses custom scrape protocol prioritization or
428
+ // histograms feature is enabled (then Prometheus proto format is prioritized,
429
+ // which client_golang supports).
430
+ //
431
+ // Keep in mind that the move to OpenMetrics is not completely transparent. Most notably,
432
+ // the values of "quantile" labels of Summaries and "le" labels of Histograms are
433
+ // formatted with a trailing ".0" if they would otherwise look like integer numbers
434
+ // (which changes the identity of the resulting series on the Prometheus
435
+ // server).
436
+ //
437
+ // See other options in OpenMetricsOptions to learn how to enable some special
438
+ // features e.g. potentially dangerous created timestamp series.
439
+ Enable bool
440
+ // EnableCreatedTimestamps specifies if this handler should add, extra, synthetic
441
+ // Created Timestamps for counters, histograms and summaries, which for the current
442
+ // version of OpenMetrics are defined as extra series with the same name and "_created"
443
+ // suffix. See also the OpenMetrics specification for more details
444
+ // https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#counter-1
445
+ //
446
+ // Created timestamps are used to improve the accuracy of reset detection,
447
+ // but the way it's designed in OpenMetrics 1.0 it also dramatically increases cardinality
448
+ // if the scraper does not handle those metrics correctly (converting to created timestamp
449
+ // instead of leaving those series as-is). New OpenMetrics versions might improve
450
+ // this situation.
451
+ //
452
+ // Prometheus introduced the feature flag 'created-timestamp-zero-ingestion'
453
+ // in version 2.50.0, but only for the Prometheus protobuf format. Starting in
454
+ // future Prometheus version, the feature flag will be extended to the OpenMetrics
455
+ // text format, thus safe to be enabled to improve accuracy of counters in Prometheus.
456
+ EnableCreatedTimestamps bool
457
+ }
458
+
421
459
// httpError removes any content-encoding header and then calls http.Error with
422
460
// the provided error and http.StatusInternalServerError. Error contents is
423
461
// supposed to be uncompressed plain text. Same as with a plain http.Error, this
0 commit comments