Attributes guide
August 4, 2026 ยท View on GitHub
Status: Draft
This document consolidates project decisions and guidance on attributes: naming, placement, cardinality, normalization, and lifecycle.
It complements:
- semantic-conventions-guide.md for upstream naming rules
- entity-model.md for the entity attribute sets and relationships
- stability-compatibility-guide.md for evolution rules
- security-privacy-guide.md for sensitive-data constraints
Attribute categories
Attributes fall into three categories.
1) Resource attributes
Describe the producing service and runtime environment.
- MUST be attached at the resource level
- MUST NOT be duplicated on every signal
- SHOULD reuse upstream semantic conventions (
service.*,host.*,process.*,container.*)
2) Entity attributes
Identify stable in-process entities (pipelines, nodes, channels, runtime threads).
- MUST be attached/translated as scope attributes in OTLP exports
- MUST NOT be duplicated on every signal
- MUST be stable for the lifetime of the entity
- MUST be bounded and known at entity creation time
- MUST be the foundation of metric set identity for core system telemetry
3) Signal-specific attributes
Provide additional bounded context needed to interpret a measurement or event occurrence.
- MAY be used when required for interpretation
- MUST be bounded and documented
- MUST remain meaningful under aggregation (metrics) and filtering (events)
Naming and namespaces
Reuse upstream first
- Reuse existing OpenTelemetry semantic attributes whenever possible.
- Do not redefine upstream attributes with different meaning.
Project-defined namespace
Project-defined entity attributes MUST be namespaced to avoid collisions with upstream conventions.
Policy:
- Use
otelcol.*for project-defined attributes. - Do not introduce new un-prefixed top-level namespaces for custom entities.
Closed sets (enums)
When an attribute represents a categorical dimension:
- The value set MUST be a documented closed set.
- Values MUST be lowercase and stable.
- Avoid synonyms that fragment cardinality (
failvserrorvsfailed).
Adding enum values for stable telemetry follows the compatibility rules in stability-compatibility-guide.md.
Placement rules
- Resource attributes belong on the resource attributes.
- Entity attributes belong on the scope attributes.
- Signal-specific attributes belong only where they apply, and must be bounded.
Do not duplicate information:
- If a value is already present as an entity attribute, do not repeat it as a signal-specific attribute.
- Prefer a single canonical key.
How the layers are rendered
The self-telemetry pipeline emits each category on its correct OpenTelemetry layer for every exported signal - both metrics and logs (see issue #3161). The mapping is signal-independent:
| Category | OTLP metrics and logs | Admin Prometheus metrics |
|---|---|---|
| Resource | Resource attributes | target_info gauge labels |
| Entity | Instrumentation scope attributes | otel_scope_* series labels |
| Signal-specific | Point or record attributes | Inline point labels |
Notes:
- Resource attributes are produced by the detectors listed in
engine.telemetry.detectors(defaultservice_instance,env,service_name);host,os,process,container, andk8sare opt-in, and an unrecognized detector name fails engine startup. Precedence is explicitly configuredengine.telemetry.resourceattributes > detectors > the build-info defaults forservice.name/service.version. - The opt-in
processdetector emitsprocess.command_args(the full command line), which can include secrets passed as arguments. Enable it only where that is acceptable. - The same resolved resource map feeds every consumer: the native OTLP
metric and log resource encoders and the admin
target_infogauge - so resource identity is consistent across metrics, logs, and the admin endpoint. - Entity identity is resolved from the telemetry registry once per entity and
attached as
InstrumentationScope.attributesfor both metrics and logs (logs carry entity keys via theirLogContext). On the admin Prometheus endpoint the same entity attributes are rendered asotel_scope_*labels per the OpenTelemetry-to-Prometheus specification; the reserved keysotel_scope_name,otel_scope_version, andotel_scope_schema_urlare not overridden. - Engine-global signals (e.g. the
memory_rssmetric) carry no scope attributes; their identity comes entirely from the Resource layer. - Metric sets support bounded enum attributes on the signal-specific data-point layer. See Item Attributes for Metrics.
Core rule
Attributes attached to core system metrics MUST have bounded cardinality.
Before adding an attribute, ask:
- If I aggregate across this attribute, does the result still make sense?
- Is the value space bounded and known at entity creation time?
If not, the attribute is mis-modeled for core system metrics.
Prohibited by default in core system metrics
The following are prohibited as metric attributes unless explicitly approved and normalized:
- user_id, session_id, request_id
- raw URL path, raw query string
- raw SQL, raw error messages, unbounded file paths
- unbounded plugin configuration values
Important node: This restriction may be relaxed in the future through an explicit opt-in mechanism, for example to allow controlled propagation of selected attributes from baggage into metrics or logs under well-defined processing rules.
Normalization patterns
When context is useful but high cardinality, normalize:
- URL path -> route template
- SQL query -> normalized fingerprint
- IP address -> prefix or bucket
- error message -> error class or error type
Errors and exceptions
Error classification
Prefer low-cardinality classification:
- Use
error.type(or an equivalent stable classifier) when applicable. - Avoid raw error messages as attributes in stable telemetry.
Exceptions
When recording an actual exception:
- Use
exception.typeandexception.message. exception.stacktracemust follow security-privacy-guide.md gating rules.
Attributes vs event body
This project distinguishes between queryable attributes and potentially large bodies:
- Put small, queryable fields in attributes.
- Put large payloads in the body only when strictly required.
- Do not duplicate the same data in both places.
Checklist
When introducing a new attribute:
- It is categorized (resource, entity, signal-specific).
- It reuses upstream semantic attributes when available.
- If project-defined, it uses the
otelcol.*namespace. - Cardinality is bounded and documented.
- For enums, the closed set is documented and stable.
- It follows security and privacy rules (no sensitive data).
- If stable, the change follows the compatibility rules.