1
0
mirror of https://github.com/prometheus-community/bind_exporter.git synced 2025-07-28 23:01:57 +03:00

Extract bind statistics parsing in sub-packages

This prepares the addition of statistics v3 parsing.
This commit is contained in:
Tobias Schmidt
2016-09-09 20:14:14 -04:00
parent 1a41fed389
commit e141d9013a
7 changed files with 3573 additions and 2955 deletions

60
bind/client.go Normal file
View File

@ -0,0 +1,60 @@
package bind
// Client queries the BIND API, parses the response and returns stats in a
// generic format.
type Client interface {
Stats() (Statistics, error)
}
// Common bind field types.
const (
QryRTT = "QryRTT"
)
// Statistics is a generic representation of BIND statistics.
type Statistics struct {
Server struct {
IncomingQueries []Stat
IncomingRequests []Stat
NSStats []Stat
}
Views []View
TaskManager TaskManager
}
// View represents a statistics for a single BIND view.
type View struct {
Name string
Cache []Stat
ResolverStats []Stat
ResolverQueries []Stat
}
// Stat represents a single counter value.
type Stat struct {
Name string
Counter uint
}
// Task represents a single running task.
type Task struct {
ID string `xml:"id"`
Name string `xml:"name"`
Quantum uint `xml:"quantum"`
References uint `xml:"references"`
State string `xml:"state"`
}
// TaskManager contains information about all running tasks.
type TaskManager struct {
Tasks []Task `xml:"tasks>task"`
ThreadModel ThreadModel `xml:"thread-model"`
}
// ThreadModel contains task and worker information.
type ThreadModel struct {
Type string `xml:"type"`
WorkerThreads uint `xml:"worker-threads"`
DefaultQuantum uint `xml:"default-quantum"`
TasksRunning uint `xml:"tasks-running"`
}

71
bind/v2/struct.go Normal file
View File

@ -0,0 +1,71 @@
package v2
import (
"encoding/xml"
"github.com/digitalocean/bind_exporter/bind"
)
type Zone struct {
Name string `xml:"name"`
Rdataclass string `xml:"rdataclass"`
Serial string `xml:"serial"`
}
type Stat struct {
Name string `xml:"name"`
Counter uint `xml:"counter"`
}
type View struct {
Name string `xml:"name"`
Cache []Stat `xml:"cache>rrset"`
Rdtype []Stat `xml:"rdtype"`
Resstat []Stat `xml:"resstat"`
Zones []Zone `xml:"zones>zone"`
}
//TODO expand
type Socket struct {
ID string `xml:"id"`
Name string `xml:"name"`
LocalAddress string `xml:"local-address"`
References uint `xml:"references"`
}
type Socketmgr struct {
References uint `xml:"references"`
Sockets []Socket `xml:"sockets>socket"`
}
type QueriesIn struct {
Rdtype []Stat `xml:"rdtype"`
}
type Requests struct {
Opcode []Stat `xml:"opcode"`
}
type Server struct {
Requests Requests `xml:"requests"`
QueriesIn QueriesIn `xml:"queries-in"`
NsStats []Stat `xml:"nsstat"`
SocketStats []Stat `xml:"socketstat"`
ZoneStats []Stat `xml:"zonestats"`
}
type Statistics struct {
Views []View `xml:"views>view"`
Socketmgr Socketmgr `xml:"socketmgr"`
Taskmgr bind.TaskManager `xml:"taskmgr"`
Server Server `xml:"server"`
Memory struct{} `xml:"memory"`
}
type Bind struct {
Statistics Statistics `xml:"statistics"`
}
type Isc struct {
XMLName xml.Name `xml:"isc"`
Bind Bind `xml:"bind"`
}

79
bind/v2/v2.go Normal file
View File

@ -0,0 +1,79 @@
package v2
import (
"encoding/xml"
"fmt"
"io/ioutil"
"net/http"
"github.com/digitalocean/bind_exporter/bind"
)
// Client implements bind.Client and can be used to query a BIND v2 API.
type Client struct {
url string
http *http.Client
}
// NewClient returns an initialized Client.
func NewClient(url string, c *http.Client) *Client {
return &Client{
url: url,
http: c,
}
}
// Stats implements bind.Stats.
func (c *Client) Stats() (bind.Statistics, error) {
s := bind.Statistics{}
resp, err := c.http.Get(c.url)
if err != nil {
return s, fmt.Errorf("error querying stats: %s", err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return s, fmt.Errorf("failed to read response: %s", err)
}
root := Isc{}
if err := xml.Unmarshal([]byte(body), &root); err != nil {
return s, fmt.Errorf("Failed to unmarshal XML response: %s", err)
}
stats := root.Bind.Statistics
for _, t := range stats.Server.QueriesIn.Rdtype {
s.Server.IncomingQueries = append(s.Server.IncomingQueries, stat(t))
}
for _, t := range stats.Server.Requests.Opcode {
s.Server.IncomingRequests = append(s.Server.IncomingRequests, stat(t))
}
for _, t := range stats.Server.NsStats {
s.Server.NSStats = append(s.Server.NSStats, stat(t))
}
for _, view := range stats.Views {
v := bind.View{Name: view.Name}
for _, t := range view.Cache {
v.Cache = append(v.Cache, stat(t))
}
for _, t := range view.Rdtype {
v.ResolverQueries = append(v.ResolverQueries, stat(t))
}
for _, t := range view.Resstat {
v.ResolverStats = append(v.ResolverStats, stat(t))
}
s.Views = append(s.Views, v)
}
s.TaskManager = stats.Taskmgr
return s, nil
}
func stat(s Stat) bind.Stat {
return bind.Stat{
Name: s.Name,
Counter: s.Counter,
}
}