Skip to content

Commit 421fe30

Browse files
feat(blog): add 'How to Name Your Span Attributes' blog post (#7602)
Signed-off-by: Juraci Paixão Kröhling <juraci@kroehling.de> Signed-off-by: Vitor Vasconcellos <vitor.vasconcellos@mercadolivre.com> Co-authored-by: Vitor Vasconcellos <vitor.vasconcellos@mercadolivre.com>
1 parent 1aa5327 commit 421fe30

2 files changed

Lines changed: 286 additions & 0 deletions

File tree

Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
---
2+
title: How to Name Your Span Attributes
3+
linkTitle: How to Name Your Span Attributes
4+
date: 2025-08-27
5+
author: >-
6+
[Juraci Paixão Kröhling](https://github.com/jpkrohling) (OllyGarden)
7+
canonical_url: https://blog.olly.garden/how-to-name-your-span-attributes
8+
cSpell:ignore: interoperability jpkrohling OllyGarden shopify
9+
---
10+
11+
Welcome to the second installment in our series on OpenTelemetry naming best
12+
practices. In our [previous post](/blog/2025/how-to-name-your-spans/), we
13+
explored how to name spans using the `{verb} {object}` pattern. Today, we're
14+
diving into span attributes—the rich contextual data that transforms your traces
15+
from simple operation logs into powerful debugging and analysis tools.
16+
17+
This guide targets developers who are:
18+
19+
- **Instrumenting their own applications** with custom spans and attributes
20+
- **Enriching telemetry** beyond what auto-instrumentation provides
21+
- **Creating libraries** that others will instrument
22+
23+
The attribute naming decisions you make directly impact the usability and
24+
maintainability of your observability data. Let's get them right.
25+
26+
## Start with semantic conventions
27+
28+
Here's the most important rule that will save you time and improve
29+
interoperability: **if an OpenTelemetry
30+
[semantic convention exists](/docs/specs/semconv/registry/attributes/) and the
31+
semantics match your use case, use it**.
32+
33+
This isn't just about convenience—it's about building telemetry that integrates
34+
seamlessly with the broader OpenTelemetry ecosystem. When you use standardized
35+
attribute names, your data automatically works with existing dashboards,
36+
alerting rules, and analysis tools.
37+
38+
### When semantics match, use the convention
39+
40+
| Your need | Use this semantic convention | Why |
41+
| :----------------------- | :--------------------------- | :---------------------------------------------- |
42+
| HTTP request method | `http.request.method` | Standardized across all HTTP instrumentation |
43+
| Database collection name | `db.collection.name` | Works with database monitoring tools |
44+
| Service identification | `service.name` | Core resource attribute for service correlation |
45+
| Network peer address | `network.peer.address` | Standard for network-level debugging |
46+
| Error classification | `error.type` | Enables consistent error analysis |
47+
48+
The key principle is **semantic match over naming preference**. Even if you
49+
prefer `database_table` over `db.collection.name`, use the semantic convention
50+
when it accurately describes your data.
51+
52+
### When semantics don't match, don't force it
53+
54+
Resist the temptation to misuse semantic conventions:
55+
56+
| Don't do this | Why it's wrong |
57+
| :----------------------------------------------- | :---------------------------------------------------- |
58+
| Using `db.collection.name` for a file name | Files and database collections are different concepts |
59+
| Using `http.request.method` for business actions | "approve_payment" isn't an HTTP method |
60+
| Using `user.id` for a transaction ID | Users and transactions are different entities |
61+
62+
Misusing semantic conventions is worse than creating custom attributes—it
63+
creates confusion and breaks tooling that expects the standard semantics.
64+
65+
## The golden rule: Domain first, never company first
66+
67+
When you need custom attributes beyond the semantic conventions, the most
68+
critical principle is: **start with the domain or technology, never your company
69+
or application name**.
70+
71+
This principle seems obvious but is consistently violated across the industry.
72+
Here's why it matters and how to get it right.
73+
74+
### Why company-first naming fails
75+
76+
| Bad attribute name | Problems |
77+
| :-------------------------- | :--------------------------------------------------- |
78+
| `og.user.id` | Company prefix pollutes global namespace |
79+
| `myapp.request.size` | Application-specific, not reusable |
80+
| `acme.inventory.count` | Makes correlation with standard attributes difficult |
81+
| `shopify_store.product.sku` | Unnecessarily ties concept to one vendor |
82+
83+
These approaches create attributes that are:
84+
85+
- Difficult to correlate across teams and organizations
86+
- Impossible to reuse in different contexts
87+
- Vendor-locked and inflexible
88+
- Inconsistent with OpenTelemetry's interoperability goals
89+
90+
### Domain-first success stories
91+
92+
| Good attribute name | Why it works |
93+
| :------------------- | :--------------------------------- |
94+
| `user.id` | Universal concept, vendor-neutral |
95+
| `request.size` | Reusable across applications |
96+
| `inventory.count` | Clear, domain-specific concept |
97+
| `product.sku` | Standard e-commerce terminology |
98+
| `workflow.step.name` | Generic process management concept |
99+
100+
This approach creates attributes that are universally understandable, reusable
101+
by others facing similar problems, and future-proof.
102+
103+
## Understanding the structure: Dots and underscores
104+
105+
OpenTelemetry attribute names follow a specific structural pattern that balances
106+
readability with consistency. Understanding this pattern helps you create
107+
attributes that feel natural alongside standard semantic conventions.
108+
109+
### Use dots for hierarchical separation
110+
111+
Dots (`.`) separate hierarchical components, following the pattern:
112+
`{domain}.{component}.{property}`
113+
114+
Examples from semantic conventions:
115+
116+
- `http.request.method` - HTTP domain, request component, method property
117+
- `db.collection.name` - Database domain, collection component, name property
118+
- `service.instance.id` - Service domain, instance component, ID property
119+
120+
### Use underscores for multi-word components
121+
122+
When a single component contains multiple words, use underscores (`_`):
123+
124+
- `http.response.status_code` - "status_code" is one logical component
125+
- `system.memory.usage_percent` - "usage_percent" is one measurement concept
126+
127+
### Create deeper hierarchies when needed
128+
129+
You can nest further when it adds clarity:
130+
131+
- `http.request.body.size`
132+
- `k8s.pod.label.{key}`
133+
- `messaging.kafka.message.key`
134+
135+
Each level should represent a meaningful conceptual boundary.
136+
137+
## Reserved namespaces: What you must never use
138+
139+
Certain namespaces are strictly reserved, and violating these rules can break
140+
your telemetry data.
141+
142+
### The `otel.*` namespace is off-limits
143+
144+
The `otel.*` prefix is exclusively reserved for the OpenTelemetry specification
145+
itself. It's used to express OpenTelemetry concepts in telemetry formats that
146+
don't natively support them.
147+
148+
Reserved `otel.*` attributes include:
149+
150+
- `otel.scope.name` - Instrumentation scope name
151+
- `otel.status_code` - Span status code
152+
- `otel.span.sampling_result` - Sampling decision
153+
154+
**Never create attributes starting with `otel.`** Any additions to this
155+
namespace must be approved as part of the OpenTelemetry specification.
156+
157+
### Other reserved attributes
158+
159+
The specification also reserves these specific attribute names:
160+
161+
- `error.type`
162+
- `exception.message`, `exception.stacktrace`, `exception.type`
163+
- `server.address`, `server.port`
164+
- `service.name`
165+
- `telemetry.sdk.language`, `telemetry.sdk.name`, `telemetry.sdk.version`
166+
- `url.scheme`
167+
168+
## Semantic convention patterns
169+
170+
The best way to develop good attribute naming intuition is studying
171+
OpenTelemetry's semantic conventions. These represent thousands of hours of
172+
design work by observability experts.
173+
174+
### Domain organization patterns
175+
176+
Notice how semantic conventions organize around clear domains:
177+
178+
#### Infrastructure domains
179+
180+
- `service.*` - Service identity and metadata
181+
- `host.*` - Host/machine information
182+
- `container.*` - Container runtime information
183+
- `process.*` - Operating system processes
184+
185+
#### Communication domains
186+
187+
- `http.*` - HTTP protocol specifics
188+
- `network.*` - Network layer information
189+
- `rpc.*` - Remote procedure call attributes
190+
- `messaging.*` - Message queue systems
191+
192+
#### Data domains
193+
194+
- `db.*` - Database operations
195+
- `url.*` - URL components
196+
197+
### Universal property patterns
198+
199+
Across all domains, consistent patterns emerge for common properties:
200+
201+
#### Identity properties
202+
203+
- `.name` - Human-readable identifiers (`service.name`, `container.name`)
204+
- `.id` - System identifiers (`container.id`, `process.pid`)
205+
- `.version` - Version information (`service.version`)
206+
- `.type` - Classification (`messaging.operation.type`, `error.type`)
207+
208+
#### Network properties
209+
210+
- `.address` - Network addresses (`server.address`, `client.address`)
211+
- `.port` - Port numbers (`server.port`, `client.port`)
212+
213+
#### Measurement properties
214+
215+
- `.size` - Byte measurements (`http.request.body.size`)
216+
- `.count` - Quantities (`messaging.batch.message_count`)
217+
- `.duration` - Time measurements (`http.server.request.duration`)
218+
219+
When creating custom domains, follow these same patterns. For inventory
220+
management, consider:
221+
222+
- `inventory.item.name`
223+
- `inventory.item.id`
224+
- `inventory.location.address`
225+
- `inventory.batch.count`
226+
227+
## Creating custom domains safely
228+
229+
Sometimes your business logic requires attributes outside existing semantic
230+
conventions. This is normal—OpenTelemetry can't cover every possible business
231+
domain.
232+
233+
### Guidelines for safe custom domains
234+
235+
1. **Choose descriptive, generic names** that others could reuse.
236+
2. **Avoid company-specific terminology** in the domain name.
237+
3. **Follow hierarchical patterns** established by semantic conventions.
238+
4. **Consider if your domain could become a future semantic convention**.
239+
240+
### Examples of well-designed custom attributes
241+
242+
| Domain | Good attributes | Why they work |
243+
| :-------- | :--------------------------------------- | :-------------------------------- |
244+
| Business | `payment.method`, `order.status` | Clear, reusable business concepts |
245+
| Logistics | `inventory.location`, `shipment.carrier` | Domain-specific but transferable |
246+
| Process | `workflow.step.name`, `approval.status` | Generic process management |
247+
| Content | `document.format`, `media.codec` | Universal content concepts |
248+
249+
## The rare exception: When prefixes make sense
250+
251+
In rare cases, you might need company or application prefixes. This typically
252+
happens when your custom attribute might conflict with attributes from other
253+
sources in a distributed system.
254+
255+
**Consider prefixes when:**
256+
257+
- Your attribute might conflict with vendor attributes in a distributed system.
258+
- You're instrumenting proprietary technology that's truly company-specific.
259+
- You're capturing internal implementation details that shouldn't be
260+
generalized.
261+
262+
For most business logic attributes, stick with domain-first naming.
263+
264+
## Your action plan
265+
266+
Naming span attributes well creates telemetry data that's maintainable,
267+
interoperable, and valuable across your organization. Here's your roadmap:
268+
269+
1. **Always check semantic conventions first** - Use them when semantics match.
270+
2. **Lead with domain, never company** - Create vendor-neutral attributes.
271+
3. **Respect reserved namespaces** - Especially avoid `otel.*`.
272+
4. **Follow hierarchical patterns** - Use dots and underscores consistently.
273+
5. **Build for reusability** - Think beyond your current needs.
274+
275+
By following these principles, you're not just solving today's instrumentation
276+
challenges—you're contributing to a more coherent, interoperable observability
277+
ecosystem that benefits everyone.
278+
279+
In our next post in this series, we'll shift our focus from spans to
280+
metrics—exploring how to name the quantitative measurements that tell us how our
281+
systems are performing, and why the same principles of separation and
282+
domain-first thinking apply to the numbers that matter most.

static/refcache.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,10 @@
247247
"StatusCode": 200,
248248
"LastSeen": "2024-08-09T10:46:28.075977-04:00"
249249
},
250+
"https://blog.olly.garden/how-to-name-your-span-attributes": {
251+
"StatusCode": 200,
252+
"LastSeen": "2025-08-27T08:48:18.571347-03:00"
253+
},
250254
"https://blog.olly.garden/how-to-name-your-spans": {
251255
"StatusCode": 200,
252256
"LastSeen": "2025-08-07T16:56:56.220013+02:00"

0 commit comments

Comments
 (0)