diff --git a/sentry_sdk/integrations/opentelemetry/potel_span_processor.py b/sentry_sdk/integrations/opentelemetry/potel_span_processor.py index 1736fcd25e..14636b9e37 100644 --- a/sentry_sdk/integrations/opentelemetry/potel_span_processor.py +++ b/sentry_sdk/integrations/opentelemetry/potel_span_processor.py @@ -179,8 +179,6 @@ def _root_span_to_transaction_event(self, span): transaction_name, transaction_source = extract_transaction_name_source(span) span_data = extract_span_data(span) - (_, description, status, http_status, _) = span_data - trace_context = get_trace_context(span, span_data=span_data) contexts = {"trace": trace_context} @@ -188,6 +186,8 @@ def _root_span_to_transaction_event(self, span): if profile_context: contexts["profile"] = profile_context + (_, description, _, http_status, _) = span_data + if http_status: contexts["response"] = {"status_code": http_status} diff --git a/sentry_sdk/integrations/opentelemetry/utils.py b/sentry_sdk/integrations/opentelemetry/utils.py index 6127ceba5c..673b334318 100644 --- a/sentry_sdk/integrations/opentelemetry/utils.py +++ b/sentry_sdk/integrations/opentelemetry/utils.py @@ -114,7 +114,6 @@ def extract_span_data(span): description = span.name status, http_status = extract_span_status(span) origin = None - if span.attributes is None: return (op, description, status, http_status, origin) @@ -133,11 +132,23 @@ def extract_span_data(span): rpc_service = span.attributes.get(SpanAttributes.RPC_SERVICE) if rpc_service: - return ("rpc", description, status, http_status, origin) + return ( + span.attributes.get(SentrySpanAttribute.OP) or "rpc", + description, + status, + http_status, + origin, + ) messaging_system = span.attributes.get(SpanAttributes.MESSAGING_SYSTEM) if messaging_system: - return ("message", description, status, http_status, origin) + return ( + span.attributes.get(SentrySpanAttribute.OP) or "message", + description, + status, + http_status, + origin, + ) faas_trigger = span.attributes.get(SpanAttributes.FAAS_TRIGGER) if faas_trigger: diff --git a/sentry_sdk/integrations/rq.py b/sentry_sdk/integrations/rq.py index f32e2c5871..2a2fa81439 100644 --- a/sentry_sdk/integrations/rq.py +++ b/sentry_sdk/integrations/rq.py @@ -6,6 +6,7 @@ from sentry_sdk.integrations.logging import ignore_logger from sentry_sdk.tracing import TRANSACTION_SOURCE_TASK from sentry_sdk.utils import ( + _serialize_span_attribute, capture_internal_exceptions, ensure_integration_enabled, event_from_exception, @@ -192,4 +193,10 @@ def _prepopulate_attributes(job, queue): if getattr(queue, prop, None) is not None: attributes[attr] = getattr(queue, prop) + try: + attributes["rq.job.args"] = _serialize_span_attribute(job.args) + attributes["rq.job.kwargs"] = _serialize_span_attribute(job.kwargs) + except Exception: + pass + return attributes diff --git a/tests/integrations/rq/test_rq.py b/tests/integrations/rq/test_rq.py index 1a9ad55fc3..b972ea2430 100644 --- a/tests/integrations/rq/test_rq.py +++ b/tests/integrations/rq/test_rq.py @@ -118,7 +118,9 @@ def test_transaction_with_error( ) assert envelope["type"] == "transaction" - assert envelope["contexts"]["trace"] == error_event["contexts"]["trace"] + assert envelope["contexts"]["trace"] == DictionaryContaining( + error_event["contexts"]["trace"] + ) assert envelope["transaction"] == error_event["transaction"] assert envelope["extra"]["rq-job"] == DictionaryContaining( { @@ -148,10 +150,7 @@ def test_error_has_trace_context_if_tracing_disabled( assert error_event["contexts"]["trace"] -def test_tracing_enabled( - sentry_init, - capture_events, -): +def test_tracing_enabled(sentry_init, capture_events, DictionaryContaining): sentry_init(integrations=[RqIntegration()], traces_sample_rate=1.0) events = capture_events() @@ -165,12 +164,10 @@ def test_tracing_enabled( assert error_event["transaction"] == "tests.integrations.rq.test_rq.crashing_job" assert transaction["transaction"] == "tests.integrations.rq.test_rq.crashing_job" - for trace_key in error_event["contexts"]["trace"]: - assert trace_key in transaction["contexts"]["trace"] - assert ( - error_event["contexts"]["trace"][trace_key] - == transaction["contexts"]["trace"][trace_key] - ) + assert ( + DictionaryContaining(error_event["contexts"]["trace"]) + == transaction["contexts"]["trace"] + ) def test_tracing_disabled( @@ -223,9 +220,7 @@ def test_transaction_no_error( ) -def test_traces_sampler_gets_correct_values_in_sampling_context( - sentry_init, DictionaryContaining, ObjectDescribedBy # noqa:N803 -): +def test_traces_sampler_gets_correct_values_in_sampling_context(sentry_init): traces_sampler = mock.Mock(return_value=True) sentry_init(integrations=[RqIntegration()], traces_sampler=traces_sampler) @@ -235,22 +230,12 @@ def test_traces_sampler_gets_correct_values_in_sampling_context( queue.enqueue(do_trick, "Bodhi", trick="roll over") worker.work(burst=True) - traces_sampler.assert_any_call( - DictionaryContaining( - { - "rq_job": ObjectDescribedBy( - type=rq.job.Job, - attrs={ - "description": "tests.integrations.rq.test_rq.do_trick('Bodhi', trick='roll over')", - "result": "Bodhi, can you roll over? Good dog!", - "func_name": "tests.integrations.rq.test_rq.do_trick", - "args": ("Bodhi",), - "kwargs": {"trick": "roll over"}, - }, - ), - } - ) - ) + sampling_context = traces_sampler.call_args_list[0][0][0] + assert sampling_context["messaging.system"] == "rq" + assert sampling_context["rq.job.args"] == ["Bodhi"] + assert sampling_context["rq.job.kwargs"] == '{"trick": "roll over"}' + assert sampling_context["messaging.message.id"] + assert sampling_context["messaging.destination.name"] == "default" @pytest.mark.skipif(