Skip to content

Fixing POTel tests #3398

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

Closed
wants to merge 16 commits into from
28 changes: 17 additions & 11 deletions sentry_sdk/api.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import inspect

from sentry_sdk import tracing, tracing_utils, Client
from sentry_sdk import tracing_utils, Client
from sentry_sdk._init_implementation import init
from sentry_sdk.tracing import POTelSpan, Transaction, trace
from sentry_sdk.tracing import Span, trace
from sentry_sdk.crons import monitor

# TODO-neel-potel make 2 scope strategies/impls and switch
Expand All @@ -11,7 +11,6 @@
new_scope,
isolation_scope,
)

from sentry_sdk._types import TYPE_CHECKING

if TYPE_CHECKING:
Expand All @@ -37,7 +36,7 @@
LogLevelStr,
SamplingContext,
)
from sentry_sdk.tracing import Span, TransactionKwargs
from sentry_sdk.tracing import TransactionKwargs

T = TypeVar("T")
F = TypeVar("F", bound=Callable[..., Any])
Expand Down Expand Up @@ -233,22 +232,25 @@ def flush(


def start_span(
*,
root_span=None,
custom_sampling_context=None,
**kwargs, # type: Any
):
# type: (...) -> POTelSpan
# type: (...) -> Span
"""
Alias for tracing.POTelSpan constructor. The method signature is the same.
Start and return a span.
"""
# TODO: Consider adding type hints to the method signature.
return tracing.POTelSpan(**kwargs)
return get_current_scope().start_span(root_span, custom_sampling_context, **kwargs)


def start_transaction(
transaction=None, # type: Optional[Transaction]
transaction=None, # type: Optional[Span]
custom_sampling_context=None, # type: Optional[SamplingContext]
**kwargs, # type: Unpack[TransactionKwargs]
):
# type: (...) -> POTelSpan
# type: (...) -> Span
"""
.. deprecated:: 3.0.0
This function is deprecated and will be removed in a future release.
Expand Down Expand Up @@ -282,7 +284,11 @@ def start_transaction(
constructor. See :py:class:`sentry_sdk.tracing.Transaction` for
available arguments.
"""
return start_span(**kwargs)
return get_current_scope().start_span(
root_span=transaction,
custom_sampling_context=custom_sampling_context,
**kwargs,
)


def set_measurement(name, value, unit=""):
Expand Down Expand Up @@ -323,7 +329,7 @@ def get_baggage():
def continue_trace(
environ_or_headers, op=None, name=None, source=None, origin="manual"
):
# type: (Dict[str, Any], Optional[str], Optional[str], Optional[str], str) -> Transaction
# type: (Dict[str, Any], Optional[str], Optional[str], Optional[str], str) -> Span
"""
Sets the propagation context from environment or headers and returns a transaction.
"""
Expand Down
3 changes: 2 additions & 1 deletion sentry_sdk/integrations/boto3.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import sentry_sdk
from sentry_sdk.consts import OP, SPANDATA
from sentry_sdk.integrations import Integration, DidNotEnable
from sentry_sdk.tracing import Span

from sentry_sdk._types import TYPE_CHECKING
from sentry_sdk.utils import (
Expand All @@ -19,6 +18,8 @@
from typing import Optional
from typing import Type

from sentry_sdk.tracing import Span

try:
from botocore import __version__ as BOTOCORE_VERSION # type: ignore
from botocore.client import BaseClient # type: ignore
Expand Down
13 changes: 6 additions & 7 deletions sentry_sdk/integrations/opentelemetry/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# TODO-neel-potel fix circular imports
# from sentry_sdk.integrations.opentelemetry.span_processor import ( # noqa: F401
# SentrySpanProcessor,
# )
from sentry_sdk.integrations.opentelemetry.span_processor import ( # noqa: F401
SentrySpanProcessor,
)

# from sentry_sdk.integrations.opentelemetry.propagator import ( # noqa: F401
# SentryPropagator,
# )
from sentry_sdk.integrations.opentelemetry.propagator import ( # noqa: F401
SentryPropagator,
)
18 changes: 9 additions & 9 deletions sentry_sdk/integrations/opentelemetry/potel_span_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from sentry_sdk import capture_event
from sentry_sdk.integrations.opentelemetry.utils import (
is_sentry_span,
convert_otel_timestamp,
convert_from_otel_timestamp,
extract_span_data,
)
from sentry_sdk.integrations.opentelemetry.consts import (
Expand Down Expand Up @@ -116,12 +116,12 @@ def _root_span_to_transaction_event(self, span):
span_id = format_span_id(span.context.span_id)
parent_span_id = format_span_id(span.parent.span_id) if span.parent else None

(op, description, status, _) = extract_span_data(span)
(op, description, status, _, origin) = extract_span_data(span)

trace_context = {
"trace_id": trace_id,
"span_id": span_id,
"origin": SPAN_ORIGIN,
"origin": origin,
"op": op,
"status": status,
} # type: dict[str, Any]
Expand All @@ -141,8 +141,8 @@ def _root_span_to_transaction_event(self, span):
# TODO-neel-potel tx source based on integration
"transaction_info": {"source": "custom"},
"contexts": contexts,
"start_timestamp": convert_otel_timestamp(span.start_time),
"timestamp": convert_otel_timestamp(span.end_time),
"start_timestamp": convert_from_otel_timestamp(span.start_time),
"timestamp": convert_from_otel_timestamp(span.end_time),
} # type: Event

return event
Expand All @@ -160,17 +160,17 @@ def _span_to_json(self, span):
span_id = format_span_id(span.context.span_id)
parent_span_id = format_span_id(span.parent.span_id) if span.parent else None

(op, description, status, _) = extract_span_data(span)
(op, description, status, _, origin) = extract_span_data(span)

span_json = {
"trace_id": trace_id,
"span_id": span_id,
"origin": SPAN_ORIGIN,
"op": op,
"description": description,
"status": status,
"start_timestamp": convert_otel_timestamp(span.start_time),
"timestamp": convert_otel_timestamp(span.end_time),
"start_timestamp": convert_from_otel_timestamp(span.start_time),
"timestamp": convert_from_otel_timestamp(span.end_time),
"origin": origin or SPAN_ORIGIN,
} # type: dict[str, Any]

if parent_span_id:
Expand Down
7 changes: 4 additions & 3 deletions sentry_sdk/integrations/opentelemetry/span_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
INVALID_SPAN_ID,
INVALID_TRACE_ID,
)
from sentry_sdk import get_client, start_transaction
from sentry_sdk.integrations.opentelemetry.consts import (
SENTRY_BAGGAGE_KEY,
SENTRY_TRACE_KEY,
Expand Down Expand Up @@ -106,6 +105,8 @@ def _prune_old_spans(self):

def on_start(self, otel_span, parent_context=None):
# type: (OTelSpan, Optional[context_api.Context]) -> None
from sentry_sdk import get_client, start_transaction

client = get_client()

if not client.dsn:
Expand Down Expand Up @@ -258,7 +259,7 @@ def _update_span_with_otel_data(self, sentry_span, otel_span):
for key, val in otel_span.attributes.items():
sentry_span.set_data(key, val)

(op, description, status, http_status) = extract_span_data(otel_span)
(op, description, status, http_status, _) = extract_span_data(otel_span)
sentry_span.op = op
sentry_span.description = description

Expand All @@ -269,7 +270,7 @@ def _update_span_with_otel_data(self, sentry_span, otel_span):

def _update_transaction_with_otel_data(self, sentry_span, otel_span):
# type: (SentrySpan, OTelSpan) -> None
(op, _, status, http_status) = extract_span_data(otel_span)
(op, _, status, http_status, _) = extract_span_data(otel_span)
sentry_span.op = op

if http_status:
Expand Down
47 changes: 30 additions & 17 deletions sentry_sdk/integrations/opentelemetry/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
from opentelemetry.sdk.trace import ReadableSpan
from sentry_sdk.consts import SPANSTATUS
from sentry_sdk.tracing import get_span_status_from_http_code
from sentry_sdk.integrations.opentelemetry.consts import SentrySpanAttribute
from urllib3.util import parse_url as urlparse

from sentry_sdk import get_client
from sentry_sdk.utils import Dsn

from sentry_sdk._types import TYPE_CHECKING
Expand Down Expand Up @@ -43,6 +43,8 @@ def is_sentry_span(span):
Break infinite loop:
HTTP requests to Sentry are caught by OTel and send again to Sentry.
"""
from sentry_sdk import get_client

if not span.attributes:
return False

Expand Down Expand Up @@ -70,19 +72,32 @@ def is_sentry_span(span):
return False


def convert_otel_timestamp(time):
def convert_from_otel_timestamp(time):
# type: (int) -> datetime
"""Convert an OTel ns-level timestamp to a datetime."""
return datetime.fromtimestamp(time / 1e9, timezone.utc)


def convert_to_otel_timestamp(time):
# type: (Union[datetime.datetime, float]) -> int
"""Convert a datetime to an OTel timestamp (with ns precision)."""
if isinstance(time, datetime):
return int(time.timestamp() * 1e9)
return int(time * 1e9)


def extract_span_data(span):
# type: (ReadableSpan) -> tuple[str, str, Optional[str], Optional[int]]
# type: (ReadableSpan) -> tuple[str, str, Optional[str], Optional[int], Optional[str]]
op = span.name
description = span.name
status, http_status = extract_span_status(span)
origin = None

if span.attributes is None:
return (op, description, status, http_status)
return (op, description, status, http_status, origin)

origin = span.attributes.get(SentrySpanAttribute.ORIGIN)
description = span.attributes.get(SentrySpanAttribute.DESCRIPTION) or description

http_method = span.attributes.get(SpanAttributes.HTTP_METHOD)
http_method = cast("Optional[str]", http_method)
Expand All @@ -95,26 +110,21 @@ def extract_span_data(span):

rpc_service = span.attributes.get(SpanAttributes.RPC_SERVICE)
if rpc_service:
return ("rpc", description, status, http_status)
return ("rpc", description, status, http_status, origin)

messaging_system = span.attributes.get(SpanAttributes.MESSAGING_SYSTEM)
if messaging_system:
return ("message", description, status, http_status)
return ("message", description, status, http_status, origin)

faas_trigger = span.attributes.get(SpanAttributes.FAAS_TRIGGER)
if faas_trigger:
return (
str(faas_trigger),
description,
status,
http_status,
)
return (str(faas_trigger), description, status, http_status, origin)

return (op, description, status, http_status)
return (op, description, status, http_status, origin)


def span_data_for_http_method(span):
# type: (ReadableSpan) -> tuple[str, str, Optional[str], Optional[int]]
# type: (ReadableSpan) -> tuple[str, str, Optional[str], Optional[int], Optional[str]]
span_attributes = span.attributes or {}

op = "http"
Expand Down Expand Up @@ -150,11 +160,13 @@ def span_data_for_http_method(span):

status, http_status = extract_span_status(span)

return (op, description, status, http_status)
origin = span_attributes.get(SentrySpanAttribute.ORIGIN)

return (op, description, status, http_status, origin)


def span_data_for_db_query(span):
# type: (ReadableSpan) -> tuple[str, str, Optional[str], Optional[int]]
# type: (ReadableSpan) -> tuple[str, str, Optional[str], Optional[int], Optional[str]]
span_attributes = span.attributes or {}

op = "db"
Expand All @@ -163,8 +175,9 @@ def span_data_for_db_query(span):
statement = cast("Optional[str]", statement)

description = statement or span.name
origin = span_attributes.get(SentrySpanAttribute.ORIGIN)

return (op, description, None, None)
return (op, description, None, None, origin)


def extract_span_status(span):
Expand Down
6 changes: 3 additions & 3 deletions sentry_sdk/integrations/wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def __call__(self, environ, start_response):
)
)

transaction = continue_trace(
root_span = continue_trace(
environ,
op=OP.HTTP_SERVER,
name="generic WSGI request",
Expand All @@ -100,13 +100,13 @@ def __call__(self, environ, start_response):
)

with sentry_sdk.start_transaction(
transaction, custom_sampling_context={"wsgi_environ": environ}
root_span, custom_sampling_context={"wsgi_environ": environ}
):
try:
response = self.app(
environ,
partial(
_sentry_start_response, start_response, transaction
_sentry_start_response, start_response, root_span
),
)
except BaseException:
Expand Down
Loading
Loading