Handling mutable entities (sessions, page views) #265
Replies: 3 comments 1 reply
-
Isn't that what we trying to avoid by grouping all common attributes in the entity? Or what you're saying is that we avoid using entities at all with option 2?
My concern in this pattern is how do we deal with having multiple entities? Let's say we have a session entity, page entity and user entity. All that contextual most likely applies to all events / metrics. Then:
|
Beta Was this translation helpful? Give feedback.
-
|
So my cents if I was to implement a solution which includes ability to have spec changes.
That way we avoid the complexity of switching providers and we use the existing getMeter method passing in the scope attributes. For session, I get the feeling it might be better to specify the session id as a field alongside span-id and use a strongly defined log record to transfer the details of the session to a back end. This way we can define the special handling of the session including creating links |
Beta Was this translation helpful? Give feedback.
-
|
I'm a fan of the entity concept as a mutable resource: having a semantic for sharing properties between logs and spans is a neat feature for reducing payload size. And not all shared My only concern is the rate of mutation of some entities. If an entity changes too often — for instance browser.document.url.full, which mutates on every query-param update, every I raised this as a problem statement in #269 (comment). So I think we should document and clarify in the specs somehow what makes a good entity (like session.id) versus a bad one (like browser.document.url.full). |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Background
In browser (and mobile) applications, key entities change during the SDK's lifetime:
session.id.These entities are contextual — they apply to all telemetry produced by the SDK, which makes Resource the semantically correct place for them. However, the OTel specification requires Resources to be immutable. This applies to all signals. In addition, for metrics, the spec also defines resources as part of metric stream identity.
This discussion explores how client SDKs should handle mutable entities across all signals, with particular attention to the impact on metrics.
The problem
When an entity changes in the browser, the new entity must replace the previous one for all telemetry generated by the SDK — all instrumentations and user code must start producing telemetry associated with the new entity, and the old entity is no longer valid.
However, replacing a resource is not possible per spec, and creating a new provider for each entity change has implications that differ by signal type.
logs and traces
Logs and traces are stateless emitters — each
emit()or span creation is independent. A proxy pattern (likeEntityAwareLoggerProvider) can handle entity replacement by swapping the underlying delegate provider when the entity changes. Instrumentation references remain valid, and each emission resolves to the current entity. We have a working prototype of this approach for logs.metrics
A proxy pattern similar to logs/traces can work for metrics — proxy instruments delegate to the current real instruments, which are swapped when the entity changes. It's more involved (more proxy classes, flushing old aggregation state) but solvable.
The other (and more important) issue is that the OTel spec defines metric stream identity as (Resource, Scope, Name). Replacing the entity means the Resource changes, which means the metric stream's identity changes. In practice, the impact depends on the backend:
service.name->jobandservice.instance.id->instanceare the only ones promoted by default). Changing other Resource attributes likesession.idis invisible to Prometheus.So the identity issue is a spec-level contract concern rather than a practical aggregation problem for most backends.
Possible approaches
Option 1: Clarify the spec
Define in the specification what consumers should do when Resource attributes change for a metric stream — e.g., by distinguishing "identifying" vs. "descriptive" Resource attributes (as proposed in OTEP 264). This would make entity replacement for metrics a supported pattern, but requires spec consensus and backend adoption.
Option 2: Exclude mutable attributes from the metrics Resource
Sidestep the identity problem by keeping mutable entity attributes off the metrics Resource entirely. Give the MeterProvider a static Resource containing only immutable attributes (
service.name,telemetry.sdk.version, etc.). Session ID and other entity attributes would still be on the LoggerProvider and TracerProvider Resources, where entity replacement works with the proxy pattern.For entity attributes that are useful as metric dimensions (e.g., page URL for "page views per route"), the SDK would inject them as data point attributes at record time rather than putting them on the Resource:
This keeps the Resource immutable, avoids MeterProvider recreation, and lets aggregation work naturally (different attribute values = different series).
Option 3: Use events instead of metrics
Avoid the metrics identity problem altogether by not using the Metrics SDK for client-side telemetry. Instead, send measurements as log events and generate metrics downstream (e.g., in the Collector using connectors like
signaltometrics). Entity attributes are simply event attributes — no Resource immutability constraints apply.The downside is that this creates friction for teams without Collector access or who want to use familiar metric instruments (counters, histograms) in their application code.
Open questions
Automatic attribute injection mechanism: If using Option 2, what is the right mechanism for automatically injecting entity attributes as data point attributes?
Cross-signal correlation: If metrics exclude session ID from their Resource but logs/traces include it, how do you correlate metrics with logs/traces for the same session? Is there a use case for this?
Relationship to OTEP 4665: The entity proposal focuses on
forEntity()which creates new providers. Option 2 proposes a different pattern (static Resource + data point attribute injection). Should the entity proposal account for this, or should this be a client SDK-specific solution?Beta Was this translation helpful? Give feedback.
All reactions