Skip to content

Commit

Permalink
Cleanup collection of prometheus metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
aledbf committed Mar 10, 2017
1 parent 1d38e3a commit 7ba389c
Show file tree
Hide file tree
Showing 11 changed files with 639 additions and 476 deletions.
441 changes: 16 additions & 425 deletions controllers/nginx/pkg/cmd/controller/metrics.go

Large diffs are not rendered by default.

27 changes: 24 additions & 3 deletions controllers/nginx/pkg/cmd/controller/nginx.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,26 @@ import (

"k8s.io/kubernetes/pkg/api"

"strings"

"k8s.io/ingress/controllers/nginx/pkg/config"
ngx_template "k8s.io/ingress/controllers/nginx/pkg/template"
"k8s.io/ingress/controllers/nginx/pkg/version"
"k8s.io/ingress/core/pkg/ingress"
"k8s.io/ingress/core/pkg/ingress/defaults"
"k8s.io/ingress/core/pkg/net/ssl"
"strings"
)

type statusModule string

const (
ngxHealthPort = 18080
ngxHealthPath = "/healthz"
ngxStatusPath = "/internal_nginx_status"
ngxVtsPath = "/nginx_status/format/json"

defaultStatusModule statusModule = "default"
vtsStatusModule statusModule = "vts"
)

