open-telemetry / open-telemetry/opentelemetry-python

View identity-conflict warning never fires when the conflicting views match the same instrument

Open
#5,627 0 comments 0 reactions 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
  • OS: any (verified on macOS)
  • Python version: any supported (verified on Python 3.10)
  • SDK version: current main (96df63ad); the gap exists since the warning was introduced in #2608
  • API version: same as SDK
What happened?

MetricReaderStorage._handle_view_instrument_match warns when a new
_ViewInstrumentMatch conflicts with an existing one ("Views %s and %s will
cause conflicting metrics identities"). The conflict check only iterates
self._instrument_view_instrument_matches.values() — the matches of
previously seen instruments. The list being built for the current
instrument is only written into that dict after all views are processed
(_get_or_init_view_instrument_match), so when two views match the same
instrument and produce identical stream identities, the conflict is invisible
to the check: both streams are exported under the same name in one payload and
nothing is logged.

The spec requires the warning
(https://opentelemetry.io/docs/specs/otel/metrics/sdk/#view):

If applying the View results in conflicting metric identities the
implementation SHOULD apply the View and emit a warning.

The SDK does the "apply" half (both streams are exported) but skips the
"emit a warning" half in exactly the case that is easiest to hit — e.g. two
views selecting different attribute_keys for the same instrument without
renaming one of them.

Steps to Reproduce
import logging

from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import InMemoryMetricReader
from opentelemetry.sdk.metrics.view import View

logging.basicConfig(level=logging.WARNING)

reader = InMemoryMetricReader()
mp = MeterProvider(
    metric_readers=[reader],
    views=[
        View(instrument_name="requests", attribute_keys={"path"}),
        View(instrument_name="requests", attribute_keys={"method"}),
    ],
)
counter = mp.get_meter("m").create_counter("requests", unit="1")
counter.add(1, {"path": "/a", "method": "GET"})

md = reader.get_metrics_data()
print([m.name for m in md.resource_metrics[0].scope_metrics[0].metrics])
# ['requests', 'requests'] — duplicate identity in one payload, no warning

Control: the same conflict split across two instruments
(View(instrument_name="c1", name="foo") + View(instrument_name="c2", name="foo")) does log the warning, so only the same-instrument path is affected.

Expected Result

A "Views ... will cause conflicting metrics identities" warning is emitted,
the same as when the conflicting views match different instruments.

Actual Result

No warning. Two metrics with identical identity (same name, unit, aggregation)
are silently exported in the same payload, which backends treat as a duplicate
/ conflicting stream.

Additional context

Proposed fix (I have a branch ready and can open a PR): include the
in-progress view_instrument_matches list in the conflict scan, e.g.

for existing_view_instrument_matches in (
    *self._instrument_view_instrument_matches.values(),
    view_instrument_matches,
):

plus two tests extending the existing test_view_instrument_match_conflict_*
series (same-instrument conflict warns; same instrument with different view
names does not).

Would you like to implement a fix?

Yes

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 at MetricReaderStorage._handle_view_instrument_match and trace how get_or_init_view_instrument_match records matches for the current instrument. Run the existing test_view_instrument_match_conflict* series first. Done means a same-instrument identity conflict emits the warning, while different view names for the same instrument do not.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.