From b7d00b230d67fd2868d78e420b7801335541341d Mon Sep 17 00:00:00 2001 From: Arthur Silva Sens Date: Tue, 12 Dec 2023 19:29:56 -0300 Subject: [PATCH] Optinally print OM created lines Signed-off-by: Arthur Silva Sens --- examples/createdtimestamps/main.go | 67 ++++++++++++++++++++++++++++++ go.mod | 2 + go.sum | 4 +- prometheus/promhttp/http.go | 22 +++++++++- 4 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 examples/createdtimestamps/main.go diff --git a/examples/createdtimestamps/main.go b/examples/createdtimestamps/main.go new file mode 100644 index 000000000..1f6befed8 --- /dev/null +++ b/examples/createdtimestamps/main.go @@ -0,0 +1,67 @@ +// 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/collectors" + "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() + + // Add go runtime metrics and process collectors. + registry.MustRegister( + collectors.NewGoCollector(), + collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}), + 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, + EnableOpenMetricsCreatedLines: true, + }), + ) + // To test: curl -H 'Accept: application/openmetrics-text' localhost:8080/metrics + log.Fatalln(http.ListenAndServe(":8081", nil)) +} diff --git a/go.mod b/go.mod index 1199beb0c..63e7a36db 100644 --- a/go.mod +++ b/go.mod @@ -29,3 +29,5 @@ require ( ) exclude github.com/prometheus/client_golang v1.12.1 + +replace github.com/prometheus/common => github.com/ArthurSens/common v0.0.0-20240202142709-6a6b93b6b111 diff --git a/go.sum b/go.sum index 4f1f464ff..e81026d16 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/ArthurSens/common v0.0.0-20240202142709-6a6b93b6b111 h1:W9c8LaygwdqrtdNxx7rtjuMjZVolfG3bV12TVpW7ob8= +github.com/ArthurSens/common v0.0.0-20240202142709-6a6b93b6b111/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= @@ -33,8 +35,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= -github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y= -github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= diff --git a/prometheus/promhttp/http.go b/prometheus/promhttp/http.go index 09b8d2fbe..633156e35 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.EnableOpenMetricsCreatedLines { + 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, 'EnableOpenMetricsCreatedLines' 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. + EnableOpenMetricsCreatedLines 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