Skip to main content
In this lesson we’ll cover span attributes: what they are, how to attach them to spans in OpenTelemetry (Python), and best practices for using them safely to enrich traces and speed up debugging.

What are span attributes?

Span attributes are key/value metadata attached to individual spans. They enrich trace data with contextual information (for example, user IDs, account numbers, or external system identifiers) so you can filter, group, and diagnose trace data more effectively. Resource attributes, in contrast, describe the service that generates telemetry (for example service.name and service.version). A typical tracer/provider setup looks like this:

Setting span attributes

You can add attributes to spans in multiple ways:
  • Set multiple attributes at once with span.set_attributes({...}).
  • Set a single attribute with span.set_attribute(key, value).
  • Provide attributes when creating a span (many APIs accept an attributes parameter).
Example: creating spans and adding attributes to the current span
Or set a single attribute:
You can also pass attributes when starting a span (if the API supports it):
Running the earlier script prints:
If you inspect the “Starting Payment” span in your tracing backend (for example, Jaeger), you’ll typically see the attributes attached to the span (often displayed as tags): user, account_number, and bank.
Avoid placing highly sensitive data (such as full credit card numbers, passwords, or unmasked PII) into span attributes. Traces may be accessible to multiple teams and stored long term. Instead, consider hashing, tokenizing, truncating, or excluding sensitive fields.

Quick reference: attribute methods

MethodUse caseExample
span.set_attributes()Set multiple attributes in one callspan.set_attributes({"user":"john","account_number":"7372349"})
span.set_attribute()Set or update a single attributespan.set_attribute("user", "john")
start_as_current_span(..., attributes=...)Initialize span with attributes at creationtracer.start_as_current_span("name", attributes={"env":"prod"})

Best practices

  • Instrument with meaningful attributes that help answer operational questions (e.g., which customer, which endpoint, which upstream service).
  • Keep cardinality reasonable: avoid unbounded values (like raw identifiers that create a new value per request) that can blow up your backend index.
  • Avoid or obfuscate PII and secrets. Use tokens, IDs with limited scope, or aggregated metrics where appropriate.
  • Consistently name attributes using clear, lowercase keys (for example, user.id, http.method, db.statement) to make querying easier.

Watch Video