OTEP: Allow multiple Resources in an SDK#4665
Conversation
|
Does this OTEP imply removing EntityRefs from the Resource in proto? |
|
I like this direction. |
smith
left a comment
There was a problem hiding this comment.
Just a few typo suggestions. There's a lot here but it's an understandable summary of the proposal.
No. EntityRef in resource would interact with Entity on InstrumentationScope, and we need to sort out how. |
dyladan
left a comment
There was a problem hiding this comment.
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.
- Resources are merged in the SDK before being passed to the
*Providerconstructors, async resource attributes continue to resolve even after this occurs - New entities, including potentially async attribute values, are layered on the resource using
provider.for(...). - 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.
|
This PR was marked stale due to lack of activity. It will be closed in 7 days. |
|
This PR was marked stale due to lack of activity. It will be closed in 7 days. |
|
Closed as inactive. Feel free to reopen if this PR is still being worked on. |
@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? |
|
Approving this after reviewing the Java POC, where |
|
JS prototype now up to date open-telemetry/opentelemetry-js#6357 |
|
If I understand correctly, this proposal works when the caller of 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 |
jack-berg
left a comment
There was a problem hiding this comment.
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.
reyang
left a comment
There was a problem hiding this comment.
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.
849edf7
Alternative to #4316 -
We propose allowing
{Signal}Providerto 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
instead of: