CtrlK
BlogDocsLog inGet started
Tessl Logo

dash0/agent-skills

Expert guidance for configuring and deploying the OpenTelemetry Collector. Use when setting up a Collector pipeline, configuring receivers, exporters, or processors, deploying a Collector to Kubernetes or Docker, or forwarding telemetry to Dash0. Triggers on requests involving collector, pipeline, OTLP receiver, exporter, or Dash0 collector setup.

100

Quality

100%

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Advisory

Suggest reviewing before use

Overview
Quality
Evals
Security
Files

attributes.mdskills/otel-semantic-conventions/rules/

title:
Attributes: Registry, Selection, and Placement
impact:
CRITICAL
tags:
attributes, registry, semconv, http, database, messaging, rpc

Attributes

When adding attributes to telemetry, always search the Attribute Registry first and place each attribute at the correct telemetry level. Wrong attributes — or attributes at the wrong level — make telemetry unqueryable and break cross-service correlation.

Core principles

  1. Registry first. Before creating a custom attribute, search the Attribute Registry. If a registered attribute exists for your concept, use it — even if the name is not exactly what you would choose.
  2. No custom attributes unless necessary. Custom attributes fragment querying and break tooling. Only create them for truly domain-specific concepts that have no registry equivalent. When you must, use a namespaced prefix (e.g., com.acme.order.priority).
  3. Low cardinality in metric attributes, high cardinality in span attributes. Metric attribute values must be bounded. Put variable data (IDs, paths, user inputs) into span attributes, not metric attributes.
  4. Right level, every time. Place attributes at the correct telemetry level (resource, scope, span, log, metric data point). Never duplicate resource-level data on every span.
  5. Consistent placement. Once you decide an attribute belongs at a certain level, keep it there everywhere. Inconsistency (sometimes resource, sometimes span) makes querying unreliable.

Attribute placement

Levels

LevelWhat belongs hereExamples
ResourceIdentity and environment of the telemetry source. Stable for the lifetime of the process.service.name, service.version, deployment.environment.name, k8s.pod.name, host.name
ScopeIdentity of the instrumentation library or component.otel.scope.name, otel.scope.version
SpanRequest-specific context for a single operation.http.request.method, http.response.status_code, db.operation.name, url.path
Span EventPoint-in-time occurrences within a span.exception.type, exception.message, exception.stacktrace
Log RecordStructured log entry attributes.log.file.path, severity fields, body fields
Metric Data PointLow-cardinality dimensions for aggregation.http.request.method, http.response.status_code, http.route

Common mistakes

  • Putting service.name on spans. It is a resource attribute. Putting it on spans duplicates data and wastes storage.
  • Putting k8s.pod.name on every span. Kubernetes metadata belongs on the resource. The Collector's k8sattributes processor handles this.
  • Inconsistent placement. If deployment.environment.name is a resource attribute in one service, it must be a resource attribute in every service. Mixing levels breaks cross-service queries.
  • High-cardinality metric attributes. Attributes like url.path or user.id on metrics cause cardinality explosion. Metrics attributes must be low-cardinality. Use http.route, not url.path.
  • Putting enduser.* or user.* on resources. User identity changes per request — these are span or log attributes, never resource attributes. A resource describes the process, not who is calling it.
  • Putting browser.* on resources. Browser attributes like browser.language or browser.brands vary per request in server-side telemetry. They belong on spans, not on the resource.

Required and important attributes

Must-have resource attributes

AttributeTypeWhy
service.namestringRequired. Identifies the service. Without it, telemetry is unattributable. Falls back to unknown_service if not set.
service.versionstringEnables version-aware analysis, deployment tracking, and regression detection.
service.instance.idstringUniquely identifies the service instance (e.g., pod). Must be unique across all instances sharing the same service.name.
deployment.environment.namestringDistinguishes production from staging/dev. Previously deployment.environment.
k8s.pod.uidstringRequired for Kubernetes workloads. Enables telemetry correlation via the k8sattributes processor. Prefer over k8s.pod.ip, which breaks with service meshes (Istio, and Linkerd).

Most common span attributes

HTTP

Current AttributeTypeReqPrevious Name
http.request.methodstringRequiredhttp.method
http.response.status_codeintConditionally requiredhttp.status_code
url.schemestringRequiredhttp.scheme
url.pathstringRequiredPart of http.target
url.querystringConditionally requiredPart of http.target
url.fullstringRequired (client)http.url
http.routestringConditionally required (server)http.route (unchanged)
server.addressstringRequirednet.peer.name (client) / net.host.name (server)
server.portintRequirednet.peer.port / net.host.port
client.addressstringRecommended (server)http.client_ip
network.protocol.versionstringRecommendedhttp.flavor (values changed: 2.02)
user_agent.originalstringRecommendedhttp.user_agent
error.typestringConditionally required(new)

Database

Current AttributeTypeReqPrevious Name
db.system.namestringRequireddb.system
db.operation.namestringConditionally requireddb.operation
db.collection.namestringConditionally requireddb.sql.table / db.mongodb.collection
db.namespacestringConditionally requireddb.name
db.query.textstringOpt-indb.statement
db.response.status_codestringConditionally required(new)
server.addressstringRequirednet.peer.name
server.portintConditionally requirednet.peer.port
error.typestringConditionally required(new)

