[DRAFT] Entity SDK prototype#8464
Conversation
- Create new Entity Detectors that are completely separate from existing reosurce detectors so entity must be FULL opt-in before behavior changes, even if OTLP is non-breaking. - Wire "either/or" scenarios into resource factory and declarative config. TODOs we need to sort out: - Features of ResourceConfiguration spec that interact poorly with entities, e.g. attribute-specific filters that aren't entity aware, raw attribute definitions. - Adding `env` as a supported detector for reading in Entity env variable propagation. - Dealing with oddities of ResourceBuilder/Factory wanting to only use attributes in Java - we worked around it for now.
jack-berg
left a comment
There was a problem hiding this comment.
You'll need to handle some merge conflicts since declarative config has been undergoing construction:
- It moved out of the incubator into a dedicated artifact in #8265
- We started commiting generated POJOs to VCS in #8408
As mentioned in the SIG meeting, I don't think you need the incubator copies of Entity interfaces. I pushed a commit here to delete them: jack-berg@3ea17f4
Per the discussion, resource detectors will need to updated to optionally produce entity-aware resources. If the user opts in, then those resource detectors can call the internal APIs from opentelemetry-sdk-common to produce those.
| /** | ||
| * Returns a map of attributes that describe the resource. | ||
| * | ||
| * @return a map of attributes. | ||
| */ | ||
| public abstract Attributes getAttributes(); | ||
| // @Memoized - This breaks nullaway. |
| } | ||
|
|
||
| /** Appends a new entity on to the end of the list of entities. */ | ||
| ResourceBuilder add(Entity e) { |
There was a problem hiding this comment.
| ResourceBuilder add(Entity e) { | |
| ResourceBuilder addEntity(Entity e) { |
| return this; | ||
| } | ||
|
|
||
| /** Appends a new collection of entities on to the end of the list of entities. */ |
| }); | ||
| // In merge rules, raw comes last, so we return these last. | ||
| result.putAll(getRawAttributes()); | ||
| return result.build(); |
There was a problem hiding this comment.
Why compute / memoize these at get time instead of at initialization time? I.e. in Resource.create methods.
| * | ||
| * @return a map of attributes. | ||
| */ | ||
| abstract Attributes getRawAttributes(); |
| * | ||
| * @param entityType the entity type string of this entity. | ||
| */ | ||
| public static final EntityBuilder builder(String entityType) { |
There was a problem hiding this comment.
| public static final EntityBuilder builder(String entityType) { | |
| public static EntityBuilder builder(String entityType) { |
| * @param description a map of attributes that describe the entity. | ||
| * @return a {@code Entity}. | ||
| */ | ||
| static final Entity create( |
There was a problem hiding this comment.
| static final Entity create( | |
| static Entity create( |
| * A service provider interface (SPI) for providing a collection of {@link Entity} that are merged | ||
| * into the {@link Resource#getDefault() default resource}. | ||
| */ | ||
| public interface EntityDetector extends Ordered { |
There was a problem hiding this comment.
Why do we need a new EntityDetector SPI rather than just using existing ResourceProvider and having implementations provide entity aware resources?
|
|
||
| ExperimentalResourceDetectionModel detectionModel = model.getDetectionDevelopment(); | ||
| if (detectionModel != null) { | ||
| if (context.isEntitiesEnabled()) { |
There was a problem hiding this comment.
Let's assume that the toggle flag is controlled on the instrumentation side of things (i.e. the implementations of resource detectors / entity detectors).
| if (context.isEntitiesEnabled()) { | ||
| List<ExperimentalResourceDetectorModel> detectorModels = detectionModel.getDetectors(); | ||
| if (detectorModels != null) { | ||
| List<EntityDetector> detectors = new ArrayList<>(); |
There was a problem hiding this comment.
SPIs work differently in declarative config than in autoconfigure. Rather than having a dedicated SPI per extension plugin interface (i.e. ResourceProvider, ConfigurableSpanExporterProvider, etc), there's a single ComponentProvider SPI. Implementations specify the type of extension plugin interface they provide via ComponentProvider.getType().
Also, we we're discussing in DMs about adjusting the semantics of existing declarative configuration resource provider types to make them entity aware, such that YAML like:
resource:
attributes_list: ${OTEL_RESOURCE_ATTRIBUTES}
detection/development: # /development properties may not be supported in all SDKs
detectors:
- env: # We add this - it allows runtimes, like Cloud Run or AWS lambda to pass resource identity via ENV variable without blowing away existing working setups.
- service:
- host:
- process:
- container:
Which is valid today. The env, service, host, process, container detectors would be updated to produce entity-aware Resources.
Going this route, I think there's basically nothing that needs to be done in ResourceFactory. It will start configuring entity-aware resources when the detectors are updated to produce them.
This is a more up-to-date PR accounting for changes from OpenTelemetry Configuraiton work for Entities.
What this does:
sdk-extensions/incubatingA few issues though:
Resourceis exposed in the SDK as an autovalue - which has compatibility limitations. I"m not sure how to keep the auto API compat bot happy here as effectively you can't subclass this without breaking Java's visibiltiy rules, but also it appears like it can be subclassed if you do bytecode rewritting so it technically is a bincompat change.