Add metrics "phpfpm_up" and "phpfpm_scrape_failures" to report on scraping issues (#2)

This commit is contained in:
Enrico Stahn 2018-02-22 15:41:27 +11:00
parent 255e2fa6d0
commit 8303048f5e
No known key found for this signature in database
GPG key ID: 5263621C269A50DE
2 changed files with 40 additions and 16 deletions

View file

@ -14,6 +14,7 @@
package phpfpm package phpfpm
import ( import (
"fmt"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"sync" "sync"
) )
@ -27,6 +28,8 @@ type Exporter struct {
PoolManager PoolManager PoolManager PoolManager
mutex sync.Mutex mutex sync.Mutex
up *prometheus.Desc
scrapeFailues *prometheus.Desc
startSince *prometheus.Desc startSince *prometheus.Desc
acceptedConnections *prometheus.Desc acceptedConnections *prometheus.Desc
listenQueue *prometheus.Desc listenQueue *prometheus.Desc
@ -45,6 +48,18 @@ func NewExporter(pm PoolManager) *Exporter {
return &Exporter{ return &Exporter{
PoolManager: pm, PoolManager: pm,
up: prometheus.NewDesc(
prometheus.BuildFQName(namespace, "", "up"),
"Could PHP-FPM be reached?",
[]string{"pool"},
nil),
scrapeFailues: prometheus.NewDesc(
prometheus.BuildFQName(namespace, "", "scrape_failures"),
"The number of failures scraping from PHP-FPM.",
[]string{"pool"},
nil),
startSince: prometheus.NewDesc( startSince: prometheus.NewDesc(
prometheus.BuildFQName(namespace, "", "start_since"), prometheus.BuildFQName(namespace, "", "start_since"),
"The number of seconds since FPM has started.", "The number of seconds since FPM has started.",
@ -121,6 +136,15 @@ func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
e.PoolManager.Update() e.PoolManager.Update()
for _, pool := range e.PoolManager.Pools { for _, pool := range e.PoolManager.Pools {
ch <- prometheus.MustNewConstMetric(e.scrapeFailues, prometheus.CounterValue, float64(pool.ScrapeFailures))
if pool.ScrapeError != nil {
ch <- prometheus.MustNewConstMetric(e.up, prometheus.GaugeValue, 0)
log.Error("Error scraping PHP-FPM: %v", pool.ScrapeError)
continue
}
ch <- prometheus.MustNewConstMetric(e.up, prometheus.GaugeValue, 1, pool.Name)
ch <- prometheus.MustNewConstMetric(e.startSince, prometheus.CounterValue, float64(pool.AcceptedConnections), pool.Name) ch <- prometheus.MustNewConstMetric(e.startSince, prometheus.CounterValue, float64(pool.AcceptedConnections), pool.Name)
ch <- prometheus.MustNewConstMetric(e.acceptedConnections, prometheus.CounterValue, float64(pool.StartSince), pool.Name) ch <- prometheus.MustNewConstMetric(e.acceptedConnections, prometheus.CounterValue, float64(pool.StartSince), pool.Name)
ch <- prometheus.MustNewConstMetric(e.listenQueue, prometheus.GaugeValue, float64(pool.ListenQueue), pool.Name) ch <- prometheus.MustNewConstMetric(e.listenQueue, prometheus.GaugeValue, float64(pool.ListenQueue), pool.Name)
@ -134,11 +158,6 @@ func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
ch <- prometheus.MustNewConstMetric(e.slowRequests, prometheus.CounterValue, float64(pool.SlowRequests), pool.Name) ch <- prometheus.MustNewConstMetric(e.slowRequests, prometheus.CounterValue, float64(pool.SlowRequests), pool.Name)
} }
//if err := e.collect(ch); err != nil {
// log.Errorf("Error scraping apache: %s", err)
// e.scrapeFailures.Inc()
// e.scrapeFailures.Collect(ch)
//}
return return
} }

View file

@ -41,7 +41,8 @@ type PoolManager struct {
type Pool struct { type Pool struct {
// The address of the pool, e.g. tcp://127.0.0.1:9000 or unix:///tmp/php-fpm.sock // The address of the pool, e.g. tcp://127.0.0.1:9000 or unix:///tmp/php-fpm.sock
Address string `json:"-"` Address string `json:"-"`
CollectionError error `json:"-"` ScrapeError error `json:"-"`
ScrapeFailures int64 `json:"-"`
Name string `json:"pool"` Name string `json:"pool"`
ProcessManager string `json:"process manager"` ProcessManager string `json:"process manager"`
StartTime timestamp `json:"start time"` StartTime timestamp `json:"start time"`
@ -108,14 +109,15 @@ func (pm *PoolManager) Update() (err error) {
// Update will connect to PHP-FPM and retrieve the latest data for the pool. // Update will connect to PHP-FPM and retrieve the latest data for the pool.
func (p *Pool) Update() (err error) { func (p *Pool) Update() (err error) {
p.CollectionError = nil p.ScrapeError = nil
env := make(map[string]string) env := map[string]string{
env["SCRIPT_FILENAME"] = "/status" "SCRIPT_FILENAME": "/status",
env["SCRIPT_NAME"] = "/status" "SCRIPT_NAME": "/status",
env["SERVER_SOFTWARE"] = "go / php-fpm_exporter " "SERVER_SOFTWARE": "go / php-fpm_exporter",
env["REMOTE_ADDR"] = "127.0.0.1" "REMOTE_ADDR": "127.0.0.1",
env["QUERY_STRING"] = "json&full" "QUERY_STRING": "json&full",
}
uri, err := url.Parse(p.Address) uri, err := url.Parse(p.Address)
if err != nil { if err != nil {
@ -127,18 +129,20 @@ func (p *Pool) Update() (err error) {
return p.error(err) return p.error(err)
} }
defer fcgi.Close()
resp, err := fcgi.Get(env) resp, err := fcgi.Get(env)
if err != nil { if err != nil {
return p.error(err) return p.error(err)
} }
defer resp.Body.Close()
content, err := ioutil.ReadAll(resp.Body) content, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
return p.error(err) return p.error(err)
} }
fcgi.Close()
log.Debugf("Pool[", p.Address, "]:", string(content)) log.Debugf("Pool[", p.Address, "]:", string(content))
if err = json.Unmarshal(content, &p); err != nil { if err = json.Unmarshal(content, &p); err != nil {
@ -149,7 +153,8 @@ func (p *Pool) Update() (err error) {
} }
func (p *Pool) error(err error) error { func (p *Pool) error(err error) error {
p.CollectionError = err p.ScrapeError = err
p.ScrapeFailures++
log.Error(err) log.Error(err)
return err return err
} }