Implement unix socket support and make status path configurable (#23)

* Implement unix socket support and make status path configurable (Thx @herb123456 for the initial implementation) #19 #22
* Follow linting guidelines
* Follow linting guidelines
* Move `env` to where it's being used
This commit is contained in:
Enrico Stahn 2018-03-18 12:23:38 +11:00 committed by GitHub
parent a40daa1d8b
commit 8a0c89d182
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 10 deletions

View file

@ -20,6 +20,7 @@ import (
"io/ioutil" "io/ioutil"
"net/url" "net/url"
"strconv" "strconv"
"strings"
"sync" "sync"
"time" "time"
@ -144,26 +145,26 @@ func (pm *PoolManager) Update() (err error) {
func (p *Pool) Update() (err error) { func (p *Pool) Update() (err error) {
p.ScrapeError = nil p.ScrapeError = nil
env := map[string]string{ scheme, address, path, err := parseURL(p.Address)
"SCRIPT_FILENAME": "/status",
"SCRIPT_NAME": "/status",
"SERVER_SOFTWARE": "go / php-fpm_exporter",
"REMOTE_ADDR": "127.0.0.1",
"QUERY_STRING": "json&full",
}
uri, err := url.Parse(p.Address)
if err != nil { if err != nil {
return p.error(err) return p.error(err)
} }
fcgi, err := fcgiclient.DialTimeout(uri.Scheme, uri.Hostname()+":"+uri.Port(), time.Duration(3)*time.Second) fcgi, err := fcgiclient.DialTimeout(scheme, address, time.Duration(3)*time.Second)
if err != nil { if err != nil {
return p.error(err) return p.error(err)
} }
defer fcgi.Close() defer fcgi.Close()
env := map[string]string{
"SCRIPT_FILENAME": path,
"SCRIPT_NAME": path,
"SERVER_SOFTWARE": "go / php-fpm_exporter",
"REMOTE_ADDR": "127.0.0.1",
"QUERY_STRING": "json&full",
}
resp, err := fcgi.Get(env) resp, err := fcgi.Get(env)
if err != nil { if err != nil {
return p.error(err) return p.error(err)
@ -213,6 +214,30 @@ func CountProcessState(processes []PoolProcess) (active int64, idle int64, total
return active, idle, active + idle return active, idle, active + idle
} }
// parseURL creates elements to be passed into fcgiclient.DialTimeout
func parseURL(rawurl string) (scheme string, address string, path string, err error) {
uri, err := url.Parse(rawurl)
if err != nil {
return uri.Scheme, uri.Host, uri.Path, err
}
scheme = uri.Scheme
switch uri.Scheme {
case "unix":
result := strings.Split(uri.Path, ";")
address = result[0]
if len(result) > 1 {
path = result[1]
}
default:
address = uri.Host
path = uri.Path
}
return
}
type timestamp time.Time type timestamp time.Time
// MarshalJSON customise JSON for timestamp // MarshalJSON customise JSON for timestamp

View file

@ -93,3 +93,22 @@ func TestCannotUnmarshalNumberIssue10(t *testing.T) {
assert.NotNil(t, err, err.Error()) assert.NotNil(t, err, err.Error())
} }
func TestParseURL(t *testing.T) {
var uris = []struct {
in string
out []string
err error
}{
{"tcp://127.0.0.1:9000/status", []string{"tcp", "127.0.0.1:9000", "/status"}, nil},
{"tcp://127.0.0.1", []string{"tcp", "127.0.0.1", ""}, nil},
{"unix:///tmp/php.sock;/status", []string{"unix", "/tmp/php.sock", "/status"}, nil},
{"unix:///tmp/php.sock", []string{"unix", "/tmp/php.sock", ""}, nil},
}
for _, u := range uris {
scheme, address, path, err := parseURL(u.in)
assert.Equal(t, u.err, err)
assert.Equal(t, u.out, []string{scheme, address, path})
}
}