fix(inputs.bind): Convert counters to uint64 (#16015)

This commit is contained in:
Sven Rebhan 2024-10-30 15:30:50 +01:00 committed by GitHub
parent d76723d21c
commit 9c8196fdac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 1333 additions and 24 deletions

View File

@ -1,6 +1,17 @@
<!-- markdownlint-disable MD024 --> <!-- markdownlint-disable MD024 -->
# Changelog # Changelog
## Unreleased
### Important Changes
- PR [#16015](https://github.com/influxdata/telegraf/pull/16015) changes the internal
counters of the Bind plugin to unsigned integers matching the server
implementation. We keep backward compatibility by setting
`report_counters_as_int` to `true` by default to avoid type conflicts on the
output side. However, you should change this setting to `false` as soon as
possible to avoid invalid values and parsing errors with the v3 XML statistics.
## v1.32.2 [2024-10-28] ## v1.32.2 [2024-10-28]
### Bugfixes ### Bugfixes

View File

@ -35,6 +35,11 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
# gather_memory_contexts = false # gather_memory_contexts = false
# gather_views = false # gather_views = false
## Report xml v3 counters as integers instead of unsigned for backward
## compatibility. Set this to false as soon as possible!
## Values are clipped if exceeding the integer range.
# report_counters_as_int = true
## Timeout for http requests made by bind nameserver ## Timeout for http requests made by bind nameserver
# timeout = "4s" # timeout = "4s"
``` ```

View File

@ -18,10 +18,11 @@ import (
var sampleConfig string var sampleConfig string
type Bind struct { type Bind struct {
Urls []string Urls []string `toml:"urls"`
GatherMemoryContexts bool GatherMemoryContexts bool `toml:"gather_memory_contexts"`
GatherViews bool GatherViews bool `toml:"gather_views"`
Timeout config.Duration `toml:"timeout"` Timeout config.Duration `toml:"timeout"`
CountersAsInt bool `toml:"report_counters_as_int"`
client http.Client client http.Client
} }
@ -84,5 +85,5 @@ func (b *Bind) gatherURL(addr *url.URL, acc telegraf.Accumulator) error {
} }
func init() { func init() {
inputs.Add("bind", func() telegraf.Input { return &Bind{} }) inputs.Add("bind", func() telegraf.Input { return &Bind{CountersAsInt: true} })
} }

File diff suppressed because it is too large Load Diff

View File

@ -6,5 +6,10 @@
# gather_memory_contexts = false # gather_memory_contexts = false
# gather_views = false # gather_views = false
## Report xml v3 counters as integers instead of unsigned for backward
## compatibility. Set this to false as soon as possible!
## Values are clipped if exceeding the integer range.
# report_counters_as_int = true
## Timeout for http requests made by bind nameserver ## Timeout for http requests made by bind nameserver
# timeout = "4s" # timeout = "4s"

View File

@ -3,6 +3,7 @@ package bind
import ( import (
"encoding/xml" "encoding/xml"
"fmt" "fmt"
"math"
"net" "net"
"net/http" "net/http"
"net/url" "net/url"
@ -27,15 +28,15 @@ type v3Memory struct {
// Omitted nodes: references, maxinuse, blocksize, pools, hiwater, lowater // Omitted nodes: references, maxinuse, blocksize, pools, hiwater, lowater
ID string `xml:"id"` ID string `xml:"id"`
Name string `xml:"name"` Name string `xml:"name"`
Total int64 `xml:"total"` Total uint64 `xml:"total"`
InUse int64 `xml:"inuse"` InUse uint64 `xml:"inuse"`
} `xml:"contexts>context"` } `xml:"contexts>context"`
Summary struct { Summary struct {
TotalUse int64 TotalUse uint64
InUse int64 InUse uint64
BlockSize int64 BlockSize uint64
ContextSize int64 ContextSize uint64
Lost int64 Lost uint64
} `xml:"summary"` } `xml:"summary"`
} }
@ -53,7 +54,7 @@ type v3View struct {
Name string `xml:"name,attr"` Name string `xml:"name,attr"`
RRSets []struct { RRSets []struct {
Name string `xml:"name"` Name string `xml:"name"`
Value int64 `xml:"counter"` Value uint64 `xml:"counter"`
} `xml:"rrset"` } `xml:"rrset"`
} `xml:"cache"` } `xml:"cache"`
} }
@ -63,7 +64,7 @@ type v3CounterGroup struct {
Type string `xml:"type,attr"` Type string `xml:"type,attr"`
Counters []struct { Counters []struct {
Name string `xml:"name,attr"` Name string `xml:"name,attr"`
Value int64 `xml:",chardata"` Value uint64 `xml:",chardata"`
} `xml:"counter"` } `xml:"counter"`
} }
@ -83,8 +84,15 @@ func (b *Bind) addStatsXMLv3(stats v3Stats, acc telegraf.Accumulator, hostPort s
} }
tags := map[string]string{"url": hostPort, "source": host, "port": port, "type": cg.Type} tags := map[string]string{"url": hostPort, "source": host, "port": port, "type": cg.Type}
var v interface{} = c.Value
grouper.Add("bind_counter", tags, ts, c.Name, 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)
} }
} }
@ -96,6 +104,7 @@ func (b *Bind) addStatsXMLv3(stats v3Stats, acc telegraf.Accumulator, hostPort s
"context_size": stats.Memory.Summary.ContextSize, "context_size": stats.Memory.Summary.ContextSize,
"lost": stats.Memory.Summary.Lost, "lost": stats.Memory.Summary.Lost,
} }
b.postProcessFields(fields)
acc.AddGauge("bind_memory", fields, map[string]string{"url": hostPort, "source": host, "port": port}) acc.AddGauge("bind_memory", fields, map[string]string{"url": hostPort, "source": host, "port": port})
// Detailed, per-context memory stats // Detailed, per-context memory stats
@ -104,6 +113,7 @@ func (b *Bind) addStatsXMLv3(stats v3Stats, acc telegraf.Accumulator, hostPort s
tags := map[string]string{"url": hostPort, "source": host, "port": port, "id": c.ID, "name": c.Name} 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} fields := map[string]interface{}{"total": c.Total, "in_use": c.InUse}
b.postProcessFields(fields)
acc.AddGauge("bind_memory_context", fields, tags) acc.AddGauge("bind_memory_context", fields, tags)
} }
} }
@ -120,8 +130,15 @@ func (b *Bind) addStatsXMLv3(stats v3Stats, acc telegraf.Accumulator, hostPort s
"view": v.Name, "view": v.Name,
"type": cg.Type, "type": cg.Type,
} }
var v interface{} = c.Value
grouper.Add("bind_counter", tags, ts, c.Name, 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)
} }
} }
} }
@ -170,3 +187,18 @@ func (b *Bind) readStatsXMLv3(addr *url.URL, acc telegraf.Accumulator) error {
b.addStatsXMLv3(stats, acc, addr.Host) b.addStatsXMLv3(stats, acc, addr.Host)
return nil 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)
}
}
}
}