diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index e01f4b3cbee..d5905f82c94 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -85,7 +85,7 @@ val DEPENDENCIES = listOf( "io.jaegertracing:jaeger-client:1.8.1", "io.opentelemetry.contrib:opentelemetry-aws-xray-propagator:1.46.0-alpha", "io.opentelemetry.semconv:opentelemetry-semconv-incubating:1.32.0-alpha", - "io.opentelemetry.proto:opentelemetry-proto:1.5.0-alpha", + "io.opentelemetry.proto:opentelemetry-proto:1.7.0-alpha", "io.opentracing:opentracing-api:0.33.0", "io.opentracing:opentracing-noop:0.33.0", "junit:junit:4.13.2", diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileData.java index 520139b2452..ae67fde5908 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileData.java @@ -6,13 +6,8 @@ package io.opentelemetry.exporter.otlp.internal.data; import com.google.auto.value.AutoValue; -import io.opentelemetry.exporter.internal.otlp.AttributeKeyValue; -import io.opentelemetry.exporter.otlp.profiles.AttributeUnitData; -import io.opentelemetry.exporter.otlp.profiles.FunctionData; -import io.opentelemetry.exporter.otlp.profiles.LinkData; -import io.opentelemetry.exporter.otlp.profiles.LocationData; -import io.opentelemetry.exporter.otlp.profiles.MappingData; import io.opentelemetry.exporter.otlp.profiles.ProfileData; +import io.opentelemetry.exporter.otlp.profiles.ProfileDictionaryData; import io.opentelemetry.exporter.otlp.profiles.SampleData; import io.opentelemetry.exporter.otlp.profiles.ValueTypeData; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; @@ -23,8 +18,7 @@ /** * Auto value implementation of {@link ProfileData}, which represents a complete profile, including - * sample types, samples, mappings to binaries, locations, functions, string table, and additional - * metadata. + * sample types, samples, mappings to binaries, locations, and additional metadata. * *

This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. @@ -42,16 +36,10 @@ public abstract class ImmutableProfileData implements ProfileData { public static ProfileData create( Resource resource, InstrumentationScopeInfo instrumentationScopeInfo, + ProfileDictionaryData profileDictionaryData, List sampleTypes, List samples, - List mappingTable, - List locationTable, List locationIndices, - List functionTable, - List> attributeTable, - List attributeUnits, - List linkTable, - List stringTable, long timeNanos, long durationNanos, ValueTypeData periodType, @@ -66,16 +54,10 @@ public static ProfileData create( return new AutoValue_ImmutableProfileData( resource, instrumentationScopeInfo, + profileDictionaryData, sampleTypes, samples, - mappingTable, - locationTable, locationIndices, - functionTable, - attributeTable, - attributeUnits, - linkTable, - stringTable, timeNanos, durationNanos, periodType, diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileDictionaryData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileDictionaryData.java new file mode 100644 index 00000000000..4ee54e7d9ea --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/internal/data/ImmutableProfileDictionaryData.java @@ -0,0 +1,55 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.internal.data; + +import com.google.auto.value.AutoValue; +import io.opentelemetry.exporter.internal.otlp.AttributeKeyValue; +import io.opentelemetry.exporter.otlp.profiles.AttributeUnitData; +import io.opentelemetry.exporter.otlp.profiles.FunctionData; +import io.opentelemetry.exporter.otlp.profiles.LinkData; +import io.opentelemetry.exporter.otlp.profiles.LocationData; +import io.opentelemetry.exporter.otlp.profiles.MappingData; +import io.opentelemetry.exporter.otlp.profiles.ProfileDictionaryData; +import java.util.List; +import javax.annotation.concurrent.Immutable; + +/** + * Auto value implementation of {@link ProfileDictionaryData}, which represents profiles data shared + * across the entire message being sent. + * + *

This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +@Immutable +@AutoValue +public abstract class ImmutableProfileDictionaryData implements ProfileDictionaryData { + + /** + * Returns a new ProfileData representing the given data. + * + * @return a new ProfileData representing the given data. + */ + @SuppressWarnings("TooManyParameters") + public static ProfileDictionaryData create( + List mappingTable, + List locationTable, + List functionTable, + List> attributeTable, + List attributeUnits, + List linkTable, + List stringTable) { + return new AutoValue_ImmutableProfileDictionaryData( + mappingTable, + locationTable, + functionTable, + attributeTable, + attributeUnits, + linkTable, + stringTable); + } + + ImmutableProfileDictionaryData() {} +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileData.java index 0f6ef8e6ea3..54f5e1743ac 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileData.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileData.java @@ -6,7 +6,6 @@ package io.opentelemetry.exporter.otlp.profiles; import io.opentelemetry.api.internal.OtelEncodingUtils; -import io.opentelemetry.exporter.internal.otlp.AttributeKeyValue; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.resources.Resource; import java.nio.ByteBuffer; @@ -16,7 +15,7 @@ /** * Represents a complete profile, including sample types, samples, mappings to binaries, locations, - * functions, string table, and additional metadata. + * and additional metadata. * * @see "profiles.proto::Profile" */ @@ -29,41 +28,18 @@ public interface ProfileData { /** Returns the instrumentation scope that generated this profile. */ InstrumentationScopeInfo getInstrumentationScopeInfo(); + /** Returns the dictionary data of this profile. */ + ProfileDictionaryData getProfileDictionaryData(); + /** A description of the samples associated with each Sample.value. */ List getSampleTypes(); /** The set of samples recorded in this profile. */ List getSamples(); - /** - * Mapping from address ranges to the image/binary/library mapped into that address range. - * mapping[0] will be the main binary. - */ - List getMappingTable(); - - /** Locations referenced by samples via location_indices. */ - List getLocationTable(); - /** Array of locations referenced by samples. */ List getLocationIndices(); - /** Functions referenced by locations. */ - List getFunctionTable(); - - /** Lookup table for attributes. */ - List> getAttributeTable(); - - /** Represents a mapping between Attribute Keys and Units. */ - List getAttributeUnits(); - - /** Lookup table for links. */ - List getLinkTable(); - - /** - * A common table for strings referenced by various messages. string_table[0] must always be "". - */ - List getStringTable(); - /** Time of collection (UTC) represented as nanoseconds past the epoch. */ long getTimeNanos(); diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileDictionaryData.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileDictionaryData.java new file mode 100644 index 00000000000..e67b27d8e75 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileDictionaryData.java @@ -0,0 +1,45 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import io.opentelemetry.exporter.internal.otlp.AttributeKeyValue; +import java.util.List; +import javax.annotation.concurrent.Immutable; + +/** + * Represents profiles data shared across the entire message being sent. + * + * @see "profiles.proto::ProfilesDictionary" + */ +@Immutable +public interface ProfileDictionaryData { + + /** + * Mapping from address ranges to the image/binary/library mapped into that address range. + * mapping[0] will be the main binary. + */ + List getMappingTable(); + + /** Locations referenced by samples via location_indices. */ + List getLocationTable(); + + /** Functions referenced by locations. */ + List getFunctionTable(); + + /** Lookup table for attributes. */ + List> getAttributeTable(); + + /** Represents a mapping between Attribute Keys and Units. */ + List getAttributeUnits(); + + /** Lookup table for links. */ + List getLinkTable(); + + /** + * A common table for strings referenced by various messages. string_table[0] must always be "". + */ + List getStringTable(); +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileDictionaryMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileDictionaryMarshaler.java new file mode 100644 index 00000000000..234040a7d84 --- /dev/null +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileDictionaryMarshaler.java @@ -0,0 +1,120 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.otlp.profiles; + +import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; +import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; +import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.internal.otlp.KeyValueMarshaler; +import io.opentelemetry.proto.profiles.v1development.internal.ProfilesDictionary; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +final class ProfileDictionaryMarshaler extends MarshalerWithSize { + + private final MappingMarshaler[] mappingTableMarshalers; + private final LocationMarshaler[] locationTableMarshalers; + private final FunctionMarshaler[] functionTableMarshalers; + private final KeyValueMarshaler[] attributeTableMarshalers; + private final AttributeUnitMarshaler[] attributeUnitMarshalers; + private final LinkMarshaler[] linkTableMarshalers; + private final byte[][] stringTable; + + static ProfileDictionaryMarshaler create(ProfileDictionaryData profileDictionaryData) { + + MappingMarshaler[] mappingMarshalers = + MappingMarshaler.createRepeated(profileDictionaryData.getMappingTable()); + LocationMarshaler[] locationMarshalers = + LocationMarshaler.createRepeated(profileDictionaryData.getLocationTable()); + FunctionMarshaler[] functionMarshalers = + FunctionMarshaler.createRepeated(profileDictionaryData.getFunctionTable()); + KeyValueMarshaler[] attributeTableMarshalers = + KeyValueMarshaler.createRepeated(profileDictionaryData.getAttributeTable()); + AttributeUnitMarshaler[] attributeUnitsMarshalers = + AttributeUnitMarshaler.createRepeated(profileDictionaryData.getAttributeUnits()); + LinkMarshaler[] linkMarshalers = + LinkMarshaler.createRepeated(profileDictionaryData.getLinkTable()); + + byte[][] convertedStrings = new byte[profileDictionaryData.getStringTable().size()][]; + for (int i = 0; i < profileDictionaryData.getStringTable().size(); i++) { + convertedStrings[i] = + profileDictionaryData.getStringTable().get(i).getBytes(StandardCharsets.UTF_8); + } + + return new ProfileDictionaryMarshaler( + mappingMarshalers, + locationMarshalers, + functionMarshalers, + attributeTableMarshalers, + attributeUnitsMarshalers, + linkMarshalers, + convertedStrings); + } + + private ProfileDictionaryMarshaler( + MappingMarshaler[] mappingTableMarshalers, + LocationMarshaler[] locationTableMarshalers, + FunctionMarshaler[] functionTableMarshalers, + KeyValueMarshaler[] attributeTableMarshalers, + AttributeUnitMarshaler[] attributeUnitMarshalers, + LinkMarshaler[] linkTableMarshalers, + byte[][] stringTableUtf8) { + super( + calculateSize( + mappingTableMarshalers, + locationTableMarshalers, + functionTableMarshalers, + attributeTableMarshalers, + attributeUnitMarshalers, + linkTableMarshalers, + stringTableUtf8)); + this.mappingTableMarshalers = mappingTableMarshalers; + this.locationTableMarshalers = locationTableMarshalers; + this.functionTableMarshalers = functionTableMarshalers; + this.attributeTableMarshalers = attributeTableMarshalers; + this.attributeUnitMarshalers = attributeUnitMarshalers; + this.linkTableMarshalers = linkTableMarshalers; + this.stringTable = stringTableUtf8; + } + + @Override + protected void writeTo(Serializer output) throws IOException { + output.serializeRepeatedMessage(ProfilesDictionary.MAPPING_TABLE, mappingTableMarshalers); + output.serializeRepeatedMessage(ProfilesDictionary.LOCATION_TABLE, locationTableMarshalers); + output.serializeRepeatedMessage(ProfilesDictionary.FUNCTION_TABLE, functionTableMarshalers); + output.serializeRepeatedMessage(ProfilesDictionary.ATTRIBUTE_TABLE, attributeTableMarshalers); + output.serializeRepeatedMessage(ProfilesDictionary.ATTRIBUTE_UNITS, attributeUnitMarshalers); + output.serializeRepeatedMessage(ProfilesDictionary.LINK_TABLE, linkTableMarshalers); + output.serializeRepeatedString(ProfilesDictionary.STRING_TABLE, stringTable); + } + + private static int calculateSize( + MappingMarshaler[] mappingMarshalers, + LocationMarshaler[] locationMarshalers, + FunctionMarshaler[] functionMarshalers, + KeyValueMarshaler[] attributeTableMarshalers, + AttributeUnitMarshaler[] attributeUnitMarshalers, + LinkMarshaler[] linkMarshalers, + byte[][] stringTable) { + int size; + size = 0; + size += MarshalerUtil.sizeRepeatedMessage(ProfilesDictionary.MAPPING_TABLE, mappingMarshalers); + size += + MarshalerUtil.sizeRepeatedMessage(ProfilesDictionary.LOCATION_TABLE, locationMarshalers); + size += + MarshalerUtil.sizeRepeatedMessage(ProfilesDictionary.FUNCTION_TABLE, functionMarshalers); + size += + MarshalerUtil.sizeRepeatedMessage( + ProfilesDictionary.ATTRIBUTE_TABLE, attributeTableMarshalers); + size += + MarshalerUtil.sizeRepeatedMessage( + ProfilesDictionary.ATTRIBUTE_UNITS, attributeUnitMarshalers); + size += MarshalerUtil.sizeRepeatedMessage(ProfilesDictionary.LINK_TABLE, linkMarshalers); + size += MarshalerUtil.sizeRepeatedString(ProfilesDictionary.STRING_TABLE, stringTable); + + return size; + } +} diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileMarshaler.java index 8d04bbbf94f..07b66848489 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileMarshaler.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfileMarshaler.java @@ -8,25 +8,16 @@ import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; import io.opentelemetry.exporter.internal.marshal.Serializer; -import io.opentelemetry.exporter.internal.otlp.KeyValueMarshaler; import io.opentelemetry.proto.profiles.v1development.internal.Profile; import java.io.IOException; import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; import java.util.List; final class ProfileMarshaler extends MarshalerWithSize { private final ValueTypeMarshaler[] sampleTypeMarshalers; private final SampleMarshaler[] sampleMarshalers; - private final MappingMarshaler[] mappingTableMarshalers; - private final LocationMarshaler[] locationTableMarshalers; private final List locationIndices; - private final FunctionMarshaler[] functionTableMarshalers; - private final KeyValueMarshaler[] attributeTableMarshalers; - private final AttributeUnitMarshaler[] attributeUnitMarshalers; - private final LinkMarshaler[] linkTableMarshalers; - private final byte[][] stringTable; private final long timeNanos; private final long durationNanos; private final ValueTypeMarshaler periodTypeMarshaler; @@ -44,38 +35,15 @@ static ProfileMarshaler create(ProfileData profileData) { ValueTypeMarshaler[] sampleTypeMarshalers = ValueTypeMarshaler.createRepeated(profileData.getSampleTypes()); SampleMarshaler[] sampleMarshalers = SampleMarshaler.createRepeated(profileData.getSamples()); - MappingMarshaler[] mappingMarshalers = - MappingMarshaler.createRepeated(profileData.getMappingTable()); - LocationMarshaler[] locationMarshalers = - LocationMarshaler.createRepeated(profileData.getLocationTable()); - FunctionMarshaler[] functionMarshalers = - FunctionMarshaler.createRepeated(profileData.getFunctionTable()); - KeyValueMarshaler[] attributeTableMarshalers = - KeyValueMarshaler.createRepeated(profileData.getAttributeTable()); - AttributeUnitMarshaler[] attributeUnitsMarshalers = - AttributeUnitMarshaler.createRepeated(profileData.getAttributeUnits()); - LinkMarshaler[] linkMarshalers = LinkMarshaler.createRepeated(profileData.getLinkTable()); ValueTypeMarshaler periodTypeMarshaler = ValueTypeMarshaler.create(profileData.getPeriodType()); - byte[][] convertedStrings = new byte[profileData.getStringTable().size()][]; - for (int i = 0; i < profileData.getStringTable().size(); i++) { - convertedStrings[i] = profileData.getStringTable().get(i).getBytes(StandardCharsets.UTF_8); - } - int droppedAttributesCount = profileData.getTotalAttributeCount() - profileData.getAttributeIndices().size(); return new ProfileMarshaler( sampleTypeMarshalers, sampleMarshalers, - mappingMarshalers, - locationMarshalers, profileData.getLocationIndices(), - functionMarshalers, - attributeTableMarshalers, - attributeUnitsMarshalers, - linkMarshalers, - convertedStrings, profileData.getTimeNanos(), profileData.getDurationNanos(), periodTypeMarshaler, @@ -92,14 +60,7 @@ static ProfileMarshaler create(ProfileData profileData) { private ProfileMarshaler( ValueTypeMarshaler[] sampleTypeMarshalers, SampleMarshaler[] sampleMarshalers, - MappingMarshaler[] mappingTableMarshalers, - LocationMarshaler[] locationTableMarshalers, List locationIndices, - FunctionMarshaler[] functionTableMarshalers, - KeyValueMarshaler[] attributeTableMarshalers, - AttributeUnitMarshaler[] attributeUnitMarshalers, - LinkMarshaler[] linkTableMarshalers, - byte[][] stringTableUtf8, long timeNanos, long durationNanos, ValueTypeMarshaler periodTypeMarshaler, @@ -115,14 +76,7 @@ private ProfileMarshaler( calculateSize( sampleTypeMarshalers, sampleMarshalers, - mappingTableMarshalers, - locationTableMarshalers, locationIndices, - functionTableMarshalers, - attributeTableMarshalers, - attributeUnitMarshalers, - linkTableMarshalers, - stringTableUtf8, timeNanos, durationNanos, periodTypeMarshaler, @@ -136,14 +90,7 @@ private ProfileMarshaler( originalPayload)); this.sampleTypeMarshalers = sampleTypeMarshalers; this.sampleMarshalers = sampleMarshalers; - this.mappingTableMarshalers = mappingTableMarshalers; - this.locationTableMarshalers = locationTableMarshalers; this.locationIndices = locationIndices; - this.functionTableMarshalers = functionTableMarshalers; - this.attributeTableMarshalers = attributeTableMarshalers; - this.attributeUnitMarshalers = attributeUnitMarshalers; - this.linkTableMarshalers = linkTableMarshalers; - this.stringTable = stringTableUtf8; this.timeNanos = timeNanos; this.durationNanos = durationNanos; this.periodTypeMarshaler = periodTypeMarshaler; @@ -161,20 +108,13 @@ private ProfileMarshaler( protected void writeTo(Serializer output) throws IOException { output.serializeRepeatedMessage(Profile.SAMPLE_TYPE, sampleTypeMarshalers); output.serializeRepeatedMessage(Profile.SAMPLE, sampleMarshalers); - output.serializeRepeatedMessage(Profile.MAPPING_TABLE, mappingTableMarshalers); - output.serializeRepeatedMessage(Profile.LOCATION_TABLE, locationTableMarshalers); output.serializeRepeatedInt32(Profile.LOCATION_INDICES, locationIndices); - output.serializeRepeatedMessage(Profile.FUNCTION_TABLE, functionTableMarshalers); - output.serializeRepeatedMessage(Profile.ATTRIBUTE_TABLE, attributeTableMarshalers); - output.serializeRepeatedMessage(Profile.ATTRIBUTE_UNITS, attributeUnitMarshalers); - output.serializeRepeatedMessage(Profile.LINK_TABLE, linkTableMarshalers); - output.serializeRepeatedString(Profile.STRING_TABLE, stringTable); output.serializeInt64(Profile.TIME_NANOS, timeNanos); output.serializeInt64(Profile.DURATION_NANOS, durationNanos); output.serializeMessage(Profile.PERIOD_TYPE, periodTypeMarshaler); output.serializeInt64(Profile.PERIOD, period); output.serializeRepeatedInt32(Profile.COMMENT_STRINDICES, comment); - output.serializeInt32(Profile.DEFAULT_SAMPLE_TYPE_STRINDEX, defaultSampleType); + output.serializeInt32(Profile.DEFAULT_SAMPLE_TYPE_INDEX, defaultSampleType); output.serializeBytes(Profile.PROFILE_ID, profileId); output.serializeRepeatedInt32(Profile.ATTRIBUTE_INDICES, attributeIndices); @@ -186,14 +126,7 @@ protected void writeTo(Serializer output) throws IOException { private static int calculateSize( ValueTypeMarshaler[] sampleTypeMarshalers, SampleMarshaler[] sampleMarshalers, - MappingMarshaler[] mappingMarshalers, - LocationMarshaler[] locationMarshalers, List locationIndices, - FunctionMarshaler[] functionMarshalers, - KeyValueMarshaler[] attributeTableMarshalers, - AttributeUnitMarshaler[] attributeUnitMarshalers, - LinkMarshaler[] linkMarshalers, - byte[][] stringTable, long timeNanos, long durationNanos, ValueTypeMarshaler periodTypeMarshaler, @@ -209,20 +142,13 @@ private static int calculateSize( size = 0; size += MarshalerUtil.sizeRepeatedMessage(Profile.SAMPLE_TYPE, sampleTypeMarshalers); size += MarshalerUtil.sizeRepeatedMessage(Profile.SAMPLE, sampleMarshalers); - size += MarshalerUtil.sizeRepeatedMessage(Profile.MAPPING_TABLE, mappingMarshalers); - size += MarshalerUtil.sizeRepeatedMessage(Profile.LOCATION_TABLE, locationMarshalers); size += MarshalerUtil.sizeRepeatedInt32(Profile.LOCATION_INDICES, locationIndices); - size += MarshalerUtil.sizeRepeatedMessage(Profile.FUNCTION_TABLE, functionMarshalers); - size += MarshalerUtil.sizeRepeatedMessage(Profile.ATTRIBUTE_TABLE, attributeTableMarshalers); - size += MarshalerUtil.sizeRepeatedMessage(Profile.ATTRIBUTE_UNITS, attributeUnitMarshalers); - size += MarshalerUtil.sizeRepeatedMessage(Profile.LINK_TABLE, linkMarshalers); - size += MarshalerUtil.sizeRepeatedString(Profile.STRING_TABLE, stringTable); size += MarshalerUtil.sizeInt64(Profile.TIME_NANOS, timeNanos); size += MarshalerUtil.sizeInt64(Profile.DURATION_NANOS, durationNanos); size += MarshalerUtil.sizeMessage(Profile.PERIOD_TYPE, periodTypeMarshaler); size += MarshalerUtil.sizeInt64(Profile.PERIOD, period); size += MarshalerUtil.sizeRepeatedInt32(Profile.COMMENT_STRINDICES, comment); - size += MarshalerUtil.sizeInt64(Profile.DEFAULT_SAMPLE_TYPE_STRINDEX, defaultSampleType); + size += MarshalerUtil.sizeInt64(Profile.DEFAULT_SAMPLE_TYPE_INDEX, defaultSampleType); size += MarshalerUtil.sizeBytes(Profile.PROFILE_ID, profileId); size += MarshalerUtil.sizeRepeatedInt32(Profile.ATTRIBUTE_INDICES, attributeIndices); diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshaler.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshaler.java index 3d57825899a..4c7b953352d 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshaler.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshaler.java @@ -5,14 +5,18 @@ package io.opentelemetry.exporter.otlp.profiles; +import static io.opentelemetry.proto.collector.profiles.v1development.internal.ExportProfilesServiceRequest.DICTIONARY; + import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.exporter.internal.marshal.MarshalerUtil; import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize; import io.opentelemetry.exporter.internal.marshal.ProtoFieldInfo; import io.opentelemetry.exporter.internal.marshal.Serializer; +import io.opentelemetry.exporter.otlp.internal.data.ImmutableProfileDictionaryData; import io.opentelemetry.proto.collector.profiles.v1development.internal.ExportProfilesServiceRequest; import java.io.IOException; import java.util.Collection; +import java.util.Collections; /** * {@link Marshaler} to convert SDK {@link ProfileData} to OTLP ExportProfilesServiceRequest. @@ -22,26 +26,66 @@ */ public final class ProfilesRequestMarshaler extends MarshalerWithSize { + private static final ProfileDictionaryData EMPTY_DICTIONARY_DATA = + ImmutableProfileDictionaryData.create( + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList()); + private static final ProtoFieldInfo RESOURCE_PROFILES = ExportProfilesServiceRequest.RESOURCE_PROFILES; private final ResourceProfilesMarshaler[] resourceProfilesMarshalers; + private final ProfileDictionaryMarshaler profileDictionaryMarshaler; /** * Returns a {@link ProfilesRequestMarshaler} that can be used to convert the provided {@link * ProfileData} into a serialized OTLP ExportProfilesServiceRequest. */ public static ProfilesRequestMarshaler create(Collection profileList) { - return new ProfilesRequestMarshaler(ResourceProfilesMarshaler.create(profileList)); + // Verify all profiles in batch have identical dictionary + ProfileDictionaryData profileDictionaryData = null; + for (ProfileData profileData : profileList) { + if (profileDictionaryData == null) { + profileDictionaryData = profileData.getProfileDictionaryData(); + } else if (profileDictionaryData != profileData.getProfileDictionaryData()) { + throw new IllegalArgumentException( + "All profiles in batch must have identical ProfileDictionaryData"); + } + } + + ProfileDictionaryMarshaler profileDictionaryMarshaler = + ProfileDictionaryMarshaler.create( + profileDictionaryData == null ? EMPTY_DICTIONARY_DATA : profileDictionaryData); + + return new ProfilesRequestMarshaler( + ResourceProfilesMarshaler.create(profileList), profileDictionaryMarshaler); } - private ProfilesRequestMarshaler(ResourceProfilesMarshaler[] resourceProfilesMarshalers) { - super(MarshalerUtil.sizeRepeatedMessage(RESOURCE_PROFILES, resourceProfilesMarshalers)); + private ProfilesRequestMarshaler( + ResourceProfilesMarshaler[] resourceProfilesMarshalers, + ProfileDictionaryMarshaler profileDictionaryMarshaler) { + super(calculateSize(resourceProfilesMarshalers, profileDictionaryMarshaler)); this.resourceProfilesMarshalers = resourceProfilesMarshalers; + this.profileDictionaryMarshaler = profileDictionaryMarshaler; } @Override public void writeTo(Serializer output) throws IOException { output.serializeRepeatedMessage(RESOURCE_PROFILES, resourceProfilesMarshalers); + output.serializeMessage(DICTIONARY, profileDictionaryMarshaler); + } + + private static int calculateSize( + ResourceProfilesMarshaler[] resourceProfilesMarshalers, + ProfileDictionaryMarshaler profileDictionaryMarshaler) { + int size = 0; + size += MarshalerUtil.sizeRepeatedMessage(RESOURCE_PROFILES, resourceProfilesMarshalers); + size += MarshalerUtil.sizeMessage(DICTIONARY, profileDictionaryMarshaler); + return size; } } diff --git a/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/FakeTelemetryUtil.java b/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/FakeTelemetryUtil.java index 2c511bac6bf..eb997485fcf 100644 --- a/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/FakeTelemetryUtil.java +++ b/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/FakeTelemetryUtil.java @@ -7,6 +7,7 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.exporter.otlp.internal.data.ImmutableProfileData; +import io.opentelemetry.exporter.otlp.internal.data.ImmutableProfileDictionaryData; import io.opentelemetry.exporter.otlp.internal.data.ImmutableValueTypeData; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.resources.Resource; @@ -16,6 +17,16 @@ // TODO eventually merge with io.opentelemetry.exporter.otlp.testing.internal.FakeTelemetryUtil class FakeTelemetryUtil { + private static final ProfileDictionaryData EMPTY_PROFILE_DICTIONARY_DATA = + ImmutableProfileDictionaryData.create( + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList()); + private FakeTelemetryUtil() {} private static final InstrumentationScopeInfo SCOPE_INFO = @@ -30,13 +41,7 @@ static ProfileData generateFakeProfileData() { return ImmutableProfileData.create( Resource.create(Attributes.empty()), SCOPE_INFO, - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), + EMPTY_PROFILE_DICTIONARY_DATA, Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), diff --git a/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java b/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java index 3ed1d9159d2..33ddc1c0f47 100644 --- a/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java +++ b/exporters/otlp/profiles/src/test/java/io/opentelemetry/exporter/otlp/profiles/ProfilesRequestMarshalerTest.java @@ -20,6 +20,7 @@ import io.opentelemetry.exporter.otlp.internal.data.ImmutableLocationData; import io.opentelemetry.exporter.otlp.internal.data.ImmutableMappingData; import io.opentelemetry.exporter.otlp.internal.data.ImmutableProfileData; +import io.opentelemetry.exporter.otlp.internal.data.ImmutableProfileDictionaryData; import io.opentelemetry.exporter.otlp.internal.data.ImmutableSampleData; import io.opentelemetry.exporter.otlp.internal.data.ImmutableValueTypeData; import io.opentelemetry.proto.common.v1.InstrumentationScope; @@ -145,16 +146,17 @@ void compareResourceProfilesMarshaling() { ImmutableProfileData.create( Resource.create(Attributes.empty()), InstrumentationScopeInfo.create("testscope"), - Collections.emptyList(), - Collections.emptyList(), + ImmutableProfileDictionaryData.create( + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList()), Collections.emptyList(), Collections.emptyList(), listOf(1, 2), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), - Collections.emptyList(), 5L, 6L, ImmutableValueTypeData.create(1, 2, AggregationTemporality.CUMULATIVE),