Adds clock_time_seconds_gauge metric which returns the current clock

time, based on unix time since time began

Signed-off-by: joshvanl <vleeuwenjoshua@gmail.com>
This commit is contained in:
joshvanl 2021-12-02 11:27:22 +00:00
parent 3191293cb8
commit 51e728688f
3 changed files with 54 additions and 23 deletions

View File

@ -47,7 +47,9 @@ go_test(
"//pkg/apis/meta/v1:go_default_library",
"//pkg/logs/testing:go_default_library",
"//test/unit/gen:go_default_library",
"@com_github_prometheus_client_golang//prometheus:go_default_library",
"@com_github_prometheus_client_golang//prometheus/testutil:go_default_library",
"@com_github_stretchr_testify//assert:go_default_library",
"@io_k8s_apimachinery//pkg/apis/meta/v1:go_default_library",
"@io_k8s_utils//clock:go_default_library",
"@io_k8s_utils//clock/testing:go_default_library",

View File

@ -29,12 +29,10 @@ import (
"net/http"
"time"
"k8s.io/utils/clock"
"github.com/go-logr/logr"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"k8s.io/utils/clock"
cmmeta "github.com/jetstack/cert-manager/pkg/apis/meta/v1"
)
@ -54,6 +52,7 @@ type Metrics struct {
registry *prometheus.Registry
clockTimeSeconds prometheus.CounterFunc
clockTimeSecondsGauge prometheus.GaugeFunc
certificateExpiryTimeSeconds *prometheus.GaugeVec
certificateRenewalTimeSeconds *prometheus.GaugeVec
certificateReadyStatus *prometheus.GaugeVec
@ -78,6 +77,25 @@ func New(log logr.Logger, c clock.Clock) *Metrics {
},
)
// The clockTimeSeconds metric was first added, however this was
// erroneously made a "counter" metric type. Time can in fact go backwards,
// see:
// - https://github.com/jetstack/cert-manager/issues/4560
// - https://www.robustperception.io/are-increasing-timestamps-counters-or-gauges
// In order to not break users relying on the `clock_time_seconds` metric,
// a new `clock_time_seconds_gauge` metric of type gauge is added which
// implements the same thing.
clockTimeSecondsGauge = prometheus.NewGaugeFunc(
prometheus.GaugeOpts{
Namespace: namespace,
Name: "clock_time_seconds_gauge",
Help: "The clock time given in seconds (from 1970/01/01 UTC).",
},
func() float64 {
return float64(c.Now().Unix())
},
)
certificateExpiryTimeSeconds = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: namespace,
@ -146,6 +164,7 @@ func New(log logr.Logger, c clock.Clock) *Metrics {
registry: prometheus.NewRegistry(),
clockTimeSeconds: clockTimeSeconds,
clockTimeSecondsGauge: clockTimeSecondsGauge,
certificateExpiryTimeSeconds: certificateExpiryTimeSeconds,
certificateRenewalTimeSeconds: certificateRenewalTimeSeconds,
certificateReadyStatus: certificateReadyStatus,

View File

@ -22,39 +22,49 @@ import (
"testing"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/testutil"
"github.com/stretchr/testify/assert"
logtesting "github.com/jetstack/cert-manager/pkg/logs/testing"
fakeclock "k8s.io/utils/clock/testing"
)
var (
fixedClock = fakeclock.NewFakeClock(time.Now())
)
func Test_clockTimeSeconds(t *testing.T) {
fixedClock := fakeclock.NewFakeClock(time.Now())
m := New(logtesting.TestLogger{T: t}, fixedClock)
tests := map[string]struct {
metricName string
metric prometheus.Collector
func TestClockMetrics(t *testing.T) {
type testT struct {
expected string
}
tests := map[string]testT{
"clock time seconds as expected": {
}{
"clock_time_seconds of type counter": {
metricName: "certmanager_clock_time_seconds",
metric: m.clockTimeSeconds,
expected: fmt.Sprintf(`
# HELP certmanager_clock_time_seconds The clock time given in seconds (from 1970/01/01 UTC).
# TYPE certmanager_clock_time_seconds counter
certmanager_clock_time_seconds %f
# HELP certmanager_clock_time_seconds The clock time given in seconds (from 1970/01/01 UTC).
# TYPE certmanager_clock_time_seconds counter
certmanager_clock_time_seconds %f
`, float64(fixedClock.Now().Unix())),
},
"clock_time_seconds_gauge of type gauge": {
metricName: "certmanager_clock_time_seconds_gauge",
metric: m.clockTimeSecondsGauge,
expected: fmt.Sprintf(`
# HELP certmanager_clock_time_seconds_gauge The clock time given in seconds (from 1970/01/01 UTC).
# TYPE certmanager_clock_time_seconds_gauge gauge
certmanager_clock_time_seconds_gauge %f
`, float64(fixedClock.Now().Unix())),
},
}
for n, test := range tests {
t.Run(n, func(t *testing.T) {
m := New(logtesting.TestLogger{T: t}, fixedClock)
if err := testutil.CollectAndCompare(m.clockTimeSeconds,
strings.NewReader(test.expected),
"certmanager_clock_time_seconds",
); err != nil {
t.Errorf("unexpected collecting result:\n%s", err)
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
assert.NoError(t,
testutil.CollectAndCompare(test.metric, strings.NewReader(test.expected), test.metricName),
)
})
}
}