]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
Merge pull request #36298 from p-se/mgr-prom-collect-time-metric
authorKefu Chai <kchai@redhat.com>
Mon, 15 Mar 2021 09:11:55 +0000 (17:11 +0800)
committerGitHub <noreply@github.com>
Mon, 15 Mar 2021 09:11:55 +0000 (17:11 +0800)
mgr/prometheus: introduce metric for collection time

Reviewed-by: Mykola Golub <mgolub@suse.com>
Reviewed-by: Ernesto Puerta <epuertat@redhat.com>
Reviewed-by: Kefu Chai <kchai@redhat.com>
1  2 
src/pybind/mgr/prometheus/module.py

index ea4b59c2439888efdacc2dce0356ee22128d6bab,3f29b175d87102f7d922f0d2f5728691901c060a..fd1fa59487c4e513986a7cb755307e928e3184e0
@@@ -187,8 -184,27 +187,26 @@@ class Metric(object)
          return expfmt
  
  
+ class MetricCounter(Metric):
+     def __init__(self, name, desc, labels=None):
+         super(MetricCounter, self).__init__('counter', name, desc, labels)
+         self.value = defaultdict(lambda: 0)
+     def clear(self):
+         pass  # Skip calls to clear as we want to keep the counters here.
+     def set(self, value, labelvalues=None):
+         msg = 'This method must not be used for instances of MetricCounter class'
+         raise NotImplementedError(msg)
+     def add(self, value, labelvalues=None):
+         # labelvalues must be a tuple
+         labelvalues = labelvalues or ('',)
+         self.value[labelvalues] += value
  class MetricCollectionThread(threading.Thread):
 -    def __init__(self, module):
 -        # type: (Module) -> None
 +    def __init__(self, module: 'Module') -> None:
          self.mod = module
          self.active = True
          self.event = threading.Event()
@@@ -1101,8 -1124,34 +1121,34 @@@ class Module(MgrModule)
  
          self.metrics.update(new_metrics)
  
+     def get_collect_time_metrics(self):
+         if 'prometheus_collect_duration_seconds_sum' not in self.metrics:
+             self.metrics['prometheus_collect_duration_seconds_sum'] = MetricCounter(
+                 'prometheus_collect_duration_seconds_sum',
+                 'The sum of seconds took to collect all metrics of this exporter',
+                 ('method',),
+             )
+         if 'prometheus_collect_duration_seconds_count' not in self.metrics:
+             self.metrics['prometheus_collect_duration_seconds_count'] = MetricCounter(
+                 'prometheus_collect_duration_seconds_count',
+                 'The amount of metrics gathered for this exporter',
+                 ('method',),
+             )
+         # Collect all timing data and make it available as metric, excluding the
+         # `collect` method because it has not finished at this point and hence
+         # there's no `_execution_duration` attribute to be found. The
+         # `_execution_duration` attribute is added by the `profile_method`
+         # decorator.
+         for method_name, method in Module.__dict__.items():
+             if hasattr(method, '_execution_duration'):
+                 self.metrics['prometheus_collect_duration_seconds_sum'].add(
+                     method._execution_duration, (method_name, ))
+                 self.metrics['prometheus_collect_duration_seconds_count'].add(
+                     1, (method_name, ))
      @profile_method(True)
 -    def collect(self):
 +    def collect(self) -> str:
          # Clear the metrics before scraping
          for k in self.metrics.keys():
              self.metrics[k].clear()