From 002463e021c960c7e52565f4b1917700195597c0 Mon Sep 17 00:00:00 2001 From: Dominik Roos Date: Mon, 26 Oct 2020 16:52:31 +0100 Subject: [PATCH] router: add metric to track service instance count (#3918) Add two metrics to track the number of service instances known to the data plane. # HELP router_service_instance_changes_total Number of total service instance changes. Both addition and removal of a service instance is accumulated # TYPE router_service_instance_changes_total counter router_service_instance_changes_total{isd_as="1-ff00:0:110",service="CS"} 11 router_service_instance_changes_total{isd_as="1-ff00:0:110",service="DS"} 11 # HELP router_service_instance_count Number of service instances known by the data plane. # TYPE router_service_instance_count gauge router_service_instance_count{isd_as="1-ff00:0:110",service="CS"} 3 router_service_instance_count{isd_as="1-ff00:0:110",service="DS"} 3 --- go/pkg/router/dataplane.go | 17 +++++++++++++++++ go/pkg/router/metrics.go | 17 +++++++++++++++++ go/posix-router/main.go | 22 +++++++++++----------- 3 files changed, 45 insertions(+), 11 deletions(-) diff --git a/go/pkg/router/dataplane.go b/go/pkg/router/dataplane.go index 1a2311b378..0816a2f191 100644 --- a/go/pkg/router/dataplane.go +++ b/go/pkg/router/dataplane.go @@ -329,6 +329,11 @@ func (d *DataPlane) AddSvc(svc addr.HostSVC, a *net.UDPAddr) error { d.svc = newServices() } d.svc.AddSvc(svc, a) + if d.Metrics != nil { + labels := serviceMetricLabels(d.localIA, svc) + d.Metrics.ServiceInstanceChanges.With(labels).Add(1) + d.Metrics.ServiceInstanceCount.With(labels).Add(1) + } return nil } @@ -343,6 +348,11 @@ func (d *DataPlane) DelSvc(svc addr.HostSVC, a *net.UDPAddr) error { return nil } d.svc.DelSvc(svc, a) + if d.Metrics != nil { + labels := serviceMetricLabels(d.localIA, svc) + d.Metrics.ServiceInstanceChanges.With(labels).Add(1) + d.Metrics.ServiceInstanceCount.With(labels).Add(-1) + } return nil } @@ -1436,3 +1446,10 @@ func interfaceToMetricLabels(id uint16, localIA addr.IA, "neighbor_isd_as": neighbors[id].String(), } } + +func serviceMetricLabels(localIA addr.IA, svc addr.HostSVC) prometheus.Labels { + return prometheus.Labels{ + "isd_as": localIA.String(), + "service": svc.BaseString(), + } +} diff --git a/go/pkg/router/metrics.go b/go/pkg/router/metrics.go index fd047d7349..a9bb86d956 100644 --- a/go/pkg/router/metrics.go +++ b/go/pkg/router/metrics.go @@ -30,6 +30,8 @@ type Metrics struct { BFDInterfaceStateChanges *prometheus.CounterVec BFDPacketsSent *prometheus.CounterVec BFDPacketsReceived *prometheus.CounterVec + ServiceInstanceCount *prometheus.GaugeVec + ServiceInstanceChanges *prometheus.CounterVec SiblingReachable *prometheus.GaugeVec SiblingBFDPacketsSent *prometheus.CounterVec SiblingBFDPacketsReceived *prometheus.CounterVec @@ -104,6 +106,21 @@ func NewMetrics() *Metrics { }, []string{"interface", "isd_as", "neighbor_isd_as"}, ), + ServiceInstanceCount: promauto.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "router_service_instance_count", + Help: "Number of service instances known by the data plane.", + }, + []string{"service", "isd_as"}, + ), + ServiceInstanceChanges: promauto.NewCounterVec( + prometheus.CounterOpts{ + Name: "router_service_instance_changes_total", + Help: "Number of total service instance changes. Both addition and removal of a " + + "service instance is accumulated.", + }, + []string{"service", "isd_as"}, + ), SiblingReachable: promauto.NewGaugeVec( prometheus.GaugeOpts{ Name: "router_sibling_reachable", diff --git a/go/posix-router/main.go b/go/posix-router/main.go index 1e6310b983..0ad69e18e5 100644 --- a/go/posix-router/main.go +++ b/go/posix-router/main.go @@ -30,7 +30,7 @@ import ( "github.com/scionproto/scion/go/lib/serrors" "github.com/scionproto/scion/go/pkg/command" "github.com/scionproto/scion/go/pkg/router" - brconf "github.com/scionproto/scion/go/pkg/router/config" + "github.com/scionproto/scion/go/pkg/router/config" "github.com/scionproto/scion/go/pkg/router/control" "github.com/scionproto/scion/go/pkg/service" ) @@ -52,7 +52,7 @@ func main() { } cmd.AddCommand( command.NewCompletion(cmd), - command.NewSample(cmd, command.NewSampleConfig(&brconf.Config{})), + command.NewSample(cmd, command.NewSampleConfig(&config.Config{})), command.NewVersion(cmd), ) cmd.Flags().StringVar(&flags.config, "config", "", "Configuration file (required)") @@ -72,7 +72,7 @@ func run(file string, metrics *router.Metrics) error { defer log.Flush() defer env.LogAppStopped("BR", fileConfig.General.ID) defer log.HandlePanic() - if err := validateCfg(fileConfig); err != nil { + if err := validateConfig(fileConfig); err != nil { return err } controlConfig, err := loadControlConfig(fileConfig) @@ -115,30 +115,30 @@ func run(file string, metrics *router.Metrics) error { } } -func setupBasic(file string) (brconf.Config, error) { - var cfg brconf.Config +func setupBasic(file string) (config.Config, error) { + var cfg config.Config if err := libconfig.LoadFile(file, &cfg); err != nil { - return brconf.Config{}, serrors.WrapStr("loading config from file", err, "file", file) + return config.Config{}, serrors.WrapStr("loading config from file", err, "file", file) } cfg.InitDefaults() if err := log.Setup(cfg.Logging); err != nil { - return brconf.Config{}, serrors.WrapStr("initialize logging", err) + return config.Config{}, serrors.WrapStr("initialize logging", err) } prom.ExportElementID(cfg.General.ID) if err := env.LogAppStarted("BR", cfg.General.ID); err != nil { - return brconf.Config{}, err + return config.Config{}, err } return cfg, nil } -func validateCfg(cfg brconf.Config) error { +func validateConfig(cfg config.Config) error { if err := cfg.Validate(); err != nil { return serrors.WrapStr("validating config", err) } return nil } -func loadControlConfig(cfg brconf.Config) (*control.Config, error) { +func loadControlConfig(cfg config.Config) (*control.Config, error) { newConf, err := control.LoadConfig(cfg.General.ID, cfg.General.ConfigDir) if err != nil { return nil, serrors.WrapStr("loading topology", err) @@ -146,7 +146,7 @@ func loadControlConfig(cfg brconf.Config) (*control.Config, error) { return newConf, nil } -func setupHTTPHandlers(cfg brconf.Config) error { +func setupHTTPHandlers(cfg config.Config) error { statusPages := service.StatusPages{ "info": service.NewInfoHandler(), "config": service.NewConfigHandler(cfg),