diff options
Diffstat (limited to '')
-rw-r--r-- | src/go/collectors/go.d.plugin/modules/haproxy/collect.go | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/src/go/collectors/go.d.plugin/modules/haproxy/collect.go b/src/go/collectors/go.d.plugin/modules/haproxy/collect.go new file mode 100644 index 000000000..203ff1ec4 --- /dev/null +++ b/src/go/collectors/go.d.plugin/modules/haproxy/collect.go @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +package haproxy + +import ( + "errors" + "strings" + + "github.com/netdata/netdata/go/go.d.plugin/agent/module" + "github.com/netdata/netdata/go/go.d.plugin/pkg/prometheus" +) + +const ( + metricBackendSessionsTotal = "haproxy_backend_sessions_total" + metricBackendCurrentSessions = "haproxy_backend_current_sessions" + metricBackendHTTPResponsesTotal = "haproxy_backend_http_responses_total" + metricBackendResponseTimeAverageSeconds = "haproxy_backend_response_time_average_seconds" + metricBackendCurrentQueue = "haproxy_backend_current_queue" + metricBackendQueueTimeAverageSeconds = "haproxy_backend_queue_time_average_seconds" + metricBackendBytesInTotal = "haproxy_backend_bytes_in_total" + metricBackendBytesOutTotal = "haproxy_backend_bytes_out_total" +) + +func isHaproxyMetrics(pms prometheus.Series) bool { + for _, pm := range pms { + if strings.HasPrefix(pm.Name(), "haproxy_") { + return true + } + } + return false +} + +func (h *Haproxy) collect() (map[string]int64, error) { + pms, err := h.prom.ScrapeSeries() + if err != nil { + return nil, err + } + + if h.validateMetrics && !isHaproxyMetrics(pms) { + return nil, errors.New("unexpected metrics (not HAProxy)") + } + h.validateMetrics = false + + mx := make(map[string]int64) + for _, pm := range pms { + proxy := pm.Labels.Get("proxy") + if proxy == "" { + continue + } + + if !h.proxies[proxy] { + h.proxies[proxy] = true + h.addProxyToCharts(proxy) + } + + mx[dimID(pm)] = int64(pm.Value * multiplier(pm)) + } + + return mx, nil +} + +func (h *Haproxy) addProxyToCharts(proxy string) { + h.addDimToChart(chartBackendCurrentSessions.ID, &module.Dim{ + ID: proxyDimID(metricBackendCurrentSessions, proxy), + Name: proxy, + }) + h.addDimToChart(chartBackendSessions.ID, &module.Dim{ + ID: proxyDimID(metricBackendSessionsTotal, proxy), + Name: proxy, + Algo: module.Incremental, + }) + + h.addDimToChart(chartBackendResponseTimeAverage.ID, &module.Dim{ + ID: proxyDimID(metricBackendResponseTimeAverageSeconds, proxy), + Name: proxy, + }) + if err := h.Charts().Add(newChartBackendHTTPResponses(proxy)); err != nil { + h.Warning(err) + } + + h.addDimToChart(chartBackendCurrentQueue.ID, &module.Dim{ + ID: proxyDimID(metricBackendCurrentQueue, proxy), + Name: proxy, + }) + h.addDimToChart(chartBackendQueueTimeAverage.ID, &module.Dim{ + ID: proxyDimID(metricBackendQueueTimeAverageSeconds, proxy), + Name: proxy, + }) + + if err := h.Charts().Add(newChartBackendNetworkIO(proxy)); err != nil { + h.Warning(err) + } +} + +func (h *Haproxy) addDimToChart(chartID string, dim *module.Dim) { + chart := h.Charts().Get(chartID) + if chart == nil { + h.Warningf("error on adding '%s' dimension: can not find '%s' chart", dim.ID, chartID) + return + } + if err := chart.AddDim(dim); err != nil { + h.Warning(err) + return + } + chart.MarkNotCreated() +} + +func multiplier(pm prometheus.SeriesSample) float64 { + switch pm.Name() { + case metricBackendResponseTimeAverageSeconds, + metricBackendQueueTimeAverageSeconds: + // to milliseconds + return 1000 + } + return 1 +} + +func dimID(pm prometheus.SeriesSample) string { + proxy := pm.Labels.Get("proxy") + if proxy == "" { + return "" + } + + name := cleanMetricName(pm.Name()) + if pm.Name() == metricBackendHTTPResponsesTotal { + name += "_" + pm.Labels.Get("code") + } + return proxyDimID(name, proxy) +} + +func proxyDimID(metric, proxy string) string { + return cleanMetricName(metric) + "_proxy_" + proxy +} + +func cleanMetricName(name string) string { + if strings.HasSuffix(name, "_total") { + return name[:len(name)-6] + } + if strings.HasSuffix(name, "_seconds") { + return name[:len(name)-8] + } + return name +} |