Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add constant labels feature #42

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions cmd/php-fpm-exporter/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand All @@ -29,6 +30,7 @@ func main() {
exporter.SetFastcgi(*fcgiEndpoint),
exporter.SetLogger(logger),
exporter.SetMetricsEndpoint(*metricsEndpoint),
exporter.SetLabels(*labels),
)

if err != nil {
Expand Down
24 changes: 12 additions & 12 deletions collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
}

Expand Down
19 changes: 19 additions & 0 deletions exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"net/url"
"os"
"os/signal"
"strings"
"syscall"
"time"

Expand All @@ -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.
Expand Down Expand Up @@ -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.
Expand Down