...

Source file src/github.com/chaos-mesh/chaos-mesh/controllers/metrics/metrics.go

Documentation: github.com/chaos-mesh/chaos-mesh/controllers/metrics

     1  // Copyright 2020 Chaos Mesh Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package metrics
    15  
    16  import (
    17  	"context"
    18  
    19  	"github.com/prometheus/client_golang/prometheus"
    20  	ctrl "sigs.k8s.io/controller-runtime"
    21  	"sigs.k8s.io/controller-runtime/pkg/cache"
    22  
    23  	"github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
    24  )
    25  
    26  var log = ctrl.Log.WithName("metrics-collector")
    27  
    28  // ChaosCollector implements prometheus.Collector interface
    29  type ChaosCollector struct {
    30  	store               cache.Cache
    31  	experimentStatus    *prometheus.GaugeVec
    32  	SidecarTemplates    prometheus.Gauge
    33  	ConfigTemplates     *prometheus.GaugeVec
    34  	InjectionConfigs    *prometheus.GaugeVec
    35  	TemplateNotExist    *prometheus.CounterVec
    36  	TemplateLoadError   prometheus.Counter
    37  	ConfigNameDuplicate *prometheus.CounterVec
    38  	InjectRequired      *prometheus.CounterVec
    39  	Injections          *prometheus.CounterVec
    40  }
    41  
    42  // NewChaosCollector initializes metrics and collector
    43  func NewChaosCollector(store cache.Cache, registerer prometheus.Registerer) *ChaosCollector {
    44  	c := &ChaosCollector{
    45  		store: store,
    46  		experimentStatus: prometheus.NewGaugeVec(prometheus.GaugeOpts{
    47  			Name: "chaos_mesh_experiments",
    48  			Help: "Total number of chaos experiments and their phases",
    49  		}, []string{"namespace", "kind", "phase"}),
    50  		SidecarTemplates: prometheus.NewGauge(prometheus.GaugeOpts{
    51  			Name: "chaos_mesh_templates",
    52  			Help: "Total number of injection templates",
    53  		}),
    54  		ConfigTemplates: prometheus.NewGaugeVec(prometheus.GaugeOpts{
    55  			Name: "chaos_mesh_config_templates",
    56  			Help: "Total number of config templates",
    57  		}, []string{"namespace", "template"}),
    58  		InjectionConfigs: prometheus.NewGaugeVec(prometheus.GaugeOpts{
    59  			Name: "chaos_mesh_injection_configs",
    60  			Help: "Total number of injection configs",
    61  		}, []string{"namespace", "template"}),
    62  		TemplateNotExist: prometheus.NewCounterVec(prometheus.CounterOpts{
    63  			Name: "chaos_mesh_template_not_exist_total",
    64  			Help: "Total number of template not exist error",
    65  		}, []string{"namespace", "template"}),
    66  		ConfigNameDuplicate: prometheus.NewCounterVec(prometheus.CounterOpts{
    67  			Name: "chaos_mesh_config_name_duplicate_total",
    68  			Help: "Total number of config name duplication error",
    69  		}, []string{"namespace", "config"}),
    70  		TemplateLoadError: prometheus.NewCounter(prometheus.CounterOpts{
    71  			Name: "chaos_mesh_template_load_failed_total",
    72  			Help: "Total number of failures when rendering config args to template",
    73  		}),
    74  		InjectRequired: prometheus.NewCounterVec(prometheus.CounterOpts{
    75  			Name: "chaos_mesh_inject_required_total",
    76  			Help: "Total number of injections required",
    77  		}, []string{"namespace", "config"}),
    78  		Injections: prometheus.NewCounterVec(prometheus.CounterOpts{
    79  			Name: "chaos_mesh_injections_total",
    80  			Help: "Total number of sidecar injections performed on the webhook",
    81  		}, []string{"namespace", "config"}),
    82  	}
    83  	registerer.MustRegister(c)
    84  	return c
    85  }
    86  
    87  // Describe implements the prometheus.Collector interface.
    88  func (c *ChaosCollector) Describe(ch chan<- *prometheus.Desc) {
    89  	c.experimentStatus.Describe(ch)
    90  	c.SidecarTemplates.Describe(ch)
    91  	c.ConfigTemplates.Describe(ch)
    92  	c.InjectionConfigs.Describe(ch)
    93  	c.TemplateNotExist.Describe(ch)
    94  	c.ConfigNameDuplicate.Describe(ch)
    95  	c.TemplateLoadError.Describe(ch)
    96  	c.InjectRequired.Describe(ch)
    97  	c.Injections.Describe(ch)
    98  }
    99  
   100  // Collect implements the prometheus.Collector interface.
   101  func (c *ChaosCollector) Collect(ch chan<- prometheus.Metric) {
   102  	c.collect()
   103  	c.SidecarTemplates.Collect(ch)
   104  	c.ConfigTemplates.Collect(ch)
   105  	c.InjectionConfigs.Collect(ch)
   106  	c.TemplateNotExist.Collect(ch)
   107  	c.ConfigNameDuplicate.Collect(ch)
   108  	c.TemplateLoadError.Collect(ch)
   109  	c.InjectRequired.Collect(ch)
   110  	c.Injections.Collect(ch)
   111  	c.experimentStatus.Collect(ch)
   112  }
   113  
   114  func (c *ChaosCollector) collect() {
   115  	// TODO(yeya24) if there is an error in List
   116  	// the experiment status will be lost
   117  	c.experimentStatus.Reset()
   118  
   119  	for kind, obj := range v1alpha1.AllKinds() {
   120  		expCache := map[string]map[string]int{}
   121  		if err := c.store.List(context.TODO(), obj.ChaosList); err != nil {
   122  			log.Error(err, "failed to list chaos", "kind", kind)
   123  			return
   124  		}
   125  		for _, chaos := range obj.ListChaos() {
   126  			if _, ok := expCache[chaos.Namespace]; !ok {
   127  				// There is only 4 supported phases
   128  				expCache[chaos.Namespace] = make(map[string]int, 4)
   129  			}
   130  			expCache[chaos.Namespace][chaos.Status]++
   131  		}
   132  
   133  		for ns, v := range expCache {
   134  			for phase, count := range v {
   135  				c.experimentStatus.WithLabelValues(ns, kind, phase).Set(float64(count))
   136  			}
   137  		}
   138  	}
   139  }
   140