Skip to content

Commit 3a082b2

Browse files
authored
[Feature] Allow to exclude metrics (#1194)
1 parent 2ffd238 commit 3a082b2

File tree

9 files changed

+344
-41
lines changed

9 files changed

+344
-41
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
- (Bugfix) Fix ErrorArray String function
3636
- (Feature) Switch services to Port names
3737
- (Feature) Configurable ArangoD Port
38+
- (Feature) Allow to exclude metrics
3839

3940
## [1.2.20](https://github.com/arangodb/kube-arangodb/tree/1.2.20) (2022-10-25)
4041
- (Feature) Add action progress

cmd/cmd.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import (
5353
"github.com/arangodb/kube-arangodb/pkg/deployment/features"
5454
"github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/scheme"
5555
"github.com/arangodb/kube-arangodb/pkg/logging"
56+
"github.com/arangodb/kube-arangodb/pkg/metrics/collector"
5657
"github.com/arangodb/kube-arangodb/pkg/operator"
5758
"github.com/arangodb/kube-arangodb/pkg/operator/scope"
5859
"github.com/arangodb/kube-arangodb/pkg/server"
@@ -63,6 +64,7 @@ import (
6364
operatorHTTP "github.com/arangodb/kube-arangodb/pkg/util/http"
6465
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
6566
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
67+
"github.com/arangodb/kube-arangodb/pkg/util/metrics"
6668
"github.com/arangodb/kube-arangodb/pkg/util/probe"
6769
"github.com/arangodb/kube-arangodb/pkg/util/retry"
6870
"github.com/arangodb/kube-arangodb/pkg/version"
@@ -161,6 +163,9 @@ var (
161163
chaosOptions struct {
162164
allowed bool
163165
}
166+
metricsOptions struct {
167+
excludedMetricPrefixes []string
168+
}
164169
livenessProbe probe.LivenessProbe
165170
deploymentProbe probe.ReadyProbe
166171
deploymentReplicationProbe probe.ReadyProbe
@@ -214,6 +219,7 @@ func init() {
214219
f.BoolVar(&crdOptions.install, "crd.install", true, "Install missing CRD if access is possible")
215220
f.IntVar(&operatorBackup.concurrentUploads, "backup-concurrent-uploads", globals.DefaultBackupConcurrentUploads, "Number of concurrent uploads per deployment")
216221
f.Uint64Var(&memoryLimit.hardLimit, "memory-limit", 0, "Define memory limit for hard shutdown and the dump of goroutines. Used for testing")
222+
f.StringArrayVar(&metricsOptions.excludedMetricPrefixes, "metrics.excluded-prefixes", nil, "List of the excluded metrics prefixes")
217223
if err := features.Init(&cmdMain); err != nil {
218224
panic(err.Error())
219225
}
@@ -253,6 +259,8 @@ func executeMain(cmd *cobra.Command, args []string) {
253259
globals.GetGlobals().Kubernetes().RequestBatchSize().Set(operatorKubernetesOptions.maxBatchSize)
254260
globals.GetGlobals().Backup().ConcurrentUploads().Set(operatorBackup.concurrentUploads)
255261

262+
collector.GetCollector().SetFilter(metrics.NegateMetricPushFilter(metrics.NewPrefixMetricPushFilter(metricsOptions.excludedMetricPrefixes...)))
263+
256264
kclient.SetDefaultQPS(operatorKubernetesOptions.qps)
257265
kclient.SetDefaultBurst(operatorKubernetesOptions.burst)
258266

pkg/deployment/old_metrics.go

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,10 @@ package deployment
2323
import (
2424
"sync"
2525

26-
"github.com/prometheus/client_golang/prometheus"
27-
2826
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
2927
"github.com/arangodb/kube-arangodb/pkg/deployment/features"
3028
"github.com/arangodb/kube-arangodb/pkg/generated/metric_descriptions"
29+
"github.com/arangodb/kube-arangodb/pkg/metrics/collector"
3130
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/definitions"
3231
"github.com/arangodb/kube-arangodb/pkg/util/metrics"
3332
)
@@ -49,13 +48,12 @@ func init() {
4948
operatorStateRefreshMetric: metrics.NewDescription("arango_operator_deployment_state_refresh_count", "Number of refreshes in deployment", []string{"namespace", "deployment", "type"}, nil),
5049
}
5150

52-
prometheus.MustRegister(&localInventory)
51+
collector.GetCollector().RegisterMetric(&localInventory)
52+
collector.GetCollector().RegisterDescription(&localInventory)
5353
}
5454

5555
var localInventory inventory
5656

57-
var _ prometheus.Collector = &inventory{}
58-
5957
type inventory struct {
6058
lock sync.Mutex
6159
deployments map[string]map[string]*Deployment
@@ -65,50 +63,42 @@ type inventory struct {
6563
operatorStateRefreshMetric metrics.Description
6664
}
6765

68-
func (i *inventory) Describe(descs chan<- *prometheus.Desc) {
69-
i.lock.Lock()
70-
defer i.lock.Unlock()
71-
72-
pd := metrics.NewPushDescription(descs)
73-
pd.Push(i.deploymentsMetric, i.deploymentMetricsMembersMetric, i.deploymentAgencyStateMetric, i.deploymentShardLeadersMetric, i.deploymentShardsMetric, i.operatorStateRefreshMetric)
66+
func (i *inventory) CollectDescriptions(in metrics.PushDescription) {
67+
in.Push(i.deploymentsMetric, i.deploymentMetricsMembersMetric, i.deploymentAgencyStateMetric, i.deploymentShardLeadersMetric, i.deploymentShardsMetric, i.operatorStateRefreshMetric)
7468

75-
metric_descriptions.Descriptions(pd)
69+
metric_descriptions.Descriptions(in)
7670
}
7771

78-
func (i *inventory) Collect(m chan<- prometheus.Metric) {
79-
i.lock.Lock()
80-
defer i.lock.Unlock()
81-
82-
p := metrics.NewPushMetric(m)
72+
func (i *inventory) CollectMetrics(in metrics.PushMetric) {
8373
for _, deployments := range i.deployments {
8474
for _, deployment := range deployments {
85-
p.Push(i.deploymentsMetric.Gauge(1, deployment.GetNamespace(), deployment.GetName()))
75+
in.Push(i.deploymentsMetric.Gauge(1, deployment.GetNamespace(), deployment.GetName()))
8676

87-
deployment.CollectMetrics(p)
77+
deployment.CollectMetrics(in)
8878

8979
if state := deployment.acs.CurrentClusterCache(); state != nil {
9080
t := state.GetThrottles()
9181

9282
for _, c := range definitions.AllComponents() {
93-
p.Push(i.operatorStateRefreshMetric.Gauge(float64(t.Get(c).Count()), deployment.GetNamespace(), deployment.GetName(), string(c)))
83+
in.Push(i.operatorStateRefreshMetric.Gauge(float64(t.Get(c).Count()), deployment.GetNamespace(), deployment.GetName(), string(c)))
9484
}
9585
}
9686

9787
spec := deployment.GetSpec()
9888
status := deployment.GetStatus()
9989

10090
for _, member := range status.Members.AsList() {
101-
p.Push(i.deploymentMetricsMembersMetric.Gauge(1, deployment.GetNamespace(), deployment.GetName(), member.Group.AsRole(), member.Member.ID))
91+
in.Push(i.deploymentMetricsMembersMetric.Gauge(1, deployment.GetNamespace(), deployment.GetName(), member.Group.AsRole(), member.Member.ID))
10292
}
10393

10494
if spec.Mode.Get().HasAgents() {
10595
agency, agencyOk := deployment.GetAgencyCache()
10696
if !agencyOk {
107-
p.Push(i.deploymentAgencyStateMetric.Gauge(0, deployment.GetNamespace(), deployment.GetName()))
97+
in.Push(i.deploymentAgencyStateMetric.Gauge(0, deployment.GetNamespace(), deployment.GetName()))
10898
continue
10999
}
110100

111-
p.Push(i.deploymentAgencyStateMetric.Gauge(1, deployment.GetNamespace(), deployment.GetName()))
101+
in.Push(i.deploymentAgencyStateMetric.Gauge(1, deployment.GetNamespace(), deployment.GetName()))
112102

113103
if spec.Mode.Get() == api.DeploymentModeCluster {
114104
for db, collections := range agency.Current.Collections {
@@ -145,9 +135,9 @@ func (i *inventory) Collect(m chan<- prometheus.Metric) {
145135
}
146136

147137
if id == 0 {
148-
p.Push(i.deploymentShardLeadersMetric.Gauge(1, m...))
138+
in.Push(i.deploymentShardLeadersMetric.Gauge(1, m...))
149139
}
150-
p.Push(i.deploymentShardsMetric.Gauge(1, m...))
140+
in.Push(i.deploymentShardsMetric.Gauge(1, m...))
151141
}
152142
}
153143
}

pkg/metrics/collector/collector.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package collector
22+
23+
import (
24+
"sync"
25+
26+
"github.com/prometheus/client_golang/prometheus"
27+
28+
"github.com/arangodb/kube-arangodb/pkg/util/metrics"
29+
)
30+
31+
type Collector interface {
32+
RegisterMetric(m metrics.MCollector)
33+
RegisterDescription(m metrics.DCollector)
34+
35+
SetFilter(filter metrics.MetricPushFilter)
36+
}
37+
38+
func init() {
39+
prometheus.MustRegister(collectorObject)
40+
}
41+
42+
func GetCollector() Collector {
43+
return collectorObject
44+
}
45+
46+
var collectorObject = &collector{}
47+
48+
type collector struct {
49+
lock sync.Mutex
50+
51+
filter metrics.MetricPushFilter
52+
53+
metrics []metrics.MCollector
54+
descriptions []metrics.DCollector
55+
}
56+
57+
func (p *collector) SetFilter(filter metrics.MetricPushFilter) {
58+
p.lock.Lock()
59+
defer p.lock.Unlock()
60+
61+
p.filter = filter
62+
}
63+
64+
func (p *collector) RegisterDescription(m metrics.DCollector) {
65+
p.lock.Lock()
66+
defer p.lock.Unlock()
67+
68+
p.descriptions = append(p.descriptions, m)
69+
}
70+
71+
func (p *collector) RegisterMetric(m metrics.MCollector) {
72+
p.lock.Lock()
73+
defer p.lock.Unlock()
74+
75+
p.metrics = append(p.metrics, m)
76+
}
77+
78+
func (p *collector) Describe(descs chan<- *prometheus.Desc) {
79+
p.lock.Lock()
80+
defer p.lock.Unlock()
81+
82+
out := metrics.NewPushDescription(descs)
83+
84+
for id := range p.descriptions {
85+
p.descriptions[id].CollectDescriptions(out)
86+
}
87+
}
88+
89+
func (p *collector) Collect(c chan<- prometheus.Metric) {
90+
p.lock.Lock()
91+
defer p.lock.Unlock()
92+
93+
out := metrics.NewPushMetric(c)
94+
95+
if f := p.filter; f != nil {
96+
out = metrics.NewMetricsPushFilter(out, f)
97+
}
98+
99+
for id := range p.metrics {
100+
p.metrics[id].CollectMetrics(out)
101+
}
102+
}

pkg/util/errors/panics/metric.go

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,14 @@ package panics
2323
import (
2424
"sync"
2525

26-
"github.com/prometheus/client_golang/prometheus"
27-
2826
"github.com/arangodb/kube-arangodb/pkg/generated/metric_descriptions"
2927
"github.com/arangodb/kube-arangodb/pkg/logging"
28+
"github.com/arangodb/kube-arangodb/pkg/metrics/collector"
3029
"github.com/arangodb/kube-arangodb/pkg/util/metrics"
3130
)
3231

3332
func init() {
34-
prometheus.MustRegister(panicsReceived)
33+
collector.GetCollector().RegisterMetric(panicsReceived)
3534
}
3635

3736
var (
@@ -45,18 +44,9 @@ type panicsReceiver struct {
4544
lock sync.Mutex
4645
}
4746

48-
func (p *panicsReceiver) Describe(descs chan<- *prometheus.Desc) {
49-
50-
}
51-
52-
func (p *panicsReceiver) Collect(c chan<- prometheus.Metric) {
53-
p.lock.Lock()
54-
defer p.lock.Unlock()
55-
56-
out := metrics.NewPushMetric(c)
57-
47+
func (p *panicsReceiver) CollectMetrics(in metrics.PushMetric) {
5848
for k, v := range p.panics {
59-
out.Push(metric_descriptions.ArangodbOperatorEnginePanicsRecoveredCounter(float64(v), k))
49+
in.Push(metric_descriptions.ArangodbOperatorEnginePanicsRecoveredCounter(float64(v), k))
6050
}
6151
}
6252

pkg/util/metrics/collector.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,15 @@
2020

2121
package metrics
2222

23-
import "github.com/prometheus/client_golang/prometheus"
23+
type MCollector interface {
24+
CollectMetrics(in PushMetric)
25+
}
26+
27+
type DCollector interface {
28+
CollectDescriptions(in PushDescription)
29+
}
2430

2531
type Collector interface {
26-
Collect(description Description, metrics chan<- prometheus.Metric)
32+
MCollector
33+
DCollector
2734
}

pkg/util/metrics/push_filter.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package metrics
22+
23+
type MetricPushFilter func(m Metric) bool
24+
25+
func NegateMetricPushFilter(in MetricPushFilter) MetricPushFilter {
26+
return func(m Metric) bool {
27+
return !in(m)
28+
}
29+
}
30+
31+
func MergeMetricPushFilter(filters ...MetricPushFilter) MetricPushFilter {
32+
return func(m Metric) bool {
33+
for _, f := range filters {
34+
if f == nil {
35+
continue
36+
}
37+
if !f(m) {
38+
return false
39+
}
40+
}
41+
42+
return true
43+
}
44+
}
45+
46+
type metricPushFilter struct {
47+
filter MetricPushFilter
48+
49+
out PushMetric
50+
}
51+
52+
func (m metricPushFilter) Push(desc ...Metric) PushMetric {
53+
for id := range desc {
54+
if m.filter(desc[id]) {
55+
m.out.Push(desc[id])
56+
continue
57+
}
58+
}
59+
60+
return m
61+
}
62+
63+
func NewMetricsPushFilter(out PushMetric, filter MetricPushFilter) PushMetric {
64+
return &metricPushFilter{
65+
filter: filter,
66+
out: out,
67+
}
68+
}

0 commit comments

Comments
 (0)