Build namespace and ingress class as label

This commit is contained in:
Giancarlo Rubio 2017-04-04 14:32:08 +02:00
parent c21f7ce666
commit 197acf0f2b
2 changed files with 104 additions and 111 deletions

View file

@ -17,8 +17,6 @@ limitations under the License.
package collector package collector
import ( import (
"fmt"
"github.com/golang/glog" "github.com/golang/glog"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
@ -29,6 +27,8 @@ type (
ngxHealthPort int ngxHealthPort int
ngxVtsPath string ngxVtsPath string
data *nginxStatusData data *nginxStatusData
watchNamespace string
ingressClass string
} }
nginxStatusData struct { nginxStatusData struct {
@ -42,62 +42,52 @@ type (
} }
) )
func buildNS(namespace, class string) string {
if namespace == "" {
namespace = "all"
}
if class == "" {
class = "all"
}
return fmt.Sprintf("%v_%v", namespace, class)
}
// NewNginxStatus returns a new prometheus collector the default nginx status module // NewNginxStatus returns a new prometheus collector the default nginx status module
func NewNginxStatus(namespace, class string, ngxHealthPort int, ngxVtsPath string) Stopable { func NewNginxStatus(watchNamespace, ingressClass string, ngxHealthPort int, ngxVtsPath string) Stopable {
p := nginxStatusCollector{ p := nginxStatusCollector{
scrapeChan: make(chan scrapeRequest), scrapeChan: make(chan scrapeRequest),
ngxHealthPort: ngxHealthPort, ngxHealthPort: ngxHealthPort,
ngxVtsPath: ngxVtsPath, ngxVtsPath: ngxVtsPath,
watchNamespace: watchNamespace,
ingressClass: ingressClass,
} }
ns := buildNS(namespace, class)
p.data = &nginxStatusData{ p.data = &nginxStatusData{
active: prometheus.NewDesc( active: prometheus.NewDesc(
prometheus.BuildFQName(system, ns, "active_connections"), prometheus.BuildFQName(ns, "", "active_connections"),
"total number of active connections", "total number of active connections",
nil, nil), []string{"ingress_class", "namespace"}, nil),
accepted: prometheus.NewDesc( accepted: prometheus.NewDesc(
prometheus.BuildFQName(system, ns, "accepted_connections"), prometheus.BuildFQName(ns, "", "accepted_connections"),
"total number of accepted client connections", "total number of accepted client connections",
nil, nil), []string{"ingress_class", "namespace"}, nil),
handled: prometheus.NewDesc( handled: prometheus.NewDesc(
prometheus.BuildFQName(system, ns, "handled_connections"), prometheus.BuildFQName(ns, "", "handled_connections"),
"total number of handled connections", "total number of handled connections",
nil, nil), []string{"ingress_class", "namespace"}, nil),
requests: prometheus.NewDesc( requests: prometheus.NewDesc(
prometheus.BuildFQName(system, ns, "total_requests"), prometheus.BuildFQName(ns, "", "total_requests"),
"total number of client requests", "total number of client requests",
nil, nil), []string{"ingress_class", "namespace"}, nil),
reading: prometheus.NewDesc( reading: prometheus.NewDesc(
prometheus.BuildFQName(system, ns, "current_reading_connections"), prometheus.BuildFQName(ns, "", "current_reading_connections"),
"current number of connections where nginx is reading the request header", "current number of connections where nginx is reading the request header",
nil, nil), []string{"ingress_class", "namespace"}, nil),
writing: prometheus.NewDesc( writing: prometheus.NewDesc(
prometheus.BuildFQName(system, ns, "current_writing_connections"), prometheus.BuildFQName(ns, "", "current_writing_connections"),
"current number of connections where nginx is writing the response back to the client", "current number of connections where nginx is writing the response back to the client",
nil, nil), []string{"ingress_class", "namespace"}, nil),
waiting: prometheus.NewDesc( waiting: prometheus.NewDesc(
prometheus.BuildFQName(system, ns, "current_waiting_connections"), prometheus.BuildFQName(ns, "", "current_waiting_connections"),
"current number of idle client connections waiting for a request", "current number of idle client connections waiting for a request",
nil, nil), []string{"ingress_class", "namespace"}, nil),
} }
go p.start() go p.start()
@ -144,17 +134,17 @@ func (p nginxStatusCollector) scrape(ch chan<- prometheus.Metric) {
} }
ch <- prometheus.MustNewConstMetric(p.data.active, ch <- prometheus.MustNewConstMetric(p.data.active,
prometheus.GaugeValue, float64(s.Active)) prometheus.GaugeValue, float64(s.Active), p.ingressClass, p.watchNamespace)
ch <- prometheus.MustNewConstMetric(p.data.accepted, ch <- prometheus.MustNewConstMetric(p.data.accepted,
prometheus.GaugeValue, float64(s.Accepted)) prometheus.GaugeValue, float64(s.Accepted), p.ingressClass, p.watchNamespace)
ch <- prometheus.MustNewConstMetric(p.data.handled, ch <- prometheus.MustNewConstMetric(p.data.handled,
prometheus.GaugeValue, float64(s.Handled)) prometheus.GaugeValue, float64(s.Handled), p.ingressClass, p.watchNamespace)
ch <- prometheus.MustNewConstMetric(p.data.requests, ch <- prometheus.MustNewConstMetric(p.data.requests,
prometheus.GaugeValue, float64(s.Requests)) prometheus.GaugeValue, float64(s.Requests), p.ingressClass, p.watchNamespace)
ch <- prometheus.MustNewConstMetric(p.data.reading, ch <- prometheus.MustNewConstMetric(p.data.reading,
prometheus.GaugeValue, float64(s.Reading)) prometheus.GaugeValue, float64(s.Reading), p.ingressClass, p.watchNamespace)
ch <- prometheus.MustNewConstMetric(p.data.writing, ch <- prometheus.MustNewConstMetric(p.data.writing,
prometheus.GaugeValue, float64(s.Writing)) prometheus.GaugeValue, float64(s.Writing), p.ingressClass, p.watchNamespace)
ch <- prometheus.MustNewConstMetric(p.data.waiting, ch <- prometheus.MustNewConstMetric(p.data.waiting,
prometheus.GaugeValue, float64(s.Waiting)) prometheus.GaugeValue, float64(s.Waiting), p.ingressClass, p.watchNamespace)
} }

