Skip to content

Deprecate Span.set_data() #4261

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 4 commits into from
Apr 9, 2025
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: 2 additions & 1 deletion MIGRATION_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh

### Deprecated

- `sentry_sdk.start_transaction` is deprecated. Use `sentry_sdk.start_span` instead.
- `sentry_sdk.start_transaction()` is deprecated. Use `sentry_sdk.start_span()` instead.
- `Span.set_data()` is deprecated. Use `Span.set_attribute()` instead.

## Upgrading to 2.0

Expand Down
10 changes: 5 additions & 5 deletions sentry_sdk/ai/monitoring.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ def sync_wrapped(*args, **kwargs):
for k, v in kwargs.pop("sentry_tags", {}).items():
span.set_tag(k, v)
for k, v in kwargs.pop("sentry_data", {}).items():
span.set_data(k, v)
span.set_attribute(k, v)
if curr_pipeline:
span.set_data("ai.pipeline.name", curr_pipeline)
span.set_attribute("ai.pipeline.name", curr_pipeline)
return f(*args, **kwargs)
else:
_ai_pipeline_name.set(description)
Expand Down Expand Up @@ -70,9 +70,9 @@ async def async_wrapped(*args, **kwargs):
for k, v in kwargs.pop("sentry_tags", {}).items():
span.set_tag(k, v)
for k, v in kwargs.pop("sentry_data", {}).items():
span.set_data(k, v)
span.set_attribute(k, v)
if curr_pipeline:
span.set_data("ai.pipeline.name", curr_pipeline)
span.set_attribute("ai.pipeline.name", curr_pipeline)
return await f(*args, **kwargs)
else:
_ai_pipeline_name.set(description)
Expand Down Expand Up @@ -104,7 +104,7 @@ def record_token_usage(
# type: (Span, Optional[int], Optional[int], Optional[int]) -> None
ai_pipeline_name = get_ai_pipeline_name()
if ai_pipeline_name:
span.set_data("ai.pipeline.name", ai_pipeline_name)
span.set_attribute("ai.pipeline.name", ai_pipeline_name)
if prompt_tokens is not None:
span.set_measurement("ai_prompt_tokens_used", value=prompt_tokens)
if completion_tokens is not None:
Expand Down
2 changes: 1 addition & 1 deletion sentry_sdk/ai/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ def _normalize_data(data):
def set_data_normalized(span, key, value):
# type: (Span, str, Any) -> None
normalized = _normalize_data(value)
span.set_data(key, normalized)
span.set_attribute(key, normalized)
4 changes: 2 additions & 2 deletions sentry_sdk/integrations/aiohttp.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ async def on_request_start(session, trace_config_ctx, params):
data[SPANDATA.HTTP_FRAGMENT] = parsed_url.fragment

for key, value in data.items():
span.set_data(key, value)
span.set_attribute(key, value)

client = sentry_sdk.get_client()

Expand Down Expand Up @@ -291,7 +291,7 @@ async def on_request_end(session, trace_config_ctx, params):

span = trace_config_ctx.span
span.set_http_status(int(params.response.status))
span.set_data("reason", params.response.reason)
span.set_attribute("reason", params.response.reason)
span.finish()

trace_config = TraceConfig()
Expand Down
16 changes: 9 additions & 7 deletions sentry_sdk/integrations/anthropic.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,13 @@ def _add_ai_data_to_span(
with capture_internal_exceptions():
if should_send_default_pii() and integration.include_prompts:
complete_message = "".join(content_blocks)
span.set_data(
span.set_attribute(
SPANDATA.AI_RESPONSES,
[{"type": "text", "text": complete_message}],
)
total_tokens = input_tokens + output_tokens
record_token_usage(span, input_tokens, output_tokens, total_tokens)
span.set_data(SPANDATA.AI_STREAMING, True)
span.set_attribute(SPANDATA.AI_STREAMING, True)


def _sentry_patched_create_common(f, *args, **kwargs):
Expand Down Expand Up @@ -159,15 +159,17 @@ def _sentry_patched_create_common(f, *args, **kwargs):
model = kwargs.get("model")

with capture_internal_exceptions():
span.set_data(SPANDATA.AI_MODEL_ID, model)
span.set_data(SPANDATA.AI_STREAMING, False)
span.set_attribute(SPANDATA.AI_MODEL_ID, model)
span.set_attribute(SPANDATA.AI_STREAMING, False)

if should_send_default_pii() and integration.include_prompts:
span.set_data(SPANDATA.AI_INPUT_MESSAGES, messages)
span.set_attribute(SPANDATA.AI_INPUT_MESSAGES, messages)

if hasattr(result, "content"):
if should_send_default_pii() and integration.include_prompts:
span.set_data(SPANDATA.AI_RESPONSES, _get_responses(result.content))
span.set_attribute(
SPANDATA.AI_RESPONSES, _get_responses(result.content)
)
_calculate_token_usage(result, span)
span.__exit__(None, None, None)

Expand Down Expand Up @@ -215,7 +217,7 @@ async def new_iterator_async():
result._iterator = new_iterator()

else:
span.set_data("unknown_response", True)
span.set_attribute("unknown_response", True)
span.__exit__(None, None, None)

return result
Expand Down
2 changes: 1 addition & 1 deletion sentry_sdk/integrations/boto3.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def _sentry_request_created(service_id, request, operation_name, **kwargs):
data[SPANDATA.HTTP_FRAGMENT] = parsed_url.fragment

for key, value in data.items():
span.set_data(key, value)
span.set_attribute(key, value)

span.set_tag("aws.service_id", service_id)
span.set_tag("aws.operation_name", operation_name)
Expand Down
20 changes: 11 additions & 9 deletions sentry_sdk/integrations/celery/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ def _set_messaging_destination_name(task, span):
if delivery_info.get("exchange") == "" and routing_key is not None:
# Empty exchange indicates the default exchange, meaning the tasks
# are sent to the queue with the same name as the routing key.
span.set_data(SPANDATA.MESSAGING_DESTINATION_NAME, routing_key)
span.set_attribute(SPANDATA.MESSAGING_DESTINATION_NAME, routing_key)


def _wrap_task_call(task, f):
Expand Down Expand Up @@ -380,18 +380,20 @@ def _inner(*args, **kwargs):
)

if latency is not None:
span.set_data(SPANDATA.MESSAGING_MESSAGE_RECEIVE_LATENCY, latency)
span.set_attribute(
SPANDATA.MESSAGING_MESSAGE_RECEIVE_LATENCY, latency
)

with capture_internal_exceptions():
span.set_data(SPANDATA.MESSAGING_MESSAGE_ID, task.request.id)
span.set_attribute(SPANDATA.MESSAGING_MESSAGE_ID, task.request.id)

with capture_internal_exceptions():
span.set_data(
span.set_attribute(
SPANDATA.MESSAGING_MESSAGE_RETRY_COUNT, task.request.retries
)

with capture_internal_exceptions():
span.set_data(
span.set_attribute(
SPANDATA.MESSAGING_SYSTEM,
task.app.connection().transport.driver_type,
)
Expand Down Expand Up @@ -499,18 +501,18 @@ def sentry_publish(self, *args, **kwargs):
only_if_parent=True,
) as span:
if task_id is not None:
span.set_data(SPANDATA.MESSAGING_MESSAGE_ID, task_id)
span.set_attribute(SPANDATA.MESSAGING_MESSAGE_ID, task_id)

if exchange == "" and routing_key is not None:
# Empty exchange indicates the default exchange, meaning messages are
# routed to the queue with the same name as the routing key.
span.set_data(SPANDATA.MESSAGING_DESTINATION_NAME, routing_key)
span.set_attribute(SPANDATA.MESSAGING_DESTINATION_NAME, routing_key)

if retries is not None:
span.set_data(SPANDATA.MESSAGING_MESSAGE_RETRY_COUNT, retries)
span.set_attribute(SPANDATA.MESSAGING_MESSAGE_RETRY_COUNT, retries)

with capture_internal_exceptions():
span.set_data(
span.set_attribute(
SPANDATA.MESSAGING_SYSTEM, self.connection.transport.driver_type
)

Expand Down
10 changes: 5 additions & 5 deletions sentry_sdk/integrations/django/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ def _set_db_data(span, cursor_or_db):
# type: (Span, Any) -> None
db = cursor_or_db.db if hasattr(cursor_or_db, "db") else cursor_or_db
vendor = db.vendor
span.set_data(SPANDATA.DB_SYSTEM, vendor)
span.set_attribute(SPANDATA.DB_SYSTEM, vendor)

# Some custom backends override `__getattr__`, making it look like `cursor_or_db`
# actually has a `connection` and the `connection` has a `get_dsn_parameters`
Expand Down Expand Up @@ -712,16 +712,16 @@ def _set_db_data(span, cursor_or_db):

db_name = connection_params.get("dbname") or connection_params.get("database")
if db_name is not None:
span.set_data(SPANDATA.DB_NAME, db_name)
span.set_attribute(SPANDATA.DB_NAME, db_name)

server_address = connection_params.get("host")
if server_address is not None:
span.set_data(SPANDATA.SERVER_ADDRESS, server_address)
span.set_attribute(SPANDATA.SERVER_ADDRESS, server_address)

server_port = connection_params.get("port")
if server_port is not None:
span.set_data(SPANDATA.SERVER_PORT, str(server_port))
span.set_attribute(SPANDATA.SERVER_PORT, str(server_port))

server_socket_address = connection_params.get("unix_socket")
if server_socket_address is not None:
span.set_data(SPANDATA.SERVER_SOCKET_ADDRESS, server_socket_address)
span.set_attribute(SPANDATA.SERVER_SOCKET_ADDRESS, server_socket_address)
12 changes: 6 additions & 6 deletions sentry_sdk/integrations/django/caching.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,22 @@ def _instrument_call(

with capture_internal_exceptions():
if address is not None:
span.set_data(SPANDATA.NETWORK_PEER_ADDRESS, address)
span.set_attribute(SPANDATA.NETWORK_PEER_ADDRESS, address)

if port is not None:
span.set_data(SPANDATA.NETWORK_PEER_PORT, port)
span.set_attribute(SPANDATA.NETWORK_PEER_PORT, port)

key = _get_safe_key(method_name, args, kwargs)
if key is not None:
span.set_data(SPANDATA.CACHE_KEY, key)
span.set_attribute(SPANDATA.CACHE_KEY, key)

item_size = None
if is_get_operation:
if value:
item_size = len(str(value))
span.set_data(SPANDATA.CACHE_HIT, True)
span.set_attribute(SPANDATA.CACHE_HIT, True)
else:
span.set_data(SPANDATA.CACHE_HIT, False)
span.set_attribute(SPANDATA.CACHE_HIT, False)
else: # TODO: We don't handle `get_or_set` which we should
arg_count = len(args)
if arg_count >= 2:
Expand All @@ -86,7 +86,7 @@ def _instrument_call(
item_size = len(str(args[0]))

if item_size is not None:
span.set_data(SPANDATA.CACHE_ITEM_SIZE, item_size)
span.set_attribute(SPANDATA.CACHE_ITEM_SIZE, item_size)

return value

Expand Down
2 changes: 1 addition & 1 deletion sentry_sdk/integrations/django/signals_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def wrapper(*args, **kwargs):
origin=DjangoIntegration.origin,
only_if_parent=True,
) as span:
span.set_data("signal", signal_name)
span.set_attribute("signal", signal_name)
return receiver(*args, **kwargs)

return wrapper
Expand Down
4 changes: 2 additions & 2 deletions sentry_sdk/integrations/django/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def rendered_content(self):
) as span:
if isinstance(self.context_data, dict):
for k, v in self.context_data.items():
span.set_data(f"context.{k}", v)
span.set_attribute(f"context.{k}", v)
return real_rendered_content.fget(self)

SimpleTemplateResponse.rendered_content = rendered_content
Expand Down Expand Up @@ -97,7 +97,7 @@ def render(request, template_name, context=None, *args, **kwargs):
only_if_parent=True,
) as span:
for k, v in context.items():
span.set_data(f"context.{k}", v)
span.set_attribute(f"context.{k}", v)
return real_render(request, template_name, context, *args, **kwargs)

django.shortcuts.render = render
Expand Down
6 changes: 3 additions & 3 deletions sentry_sdk/integrations/graphene.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def graphql_span(schema, source, kwargs):
with sentry_sdk.start_span(
op=op, name=operation_name, only_if_parent=True
) as graphql_span:
graphql_span.set_data("graphql.document", source)
graphql_span.set_data("graphql.operation.name", operation_name)
graphql_span.set_data("graphql.operation.type", operation_type)
graphql_span.set_attribute("graphql.document", source)
graphql_span.set_attribute("graphql.operation.name", operation_name)
graphql_span.set_attribute("graphql.operation.type", operation_type)
yield
12 changes: 6 additions & 6 deletions sentry_sdk/integrations/grpc/aio/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,16 @@ async def intercept_unary_unary(
origin=SPAN_ORIGIN,
only_if_parent=True,
) as span:
span.set_data("type", "unary unary")
span.set_data("method", method)
span.set_attribute("type", "unary unary")
span.set_attribute("method", method)

client_call_details = self._update_client_call_details_metadata_from_scope(
client_call_details
)

response = await continuation(client_call_details, request)
status_code = await response.code()
span.set_data("code", status_code.name)
span.set_attribute("code", status_code.name)

return response

Expand All @@ -86,15 +86,15 @@ async def intercept_unary_stream(
origin=SPAN_ORIGIN,
only_if_parent=True,
) as span:
span.set_data("type", "unary stream")
span.set_data("method", method)
span.set_attribute("type", "unary stream")
span.set_attribute("method", method)

client_call_details = self._update_client_call_details_metadata_from_scope(
client_call_details
)

response = await continuation(client_call_details, request)
# status_code = await response.code()
# span.set_data("code", status_code)
# span.set_attribute("code", status_code)

return response
12 changes: 6 additions & 6 deletions sentry_sdk/integrations/grpc/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ def intercept_unary_unary(self, continuation, client_call_details, request):
origin=SPAN_ORIGIN,
only_if_parent=True,
) as span:
span.set_data("type", "unary unary")
span.set_data("method", method)
span.set_attribute("type", "unary unary")
span.set_attribute("method", method)

client_call_details = self._update_client_call_details_metadata_from_scope(
client_call_details
)

response = continuation(client_call_details, request)
span.set_data("code", response.code().name)
span.set_attribute("code", response.code().name)

return response

Expand All @@ -55,8 +55,8 @@ def intercept_unary_stream(self, continuation, client_call_details, request):
origin=SPAN_ORIGIN,
only_if_parent=True,
) as span:
span.set_data("type", "unary stream")
span.set_data("method", method)
span.set_attribute("type", "unary stream")
span.set_attribute("method", method)

client_call_details = self._update_client_call_details_metadata_from_scope(
client_call_details
Expand All @@ -66,7 +66,7 @@ def intercept_unary_stream(self, continuation, client_call_details, request):
client_call_details, request
) # type: UnaryStreamCall
# Setting code on unary-stream leads to execution getting stuck
# span.set_data("code", response.code().name)
# span.set_attribute("code", response.code().name)

return response

Expand Down
8 changes: 4 additions & 4 deletions sentry_sdk/integrations/httpx.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def send(self, request, **kwargs):
data[SPANDATA.HTTP_FRAGMENT] = parsed_url.fragment

for key, value in data.items():
span.set_data(key, value)
span.set_attribute(key, value)

if should_propagate_trace(sentry_sdk.get_client(), str(request.url)):
for (
Expand All @@ -93,7 +93,7 @@ def send(self, request, **kwargs):
rv = real_send(self, request, **kwargs)

span.set_http_status(rv.status_code)
span.set_data("reason", rv.reason_phrase)
span.set_attribute("reason", rv.reason_phrase)

data[SPANDATA.HTTP_STATUS_CODE] = rv.status_code
data["reason"] = rv.reason_phrase
Expand Down Expand Up @@ -142,7 +142,7 @@ async def send(self, request, **kwargs):
data[SPANDATA.HTTP_FRAGMENT] = parsed_url.fragment

for key, value in data.items():
span.set_data(key, value)
span.set_attribute(key, value)

if should_propagate_trace(sentry_sdk.get_client(), str(request.url)):
for (
Expand All @@ -165,7 +165,7 @@ async def send(self, request, **kwargs):
rv = await real_send(self, request, **kwargs)

span.set_http_status(rv.status_code)
span.set_data("reason", rv.reason_phrase)
span.set_attribute("reason", rv.reason_phrase)

data[SPANDATA.HTTP_STATUS_CODE] = rv.status_code
data["reason"] = rv.reason_phrase
Expand Down
Loading
Loading