Skip to content
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
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ module github.com/Lusitaniae/phpfpm_exporter
go 1.16

require (
github.com/kanocz/fcgi_client v0.0.0-20210113082628-fff85c8adfb7
github.com/prometheus/client_golang v1.10.0
github.com/prometheus/client_model v0.2.0
github.com/prometheus/common v0.27.0
github.com/tomasen/fcgi_client v0.0.0-20180423082037-2bb3d819fd19
gopkg.in/alecthomas/kingpin.v2 v2.2.6
)
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,8 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/kanocz/fcgi_client v0.0.0-20210113082628-fff85c8adfb7 h1:W0fAsQ7bC1db4k9O2X6yZvatz/0c/ISyxhmNnc6arZA=
github.com/kanocz/fcgi_client v0.0.0-20210113082628-fff85c8adfb7/go.mod h1:dHpIS7C6YjFguh5vo9QBVEojDoL3vh3v6oEho2HtNyA=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
Expand Down Expand Up @@ -331,8 +333,6 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tomasen/fcgi_client v0.0.0-20180423082037-2bb3d819fd19 h1:ZCmSnT6CLGhfoQ2lPEhL4nsJstKDCw1F1RfN8/smTCU=
github.com/tomasen/fcgi_client v0.0.0-20180423082037-2bb3d819fd19/go.mod h1:SXTY+QvI+KTTKXQdg0zZ7nx0u94QWh8ZAwBQYsW9cqk=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
Expand Down
54 changes: 34 additions & 20 deletions phpfpm_exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ import (

"path/filepath"

fcgiclient "github.com/kanocz/fcgi_client"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
client_model "github.com/prometheus/client_model/go"
"github.com/prometheus/common/expfmt"
"github.com/prometheus/common/version"
"github.com/tomasen/fcgi_client"
"gopkg.in/alecthomas/kingpin.v2"
)

Expand Down Expand Up @@ -147,19 +147,23 @@ func CollectStatusFromReader(reader io.Reader, socketPath string, ch chan<- prom
return nil
}

