Adding upstream version 1.34.4.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
e393c3af3f
commit
4978089aab
4963 changed files with 677545 additions and 0 deletions
204
plugins/inputs/bind/xml_stats_v3.go
Normal file
204
plugins/inputs/bind/xml_stats_v3.go
Normal file
|
@ -0,0 +1,204 @@
|
|||
package bind
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"math"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/metric"
|
||||
)
|
||||
|
||||
// XML path: //statistics
|
||||
// Omitted branches: socketmgr, taskmgr
|
||||
type v3Stats struct {
|
||||
Server v3Server `xml:"server"`
|
||||
Views []v3View `xml:"views>view"`
|
||||
Memory v3Memory `xml:"memory"`
|
||||
}
|
||||
|
||||
// XML path: //statistics/memory
|
||||
type v3Memory struct {
|
||||
Contexts []struct {
|
||||
// Omitted nodes: references, maxinuse, blocksize, pools, hiwater, lowater
|
||||
ID string `xml:"id"`
|
||||
Name string `xml:"name"`
|
||||
Total uint64 `xml:"total"`
|
||||
InUse uint64 `xml:"inuse"`
|
||||
} `xml:"contexts>context"`
|
||||
Summary struct {
|
||||
TotalUse uint64
|
||||
InUse uint64
|
||||
BlockSize uint64
|
||||
ContextSize uint64
|
||||
Lost uint64
|
||||
} `xml:"summary"`
|
||||
}
|
||||
|
||||
// XML path: //statistics/server
|
||||
type v3Server struct {
|
||||
CounterGroups []v3CounterGroup `xml:"counters"`
|
||||
}
|
||||
|
||||
// XML path: //statistics/views/view
|
||||
type v3View struct {
|
||||
// Omitted branches: zones
|
||||
Name string `xml:"name,attr"`
|
||||
CounterGroups []v3CounterGroup `xml:"counters"`
|
||||
Caches []struct {
|
||||
Name string `xml:"name,attr"`
|
||||
RRSets []struct {
|
||||
Name string `xml:"name"`
|
||||
Value uint64 `xml:"counter"`
|
||||
} `xml:"rrset"`
|
||||
} `xml:"cache"`
|
||||
}
|
||||
|
||||
// Generic XML v3 doc fragment used in multiple places
|
||||
type v3CounterGroup struct {
|
||||
Type string `xml:"type,attr"`
|
||||
Counters []struct {
|
||||
Name string `xml:"name,attr"`
|
||||
Value uint64 `xml:",chardata"`
|
||||
} `xml:"counter"`
|
||||
}
|
||||
|
||||
// addStatsXMLv3 walks a v3Stats struct and adds the values to the telegraf.Accumulator.
|
||||
func (b *Bind) addStatsXMLv3(stats v3Stats, acc telegraf.Accumulator, hostPort string) {
|
||||
grouper := metric.NewSeriesGrouper()
|
||||
ts := time.Now()
|
||||
host, port, err := net.SplitHostPort(hostPort)
|
||||
if err != nil {
|
||||
acc.AddError(err)
|
||||
}
|
||||
// Counter groups
|
||||
for _, cg := range stats.Server.CounterGroups {
|
||||
for _, c := range cg.Counters {
|
||||
if cg.Type == "opcode" && strings.HasPrefix(c.Name, "RESERVED") {
|
||||
continue
|
||||
}
|
||||
|
||||
tags := map[string]string{"url": hostPort, "source": host, "port": port, "type": cg.Type}
|
||||
var v interface{} = c.Value
|
||||
if b.CountersAsInt {
|
||||
if c.Value < math.MaxInt64 {
|
||||
v = int64(c.Value)
|
||||
} else {
|
||||
v = int64(math.MaxInt64)
|
||||
}
|
||||
}
|
||||
grouper.Add("bind_counter", tags, ts, c.Name, v)
|
||||
}
|
||||
}
|
||||
|
||||
// Memory stats
|
||||
fields := map[string]interface{}{
|
||||
"total_use": stats.Memory.Summary.TotalUse,
|
||||
"in_use": stats.Memory.Summary.InUse,
|
||||
"block_size": stats.Memory.Summary.BlockSize,
|
||||
"context_size": stats.Memory.Summary.ContextSize,
|
||||
"lost": stats.Memory.Summary.Lost,
|
||||
}
|
||||
b.postProcessFields(fields)
|
||||
acc.AddGauge("bind_memory", fields, map[string]string{"url": hostPort, "source": host, "port": port})
|
||||
|
||||
// Detailed, per-context memory stats
|
||||
if b.GatherMemoryContexts {
|
||||
for _, c := range stats.Memory.Contexts {
|
||||
tags := map[string]string{"url": hostPort, "source": host, "port": port, "id": c.ID, "name": c.Name}
|
||||
fields := map[string]interface{}{"total": c.Total, "in_use": c.InUse}
|
||||
|
||||
b.postProcessFields(fields)
|
||||
acc.AddGauge("bind_memory_context", fields, tags)
|
||||
}
|
||||
}
|
||||
|
||||
// Detailed, per-view stats
|
||||
if b.GatherViews {
|
||||
for _, v := range stats.Views {
|
||||
for _, cg := range v.CounterGroups {
|
||||
for _, c := range cg.Counters {
|
||||
tags := map[string]string{
|
||||
"url": hostPort,
|
||||
"source": host,
|
||||
"port": port,
|
||||
"view": v.Name,
|
||||
"type": cg.Type,
|
||||
}
|
||||
var v interface{} = c.Value
|
||||
if b.CountersAsInt {
|
||||
if c.Value < math.MaxInt64 {
|
||||
v = int64(c.Value)
|
||||
} else {
|
||||
v = int64(math.MaxInt64)
|
||||
}
|
||||
}
|
||||
grouper.Add("bind_counter", tags, ts, c.Name, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add grouped metrics
|
||||
for _, groupedMetric := range grouper.Metrics() {
|
||||
acc.AddMetric(groupedMetric)
|
||||
}
|
||||
}
|
||||
|
||||
// readStatsXMLv3 takes a base URL to probe, and requests the individual statistics documents that
|
||||
// we are interested in. These individual documents have a combined size which is significantly
|
||||
// smaller than if we requested everything at once (e.g. taskmgr and socketmgr can be omitted).
|
||||
func (b *Bind) readStatsXMLv3(addr *url.URL, acc telegraf.Accumulator) error {
|
||||
var stats v3Stats
|
||||
|
||||
// Progressively build up full v3Stats struct by parsing the individual HTTP responses
|
||||
for _, suffix := range [...]string{"/server", "/net", "/mem"} {
|
||||
err := func() error {
|
||||
scrapeURL := addr.String() + suffix
|
||||
|
||||
resp, err := b.client.Get(scrapeURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("%s returned HTTP status: %s", scrapeURL, resp.Status)
|
||||
}
|
||||
|
||||
if err := xml.NewDecoder(resp.Body).Decode(&stats); err != nil {
|
||||
return fmt.Errorf("unable to decode XML document: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
b.addStatsXMLv3(stats, acc, addr.Host)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Bind) postProcessFields(fields map[string]interface{}) {
|
||||
if !b.CountersAsInt {
|
||||
return
|
||||
}
|
||||
for k, val := range fields {
|
||||
if v, ok := val.(uint64); ok {
|
||||
if v < math.MaxInt64 {
|
||||
fields[k] = int64(v)
|
||||
} else {
|
||||
fields[k] = int64(math.MaxInt64)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue