master
go 138 lines 3.16 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package pulsar
4
5 import (
6 "errors"
7 "strings"
8
9 "github.com/netdata/netdata/go/plugins/pkg/prometheus"
10 "github.com/netdata/netdata/go/plugins/pkg/stm"
11 )
12
13 func isValidPulsarMetrics(pms prometheus.Series) bool {
14 return pms.FindByName(metricPulsarTopicsCount).Len() > 0
15 }
16
17 func (c *Collector) resetCurCache() {
18 for ns := range c.curCache.namespaces {
19 delete(c.curCache.namespaces, ns)
20 }
21 for top := range c.curCache.topics {
22 delete(c.curCache.topics, top)
23 }
24 }
25
26 func (c *Collector) collect() (map[string]int64, error) {
27 pms, err := c.prom.ScrapeSeries()
28 if err != nil {
29 return nil, err
30 }
31
32 if !isValidPulsarMetrics(pms) {
33 return nil, errors.New("returned metrics aren't Apache Pulsar metrics")
34 }
35
36 c.once.Do(func() {
37 c.adjustCharts(pms)
38 })
39
40 mx := c.collectMetrics(pms)
41 c.updateCharts()
42 c.resetCurCache()
43
44 return stm.ToMap(mx), nil
45 }
46
47 func (c *Collector) collectMetrics(pms prometheus.Series) map[string]float64 {
48 mx := make(map[string]float64)
49 c.collectBroker(mx, pms)
50 return mx
51 }
52
53 func (c *Collector) collectBroker(mx map[string]float64, pms prometheus.Series) {
54 pms = findPulsarMetrics(pms)
55 for _, pm := range pms {
56 ns, top := newNamespace(pm), newTopic(pm)
57 if ns.name == "" {
58 continue
59 }
60
61 c.curCache.namespaces[ns] = true
62
63 value := pm.Value * precision(pm.Name())
64 mx[pm.Name()] += value
65 mx[pm.Name()+"_"+ns.name] += value
66
67 if top.name == "" || !c.topicFilter.MatchString(top.name) {
68 continue
69 }
70
71 c.curCache.topics[top] = true
72 mx[pm.Name()+"_"+top.name] += value
73 }
74 mx["pulsar_namespaces_count"] = float64(len(c.curCache.namespaces))
75 }
76
77 func newNamespace(pm prometheus.SeriesSample) namespace {
78 return namespace{
79 name: pm.Labels.Get("namespace"),
80 }
81 }
82
83 func newTopic(pm prometheus.SeriesSample) topic {
84 return topic{
85 namespace: pm.Labels.Get("namespace"),
86 name: pm.Labels.Get("topic"),
87 }
88 }
89
90 func findPulsarMetrics(pms prometheus.Series) prometheus.Series {
91 var ms prometheus.Series
92 for _, pm := range pms {
93 if isPulsarHistogram(pm) {
94 ms = append(ms, pm)
95 }
96 }
97 pms = pms.FindByNames(
98 metricPulsarTopicsCount,
99 metricPulsarSubscriptionDelayed,
100 metricPulsarSubscriptionsCount,
101 metricPulsarProducersCount,
102 metricPulsarConsumersCount,
103 metricPulsarRateIn,
104 metricPulsarRateOut,
105 metricPulsarThroughputIn,
106 metricPulsarThroughputOut,
107 metricPulsarStorageSize,
108 metricPulsarStorageWriteRate,
109 metricPulsarStorageReadRate,
110 metricPulsarMsgBacklog,
111 metricPulsarSubscriptionMsgRateRedeliver,
112 metricPulsarSubscriptionBlockedOnUnackedMessages,
113 )
114 return append(ms, pms...)
115 }
116
117 func isPulsarHistogram(pm prometheus.SeriesSample) bool {
118 s := pm.Name()
119 return strings.HasPrefix(s, "pulsar_storage_write_latency") || strings.HasPrefix(s, "pulsar_entry_size")
120 }
121
122 func precision(metric string) float64 {
123 switch metric {
124 case metricPulsarRateIn,
125 metricPulsarRateOut,
126 metricPulsarThroughputIn,
127 metricPulsarThroughputOut,
128 metricPulsarStorageWriteRate,
129 metricPulsarStorageReadRate,
130 metricPulsarSubscriptionMsgRateRedeliver,
131 metricPulsarReplicationRateIn,
132 metricPulsarReplicationRateOut,
133 metricPulsarReplicationThroughputIn,
134 metricPulsarReplicationThroughputOut:
135 return 1000
136 }
137 return 1
138 }