From 043484c77775d77c6142ee4dddce74b394bf1981 Mon Sep 17 00:00:00 2001 From: Arun Kumar Mohan Date: Sat, 22 Dec 2018 13:41:54 +0530 Subject: [PATCH 1/3] Initial changes for gluster daemon status metrices Signed-off-by: Arun Kumar Mohan --- gluster-exporter/metric_daemon_status.go | 18 ++++++++++++++++++ pkg/glusterutils/exporterd.go | 12 ++++++++++++ pkg/glusterutils/types.go | 5 +++++ 3 files changed, 35 insertions(+) create mode 100644 gluster-exporter/metric_daemon_status.go diff --git a/gluster-exporter/metric_daemon_status.go b/gluster-exporter/metric_daemon_status.go new file mode 100644 index 0000000..d391081 --- /dev/null +++ b/gluster-exporter/metric_daemon_status.go @@ -0,0 +1,18 @@ +package main + +import ( + "github.com/gluster/gluster-prometheus/pkg/glusterutils" + // "github.com/prometheus/client_golang/prometheus" + log "github.com/sirupsen/logrus" +) + +// MyTestFunc is for testing +func MyTestFunc(gd glusterutils.GInterface) { + var conf *glusterutils.Config + if gdConf, ok := gd.(glusterutils.GDConfigInterface); ok { + conf = gdConf.Config() + } + if conf != nil { + log.Println("GD Management: ", conf.GlusterMgmt) + } +} diff --git a/pkg/glusterutils/exporterd.go b/pkg/glusterutils/exporterd.go index daefb61..cdd96ef 100644 --- a/pkg/glusterutils/exporterd.go +++ b/pkg/glusterutils/exporterd.go @@ -15,6 +15,12 @@ var ( peerIDPattern = regexp.MustCompile("[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}") ) +// Config returns the configuration associated with it +// and makes it compatible with 'GDConfigInterface' +func (g *GD1) Config() *Config { + return g.config +} + // IsLeader returns true or false based on whether the node is the leader of the cluster or not func (g *GD1) IsLeader() (bool, error) { setDefaultConfig(g.config) @@ -42,6 +48,12 @@ func (g *GD1) IsLeader() (bool, error) { return false, nil } +// Config returns the configuration associated with it +// and makes it compatible with 'GDConfigInterface' +func (g *GD2) Config() *Config { + return g.config +} + // IsLeader returns true or false based on whether the node is the leader of the cluster or not func (g *GD2) IsLeader() (bool, error) { peerList, err := g.Peers() diff --git a/pkg/glusterutils/types.go b/pkg/glusterutils/types.go index 986fa8d..32e5a16 100644 --- a/pkg/glusterutils/types.go +++ b/pkg/glusterutils/types.go @@ -134,6 +134,11 @@ type GInterface interface { VolumeBrickStatus(vol string) ([]BrickStatus, error) } +// GDConfigInterface returns the configuration of the GD +type GDConfigInterface interface { + Config() *Config +} + // FopStat defines file ops related details type FopStat struct { Name string From 4a884c78881adf2b6e1f4b78cb516f98cff56a2d Mon Sep 17 00:00:00 2001 From: Arun Kumar Mohan Date: Mon, 24 Dec 2018 15:58:34 +0530 Subject: [PATCH 2/3] [WIP] Added status metrices for gluster daemon and gluster exporter Signed-off-by: Arun Kumar Mohan --- gluster-exporter/metric_daemon_status.go | 120 +++++++++++++++++++++-- pkg/glusterutils/exporterd.go | 10 ++ 2 files changed, 123 insertions(+), 7 deletions(-) diff --git a/gluster-exporter/metric_daemon_status.go b/gluster-exporter/metric_daemon_status.go index d391081..2ac4f11 100644 --- a/gluster-exporter/metric_daemon_status.go +++ b/gluster-exporter/metric_daemon_status.go @@ -1,18 +1,124 @@ package main import ( + "errors" + "io/ioutil" + "net/http" + "strings" + "github.com/gluster/gluster-prometheus/pkg/glusterutils" - // "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus" log "github.com/sirupsen/logrus" ) -// MyTestFunc is for testing -func MyTestFunc(gd glusterutils.GInterface) { +const ( + // GDaemonLabel provides static label to info/error provided from this metrics + GDaemonLabel = "Gluster_Daemon_Status" +) + +func gdStatus(conf *glusterutils.Config) error { + if conf.GlusterMgmt == glusterutils.MgmtGlusterd { + if _, err := glusterutils.ExecuteCmd("ps --no-header -ww -o pid,comm -C glusterd"); err != nil { + return err + } + } else if conf.GlusterMgmt == glusterutils.MgmtGlusterd2 { + if conf.Glusterd2Endpoint == "" { + return errors.New("[" + GDaemonLabel + "] Empty GD2 Endpoint") + } + pingURL := strings.Join([]string{conf.Glusterd2Endpoint, "ping"}, "/") + resp, err := http.Get(pingURL) + if err != nil { + return errors.New("[" + GDaemonLabel + "]" + "Endpoint Get Error: " + err.Error()) + } + _, err = ioutil.ReadAll(resp.Body) + if err != nil { + return errors.New("[" + GDaemonLabel + "]" + "Endpoint Read Error: " + err.Error()) + } + } + return nil +} + +var ( + // metric labels + gdStatusLbl = []MetricLabel{ + { + Name: "name", + Help: "Metric name, for which the status is collected", + }, + { + Name: "gdType", + Help: "Type of gluster daemon / service running (GD1 or GD2)", + }, + { + Name: "peerID", + Help: "Peer ID of the host for which this metric status is updated", + }, + } + gExprtrLbl = []MetricLabel{ + { + Name: "name", + Help: "Metric Name to be collected", + }, + { + Name: "peerID", + Help: "Peer ID of the host, on which the data is collected", + }, + } + glusterDaemonStatus = newPrometheusGaugeVec(Metric{ + Namespace: "gluster", + Name: "daemon_status", + Help: "Status of gluster management daemon (1 = running and 0 = not-running)", + LongHelp: "", + Labels: gdStatusLbl, + }) + glusterExporterStatus = newPrometheusGaugeVec(Metric{ + Namespace: "gluster", + Name: "exporter_status", + Help: "Status of gluster exporter (will be set 1 always)", + LongHelp: "", + Labels: gExprtrLbl, + }) +) + +// gDaemonStatus registering function, +// provides the status of services running on the machine +func gDaemonStatus() error { var conf *glusterutils.Config - if gdConf, ok := gd.(glusterutils.GDConfigInterface); ok { - conf = gdConf.Config() + if gluster == nil { + return errors.New("[" + GDaemonLabel + "] Unable to get a 'GInterface' object") + } + peerID, err := gluster.LocalPeerID() + if err != nil { + return errors.New("[" + GDaemonLabel + "] Getting Peer ID failed: " + err.Error()) + } + conf, err = glusterutils.GDConfigFromInterface(gluster) + if err != nil { + return errors.New("[" + GDaemonLabel + "] Error: " + err.Error()) } - if conf != nil { - log.Println("GD Management: ", conf.GlusterMgmt) + log.Println("GD Management: ", conf.GlusterMgmt) + genrlLbls := prometheus.Labels{ + "name": "Glusterd_Status", + "gdType": conf.GlusterMgmt, + "peerID": peerID, } + err = gdStatus(conf) + if err != nil { + log.WithError(err).WithFields(log.Fields{ + "peer": peerID, + "name": "Glusterd_Status", + }).Errorln("["+GDaemonLabel+"] Error:", err) + glusterDaemonStatus.With(genrlLbls).Set(float64(0)) + } else { + glusterDaemonStatus.With(genrlLbls).Set(float64(1)) + } + genrlLbls = prometheus.Labels{ + "name": "Gluster_Exporter_Status", + "peerID": peerID, + } + glusterExporterStatus.With(genrlLbls).Set(float64(1)) + return nil +} + +func init() { + registerMetric("gluster_daemon_status", gDaemonStatus) } diff --git a/pkg/glusterutils/exporterd.go b/pkg/glusterutils/exporterd.go index cdd96ef..6a84601 100644 --- a/pkg/glusterutils/exporterd.go +++ b/pkg/glusterutils/exporterd.go @@ -15,6 +15,16 @@ var ( peerIDPattern = regexp.MustCompile("[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}") ) +// GDConfigFromInterface checks the given interface is compatible with 'GDConfigInterface' +// and returns a pointer to glusterutils.Config +func GDConfigFromInterface(iFace interface{}) (*Config, error) { + if gdConf, ok := iFace.(GDConfigInterface); ok { + return gdConf.Config(), nil + } + return nil, errors.New("Incompatible interface type, " + + "cannot be converted to 'GDConfigInterface'") +} + // Config returns the configuration associated with it // and makes it compatible with 'GDConfigInterface' func (g *GD1) Config() *Config { From f0a1343c65dbf15c9921c484ec755c024edc81e2 Mon Sep 17 00:00:00 2001 From: Arun Kumar Mohan Date: Tue, 25 Dec 2018 18:56:50 +0530 Subject: [PATCH 3/3] Fixing a metalinter issue Signed-off-by: Arun Kumar Mohan --- gluster-exporter/metric_daemon_status.go | 1 + 1 file changed, 1 insertion(+) diff --git a/gluster-exporter/metric_daemon_status.go b/gluster-exporter/metric_daemon_status.go index 2ac4f11..d25ad1b 100644 --- a/gluster-exporter/metric_daemon_status.go +++ b/gluster-exporter/metric_daemon_status.go @@ -26,6 +26,7 @@ func gdStatus(conf *glusterutils.Config) error { return errors.New("[" + GDaemonLabel + "] Empty GD2 Endpoint") } pingURL := strings.Join([]string{conf.Glusterd2Endpoint, "ping"}, "/") + // #nosec resp, err := http.Get(pingURL) if err != nil { return errors.New("[" + GDaemonLabel + "]" + "Endpoint Get Error: " + err.Error())