Messaging

Current AttributeTypeReqPrevious Name
messaging.systemstringRequiredmessaging.system (unchanged)
messaging.operation.namestringRequiredmessaging.operation
messaging.destination.namestringConditionally requiredmessaging.destination
messaging.message.idstringRecommendedmessaging.message_id
messaging.consumer.group.namestringConditionally requiredmessaging.kafka.consumer_group etc.

RPC

Current AttributeTypeReqPrevious Name
rpc.systemstringRequiredrpc.system (unchanged)
rpc.servicestringRecommendedrpc.service (unchanged)
rpc.methodstringRecommendedrpc.method (unchanged)
rpc.grpc.status_codeintRequired (gRPC)rpc.grpc.status_code (unchanged)
server.addressstringRequirednet.peer.name
server.portintRequirednet.peer.port

Error

AttributeTypeNotes
error.typestringThe error class, status code, or stable identifier. Set whenever span status is ERROR. See span status code rules.
exception.typestringOn span events of type exception.
exception.messagestringHuman-readable error message.
exception.stacktracestringFull stacktrace as a string.

The _OTHER pattern

Attributes like http.request.method only accept a fixed set of known values. Unknown values are normalized to _OTHER and the original is preserved in a companion attribute (e.g., http.request.method_original). This bounds cardinality while retaining detail.

Attribute registry namespaces

Before creating a custom attribute, check if it belongs to an existing namespace. The registry contains 80+ namespaces.

Infrastructure and compute

NamespaceCovers
serviceService identity: name, namespace, version, instance ID
deploymentDeployment environment, ID, name, status
hostPhysical or virtual host: hostname, IP, arch, OS
osOperating system type, version, description
processOS process: PID, command, arguments, owner
containerContainer instance: ID, image, runtime, name
k8sKubernetes resources: pod, node, deployment, namespace, service
cloudCloud provider, account, region, availability zone, platform
faasServerless function: name, version, trigger, invocation ID
devicePhysical device: ID, manufacturer, model

Cloud providers

NamespaceCovers
awsAWS services: ECS, EKS, Lambda, S3, DynamoDB, SQS, SNS, Bedrock
gcpGCP services: Cloud Run, Compute Engine, client libraries
azureAzure services: Cosmos DB, client libraries
herokuHeroku app, release, dyno metadata

Protocols and communication

NamespaceCovers
httpHTTP request/response: method, status code, headers, body size
rpcRemote procedure calls: system, service, method, status
graphqlGraphQL operations: document, operation name, type
dnsDNS queries: resolved addresses, queried domain
tlsTLS/SSL: cipher suite, protocol version, certificate details
networkNetwork connection: transport, protocol, peer/local address
clientClient side of connection: address, port
serverServer side of connection: address, port

Data systems

NamespaceCovers
dbDatabase operations: system, operation, collection, namespace, query
messagingMessaging systems: Kafka, RabbitMQ, SQS, destination, operation

URLs and identity

NamespaceCovers
urlURL components: scheme, path, query, full, template
user_agentUser-Agent header: original string, parsed name
userUser identity: ID, email, name, roles
enduserEnd user: ID, scope, role
sessionSession: ID, previous session ID
peerRemote service: peer.service for uninstrumented peers

Errors and diagnostics

NamespaceCovers
errorError classification: error.type
exceptionException details: type, message, stacktrace
codeSource code location: function, filepath, line number
threadThread identity: ID, name
logLog record metadata: file path, iostream, record UID
eventEvent identification: event.name

Application runtimes

NamespaceCovers
jvmJVM: GC, memory pools, buffer pools, threads, classes
dotnet.NET runtime: GC generation, heap info
goGo runtime: memory types, goroutines
nodejsNode.js: event loop state
v8jsV8 engine: GC type, heap spaces
cpythonCPython: GC generation

AI and ML

NamespaceCovers
gen_aiGenerative AI: model, provider, token usage, tool calls
openaiOpenAI-specific: API type, service tier
mcpModel Context Protocol: tool interactions

CI/CD and source control

NamespaceCovers
cicdCI/CD pipelines: pipeline name, run ID, task
vcsVersion control: repository, branch, commit, change (PR)

Mobile and browser

NamespaceCovers
browserBrowser: brands, language, platform, mobile flag
androidAndroid: app state, API level
iosiOS: app lifecycle state
appClient apps: installation ID, screen, widgets

Other

NamespaceCovers
feature_flagFeature flags: key, variant, provider, evaluation
testTesting: test case, suite, result
geoGeolocation: country, region, city, coordinates
fileFile system: name, path, size, hash
artifactDistribution artifacts: filename, hash, version
hwHardware components: CPU, disk, memory, sensors
systemSystem metrics: filesystem, memory, paging
telemetryTelemetry SDK: name, version, language
otelOpenTelemetry internals: status, scope, component name

Full registry: https://opentelemetry.io/docs/specs/semconv/registry/attributes/

References

skills

otel-semantic-conventions

README.md

tile.json