From 5e47fbf45b92063ccc706fcf876bc2e4ddcdd17e Mon Sep 17 00:00:00 2001 From: jfcoz Date: Mon, 15 Mar 2021 14:24:37 +0100 Subject: [PATCH] --add-delays argument calculate delays in seconds x509_cert_seconds_since_not_before and x509_cert_seconds_until_not_after --- README.md | 9 ++--- cmd/x509-certificate-exporter/main.go | 4 +-- internal/collector.go | 51 +++++++++++++++++++-------- internal/exporter.go | 2 +- 4 files changed, 43 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 01eae34..2486e7a 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,6 @@ The following metrics are available: * `x509_cert_not_after` * `x509_cert_expired` * `x509_read_errors` -* `x509_read_timestamp` ### Advanced usage @@ -106,12 +105,10 @@ Here is an exemple: x509_cert_not_after - time() ``` -When collecting these metrics from tools like Datadog that does not have timestamp functions, the `x509_read_timestamp` allow to know read timestamp. -Run the exporter with `--timestamp-metric` to get that optionnal metric. +When collecting these metrics from tools like Datadog that does not have timestamp functions, run the exporter with `--add-delays` argument to get that optionnal metrics: -``` -x509_cert_not_after - x509_read_timestamp > delay_in_seconds -``` +* `x509_cert_seconds_since_not_before` +* `x509_cert_seconds_until_not_after` ### How to ensure it keeps working over time? diff --git a/cmd/x509-certificate-exporter/main.go b/cmd/x509-certificate-exporter/main.go index 8487487..cb56ff8 100644 --- a/cmd/x509-certificate-exporter/main.go +++ b/cmd/x509-certificate-exporter/main.go @@ -27,7 +27,7 @@ func main() { port := getopt.IntLong("port", 'p', 9793, "prometheus exporter listening port") debug := getopt.BoolLong("debug", 0, "enable debug mode") trimPathComponents := getopt.IntLong("trim-path-components", 0, 0, "remove leading component(s) from path(s) in label(s)") - emitTimestampMetric := getopt.BoolLong("timestamp-metric", 0, "provide an additionnal metric with current timestamp") + emitDelayMetrics := getopt.BoolLong("add-delays", 0, "provide x509_cert_seconds_since_not_before/x509_cert_seconds_until_not_after additionnal metrics") files := stringArrayFlag{} getopt.FlagLong(&files, "watch-file", 'f', "watch one or more x509 certificate file") @@ -78,7 +78,7 @@ func main() { YAMLs: yamls, YAMLPaths: internal.DefaultYamlPaths, TrimPathComponents: *trimPathComponents, - EmitTimestampMetric: *emitTimestampMetric, + EmitDelayMetrics: *emitDelayMetrics, KubeSecretTypes: kubeSecretTypes, KubeIncludeNamespaces: kubeIncludeNamespaces, KubeExcludeNamespaces: kubeExcludeNamespaces, diff --git a/internal/collector.go b/internal/collector.go index bd8daa9..a8d2aef 100644 --- a/internal/collector.go +++ b/internal/collector.go @@ -25,17 +25,21 @@ var ( certNotBeforeHelp = "Indicates the certificate's not before timestamp" certNotBeforeDesc = prometheus.NewDesc(certNotBeforeMetric, certNotBeforeHelp, nil, nil) + certSecondsSinceNotBeforeMetric = "x509_cert_seconds_since_not_before" + certSecondsSinceNotBeforeHelp = "Indicates seconds since certificate's not before timestamp" + certSecondsSinceNotBeforeDesc = prometheus.NewDesc(certSecondsSinceNotBeforeMetric, certSecondsSinceNotBeforeHelp, nil, nil) + certNotAfterMetric = "x509_cert_not_after" certNotAfterHelp = "Indicates the certificate's not after timestamp" certNotAfterDesc = prometheus.NewDesc(certNotAfterMetric, certNotAfterHelp, nil, nil) + certSecondsUntilNotAfterMetric = "x509_cert_seconds_until_not_after" + certSecondsUntilNotAfterHelp = "Indicates the seconds until certificate's not after timestamp" + certSecondsUntilNotAfterDesc = prometheus.NewDesc(certSecondsUntilNotAfterMetric, certSecondsUntilNotAfterHelp, nil, nil) + certErrorsMetric = "x509_read_errors" certErrorsHelp = "Indicates the number of read failure(s)" certErrorsDesc = prometheus.NewDesc(certErrorsMetric, certErrorsHelp, nil, nil) - - certTimestampMetric = "x509_read_timestamp" - certTimestampHelp = "Indicates the read timestamp" - certTimestampDesc = prometheus.NewDesc(certTimestampMetric, certTimestampHelp, nil, nil) ) func (collector *collector) Describe(ch chan<- *prometheus.Desc) { @@ -43,7 +47,10 @@ func (collector *collector) Describe(ch chan<- *prometheus.Desc) { ch <- certNotBeforeDesc ch <- certNotAfterDesc ch <- certErrorsDesc - ch <- certTimestampDesc + if collector.exporter.EmitDelayMetrics { + ch <- certSecondsSinceNotBeforeDesc + ch <- certSecondsUntilNotAfterDesc + } } func (collector *collector) Collect(ch chan<- prometheus.Metric) { @@ -71,14 +78,6 @@ func (collector *collector) Collect(ch chan<- prometheus.Metric) { prometheus.GaugeValue, float64(len(certErrors)), ) - - if collector.exporter.EmitTimestampMetric { - ch <- prometheus.MustNewConstMetric( - certTimestampDesc, - prometheus.GaugeValue, - float64(time.Now().Unix()), - ) - } } func (collector *collector) getMetricsForCertificate(certData *parsedCertificate, ref *certificateRef) []prometheus.Metric { @@ -131,7 +130,7 @@ func (collector *collector) getMetricsForCertificate(certData *parsedCertificate expired = 1. } - return []prometheus.Metric{ + CertificatesMetrics := []prometheus.Metric{ prometheus.MustNewConstMetric( prometheus.NewDesc(certExpiredMetric, certExpiredHelp, labels, nil), prometheus.GaugeValue, @@ -151,6 +150,30 @@ func (collector *collector) getMetricsForCertificate(certData *parsedCertificate labelsValue..., ), } + + if collector.exporter.EmitDelayMetrics { + seconds_since_not_before := time.Now().Unix() - certData.cert.NotBefore.Unix() + seconds_until_not_after := certData.cert.NotAfter.Unix() - time.Now().Unix() + + CertificatesDelaysMetrics := []prometheus.Metric{ + prometheus.MustNewConstMetric( + prometheus.NewDesc(certSecondsSinceNotBeforeMetric, certSecondsSinceNotBeforeHelp, labels, nil), + prometheus.GaugeValue, + float64(seconds_since_not_before), + labelsValue..., + ), + prometheus.MustNewConstMetric( + prometheus.NewDesc(certSecondsUntilNotAfterMetric, certSecondsUntilNotAfterHelp, labels, nil), + prometheus.GaugeValue, + float64(seconds_until_not_after), + labelsValue..., + ), + } + + CertificatesMetrics = append(CertificatesMetrics, CertificatesDelaysMetrics...) + } + + return CertificatesMetrics } func getLabelsFromName(name *pkix.Name, prefix string) (labels []string, labelsValue []string) { diff --git a/internal/exporter.go b/internal/exporter.go index 04d8649..d125479 100644 --- a/internal/exporter.go +++ b/internal/exporter.go @@ -22,7 +22,7 @@ type Exporter struct { YAMLs []string YAMLPaths []YAMLCertRef TrimPathComponents int - EmitTimestampMetric bool + EmitDelayMetrics bool KubeSecretTypes []string KubeIncludeNamespaces []string KubeExcludeNamespaces []string