Skip to content

Commit 96ba73d

Browse files
Review 1 - Add descriptions of where column definitions come from
Add haproxy rtime (average response latency for http in ms over the last 1024 requests) as a metric.
1 parent 4e56f44 commit 96ba73d

File tree

3 files changed

+26
-8
lines changed

3 files changed

+26
-8
lines changed

pkg/cmd/admin/router/router.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,7 @@ func RunCmdRouter(f *clientcmd.Factory, cmd *cobra.Command, out, errout io.Write
666666
}
667667
env["ROUTER_CANONICAL_HOSTNAME"] = cfg.RouterCanonicalHostname
668668
}
669-
// automatically start the internal metrics agent if the type has metrics
669+
// automatically start the internal metrics agent if we are handling a known type
670670
if cfg.Type == "haproxy-router" {
671671
env["ROUTER_LISTEN_ADDR"] = fmt.Sprintf("0.0.0.0:%d", defaultStatsPort-1)
672672
env["ROUTER_METRICS_TYPE"] = "haproxy"

pkg/cmd/infra/router/template.go

+17-4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414

1515
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
1616
ktypes "k8s.io/kubernetes/pkg/types"
17+
"k8s.io/kubernetes/pkg/util/sets"
1718
"k8s.io/kubernetes/pkg/util/validation"
1819

1920
ocmd "github.com/openshift/origin/pkg/cmd/cli/cmd"
@@ -182,9 +183,12 @@ func (o *TemplateRouterOptions) Complete() error {
182183
return o.RouterSelection.Complete()
183184
}
184185

186+
// supportedMetricsTypes is the set of supported metrics arguments
187+
var supportedMetricsTypes = sets.NewString("haproxy")
188+
185189
func (o *TemplateRouterOptions) Validate() error {
186-
if len(o.MetricsType) > 0 && o.MetricsType != "haproxy" {
187-
return errors.New("supported metrics types are: 'haproxy'")
190+
if len(o.MetricsType) > 0 && !supportedMetricsTypes.Has(o.MetricsType) {
191+
return fmt.Errorf("supported metrics types are: %s", strings.Join(supportedMetricsTypes.List(), ", "))
188192
}
189193
if len(o.RouterName) == 0 {
190194
return errors.New("router must have a name to identify itself in route status")
@@ -204,6 +208,10 @@ func (o *TemplateRouterOptions) Run() error {
204208
var reloadCallbacks []func()
205209
switch {
206210
case o.MetricsType == "haproxy" && len(o.ListenAddr) > 0:
211+
if len(o.StatsUsername) == 0 || len(o.StatsPassword) == 0 {
212+
glog.Warningf("Metrics were requested but no username or password has been provided - the metrics endpoint will not be accessible to prevent accidental security breaches")
213+
}
214+
// Exposed to allow tuning in production if this becomes an issue
207215
var timeout time.Duration
208216
if t := util.Env("ROUTER_METRICS_HAPROXY_TIMEOUT", ""); len(t) > 0 {
209217
d, err := time.ParseDuration(t)
@@ -212,6 +220,7 @@ func (o *TemplateRouterOptions) Run() error {
212220
}
213221
timeout = d
214222
}
223+
// Exposed to allow tuning in production if this becomes an issue
215224
var baseScrapeInterval time.Duration
216225
if t := util.Env("ROUTER_METRICS_HAPROXY_BASE_SCRAPE_INTERVAL", ""); len(t) > 0 {
217226
d, err := time.ParseDuration(t)
@@ -220,6 +229,7 @@ func (o *TemplateRouterOptions) Run() error {
220229
}
221230
baseScrapeInterval = d
222231
}
232+
// Exposed to allow tuning in production if this becomes an issue
223233
var serverThreshold int
224234
if t := util.Env("ROUTER_METRICS_HAPROXY_SERVER_THRESHOLD", ""); len(t) > 0 {
225235
i, err := strconv.Atoi(t)
@@ -228,18 +238,21 @@ func (o *TemplateRouterOptions) Run() error {
228238
}
229239
serverThreshold = i
230240
}
241+
// Exposed to allow tuning in production if this becomes an issue
231242
var exported []int
232243
if t := util.Env("ROUTER_METRICS_HAPROXY_EXPORTED", ""); len(t) > 0 {
233244
for _, s := range strings.Split(t, ",") {
234245
i, err := strconv.Atoi(s)
235246
if err != nil {
236-
return errors.New("ROUTER_METRICS_HAPROXY_EXPORTED must be a comma delimited list of non-negative integers")
247+
return errors.New("ROUTER_METRICS_HAPROXY_EXPORTED must be a comma delimited list of column numbers to extract from the HAProxy configuration")
237248
}
238249
exported = append(exported, i)
239250
}
240251
}
241252
_, err := haproxy.NewPrometheusCollector(haproxy.PrometheusOptions{
242-
ScrapeURI: util.Env("ROUTER_METRICS_HAPROXY_SCRAPE_URI", ""),
253+
// Only template router customizers who alter the image should need this
254+
ScrapeURI: util.Env("ROUTER_METRICS_HAPROXY_SCRAPE_URI", ""),
255+
// Only template router customizers who alter the image should need this
243256
PidFile: util.Env("ROUTER_METRICS_HAPROXY_PID_FILE", ""),
244257
Timeout: timeout,
245258
ServerThreshold: serverThreshold,

pkg/router/metrics/haproxy/haproxy.go

+8-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ const (
2828
// HAProxy 1.4
2929
// # pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,dresp,ereq,econ,eresp,wretr,wredis,status,weight,act,bck,chkfail,chkdown,lastchg,downtime,qlimit,pid,iid,sid,throttle,lbtot,tracked,type,rate,rate_lim,rate_max,check_status,check_code,check_duration,hrsp_1xx,hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt,
3030
// HAProxy 1.5
31-
// pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,dresp,ereq,econ,eresp,wretr,wredis,status,weight,act,bck,chkfail,chkdown,lastchg,downtime,qlimit,pid,iid,sid,throttle,lbtot,tracked,type,rate,rate_lim,rate_max,check_status,check_code,check_duration,hrsp_1xx,hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt,comp_in,comp_out,comp_byp,comp_rsp,lastsess,
31+
// These columns are part of the stable API for HAProxy and are documented here: https://cbonte.github.io/haproxy-dconv/1.5/configuration.html#9.1
32+
// pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,dresp,ereq,econ,eresp,wretr,wredis,status,weight,act,bck,chkfail,chkdown,lastchg,downtime,qlimit,pid,iid,sid,throttle,lbtot,tracked,type,rate,rate_lim,rate_max,check_status,check_code,check_duration,hrsp_1xx,hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt,comp_in,comp_out,comp_byp,comp_rsp,lastsess,last_chk,last_agt,qtime,ctime,rtime,ttime
3233
expectedCsvFieldCount = 52
3334
statusField = 17
3435

@@ -91,8 +92,9 @@ func (m metrics) Names() []int {
9192
return keys
9293
}
9394

94-
// defaultSelectedMetrics is the list of metrics included by default
95-
var defaultSelectedMetrics = []int{2, 4, 5, 7, 8, 9, 13, 14, 17, 21, 24, 33, 35, 40, 43}
95+
// defaultSelectedMetrics is the list of metrics included by default. These metrics are a subset
96+
// of the metrics exposed by haproxy_exporter by default for performance reasons.
97+
var defaultSelectedMetrics = []int{2, 4, 5, 7, 8, 9, 13, 14, 17, 21, 24, 33, 35, 40, 43, 60}
9698

9799
// Exporter collects HAProxy stats from the given URI and exports them using
98100
// the prometheus metrics package.
@@ -194,6 +196,7 @@ func NewExporter(opts PrometheusOptions) (*Exporter, error) {
194196
43: newFrontendMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "5xx"}),
195197
44: newFrontendMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "other"}),
196198
48: newFrontendMetric("http_requests_total", "Total HTTP requests.", nil),
199+
60: newFrontendMetric("http_average_response_latency_milliseconds", "Average response latency of the last 1024 requests in milliseconds.", nil),
197200
}),
198201
reducedBackendExports: map[int]struct{}{2: {}, 3: {}, 7: {}, 17: {}},
199202
backendMetrics: filterMetrics(opts.ExportedMetrics, metrics{
@@ -219,6 +222,7 @@ func NewExporter(opts PrometheusOptions) (*Exporter, error) {
219222
42: newBackendMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "4xx"}),
220223
43: newBackendMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "5xx"}),
221224
44: newBackendMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "other"}),
225+
60: newBackendMetric("http_average_response_latency_milliseconds", "Average response latency of the last 1024 requests in milliseconds.", nil),
222226
}),
223227
serverMetrics: filterMetrics(opts.ExportedMetrics, metrics{
224228
2: newServerMetric("current_queue", "Current number of queued requests assigned to this server.", nil),
@@ -246,6 +250,7 @@ func NewExporter(opts PrometheusOptions) (*Exporter, error) {
246250
42: newServerMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "4xx"}),
247251
43: newServerMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "5xx"}),
248252
44: newServerMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "other"}),
253+
60: newServerMetric("http_average_response_latency_milliseconds", "Average response latency of the last 1024 requests in milliseconds.", nil),
249254
}),
250255
}, nil
251256
}

0 commit comments

Comments
 (0)