func CollectStatusFromSocket(path *SocketPath, statusPath string, ch chan<- prometheus.Metric) error {
func CollectStatusFromSocket(path *SocketPath, statusPath string, connectTimeout time.Duration, operationTimeout time.Duration, ch chan<- prometheus.Metric) error {

env := make(map[string]string)
env["SCRIPT_FILENAME"] = statusPath
env["SCRIPT_NAME"] = statusPath
env["REQUEST_METHOD"] = "GET"

fcgi, err := fcgiclient.Dial(path.Network, path.Address)
fcgi, err := fcgiclient.DialTimeout(path.Network, path.Address, connectTimeout)
if err != nil {
return err
}
defer fcgi.Close()

if operationTimeout > 0 {
fcgi.SetTimeout(operationTimeout)
}

resp, err := fcgi.Get(env)
if err != nil {
return err
Expand All @@ -168,17 +172,21 @@ func CollectStatusFromSocket(path *SocketPath, statusPath string, ch chan<- prom
return CollectStatusFromReader(resp.Body, path.FormatStr(), ch)
}

func CollectMetricsFromScript(socketPaths []*SocketPath, scriptPaths []string) ([]*client_model.MetricFamily, error) {
func CollectMetricsFromScript(socketPaths []*SocketPath, connectTimeout time.Duration, operationTimeout time.Duration, scriptPaths []string) ([]*client_model.MetricFamily, error) {
var result []*client_model.MetricFamily

for _, socketPath := range socketPaths {
for _, scriptPath := range scriptPaths {
fcgi, err := fcgiclient.Dial(socketPath.Network, socketPath.Address)
fcgi, err := fcgiclient.DialTimeout(socketPath.Network, socketPath.Address, connectTimeout)
if err != nil {
return result, err
}
defer fcgi.Close()

if operationTimeout > 0 {
fcgi.SetTimeout(operationTimeout)
}

env := make(map[string]string)
env["DOCUMENT_ROOT"] = path.Dir(scriptPath)
env["SCRIPT_FILENAME"] = scriptPath
Expand Down Expand Up @@ -219,14 +227,18 @@ func CollectMetricsFromScript(socketPaths []*SocketPath, scriptPaths []string) (
}

type PhpfpmExporter struct {
socketPaths []*SocketPath
statusPath string
socketPaths []*SocketPath
connectTimeout time.Duration
operationTimeout time.Duration
statusPath string
}

func NewPhpfpmExporter(socketPaths []*SocketPath, statusPath string) (*PhpfpmExporter, error) {
func NewPhpfpmExporter(socketPaths []*SocketPath, connectTimeout time.Duration, operationTimeout time.Duration, statusPath string) (*PhpfpmExporter, error) {
return &PhpfpmExporter{
socketPaths: socketPaths,
statusPath: statusPath,
socketPaths: socketPaths,
connectTimeout: connectTimeout,
operationTimeout: operationTimeout,
statusPath: statusPath,
}, nil
}

Expand All @@ -242,7 +254,7 @@ func (e *PhpfpmExporter) Describe(ch chan<- *prometheus.Desc) {
func (e *PhpfpmExporter) Collect(ch chan<- prometheus.Metric) {

for _, socketPath := range e.socketPaths {
err := CollectStatusFromSocket(socketPath, e.statusPath, ch)
err := CollectStatusFromSocket(socketPath, e.statusPath, e.connectTimeout, e.operationTimeout, ch)
if err == nil {
ch <- prometheus.MustNewConstMetric(
phpfpmUpDesc,
Expand Down Expand Up @@ -282,13 +294,15 @@ func NewSocketPath(socketPath string) *SocketPath {

func main() {
var (
listenAddress = kingpin.Flag("web.listen-address", "Address to listen on for web interface and telemetry.").Default(":9253").String()
metricsPath = kingpin.Flag("web.telemetry-path", "Path under which to expose metrics.").Default("/metrics").String()
socketPaths = kingpin.Flag("phpfpm.socket-paths", "Paths of the PHP-FPM sockets.").Strings()
socketDirectories = kingpin.Flag("phpfpm.socket-directories", "Path(s) of the directory where PHP-FPM sockets are located.").Strings()
statusPath = kingpin.Flag("phpfpm.status-path", "Path which has been configured in PHP-FPM to show status page.").Default("/status").String()
scriptCollectorPaths = kingpin.Flag("phpfpm.script-collector-paths", "Paths of the PHP file whose output needs to be collected.").Strings()
showVersion = kingpin.Flag("version", "Print version information.").Bool()
listenAddress = kingpin.Flag("web.listen-address", "Address to listen on for web interface and telemetry.").Default(":9253").String()
metricsPath = kingpin.Flag("web.telemetry-path", "Path under which to expose metrics.").Default("/metrics").String()
socketPaths = kingpin.Flag("phpfpm.socket-paths", "Paths of the PHP-FPM sockets.").Strings()
socketDirectories = kingpin.Flag("phpfpm.socket-directories", "Path(s) of the directory where PHP-FPM sockets are located.").Strings()
statusPath = kingpin.Flag("phpfpm.status-path", "Path which has been configured in PHP-FPM to show status page.").Default("/status").String()
scriptCollectorPaths = kingpin.Flag("phpfpm.script-collector-paths", "Paths of the PHP file whose output needs to be collected.").Strings()
socketConnectionTimeout = kingpin.Flag("phpfpm.connection-timeout", "Connection timeout for PHP-FPM sockets.").Duration()
socketOperationTimeout = kingpin.Flag("phpfpm.operation-timeout", "Read/write operation timeout for PHP-FPM sockets.").Duration()
showVersion = kingpin.Flag("version", "Print version information.").Bool()
)

kingpin.CommandLine.HelpFlag.Short('h')
Expand All @@ -313,7 +327,7 @@ func main() {
os.Exit(0)
}

exporter, err := NewPhpfpmExporter(sockets, *statusPath)
exporter, err := NewPhpfpmExporter(sockets, *socketConnectionTimeout, *socketOperationTimeout, *statusPath)
if err != nil {
panic(err)
}
Expand All @@ -324,7 +338,7 @@ func main() {
gatherer = prometheus.Gatherers{
prometheus.DefaultGatherer,
prometheus.GathererFunc(func() ([]*client_model.MetricFamily, error) {
return CollectMetricsFromScript(sockets, *scriptCollectorPaths)
return CollectMetricsFromScript(sockets, *socketConnectionTimeout, *socketOperationTimeout, *scriptCollectorPaths)
}),
}
}
Expand Down