Skip to content

Commit 872a4b2

Browse files
committed
fix prometheus
1 parent a4ff397 commit 872a4b2

File tree

3 files changed

+149
-41
lines changed

3 files changed

+149
-41
lines changed

config.go

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,46 @@ var (
5555
OutputPrometheusMetrics{
5656
Name: "dtap_query_qtype_total",
5757
Help: "Total number of queries with a given query type.",
58-
Labels: []string{"qtype"},
58+
Labels: []string{"Qtype"},
5959
},
6060
OutputPrometheusMetrics{
61-
Name: "dtap_query_protocol_total",
62-
Help: "Total number of queries with a given query rotocol.",
63-
Labels: []string{"socket_protocol"},
61+
Name: "dtap_query_rcode_total",
62+
Help: "Total number of queries with a given query type.",
63+
Labels: []string{"Rcode"},
64+
},
65+
OutputPrometheusMetrics{
66+
Name: "dtap_query_tc_bit_total",
67+
Help: "Total number of queries with a given query tc bit.",
68+
Labels: []string{"TC"},
69+
},
70+
OutputPrometheusMetrics{
71+
Name: "dtap_query_ad_bit_total",
72+
Help: "Total number of queries with a given query ad bit.",
73+
Labels: []string{"AD"},
74+
},
75+
OutputPrometheusMetrics{
76+
Name: "dtap_query_socket_protocol_total",
77+
Help: "Total number of queries with a given query transport rotocol.",
78+
Labels: []string{"SocketProtocol"},
79+
},
80+
OutputPrometheusMetrics{
81+
Name: "dtap_query_socket_family_total",
82+
Help: "Total number of queries with a given query IP Protocol.",
83+
Labels: []string{"SocketFamily"},
6484
},
6585
OutputPrometheusMetrics{
66-
Name: "dtap_query_tld_total",
67-
Help: "Total number of queries with a given query tld.",
68-
Labels: []string{"tld"},
69-
Limit: 100,
86+
Name: "dtap_query_tld_total",
87+
Help: "Total number of queries with a given query tld.",
88+
Labels: []string{"TopLevelDomainName"},
89+
ExpireInterval: 5,
90+
ExpireSec: 60,
91+
},
92+
OutputPrometheusMetrics{
93+
Name: "dtap_query_sld_total",
94+
Help: "Total number of queries with a given query tld.",
95+
Labels: []string{"TopLevelDomainName"},
96+
ExpireInterval: 5,
97+
ExpireSec: 60,
7098
},
7199
}
72100
)
@@ -466,7 +494,6 @@ func (o *OutputNatsConfig) GetToken() string {
466494

467495
type OutputPrometheus struct {
468496
Counters []OutputPrometheusMetrics
469-
Interval int
470497
Flat OutputCommonConfig
471498
Buffer OutputBufferConfig
472499
}
@@ -478,19 +505,17 @@ func (o *OutputPrometheus) GetCounters() []OutputPrometheusMetrics {
478505
return o.Counters
479506
}
480507

481-
func (o *OutputPrometheus) GetInternal() int {
482-
return o.Interval
483-
}
484-
485508
func (o *OutputPrometheus) Validate() *ValidationError {
486509
return nil
487510
}
488511

489512
type OutputPrometheusMetrics struct {
490-
Name string
491-
Help string
492-
Labels []string
493-
Limit int
513+
Name string
514+
Help string
515+
Labels []string
516+
Limit int
517+
ExpireInterval int
518+
ExpireSec int
494519
}
495520

496521
func (o *OutputPrometheusMetrics) GetName() string {
@@ -509,6 +534,14 @@ func (o *OutputPrometheusMetrics) GetLimit() int {
509534
return o.Limit
510535
}
511536

537+
func (o *OutputPrometheusMetrics) GetExpireInterval() int {
538+
return o.ExpireInterval
539+
}
540+
541+
func (o *OutputPrometheusMetrics) GetExpireSec() int {
542+
return o.ExpireSec
543+
}
544+
512545
type OutputBufferConfig struct {
513546
BufferSize uint
514547
}

dnstap_prometheus_output.go

Lines changed: 96 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@
1717
package dtap
1818

1919
import (
20+
"context"
21+
"strings"
22+
"time"
23+
24+
log "github.com/sirupsen/logrus"
25+
2026
"fmt"
2127
"reflect"
2228
"strconv"
@@ -33,21 +39,71 @@ type DnstapPrometheusOutput struct {
3339
}
3440

3541
type DnstapPrometheusOutputMetrics struct {
36-
Vec *prometheus.CounterVec
37-
Labels []string
42+
Name string
43+
Vec *prometheus.CounterVec
44+
LabelKeys []string
45+
LabelValues map[string]*DnstapPrometheusOutputMetricsValues
46+
Interval int
47+
Expire int
48+
CancelFunc context.CancelFunc
49+
}
50+
51+
func (d *DnstapPrometheusOutputMetrics) GetInterval() int {
52+
if d.Interval <= 0 {
53+
return 0
54+
}
55+
return d.Interval
56+
}
57+
58+
func (d *DnstapPrometheusOutputMetrics) GetExpire() int {
59+
if d.Expire <= 0 {
60+
return 0
61+
}
62+
return d.Expire
63+
}
64+
65+
type DnstapPrometheusOutputMetricsValues struct {
66+
Values []string
67+
LastUpdate time.Time
68+
}
69+
70+
func NewDnstapPrometheusOutputMetrics(counterConfig OutputPrometheusMetrics) *DnstapPrometheusOutputMetrics {
71+
return &DnstapPrometheusOutputMetrics{
72+
Name: counterConfig.GetName(),
73+
Vec: promauto.NewCounterVec(prometheus.CounterOpts{
74+
Name: counterConfig.GetName(),
75+
Help: counterConfig.GetHelp(),
76+
}, counterConfig.GetLabels()),
77+
LabelKeys: counterConfig.GetLabels(),
78+
LabelValues: map[string]*DnstapPrometheusOutputMetricsValues{},
79+
Expire: counterConfig.GetExpireSec(),
80+
Interval: counterConfig.GetExpireInterval(),
81+
}
3882
}
3983

40-
func NewDtapCounterVec(opts prometheus.CounterOpts) *prometheus.CounterVec {
41-
s := DnstapFlatT{}
42-
t := reflect.TypeOf(s)
43-
var labels []string
84+
func (d *DnstapPrometheusOutputMetrics) Inc(values []string) {
85+
d.Vec.WithLabelValues(values...).Inc()
86+
d.LabelValues[strings.Join(values, ",")] = &DnstapPrometheusOutputMetricsValues{
87+
Values: values,
88+
LastUpdate: time.Now(),
89+
}
90+
}
4491

45-
for i := 0; i < t.NumField(); i++ {
46-
field := t.Field(i)
47-
j := field.Tag.Get("json")
48-
labels = append(labels, j)
92+
func (d *DnstapPrometheusOutputMetrics) Flush(ctx context.Context) {
93+
ticker := time.NewTicker(time.Second * time.Duration(d.Interval))
94+
for {
95+
select {
96+
case <-ctx.Done():
97+
return
98+
case <-ticker.C:
99+
for k, value := range d.LabelValues {
100+
if time.Now().Sub(value.LastUpdate) > time.Second*time.Duration(d.Expire) {
101+
d.Vec.DeleteLabelValues(value.Values...)
102+
delete(d.LabelValues, k)
103+
}
104+
}
105+
}
49106
}
50-
return promauto.NewCounterVec(opts, labels)
51107
}
52108

53109
func NewDnstapPrometheusOutput(config *OutputPrometheus, params *DnstapOutputParams) *DnstapOutput {
@@ -56,20 +112,20 @@ func NewDnstapPrometheusOutput(config *OutputPrometheus, params *DnstapOutputPar
56112
Metrics: []*DnstapPrometheusOutputMetrics{},
57113
}
58114
for _, counterConfig := range config.GetCounters() {
59-
counter := &DnstapPrometheusOutputMetrics{
60-
Vec: NewDtapCounterVec(prometheus.CounterOpts{
61-
Name: counterConfig.GetName(),
62-
Help: counterConfig.GetHelp(),
63-
}),
64-
Labels: counterConfig.GetLabels(),
65-
}
66-
p.Metrics = append(p.Metrics, counter)
115+
p.Metrics = append(p.Metrics, NewDnstapPrometheusOutputMetrics(counterConfig))
67116
}
68117
params.Handler = p
69118
return NewDnstapOutput(params)
70119
}
71120

72121
func (o *DnstapPrometheusOutput) open() error {
122+
for _, metrics := range o.Metrics {
123+
if metrics.GetInterval() > 0 && metrics.GetExpire() > 0 {
124+
ctx, cancelFunc := context.WithCancel(context.Background())
125+
metrics.CancelFunc = cancelFunc
126+
go metrics.Flush(ctx)
127+
}
128+
}
73129
return nil
74130
}
75131

@@ -85,31 +141,47 @@ func (o *DnstapPrometheusOutput) write(frame []byte) error {
85141
e := reflect.ValueOf(data).Elem()
86142
m := make(map[string]string)
87143
for i := 0; i < e.NumField(); i++ {
88-
field := e.Type().Field(i).Tag.Get("json")
144+
field := e.Type().Field(i).Name
89145
value := e.Field(i).Interface()
146+
if value == nil {
147+
continue
148+
}
90149
switch v := value.(type) {
91150
case string:
92151
m[field] = v
93152
case uint32:
94153
m[field] = strconv.Itoa(int(v))
95154
case uint16:
96155
m[field] = strconv.Itoa(int(v))
156+
case bool:
157+
if v {
158+
m[field] = "1"
159+
} else {
160+
m[field] = "0"
161+
}
97162
case fmt.Stringer:
98163
m[field] = v.String()
99164
}
100165
}
101166

102167
for _, counter := range o.Metrics {
103-
labels := map[string]string{}
104-
for _, l := range counter.Labels {
168+
labelValues := make([]string, 0, len(counter.LabelKeys))
169+
for _, l := range counter.LabelKeys {
105170
if v, ok := m[l]; ok {
106-
labels[l] = v
171+
labelValues = append(labelValues, v)
172+
} else {
173+
log.Warnf("can't get metrics: %v, %v", l, counter.Name)
107174
}
108175
}
109-
counter.Vec.With(labels).Inc()
176+
counter.Inc(labelValues)
110177
}
111178
return nil
112179
}
113180

114181
func (o *DnstapPrometheusOutput) close() {
182+
for _, metrics := range o.Metrics {
183+
if metrics.CancelFunc != nil {
184+
metrics.CancelFunc()
185+
}
186+
}
115187
}

net.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ type Net struct {
2929
}
3030

3131
func (n *Net) String() string {
32+
if n == nil || n.IP == nil {
33+
return "<nil>"
34+
}
3235
return n.IP.String() + "/" + strconv.Itoa(n.PrefixLength)
3336
}
3437

0 commit comments

Comments
 (0)