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:
parent
5bc68c9ba7
commit
720b399467
@ -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...)
|
||||
}
|
46
bind/bind.go
46
bind/bind.go
@ -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"
|
||||
|
@ -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.
|
||||
|
@ -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()
|
||||
|
@ -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)),
|
||||
|
Loading…
x
Reference in New Issue
Block a user