1
0
mirror of https://github.com/prometheus-community/bind_exporter.git synced 2025-04-18 13:04:01 +03:00

Default to JSON statistics channel

This also drops support for "auto" determination of stats version, which
is too tightly coupled to the XML stats channel to easily support JSON
too. It is essentially redundant anyway, since the JSON stats channel is
supported and always present since BIND v9.10.0.

We also no longer unmarshal the memory or socketmgr nodes of the XML
stats, since we don't currently expose any metrics for these, and they
have been responsible for unmarshal errors in the past. Once we actually
_do_ expose metrics for them, they should be included in tests.

Signed-off-by: Daniel Swarbrick <daniel.swarbrick@gmail.com>
This commit is contained in:
Daniel Swarbrick 2023-04-14 20:25:57 +02:00
parent 5bc68c9ba7
commit 720b399467
No known key found for this signature in database
GPG Key ID: C346A9571DD986F5
5 changed files with 44 additions and 106 deletions

View File

@ -1,37 +0,0 @@
// Copyright 2020 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package auto
import (
"net/http"
"github.com/prometheus-community/bind_exporter/bind"
"github.com/prometheus-community/bind_exporter/bind/xml"
)
// Client is a client which automatically detects the statistics version of the
// BIND server and delegates the request to the correct versioned client.
type Client struct {
*bind.XMLClient
}
// NewClient returns an initialized Client.
func NewClient(url string, c *http.Client) *Client {
return &Client{XMLClient: bind.NewXMLClient(url, c)}
}
// Stats implements bind.Stats.
func (c *Client) Stats(g ...bind.StatisticGroup) (bind.Statistics, error) {
return (&xml.Client{XMLClient: c.XMLClient}).Stats(g...)
}

View File

@ -14,11 +14,6 @@
package bind
import (
"encoding/xml"
"fmt"
"net/http"
"net/url"
"path"
"time"
)
@ -28,47 +23,6 @@ type Client interface {
Stats(...StatisticGroup) (Statistics, error)
}
// XMLClient is a generic BIND API client to retrieve statistics in XML format.
type XMLClient struct {
url string
http *http.Client
}
// NewXMLClient returns an initialized XMLClient.
func NewXMLClient(url string, c *http.Client) *XMLClient {
return &XMLClient{
url: url,
http: c,
}
}
// Get queries the given path and stores the result in the value pointed to by
// v. The endpoint must return a valid XML representation which can be
// unmarshaled into the provided value.
func (c *XMLClient) Get(p string, v interface{}) error {
u, err := url.Parse(c.url)
if err != nil {
return fmt.Errorf("invalid URL %q: %s", c.url, err)
}
u.Path = path.Join(u.Path, p)
resp, err := c.http.Get(u.String())
if err != nil {
return fmt.Errorf("error querying stats: %s", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("unexpected status for %q: %s", u, resp.Status)
}
if err := xml.NewDecoder(resp.Body).Decode(v); err != nil {
return fmt.Errorf("failed to unmarshal XML response: %s", err)
}
return nil
}
const (
// QryRTT is the common prefix of query round-trip histogram counters.
QryRTT = "QryRTT"

View File

@ -14,7 +14,11 @@
package xml
import (
"encoding/xml"
"fmt"
"net/http"
"net/url"
"path"
"time"
"github.com/prometheus-community/bind_exporter/bind"
@ -40,11 +44,9 @@ const (
)
type Statistics struct {
Memory struct{} `xml:"memory"`
Server Server `xml:"server"`
Socketmgr struct{} `xml:"socketmgr"`
Taskmgr bind.TaskManager `xml:"taskmgr"`
Views []View `xml:"views>view"`
Server Server `xml:"server"`
Taskmgr bind.TaskManager `xml:"taskmgr"`
Views []View `xml:"views>view"`
}
type ZoneStatistics struct {
@ -84,14 +86,45 @@ type ZoneCounter struct {
Serial string `xml:"serial"`
}
// Client implements bind.Client and can be used to query a BIND v3 API.
// Client implements bind.Client and can be used to query a BIND XML v3 API.
type Client struct {
*bind.XMLClient
url string
http *http.Client
}
// NewClient returns an initialized Client.
func NewClient(url string, c *http.Client) *Client {
return &Client{XMLClient: bind.NewXMLClient(url, c)}
return &Client{
url: url,
http: c,
}
}
// Get queries the given path and stores the result in the value pointed to by
// v. The endpoint must return a valid XML representation which can be
// unmarshaled into the provided value.
func (c *Client) Get(p string, v interface{}) error {
u, err := url.Parse(c.url)
if err != nil {
return fmt.Errorf("invalid URL %q: %s", c.url, err)
}
u.Path = path.Join(u.Path, p)
resp, err := c.http.Get(u.String())
if err != nil {
return fmt.Errorf("error querying stats: %s", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("unexpected status %s", resp.Status)
}
if err := xml.NewDecoder(resp.Body).Decode(v); err != nil {
return fmt.Errorf("failed to unmarshal XML response: %s", err)
}
return nil
}
// Stats implements bind.Stats.

View File

@ -28,7 +28,6 @@ import (
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/prometheus-community/bind_exporter/bind"
"github.com/prometheus-community/bind_exporter/bind/auto"
"github.com/prometheus-community/bind_exporter/bind/json"
"github.com/prometheus-community/bind_exporter/bind/xml"
"github.com/prometheus/client_golang/prometheus"
@ -401,12 +400,10 @@ type Exporter struct {
func NewExporter(logger log.Logger, version, url string, timeout time.Duration, g []bind.StatisticGroup) *Exporter {
var c bind.Client
switch version {
case "json":
c = json.NewClient(url, &http.Client{Timeout: timeout})
case "xml", "xml.v3":
c = xml.NewClient(url, &http.Client{Timeout: timeout})
default:
c = auto.NewClient(url, &http.Client{Timeout: timeout})
c = json.NewClient(url, &http.Client{Timeout: timeout})
}
var cs []collectorConstructor
@ -535,8 +532,8 @@ func main() {
"Path to BIND's pid file to export process information",
).Default("/run/named/named.pid").String()
bindVersion = kingpin.Flag("bind.stats-version",
"BIND statistics version. Can be detected automatically.",
).Default("auto").Enum("json", "xml", "xml.v3", "auto")
"BIND statistics channel",
).Default("json").Enum("json", "xml", "xml.v3", "auto")
metricsPath = kingpin.Flag(
"web.telemetry-path", "Path under which to expose metrics",
).Default("/metrics").String()

View File

@ -90,15 +90,6 @@ func TestBindExporterV3Client(t *testing.T) {
}.run(t)
}
func TestBindExporterAutomaticClient(t *testing.T) {
bindExporterTest{
server: newV3Server(),
groups: []bind.StatisticGroup{bind.ServerStats},
version: "auto",
include: combine([]string{`bind_up 1`}, serverStats),
}.run(t)
}
func TestBindExporterBindFailure(t *testing.T) {
bindExporterTest{
server: httptest.NewServer(http.HandlerFunc(http.NotFound)),