prometheus / client_python

Prometheus instrumentation library for Python applications

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

AttributeError: "'Gauge' object has no attribute 'name'"

thomasdraebing opened this issue · comments

Dear all,

I currently get the following error, when trying to expose a metric:

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/wsgiref/handlers.py", line 137, in run
    self.result = application(self.environ, self.start_response)
  File "/root/.local/share/virtualenvs/exporter-Z0zPv-Sy/lib/python3.8/site-packages/prometheus_client/exposition.py", line 129, in prometheus_app
    status, headers, output = _bake_output(registry, accept_header, accept_encoding_header, params, disable_compression)
  File "/root/.local/share/virtualenvs/exporter-Z0zPv-Sy/lib/python3.8/site-packages/prometheus_client/exposition.py", line 105, in _bake_output
    output = encoder(registry)
  File "/root/.local/share/virtualenvs/exporter-Z0zPv-Sy/lib/python3.8/site-packages/prometheus_client/exposition.py", line 200, in generate_latest
    mname = metric.name
AttributeError: ("'Gauge' object has no attribute 'name'", prometheus_client.metrics.Gauge(nfs_total_ops_per_sec))

I can see that metrics have a property _name, but not name. However, since that code is relatively old, I guess that I missed something rather than this being a bug. Help would be much appreciated.

My code looks like this:

from prometheus_client import start_http_server, Gauge, CollectorRegistry
import logging
import sys
import time

import utils.nfsiostat as nfsiostat

class NfsMetricCollector:
    def __init__(self, registry):
        self.stats = {}

        registry.register(self)

        self.total_ops_per_sec_gauge = Gauge(
            name="nfs_total_ops_per_sec",
            documentation="Operations per second on a NFS volume mount",
            labelnames=["server", "share"],
        )

    def collect(self):
        if not self.stats:
            return

        for stat in self.stats.values():
            self.total_ops_per_sec_gauge.labels(stat.server, stat.share).set(
                stat.total_ops_per_sec
            )

        return [self.total_ops_per_sec_gauge]


if __name__ == "__main__":
    registry = CollectorRegistry()
    collector = NfsMetricCollector(registry)
    start_http_server(8000, registry=registry)
    for stat in nfsiostat.stream():
        collector.stats = stat
        time.sleep(60)

Hello,

When you are using a custom collector such as this case you should use a GaugeMetricFamily instead of just a Gauge, you can see the Custom Collectors section of the README for an example. Using a GaugeMetricFamily will return the proper type that has a public .name value.

Thanks for the explanation!