Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get rid of deprecated Counter.Set() function #5

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 19 additions & 19 deletions metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ type gaugeDefinition struct {
key string
}

// Used to programmatically create prometheus.CounterVec metrics
type counterVecDefinition struct {
// Used to programmatically create prometheus.Counter metrics
type counterDefinition struct {
id int
name string
desc string
Expand Down Expand Up @@ -64,22 +64,22 @@ var (
gaugeDefinition{3, "cache_size", "Number of entries in the cache.", "cache-entries"},
}

recursorCounterVecDefs = []counterVecDefinition{
counterVecDefinition{
recursorCounterDefs = []counterDefinition{
counterDefinition{
1, "incoming_queries_total", "Total number of incoming queries by network.", "net",
map[string]string{"questions": "udp", "tcp-questions": "tcp"},
},
counterVecDefinition{
counterDefinition{
2, "outgoing_queries_total", "Total number of outgoing queries by network.", "net",
map[string]string{"all-outqueries": "udp", "tcp-outqueries": "tcp"},
},
counterVecDefinition{
counterDefinition{
3, "cache_lookups_total", "Total number of cache lookups by result.", "result",
map[string]string{"cache-hits": "hit", "cache-misses": "miss"},
},
counterVecDefinition{4, "answers_rcodes_total", "Total number of answers by response code.", "rcode", rCodeLabelMap},
counterVecDefinition{5, "answers_rtime_total", "Total number of answers grouped by response time slots.", "timeslot", rTimeLabelMap},
counterVecDefinition{6, "exceptions_total", "Total number of exceptions by error.", "error", exceptionsLabelMap},
counterDefinition{4, "answers_rcodes_total", "Total number of answers by response code.", "rcode", rCodeLabelMap},
counterDefinition{5, "answers_rtime_total", "Total number of answers grouped by response time slots.", "timeslot", rTimeLabelMap},
counterDefinition{6, "exceptions_total", "Total number of exceptions by error.", "error", exceptionsLabelMap},
}
)

Expand All @@ -93,32 +93,32 @@ var (
gaugeDefinition{5, "metadata_cache_size", "Number of entries in the metadata cache.", "meta-cache-size"},
gaugeDefinition{6, "qsize", "Number of packets waiting for database attention.", "qsize-q"},
}
authoritativeCounterVecDefs = []counterVecDefinition{
counterVecDefinition{
authoritativeCounterDefs = []counterDefinition{
counterDefinition{
1, "queries_total", "Total number of queries by network.", "net",
map[string]string{"tcp-queries": "tcp", "udp-queries": "udp"},
},
counterVecDefinition{
counterDefinition{
2, "answers_total", "Total number of answers by network.", "net",
map[string]string{"tcp-answers": "tcp", "udp-answers": "udp"},
},
counterVecDefinition{
counterDefinition{
3, "recursive_queries_total", "Total number of recursive queries by status.", "status",
map[string]string{"rd-queries": "requested", "recursing-questions": "processed", "recursing-answers": "answered", "recursion-unanswered": "unanswered"},
},
counterVecDefinition{
counterDefinition{
4, "update_queries_total", "Total number of DNS update queries by status.", "status",
map[string]string{"dnsupdate-answers": "answered", "dnsupdate-changes": "applied", "dnsupdate-queries": "requested", "dnsupdate-refused": "refused"},
},
counterVecDefinition{
counterDefinition{
5, "packet_cache_lookups_total", "Total number of packet-cache lookups by result.", "result",
map[string]string{"packetcache-hit": "hit", "packetcache-miss": "miss"},
},
counterVecDefinition{
counterDefinition{
6, "query_cache_lookups_total", "Total number of query-cache lookups by result.", "result",
map[string]string{"query-cache-hit": "hit", "query-cache-miss": "miss"},
},
counterVecDefinition{
counterDefinition{
7, "exceptions_total", "Total number of exceptions by error.", "error",
map[string]string{"servfail-packets": "servfail", "timedout-questions": "timeout", "udp-recvbuf-errors": "recvbuf-error", "udp-sndbuf-errors": "sndbuf-error"},
},
Expand All @@ -128,7 +128,7 @@ var (
// PowerDNS Dnsdist metrics definitions
var (
dnsdistGaugeDefs = []gaugeDefinition{}
dnsdistCounterVecDefs = []counterVecDefinition{}
dnsdistCounterDefs = []counterDefinition{}
)

// Creates a fixed-value response time histogram from the following stats counters:
Expand Down Expand Up @@ -168,4 +168,4 @@ func makeRecursorRTimeHistogram(statsMap map[string]float64) (prometheus.Metric,

h := prometheus.MustNewConstHistogram(desc, count, 0, buckets)
return h, nil
}
}
100 changes: 42 additions & 58 deletions powerdns_exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"time"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/prometheus/common/log"
)

Expand Down Expand Up @@ -70,24 +71,12 @@ type Exporter struct {
totalScrapes prometheus.Counter
jsonParseFailures prometheus.Counter
gaugeMetrics map[int]prometheus.Gauge
counterVecMetrics map[int]*prometheus.CounterVec
counterMetrics map[int]*prometheus.Desc
gaugeDefs []gaugeDefinition
counterVecDefs []counterVecDefinition
counterDefs []counterDefinition
client *http.Client
}

func newCounterVecMetric(serverType, metricName, docString string, labelNames []string) *prometheus.CounterVec {
return prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: namespace,
Subsystem: serverType,
Name: metricName,
Help: docString,
},
labelNames,
)
}

func newGaugeMetric(serverType, metricName, docString string) prometheus.Gauge {
return prometheus.NewGauge(
prometheus.GaugeOpts{
Expand All @@ -102,29 +91,42 @@ func newGaugeMetric(serverType, metricName, docString string) prometheus.Gauge {
// NewExporter returns an initialized Exporter.
func NewExporter(apiKey, serverType string, hostURL *url.URL) *Exporter {
var gaugeDefs []gaugeDefinition
var counterVecDefs []counterVecDefinition
var counterDefs []counterDefinition

gaugeMetrics := make(map[int]prometheus.Gauge)
counterVecMetrics := make(map[int]*prometheus.CounterVec)
counterMetrics := make(map[int]*prometheus.Desc)

switch serverType {
case "recursor":
gaugeDefs = recursorGaugeDefs
counterVecDefs = recursorCounterVecDefs
counterDefs = recursorCounterDefs
case "authoritative":
gaugeDefs = authoritativeGaugeDefs
counterVecDefs = authoritativeCounterVecDefs
counterDefs = authoritativeCounterDefs
case "dnsdist":
gaugeDefs = dnsdistGaugeDefs
counterVecDefs = dnsdistCounterVecDefs
counterDefs = dnsdistCounterDefs
}

for _, def := range gaugeDefs {
gaugeMetrics[def.id] = newGaugeMetric(serverType, def.name, def.desc)
}

for _, def := range counterVecDefs {
counterVecMetrics[def.id] = newCounterVecMetric(serverType, def.name, def.desc, []string{def.label})
for _, def := range counterDefs {
labels := make([]string, 0, len(def.labelMap))
for _, l := range def.labelMap {
labels = append(labels, l)
}
counterMetrics[def.id] = prometheus.NewDesc(
prometheus.BuildFQName(
def.label,
serverType,
def.name,
),
def.desc,
labels,
nil,
)
}

return &Exporter{
Expand All @@ -150,17 +152,17 @@ func NewExporter(apiKey, serverType string, hostURL *url.URL) *Exporter {
Help: "Number of errors while parsing PowerDNS JSON stats.",
}),
gaugeMetrics: gaugeMetrics,
counterVecMetrics: counterVecMetrics,
counterMetrics: counterMetrics,
gaugeDefs: gaugeDefs,
counterVecDefs: counterVecDefs,
counterDefs: counterDefs,
}
}

// Describe describes all the metrics ever exported by the PowerDNS exporter. It
// implements prometheus.Collector.
func (e *Exporter) Describe(ch chan<- *prometheus.Desc) {
for _, m := range e.counterVecMetrics {
m.Describe(ch)
for _, m := range e.counterMetrics {
ch <- m
}
for _, m := range e.gaugeMetrics {
ch <- m.Desc()
Expand All @@ -179,12 +181,10 @@ func (e *Exporter) Collect(ch chan<- prometheus.Metric) {

e.mutex.Lock()
defer e.mutex.Unlock()
e.resetMetrics()
statsMap := e.setMetrics(jsonStats)
ch <- e.up
ch <- e.totalScrapes
ch <- e.jsonParseFailures
e.collectMetrics(ch, statsMap)
e.collectMetrics(ch, jsonStats)
}

func (e *Exporter) scrape(jsonStats chan<- []StatsEntry) {
Expand All @@ -207,32 +207,8 @@ func (e *Exporter) scrape(jsonStats chan<- []StatsEntry) {
jsonStats <- data
}

func (e *Exporter) resetMetrics() {
for _, m := range e.counterVecMetrics {
m.Reset()
}
}

func (e *Exporter) collectMetrics(ch chan<- prometheus.Metric, statsMap map[string]float64) {
for _, m := range e.counterVecMetrics {
m.Collect(ch)
}
for _, m := range e.gaugeMetrics {
ch <- m
}

if e.ServerType == "recursor" {
h, err := makeRecursorRTimeHistogram(statsMap)
if err != nil {
log.Errorf("Could not create response time histogram: %v", err)
return
}
ch <- h
}
}

func (e *Exporter) setMetrics(jsonStats <-chan []StatsEntry) (statsMap map[string]float64) {
statsMap = make(map[string]float64)
func (e *Exporter) collectMetrics(ch chan<- prometheus.Metric, jsonStats <-chan []StatsEntry) {
statsMap := make(map[string]float64)
stats := <-jsonStats
for _, s := range stats {
statsMap[s.Name] = s.Value
Expand All @@ -254,17 +230,25 @@ func (e *Exporter) setMetrics(jsonStats <-chan []StatsEntry) (statsMap map[strin
}
}

for _, def := range e.counterVecDefs {
for _, def := range e.counterDefs {
for key, label := range def.labelMap {
if value, ok := statsMap[key]; ok {
e.counterVecMetrics[def.id].WithLabelValues(label).Set(value)
ch <- prometheus.MustNewConstMetric(e.counterMetrics[def.id], prometheus.CounterValue, float64(value), label)
} else {
log.Errorf("Expected PowerDNS stats key not found: %s", key)
e.jsonParseFailures.Inc()
}
}
}
return

if e.ServerType == "recursor" {
h, err := makeRecursorRTimeHistogram(statsMap)
if err != nil {
log.Errorf("Could not create response time histogram: %v", err)
return
}
ch <- h
}
}

func getServerInfo(hostURL *url.URL, apiKey string) (*ServerInfo, error) {
Expand Down Expand Up @@ -336,7 +320,7 @@ func main() {
prometheus.MustRegister(exporter)

log.Infof("Starting Server: %s", *listenAddress)
http.Handle(*metricsPath, prometheus.Handler())
http.Handle(*metricsPath, promhttp.Handler())
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`<html>
<head><title>PowerDNS Exporter</title></head>
Expand Down