diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f85f512..a640db2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ * [ENHANCEMENT] Add check for systemd version before attempting to query certain metrics. #1413 * [ENHANCEMENT] Add new counters for flush requests in Linux 5.5 #1548 * [ENHANCEMENT] The sockstat collector now exposes IPv6 statistics in addition to the existing IPv4 support. #1552 +* [ENHANCEMENT] Add unix socket support for supervisord collector #262 * [BUGFIX] Renamed label `state` to `name` on `node_systemd_service_restart_total`. #1393 * [BUGFIX] Fix netdev nil reference on Darwin #1414 * [BUGFIX] Strip path.rootfs from mountpoint labels #1421 diff --git a/collector/supervisord.go b/collector/supervisord.go index a1820621..33f3b8a1 100644 --- a/collector/supervisord.go +++ b/collector/supervisord.go @@ -16,7 +16,12 @@ package collector import ( + "context" "fmt" + "net" + "net/http" + "net/url" + "time" "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" @@ -27,6 +32,7 @@ import ( var ( supervisordURL = kingpin.Flag("collector.supervisord.url", "XML RPC endpoint.").Default("http://localhost:9001/RPC2").String() + xrpc *xmlrpc.Client ) type supervisordCollector struct { @@ -47,6 +53,21 @@ func NewSupervisordCollector(logger log.Logger) (Collector, error) { subsystem = "supervisord" labelNames = []string{"name", "group"} ) + + if u, err := url.Parse(*supervisordURL); err == nil && u.Scheme == "unix" { + // Fake the URI scheme as http, since net/http.*Transport.roundTrip will complain + // about a non-http(s) transport. + xrpc = xmlrpc.NewClient("http://unix/RPC2") + xrpc.HttpClient.Transport = &http.Transport{ + DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) { + d := net.Dialer{Timeout: 10 * time.Second} + return d.DialContext(ctx, "unix", u.Path) + }, + } + } else { + xrpc = xmlrpc.NewClient(*supervisordURL) + } + return &supervisordCollector{ upDesc: prometheus.NewDesc( prometheus.BuildFQName(namespace, subsystem, "up"), @@ -111,7 +132,7 @@ func (c *supervisordCollector) Update(ch chan<- prometheus.Metric) error { PID int `xmlrpc:"pid"` } - res, err := xmlrpc.Call(*supervisordURL, "supervisor.getAllProcessInfo") + res, err := xrpc.Call("supervisor.getAllProcessInfo") if err != nil { return fmt.Errorf("unable to call supervisord: %s", err) }