package metrics import ( "crypto/tls" "crypto/x509" "sync/atomic" "time" "go.opencensus.io/metric" "github.com/pomerium/pomerium/pkg/metrics" ) var ( autocertRenewalsTotal int64 autocertCertificatesTotal int64 autocertCertificateNextExpiresSeconds int64 ) func registerAutocertMetrics(registry *metric.Registry) error { gaugeMetrics := []struct { name string desc string ptr *int64 }{ {metrics.AutocertCertificatesTotal, "Number of certificates tracked by autocert.", &autocertCertificatesTotal}, {metrics.AutocertCertificateNextExpiresSeconds, "The next expiration timestamp in seconds.", &autocertCertificateNextExpiresSeconds}, } for _, gm := range gaugeMetrics { m, err := registry.AddInt64DerivedGauge(gm.name, metric.WithDescription(gm.desc)) if err != nil { return err } err = m.UpsertEntry(func() int64 { return atomic.LoadInt64(gm.ptr) }) if err != nil { return err } } cumulativeMetrics := []struct { name string desc string ptr *int64 }{ {metrics.AutocertRenewalsTotal, "Number of autocert renewals.", &autocertRenewalsTotal}, } for _, cm := range cumulativeMetrics { m, err := registry.AddInt64DerivedCumulative(cm.name, metric.WithDescription(cm.desc)) if err != nil { return err } err = m.UpsertEntry(func() int64 { return atomic.LoadInt64(cm.ptr) }) if err != nil { return err } } return nil } // RecordAutocertRenewal records an autocert renewal. func RecordAutocertRenewal() { atomic.AddInt64(&autocertRenewalsTotal, 1) } // RecordAutocertCertificates records the next timestamp an autocert certificate will expire. func RecordAutocertCertificates(certs []tls.Certificate) { var expiresAt time.Time for _, cert := range certs { if len(cert.Certificate) == 0 { continue } c, err := x509.ParseCertificate(cert.Certificate[0]) if err != nil { continue } if expiresAt.IsZero() || c.NotAfter.Before(expiresAt) { expiresAt = c.NotAfter } } if !expiresAt.IsZero() { atomic.StoreInt64(&autocertCertificateNextExpiresSeconds, expiresAt.Unix()) } atomic.StoreInt64(&autocertCertificatesTotal, int64(len(certs))) }