/
metrics.go
71 lines (55 loc) · 1.39 KB
/
metrics.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
package metrics
import (
"context"
"sync"
"github.com/miekg/dns"
"github.com/prometheus/client_golang/prometheus"
"github.com/semihalev/sdns/config"
"github.com/semihalev/sdns/middleware"
)
// Metrics type
type Metrics struct {
queries *prometheus.CounterVec
}
// New return new metrics
func New(cfg *config.Config) *Metrics {
m := &Metrics{
queries: prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "dns_queries_total",
Help: "How many DNS queries processed",
},
[]string{"qtype", "rcode"},
),
}
_ = prometheus.Register(m.queries)
return m
}
// Name return middleware name
func (m *Metrics) Name() string { return name }
// ServeDNS implements the Handle interface.
func (m *Metrics) ServeDNS(ctx context.Context, ch *middleware.Chain) {
ch.Next(ctx)
if !ch.Writer.Written() {
return
}
labels := AcquireLabels()
defer ReleaseLabels(labels)
labels["qtype"] = dns.TypeToString[ch.Request.Question[0].Qtype]
labels["rcode"] = dns.RcodeToString[ch.Writer.Rcode()]
m.queries.With(labels).Inc()
}
var labelsPool sync.Pool
// AcquireLabels returns a label from pool
func AcquireLabels() prometheus.Labels {
x := labelsPool.Get()
if x == nil {
return prometheus.Labels{"qtype": "", "rcode": ""}
}
return x.(prometheus.Labels)
}
// ReleaseLabels returns labels to pool
func ReleaseLabels(labels prometheus.Labels) {
labelsPool.Put(labels)
}
const name = "metrics"