1
0
Fork 0

Adding upstream version 1.34.4.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-05-24 07:26:29 +02:00
parent e393c3af3f
commit 4978089aab
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
4963 changed files with 677545 additions and 0 deletions

View file

@ -0,0 +1,195 @@
# NLnet Labs Name Server Daemon Input Plugin
This plugin gathers statistics from a [NLnet Labs Name Server Daemon][nsd], an
authoritative DNS name server.
⭐ Telegraf v1.0.0
🏷️ server
💻 all
[nsd]: https://www.nlnetlabs.nl/projects/nsd/about
## Global configuration options <!-- @/docs/includes/plugin_config.md -->
In addition to the plugin-specific configuration settings, plugins support
additional global and plugin configuration settings. These settings are used to
modify metrics, tags, and field or create aliases and configure ordering, etc.
See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
[CONFIGURATION.md]: ../../../docs/CONFIGURATION.md#plugins
## Configuration
```toml @sample.conf
# A plugin to collect stats from the NSD DNS resolver
[[inputs.nsd]]
## Address of server to connect to, optionally ':port'. Defaults to the
## address in the nsd config file.
server = "127.0.0.1:8953"
## If running as a restricted user you can prepend sudo for additional access:
# use_sudo = false
## The default location of the nsd-control binary can be overridden with:
# binary = "/usr/sbin/nsd-control"
## The default location of the nsd config file can be overridden with:
# config_file = "/etc/nsd/nsd.conf"
## The default timeout of 1s can be overridden with:
# timeout = "1s"
```
### Permissions
It's important to note that this plugin references nsd-control, which may
require additional permissions to execute successfully. Depending on the
user/group permissions of the telegraf user executing this plugin, you may
need to alter the group membership, set facls, or use sudo.
**Group membership (Recommended)**:
```bash
$ groups telegraf
telegraf : telegraf
$ usermod -a -G nsd telegraf
$ groups telegraf
telegraf : telegraf nsd
```
**Sudo privileges**:
If you use this method, you will need the following in your telegraf config:
```toml
[[inputs.nsd]]
use_sudo = true
```
You will also need to update your sudoers file:
```bash
$ visudo
# Add the following line:
Cmnd_Alias NSDCONTROLCTL = /usr/sbin/nsd-control
telegraf ALL=(ALL) NOPASSWD: NSDCONTROLCTL
Defaults!NSDCONTROLCTL !logfile, !syslog, !pam_session
```
Please use the solution you see as most appropriate.
## Metrics
This is the full list of stats provided by nsd-control. In the output, the
dots in the nsd-control stat name are replaced by underscores (see
<https://www.nlnetlabs.nl/documentation/nsd/nsd-control/> for details).
- nsd
- fields:
- num_queries
- time_boot
- time_elapsed
- size_db_disk
- size_db_mem
- size_xfrd_mem
- size_config_disk
- size_config_mem
- num_type_TYPE0
- num_type_A
- num_type_NS
- num_type_MD
- num_type_MF
- num_type_CNAME
- num_type_SOA
- num_type_MB
- num_type_MG
- num_type_MR
- num_type_NULL
- num_type_WKS
- num_type_PTR
- num_type_HINFO
- num_type_MINFO
- num_type_MX
- num_type_TXT
- num_type_RP
- num_type_AFSDB
- num_type_X25
- num_type_ISDN
- num_type_RT
- num_type_NSAP
- num_type_SIG
- num_type_KEY
- num_type_PX
- num_type_AAAA
- num_type_LOC
- num_type_NXT
- num_type_SRV
- num_type_NAPTR
- num_type_KX
- num_type_CERT
- num_type_DNAME
- num_type_OPT
- num_type_APL
- num_type_DS
- num_type_SSHFP
- num_type_IPSECKEY
- num_type_RRSIG
- num_type_NSEC
- num_type_DNSKEY
- num_type_DHCID
- num_type_NSEC3
- num_type_NSEC3PARAM
- num_type_TLSA
- num_type_SMIMEA
- num_type_CDS
- num_type_CDNSKEY
- num_type_OPENPGPKEY
- num_type_CSYNC
- num_type_SPF
- num_type_NID
- num_type_L32
- num_type_L64
- num_type_LP
- num_type_EUI48
- num_type_EUI64
- num_type_TYPE252
- num_type_TYPE253
- num_type_TYPE255
- num_opcode_QUERY
- num_opcode_NOTIFY
- num_class_CLASS0
- num_class_IN
- num_class_CH
- num_rcode_NOERROR
- num_rcode_FORMERR
- num_rcode_SERVFAIL
- num_rcode_NXDOMAIN
- num_rcode_NOTIMP
- num_rcode_REFUSED
- num_rcode_YXDOMAIN
- num_rcode_NOTAUTH
- num_edns
- num_ednserr
- num_udp
- num_udp6
- num_tcp
- num_tcp6
- num_tls
- num_tls6
- num_answer_wo_aa
- num_rxerr
- num_txerr
- num_raxfr
- num_truncated
- num_dropped
- zone_master
- zone_slave
- nsd_servers
- tags:
- server
- fields:
- queries
## Example Output

147
plugins/inputs/nsd/nsd.go Normal file
View file

@ -0,0 +1,147 @@
//go:generate ../../../tools/readme_config_includer/generator
package nsd
import (
"bufio"
"bytes"
_ "embed"
"fmt"
"net"
"os/exec"
"strconv"
"strings"
"time"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/config"
"github.com/influxdata/telegraf/internal"
"github.com/influxdata/telegraf/plugins/inputs"
)
//go:embed sample.conf
var sampleConfig string
var (
defaultBinary = "/usr/sbin/nsd-control"
defaultTimeout = config.Duration(time.Second)
)
type NSD struct {
Binary string `toml:"binary"`
Timeout config.Duration `toml:"timeout"`
UseSudo bool `toml:"use_sudo"`
Server string `toml:"server"`
ConfigFile string `toml:"config_file"`
run runner
}
type runner func(cmdName string, timeout config.Duration, useSudo bool, Server string, ConfigFile string) (*bytes.Buffer, error)
func (*NSD) SampleConfig() string {
return sampleConfig
}
func (s *NSD) Gather(acc telegraf.Accumulator) error {
out, err := s.run(s.Binary, s.Timeout, s.UseSudo, s.Server, s.ConfigFile)
if err != nil {
return fmt.Errorf("error gathering metrics: %w", err)
}
// Process values
fields := make(map[string]interface{})
fieldsServers := make(map[string]map[string]interface{})
scanner := bufio.NewScanner(out)
for scanner.Scan() {
cols := strings.Split(scanner.Text(), "=")
// Check split correctness
if len(cols) != 2 {
continue
}
stat := cols[0]
value := cols[1]
fieldValue, err := strconv.ParseFloat(value, 64)
if err != nil {
acc.AddError(fmt.Errorf("expected a numerical value for %s = %v",
stat, value))
continue
}
if strings.HasPrefix(stat, "server") {
statTokens := strings.Split(stat, ".")
if len(statTokens) > 1 {
serverID := strings.TrimPrefix(statTokens[0], "server")
if _, err := strconv.Atoi(serverID); err == nil {
serverTokens := statTokens[1:]
field := strings.Join(serverTokens[:], "_")
if fieldsServers[serverID] == nil {
fieldsServers[serverID] = make(map[string]interface{})
}
fieldsServers[serverID][field] = fieldValue
}
}
} else {
field := strings.ReplaceAll(stat, ".", "_")
fields[field] = fieldValue
}
}
acc.AddFields("nsd", fields, nil)
for thisServerID, thisServerFields := range fieldsServers {
thisServerTag := map[string]string{"server": thisServerID}
acc.AddFields("nsd_servers", thisServerFields, thisServerTag)
}
return nil
}
// Shell out to nsd_stat and return the output
func nsdRunner(cmdName string, timeout config.Duration, useSudo bool, server, configFile string) (*bytes.Buffer, error) {
cmdArgs := []string{"stats_noreset"}
if server != "" {
host, port, err := net.SplitHostPort(server)
if err == nil {
server = host + "@" + port
}
cmdArgs = append([]string{"-s", server}, cmdArgs...)
}
if configFile != "" {
cmdArgs = append([]string{"-c", configFile}, cmdArgs...)
}
cmd := exec.Command(cmdName, cmdArgs...)
if useSudo {
cmdArgs = append([]string{cmdName}, cmdArgs...)
cmd = exec.Command("sudo", cmdArgs...)
}
var out bytes.Buffer
cmd.Stdout = &out
err := internal.RunTimeout(cmd, time.Duration(timeout))
if err != nil {
return &out, fmt.Errorf("error running nsd-control: %w (%s %v)", err, cmdName, cmdArgs)
}
return &out, nil
}
func init() {
inputs.Add("nsd", func() telegraf.Input {
return &NSD{
run: nsdRunner,
Binary: defaultBinary,
Timeout: defaultTimeout,
UseSudo: false,
Server: "",
ConfigFile: "",
}
})
}

View file

@ -0,0 +1,241 @@
package nsd
import (
"bytes"
"testing"
"github.com/stretchr/testify/require"
"github.com/influxdata/telegraf/config"
"github.com/influxdata/telegraf/testutil"
)
func nsdControl(output string) func(string, config.Duration, bool, string, string) (*bytes.Buffer, error) {
return func(string, config.Duration, bool, string, string) (*bytes.Buffer, error) {
return bytes.NewBufferString(output), nil
}
}
func TestParseFullOutput(t *testing.T) {
acc := &testutil.Accumulator{}
v := &NSD{
run: nsdControl(fullOutput),
}
err := v.Gather(acc)
require.NoError(t, err)
require.True(t, acc.HasMeasurement("nsd"))
require.True(t, acc.HasMeasurement("nsd_servers"))
require.Len(t, acc.Metrics, 2)
require.Equal(t, 99, acc.NFields())
acc.AssertContainsFields(t, "nsd", parsedFullOutput)
acc.AssertContainsFields(t, "nsd_servers", parsedFullOutputServerAsTag)
}
var parsedFullOutputServerAsTag = map[string]interface{}{
"queries": float64(75576),
}
var parsedFullOutput = map[string]interface{}{
"num_queries": float64(75557),
"time_boot": float64(2944405.500253),
"time_elapsed": float64(2944405.500253),
"size_db_disk": float64(98304),
"size_db_mem": float64(22784),
"size_xfrd_mem": float64(83956312),
"size_config_disk": float64(0),
"size_config_mem": float64(6088),
"num_type_TYPE0": float64(6),
"num_type_A": float64(46311),
"num_type_NS": float64(478),
"num_type_MD": float64(0),
"num_type_MF": float64(0),
"num_type_CNAME": float64(272),
"num_type_SOA": float64(596),
"num_type_MB": float64(0),
"num_type_MG": float64(0),
"num_type_MR": float64(0),
"num_type_NULL": float64(0),
"num_type_WKS": float64(0),
"num_type_PTR": float64(83),
"num_type_HINFO": float64(1),
"num_type_MINFO": float64(0),
"num_type_MX": float64(296),
"num_type_TXT": float64(794),
"num_type_RP": float64(0),
"num_type_AFSDB": float64(0),
"num_type_X25": float64(0),
"num_type_ISDN": float64(0),
"num_type_RT": float64(0),
"num_type_NSAP": float64(0),
"num_type_SIG": float64(0),
"num_type_KEY": float64(1),
"num_type_PX": float64(0),
"num_type_AAAA": float64(22736),
"num_type_LOC": float64(2),
"num_type_NXT": float64(0),
"num_type_SRV": float64(93),
"num_type_NAPTR": float64(5),
"num_type_KX": float64(0),
"num_type_CERT": float64(0),
"num_type_DNAME": float64(0),
"num_type_OPT": float64(0),
"num_type_APL": float64(0),
"num_type_DS": float64(0),
"num_type_SSHFP": float64(0),
"num_type_IPSECKEY": float64(0),
"num_type_RRSIG": float64(21),
"num_type_NSEC": float64(0),
"num_type_DNSKEY": float64(325),
"num_type_DHCID": float64(0),
"num_type_NSEC3": float64(0),
"num_type_NSEC3PARAM": float64(0),
"num_type_TLSA": float64(35),
"num_type_SMIMEA": float64(0),
"num_type_CDS": float64(0),
"num_type_CDNSKEY": float64(0),
"num_type_OPENPGPKEY": float64(0),
"num_type_CSYNC": float64(0),
"num_type_SPF": float64(16),
"num_type_NID": float64(0),
"num_type_L32": float64(0),
"num_type_L64": float64(0),
"num_type_LP": float64(0),
"num_type_EUI48": float64(0),
"num_type_EUI64": float64(0),
"num_type_TYPE252": float64(962),
"num_type_TYPE253": float64(2),
"num_type_TYPE255": float64(1840),
"num_opcode_QUERY": float64(75527),
"num_opcode_NOTIFY": float64(6),
"num_class_CLASS0": float64(6),
"num_class_IN": float64(75395),
"num_class_CH": float64(132),
"num_rcode_NOERROR": float64(65541),
"num_rcode_FORMERR": float64(8),
"num_rcode_SERVFAIL": float64(0),
"num_rcode_NXDOMAIN": float64(6642),
"num_rcode_NOTIMP": float64(18),
"num_rcode_REFUSED": float64(3341),
"num_rcode_YXDOMAIN": float64(0),
"num_rcode_NOTAUTH": float64(2),
"num_edns": float64(71398),
"num_ednserr": float64(0),
"num_udp": float64(34111),
"num_udp6": float64(40429),
"num_tcp": float64(1015),
"num_tcp6": float64(2),
"num_tls": float64(0),
"num_tls6": float64(0),
"num_answer_wo_aa": float64(13),
"num_rxerr": float64(0),
"num_txerr": float64(0),
"num_raxfr": float64(954),
"num_truncated": float64(1),
"num_dropped": float64(5),
"zone_master": float64(2),
"zone_slave": float64(1),
}
var fullOutput = `server0.queries=75576
num.queries=75557
time.boot=2944405.500253
time.elapsed=2944405.500253
size.db.disk=98304
size.db.mem=22784
size.xfrd.mem=83956312
size.config.disk=0
size.config.mem=6088
num.type.TYPE0=6
num.type.A=46311
num.type.NS=478
num.type.MD=0
num.type.MF=0
num.type.CNAME=272
num.type.SOA=596
num.type.MB=0
num.type.MG=0
num.type.MR=0
num.type.NULL=0
num.type.WKS=0
num.type.PTR=83
num.type.HINFO=1
num.type.MINFO=0
num.type.MX=296
num.type.TXT=794
num.type.RP=0
num.type.AFSDB=0
num.type.X25=0
num.type.ISDN=0
num.type.RT=0
num.type.NSAP=0
num.type.SIG=0
num.type.KEY=1
num.type.PX=0
num.type.AAAA=22736
num.type.LOC=2
num.type.NXT=0
num.type.SRV=93
num.type.NAPTR=5
num.type.KX=0
num.type.CERT=0
num.type.DNAME=0
num.type.OPT=0
num.type.APL=0
num.type.DS=0
num.type.SSHFP=0
num.type.IPSECKEY=0
num.type.RRSIG=21
num.type.NSEC=0
num.type.DNSKEY=325
num.type.DHCID=0
num.type.NSEC3=0
num.type.NSEC3PARAM=0
num.type.TLSA=35
num.type.SMIMEA=0
num.type.CDS=0
num.type.CDNSKEY=0
num.type.OPENPGPKEY=0
num.type.CSYNC=0
num.type.SPF=16
num.type.NID=0
num.type.L32=0
num.type.L64=0
num.type.LP=0
num.type.EUI48=0
num.type.EUI64=0
num.type.TYPE252=962
num.type.TYPE253=2
num.type.TYPE255=1840
num.opcode.QUERY=75527
num.opcode.NOTIFY=6
num.class.CLASS0=6
num.class.IN=75395
num.class.CH=132
num.rcode.NOERROR=65541
num.rcode.FORMERR=8
num.rcode.SERVFAIL=0
num.rcode.NXDOMAIN=6642
num.rcode.NOTIMP=18
num.rcode.REFUSED=3341
num.rcode.YXDOMAIN=0
num.rcode.NOTAUTH=2
num.edns=71398
num.ednserr=0
num.udp=34111
num.udp6=40429
num.tcp=1015
num.tcp6=2
num.tls=0
num.tls6=0
num.answer_wo_aa=13
num.rxerr=0
num.txerr=0
num.raxfr=954
num.truncated=1
num.dropped=5
zone.master=2
zone.slave=1`

View file

@ -0,0 +1,17 @@
# A plugin to collect stats from the NSD DNS resolver
[[inputs.nsd]]
## Address of server to connect to, optionally ':port'. Defaults to the
## address in the nsd config file.
server = "127.0.0.1:8953"
## If running as a restricted user you can prepend sudo for additional access:
# use_sudo = false
## The default location of the nsd-control binary can be overridden with:
# binary = "/usr/sbin/nsd-control"
## The default location of the nsd config file can be overridden with:
# config_file = "/etc/nsd/nsd.conf"
## The default timeout of 1s can be overridden with:
# timeout = "1s"