Skip to content

Include attributes when starting sqlalchemy spans for samplers #3563

Open
@alexmojaki

Description

@alexmojaki

In this code:

def _set_db_client_span_attributes(self, span, statement, attrs) -> None:
"""Uses statement and attrs to set attributes of provided Otel span"""
span.set_attribute(SpanAttributes.DB_STATEMENT, statement)
span.set_attribute(SpanAttributes.DB_SYSTEM, self.vendor)
for key, value in attrs.items():
span.set_attribute(key, value)
def _before_cur_exec(
self, conn, cursor, statement, params, context, _executemany
):
if not is_instrumentation_enabled():
return statement, params
attrs, found = _get_attributes_from_url(conn.engine.url)
if not found:
attrs = _get_attributes_from_cursor(self.vendor, cursor, attrs)
db_name = attrs.get(SpanAttributes.DB_NAME, "")
span = self.tracer.start_span(
self._operation_name(db_name, statement),
kind=trace.SpanKind.CLIENT,
)
with trace.use_span(span, end_on_exit=False):
if span.is_recording():
if self.enable_commenter:
commenter_data = self._get_commenter_data(conn)
if self.enable_attribute_commenter:
# just to handle type safety
statement = str(statement)
# sqlcomment is added to executed query and db.statement span attribute
statement = _add_sql_comment(
statement, **commenter_data
)
self._set_db_client_span_attributes(
span, statement, attrs
)
else:
# sqlcomment is only added to executed query
# so db.statement is set before add_sql_comment
self._set_db_client_span_attributes(
span, statement, attrs
)
statement = _add_sql_comment(
statement, **commenter_data
)
else:
# no sqlcomment anywhere
self._set_db_client_span_attributes(span, statement, attrs)

There's no good reason to set the attributes only after checking is_recording, except:

  1. when enable_commenter and enable_attribute_commenter are both true
  2. specifically for the statement attribute
  3. assuming that it's important that the initial and final values of the statement attribute are the same.

Otherwise, it's computationally trivial to include those attributes when starting the span. This would allow samplers to exclude spans with particular attributes (especially certain trivial queries which aren't worth tracing), and SpanProcessor.on_start to make use of the attributes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions