Skip to content

Commit 9d693f7

Browse files
committed
Make transaction names work
* while sending the event in the final payload, the transaction name will be picked up from the attributes `sentry.name` or fallback to the `description` when we only have otel instrumentation * for populating DSC in the head case, we are doing a best attempt solution and fetching the transaction name/source from the current and isolation scopes * NOTE that there are cases where this will be inaccurate if we never set the transaction name on the scope in some integration, so we will go through and fix those cases separately.
1 parent a67125a commit 9d693f7

File tree

6 files changed

+59
-7
lines changed

6 files changed

+59
-7
lines changed

sentry_sdk/integrations/opentelemetry/consts.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,5 @@ class SentrySpanAttribute:
2828
MEASUREMENT = "sentry.measurement"
2929
TAG = "sentry.tag"
3030
NAME = "sentry.name"
31+
SOURCE = "sentry.source"
3132
CONTEXT = "sentry.context"

sentry_sdk/integrations/opentelemetry/potel_span_processor.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
convert_from_otel_timestamp,
1919
extract_span_attributes,
2020
extract_span_data,
21+
extract_transaction_name_source,
2122
get_trace_context,
2223
)
2324
from sentry_sdk.integrations.opentelemetry.consts import (
@@ -137,6 +138,7 @@ def _root_span_to_transaction_event(self, span):
137138
if event is None:
138139
return None
139140

141+
transaction_name, transaction_source = extract_transaction_name_source(span)
140142
span_data = extract_span_data(span)
141143
(_, description, _, http_status, _) = span_data
142144

@@ -152,9 +154,8 @@ def _root_span_to_transaction_event(self, span):
152154
event.update(
153155
{
154156
"type": "transaction",
155-
"transaction": description,
156-
# TODO-neel-potel tx source based on integration
157-
"transaction_info": {"source": "custom"},
157+
"transaction": transaction_name or description,
158+
"transaction_info": {"source": transaction_source or "custom"},
158159
"contexts": contexts,
159160
}
160161
)

sentry_sdk/integrations/opentelemetry/utils.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from sentry_sdk.utils import Dsn
2020
from sentry_sdk.consts import SPANSTATUS, OP
2121
from sentry_sdk.tracing import get_span_status_from_http_code, DEFAULT_SPAN_ORIGIN
22-
from sentry_sdk.tracing_utils import Baggage
22+
from sentry_sdk.tracing_utils import Baggage, LOW_QUALITY_TRANSACTION_SOURCES
2323
from sentry_sdk.integrations.opentelemetry.consts import SentrySpanAttribute
2424

2525
from sentry_sdk._types import TYPE_CHECKING
@@ -98,6 +98,16 @@ def convert_to_otel_timestamp(time):
9898
return int(time * 1e9)
9999

100100

101+
def extract_transaction_name_source(span):
102+
# type: (ReadableSpan) -> tuple[Optional[str], Optional[str]]
103+
if not span.attributes:
104+
return (None, None)
105+
return (
106+
cast("Optional[str]", span.attributes.get(SentrySpanAttribute.NAME)),
107+
cast("Optional[str]", span.attributes.get(SentrySpanAttribute.SOURCE)),
108+
)
109+
110+
101111
def extract_span_data(span):
102112
# type: (ReadableSpan) -> OtelExtractedSpanData
103113
op = span.name
@@ -394,5 +404,27 @@ def get_trace_state(span):
394404
Baggage.SENTRY_PREFIX + "public_key", Dsn(options["dsn"]).public_key
395405
)
396406

397-
# TODO-neel-potel head dsc transaction name
407+
# we cannot access the root span in most cases here, so we HAVE to rely on the
408+
# scopes to carry the correct transaction name/source.
409+
# IDEALLY we will always move to using the isolation scope here
410+
# but our integrations do all kinds of stuff with both isolation and current
411+
# so I am keeping both for now as a best attempt solution till we get to a better state.
412+
isolation_scope = sentry_sdk.get_isolation_scope()
413+
current_scope = sentry_sdk.get_current_scope()
414+
if (
415+
current_scope.transaction_name
416+
and current_scope.transaction_source not in LOW_QUALITY_TRANSACTION_SOURCES
417+
):
418+
trace_state = trace_state.update(
419+
Baggage.SENTRY_PREFIX + "transaction", current_scope.transaction_name
420+
)
421+
elif (
422+
isolation_scope.transaction_name
423+
and isolation_scope.transaction_source
424+
not in LOW_QUALITY_TRANSACTION_SOURCES
425+
):
426+
trace_state = trace_state.update(
427+
Baggage.SENTRY_PREFIX + "transaction", isolation_scope.transaction_name
428+
)
429+
398430
return trace_state

sentry_sdk/scope.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,16 @@ def set_transaction_name(self, name, source=None):
741741
if source:
742742
self._transaction_info["source"] = source
743743

744+
@property
745+
def transaction_name(self):
746+
# type: () -> Optional[str]
747+
return self._transaction
748+
749+
@property
750+
def transaction_source(self):
751+
# type: () -> Optional[str]
752+
return self._transaction_info.get("source")
753+
744754
@_attr_setter
745755
def user(self, value):
746756
# type: (Optional[Dict[str, Any]]) -> None

sentry_sdk/tracing.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,12 +1400,18 @@ def name(self, value):
14001400
@property
14011401
def source(self):
14021402
# type: () -> str
1403-
pass
1403+
from sentry_sdk.integrations.opentelemetry.consts import SentrySpanAttribute
1404+
1405+
return (
1406+
self._get_attribute(SentrySpanAttribute.SOURCE) or TRANSACTION_SOURCE_CUSTOM
1407+
)
14041408

14051409
@source.setter
14061410
def source(self, value):
14071411
# type: (str) -> None
1408-
pass
1412+
from sentry_sdk.integrations.opentelemetry.consts import SentrySpanAttribute
1413+
1414+
self._otel_span.set_attribute(SentrySpanAttribute.SOURCE, value)
14091415

14101416
@property
14111417
def start_timestamp(self):

tests/integrations/flask/test_flask.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,12 +751,14 @@ def hi_tx():
751751

752752
assert transaction_event["type"] == "transaction"
753753
assert transaction_event["transaction"] == "hi_tx"
754+
assert transaction_event["transaction_info"] == {"source": "component"}
754755
assert transaction_event["contexts"]["trace"]["status"] == "ok"
755756
assert transaction_event["tags"]["view"] == "yes"
756757
assert transaction_event["tags"]["before_request"] == "yes"
757758

758759
assert message_event["message"] == "hi"
759760
assert message_event["transaction"] == "hi_tx"
761+
assert message_event["transaction_info"] == {"source": "component"}
760762
assert message_event["tags"]["view"] == "yes"
761763
assert message_event["tags"]["before_request"] == "yes"
762764

0 commit comments

Comments
 (0)