Add Prometheus http handler for metrics

Metrics are: connection counts, active IP addresses, DNS addresses,
FastDP flow metrics, connection termination count
This commit is contained in:
Bryan Boreham committed 2016-10-20 16:25:16 +01:00
1 parent 00c86fed42
commit b8d619dde7
11 files changed
+170 -1

No files matched your search

+21
View File
@@ -82,3 +82,24 @@
[submodule "vendor/github.com/weaveworks/docker"]
path = vendor/github.com/weaveworks/docker
url = https://github.com/weaveworks/docker
[submodule "vendor/github.com/beorn7/perks"]
path = vendor/github.com/beorn7/perks
url = https://github.com/beorn7/perks
[submodule "vendor/github.com/prometheus/procfs"]
path = vendor/github.com/prometheus/procfs
url = https://github.com/prometheus/procfs
[submodule "vendor/github.com/prometheus/client_golang"]
path = vendor/github.com/prometheus/client_golang
url = https://github.com/prometheus/client_golang
[submodule "vendor/github.com/prometheus/client_model"]
path = vendor/github.com/prometheus/client_model
url = https://github.com/prometheus/client_model
[submodule "vendor/github.com/prometheus/common"]
path = vendor/github.com/prometheus/common
url = https://github.com/prometheus/common
[submodule "vendor/github.com/golang/protobuf"]
path = vendor/github.com/golang/protobuf
url = https://github.com/golang/protobuf
[submodule "vendor/github.com/matttproud/golang_protobuf_extensions"]
path = vendor/github.com/matttproud/golang_protobuf_extensions
url = https://github.com/matttproud/golang_protobuf_extensions
+12
View File
@@ -121,6 +121,16 @@ func countDNSEntries(entries []nameserver.EntryStatus) int {
return count
}
func countDNSEntriesForPeer(peername string, entries []nameserver.EntryStatus) int {
count := 0
for _, entry := range entries {
if entry.Tombstone == 0 && entry.Origin == peername {
count++
}
}
return count
}
// Print counts in a specified order
func printCounts(counts map[string]int, keys []string) string {
var stringCounts []string
@@ -322,4 +332,6 @@ func HandleHTTP(muxRouter *mux.Router, version string, router *weave.NetworkRout
defHandler("/status/peers", peersTemplate)
defHandler("/status/dns", dnsEntriesTemplate)
defHandler("/status/ipam", ipamTemplate)
muxRouter.Methods("GET").Path("/metrics").Handler(metricsHandler(router, allocator, ns))
}
+129
View File
@@ -0,0 +1,129 @@
package main
import (
"net/http"
"os"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/weaveworks/weave/ipam"
"github.com/weaveworks/weave/nameserver"
"github.com/weaveworks/weave/net/address"
weave "github.com/weaveworks/weave/router"
)
func metricsHandler(router *weave.NetworkRouter, allocator *ipam.Allocator, ns *nameserver.Nameserver, dnsserver *nameserver.DNSServer) http.Handler {
reg := prometheus.NewRegistry()
reg.MustRegister(prometheus.NewProcessCollector(os.Getpid(), ""))
reg.MustRegister(newMetrics(router, allocator, ns, dnsserver))
return promhttp.HandlerFor(reg, promhttp.HandlerOpts{})
}
type collector struct {
router *weave.NetworkRouter
allocator *ipam.Allocator
ns *nameserver.Nameserver
dnsserver *nameserver.DNSServer
}
type metric struct {
*prometheus.Desc
Collect func(WeaveStatus, *prometheus.Desc, chan<- prometheus.Metric)
}
func desc(fqName, help string, variableLabels ...string) *prometheus.Desc {
return prometheus.NewDesc(fqName, help, variableLabels, prometheus.Labels{})
}
func intGauge(desc *prometheus.Desc, val int, labels ...string) prometheus.Metric {
return prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, float64(val), labels...)
}
func uint64Counter(desc *prometheus.Desc, val uint64, labels ...string) prometheus.Metric {
return prometheus.MustNewConstMetric(desc, prometheus.CounterValue, float64(val), labels...)
}
var metrics []metric = []metric{
{desc("weave_connections", "Number of peer-to-peer connections.", "state"),
func(s WeaveStatus, desc *prometheus.Desc, ch chan<- prometheus.Metric) {
established := 0
for _, conn := range s.Router.Connections {
if conn.State == "established" {
established++
}
}
ch <- intGauge(desc, len(s.Router.Connections)-established, "non-established")
ch <- intGauge(desc, established, "established")
}},
{desc("weave_connection_termination_count", "Number of peer-to-peer connections terminated."),
func(s WeaveStatus, desc *prometheus.Desc, ch chan<- prometheus.Metric) {
ch <- uint64Counter(desc, uint64(s.Router.TerminationCount))
}},
{desc("weave_ips", "Number of IP addresses.", "state"),
func(s WeaveStatus, desc *prometheus.Desc, ch chan<- prometheus.Metric) {
ch <- intGauge(desc, s.IPAM.RangeNumIPs, "total")
ch <- intGauge(desc, s.IPAM.ActiveIPs, "local-used")
}},
{desc("weave_dns_entries", "Number of DNS entries.", "state"),
func(s WeaveStatus, desc *prometheus.Desc, ch chan<- prometheus.Metric) {
ch <- intGauge(desc, countDNSEntries(s.DNS.Entries), "total")
ch <- intGauge(desc, countDNSEntriesForPeer(s.Router.Name, s.DNS.Entries), "local")
}},
{desc("weave_flows", "Number of FastDP flows."),
func(s WeaveStatus, desc *prometheus.Desc, ch chan<- prometheus.Metric) {
if metrics := fastDPMetrics(s); metrics != nil {
ch <- intGauge(desc, metrics.Flows)
}
}},
{desc("weave_packets_total", "Number of packets transferred.", "flow"),
func(s WeaveStatus, desc *prometheus.Desc, ch chan<- prometheus.Metric) {
if metrics := fastDPMetrics(s); metrics != nil {
ch <- uint64Counter(desc, metrics.TotalPackets, "total")
}
}},
{desc("weave_bytes_total", "Number of bytes transferred.", "flow"),
func(s WeaveStatus, desc *prometheus.Desc, ch chan<- prometheus.Metric) {
if metrics := fastDPMetrics(s); metrics != nil {
ch <- uint64Counter(desc, metrics.TotalBytes, "total")
}
}},
}
func fastDPMetrics(s WeaveStatus) *weave.FastDPMetrics {
if reporter, ok := s.Router.OverlayDiagnostics.(weave.MetricsReporter); ok {
if metrics := reporter.Metrics(); metrics != nil {
if fastdpMetrics, ok := metrics.(*weave.FastDPMetrics); ok {
return fastdpMetrics
}
}
}
return nil
}
func newMetrics(router *weave.NetworkRouter, allocator *ipam.Allocator, ns *nameserver.Nameserver, dnsserver *nameserver.DNSServer) *collector {
return &collector{
router: router,
allocator: allocator,
ns: ns,
dnsserver: dnsserver,
}
}
func (m *collector) Collect(ch chan<- prometheus.Metric) {
status := WeaveStatus{"", nil,
weave.NewNetworkRouterStatus(m.router),
ipam.NewStatus(m.allocator, address.CIDR{}),
nameserver.NewStatus(m.ns, m.dnsserver)}
for _, metric := range metrics {
metric.Collect(status, metric.Desc, ch)
}
}
func (m *collector) Describe(ch chan<- *prometheus.Desc) {
for _, metric := range metrics {
ch <- metric.Desc
}
}
Generated Vendored Submodule
+1
Generated Vendored Submodule
+1