-
Notifications
You must be signed in to change notification settings - Fork 989
Entity SDK - Initial opt-in SDK features #8464
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jsuereth
wants to merge
18
commits into
open-telemetry:main
Choose a base branch
from
jsuereth:wip-entity-sdk-for-reals
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
7f67a89
Start the reboot of entities SDK for Java, this time something mergable.
jsuereth f611175
Add missing tests, spotlessApply
jsuereth 2ccb300
Add more tests and entity detectors.
jsuereth 509a7b9
First attempt to unify Entities with SDK Configuration.
jsuereth b4953f4
Merge main
jsuereth bdcc5d7
Merge Jack's change to not expose two Entity APIs.
jsuereth 279b1ea
Fix some PR feedback.
jsuereth da0b3fb
Fixes from review - Move to using existing resource detectors and a f…
jsuereth 25e35e6
Move experiment flag to common location.
jsuereth 6d78602
Spotless fixes.
jsuereth d200481
minor fixes from review, tests to follow
jsuereth c6fc930
Add tests.
jsuereth 09f0c57
Simplify Resource, fix tests.
jsuereth e2aec2a
Fix nit about builder method.
jsuereth c83a242
Remove entities from EnvironmentResource. Create new SHELL=/bin/bash
jsuereth a92a7ba
Flesh out tests.
jsuereth 169d186
Fix build time dependency issue my IDE missed.
jsuereth 632cf30
Fix tests and move constants.
jsuereth File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
83 changes: 83 additions & 0 deletions
83
...otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/EntityRefMarshaler.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| /* | ||
| * Copyright The OpenTelemetry Authors | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| package io.opentelemetry.exporter.internal.otlp; | ||
|
|
||
| import io.opentelemetry.api.internal.StringUtils; | ||
| import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; | ||
| import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; | ||
| import io.opentelemetry.exporter.internal.marshal.Serializer; | ||
| import io.opentelemetry.proto.common.v1.internal.EntityRef; | ||
| import io.opentelemetry.sdk.resources.internal.Entity; | ||
| import java.io.IOException; | ||
| import java.nio.charset.StandardCharsets; | ||
| import javax.annotation.Nullable; | ||
|
|
||
| /** | ||
| * A Marshaler of {@link io.opentelemetry.sdk.resources.internal.Entity}. | ||
| * | ||
| * <p>This class is internal and is hence not for public use. Its APIs are unstable and can change | ||
| * at any time. | ||
| */ | ||
| final class EntityRefMarshaler extends MarshalerWithSize { | ||
| @Nullable private final byte[] schemaUrlUtf8; | ||
| private final byte[] typeUtf8; | ||
| private final byte[][] idKeysUtf8; | ||
| private final byte[][] descriptionKeysUtf8; | ||
|
|
||
| @Override | ||
| protected void writeTo(Serializer output) throws IOException { | ||
| if (schemaUrlUtf8 != null) { | ||
| output.writeString(EntityRef.SCHEMA_URL, schemaUrlUtf8); | ||
| } | ||
| output.writeString(EntityRef.TYPE, typeUtf8); | ||
| output.writeRepeatedString(EntityRef.ID_KEYS, idKeysUtf8); | ||
| output.writeRepeatedString(EntityRef.DESCRIPTION_KEYS, descriptionKeysUtf8); | ||
| } | ||
|
|
||
| /** Consttructs an entity reference marshaler from a full entity. */ | ||
| static EntityRefMarshaler createForEntity(Entity e) { | ||
| byte[] schemaUrlUtf8 = null; | ||
| if (!StringUtils.isNullOrEmpty(e.getSchemaUrl())) { | ||
| schemaUrlUtf8 = e.getSchemaUrl().getBytes(StandardCharsets.UTF_8); | ||
| } | ||
| return new EntityRefMarshaler( | ||
| schemaUrlUtf8, | ||
| e.getType().getBytes(StandardCharsets.UTF_8), | ||
| e.getId().asMap().keySet().stream() | ||
| .map(key -> key.getKey().getBytes(StandardCharsets.UTF_8)) | ||
| .toArray(byte[][]::new), | ||
| e.getDescription().asMap().keySet().stream() | ||
| .map(key -> key.getKey().getBytes(StandardCharsets.UTF_8)) | ||
| .toArray(byte[][]::new)); | ||
| } | ||
|
|
||
| private EntityRefMarshaler( | ||
| @Nullable byte[] schemaUrlUtf8, | ||
| byte[] typeUtf8, | ||
| byte[][] idKeysUtf8, | ||
| byte[][] descriptionKeysUtf8) { | ||
| super(calculateSize(schemaUrlUtf8, typeUtf8, idKeysUtf8, descriptionKeysUtf8)); | ||
| this.schemaUrlUtf8 = schemaUrlUtf8; | ||
| this.typeUtf8 = typeUtf8; | ||
| this.idKeysUtf8 = idKeysUtf8; | ||
| this.descriptionKeysUtf8 = descriptionKeysUtf8; | ||
| } | ||
|
|
||
| private static int calculateSize( | ||
| @Nullable byte[] schemaUrlUtf8, | ||
| byte[] typeUtf8, | ||
| byte[][] idKeysUtf8, | ||
| byte[][] descriptionKeysUtf8) { | ||
| int size = 0; | ||
| if (schemaUrlUtf8 != null) { | ||
| size += MarshalerUtil.sizeBytes(EntityRef.SCHEMA_URL, schemaUrlUtf8); | ||
| } | ||
| size += MarshalerUtil.sizeBytes(EntityRef.TYPE, typeUtf8); | ||
| size += MarshalerUtil.sizeRepeatedString(EntityRef.ID_KEYS, idKeysUtf8); | ||
| size += MarshalerUtil.sizeRepeatedString(EntityRef.DESCRIPTION_KEYS, descriptionKeysUtf8); | ||
| return size; | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
87 changes: 87 additions & 0 deletions
87
.../common/src/test/java/io/opentelemetry/exporter/internal/otlp/EntityRefMarshalerTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| /* | ||
| * Copyright The OpenTelemetry Authors | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| package io.opentelemetry.exporter.internal.otlp; | ||
|
|
||
| import static org.assertj.core.api.Assertions.assertThat; | ||
|
|
||
| import com.google.protobuf.InvalidProtocolBufferException; | ||
| import com.google.protobuf.Message; | ||
| import com.google.protobuf.util.JsonFormat; | ||
| import io.opentelemetry.api.common.Attributes; | ||
| import io.opentelemetry.exporter.internal.marshal.Marshaler; | ||
| import io.opentelemetry.proto.common.v1.EntityRef; | ||
| import io.opentelemetry.sdk.resources.internal.Entity; | ||
| import java.io.ByteArrayOutputStream; | ||
| import java.io.IOException; | ||
| import java.io.UncheckedIOException; | ||
| import java.nio.charset.StandardCharsets; | ||
| import org.junit.jupiter.api.Test; | ||
|
|
||
| class EntityRefMarshalerTest { | ||
| @Test | ||
| void toEntityRefs() { | ||
| Entity e = | ||
| Entity.builder("test") | ||
| .setSchemaUrl("test-url") | ||
| .setDescription(Attributes.builder().put("desc.key", "desc.value").build()) | ||
| .setId(Attributes.builder().put("id.key", "id.value").build()) | ||
| .build(); | ||
| EntityRef proto = parse(EntityRef.getDefaultInstance(), EntityRefMarshaler.createForEntity(e)); | ||
| assertThat(proto.getType()).isEqualTo("test"); | ||
| assertThat(proto.getSchemaUrl()).isEqualTo("test-url"); | ||
| assertThat(proto.getIdKeysList()).containsExactly("id.key"); | ||
| assertThat(proto.getDescriptionKeysList()).containsExactly("desc.key"); | ||
| } | ||
|
|
||
| @SuppressWarnings("unchecked") | ||
| private static <T extends Message> T parse(T prototype, Marshaler marshaler) { | ||
| byte[] serialized = toByteArray(marshaler); | ||
| T result; | ||
| try { | ||
| result = (T) prototype.newBuilderForType().mergeFrom(serialized).build(); | ||
| } catch (InvalidProtocolBufferException e) { | ||
| throw new UncheckedIOException(e); | ||
| } | ||
| // Our marshaler should produce the exact same length of serialized output (for example, field | ||
| // default values are not outputted), so we check that here. The output itself may have slightly | ||
| // different ordering, mostly due to the way we don't output oneof values in field order all the | ||
| // tieme. If the lengths are equal and the resulting protos are equal, the marshaling is | ||
| // guaranteed to be valid. | ||
| assertThat(result.getSerializedSize()).isEqualTo(serialized.length); | ||
|
|
||
| // Compare JSON | ||
| String json = toJson(marshaler); | ||
| Message.Builder builder = prototype.newBuilderForType(); | ||
| try { | ||
| JsonFormat.parser().merge(json, builder); | ||
| } catch (InvalidProtocolBufferException e) { | ||
| throw new UncheckedIOException(e); | ||
| } | ||
| assertThat(builder.build()).isEqualTo(result); | ||
|
|
||
| return result; | ||
| } | ||
|
|
||
| private static byte[] toByteArray(Marshaler marshaler) { | ||
| ByteArrayOutputStream bos = new ByteArrayOutputStream(); | ||
| try { | ||
| marshaler.writeBinaryTo(bos); | ||
| } catch (IOException e) { | ||
| throw new UncheckedIOException(e); | ||
| } | ||
| return bos.toByteArray(); | ||
| } | ||
|
|
||
| private static String toJson(Marshaler marshaler) { | ||
| ByteArrayOutputStream bos = new ByteArrayOutputStream(); | ||
| try { | ||
| marshaler.writeJsonTo(bos); | ||
| } catch (IOException e) { | ||
| throw new UncheckedIOException(e); | ||
| } | ||
| return new String(bos.toByteArray(), StandardCharsets.UTF_8); | ||
| } | ||
| } |
100 changes: 100 additions & 0 deletions
100
...p/common/src/test/java/io/opentelemetry/exporter/internal/otlp/ResourceMarshalerTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| /* | ||
| * Copyright The OpenTelemetry Authors | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| package io.opentelemetry.exporter.internal.otlp; | ||
|
|
||
| import static io.opentelemetry.api.common.AttributeKey.stringKey; | ||
| import static org.assertj.core.api.Assertions.assertThat; | ||
|
|
||
| import com.google.protobuf.InvalidProtocolBufferException; | ||
| import com.google.protobuf.Message; | ||
| import com.google.protobuf.util.JsonFormat; | ||
| import io.opentelemetry.api.common.Attributes; | ||
| import io.opentelemetry.exporter.internal.marshal.Marshaler; | ||
| import io.opentelemetry.proto.resource.v1.Resource; | ||
| import io.opentelemetry.sdk.resources.ResourceBuilder; | ||
| import io.opentelemetry.sdk.resources.internal.Entity; | ||
| import io.opentelemetry.sdk.resources.internal.EntityUtil; | ||
| import java.io.ByteArrayOutputStream; | ||
| import java.io.IOException; | ||
| import java.io.UncheckedIOException; | ||
| import java.nio.charset.StandardCharsets; | ||
| import org.junit.jupiter.api.Test; | ||
|
|
||
| class ResourceMarshalerTest { | ||
|
|
||
| @Test | ||
| void marshalResourceWithEntities() { | ||
| Entity entity = | ||
| Entity.builder("process") | ||
| .setId(Attributes.of(stringKey("process.pid"), "1234")) | ||
| .setDescription(Attributes.of(stringKey("process.executable.name"), "java")) | ||
| .setSchemaUrl("http://process.schema") | ||
| .build(); | ||
|
|
||
| ResourceBuilder builder = | ||
| io.opentelemetry.sdk.resources.Resource.builder().put("service.name", "my-service"); | ||
| EntityUtil.addEntity(builder, entity); | ||
| io.opentelemetry.sdk.resources.Resource resourceWithEntity = builder.build(); | ||
|
|
||
| Resource proto = | ||
| parse(Resource.getDefaultInstance(), ResourceMarshaler.create(resourceWithEntity)); | ||
|
|
||
| assertThat(proto.getAttributesList()).hasSize(3); | ||
| assertThat(proto.getAttributesList().stream().map(a -> a.getKey())) | ||
| .containsExactlyInAnyOrder("service.name", "process.pid", "process.executable.name"); | ||
|
|
||
| assertThat(proto.getEntityRefsList()).hasSize(1); | ||
| assertThat(proto.getEntityRefs(0).getType()).isEqualTo("process"); | ||
| assertThat(proto.getEntityRefs(0).getSchemaUrl()).isEqualTo("http://process.schema"); | ||
| assertThat(proto.getEntityRefs(0).getIdKeysList()).containsExactly("process.pid"); | ||
| assertThat(proto.getEntityRefs(0).getDescriptionKeysList()) | ||
| .containsExactly("process.executable.name"); | ||
| } | ||
|
|
||
| @SuppressWarnings("unchecked") | ||
| private static <T extends Message> T parse(T prototype, Marshaler marshaler) { | ||
| byte[] serialized = toByteArray(marshaler); | ||
| T result; | ||
| try { | ||
| result = (T) prototype.newBuilderForType().mergeFrom(serialized).build(); | ||
| } catch (InvalidProtocolBufferException e) { | ||
| throw new UncheckedIOException(e); | ||
| } | ||
| assertThat(result.getSerializedSize()).isEqualTo(serialized.length); | ||
|
|
||
| // Compare JSON | ||
| String json = toJson(marshaler); | ||
| Message.Builder protoBuilder = prototype.newBuilderForType(); | ||
| try { | ||
| JsonFormat.parser().merge(json, protoBuilder); | ||
| } catch (InvalidProtocolBufferException e) { | ||
| throw new UncheckedIOException(e); | ||
| } | ||
| assertThat(protoBuilder.build()).isEqualTo(result); | ||
|
|
||
| return result; | ||
| } | ||
|
|
||
| private static byte[] toByteArray(Marshaler marshaler) { | ||
| ByteArrayOutputStream bos = new ByteArrayOutputStream(); | ||
| try { | ||
| marshaler.writeBinaryTo(bos); | ||
| } catch (IOException e) { | ||
| throw new UncheckedIOException(e); | ||
| } | ||
| return bos.toByteArray(); | ||
| } | ||
|
|
||
| private static String toJson(Marshaler marshaler) { | ||
| ByteArrayOutputStream bos = new ByteArrayOutputStream(); | ||
| try { | ||
| marshaler.writeJsonTo(bos); | ||
| } catch (IOException e) { | ||
| throw new UncheckedIOException(e); | ||
| } | ||
| return new String(bos.toByteArray(), StandardCharsets.UTF_8); | ||
| } | ||
| } |
20 changes: 20 additions & 0 deletions
20
.../main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/EntityExperimentConstants.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| /* | ||
| * Copyright The OpenTelemetry Authors | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| package io.opentelemetry.sdk.autoconfigure.spi.internal; | ||
|
|
||
| /** | ||
| * Constants for experimental entity SDK features. | ||
| * | ||
| * <p>This class is internal and is hence not for public use. Its APIs are unstable and can change | ||
| * at any time. | ||
| */ | ||
| public final class EntityExperimentConstants { | ||
|
|
||
| /** The configuration key for enabling experimental entity support in resource detectors. */ | ||
| public static final String EXPERIMENTAL_ENTITIES_ENABLED = "otel.experimental.entities.enabled"; | ||
|
|
||
| private EntityExperimentConstants() {} | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.