diff --git a/cmd/flagger/main.go b/cmd/flagger/main.go index 2c9f80aeb..463e06dbf 100644 --- a/cmd/flagger/main.go +++ b/cmd/flagger/main.go @@ -135,6 +135,7 @@ func main() { logger, slack, meshProvider, + version.VERSION, ) flaggerInformerFactory.Start(stopCh) diff --git a/docs/gitbook/usage/monitoring.md b/docs/gitbook/usage/monitoring.md index ce38bbd56..4f60151fe 100644 --- a/docs/gitbook/usage/monitoring.md +++ b/docs/gitbook/usage/monitoring.md @@ -46,6 +46,9 @@ Flagger exposes Prometheus metrics that can be used to determine the canary anal the destination weight values: ```bash +# Flagger version and mesh provider gauge +flagger_info{version="0.10.0", mesh_provider="istio"} 1 + # Canaries total gauge flagger_canary_total{namespace="test"} 1 diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 205f9e1e4..c887083a2 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -2,6 +2,7 @@ package controller import ( "fmt" + "github.com/weaveworks/flagger/pkg/metrics" "sync" "time" @@ -42,7 +43,7 @@ type Controller struct { jobs map[string]CanaryJob deployer CanaryDeployer observer CanaryObserver - recorder CanaryRecorder + recorder metrics.CanaryRecorder notifier *notifier.Slack meshProvider string } @@ -57,7 +58,7 @@ func NewController( logger *zap.SugaredLogger, notifier *notifier.Slack, meshProvider string, - + version string, ) *Controller { logger.Debug("Creating event broadcaster") flaggerscheme.AddToScheme(scheme.Scheme) @@ -84,7 +85,8 @@ func NewController( metricsServer: metricServer, } - recorder := NewCanaryRecorder(true) + recorder := metrics.NewCanaryRecorder(controllerAgentName, true) + recorder.SetInfo(version, meshProvider) ctrl := &Controller{ kubeClient: kubeClient, diff --git a/pkg/controller/controller_test.go b/pkg/controller/controller_test.go index 207bb01db..d4f3e4180 100644 --- a/pkg/controller/controller_test.go +++ b/pkg/controller/controller_test.go @@ -8,6 +8,7 @@ import ( fakeFlagger "github.com/weaveworks/flagger/pkg/client/clientset/versioned/fake" informers "github.com/weaveworks/flagger/pkg/client/informers/externalversions" "github.com/weaveworks/flagger/pkg/logging" + "github.com/weaveworks/flagger/pkg/metrics" "github.com/weaveworks/flagger/pkg/router" "go.uber.org/zap" appsv1 "k8s.io/api/apps/v1" @@ -94,7 +95,7 @@ func SetupMocks(abtest bool) Mocks { flaggerWindow: time.Second, deployer: deployer, observer: observer, - recorder: NewCanaryRecorder(false), + recorder: metrics.NewCanaryRecorder(controllerAgentName, false), } ctrl.flaggerSynced = alwaysReady diff --git a/pkg/controller/scheduler.go b/pkg/controller/scheduler.go index e277ed882..ac058b1c3 100644 --- a/pkg/controller/scheduler.go +++ b/pkg/controller/scheduler.go @@ -118,6 +118,7 @@ func (c *Controller) advanceCanary(name string, namespace string, skipLivenessCh } if !shouldAdvance { + c.recorder.SetStatus(cd, cd.Status.Phase) return } diff --git a/pkg/controller/recorder.go b/pkg/metrics/recorder.go similarity index 80% rename from pkg/controller/recorder.go rename to pkg/metrics/recorder.go index 554a345a5..699db5905 100644 --- a/pkg/controller/recorder.go +++ b/pkg/metrics/recorder.go @@ -1,4 +1,4 @@ -package controller +package metrics import ( "fmt" @@ -10,6 +10,7 @@ import ( // CanaryRecorder records the canary analysis as Prometheus metrics type CanaryRecorder struct { + info *prometheus.GaugeVec duration *prometheus.HistogramVec total *prometheus.GaugeVec status *prometheus.GaugeVec @@ -17,34 +18,41 @@ type CanaryRecorder struct { } // NewCanaryRecorder creates a new recorder and registers the Prometheus metrics -func NewCanaryRecorder(register bool) CanaryRecorder { +func NewCanaryRecorder(controller string, register bool) CanaryRecorder { + info := prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Subsystem: controller, + Name: "info", + Help: "Flagger version and mesh provider information", + }, []string{"version", "mesh_provider"}) + duration := prometheus.NewHistogramVec(prometheus.HistogramOpts{ - Subsystem: controllerAgentName, + Subsystem: controller, Name: "canary_duration_seconds", Help: "Seconds spent performing canary analysis.", Buckets: prometheus.DefBuckets, }, []string{"name", "namespace"}) total := prometheus.NewGaugeVec(prometheus.GaugeOpts{ - Subsystem: controllerAgentName, + Subsystem: controller, Name: "canary_total", Help: "Total number of canary object", }, []string{"namespace"}) // 0 - running, 1 - successful, 2 - failed status := prometheus.NewGaugeVec(prometheus.GaugeOpts{ - Subsystem: controllerAgentName, + Subsystem: controller, Name: "canary_status", Help: "Last canary analysis result", }, []string{"name", "namespace"}) weight := prometheus.NewGaugeVec(prometheus.GaugeOpts{ - Subsystem: controllerAgentName, + Subsystem: controller, Name: "canary_weight", Help: "The virtual service destination weight current value", }, []string{"workload", "namespace"}) if register { + prometheus.MustRegister(info) prometheus.MustRegister(duration) prometheus.MustRegister(total) prometheus.MustRegister(status) @@ -52,6 +60,7 @@ func NewCanaryRecorder(register bool) CanaryRecorder { } return CanaryRecorder{ + info: info, duration: duration, total: total, status: status, @@ -59,6 +68,11 @@ func NewCanaryRecorder(register bool) CanaryRecorder { } } +// SetInfo sets the version and mesh provider labels +func (cr *CanaryRecorder) SetInfo(version string, meshProvider string) { + cr.info.WithLabelValues(version, meshProvider).Set(1) +} + // SetDuration sets the time spent in seconds performing canary analysis func (cr *CanaryRecorder) SetDuration(cd *flaggerv1.Canary, duration time.Duration) { cr.duration.WithLabelValues(cd.Spec.TargetRef.Name, cd.Namespace).Observe(duration.Seconds())