Merge pull request #5 from hipages/scrape-failures
Add metrics "phpfpm_up" and "phpfpm_scrape_failures" to report on scr…
This commit is contained in:
commit
4c2b30357e
3 changed files with 52 additions and 16 deletions
13
README.md
13
README.md
|
@ -94,12 +94,16 @@ The `server` command runs the server required for prometheus to retrieve the sta
|
||||||
# TYPE phpfpm_max_children_reached counter
|
# TYPE phpfpm_max_children_reached counter
|
||||||
# HELP phpfpm_max_listen_queue The maximum number of requests in the queue of pending connections since FPM has started.
|
# HELP phpfpm_max_listen_queue The maximum number of requests in the queue of pending connections since FPM has started.
|
||||||
# TYPE phpfpm_max_listen_queue counter
|
# TYPE phpfpm_max_listen_queue counter
|
||||||
|
# HELP phpfpm_scrape_failures The number of failures scraping from PHP-FPM.
|
||||||
|
# TYPE phpfpm_scrape_failures counter
|
||||||
# HELP phpfpm_slow_requests The number of requests that exceeded your 'request_slowlog_timeout' value.
|
# HELP phpfpm_slow_requests The number of requests that exceeded your 'request_slowlog_timeout' value.
|
||||||
# TYPE phpfpm_slow_requests counter
|
# TYPE phpfpm_slow_requests counter
|
||||||
# HELP phpfpm_start_since The number of seconds since FPM has started.
|
# HELP phpfpm_start_since The number of seconds since FPM has started.
|
||||||
# TYPE phpfpm_start_since counter
|
# TYPE phpfpm_start_since counter
|
||||||
# HELP phpfpm_total_processes The number of idle + active processes.
|
# HELP phpfpm_total_processes The number of idle + active processes.
|
||||||
# TYPE phpfpm_total_processes gauge
|
# TYPE phpfpm_total_processes gauge
|
||||||
|
# HELP phpfpm_up Could PHP-FPM be reached?
|
||||||
|
# TYPE phpfpm_up gauge
|
||||||
```
|
```
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
@ -110,6 +114,15 @@ The project follows the typical GitHub pull request model.
|
||||||
See " [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/) " for more details.
|
See " [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/) " for more details.
|
||||||
Before starting any work, please either comment on an existing issue, or file a new one.
|
Before starting any work, please either comment on an existing issue, or file a new one.
|
||||||
|
|
||||||
|
## FAQ
|
||||||
|
|
||||||
|
* **How to update "Metrics collected"?**
|
||||||
|
|
||||||
|
Copy&paste the output from:
|
||||||
|
```
|
||||||
|
curl http://127.0.0.1:12345/metrics | grep phpfpm | grep "#"
|
||||||
|
```
|
||||||
|
|
||||||
## Alternatives
|
## Alternatives
|
||||||
|
|
||||||
* [bakins/php-fpm-exporter](https://github.com/bakins/php-fpm-exporter)
|
* [bakins/php-fpm-exporter](https://github.com/bakins/php-fpm-exporter)
|
||||||
|
|
|
@ -27,6 +27,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 +47,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 +135,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), pool.Name)
|
||||||
|
|
||||||
|
if pool.ScrapeError != nil {
|
||||||
|
ch <- prometheus.MustNewConstMetric(e.up, prometheus.GaugeValue, 0, pool.Name)
|
||||||
|
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 +157,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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue