Commit 8a57bcf8 authored by Geoff Simmons's avatar Geoff Simmons

Controller has /metrics http endpoint for Prometheus-friendly metrics.

Initially to publish workqueue metrics.
parent 12315f8b
......@@ -33,6 +33,7 @@ package main
import (
"flag"
"fmt"
"math"
"os"
"os/signal"
"strings"
......@@ -75,6 +76,8 @@ var (
"interval at which the monitor thread checks and updates\n"+
"instances of Varnish that implement Ingress.\n"+
"Monitor deactivated when <= 0s")
metricsPortF = flag.Uint("metricsport", 8080,
"port at which to listen for the /metrics endpoint")
logFormat = logrus.TextFormatter{
DisableColors: true,
FullTimestamp: true,
......@@ -133,6 +136,12 @@ func main() {
os.Exit(-1)
}
if *metricsPortF > math.MaxUint16 {
log.Fatalf("metricsport %d out of range (max %d)",
*metricsPortF, math.MaxUint16)
os.Exit(-1)
}
log.Info("Starting Varnish Ingress controller version:", version)
vController, err := varnish.NewVarnishController(log, *tmplDirF,
......@@ -187,7 +196,7 @@ func main() {
go handleTermination(log, ingController, vController, varnishDone)
vController.Start(varnishDone)
informerFactory.Start(informerStop)
ingController.Run(*readyfileF)
ingController.Run(*readyfileF, uint16(*metricsPortF))
}
func handleTermination(
......
......@@ -18,6 +18,9 @@ spec:
- image: varnish-ingress/controller
imagePullPolicy: IfNotPresent
name: varnish-ingress-controller
ports:
- name: http
containerPort: 8080
livenessProbe:
exec:
command:
......
......@@ -22,6 +22,7 @@ require (
github.com/onsi/ginkgo v1.7.0 // indirect
github.com/onsi/gomega v1.4.3 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/prometheus/client_golang v0.9.2
github.com/sirupsen/logrus v1.2.0
github.com/spf13/pflag v1.0.3 // indirect
golang.org/x/net v0.0.0-20181220203305-927f97764cc3 // indirect
......
......@@ -4,6 +4,8 @@ github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVk
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/emicklei/go-restful v2.8.0+incompatible h1:wN8GCRDPGHguIynsnBartv5GUgGUg1LAU7+xnSn1j7Q=
......@@ -52,6 +54,8 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGi
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
......@@ -65,6 +69,14 @@ github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+v
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.2 h1:awm861/B8OKDd2I/6o1dy3ra4BamzKhYOiGItCeZ740=
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275 h1:PnBWHBf+6L0jOqq0gIVUe6Yk0/QMZ640k6NvkxcBf+8=
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a h1:9a8MnZMP0X2nLJdBg+pBmGgkJlSaKC2KaQmTCk1XDtE=
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
......@@ -76,9 +88,11 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3 h1:eH6Eip3UpmR+yM/qI9Ijluzb1bNv/cAU/n+6l8tRSis=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8=
......
......@@ -135,6 +135,8 @@ func NewIngressController(
vController: vc,
}
InitMetrics()
eventBroadcaster := record.NewBroadcaster()
eventBroadcaster.StartLogging(ingc.log.Printf)
eventBroadcaster.StartRecordingToSink(&core_v1.EventSinkImpl{
......@@ -273,7 +275,7 @@ func (ingc *IngressController) updateObj(old, new interface{}) {
//
// If readyFile is non-empty, it is the path of a file to touch when
// the controller is ready (after informers have launched).
func (ingc *IngressController) Run(readyFile string) {
func (ingc *IngressController) Run(readyFile string, metricsPort uint16) {
defer utilruntime.HandleCrash()
defer ingc.nsQs.Stop()
......@@ -285,6 +287,9 @@ func (ingc *IngressController) Run(readyFile string) {
go ingc.informers.vcfg.Run(ingc.stopCh)
go ingc.informers.bcfg.Run(ingc.stopCh)
ingc.log.Infof("Starting metrics listener at port %d", metricsPort)
go ServeMetrics(ingc.log, metricsPort)
ingc.log.Info("Controller ready")
if readyFile != "" {
f, err := os.Create(readyFile)
......
/*
* Copyright (c) 2019 UPLEX Nils Goroll Systemoptimierung
* All rights reserved
*
* Author: Geoffrey Simmons <geoffrey.simmons@uplex.de>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
package controller
import (
"fmt"
"net/http"
"k8s.io/client-go/util/workqueue"
"github.com/sirupsen/logrus"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
const (
namespace = "varnishingctl"
workqSubsystem = "workqueue"
)
type promProvider struct{}
func (_ promProvider) NewDepthMetric(name string) workqueue.GaugeMetric {
label := make(map[string]string)
label["namespace"] = name
depth := prometheus.NewGauge(prometheus.GaugeOpts{
Subsystem: workqSubsystem,
Namespace: namespace,
Name: "depth",
Help: "Current depth of the workqueue",
ConstLabels: label,
})
prometheus.Register(depth)
return depth
}
func (_ promProvider) NewAddsMetric(name string) workqueue.CounterMetric {
label := make(map[string]string)
label["namespace"] = name
adds := prometheus.NewCounter(prometheus.CounterOpts{
Subsystem: workqSubsystem,
Namespace: namespace,
Name: "adds_total",
Help: "Total number of adds handled by the workqueue",
ConstLabels: label,
})
prometheus.Register(adds)
return adds
}
func (_ promProvider) NewLatencyMetric(name string) workqueue.SummaryMetric {
label := make(map[string]string)
label["namespace"] = name
latency := prometheus.NewSummary(prometheus.SummaryOpts{
Subsystem: workqSubsystem,
Namespace: namespace,
Name: "latency_useconds",
Help: "Time spent (in µsecs) by items waiting in the " +
"workqueue",
ConstLabels: label,
})
prometheus.Register(latency)
return latency
}
func (_ promProvider) NewWorkDurationMetric(name string) workqueue.SummaryMetric {
label := make(map[string]string)
label["namespace"] = name
workDuration := prometheus.NewSummary(prometheus.SummaryOpts{
Subsystem: workqSubsystem,
Namespace: namespace,
Name: "work_duration_useconds",
Help: "Time needed (in µsecs) to process items from the " +
"workqueue",
ConstLabels: label,
})
prometheus.Register(workDuration)
return workDuration
}
func (_ promProvider) NewRetriesMetric(name string) workqueue.CounterMetric {
label := make(map[string]string)
label["namespace"] = name
retries := prometheus.NewCounter(prometheus.CounterOpts{
Subsystem: workqSubsystem,
Namespace: namespace,
Name: "retries_total",
Help: "Total number of retries handled by workqueue",
ConstLabels: label,
})
prometheus.Register(retries)
return retries
}
func InitMetrics() {
workqueue.SetProvider(promProvider{})
}
func ServeMetrics(log *logrus.Logger, port uint16) {
addr := fmt.Sprintf(":%d", port)
http.Handle("/metrics", promhttp.Handler())
log.Fatal(http.ListenAndServe(addr, nil))
}
......@@ -284,8 +284,8 @@ func NewNamespaceQueues(
client kubernetes.Interface,
recorder record.EventRecorder) *NamespaceQueues {
q := workqueue.NewRateLimitingQueue(
workqueue.DefaultControllerRateLimiter())
q := workqueue.NewNamedRateLimitingQueue(
workqueue.DefaultControllerRateLimiter(), "_ALL_")
return &NamespaceQueues{
Queue: q,
log: log,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment