Skip to content

OTEP: Allow multiple Resources in an SDK#4665

Merged
jsuereth merged 30 commits intoopen-telemetry:mainfrom
jsuereth:wip-entity-scopes
Mar 23, 2026
Merged

OTEP: Allow multiple Resources in an SDK#4665
jsuereth merged 30 commits intoopen-telemetry:mainfrom
jsuereth:wip-entity-scopes

Conversation

@jsuereth
Copy link
Copy Markdown
Contributor

@jsuereth jsuereth commented Sep 22, 2025

Alternative to #4316 -

We propose allowing {Signal}Provider to be exended with additional Entity, instead of allowing Resource to be mutable as a forward path for modelling "session" in browsers/devices. Additionally, we believe this will help with multi-tenant telemetry use cases.

E.g. This OTEP proposes the following

const sessionEntity: Entity = discoverSessionEntity();
// SDK has created an isolated meterprovider for this session.
const meterForSession = meterProvider.forEntity(sessionEntity).getMeter("my meter"); 
const latencyForSession = meterForSession.getHistogram("latency", ...);
latencyForSession.record(...); // Record latency against session.

instead of:

const meter = meterProvider.getMeter("my meter");
const latency = meter.getHistogram("latency", ...);
const sessionEntity: Entity = discoverSessionEntity();
// On resource mutation, metrics must be flushed and/or new allocation for all metrics created.
entityProvider.addOrReplace(sessionEntity);  
latency.record(...); // Record latency against session.

@jsuereth jsuereth changed the title Allow Entity on InstrumentationScope OTEP: Allow Entity on InstrumentationScope Sep 22, 2025
@tigrannajaryan
Copy link
Copy Markdown
Member

Does this OTEP imply removing EntityRefs from the Resource in proto?

@tigrannajaryan
Copy link
Copy Markdown
Member

I like this direction.

Copy link
Copy Markdown
Contributor

@smith smith left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few typo suggestions. There's a lot here but it's an understandable summary of the proposal.

@jsuereth
Copy link
Copy Markdown
Contributor Author

Does this OTEP imply removing EntityRefs from the Resource in proto?

No. EntityRef in resource would interact with Entity on InstrumentationScope, and we need to sort out how.

Copy link
Copy Markdown
Member

@dyladan dyladan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been thinking about the meeting yesterday and I want to write down my understanding of what we discussed and how I'm currently thinking about it. Below in no particular order are some of the discussion points we hit.

No entity on scope

Instead of adding entity to InstrumentationScope, we discussed adding it directly to the core resource as a "layer" and reporting multiple resources with their associated telemetry. One possibility for lifetime management is by creating new providers and using the existing shutdown methods.

// this reports metrics against the "core" resource
const meterProvider = new api.metrics.MeterProvider();

// Scope a provider to a session entity
// This "layers" a new resource on top of the core resource using the existing merge rules
const sessionEntity = getEntityForSession();
const sessionMeterProvider = meterProvider.for(sessionEntity);

// TODO: can providers be arbitrarily layered? e.g
// const pageViewMeterProvider = sessionMeterProvider.for(getPageViewEntity());

// Use the scoped provider to report metrics against the session entity
sessionMeterProvider.getMeter('example-meter').createCounter('example_counter').add(1);

// use the core provider to report metrics which are not specific to the session
meterProvider.getMeter('example-meter').createCounter('example_counter').add(1);

Does the provider need to listen to lifetime events?

The current proposal assumes the *Provider receives the EntityInitialized event and does something. It's not clear to me what that something is intended to be. The current specification requires processors to be called synchronously with API method invocations. For example SpanProcessor.onStart() is invoked synchronously with tracer.StartSpan(). Because of this, any spans started before the resource is resolved still need to have some sort of resource attached.

In JS this is solved by allowing individual attributes of the resource to be a Promise<AttributeValue>. It is incumbent upon the processor to ensure all resource attributes are resolved before first export (by awaiting resource.waitForAsyncAttributes(). Accessing attributes before async resource is resolved results in a logged warning. Resources are merged together in the order their detectors are configured. One drawback of the current strategy is that you have to know all possible attribute keys in advance. This could be improved by allowing the key to also resolve asynchronously.


If both above suggestions are accepted, using provider.for() to merge entities and allowing async resource attributes, I believe there may be no need for a ResourceProvider or ResourceInitializer.

  1. Resources are merged in the SDK before being passed to the *Provider constructors, async resource attributes continue to resolve even after this occurs
  2. New entities, including potentially async attribute values, are layered on the resource using provider.for(...).
  3. The export pipeline ensures all resource attributes are resolved before any export. If resource is resolved, wait is a noop. If a new entity was layered on top of the core resource with async attributes, this mechanism continues to work.

This is actually how the JS entity prototype currently works, except that *Provider.for is not yet implemented.

@github-actions
Copy link
Copy Markdown

This PR was marked stale due to lack of activity. It will be closed in 7 days.

@github-actions github-actions bot added the Stale label Oct 15, 2025
@jsuereth jsuereth changed the title OTEP: Allow Entity on InstrumentationScope OTEP: Allow multiple Resources in an SDK Oct 20, 2025
@github-actions github-actions bot removed the Stale label Oct 21, 2025
@github-actions
Copy link
Copy Markdown

This PR was marked stale due to lack of activity. It will be closed in 7 days.

@github-actions github-actions bot added the Stale label Oct 28, 2025
@github-actions
Copy link
Copy Markdown

github-actions bot commented Nov 4, 2025

Closed as inactive. Feel free to reopen if this PR is still being worked on.

@github-actions github-actions bot closed this Nov 4, 2025
@dyladan dyladan reopened this Nov 24, 2025
@dyladan dyladan removed the Stale label Nov 24, 2025
@jsuereth jsuereth marked this pull request as ready for review December 15, 2025 16:39
@jsuereth jsuereth requested a review from a team as a code owner December 15, 2025 16:39
@jsuereth jsuereth removed the Stale label Jan 13, 2026
@dyladan
Copy link
Copy Markdown
Member

dyladan commented Jan 29, 2026

My main realization is that we can't include the Bind function in the API since it would add a dependency on resource, which is part of the SDK.

@dashpole can you add this comment somewhere on the diff so we can keep track of it as a thread? If this is a deal breaker it is a big problem for the OTEP as written because instrumentations are expected to be able to bind Entities to *Providers with a dependency on only the API. The bind function need only accept an Entity, not a Resource. The Resource and how the Entity is merged into it is considered to be an SDK detail not exposed via API. Is it not possible to add a bind method to the API which accepts a new type?

@carlosalberto
Copy link
Copy Markdown
Contributor

Approving this after reviewing the Java POC, where Entity is defined at the API level, rather than the SDK (unlike Resource, that is).

@dyladan
Copy link
Copy Markdown
Member

dyladan commented Jan 30, 2026

JS prototype now up to date open-telemetry/opentelemetry-js#6357

@martinkuba
Copy link
Copy Markdown
Contributor

If I understand correctly, this proposal works when the caller of forEntity() is the only emitter of the telemetry bound to that entity. How would this work for entities that should be applied to all telemetry (all instrumentations, and user application)? Browser sessions fall into this category.

In addition, when a browser session is rotated, the new session entity needs to be updated for all instrumentations. Instrumentations (typically) use the globally-registered providers. They would all either need to be notified when it changes, or the global provider itself would need to allow the entity to be updated. Is this use case purposefully excluded from the proposal? Would this be part of the API or SDK?

How would this work with multiple entities? Is the intent to chain forEntity() calls?

Copy link
Copy Markdown
Member

@jack-berg jack-berg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approve, but having learned that the browser SIG doesn't think this solves their problem, I don't think this is high enough priority to act on right now.

Copy link
Copy Markdown
Member

@reyang reyang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I support the direction of this OTEP. I've left several comments, but these are not blocking, we can sort these out when we actually hammer out the specification.

@jsuereth jsuereth enabled auto-merge March 18, 2026 03:04
@jsuereth jsuereth added this pull request to the merge queue Mar 23, 2026
Merged via the queue into open-telemetry:main with commit 849edf7 Mar 23, 2026
13 of 14 checks passed
@jsuereth jsuereth deleted the wip-entity-scopes branch March 23, 2026 18:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.