diff --git a/cmd/ris-mirror/main.go b/cmd/ris-mirror/main.go index 7857d05683c13f337aabaf0e621c29163fce83db..25540961a26a892954494e67619c1c3a0e773b04 100644 --- a/cmd/ris-mirror/main.go +++ b/cmd/ris-mirror/main.go @@ -9,6 +9,7 @@ import ( "github.com/bio-routing/bio-rd/cmd/ris-mirror/rismirror" pb "github.com/bio-routing/bio-rd/cmd/ris/api" "github.com/bio-routing/bio-rd/cmd/ris/risserver" + prom_grpc_cm "github.com/bio-routing/bio-rd/metrics/grpc/clientmanager/adapter/prom" prom_ris_mirror "github.com/bio-routing/bio-rd/metrics/ris-mirror/adapter/prom" "github.com/bio-routing/bio-rd/util/grpc/clientmanager" "github.com/bio-routing/bio-rd/util/servicewrapper" @@ -49,6 +50,7 @@ func main() { m := rismirror.New() prometheus.MustRegister(prom_ris_mirror.NewCollector(m)) + prometheus.MustRegister(prom_grpc_cm.NewCollector(grpcClientManager)) for _, rcfg := range cfg.RIBConfigs { for _, vrdRD := range rcfg.GetVRFs() { diff --git a/metrics/grpc/clientmanager/adapter/prom/clientmanager_prom.go b/metrics/grpc/clientmanager/adapter/prom/clientmanager_prom.go new file mode 100644 index 0000000000000000000000000000000000000000..7473284c123b16212339bcc1f75e352321435083 --- /dev/null +++ b/metrics/grpc/clientmanager/adapter/prom/clientmanager_prom.go @@ -0,0 +1,44 @@ +package prom + +import ( + "github.com/bio-routing/bio-rd/util/grpc/clientmanager" + "github.com/prometheus/client_golang/prometheus" +) + +const ( + prefix = "bio_grpc_clientmanager_" +) + +var ( + connectionStateDesc *prometheus.Desc +) + +func init() { + labels := []string{"target"} + connectionStateDesc = prometheus.NewDesc(prefix+"connection_state", "Connection state, 0=IDLE,1=CONNECTING,2=READY,3=TRANSIENT_FAILURE,4=SHUTDOWN", labels, nil) +} + +// NewCollector creates a new collector instance for the given clientmanager +func NewCollector(cm *clientmanager.ClientManager) prometheus.Collector { + return &grpcClientManagerCollector{ + cm: cm, + } +} + +// grpcClientManagerCollector provides a collector for RIS metrics of BIO to use with Prometheus +type grpcClientManagerCollector struct { + cm *clientmanager.ClientManager +} + +// Describe conforms to the prometheus collector interface +func (c *grpcClientManagerCollector) Describe(ch chan<- *prometheus.Desc) { + ch <- connectionStateDesc +} + +// Collect conforms to the prometheus collector interface +func (c *grpcClientManagerCollector) Collect(ch chan<- prometheus.Metric) { + for _, con := range c.cm.Metrics().Connections { + l := []string{con.Target} + ch <- prometheus.MustNewConstMetric(connectionStateDesc, prometheus.GaugeValue, float64(con.State), l...) + } +} diff --git a/util/grpc/clientmanager/clientmanager.go b/util/grpc/clientmanager/clientmanager.go index e70a6b6d6061afcf9eac9a7f0204052c2542adcf..ef01eb70575f4913e5fe2ee3174630f0b2381f25 100644 --- a/util/grpc/clientmanager/clientmanager.go +++ b/util/grpc/clientmanager/clientmanager.go @@ -4,6 +4,7 @@ import ( "fmt" "sync" + "github.com/bio-routing/bio-rd/util/grpc/clientmanager/metrics" "github.com/pkg/errors" "google.golang.org/grpc" ) @@ -50,3 +51,19 @@ func (cm *ClientManager) Add(target string, opts ...grpc.DialOption) error { cm.connections[target] = cc return nil } + +// Metrics gets ClientManager metrics +func (cm *ClientManager) Metrics() *metrics.ClientManagerMetrics { + ret := metrics.New() + cm.connectionsMu.RLock() + defer cm.connectionsMu.RUnlock() + + for t, c := range cm.connections { + ret.Connections = append(ret.Connections, &metrics.GRPCConnectionMetrics{ + Target: t, + State: int(c.GetState()), + }) + } + + return ret +} diff --git a/util/grpc/clientmanager/metrics/clientmanager_metrics.go b/util/grpc/clientmanager/metrics/clientmanager_metrics.go new file mode 100644 index 0000000000000000000000000000000000000000..01cf5b63cb054f601aefc03ed49b6990c8323385 --- /dev/null +++ b/util/grpc/clientmanager/metrics/clientmanager_metrics.go @@ -0,0 +1,19 @@ +package metrics + +// ClientManagerMetrics provides metrics for a single ClientManager instance +type ClientManagerMetrics struct { + Connections []*GRPCConnectionMetrics +} + +// New returns ClientManagerMetrics +func New() *ClientManagerMetrics { + return &ClientManagerMetrics{ + Connections: make([]*GRPCConnectionMetrics, 0), + } +} + +// GRPCConnectionMetrics represents metrics of an GRPC connection +type GRPCConnectionMetrics struct { + Target string + State int +}