Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,55 +37,48 @@ import (
var (
registryErrorsTotal = metrics.NewCounterWithOpts(
prometheus.CounterOpts{
Namespace: "external_dns",
Subsystem: "registry",
Name: "errors_total",
Help: "Number of Registry errors.",
},
)
sourceErrorsTotal = metrics.NewCounterWithOpts(
prometheus.CounterOpts{
Namespace: "external_dns",
Subsystem: "source",
Name: "errors_total",
Help: "Number of Source errors.",
},
)
sourceEndpointsTotal = metrics.NewGaugeWithOpts(
prometheus.GaugeOpts{
Namespace: "external_dns",
Subsystem: "source",
Name: "endpoints_total",
Help: "Number of Endpoints in all sources",
},
)
registryEndpointsTotal = metrics.NewGaugeWithOpts(
prometheus.GaugeOpts{
Namespace: "external_dns",
Subsystem: "registry",
Name: "endpoints_total",
Help: "Number of Endpoints in the registry",
},
)
lastSyncTimestamp = metrics.NewGaugeWithOpts(
prometheus.GaugeOpts{
Namespace: "external_dns",
Subsystem: "controller",
Name: "last_sync_timestamp_seconds",
Help: "Timestamp of last successful sync with the DNS provider",
},
)
lastReconcileTimestamp = metrics.NewGaugeWithOpts(
prometheus.GaugeOpts{
Namespace: "external_dns",
Subsystem: "controller",
Name: "last_reconcile_timestamp_seconds",
Help: "Timestamp of last attempted sync with the DNS provider",
},
)
controllerNoChangesTotal = metrics.NewCounterWithOpts(
prometheus.CounterOpts{
Namespace: "external_dns",
Subsystem: "controller",
Name: "no_op_runs_total",
Help: "Number of reconcile loops ending up with no changes on the DNS provider side.",
Expand All @@ -108,7 +101,6 @@ var (

registryRecords = metrics.NewGaugedVectorOpts(
prometheus.GaugeOpts{
Namespace: "external_dns",
Subsystem: "registry",
Name: "records",
Help: "Number of registry records partitioned by label name (vector).",
Expand All @@ -118,7 +110,6 @@ var (

sourceRecords = metrics.NewGaugedVectorOpts(
prometheus.GaugeOpts{
Namespace: "external_dns",
Subsystem: "source",
Name: "records",
Help: "Number of source records partitioned by label name (vector).",
Expand All @@ -128,7 +119,6 @@ var (

verifiedRecords = metrics.NewGaugedVectorOpts(
prometheus.GaugeOpts{
Namespace: "external_dns",
Subsystem: "controller",
Name: "verified_records",
Help: "Number of DNS records that exists both in source and registry (vector).",
Expand All @@ -138,7 +128,6 @@ var (

consecutiveSoftErrors = metrics.NewGaugeWithOpts(
prometheus.GaugeOpts{
Namespace: "external_dns",
Subsystem: "controller",
Name: "consecutive_soft_errors",
Help: "Number of consecutive soft errors in reconciliation loop.",
Expand Down
1 change: 1 addition & 0 deletions docs/monitoring/metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ curl https://localhost:7979/metrics

| Name | Metric Type | Subsystem | Help |
|:---------------------------------|:------------|:------------|:------------------------------------------------------|
| build_info | Gauge | | A metric with a constant '1' value labeled with 'version' and 'revision' of external_dns and the 'go_version', 'os' and the 'arch' used the build. |
| consecutive_soft_errors | Gauge | controller | Number of consecutive soft errors in reconciliation loop. |
| last_reconcile_timestamp_seconds | Gauge | controller | Timestamp of last attempted sync with the DNS provider |
| last_sync_timestamp_seconds | Gauge | controller | Timestamp of last successful sync with the DNS provider |
Expand Down
2 changes: 1 addition & 1 deletion internal/gen/docs/metrics/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func TestComputeMetrics(t *testing.T) {
t.Errorf("Expected not empty metrics registry, got %d", len(reg.Metrics))
}

assert.Len(t, reg.Metrics, 19)
assert.Len(t, reg.Metrics, 20)
}

func TestGenerateMarkdownTableRenderer(t *testing.T) {
Expand Down
35 changes: 28 additions & 7 deletions pkg/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,44 @@ limitations under the License.
package metrics

import (
"runtime"
"fmt"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/version"
log "github.com/sirupsen/logrus"

cfg "sigs.k8s.io/external-dns/pkg/apis/externaldns"
)

const (
Namespace = "external_dns"
)

var (
RegisterMetric = NewMetricsRegister()
)

func NewMetricsRegister() *MetricRegistry {
reg := prometheus.WrapRegistererWith(
prometheus.Labels{
func init() {
RegisterMetric.MustRegister(NewGaugeFuncMetric(prometheus.GaugeOpts{
Namespace: Namespace,
Name: "build_info",
Help: fmt.Sprintf(
"A metric with a constant '1' value labeled with 'version' and 'revision' of %s and the 'go_version', 'os' and the 'arch' used the build.",
Namespace,
),
ConstLabels: prometheus.Labels{
"version": cfg.Version,
"arch": runtime.GOARCH,
"go_version": runtime.Version(),
"revision": version.GetRevision(),
"go_version": version.GoVersion,
"os": version.GoOS,
"arch": version.GoArch,
},
}))
}

func NewMetricsRegister() *MetricRegistry {
reg := prometheus.WrapRegistererWith(
prometheus.Labels{},
prometheus.DefaultRegisterer)
return &MetricRegistry{
Registerer: reg,
Expand All @@ -54,7 +73,7 @@ func NewMetricsRegister() *MetricRegistry {
// }
func (m *MetricRegistry) MustRegister(cs IMetric) {
switch v := cs.(type) {
case CounterMetric, GaugeMetric, CounterVecMetric, GaugeVecMetric:
case CounterMetric, GaugeMetric, CounterVecMetric, GaugeVecMetric, GaugeFuncMetric:
if _, exists := m.mName[cs.Get().FQDN]; exists {
return
} else {
Expand All @@ -70,6 +89,8 @@ func (m *MetricRegistry) MustRegister(cs IMetric) {
m.Registerer.MustRegister(metric.Gauge)
case CounterVecMetric:
m.Registerer.MustRegister(metric.CounterVec)
case GaugeFuncMetric:
m.Registerer.MustRegister(metric.GaugeFunc)
}
log.Debugf("Register metric: %s", cs.Get().FQDN)
default:
Expand Down
32 changes: 32 additions & 0 deletions pkg/metrics/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ func (g GaugeVecMetric) SetWithLabels(value float64, lvs ...string) {
}

func NewGaugeWithOpts(opts prometheus.GaugeOpts) GaugeMetric {
opts.Namespace = Namespace
return GaugeMetric{
Metric: Metric{
Type: "gauge",
Expand All @@ -104,6 +105,7 @@ func NewGaugeWithOpts(opts prometheus.GaugeOpts) GaugeMetric {
// NewGaugedVectorOpts creates a new GaugeVec based on the provided GaugeOpts and
// partitioned by the given label names.
func NewGaugedVectorOpts(opts prometheus.GaugeOpts, labelNames []string) GaugeVecMetric {
opts.Namespace = Namespace
return GaugeVecMetric{
Metric: Metric{
Type: "gauge",
Expand All @@ -118,6 +120,7 @@ func NewGaugedVectorOpts(opts prometheus.GaugeOpts, labelNames []string) GaugeVe
}

func NewCounterWithOpts(opts prometheus.CounterOpts) CounterMetric {
opts.Namespace = Namespace
return CounterMetric{
Metric: Metric{
Type: "counter",
Expand All @@ -132,6 +135,7 @@ func NewCounterWithOpts(opts prometheus.CounterOpts) CounterMetric {
}

func NewCounterVecWithOpts(opts prometheus.CounterOpts, labelNames []string) CounterVecMetric {
opts.Namespace = Namespace
return CounterVecMetric{
Metric: Metric{
Type: "counter",
Expand All @@ -144,3 +148,31 @@ func NewCounterVecWithOpts(opts prometheus.CounterOpts, labelNames []string) Cou
CounterVec: prometheus.NewCounterVec(opts, labelNames),
}
}

type GaugeFuncMetric struct {
Metric
GaugeFunc prometheus.GaugeFunc
}

func (g GaugeFuncMetric) Get() *Metric {
return &g.Metric
}

func NewGaugeFuncMetric(opts prometheus.GaugeOpts) GaugeFuncMetric {
return GaugeFuncMetric{
Metric: Metric{
Type: "gauge",
Name: opts.Name,
FQDN: func() string {
if opts.Subsystem != "" {
return fmt.Sprintf("%s_%s", opts.Subsystem, opts.Name)
}
return opts.Name
}(),
Namespace: opts.Namespace,
Subsystem: opts.Subsystem,
Help: opts.Help,
},
GaugeFunc: prometheus.NewGaugeFunc(opts, func() float64 { return 1 }),
}
}
29 changes: 22 additions & 7 deletions pkg/metrics/models_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,17 @@ limitations under the License.
package metrics

import (
"reflect"
"testing"

dto "github.com/prometheus/client_model/go"

"github.com/prometheus/client_golang/prometheus"
dto "github.com/prometheus/client_model/go"
"github.com/stretchr/testify/assert"
)

func TestNewGaugeWithOpts(t *testing.T) {
opts := prometheus.GaugeOpts{
Name: "test_gauge",
Namespace: "test_namespace",
Subsystem: "test_subsystem",
Help: "This is a test gauge",
}
Expand All @@ -37,7 +36,7 @@ func TestNewGaugeWithOpts(t *testing.T) {

assert.Equal(t, "gauge", gaugeMetric.Type)
assert.Equal(t, "test_gauge", gaugeMetric.Name)
assert.Equal(t, "test_namespace", gaugeMetric.Namespace)
assert.Equal(t, Namespace, gaugeMetric.Namespace)
assert.Equal(t, "test_subsystem", gaugeMetric.Subsystem)
assert.Equal(t, "This is a test gauge", gaugeMetric.Help)
assert.Equal(t, "test_subsystem_test_gauge", gaugeMetric.FQDN)
Expand All @@ -47,7 +46,6 @@ func TestNewGaugeWithOpts(t *testing.T) {
func TestNewCounterWithOpts(t *testing.T) {
opts := prometheus.CounterOpts{
Name: "test_counter",
Namespace: "test_namespace",
Subsystem: "test_subsystem",
Help: "This is a test counter",
}
Expand All @@ -56,7 +54,7 @@ func TestNewCounterWithOpts(t *testing.T) {

assert.Equal(t, "counter", counterMetric.Type)
assert.Equal(t, "test_counter", counterMetric.Name)
assert.Equal(t, "test_namespace", counterMetric.Namespace)
assert.Equal(t, Namespace, counterMetric.Namespace)
assert.Equal(t, "test_subsystem", counterMetric.Subsystem)
assert.Equal(t, "This is a test counter", counterMetric.Help)
assert.Equal(t, "test_subsystem_test_counter", counterMetric.FQDN)
Expand All @@ -77,7 +75,7 @@ func TestNewCounterVecWithOpts(t *testing.T) {

assert.Equal(t, "counter", counterVecMetric.Type)
assert.Equal(t, "test_counter_vec", counterVecMetric.Name)
assert.Equal(t, "test_namespace", counterVecMetric.Namespace)
assert.Equal(t, Namespace, counterVecMetric.Namespace)
assert.Equal(t, "test_subsystem", counterVecMetric.Subsystem)
assert.Equal(t, "This is a test counter vector", counterVecMetric.Help)
assert.Equal(t, "test_subsystem_test_counter_vec", counterVecMetric.FQDN)
Expand Down Expand Up @@ -113,3 +111,20 @@ func TestGaugeV_SetWithLabels(t *testing.T) {

assert.Len(t, m.Label, 2)
}

func TestNewBuildInfoCollector(t *testing.T) {
metric := NewGaugeFuncMetric(prometheus.GaugeOpts{
Namespace: Namespace,
Name: "build_info",
ConstLabels: prometheus.Labels{
"version": "0.0.1",
"goversion": "1.24",
"arch": "arm64",
},
})

desc := metric.GaugeFunc.Desc()

assert.Equal(t, "external_dns_build_info", reflect.ValueOf(desc).Elem().FieldByName("fqName").String())
assert.Contains(t, desc.String(), "version=\"0.0.1\"")
}
2 changes: 0 additions & 2 deletions provider/cached_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import (
var (
cachedRecordsCallsTotal = metrics.NewCounterVecWithOpts(
prometheus.CounterOpts{
Namespace: "external_dns",
Subsystem: "provider",
Name: "cache_records_calls",
Help: "Number of calls to the provider cache Records list.",
Expand All @@ -42,7 +41,6 @@ var (
)
cachedApplyChangesCallsTotal = metrics.NewCounterWithOpts(
prometheus.CounterOpts{
Namespace: "external_dns",
Subsystem: "provider",
Name: "cache_apply_changes_calls",
Help: "Number of calls to the provider cache ApplyChanges.",
Expand Down
6 changes: 0 additions & 6 deletions provider/webhook/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,47 +43,41 @@ const (
var (
recordsErrorsGauge = metrics.NewGaugeWithOpts(
prometheus.GaugeOpts{
Namespace: "external_dns",
Subsystem: "webhook_provider",
Name: "records_errors_total",
Help: "Errors with Records method",
},
)
recordsRequestsGauge = metrics.NewGaugeWithOpts(
prometheus.GaugeOpts{
Namespace: "external_dns",
Subsystem: "webhook_provider",
Name: "records_requests_total",
Help: "Requests with Records method",
},
)
applyChangesErrorsGauge = metrics.NewGaugeWithOpts(
prometheus.GaugeOpts{
Namespace: "external_dns",
Subsystem: "webhook_provider",
Name: "applychanges_errors_total",
Help: "Errors with ApplyChanges method",
},
)
applyChangesRequestsGauge = metrics.NewGaugeWithOpts(
prometheus.GaugeOpts{
Namespace: "external_dns",
Subsystem: "webhook_provider",
Name: "applychanges_requests_total",
Help: "Requests with ApplyChanges method",
},
)
adjustEndpointsErrorsGauge = metrics.NewGaugeWithOpts(
prometheus.GaugeOpts{
Namespace: "external_dns",
Subsystem: "webhook_provider",
Name: "adjustendpoints_errors_total",
Help: "Errors with AdjustEndpoints method",
},
)
adjustEndpointsRequestsGauge = metrics.NewGaugeWithOpts(
prometheus.GaugeOpts{
Namespace: "external_dns",
Subsystem: "webhook_provider",
Name: "adjustendpoints_requests_total",
Help: "Requests with AdjustEndpoints method",
Expand Down
Loading