Skip to content

Commit bd25f49

Browse files
committed
Export metrics for assigned and requested capacity, and client count.
I wrote a custom Prometheus collector that exports the server status at collection time. This is necessary because updating the metrics as the values change would be quite expensive.
1 parent abb09e2 commit bd25f49

File tree

4 files changed

+97
-4
lines changed

4 files changed

+97
-4
lines changed

go/cmd/doorman/doorman_server.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,10 @@ func main() {
227227

228228
http.Handle("/metrics", prometheus.Handler())
229229

230+
if err := prometheus.Register(doorman.NewCollector(dm)); err != nil {
231+
log.Exitf("prometheus.Register: %v", err)
232+
}
233+
230234
go http.ListenAndServe(fmt.Sprintf(":%v", *debugPort), nil)
231235

232236
// Waits for the server to get its initial configuration. This guarantees that

go/server/doorman/collector.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package doorman
2+
3+
import (
4+
"sync"
5+
6+
"github.com/prometheus/client_golang/prometheus"
7+
)
8+
9+
type collector struct {
10+
server *Server
11+
mu sync.Mutex
12+
has *prometheus.GaugeVec
13+
wants *prometheus.GaugeVec
14+
count *prometheus.GaugeVec
15+
}
16+
17+
// NewCollector returns a custom Prometheus collector that creates
18+
// metrics for how much capacity has been assigned
19+
// (doorman_server_sum_has), requested (doorman_server_sum_wants), and
20+
// the total number of clients (doorman_server_client_count), with the
21+
// resource id as the label. It has to be registered using
22+
// prometheus.Register.
23+
func NewCollector(server *Server) prometheus.Collector {
24+
labels := []string{"resource"}
25+
return &collector{
26+
server: server,
27+
has: prometheus.NewGaugeVec(prometheus.GaugeOpts{
28+
Namespace: "doorman",
29+
Subsystem: "server",
30+
Name: "sum_has",
31+
Help: "All capacity assigned to clients for a resource.",
32+
}, labels),
33+
wants: prometheus.NewGaugeVec(prometheus.GaugeOpts{
34+
Namespace: "doorman",
35+
Subsystem: "server",
36+
Name: "sum_wants",
37+
Help: "All capacity requested by clients for a resource.",
38+
}, labels),
39+
count: prometheus.NewGaugeVec(prometheus.GaugeOpts{
40+
Namespace: "doorman",
41+
Subsystem: "server",
42+
Name: "client_count",
43+
Help: "Number of clients requesting this resource.",
44+
}, labels),
45+
}
46+
}
47+
48+
func (c *collector) Describe(ch chan<- *prometheus.Desc) {
49+
c.has.Describe(ch)
50+
c.wants.Describe(ch)
51+
c.count.Describe(ch)
52+
}
53+
54+
func (c *collector) Collect(ch chan<- prometheus.Metric) {
55+
status := c.server.Status()
56+
c.mu.Lock()
57+
defer c.mu.Unlock()
58+
59+
for id, res := range status.Resources {
60+
c.has.WithLabelValues(id).Set(res.SumHas)
61+
c.wants.WithLabelValues(id).Set(res.SumWants)
62+
c.count.WithLabelValues(id).Set(float64(res.Count))
63+
}
64+
c.has.Collect(ch)
65+
c.wants.Collect(ch)
66+
c.count.Collect(ch)
67+
68+
c.has.Reset()
69+
c.wants.Reset()
70+
c.count.Reset()
71+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package doorman
2+
3+
import (
4+
"testing"
5+
6+
"github.com/prometheus/client_golang/prometheus"
7+
8+
pb "github.com/youtube/doorman/proto/doorman"
9+
)
10+
11+
func TestCollector(t *testing.T) {
12+
s, err := MakeTestServer(makeResourceTemplate("*", pb.Algorithm_FAIR_SHARE))
13+
if err != nil {
14+
t.Fatal(err)
15+
}
16+
c := NewCollector(s)
17+
prometheus.EnableCollectChecks(true)
18+
if err := prometheus.Register(c); err != nil {
19+
t.Fatal(err)
20+
}
21+
}

go/server/doorman/server.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -524,10 +524,7 @@ func NewIntermediate(ctx context.Context, id string, addr string, leader electio
524524
return server, nil
525525
}
526526

527-
// New returns a new unconfigured server. It will use id and
528-
// masterLock (an etcd path) in a master election. masterDelay is the
529-
// amount of time in which a deposed master can try to reacquire
530-
// mastership.
527+
// New returns a new unconfigured server.
531528
func New(ctx context.Context, id string, leader election.Election, opts ...connection.Option) (*Server, error) {
532529
return NewIntermediate(ctx, id, "", leader, opts...)
533530
}

0 commit comments

Comments
 (0)