From 5240f7e8f55831977171775bd0245f2186029895 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Sat, 18 Aug 2018 15:56:08 +0200 Subject: [PATCH 1/2] Add a wrapper to add a timestamp to a metric Signed-off-by: beorn7 --- prometheus/examples_test.go | 34 ++++++++++++++++++++++++++++++++++ prometheus/metric.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/prometheus/examples_test.go b/prometheus/examples_test.go index 07b392920..52835693c 100644 --- a/prometheus/examples_test.go +++ b/prometheus/examples_test.go @@ -21,6 +21,7 @@ import ( "runtime" "sort" "strings" + "time" dto "github.com/prometheus/client_model/go" "github.com/prometheus/common/expfmt" @@ -751,3 +752,36 @@ temperature_kelvin 4.5 // temperature_kelvin{location="inside"} 298.44 // temperature_kelvin{location="outside"} 273.14 } + +func ExampleNewMetricWithTimestamp() { + desc := prometheus.NewDesc( + "temperature_kelvin", + "Current temperature in Kelvin.", + nil, nil, + ) + + // Create a constant gauge from values we got from an external + // temperature reporting system. Those values are reported with a slight + // delay, so we want to add the timestamp of the actual measurement. + temperatureReportedByExternalSystem := 298.15 + timeReportedByExternalSystem := time.Date(2009, time.November, 10, 23, 0, 0, 12345678, time.UTC) + s := prometheus.NewMetricWithTimestamp( + timeReportedByExternalSystem, + prometheus.MustNewConstMetric( + desc, prometheus.GaugeValue, temperatureReportedByExternalSystem, + ), + ) + + // Just for demonstration, let's check the state of the gauge by + // (ab)using its Write method (which is usually only used by Prometheus + // internally). + metric := &dto.Metric{} + s.Write(metric) + fmt.Println(proto.MarshalTextString(metric)) + + // Output: + // gauge: < + // value: 298.15 + // > + // timestamp_ms: 1257894000012 +} diff --git a/prometheus/metric.go b/prometheus/metric.go index 76035bca5..a2da4910a 100644 --- a/prometheus/metric.go +++ b/prometheus/metric.go @@ -15,7 +15,9 @@ package prometheus import ( "strings" + "time" + "github.com/gogo/protobuf/proto" dto "github.com/prometheus/client_model/go" ) @@ -142,3 +144,31 @@ func NewInvalidMetric(desc *Desc, err error) Metric { func (m *invalidMetric) Desc() *Desc { return m.desc } func (m *invalidMetric) Write(*dto.Metric) error { return m.err } + +type timestampedMetric struct { + Metric + t time.Time +} + +func (m timestampedMetric) Write(pb *dto.Metric) error { + e := m.Metric.Write(pb) + pb.TimestampMs = proto.Int64(m.t.Unix()*1000 + int64(m.t.Nanosecond()/1000000)) + return e +} + +// NewMetricWithTimestamp returns a new Metric wrapping the provided Metric in a +// way that it has an explicit timestamp set to the provided Time. This is only +// useful in rare cases as the timestamp of a Prometheus metric should usually +// be set by the Prometheus server during scraping. Exceptions include mirroring +// metrics with given timestamps from other metric +// sources. +// +// NewMetricWithTimestamp works best with MustNewConstMetric, +// MustNewConstHistogram, and MustNewConstSummary, see example. +// +// Currently, the exposition formats used by Prometheus are limited to +// millisecond resolution. Thus, the provided time will be rounded down to the +// next full millisecond value. +func NewMetricWithTimestamp(t time.Time, m Metric) Metric { + return timestampedMetric{Metric: m, t: t} +} From abaece07d1713945eb844977d0759e503dcf7bc9 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Sat, 18 Aug 2018 16:02:33 +0200 Subject: [PATCH 2/2] Fix import grouping Signed-off-by: beorn7 --- prometheus/examples_test.go | 4 ++-- prometheus/metric.go | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/prometheus/examples_test.go b/prometheus/examples_test.go index 52835693c..5f909a615 100644 --- a/prometheus/examples_test.go +++ b/prometheus/examples_test.go @@ -23,10 +23,10 @@ import ( "strings" "time" - dto "github.com/prometheus/client_model/go" + "github.com/golang/protobuf/proto" "github.com/prometheus/common/expfmt" - "github.com/golang/protobuf/proto" + dto "github.com/prometheus/client_model/go" "github.com/prometheus/client_golang/prometheus" ) diff --git a/prometheus/metric.go b/prometheus/metric.go index a2da4910a..06897f238 100644 --- a/prometheus/metric.go +++ b/prometheus/metric.go @@ -18,6 +18,7 @@ import ( "time" "github.com/gogo/protobuf/proto" + dto "github.com/prometheus/client_model/go" )