mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-23 13:59:09 +02:00
add certificate issue duration metrics
This commit is contained in:
@@ -42,6 +42,10 @@ type domainInfo struct {
|
|||||||
err string
|
err string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type metricsRecorder interface {
|
||||||
|
RecordCertificateIssuance(duration time.Duration)
|
||||||
|
}
|
||||||
|
|
||||||
// Manager wraps autocert.Manager with domain tracking and cross-replica
|
// Manager wraps autocert.Manager with domain tracking and cross-replica
|
||||||
// coordination via a pluggable locking strategy. The locker prevents
|
// coordination via a pluggable locking strategy. The locker prevents
|
||||||
// duplicate ACME requests when multiple replicas share a certificate cache.
|
// duplicate ACME requests when multiple replicas share a certificate cache.
|
||||||
@@ -55,6 +59,7 @@ type Manager struct {
|
|||||||
|
|
||||||
certNotifier certificateNotifier
|
certNotifier certificateNotifier
|
||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
|
metrics metricsRecorder
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewManager creates a new ACME certificate manager. The certDir is used
|
// NewManager creates a new ACME certificate manager. The certDir is used
|
||||||
@@ -63,7 +68,7 @@ type Manager struct {
|
|||||||
// eabKID and eabHMACKey are optional External Account Binding credentials
|
// eabKID and eabHMACKey are optional External Account Binding credentials
|
||||||
// required for some CAs like ZeroSSL. The eabHMACKey should be the base64
|
// required for some CAs like ZeroSSL. The eabHMACKey should be the base64
|
||||||
// URL-encoded string provided by the CA.
|
// URL-encoded string provided by the CA.
|
||||||
func NewManager(certDir, acmeURL, eabKID, eabHMACKey string, notifier certificateNotifier, logger *log.Logger, lockMethod CertLockMethod) *Manager {
|
func NewManager(certDir, acmeURL, eabKID, eabHMACKey string, notifier certificateNotifier, logger *log.Logger, lockMethod CertLockMethod, metrics metricsRecorder) *Manager {
|
||||||
if logger == nil {
|
if logger == nil {
|
||||||
logger = log.StandardLogger()
|
logger = log.StandardLogger()
|
||||||
}
|
}
|
||||||
@@ -73,6 +78,7 @@ func NewManager(certDir, acmeURL, eabKID, eabHMACKey string, notifier certificat
|
|||||||
domains: make(map[domain.Domain]*domainInfo),
|
domains: make(map[domain.Domain]*domainInfo),
|
||||||
certNotifier: notifier,
|
certNotifier: notifier,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
|
metrics: metrics,
|
||||||
}
|
}
|
||||||
|
|
||||||
var eab *acme.ExternalAccountBinding
|
var eab *acme.ExternalAccountBinding
|
||||||
@@ -161,6 +167,10 @@ func (mgr *Manager) prefetchCertificate(d domain.Domain) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if mgr.metrics != nil {
|
||||||
|
mgr.metrics.RecordCertificateIssuance(elapsed)
|
||||||
|
}
|
||||||
|
|
||||||
mgr.setDomainState(d, domainReady, "")
|
mgr.setDomainState(d, domainReady, "")
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestHostPolicy(t *testing.T) {
|
func TestHostPolicy(t *testing.T) {
|
||||||
mgr := NewManager(t.TempDir(), "https://acme.example.com/directory", "", "", nil, nil, "")
|
mgr := NewManager(t.TempDir(), "https://acme.example.com/directory", "", "", nil, nil, "", nil)
|
||||||
mgr.AddDomain("example.com", "acc1", "rp1")
|
mgr.AddDomain("example.com", "acc1", "rp1")
|
||||||
|
|
||||||
// Wait for the background prefetch goroutine to finish so the temp dir
|
// Wait for the background prefetch goroutine to finish so the temp dir
|
||||||
@@ -70,7 +70,7 @@ func TestHostPolicy(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDomainStates(t *testing.T) {
|
func TestDomainStates(t *testing.T) {
|
||||||
mgr := NewManager(t.TempDir(), "https://acme.example.com/directory", "", "", nil, nil, "")
|
mgr := NewManager(t.TempDir(), "https://acme.example.com/directory", "", "", nil, nil, "", nil)
|
||||||
|
|
||||||
assert.Equal(t, 0, mgr.PendingCerts(), "initially zero")
|
assert.Equal(t, 0, mgr.PendingCerts(), "initially zero")
|
||||||
assert.Equal(t, 0, mgr.TotalDomains(), "initially zero domains")
|
assert.Equal(t, 0, mgr.TotalDomains(), "initially zero domains")
|
||||||
|
|||||||
@@ -13,13 +13,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Metrics struct {
|
type Metrics struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
requestsTotal metric.Int64Counter
|
requestsTotal metric.Int64Counter
|
||||||
activeRequests metric.Int64UpDownCounter
|
activeRequests metric.Int64UpDownCounter
|
||||||
configuredDomains metric.Int64UpDownCounter
|
configuredDomains metric.Int64UpDownCounter
|
||||||
totalPaths metric.Int64UpDownCounter
|
totalPaths metric.Int64UpDownCounter
|
||||||
requestDuration metric.Int64Histogram
|
requestDuration metric.Int64Histogram
|
||||||
backendDuration metric.Int64Histogram
|
backendDuration metric.Int64Histogram
|
||||||
|
certificateIssueDuration metric.Int64Histogram
|
||||||
|
|
||||||
mappingsMux sync.Mutex
|
mappingsMux sync.Mutex
|
||||||
mappingPaths map[string]int
|
mappingPaths map[string]int
|
||||||
@@ -80,15 +81,25 @@ func New(ctx context.Context, meter metric.Meter) (*Metrics, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
certificateIssueDuration, err := meter.Int64Histogram(
|
||||||
|
"proxy.certificate.issue.duration.ms",
|
||||||
|
metric.WithUnit("milliseconds"),
|
||||||
|
metric.WithDescription("Duration of ACME certificate issuance"),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return &Metrics{
|
return &Metrics{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
requestsTotal: requestsTotal,
|
requestsTotal: requestsTotal,
|
||||||
activeRequests: activeRequests,
|
activeRequests: activeRequests,
|
||||||
configuredDomains: configuredDomains,
|
configuredDomains: configuredDomains,
|
||||||
totalPaths: totalPaths,
|
totalPaths: totalPaths,
|
||||||
requestDuration: requestDuration,
|
requestDuration: requestDuration,
|
||||||
backendDuration: backendDuration,
|
backendDuration: backendDuration,
|
||||||
mappingPaths: make(map[string]int),
|
certificateIssueDuration: certificateIssueDuration,
|
||||||
|
mappingPaths: make(map[string]int),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,3 +190,8 @@ func (m *Metrics) RemoveMapping(mapping proxy.Mapping) {
|
|||||||
|
|
||||||
delete(m.mappingPaths, mapping.Host)
|
delete(m.mappingPaths, mapping.Host)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RecordCertificateIssuance records the duration of a certificate issuance.
|
||||||
|
func (m *Metrics) RecordCertificateIssuance(duration time.Duration) {
|
||||||
|
m.certificateIssueDuration.Record(m.ctx, duration.Milliseconds())
|
||||||
|
}
|
||||||
|
|||||||
+1
-1
@@ -437,7 +437,7 @@ func (s *Server) configureTLS(ctx context.Context) (*tls.Config, error) {
|
|||||||
"acme_server": s.ACMEDirectory,
|
"acme_server": s.ACMEDirectory,
|
||||||
"challenge_type": s.ACMEChallengeType,
|
"challenge_type": s.ACMEChallengeType,
|
||||||
}).Debug("ACME certificates enabled, configuring certificate manager")
|
}).Debug("ACME certificates enabled, configuring certificate manager")
|
||||||
s.acme = acme.NewManager(s.CertificateDirectory, s.ACMEDirectory, s.ACMEEABKID, s.ACMEEABHMACKey, s, s.Logger, s.CertLockMethod)
|
s.acme = acme.NewManager(s.CertificateDirectory, s.ACMEDirectory, s.ACMEEABKID, s.ACMEEABHMACKey, s, s.Logger, s.CertLockMethod, s.meter)
|
||||||
|
|
||||||
if s.ACMEChallengeType == "http-01" {
|
if s.ACMEChallengeType == "http-01" {
|
||||||
s.http = &http.Server{
|
s.http = &http.Server{
|
||||||
|
|||||||
Reference in New Issue
Block a user