1. First, the Big Picture
In OpenTelemetry, telemetry data (traces, metrics, logs) has three layers of information:
- Resource → Who produced this telemetry?
- Span / Metric / Log record → What happened?
- Attributes → Extra details about it
Resource attributes describe the identity of the service. Span attributes describe a specific operation.
If you confuse these two, your observability data becomes hard to query, hard to aggregate, and semantically wrong.
2. What Is a Resource? (Conceptual Meaning)
A Resource represents: The entity that produces telemetry.
Examples of entities:
- A Spring Boot service
- A JVM process
- A Kubernetes pod
- A Docker container
- A VM
- A Lambda function
So a resource answers: “Who is emitting this telemetry?”
3. Typical Resource Attributes
Resource attributes are stable and long-lived.
Examples:
service.name = order-serviceservice.version = 1.3.2deployment.environment = prodhost.name = node-17container.id = abc123k8s.pod.name = order-service-7f9c8dcloud.provider = aws
Important property: All spans from this service instance share the same resource attributes.
4. What Is a Span?
A Span represents: One specific operation or unit of work.
Examples:
- Handling one HTTP request
- Calling one DB query
- Calling one REST API
- Processing one Kafka message
5. What Are Span Attributes?
Span attributes are: Operation-specific details.
Examples:
For an HTTP span:
http.method = POSThttp.route = /placeOrderhttp.status_code = 200
For a DB span:
db.system = postgresqldb.statement = insert into orders ...db.operation = INSERT
For a Kafka span:
messaging.system = kafkamessaging.destination = orders-topic
Span attributes change from span to span, even inside the same trace.
6. Visual Mental Model
Imagine this:
Order Service (Resource)
|
|-- Span: HTTP /placeOrder
| http.method = POST
| http.status = 200
|
|-- Span: JDBC insert order
| db.system = mysql
| db.operation = INSERT
|
|-- Span: HTTP call payment
http.url = http://payment/pay
And the resource attributes sit above all of them:
service.name = order-service service.version = 1.2.0 deployment.environment = prod host.name = node-7
They apply to all spans equally.
7. Why This Separation Exists
This separation exists because:
- Resource attributes are indexed and queried differently
- Resource attributes are used for grouping, filtering, aggregation
- Span attributes are used for detailed analysis of operations
For example:
- “Show me all traces from
service.name = payment-servicein prod” - “Compare latency of version 1.2.0 vs 1.3.0”
These are resource-level queries, not span-level.
