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

feat: inputs/powerdns: Add underscore option #10021

Closed
wants to merge 2 commits into from
Closed
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
5 changes: 5 additions & 0 deletions plugins/inputs/powerdns/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ The powerdns plugin gathers metrics about PowerDNS using unix socket.
#
# If no servers are specified, then '/var/run/pdns.controlsocket' is used as the path.
unix_sockets = ["/var/run/pdns.controlsocket"]

# Convert dash in field names to underscore
underline = false
```

#### Permissions
Expand Down Expand Up @@ -66,6 +69,8 @@ usermod telegraf -a -G pdns
- uptime
- user-msec

If underscore bool is set to true, field names will have `-` converted to `_`, e.g. changing `user-msec` to `user_msec`.

### Tags:

- tags: `server=socket`
Expand Down
15 changes: 12 additions & 3 deletions plugins/inputs/powerdns/powerdns.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@ import (

type Powerdns struct {
UnixSockets []string
Underscore bool
}

var sampleConfig = `
## An array of sockets to gather stats about.
## Specify a path to unix socket.
unix_sockets = ["/var/run/pdns.controlsocket"]

# Convert dash in field names to underscore
underscore = false
`

var defaultTimeout = 5 * time.Second
Expand Down Expand Up @@ -89,7 +93,7 @@ func (p *Powerdns) gatherServer(address string, acc telegraf.Accumulator) error
metrics := string(buf)

// Process data
fields := parseResponse(metrics)
fields := parseResponse(metrics, p.Underscore)

// Add server socket as a tag
tags := map[string]string{"server": address}
Expand All @@ -99,7 +103,7 @@ func (p *Powerdns) gatherServer(address string, acc telegraf.Accumulator) error
return nil
}

func parseResponse(metrics string) map[string]interface{} {
func parseResponse(metrics string, underscore bool) map[string]interface{} {
values := make(map[string]interface{})

s := strings.Split(metrics, ",")
Expand All @@ -116,7 +120,12 @@ func parseResponse(metrics string) map[string]interface{} {
metric, err.Error())
continue
}
values[m[0]] = i

field := m[0]
if underscore {
field = strings.ReplaceAll(field, "-", "_")
}
values[field] = i
}

return values
Expand Down
66 changes: 63 additions & 3 deletions plugins/inputs/powerdns/powerdns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ func TestPowerdnsGeneratesMetrics(t *testing.T) {
}

func TestPowerdnsParseMetrics(t *testing.T) {
values := parseResponse(metrics)
values := parseResponse(metrics, false)

tests := []struct {
key string
Expand Down Expand Up @@ -172,8 +172,68 @@ func TestPowerdnsParseMetrics(t *testing.T) {
}
}

func TestPowerdnsParseMetricsUnderscore(t *testing.T) {
values := parseResponse(metrics, true)

tests := []struct {
key string
value int64
}{
{"corrupt_packets", 0},
{"deferred_cache_inserts", 0},
{"deferred_cache_lookup", 0},
{"dnsupdate_answers", 0},
{"dnsupdate_changes", 0},
{"dnsupdate_queries", 0},
{"dnsupdate_refused", 0},
{"packetcache_hit", 0},
{"packetcache_miss", 1},
{"packetcache_size", 0},
{"query_cache_hit", 0},
{"query_cache_miss", 6},
{"rd_queries", 1},
{"recursing_answers", 0},
{"recursing_questions", 0},
{"recursion_unanswered", 0},
{"security_status", 3},
{"servfail_packets", 0},
{"signatures", 0},
{"tcp_answers", 0},
{"tcp_queries", 0},
{"timedout_packets", 0},
{"udp_answers", 1},
{"udp_answers_bytes", 50},
{"udp_do_queries", 0},
{"udp_queries", 0},
{"udp4_answers", 1},
{"udp4_queries", 1},
{"udp6_answers", 0},
{"udp6_queries", 0},
{"key_cache_size", 0},
{"latency", 26},
{"meta_cache_size", 0},
{"qsize_q", 0},
{"signature_cache_size", 0},
{"sys_msec", 2889},
{"uptime", 86317},
{"user_msec", 2167},
}

for _, test := range tests {
value, ok := values[test.key]
if !ok {
t.Errorf("Did not find key for metric %s in values", test.key)
continue
}
if value != test.value {
t.Errorf("Metric: %s, Expected: %d, actual: %d",
test.key, test.value, value)
}
}
}

func TestPowerdnsParseCorruptMetrics(t *testing.T) {
values := parseResponse(corruptMetrics)
values := parseResponse(corruptMetrics, false)

tests := []struct {
key string
Expand Down Expand Up @@ -232,7 +292,7 @@ func TestPowerdnsParseCorruptMetrics(t *testing.T) {
}

func TestPowerdnsParseIntOverflowMetrics(t *testing.T) {
values := parseResponse(intOverflowMetrics)
values := parseResponse(intOverflowMetrics, false)

tests := []struct {
key string
Expand Down
14 changes: 11 additions & 3 deletions plugins/inputs/powerdns_recursor/powerdns_recursor.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type PowerdnsRecursor struct {
UnixSockets []string `toml:"unix_sockets"`
SocketDir string `toml:"socket_dir"`
SocketMode string `toml:"socket_mode"`
Underscore bool `toml:"underscore"`

mode uint32
}
Expand All @@ -36,6 +37,8 @@ var sampleConfig = `
# socket_dir = "/var/run/"
## Socket permissions for the receive socket.
# socket_mode = "0666"
## Convert dash in field names to underscore
# underscore = false
`

func (p *PowerdnsRecursor) SampleConfig() string {
Expand Down Expand Up @@ -125,7 +128,7 @@ func (p *PowerdnsRecursor) gatherServer(address string, acc telegraf.Accumulator
metrics := string(buf)

// Process data
fields := parseResponse(metrics)
fields := parseResponse(metrics, p.Underscore)

// Add server socket as a tag
tags := map[string]string{"server": address}
Expand All @@ -135,7 +138,7 @@ func (p *PowerdnsRecursor) gatherServer(address string, acc telegraf.Accumulator
return conn.Close()
}

func parseResponse(metrics string) map[string]interface{} {
func parseResponse(metrics string, underscore bool) map[string]interface{} {
values := make(map[string]interface{})

s := strings.Split(metrics, "\n")
Expand All @@ -152,7 +155,12 @@ func parseResponse(metrics string) map[string]interface{} {
metric, err.Error())
continue
}
values[m[0]] = i

field := m[0]
if underscore {
field = strings.ReplaceAll(field, "-", "_")
}
values[field] = i
}

return values
Expand Down
128 changes: 125 additions & 3 deletions plugins/inputs/powerdns_recursor/powerdns_recursor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ func TestPowerdnsRecursorGeneratesMetrics(t *testing.T) {
}

func TestPowerdnsRecursorParseMetrics(t *testing.T) {
values := parseResponse(metrics)
values := parseResponse(metrics, false)

tests := []struct {
key string
Expand Down Expand Up @@ -309,8 +309,130 @@ func TestPowerdnsRecursorParseMetrics(t *testing.T) {
}
}

func TestPowerdnsRecursorParseMetricsUnderscore(t *testing.T) {
values := parseResponse(metrics, true)

tests := []struct {
key string
value int64
}{
{"all_outqueries", 3591637},
{"answers_slow", 36451},
{"answers0_1", 177297},
{"answers1_10", 1209328},
{"answers10_100", 1238786},
{"answers100_1000", 402917},
{"auth_zone_queries", 4},
{"auth4_answers_slow", 44248},
{"auth4_answers0_1", 59169},
{"auth4_answers1_10", 1747403},
{"auth4_answers10_100", 1315621},
{"auth4_answers100_1000", 424683},
{"auth6_answers_slow", 0},
{"auth6_answers0_1", 0},
{"auth6_answers1_10", 0},
{"auth6_answers10_100", 0},
{"auth6_answers100_1000", 0},
{"cache_entries", 295917},
{"cache_hits", 148630},
{"cache_misses", 2916149},
{"case_mismatches", 0},
{"chain_resends", 418602},
{"client_parse_errors", 0},
{"concurrent_queries", 0},
{"dlg_only_drops", 0},
{"dnssec_queries", 151536},
{"dnssec_result_bogus", 0},
{"dnssec_result_indeterminate", 0},
{"dnssec_result_insecure", 0},
{"dnssec_result_nta", 0},
{"dnssec_result_secure", 46},
{"dnssec_validations", 46},
{"dont_outqueries", 62},
{"ecs_queries", 0},
{"ecs_responses", 0},
{"edns_ping_matches", 0},
{"edns_ping_mismatches", 0},
{"failed_host_entries", 33},
{"fd_usage", 32},
{"ignored_packets", 0},
{"ipv6_outqueries", 0},
{"ipv6_questions", 0},
{"malloc_bytes", 0},
{"max_cache_entries", 1000000},
{"max_mthread_stack", 33747},
{"max_packetcache_entries", 500000},
{"negcache_entries", 100070},
{"no_packet_error", 0},
{"noedns_outqueries", 72409},
{"noerror_answers", 25155259},
{"noping_outqueries", 0},
{"nsset_invalidations", 2385},
{"nsspeeds_entries", 3571},
{"nxdomain_answers", 3307768},
{"outgoing_timeouts", 43876},
{"outgoing4_timeouts", 43876},
{"outgoing6_timeouts", 0},
{"over_capacity_drops", 0},
{"packetcache_entries", 80756},
{"packetcache_hits", 25698497},
{"packetcache_misses", 3064625},
{"policy_drops", 0},
{"policy_result_custom", 0},
{"policy_result_drop", 0},
{"policy_result_noaction", 3064779},
{"policy_result_nodata", 0},
{"policy_result_nxdomain", 0},
{"policy_result_truncate", 0},
{"qa_latency", 6587},
{"query_pipe_full_drops", 0},
{"questions", 28763276},
{"real_memory_usage", 280465408},
{"resource_limits", 0},
{"security_status", 1},
{"server_parse_errors", 0},
{"servfail_answers", 300249},
{"spoof_prevents", 0},
{"sys_msec", 1296588},
{"tcp_client_overflow", 0},
{"tcp_clients", 0},
{"tcp_outqueries", 116},
{"tcp_questions", 130},
{"throttle_entries", 33},
{"throttled_out", 13187},
{"throttled_outqueries", 13187},
{"too_old_drops", 2},
{"udp_in_errors", 4},
{"udp_noport_errors", 2908},
{"udp_recvbuf_errors", 0},
{"udp_sndbuf_errors", 0},
{"unauthorized_tcp", 0},
{"unauthorized_udp", 0},
{"unexpected_packets", 0},
{"unreachables", 1695},
{"uptime", 165725},
{"user_msec", 1266384},
{"x_our_latency", 19},
{"x_ourtime_slow", 632},
{"x_ourtime0_1", 3060079},
{"x_ourtime1_2", 3351},
{"x_ourtime16_32", 197},
{"x_ourtime2_4", 302},
{"x_ourtime4_8", 194},
{"x_ourtime8_16", 24},
}

for _, test := range tests {
value, ok := values[test.key]
if !assert.Truef(t, ok, "Did not find key for metric %s in values", test.key) {
continue
}
require.EqualValuesf(t, value, test.value, "Metric: %s, Expected: %d, actual: %d", test.key, test.value, value)
}
}

func TestPowerdnsRecursorParseCorruptMetrics(t *testing.T) {
values := parseResponse(corruptMetrics)
values := parseResponse(corruptMetrics, false)

tests := []struct {
key string
Expand Down Expand Up @@ -431,7 +553,7 @@ func TestPowerdnsRecursorParseCorruptMetrics(t *testing.T) {
}

func TestPowerdnsRecursorParseIntOverflowMetrics(t *testing.T) {
values := parseResponse(intOverflowMetrics)
values := parseResponse(intOverflowMetrics, false)

tests := []struct {
key string
Expand Down