Pick a depth. Each prompt opens in your AI pre-loaded with the lesson. Click a row to preview the prompt.
Resource attributes are the least glamorous part of OpenTelemetry and the one that most often makes a whole telemetry pipeline useless. If service.name defaults to unknown_service, every span from every one of your services lands in the same bucket. If service.version is not wired to the actual build, you can never answer 'did the deploy cause it'. If deployment.environment.name is missing, staging noise pollutes production alerts. These are three strings, set once at startup, and they determine whether your data can be grouped at all. The semantic conventions exist so that a dashboard written against one service works against every service — deviating from them means writing every query twice.
Set the resource from the environment, and make the environment come from your build and deploy tooling rather than from a developer's laptop. The Python and Node versions below are equivalent; both prefer OTEL_RESOURCE_ATTRIBUTES so that the same image can be deployed to two environments without a rebuild.
# telemetry.py — call setup() once, first thing in the process.
import os
from opentelemetry import trace
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
def setup() -> None:
# Resource.create() merges, in increasing priority:
# SDK defaults < OTEL_RESOURCE_ATTRIBUTES env var < this dict
resource = Resource.create({
"service.name": os.environ["OTEL_SERVICE_NAME"], # fail loudly
"service.version": os.environ.get("GIT_SHA", "dev"), # from CI
"deployment.environment.name": os.environ.get("ENV", "local"),
})
provider = TracerProvider(resource=resource)
provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
trace.set_tracer_provider(provider)
# Deploy-time, no rebuild needed:
# OTEL_SERVICE_NAME=checkout
# OTEL_RESOURCE_ATTRIBUTES=service.namespace=commerce,k8s.pod.name=$POD
# OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317
#
# Note os.environ[...] not .get(...): a missing service.name should crash
# the process at boot, not silently produce a year of unknown_service data.python3 main.py