Skip to content

Set the correct SpanContext in continue_trace #3475

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions sentry_sdk/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,6 @@ def flush(

def start_span(
*,
span=None,
custom_sampling_context=None,
**kwargs, # type: Any
):
Expand All @@ -255,7 +254,7 @@ def start_span(
method.
"""
# TODO: Consider adding type hints to the method signature.
return get_current_scope().start_span(span, custom_sampling_context, **kwargs)
return get_current_scope().start_span(custom_sampling_context, **kwargs)


def start_transaction(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@ def on_end(self, span):
if is_sentry_span(span):
return

# TODO-neel-potel-remote only take parent if not remote
if span.parent:
if span.parent and not span.parent.is_remote:
self._children_spans[span.parent.span_id].append(span)
else:
# if have a root span ending, we build a transaction and send it
Expand Down
43 changes: 40 additions & 3 deletions sentry_sdk/integrations/opentelemetry/scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
from contextlib import contextmanager

from opentelemetry.context import get_value, set_value, attach, detach, get_current
from opentelemetry.trace import SpanContext, NonRecordingSpan, TraceFlags, use_span

from sentry_sdk.scope import Scope, ScopeType
from sentry_sdk.tracing import POTelSpan
from sentry_sdk.integrations.opentelemetry.consts import (
SENTRY_SCOPES_KEY,
SENTRY_FORK_ISOLATION_SCOPE_KEY,
Expand All @@ -14,6 +16,8 @@
if TYPE_CHECKING:
from typing import Tuple, Optional, Generator, Dict, Any

from sentry_sdk._types import SamplingContext


class PotelScope(Scope):
@classmethod
Expand Down Expand Up @@ -61,10 +65,43 @@ def _get_isolation_scope(cls):
@contextmanager
def continue_trace(self, environ_or_headers):
# type: (Dict[str, Any]) -> Generator[None, None, None]
with new_scope() as scope:
scope.generate_propagation_context(environ_or_headers)
# TODO-neel-potel add remote span on context
self.generate_propagation_context(environ_or_headers)

span_context = self._incoming_otel_span_context()
if span_context is None:
yield
else:
with use_span(NonRecordingSpan(span_context)):
yield

def _incoming_otel_span_context(self):
# type: () -> Optional[SpanContext]
if self._propagation_context is None:
return None
# If sentry-trace extraction didn't have a parent_span_id, we don't have an upstream header
if self._propagation_context.parent_span_id is None:
return None

trace_flags = TraceFlags(
TraceFlags.SAMPLED
if self._propagation_context.parent_sampled
else TraceFlags.DEFAULT
)

# TODO-neel-potel tracestate
span_context = SpanContext(
trace_id=int(self._propagation_context.trace_id, 16), # type: ignore
span_id=int(self._propagation_context.parent_span_id, 16), # type: ignore
is_remote=True,
trace_flags=trace_flags,
)

return span_context

def start_span(self, custom_sampling_context=None, **kwargs):
# type: (Optional[SamplingContext], Any) -> POTelSpan
# TODO-neel-potel ideally want to remove the span argument, discuss with ivana
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the only use for this was using the Transaction from continue_trace, let's get rid of the arg

return POTelSpan(**kwargs, scope=self)


_INITIAL_CURRENT_SCOPE = PotelScope(ty=ScopeType.CURRENT)
Expand Down
9 changes: 5 additions & 4 deletions sentry_sdk/tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from datetime import datetime, timedelta, timezone

from opentelemetry import trace as otel_trace, context
from opentelemetry.trace import format_trace_id, format_span_id
from opentelemetry.trace.status import StatusCode

import sentry_sdk
Expand Down Expand Up @@ -1346,13 +1347,13 @@ def parent_span_id(self):

@property
def trace_id(self):
# type: () -> Optional[str]
return self._otel_span.get_span_context().trace_id
# type: () -> str
return format_trace_id(self._otel_span.get_span_context().trace_id)

@property
def span_id(self):
# type: () -> Optional[str]
return self._otel_span.get_span_context().span_id
# type: () -> str
return format_span_id(self._otel_span.get_span_context().span_id)

@property
def sampled(self):
Expand Down
Loading