prometheus / prometheus/client_python

Metrics declared at toplevel of program interfere with autoreload

Open
#1,042 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
4.4k
Forks
876
Avg merge
8d 4h
Merged PRs (30d)
1

Description

To reproduce:

  1. Create a file bar.py with contents
from prometheus_client import Gauge

my_gauge = Gauge('my_gauge', 'my description')

def add(x, y):
    return x + y
  1. Create a Jupyter notebook with the contents
%load_ext autoreload
%autoreload 2
from bar import add
# ---- cell break ----
add(2, 3)

and run it.
3. Edit bar.py in some way (e.g. add a product(x, y) function).
4. Re-run the add(2, 3) cell in the notebook

Expected behavior

Autoreload works fine; the cell runs without issue.

Actual behavior

After running add(2, 3) a second time, it prints this error to stderr:

[autoreload of bar failed: Traceback (most recent call last):
  File "/dev/shm/uid-21748-gid-32786/39d5b5d2-seed-nspid4026531836-ns-4026531841/lib/python3.10/site-packages/IPython/extensions/autoreload.py", line 245, in check
    superreload(m, reload, self.old_objects)
  File "/dev/shm/uid-21748-gid-32786/39d5b5d2-seed-nspid4026531836-ns-4026531841/lib/python3.10/site-packages/IPython/extensions/autoreload.py", line 394, in superreload
    module = reload(module)
  File "/dev/shm/uid-21748-gid-32786/39d5b5d2-seed-nspid4026531836-ns-4026531841/lib/python3.10/imp.py", line 315, in reload
    return importlib.reload(module)
  File "/dev/shm/uid-21748-gid-32786/39d5b5d2-seed-nspid4026531836-ns-4026531841/lib/python3.10/importlib/__init__.py", line 169, in reload
    _bootstrap._exec(spec, module)
  File "<frozen importlib._bootstrap>", line 619, in _exec
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/j/igm/user/kstaley/pub/Jupyter/play/bar.py", line 3, in <module>
    my_gauge = Gauge('my_gauge', 'my description')
  File "/dev/shm/uid-21748-gid-32786/39d5b5d2-seed-nspid4026531836-ns-4026531841/lib/python3.10/site-packages/prometheus_client/metrics.py", line 365, in __init__
    super().__init__(
  File "/dev/shm/uid-21748-gid-32786/39d5b5d2-seed-nspid4026531836-ns-4026531841/lib/python3.10/site-packages/prometheus_client/metrics.py", line 143, in __init__
    registry.register(self)
ValueError: Duplicated timeseries in CollectorRegistry: {'my_gauge'}
]

Notes

I think instantiating a metric should be idempotent. If you are passing the exact same metric name, docstring, labels, etc., you should get back the same metric object instance. This would imply having a factory function instead of directly exposing the metric classes. Maybe this behavior could be opt-in if enabling it by default is worrisome.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the issue with bar.py, the Jupyter notebook using IPython autoreload, and prometheus_client.Gauge, then inspect the duplicate CollectorRegistry traceback. Determine the intended behavior for reloading a top-level metric; done should mean rerunning the notebook cell after editing bar.py completes without the duplicated timeseries error.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
observability-sre
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.