Anatomy of a Resource
Resource attributes should generally follow OpenTelemetry resource semantic conventions so any OTel-compatible backend can interpret them.
Configuring a Resource
Resource.create(...) rather than the class constructor Resource(attributes=...). create() merges your attributes with the defaults from the built-in resource detectors.
Phoenix–Specific Project Routing
Phoenix resolves the project for an incoming OTLP request in this order of precedence:
For the common case, set
openinference.project.name on the Resource and forget about it.
Environment Variables
The OpenTelemetry SDK can auto-detect Resource attributes from the environment, so you can avoid hardcoding them:
Code wins over environment variables. If you set the same key in both, the value passed to
Resource.create(...) takes precedence.
The SDK also runs built-in resource detectors by default — they automatically fill in host, OS, process, and other infrastructure attributes. Disable them with OTEL_EXPERIMENTAL_RESOURCE_DETECTORS="" if you don’t want them.
For the full list, see the OpenTelemetry SDK environment variables reference.
Common Pitfalls
A few more things that trip people up:- Not following semantic conventions — using your own attribute names instead of
service.name,deployment.environment.name, etc. means other tools (and Phoenix) can’t interpret them. Stick with the resource semconv whenever there’s a standard key. - Using the class constructor
Resource(attributes=...)instead ofResource.create(...)— bypasses built-in detectors, so you lose the auto-populated host/process attributes. - Forgetting to set a project name — without
openinference.project.nameon the Resource or anx-project-namerequest header, spans land in the default project and are hard to organize.

