Skip to content

Commit 04e4140

Browse files
committed
Add Marshalers for profiling signal type
Envelope Marshalers, draft.
1 parent 485c123 commit 04e4140

File tree

5 files changed

+438
-36
lines changed

5 files changed

+438
-36
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.exporter.otlp.profiles;
7+
8+
import io.opentelemetry.exporter.internal.marshal.MarshalerUtil;
9+
import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize;
10+
import io.opentelemetry.exporter.internal.marshal.Serializer;
11+
import io.opentelemetry.exporter.internal.otlp.InstrumentationScopeMarshaler;
12+
import io.opentelemetry.proto.profiles.v1experimental.internal.ScopeProfiles;
13+
import java.io.IOException;
14+
15+
final class InstrumentationScopeProfilesMarshaler extends MarshalerWithSize {
16+
17+
private final InstrumentationScopeMarshaler instrumentationScope;
18+
private final ProfileContainerMarshaler[] profileContainerMarshalers;
19+
private final byte[] schemaUrlUtf8;
20+
21+
InstrumentationScopeProfilesMarshaler(
22+
InstrumentationScopeMarshaler instrumentationScope,
23+
byte[] schemaUrlUtf8,
24+
ProfileContainerMarshaler[] profileContainerMarshalers) {
25+
super(calculateSize(instrumentationScope, schemaUrlUtf8, profileContainerMarshalers));
26+
this.instrumentationScope = instrumentationScope;
27+
this.schemaUrlUtf8 = schemaUrlUtf8;
28+
this.profileContainerMarshalers = profileContainerMarshalers;
29+
}
30+
31+
@Override
32+
protected void writeTo(Serializer output) throws IOException {
33+
output.serializeMessage(ScopeProfiles.SCOPE, instrumentationScope);
34+
output.serializeRepeatedMessage(ScopeProfiles.PROFILES, profileContainerMarshalers);
35+
output.serializeString(ScopeProfiles.SCHEMA_URL, schemaUrlUtf8);
36+
}
37+
38+
private static int calculateSize(
39+
InstrumentationScopeMarshaler instrumentationScope,
40+
byte[] schemaUrlUtf8,
41+
ProfileContainerMarshaler[] profileContainerMarshalers) {
42+
int size = 0;
43+
size += MarshalerUtil.sizeMessage(ScopeProfiles.SCOPE, instrumentationScope);
44+
size += MarshalerUtil.sizeRepeatedMessage(ScopeProfiles.PROFILES, profileContainerMarshalers);
45+
size += MarshalerUtil.sizeBytes(ScopeProfiles.SCHEMA_URL, schemaUrlUtf8);
46+
return size;
47+
}
48+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.exporter.otlp.profiles;
7+
8+
import io.opentelemetry.exporter.internal.marshal.MarshalerUtil;
9+
import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize;
10+
import io.opentelemetry.exporter.internal.marshal.Serializer;
11+
import io.opentelemetry.exporter.internal.otlp.KeyValueMarshaler;
12+
import io.opentelemetry.proto.profiles.v1experimental.internal.ProfileContainer;
13+
import java.io.IOException;
14+
15+
final class ProfileContainerMarshaler extends MarshalerWithSize {
16+
17+
private final byte[] profileId;
18+
private final long startEpochNanos;
19+
private final long endEpochNanos;
20+
private final KeyValueMarshaler[] attributeMarshalers;
21+
private final int droppedAttributesCount;
22+
private final byte[] originalPayloadFormatUtf8;
23+
private final byte[] originalPayload;
24+
private final ProfileMarshaler profileMarshaler;
25+
26+
static ProfileContainerMarshaler create(ProfileContainerData profileContainerData) {
27+
int droppedAttributesCount =
28+
profileContainerData.getTotalAttributeCount() - profileContainerData.getAttributes().size();
29+
30+
// Not ideal, but this will do for now. ByteBuffer support in
31+
// Serialzer/CodedOutputStream/MarshalerUtilwill follow in a separate step.
32+
byte[] originalPayload = new byte[profileContainerData.getOriginalPayload().remaining()];
33+
profileContainerData.getOriginalPayload().get(originalPayload);
34+
35+
return new ProfileContainerMarshaler(
36+
profileContainerData.getProfileIdBytes(),
37+
profileContainerData.getStartEpochNanos(),
38+
profileContainerData.getEndEpochNanos(),
39+
KeyValueMarshaler.createForAttributes(profileContainerData.getAttributes()),
40+
droppedAttributesCount,
41+
MarshalerUtil.toBytes(profileContainerData.getOriginalPayloadFormat()),
42+
originalPayload,
43+
ProfileMarshaler.create(profileContainerData.getProfile()));
44+
}
45+
46+
private ProfileContainerMarshaler(
47+
byte[] profileId,
48+
long startEpochNanos,
49+
long endEpochNanos,
50+
KeyValueMarshaler[] attributeMarshalers,
51+
int droppedAttributesCount,
52+
byte[] originalPayloadFormat,
53+
byte[] originalPayload,
54+
ProfileMarshaler profileMarshaler) {
55+
super(
56+
calculateSize(
57+
profileId,
58+
startEpochNanos,
59+
endEpochNanos,
60+
attributeMarshalers,
61+
droppedAttributesCount,
62+
originalPayloadFormat,
63+
originalPayload,
64+
profileMarshaler));
65+
this.profileId = profileId;
66+
this.startEpochNanos = startEpochNanos;
67+
this.endEpochNanos = endEpochNanos;
68+
this.attributeMarshalers = attributeMarshalers;
69+
this.droppedAttributesCount = droppedAttributesCount;
70+
this.originalPayloadFormatUtf8 = originalPayloadFormat;
71+
this.originalPayload = originalPayload;
72+
this.profileMarshaler = profileMarshaler;
73+
}
74+
75+
@Override
76+
protected void writeTo(Serializer output) throws IOException {
77+
output.serializeBytes(ProfileContainer.PROFILE_ID, profileId);
78+
output.serializeFixed64(ProfileContainer.START_TIME_UNIX_NANO, startEpochNanos);
79+
output.serializeFixed64(ProfileContainer.END_TIME_UNIX_NANO, endEpochNanos);
80+
output.serializeRepeatedMessage(ProfileContainer.ATTRIBUTES, attributeMarshalers);
81+
output.serializeUInt32(ProfileContainer.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount);
82+
output.serializeString(ProfileContainer.ORIGINAL_PAYLOAD_FORMAT, originalPayloadFormatUtf8);
83+
output.serializeBytes(ProfileContainer.ORIGINAL_PAYLOAD, originalPayload);
84+
output.serializeMessage(ProfileContainer.PROFILE, profileMarshaler);
85+
}
86+
87+
private static int calculateSize(
88+
byte[] profileId,
89+
long startEpochNanos,
90+
long endEpochNanos,
91+
KeyValueMarshaler[] attributeMarshalers,
92+
int droppedAttributesCount,
93+
byte[] originalPayloadFormat,
94+
byte[] originalPayload,
95+
ProfileMarshaler profileMarshaler) {
96+
int size;
97+
size = 0;
98+
size += MarshalerUtil.sizeBytes(ProfileContainer.PROFILE_ID, profileId);
99+
size += MarshalerUtil.sizeFixed64(ProfileContainer.START_TIME_UNIX_NANO, startEpochNanos);
100+
size += MarshalerUtil.sizeFixed64(ProfileContainer.END_TIME_UNIX_NANO, endEpochNanos);
101+
size += MarshalerUtil.sizeRepeatedMessage(ProfileContainer.ATTRIBUTES, attributeMarshalers);
102+
size +=
103+
MarshalerUtil.sizeUInt32(ProfileContainer.DROPPED_ATTRIBUTES_COUNT, droppedAttributesCount);
104+
size +=
105+
MarshalerUtil.sizeBytes(ProfileContainer.ORIGINAL_PAYLOAD_FORMAT, originalPayloadFormat);
106+
size += MarshalerUtil.sizeBytes(ProfileContainer.ORIGINAL_PAYLOAD, originalPayload);
107+
size += MarshalerUtil.sizeMessage(ProfileContainer.PROFILE, profileMarshaler);
108+
return size;
109+
}
110+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.exporter.otlp.profiles;
7+
8+
import io.opentelemetry.exporter.internal.marshal.Marshaler;
9+
import io.opentelemetry.exporter.internal.marshal.MarshalerUtil;
10+
import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize;
11+
import io.opentelemetry.exporter.internal.marshal.ProtoFieldInfo;
12+
import io.opentelemetry.exporter.internal.marshal.Serializer;
13+
import io.opentelemetry.proto.collector.profiles.v1experimental.internal.ExportProfilesServiceRequest;
14+
import java.io.IOException;
15+
import java.util.Collection;
16+
17+
/**
18+
* {@link Marshaler} to convert SDK {@link ProfileContainerData} to OTLP
19+
* ExportProfilesServiceRequest.
20+
*
21+
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
22+
* at any time.
23+
*/
24+
public final class ProfilesRequestMarshaler extends MarshalerWithSize {
25+
26+
public static final ProtoFieldInfo RESOURCE_PROFILES =
27+
ExportProfilesServiceRequest.RESOURCE_PROFILES;
28+
29+
private final ResourceProfilesMarshaler[] resourceProfilesMarshalers;
30+
31+
/**
32+
* Returns a {@link ProfilesRequestMarshaler} that can be used to convert the provided {@link
33+
* ProfileContainerData} into a serialized OTLP ExportProfilesServiceRequest.
34+
*/
35+
public static ProfilesRequestMarshaler create(
36+
Collection<ProfileContainerData> profileContainerList) {
37+
return new ProfilesRequestMarshaler(ResourceProfilesMarshaler.create(profileContainerList));
38+
}
39+
40+
private ProfilesRequestMarshaler(ResourceProfilesMarshaler[] resourceProfilesMarshalers) {
41+
super(MarshalerUtil.sizeRepeatedMessage(RESOURCE_PROFILES, resourceProfilesMarshalers));
42+
this.resourceProfilesMarshalers = resourceProfilesMarshalers;
43+
}
44+
45+
@Override
46+
public void writeTo(Serializer output) throws IOException {
47+
output.serializeRepeatedMessage(RESOURCE_PROFILES, resourceProfilesMarshalers);
48+
}
49+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.exporter.otlp.profiles;
7+
8+
import io.opentelemetry.exporter.internal.marshal.MarshalerUtil;
9+
import io.opentelemetry.exporter.internal.marshal.MarshalerWithSize;
10+
import io.opentelemetry.exporter.internal.marshal.Serializer;
11+
import io.opentelemetry.exporter.internal.otlp.InstrumentationScopeMarshaler;
12+
import io.opentelemetry.exporter.internal.otlp.ResourceMarshaler;
13+
import io.opentelemetry.proto.profiles.v1experimental.internal.ResourceProfiles;
14+
import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
15+
import io.opentelemetry.sdk.resources.Resource;
16+
import java.io.IOException;
17+
import java.util.Collection;
18+
import java.util.List;
19+
import java.util.Map;
20+
21+
final class ResourceProfilesMarshaler extends MarshalerWithSize {
22+
23+
private final ResourceMarshaler resourceMarshaler;
24+
private final byte[] schemaUrl;
25+
private final InstrumentationScopeProfilesMarshaler[] instrumentationScopeProfilesMarshalers;
26+
27+
/** Returns Marshalers of ResourceProfiles created by grouping the provided Profiles. */
28+
@SuppressWarnings("AvoidObjectArrays")
29+
static ResourceProfilesMarshaler[] create(Collection<ProfileContainerData> profiles) {
30+
Map<Resource, Map<InstrumentationScopeInfo, List<ProfileContainerMarshaler>>>
31+
resourceAndScopeMap = groupByResourceAndScope(profiles);
32+
33+
ResourceProfilesMarshaler[] resourceProfilesMarshalers =
34+
new ResourceProfilesMarshaler[resourceAndScopeMap.size()];
35+
int posResource = 0;
36+
for (Map.Entry<Resource, Map<InstrumentationScopeInfo, List<ProfileContainerMarshaler>>> entry :
37+
resourceAndScopeMap.entrySet()) {
38+
InstrumentationScopeProfilesMarshaler[] instrumentationLibrarySpansMarshalers =
39+
new InstrumentationScopeProfilesMarshaler[entry.getValue().size()];
40+
int posInstrumentation = 0;
41+
42+
for (Map.Entry<InstrumentationScopeInfo, List<ProfileContainerMarshaler>> entryIs :
43+
entry.getValue().entrySet()) {
44+
instrumentationLibrarySpansMarshalers[posInstrumentation++] =
45+
new InstrumentationScopeProfilesMarshaler(
46+
InstrumentationScopeMarshaler.create(entryIs.getKey()),
47+
MarshalerUtil.toBytes(entryIs.getKey().getSchemaUrl()),
48+
entryIs.getValue().toArray(new ProfileContainerMarshaler[0]));
49+
}
50+
51+
resourceProfilesMarshalers[posResource++] =
52+
new ResourceProfilesMarshaler(
53+
ResourceMarshaler.create(entry.getKey()),
54+
MarshalerUtil.toBytes(entry.getKey().getSchemaUrl()),
55+
instrumentationLibrarySpansMarshalers);
56+
}
57+
58+
return resourceProfilesMarshalers;
59+
}
60+
61+
private ResourceProfilesMarshaler(
62+
ResourceMarshaler resourceMarshaler,
63+
byte[] schemaUrl,
64+
InstrumentationScopeProfilesMarshaler[] instrumentationScopeProfilesMarshalers) {
65+
super(calculateSize(resourceMarshaler, schemaUrl, instrumentationScopeProfilesMarshalers));
66+
this.resourceMarshaler = resourceMarshaler;
67+
this.schemaUrl = schemaUrl;
68+
this.instrumentationScopeProfilesMarshalers = instrumentationScopeProfilesMarshalers;
69+
}
70+
71+
@Override
72+
protected void writeTo(Serializer output) throws IOException {
73+
output.serializeMessage(ResourceProfiles.RESOURCE, resourceMarshaler);
74+
output.serializeRepeatedMessage(
75+
ResourceProfiles.SCOPE_PROFILES, instrumentationScopeProfilesMarshalers);
76+
output.serializeString(ResourceProfiles.SCHEMA_URL, schemaUrl);
77+
}
78+
79+
private static int calculateSize(
80+
ResourceMarshaler resourceMarshaler,
81+
byte[] schemaUrl,
82+
InstrumentationScopeProfilesMarshaler[] instrumentationScopeProfilesMarshalers) {
83+
int size = 0;
84+
size += MarshalerUtil.sizeMessage(ResourceProfiles.RESOURCE, resourceMarshaler);
85+
size +=
86+
MarshalerUtil.sizeRepeatedMessage(
87+
ResourceProfiles.SCOPE_PROFILES, instrumentationScopeProfilesMarshalers);
88+
size += MarshalerUtil.sizeBytes(ResourceProfiles.SCHEMA_URL, schemaUrl);
89+
return size;
90+
}
91+
92+
private static Map<Resource, Map<InstrumentationScopeInfo, List<ProfileContainerMarshaler>>>
93+
groupByResourceAndScope(Collection<ProfileContainerData> profiles) {
94+
return MarshalerUtil.groupByResourceAndScope(
95+
profiles,
96+
ProfileContainerData::getResource,
97+
ProfileContainerData::getInstrumentationScopeInfo,
98+
ProfileContainerMarshaler::create);
99+
}
100+
}

0 commit comments

Comments
 (0)