open-telemetry / open-telemetry/opentelemetry-python

Metric attributes does not accept all types of sequences

Open
#3,750 8 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Python
Stars
2.6k
Forks
1k
Avg merge
4d 15h
Merged PRs (30d)
19

Description

Describe your environment

Python version: 3.10.10
Opentelemetry-python version: 1.23.0

Steps to reproduce
It is defined in types.py, https://github.com/open-telemetry/opentelemetry-python/blob/main/opentelemetry-api/src/opentelemetry/util/types.py#L18, that we can supply a sequence of say strings as an attribute to a metric. This does not work with lists and sets but using a n-tuple works.

Offending line seems to be: https://github.com/open-telemetry/opentelemetry-python/blob/d01dbc219ce5a853cf72a8854d45701724e334b6/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/_view_instrument_match.py#L98

Below is a minimal example which proves that using an n-tuple works and a list does not.

from opentelemetry import metrics
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
from opentelemetry.sdk.metrics.export import ConsoleMetricExporter

reader = PeriodicExportingMetricReader(ConsoleMetricExporter())
meterProvider = MeterProvider(metric_readers=[reader])
metrics.set_meter_provider(meterProvider)

attributes = {"tuple_attr": ("string", "another_string"), "list_attr": ["string"]}

metrics.get_meter_provider().get_meter("my_test_meter").create_counter("test_counter").add(
    1, attributes=attributes
)

Example output from running the above minimal example:

Traceback (most recent call last):
  File "/home/<REDACTED>/test.py", line 12, in <module>
    metrics.get_meter_provider().get_meter("my_test_meter").create_counter("test_counter").add(
  File "/home/<REDACTED>/lib/python3.10/site-packages/opentelemetry/sdk/metrics/_internal/instrument.py", line 159, in add
    self._measurement_consumer.consume_measurement(
  File "/home/<REDACTED>/lib/python3.10/site-packages/opentelemetry/sdk/metrics/_internal/measurement_consumer.py", line 82, in consume_measurement
    reader_storage.consume_measurement(measurement)
  File "/home/<REDACTED>/lib/python3.10/site-packages/opentelemetry/sdk/metrics/_internal/metric_reader_storage.py", line 120, in consume_measurement
    view_instrument_match.consume_measurement(measurement)
  File "/home/<REDACTED>/lib/python3.10/site-packages/opentelemetry/sdk/metrics/_internal/_view_instrument_match.py", line 98, in consume_measurement
    aggr_key = frozenset(attributes.items())
TypeError: unhashable type: 'list'

What is the expected behavior?
All sequences to work as attributes.

What is the actual behavior?
Not all sequences work as attributes.

Additional context

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

Start with opentelemetry-api/src/opentelemetry/util/types.py and the consume_measurement path in opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/_view_instrument_match.py, especially the line using frozenset(attributes.items()). Reproduce the issue with the provided example, then verify that list and set sequence attributes work like tuple attributes without the unhashable-type error.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
observability
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
62/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.