View file

@ -23,7 +23,7 @@ import (
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
const system = "nginx" const ns = "nginx"
type ( type (
vtsCollector struct { vtsCollector struct {
@ -31,6 +31,8 @@ type (
ngxHealthPort int ngxHealthPort int
ngxVtsPath string ngxVtsPath string
data *vtsData data *vtsData
watchNamespace string
ingressClass string
} }
vtsData struct { vtsData struct {
@ -55,100 +57,101 @@ type (
) )
// NewNGINXVTSCollector returns a new prometheus collector for the VTS module // NewNGINXVTSCollector returns a new prometheus collector for the VTS module
func NewNGINXVTSCollector(namespace, class string, ngxHealthPort int, ngxVtsPath string) Stopable { func NewNGINXVTSCollector(watchNamespace, ingressClass string, ngxHealthPort int, ngxVtsPath string) Stopable {
p := vtsCollector{ p := vtsCollector{
scrapeChan: make(chan scrapeRequest), scrapeChan: make(chan scrapeRequest),
ngxHealthPort: ngxHealthPort, ngxHealthPort: ngxHealthPort,
ngxVtsPath: ngxVtsPath, ngxVtsPath: ngxVtsPath,
watchNamespace: watchNamespace,
ingressClass: ingressClass,
} }
ns := buildNS(namespace, class)
p.data = &vtsData{ p.data = &vtsData{
bytes: prometheus.NewDesc( bytes: prometheus.NewDesc(
prometheus.BuildFQName(system, ns, "bytes_total"), prometheus.BuildFQName(ns, "", "bytes_total"),
"Nginx bytes count", "Nginx bytes count",
[]string{"server_zone", "direction"}, nil), []string{"ingress_class", "namespace", "server_zone", "direction"}, nil),
cache: prometheus.NewDesc( cache: prometheus.NewDesc(
prometheus.BuildFQName(system, ns, "cache_total"), prometheus.BuildFQName(ns, "", "cache_total"),
"Nginx cache count", "Nginx cache count",
[]string{"server_zone", "type"}, nil), []string{"ingress_class", "namespace", "server_zone", "type"}, nil),
connections: prometheus.NewDesc( connections: prometheus.NewDesc(
prometheus.BuildFQName(system, ns, "connections_total"), prometheus.BuildFQName(ns, "", "connections_total"),
"Nginx connections count", "Nginx connections count",
[]string{"type"}, nil), []string{"ingress_class", "namespace", "type"}, nil),
response: prometheus.NewDesc( response: prometheus.NewDesc(
prometheus.BuildFQName(system, ns, "responses_total"), prometheus.BuildFQName(ns, "", "responses_total"),
"The number of responses with status codes 1xx, 2xx, 3xx, 4xx, and 5xx.", "The number of responses with status codes 1xx, 2xx, 3xx, 4xx, and 5xx.",
[]string{"server_zone", "status_code"}, nil), []string{"ingress_class", "namespace", "server_zone", "status_code"}, nil),
request: prometheus.NewDesc( request: prometheus.NewDesc(
prometheus.BuildFQName(system, ns, "requests_total"), prometheus.BuildFQName(ns, "", "requests_total"),
"The total number of requested client connections.", "The total number of requested client connections.",
[]string{"server_zone"}, nil), []string{"ingress_class", "namespace", "server_zone"}, nil),
filterZoneBytes: prometheus.NewDesc( filterZoneBytes: prometheus.NewDesc(
prometheus.BuildFQName(system, ns, "filterzone_bytes_total"), prometheus.BuildFQName(ns, "", "filterzone_bytes_total"),
"Nginx bytes count", "Nginx bytes count",
[]string{"server_zone", "country", "direction"}, nil), []string{"ingress_class", "namespace", "server_zone", "country", "direction"}, nil),
filterZoneResponse: prometheus.NewDesc( filterZoneResponse: prometheus.NewDesc(
prometheus.BuildFQName(system, ns, "filterzone_responses_total"), prometheus.BuildFQName(ns, "", "filterzone_responses_total"),
"The number of responses with status codes 1xx, 2xx, 3xx, 4xx, and 5xx.", "The number of responses with status codes 1xx, 2xx, 3xx, 4xx, and 5xx.",
[]string{"server_zone", "country", "status_code"}, nil), []string{"ingress_class", "namespace", "server_zone", "country", "status_code"}, nil),
filterZoneCache: prometheus.NewDesc( filterZoneCache: prometheus.NewDesc(
prometheus.BuildFQName(system, ns, "filterzone_cache_total"), prometheus.BuildFQName(ns, "", "filterzone_cache_total"),
"Nginx cache count", "Nginx cache count",
[]string{"server_zone", "country", "type"}, nil), []string{"ingress_class", "namespace", "server_zone", "country", "type"}, nil),
upstreamBackup: prometheus.NewDesc( upstreamBackup: prometheus.NewDesc(
prometheus.BuildFQName(system, ns, "upstream_backup"), prometheus.BuildFQName(ns, "", "upstream_backup"),
"Current backup setting of the server.", "Current backup setting of the server.",
[]string{"upstream", "server"}, nil), []string{"ingress_class", "namespace", "upstream", "server"}, nil),
upstreamBytes: prometheus.NewDesc( upstreamBytes: prometheus.NewDesc(
prometheus.BuildFQName(system, ns, "upstream_bytes_total"), prometheus.BuildFQName(ns, "", "upstream_bytes_total"),
"The total number of bytes sent to this server.", "The total number of bytes sent to this server.",
[]string{"upstream", "server", "direction"}, nil), []string{"ingress_class", "namespace", "upstream", "server", "direction"}, nil),
upstreamDown: prometheus.NewDesc( upstreamDown: prometheus.NewDesc(
prometheus.BuildFQName(system, ns, "vts_upstream_down_total"), prometheus.BuildFQName(ns, "", "vts_upstream_down_total"),
"Current down setting of the server.", "Current down setting of the server.",
[]string{"upstream", "server"}, nil), []string{"ingress_class", "namespace", "upstream", "server"}, nil),
upstreamFailTimeout: prometheus.NewDesc( upstreamFailTimeout: prometheus.NewDesc(
prometheus.BuildFQName(system, ns, "upstream_fail_timeout"), prometheus.BuildFQName(ns, "", "upstream_fail_timeout"),
"Current fail_timeout setting of the server.", "Current fail_timeout setting of the server.",
[]string{"upstream", "server"}, nil), []string{"ingress_class", "namespace", "upstream", "server"}, nil),
upstreamMaxFails: prometheus.NewDesc( upstreamMaxFails: prometheus.NewDesc(
prometheus.BuildFQName(system, ns, "upstream_maxfails"), prometheus.BuildFQName(ns, "", "upstream_maxfails"),
"Current max_fails setting of the server.", "Current max_fails setting of the server.",
[]string{"upstream", "server"}, nil), []string{"ingress_class", "namespace", "upstream", "server"}, nil),
upstreamResponses: prometheus.NewDesc( upstreamResponses: prometheus.NewDesc(
prometheus.BuildFQName(system, ns, "upstream_responses_total"), prometheus.BuildFQName(ns, "", "upstream_responses_total"),
"The number of upstream responses with status codes 1xx, 2xx, 3xx, 4xx, and 5xx.", "The number of upstream responses with status codes 1xx, 2xx, 3xx, 4xx, and 5xx.",
[]string{"upstream", "server", "status_code"}, nil), []string{"ingress_class", "namespace", "upstream", "server", "status_code"}, nil),
upstreamRequest: prometheus.NewDesc( upstreamRequest: prometheus.NewDesc(
prometheus.BuildFQName(system, ns, "upstream_requests_total"), prometheus.BuildFQName(ns, "", "upstream_requests_total"),
"The total number of client connections forwarded to this server.", "The total number of client connections forwarded to this server.",
[]string{"upstream", "server"}, nil), []string{"ingress_class", "namespace", "upstream", "server"}, nil),
upstreamResponseMsec: prometheus.NewDesc( upstreamResponseMsec: prometheus.NewDesc(
prometheus.BuildFQName(system, ns, "upstream_response_msecs_avg"), prometheus.BuildFQName(ns, "", "upstream_response_msecs_avg"),
"The average of only upstream response processing times in milliseconds.", "The average of only upstream response processing times in milliseconds.",
[]string{"upstream", "server"}, nil), []string{"ingress_class", "namespace", "upstream", "server"}, nil),
upstreamWeight: prometheus.NewDesc( upstreamWeight: prometheus.NewDesc(
prometheus.BuildFQName(system, ns, "upstream_weight"), prometheus.BuildFQName(ns, "", "upstream_weight"),
"Current upstream weight setting of the server.", "Current upstream weight setting of the server.",
[]string{"upstream", "server"}, nil), []string{"ingress_class", "namespace", "upstream", "server"}, nil),
} }
go p.start() go p.start()
@ -204,54 +207,54 @@ func (p vtsCollector) scrapeVts(ch chan<- prometheus.Metric) {
return return
} }
reflectMetrics(&nginxMetrics.Connections, p.data.connections, ch) reflectMetrics(&nginxMetrics.Connections, p.data.connections, ch, p.ingressClass, p.watchNamespace)
for name, zones := range nginxMetrics.UpstreamZones { for name, zones := range nginxMetrics.UpstreamZones {
for pos, value := range zones { for pos, value := range zones {
reflectMetrics(&zones[pos].Responses, p.data.upstreamResponses, ch, name, value.Server) reflectMetrics(&zones[pos].Responses, p.data.upstreamResponses, ch, p.ingressClass, p.watchNamespace, name, value.Server)
ch <- prometheus.MustNewConstMetric(p.data.upstreamRequest, ch <- prometheus.MustNewConstMetric(p.data.upstreamRequest,
prometheus.CounterValue, zones[pos].RequestCounter, name, value.Server) prometheus.CounterValue, zones[pos].RequestCounter, p.ingressClass, p.watchNamespace, name, value.Server)
ch <- prometheus.MustNewConstMetric(p.data.upstreamDown, ch <- prometheus.MustNewConstMetric(p.data.upstreamDown,
prometheus.CounterValue, float64(zones[pos].Down), name, value.Server) prometheus.CounterValue, float64(zones[pos].Down), p.ingressClass, p.watchNamespace, name, value.Server)
ch <- prometheus.MustNewConstMetric(p.data.upstreamWeight, ch <- prometheus.MustNewConstMetric(p.data.upstreamWeight,
prometheus.CounterValue, zones[pos].Weight, name, value.Server) prometheus.CounterValue, zones[pos].Weight, p.ingressClass, p.watchNamespace, name, value.Server)
ch <- prometheus.MustNewConstMetric(p.data.upstreamResponseMsec, ch <- prometheus.MustNewConstMetric(p.data.upstreamResponseMsec,
prometheus.CounterValue, zones[pos].ResponseMsec, name, value.Server) prometheus.CounterValue, zones[pos].ResponseMsec, p.ingressClass, p.watchNamespace, name, value.Server)
ch <- prometheus.MustNewConstMetric(p.data.upstreamBackup, ch <- prometheus.MustNewConstMetric(p.data.upstreamBackup,
prometheus.CounterValue, float64(zones[pos].Backup), name, value.Server) prometheus.CounterValue, float64(zones[pos].Backup), p.ingressClass, p.watchNamespace, name, value.Server)
ch <- prometheus.MustNewConstMetric(p.data.upstreamFailTimeout, ch <- prometheus.MustNewConstMetric(p.data.upstreamFailTimeout,
prometheus.CounterValue, zones[pos].FailTimeout, name, value.Server) prometheus.CounterValue, zones[pos].FailTimeout, p.ingressClass, p.watchNamespace, name, value.Server)
ch <- prometheus.MustNewConstMetric(p.data.upstreamMaxFails, ch <- prometheus.MustNewConstMetric(p.data.upstreamMaxFails,
prometheus.CounterValue, zones[pos].MaxFails, name, value.Server) prometheus.CounterValue, zones[pos].MaxFails, p.ingressClass, p.watchNamespace, name, value.Server)
ch <- prometheus.MustNewConstMetric(p.data.upstreamBytes, ch <- prometheus.MustNewConstMetric(p.data.upstreamBytes,
prometheus.CounterValue, zones[pos].InBytes, name, value.Server, "in") prometheus.CounterValue, zones[pos].InBytes, p.ingressClass, p.watchNamespace, name, value.Server, "in")
ch <- prometheus.MustNewConstMetric(p.data.upstreamBytes, ch <- prometheus.MustNewConstMetric(p.data.upstreamBytes,
prometheus.CounterValue, zones[pos].OutBytes, name, value.Server, "out") prometheus.CounterValue, zones[pos].OutBytes, p.ingressClass, p.watchNamespace, name, value.Server, "out")
} }
} }
for name, zone := range nginxMetrics.ServerZones { for name, zone := range nginxMetrics.ServerZones {
reflectMetrics(&zone.Responses, p.data.response, ch, name) reflectMetrics(&zone.Responses, p.data.response, ch, p.ingressClass, p.watchNamespace, name)
reflectMetrics(&zone.Cache, p.data.cache, ch, name) reflectMetrics(&zone.Cache, p.data.cache, ch, p.ingressClass, p.watchNamespace, name)
ch <- prometheus.MustNewConstMetric(p.data.request, ch <- prometheus.MustNewConstMetric(p.data.request,
prometheus.CounterValue, zone.RequestCounter, name) prometheus.CounterValue, zone.RequestCounter, p.ingressClass, p.watchNamespace, name)
ch <- prometheus.MustNewConstMetric(p.data.bytes, ch <- prometheus.MustNewConstMetric(p.data.bytes,
prometheus.CounterValue, zone.InBytes, name, "in") prometheus.CounterValue, zone.InBytes, p.ingressClass, p.watchNamespace, name, "in")
ch <- prometheus.MustNewConstMetric(p.data.bytes, ch <- prometheus.MustNewConstMetric(p.data.bytes,
prometheus.CounterValue, zone.OutBytes, name, "out") prometheus.CounterValue, zone.OutBytes, p.ingressClass, p.watchNamespace, name, "out")
} }
for serverZone, countries := range nginxMetrics.FilterZones { for serverZone, countries := range nginxMetrics.FilterZones {
for country, zone := range countries { for country, zone := range countries {
reflectMetrics(&zone.Responses, p.data.filterZoneResponse, ch, serverZone, country) reflectMetrics(&zone.Responses, p.data.filterZoneResponse, ch, p.ingressClass, p.watchNamespace, serverZone, country)
reflectMetrics(&zone.Cache, p.data.filterZoneCache, ch, serverZone, country) reflectMetrics(&zone.Cache, p.data.filterZoneCache, ch, p.ingressClass, p.watchNamespace, serverZone, country)
ch <- prometheus.MustNewConstMetric(p.data.filterZoneBytes, ch <- prometheus.MustNewConstMetric(p.data.filterZoneBytes,
prometheus.CounterValue, float64(zone.InBytes), serverZone, country, "in") prometheus.CounterValue, float64(zone.InBytes), p.ingressClass, p.watchNamespace, serverZone, country, "in")
ch <- prometheus.MustNewConstMetric(p.data.filterZoneBytes, ch <- prometheus.MustNewConstMetric(p.data.filterZoneBytes,
prometheus.CounterValue, float64(zone.OutBytes), serverZone, country, "out") prometheus.CounterValue, float64(zone.OutBytes), p.ingressClass, p.watchNamespace, serverZone, country, "out")
} }
} }
} }