open-telemetry / open-telemetry/opentelemetry-python

Duplicate Span, sometimes

Open
#3,275 14 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

Steps to reproduce
When I use opentelemetry in python3, sometimes I got duplicate span .
these code used to create tracer:

        from opentelemetry import trace, version
        from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
        from opentelemetry.sdk.resources import Resource
        from opentelemetry.sdk.trace import TracerProvider
        from opentelemetry.sdk.trace.export import BatchSpanProcessor, SimpleSpanProcessor, ConsoleSpanExporter
        from opentelemetry.propagate import set_global_textmap
        from opentelemetry.propagators.b3 import B3Format
        set_global_textmap(B3Format())
        os.environ.setdefault(u'OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT', u'10240')
        resource = Resource(attributes={
            PROCESS_IP_TAG_KEY: local_ip(),
            PROCESS_HOSTNAME_TAG_KEY: host_name(),
            PROCESS_SERVICE_NAME_TAG_KEY: service_name,
            PROCESS_SDK_VERSION_TAG_KEY: u'Opentelemetry-Python-' + version.__version__
        })
        # https://opentelemetry.io/docs/instrumentation/python/exporters/
        trace.set_tracer_provider(TracerProvider(resource=resource))
        otlp_exporter = OTLPSpanExporter(endpoint=u'http://localhost:6831', insecure=True)
        span_processor = BatchSpanProcessor(otlp_exporter)
        trace.get_tracer_provider().add_span_processor(span_processor)
        if is_tracing_print_log():
            trace.get_tracer_provider().add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter()))

        tracer_implements = trace.get_tracer(__name__)

this code used to create span:

        from opentelemetry import trace, baggage
        exist_active_span = trace.get_current_span()
        span = self.tracer_implements.start_span(name, context=parent_span_context)
        span.set_attribute(TAG_PRODUCT_FLAG, product_flag)
        scope = trace.use_span(span, end_on_exit=True)
        setattr(scope, u'__span__', span)
        scope.__enter__()
        return scope

this code used to end span:

        current_scope.__exit__(None, None, None)

Something that needs to be said IT IS NOT 100%, when I restart my server It may be disappeared. But Something when I restart my server again, It may be appear.
I swear It's duplicate by report step. cause console print twice already.
In Jaeger It looks like this:
image

What is the expected behavior?
What happened?

What is the actual behavior?

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 the shown tracer setup and span lifecycle: TracerProvider, the two span processors, start_span, use_span, and current_scope.exit. Compare console exporter output with the Jaeger result across server restarts, and determine whether the duplicate comes from repeated span creation or processor registration. Done means the duplication is consistently reproduced and its source is identified or the issue is shown to be environmental.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
observability
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.