var (
Expand Down Expand Up @@ -108,6 +114,10 @@ type NGINXController struct {
storeLister ingress.StoreLister

binary string

cmdArgs []string

statusModule statusModule
}

// Start start a new NGINX master process running in foreground.
Expand Down Expand Up @@ -157,8 +167,17 @@ func (n *NGINXController) start(cmd *exec.Cmd, done chan error) {
done <- err
return
}

n.cmdArgs = cmd.Args

cfg := ngx_template.ReadConfig(n.configmap.Data)
n.setupMonitor(cmd.Args, cfg.EnableVtsStatus)
n.statusModule = defaultStatusModule
if cfg.EnableVtsStatus {
n.statusModule = vtsStatusModule
n.setupMonitor(vtsStatusModule)
} else {
n.setupMonitor(defaultStatusModule)
}

go func() {
done <- cmd.Wait()
Expand Down Expand Up @@ -315,7 +334,9 @@ func (n *NGINXController) OnUpdate(ingressCfg ingress.Configuration) ([]byte, er
}

cfg := ngx_template.ReadConfig(n.configmap.Data)
n.setupMonitor([]string{""}, cfg.EnableVtsStatus)

// we need to check if the status module configuration changed
n.setupMonitor()

// NGINX cannot resize the has tables used to store server names.
// For this reason we check if the defined size defined is correct
Expand Down
6 changes: 0 additions & 6 deletions controllers/nginx/pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,6 @@ type Configuration struct {
func NewDefault() Configuration {
cfg := Configuration{
ClientHeaderBufferSize: "1k",
DisableAccessLog: false,
DisableIpv6: false,
EnableDynamicTLSRecords: true,
ErrorLogLevel: errorLevel,
HTTP2MaxFieldSize: "4k",
Expand All @@ -286,10 +284,8 @@ func NewDefault() Configuration {
SSLSessionCacheSize: sslSessionCacheSize,
SSLSessionTickets: true,
SSLSessionTimeout: sslSessionTimeout,
UseProxyProtocol: false,
UseGzip: true,
WorkerProcesses: runtime.NumCPU(),
EnableVtsStatus: false,
VtsStatusZoneSize: "10m",
UseHTTP2: true,
Backend: defaults.Backend{
Expand All @@ -301,11 +297,9 @@ func NewDefault() Configuration {
ProxyCookieDomain: "off",
ProxyCookiePath: "off",
SSLRedirect: true,
ForceSSLRedirect: false,
CustomHTTPErrors: []int{},
WhitelistSourceRange: []string{},
SkipAccessLogURLs: []string{},
UsePortInRedirects: false,
},
}

Expand Down
130 changes: 130 additions & 0 deletions controllers/nginx/pkg/metric/collector/nginx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
Copyright 2017 The Kubernetes 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 collector

import (
"github.com/golang/glog"
"github.com/prometheus/client_golang/prometheus"
)

var (
activeDesc = prometheus.NewDesc(
"nginx_active_connections",
"total number of active connections",
nil, nil)

acceptedDesc = prometheus.NewDesc(
"nginx_accepted_connections",
"total number of accepted client connections",
nil, nil)

handledDesc = prometheus.NewDesc(
"nginx_handled_connections",
"total number of handled connections",
nil, nil)

requestsDesc = prometheus.NewDesc(
"nginx_total_requests",
"total number of client requests",
nil, nil)

readingDesc = prometheus.NewDesc(
"nginx_current_reading_connections",
"current number of connections where nginx is reading the request header",
nil, nil)

writingDesc = prometheus.NewDesc(
"nginx_current_writing_connections",
"current number of connections where nginx is writing the response back to the client",
nil, nil)

waitingDesc = prometheus.NewDesc(
"nginx_current_waiting_connections",
"current number of idle client connections waiting for a request",
nil, nil)
)

type (
nginxStatusCollector struct {
scrapeChan chan scrapeRequest
}
)

func NewNginxStatus() (prometheus.Collector, error) {
p := nginxStatusCollector{
scrapeChan: make(chan scrapeRequest),
}

go p.start()

return p, nil
}

// Describe implements prometheus.Collector.
func (p nginxStatusCollector) Describe(ch chan<- *prometheus.Desc) {
ch <- activeDesc
ch <- acceptedDesc
ch <- handledDesc
ch <- requestsDesc
ch <- readingDesc
ch <- writingDesc
ch <- waitingDesc
}

// Collect implements prometheus.Collector.
func (p nginxStatusCollector) Collect(ch chan<- prometheus.Metric) {
req := scrapeRequest{results: ch, done: make(chan struct{})}
p.scrapeChan <- req
<-req.done
}

func (p nginxStatusCollector) start() {
for req := range p.scrapeChan {
ch := req.results
p.scrape(ch)
req.done <- struct{}{}
}
}

func (p nginxStatusCollector) Stop() {
close(p.scrapeChan)
}

// nginxStatusCollector scrap the nginx status
func (p nginxStatusCollector) scrape(ch chan<- prometheus.Metric) {
s, err := getNginxStatus()
if err != nil {
glog.Warningf("unexpected error obtaining nginx status info: %v", err)
return
}

ch <- prometheus.MustNewConstMetric(activeDesc,
prometheus.GaugeValue, float64(s.Active))
ch <- prometheus.MustNewConstMetric(acceptedDesc,
prometheus.GaugeValue, float64(s.Accepted))
ch <- prometheus.MustNewConstMetric(handledDesc,
prometheus.GaugeValue, float64(s.Handled))
ch <- prometheus.MustNewConstMetric(requestsDesc,
prometheus.GaugeValue, float64(s.Requests))
ch <- prometheus.MustNewConstMetric(readingDesc,
prometheus.GaugeValue, float64(s.Reading))
ch <- prometheus.MustNewConstMetric(writingDesc,
prometheus.GaugeValue, float64(s.Writing))
ch <- prometheus.MustNewConstMetric(waitingDesc,
prometheus.GaugeValue, float64(s.Waiting))

}
157 changes: 157 additions & 0 deletions controllers/nginx/pkg/metric/collector/process.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/*
Copyright 2017 The Kubernetes 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 collector

import (
"path/filepath"

"github.com/golang/glog"
common "github.com/ncabatoff/process-exporter"
"github.com/ncabatoff/process-exporter/proc"
"github.com/prometheus/client_golang/prometheus"
)

type BinaryNameMatcher struct {
name string
args []string
}

func (em BinaryNameMatcher) MatchAndName(nacl common.NameAndCmdline) (bool, string) {
if len(nacl.Cmdline) == 0 {
return false, ""
}
cmd := filepath.Base(nacl.Cmdline[0])
return em.name == cmd, ""
}

var (
numprocsDesc = prometheus.NewDesc(
"nginx_num_procs",
"number of processes",
nil, nil)

cpuSecsDesc = prometheus.NewDesc(
"nginx_cpu_seconds_total",
"Cpu usage in seconds",
nil, nil)

readBytesDesc = prometheus.NewDesc(
"nginx_read_bytes_total",
"number of bytes read",
nil, nil)

writeBytesDesc = prometheus.NewDesc(
"nginx_write_bytes_total",
"number of bytes written",
nil, nil)

memResidentbytesDesc = prometheus.NewDesc(
"nginx_resident_memory_bytes",
"number of bytes of memory in use",
nil, nil)

memVirtualbytesDesc = prometheus.NewDesc(
"nginx_virtual_memory_bytes",
"number of bytes of memory in use",
nil, nil)

startTimeDesc = prometheus.NewDesc(
"nginx_oldest_start_time_seconds",
"start time in seconds since 1970/01/01",
nil, nil)
)

type namedProcess struct {
scrapeChan chan scrapeRequest
*proc.Grouper
fs *proc.FS
}

func NewNamedProcessCollector(children bool, mn common.MatchNamer) (prometheus.Collector, error) {
fs, err := proc.NewFS("/proc")
if err != nil {
return nil, err
}
p := namedProcess{
scrapeChan: make(chan scrapeRequest),
Grouper: proc.NewGrouper(children, mn),
fs: fs,
}
_, err = p.Update(p.fs.AllProcs())
if err != nil {
return nil, err
}

go p.start()

return p, nil
}

// Describe implements prometheus.Collector.
func (p namedProcess) Describe(ch chan<- *prometheus.Desc) {
ch <- cpuSecsDesc
ch <- numprocsDesc
ch <- readBytesDesc
ch <- writeBytesDesc
ch <- memResidentbytesDesc
ch <- memVirtualbytesDesc
ch <- startTimeDesc
}

// Collect implements prometheus.Collector.
func (p namedProcess) Collect(ch chan<- prometheus.Metric) {
req := scrapeRequest{results: ch, done: make(chan struct{})}
p.scrapeChan <- req
<-req.done
}

func (p namedProcess) start() {
for req := range p.scrapeChan {
ch := req.results
p.scrape(ch)
req.done <- struct{}{}
}
}

func (p namedProcess) Stop() {
close(p.scrapeChan)
}

func (p namedProcess) scrape(ch chan<- prometheus.Metric) {
_, err := p.Update(p.fs.AllProcs())
if err != nil {
glog.Warningf("unexpected error obtaining nginx process info: %v", err)
return
}

for gname, gcounts := range p.Groups() {
ch <- prometheus.MustNewConstMetric(numprocsDesc,
prometheus.GaugeValue, float64(gcounts.Procs))
ch <- prometheus.MustNewConstMetric(memResidentbytesDesc,
prometheus.GaugeValue, float64(gcounts.Memresident))
ch <- prometheus.MustNewConstMetric(memVirtualbytesDesc,
prometheus.GaugeValue, float64(gcounts.Memvirtual))
ch <- prometheus.MustNewConstMetric(startTimeDesc,
prometheus.GaugeValue, float64(gcounts.OldestStartTime.Unix()))
ch <- prometheus.MustNewConstMetric(cpuSecsDesc,
prometheus.CounterValue, gcounts.Cpu)
ch <- prometheus.MustNewConstMetric(readBytesDesc,
prometheus.CounterValue, float64(gcounts.ReadBytes))
ch <- prometheus.MustNewConstMetric(writeBytesDesc,
prometheus.CounterValue, float64(gcounts.WriteBytes))
}
}
Loading

0 comments on commit 7ba389c

Please sign in to comment.