PureStorage-OpenConnect / pure-exporter

Prometheus exporter for Pure Storage FlashArray and FlashBlade. DEPRECATED IN FAVOR OF FA AND FB OPENMETRICS EXPORTERS
Apache License 2.0
29 stars 20 forks source link

Labels are not being passed as tuples #25

Closed rsaeta closed 3 years ago

rsaeta commented 3 years ago

In the metrics registration for at least array_space_metrics, the labels (of which there is a single one, "dimension"), the label value is not being passed as a list or tuple, but rather the string rep. This causes the metrics to come in with a single letter for dimension instead of the whole dimension name, which causes overwriting in the case of:

finkr commented 3 years ago

The affected labels are:

count({__name__=~"pure.*",dimension=~"."}) by (__name__)
purefa_array_performance_bandwidth_bytes{}
purefa_array_performance_iops{}
purefa_array_performance_latency_usec{}
purefa_array_space_used_bytes{}
purefa_array_performance_avg_block_bytes{}

Where dimension can be one of: r, w, l, q, s, v, m (on my installation).

rsaeta commented 3 years ago

Yep here's my gist for an update to the array_space file:

from prometheus_client.core import GaugeMetricFamily
from . import mappings

class ArraySpaceMetrics():
    """
    Base class for FlashArray Prometheus array space metrics
    """
    def __init__(self, fa):
        self.fa = fa
        self.data_reduction = GaugeMetricFamily('purefa_array_space_datareduction_ratio',
                                                'FlashArray overall data reduction',
                                                labels=['dimension'],
                                                unit='ratio')
        self.capacity = GaugeMetricFamily('purefa_array_space_capacity_bytes',
                                          'FlashArray overall space capacity',
                                          labels=['dimension'])
        self.provisioned = GaugeMetricFamily('purefa_array_space_provisioned_bytes',
                                             'FlashArray overall provisioned space',
                                             labels=['dimension'])
        self.used = GaugeMetricFamily('purefa_array_space_used_bytes',
                                      'FlashArray overall used space',
                                      labels=['dimension'])

    def _data_reduction(self):
        """
        Create metrics of gauge type for array data reduction.
        Metrics values can be iterated over.
        """
        for k in mappings.array_drr_mapping:
            self.data_reduction.add_metric((mappings.array_drr_mapping[k], ),
                                           self.fa.get_array_elem(k) if self.fa.get_array_elem(k) is not None else 0)

    def _capacity(self):
        """
        Create metrics of gauge type for array capacity indicators.
        Metrics values can be iterated over.
        """
        for k in mappings.array_capacity_mapping:
            self.capacity.add_metric((mappings.array_capacity_mapping[k], ),
                                     self.fa.get_array_elem(k) if self.fa.get_array_elem(k) is not None else 0)

    def _provisioned(self):
        """
        Create metrics of gauge type for array provisioned space indicators.
        Metrics values can be iterated over.
        """
        for k in mappings.array_provisioned_mapping:
            self.provisioned.add_metric((mappings.array_provisioned_mapping[k], ),
                                        self.fa.get_array_elem(k) if self.fa.get_array_elem(k) is not None else 0)

    def _used(self):
        """
        Create metrics of gauge type for array used space indicators.
        Metrics values can be iterated over.
        """
        for k in mappings.array_used_mapping:
            labels = (mappings.array_used_mapping[k], )
            self.used.add_metric(labels,
                                 self.fa.get_array_elem(k) if self.fa.get_array_elem(k) is not None else 0)

    def get_metrics(self):
        self._data_reduction()
        self._capacity()
        self._provisioned()
        self._used()
        yield self.data_reduction
        yield self.capacity
        yield self.provisioned
        yield self.used
genegr commented 3 years ago

Thanks for spotting the issue. It is now fixed in version 1.2.3

rsaeta commented 3 years ago

Thanks for addressing promptly @genegr !