From 4895e3baa553c1d5ce40c2eed34457ebb7d95755 Mon Sep 17 00:00:00 2001 From: SilverFire - Dmitry Naumenko Date: Wed, 28 Oct 2020 16:05:05 +0200 Subject: [PATCH 1/2] Add constant labels feature --- cmd/php-fpm-exporter/main.go | 2 ++ collector.go | 24 ++++++++++++------------ exporter.go | 19 +++++++++++++++++++ 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/cmd/php-fpm-exporter/main.go b/cmd/php-fpm-exporter/main.go index e2ab8e7..00d56f3 100644 --- a/cmd/php-fpm-exporter/main.go +++ b/cmd/php-fpm-exporter/main.go @@ -13,6 +13,7 @@ func main() { endpoint = kingpin.Flag("endpoint", "url for php-fpm status").Default("http://127.0.0.1:9000/status").Envar("ENDPOINT_URL").String() fcgiEndpoint = kingpin.Flag("fastcgi", "fastcgi url. If this is set, fastcgi will be used instead of HTTP").Envar("FASTCGI_URL").String() metricsEndpoint = kingpin.Flag("web.telemetry-path", "Path under which to expose metrics. Cannot be /").Default("/metrics").Envar("TELEMETRY_PATH").String() + labels = kingpin.Flag("labels", "A list of constant labels, that will be assigned to all metrics. For example \"service=payments-api,dc=us-west\"").Envar("METRIC_LABELS").String() ) kingpin.HelpFlag.Short('h') @@ -29,6 +30,7 @@ func main() { exporter.SetFastcgi(*fcgiEndpoint), exporter.SetLogger(logger), exporter.SetMetricsEndpoint(*metricsEndpoint), + exporter.SetLabels(*labels), ) if err != nil { diff --git a/collector.go b/collector.go index 882283c..5e32bc4 100644 --- a/collector.go +++ b/collector.go @@ -34,26 +34,26 @@ type collector struct { const metricsNamespace = "phpfpm" -func newFuncMetric(metricName string, docString string, labels []string) *prometheus.Desc { +func newFuncMetric(metricName string, docString string, labels []string, constLabels prometheus.Labels) *prometheus.Desc { return prometheus.NewDesc( prometheus.BuildFQName(metricsNamespace, "", metricName), - docString, labels, nil, + docString, labels, constLabels, ) } func (e *Exporter) newCollector() *collector { return &collector{ exporter: e, - up: newFuncMetric("up", "able to contact php-fpm", nil), - acceptedConn: newFuncMetric("accepted_connections_total", "Total number of accepted connections", nil), - listenQueue: newFuncMetric("listen_queue_connections", "Number of connections that have been initiated but not yet accepted", nil), - maxListenQueue: newFuncMetric("listen_queue_max_connections", "Max number of connections the listen queue has reached since FPM start", nil), - listenQueueLength: newFuncMetric("listen_queue_length_connections", "The length of the socket queue, dictating maximum number of pending connections", nil), - phpProcesses: newFuncMetric("processes_total", "process count", []string{"state"}), - maxActiveProcesses: newFuncMetric("active_max_processes", "Maximum active process count", nil), - maxChildrenReached: newFuncMetric("max_children_reached_total", "Number of times the process limit has been reached", nil), - slowRequests: newFuncMetric("slow_requests_total", "Number of requests that exceed request_slowlog_timeout", nil), - scrapeFailures: newFuncMetric("scrape_failures_total", "Number of errors while scraping php_fpm", nil), + up: newFuncMetric("up", "able to contact php-fpm", nil, e.constantLabels), + acceptedConn: newFuncMetric("accepted_connections_total", "Total number of accepted connections", nil, e.constantLabels), + listenQueue: newFuncMetric("listen_queue_connections", "Number of connections that have been initiated but not yet accepted", nil, e.constantLabels), + maxListenQueue: newFuncMetric("listen_queue_max_connections", "Max number of connections the listen queue has reached since FPM start", nil, e.constantLabels), + listenQueueLength: newFuncMetric("listen_queue_length_connections", "The length of the socket queue, dictating maximum number of pending connections", nil, e.constantLabels), + phpProcesses: newFuncMetric("processes_total", "process count", []string{"state"}, e.constantLabels), + maxActiveProcesses: newFuncMetric("active_max_processes", "Maximum active process count", nil, e.constantLabels), + maxChildrenReached: newFuncMetric("max_children_reached_total", "Number of times the process limit has been reached", nil, e.constantLabels), + slowRequests: newFuncMetric("slow_requests_total", "Number of requests that exceed request_slowlog_timeout", nil, e.constantLabels), + scrapeFailures: newFuncMetric("scrape_failures_total", "Number of errors while scraping php_fpm", nil, e.constantLabels), } } diff --git a/exporter.go b/exporter.go index 1bd48c9..f483ed4 100644 --- a/exporter.go +++ b/exporter.go @@ -7,6 +7,7 @@ import ( "net/url" "os" "os/signal" + "strings" "syscall" "time" @@ -24,6 +25,7 @@ type Exporter struct { fcgiEndpoint *url.URL logger *zap.Logger metricsEndpoint string + constantLabels prometheus.Labels } // OptionsFunc is a function passed to new for setting options on a new Exporter. @@ -95,6 +97,23 @@ func SetEndpoint(rawurl string) func(*Exporter) error { } } +func SetLabels(labels string) func(*Exporter) error { + return func(e *Exporter) error { + if labels == "" { + return nil + } + + labelsMap := make(map[string]string) + for _, label := range strings.Split(labels, ",") { + kv := strings.Split(label, "=") + labelsMap[kv[0]] = kv[1] + } + + e.constantLabels = labelsMap + return nil + } +} + // SetFastcgi creates a function that will set the fastcgi URL endpoint to contact // php-fpm. If this is set, then fastcgi is used rather than HTTP. // Generally only used when create a new Exporter. From 0cc4e35f0c104242623ee9d3a5e9db04ad2078e6 Mon Sep 17 00:00:00 2001 From: SilverFire - Dmitry Naumenko Date: Wed, 28 Oct 2020 16:13:14 +0200 Subject: [PATCH 2/2] Updated README --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 0f088ed..170e913 100644 --- a/README.md +++ b/README.md @@ -37,17 +37,19 @@ Usage: php-fpm-exporter [flags] Flags: - --addr string listen address for metrics handler (default "127.0.0.1:8080") - --endpoint string url for php-fpm status (default "http://127.0.0.1:9000/status") - --fastcgi string fastcgi url. If this is set, fastcgi will be used instead of HTTP + --addr="127.0.0.1:8080" listen address for metrics handler + --endpoint="http://127.0.0.1:9000/status" url for php-fpm status + --fastcgi=FASTCGI fastcgi url. If this is set, fastcgi will be used instead of HTTP + --web.telemetry-path="/metrics" Path under which to expose metrics. Cannot be / + --labels=LABELS A list of labels, that will be assigned to all metrics. For example "service=api,dc=us-west" ``` When running, a simple healthcheck is available on `/healthz` -To use the HTTP endpoint you must pass through `/status` in your webserver +To use the HTTP endpoint you must pass through `/status` in your webserver and configure php-fpm to handle status requests. Example for nginx: https://easyengine.io/tutorials/php/fpm-status-page/ -To use Fastcgi, set `--fastcgi` to a url such as `tcp://127.0.0.1:9090/status` if php-fpm is listening on a tcp socket or +To use Fastcgi, set `--fastcgi` to a url such as `tcp://127.0.0.1:9090/status` if php-fpm is listening on a tcp socket or `unix:///path/to/php.sock` for a unix socket. Note: php-fpm must be configured to use `/status` if using a unix socket, `php-fpm-exporter` does not currently support changing this. Metrics