diff --git a/examples/createdtimestamps/main.go b/examples/createdtimestamps/main.go new file mode 100644 index 0000000..f83b959 --- /dev/null +++ b/examples/createdtimestamps/main.go @@ -0,0 +1,60 @@ +// Copyright 2022 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// A simple example of how to exposed created timestamps in OpenMetrics format. + +package main + +import ( + "log" + "net/http" + "time" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" +) + +func main() { + requestDurations := prometheus.NewHistogram(prometheus.HistogramOpts{ + Name: "http_request_duration_seconds", + Help: "A histogram of the HTTP request durations in seconds.", + Buckets: prometheus.ExponentialBuckets(0.1, 1.5, 5), + }) + + // Create non-global registry. + registry := prometheus.NewRegistry() + registry.MustRegister( + requestDurations, + ) + + go func() { + for { + // Record fictional latency. + now := time.Now() + requestDurations.Observe(time.Since(now).Seconds()) + time.Sleep(600 * time.Millisecond) + } + }() + + // Expose /metrics HTTP endpoint using the created custom registry. + http.Handle( + "/metrics", promhttp.HandlerFor( + registry, + promhttp.HandlerOpts{ + EnableOpenMetrics: true, + EnableOpenMetricsCreatedMetrics: true, + }), + ) + // To test: curl -H 'Accept: application/openmetrics-text' localhost:8080/metrics + log.Fatalln(http.ListenAndServe(":8080", nil)) +} diff --git a/prometheus/promhttp/http.go b/prometheus/promhttp/http.go index 09b8d2f..1fd50ae 100644 --- a/prometheus/promhttp/http.go +++ b/prometheus/promhttp/http.go @@ -180,7 +180,12 @@ func HandlerForTransactional(reg prometheus.TransactionalGatherer, opts HandlerO w = gz } - enc := expfmt.NewEncoder(w, contentType) + var enc expfmt.Encoder + if opts.EnableOpenMetricsCreatedMetrics { + enc = expfmt.NewEncoder(w, contentType, expfmt.WithCreatedLines()) + } else { + enc = expfmt.NewEncoder(w, contentType) + } // handleError handles the error according to opts.ErrorHandling // and returns true if we have to abort after the handling. @@ -371,6 +376,21 @@ type HandlerOpts struct { // (which changes the identity of the resulting series on the Prometheus // server). EnableOpenMetrics bool + // If 'EnableOpenMetrics' is true, 'EnableOpenMetricsCreatedMetrics' allows + // to add extra '_created' lines for counters, histograms and summaries, + // as defined in the OpenMetrics specification (see + // https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#counter-1). + // Created timestamps are used to improve the accuracy of reset detection, + // but be aware that it also increases the size of the payload. + // + // Prometheus introduced the feature flag 'created-timestamp-zero-ingestion' + // in version 2.50.0, but with support limited to the Prometheus protobuf + // format. Starting in Prometheus XXXX, the feature flag will be extended + // to the OpenMetrics text format. If using Prometheus XXXX or later, it + // is recommended to enable the feature flag in Prometheus, otherwise enabling + // _created lines will result in increased cardinality and no improvements + // in reset detection. + EnableOpenMetricsCreatedMetrics bool // ProcessStartTime allows setting process start timevalue that will be exposed // with "Process-Start-Time-Unix" response header along with the metrics // payload. This allow callers to have efficient transformations to cumulative