/
server.go
90 lines (75 loc) · 3.03 KB
/
server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/*
Copyright 2020 The Kubermatic Kubernetes Platform contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package server
import (
"errors"
"fmt"
"net/http"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"sigs.k8s.io/controller-runtime/pkg/manager"
ctrlruntimemetrics "sigs.k8s.io/controller-runtime/pkg/metrics"
)
// We have to unregister the ProcessCollector and GoCollector
// from the ctrltuntimemetrics Registry, otherwise Collecting errors
// out because they are both there and in the default prometheus registry.
// This is not extremely nice but as pretty as "collect metrics from the
// two registries" will ever got, unless the ctrltuntimemetrics.Registry
// becomes configurable
func init() {
ctrlruntimemetrics.Registry.Unregister(
prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{}))
ctrlruntimemetrics.Registry.Unregister(prometheus.NewGoCollector())
}
// New returns a brand new *MetricsServer that gathers the metrics
// from both the prometheus default registry and the ctrlruntimemetrics registry
func New(listenAddress string) *MetricsServer {
return &MetricsServer{
gatherers: []prometheus.Gatherer{prometheus.DefaultGatherer, ctrlruntimemetrics.Registry},
listenAddress: listenAddress,
}
}
// MetricsServer is our own metrics server implementation that gathers the metrics from
// both the default prometheus registry and the ctrltuntimemetrics registry.
// The background is that the latter is not configurable at all and we don't
// want to force developers into using it, because that is counterintuitive
// and prone to be forgotten
type MetricsServer struct {
gatherers prometheus.Gatherers
listenAddress string
}
// Start implements sigs.k8s.io/controller-runtime/pkg/manager.Runnable
func (m *MetricsServer) Start(stop <-chan struct{}) error {
if len(m.gatherers) < 1 {
return errors.New("no gatherers defined")
}
mux := http.NewServeMux()
mux.Handle("/metrics", promhttp.InstrumentMetricHandler(
prometheus.DefaultRegisterer,
promhttp.HandlerFor(m.gatherers, promhttp.HandlerOpts{}),
))
s := http.Server{
Addr: m.listenAddress,
Handler: mux,
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
}
return fmt.Errorf("metrics server stopped: %v", s.ListenAndServe())
}
// MetricsServer implements LeaderElectionRunnable to indicate that it does not require to run
// within an elected leader
var _ manager.LeaderElectionRunnable = &MetricsServer{}
func (m *MetricsServer) NeedLeaderElection() bool {
return false
}