Add Marshalers for profiling signal type (#6565)
This commit is contained in:
parent
468b528956
commit
26b3d41d72
|
@ -81,6 +81,11 @@ final class JsonSerializer extends Serializer {
|
|||
generator.writeString(Long.toString(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeUInt64(ProtoFieldInfo field, long value) throws IOException {
|
||||
generator.writeStringField(field.getJsonName(), Long.toString(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeFixed32(ProtoFieldInfo field, int value) throws IOException {
|
||||
generator.writeNumberField(field.getJsonName(), value);
|
||||
|
|
|
@ -129,6 +129,26 @@ public final class MarshalerUtil {
|
|||
return field.getTagSize() + CodedOutputStream.computeUInt32SizeNoTag(payloadSize) + payloadSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of a repeated uint64 field.
|
||||
*
|
||||
* <p>Packed repeated fields contain the tag, an integer representing the incoming payload size,
|
||||
* and an actual payload of repeated varints.
|
||||
*/
|
||||
public static int sizeRepeatedUInt64(ProtoFieldInfo field, List<Long> values) {
|
||||
if (values.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int payloadSize = 0;
|
||||
for (long v : values) {
|
||||
payloadSize += CodedOutputStream.computeUInt64SizeNoTag(v);
|
||||
}
|
||||
|
||||
// tag size + payload indicator size + actual payload size
|
||||
return field.getTagSize() + CodedOutputStream.computeUInt32SizeNoTag(payloadSize) + payloadSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of a repeated uint64 field.
|
||||
*
|
||||
|
@ -154,6 +174,46 @@ public final class MarshalerUtil {
|
|||
return field.getTagSize() + CodedOutputStream.computeUInt32SizeNoTag(payloadSize) + payloadSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of a repeated int64 field.
|
||||
*
|
||||
* <p>Packed repeated fields contain the tag, an integer representing the incoming payload size,
|
||||
* and an actual payload of repeated varints.
|
||||
*/
|
||||
public static int sizeRepeatedInt64(ProtoFieldInfo field, long[] values) {
|
||||
if (values.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int payloadSize = 0;
|
||||
for (long v : values) {
|
||||
payloadSize += CodedOutputStream.computeInt64SizeNoTag(v);
|
||||
}
|
||||
|
||||
// tag size + payload indicator size + actual payload size
|
||||
return field.getTagSize() + CodedOutputStream.computeUInt32SizeNoTag(payloadSize) + payloadSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of a repeated int64 field.
|
||||
*
|
||||
* <p>Packed repeated fields contain the tag, an integer representing the incoming payload size,
|
||||
* and an actual payload of repeated varints.
|
||||
*/
|
||||
public static int sizeRepeatedInt64(ProtoFieldInfo field, List<Long> values) {
|
||||
if (values.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int payloadSize = 0;
|
||||
for (long v : values) {
|
||||
payloadSize += CodedOutputStream.computeInt64SizeNoTag(v);
|
||||
}
|
||||
|
||||
// tag size + payload indicator size + actual payload size
|
||||
return field.getTagSize() + CodedOutputStream.computeUInt32SizeNoTag(payloadSize) + payloadSize;
|
||||
}
|
||||
|
||||
/** Returns the size of a repeated double field. */
|
||||
public static int sizeRepeatedDouble(ProtoFieldInfo field, List<Double> values) {
|
||||
// Same as fixed64.
|
||||
|
@ -207,6 +267,14 @@ public final class MarshalerUtil {
|
|||
return field.getTagSize() + CodedOutputStream.computeInt64SizeNoTag(message);
|
||||
}
|
||||
|
||||
/** Returns the size of a uint64 field. */
|
||||
public static int sizeUInt64(ProtoFieldInfo field, long message) {
|
||||
if (message == 0) {
|
||||
return 0;
|
||||
}
|
||||
return field.getTagSize() + CodedOutputStream.computeUInt64SizeNoTag(message);
|
||||
}
|
||||
|
||||
/** Returns the size of a uint32 field. */
|
||||
public static int sizeUInt32(ProtoFieldInfo field, int message) {
|
||||
if (message == 0) {
|
||||
|
|
|
@ -108,6 +108,12 @@ final class ProtoSerializer extends Serializer implements AutoCloseable {
|
|||
output.writeInt64NoTag(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeUInt64(ProtoFieldInfo field, long value) throws IOException {
|
||||
output.writeUInt32NoTag(field.getTag());
|
||||
output.writeUInt64NoTag(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeFixed64(ProtoFieldInfo field, long value) throws IOException {
|
||||
output.writeUInt32NoTag(field.getTag());
|
||||
|
|
|
@ -139,9 +139,20 @@ public abstract class Serializer implements AutoCloseable {
|
|||
writeInt64(field, value);
|
||||
}
|
||||
|
||||
/** Serializes a protobuf {@code uint64} field. */
|
||||
public void serializeUInt64(ProtoFieldInfo field, long value) throws IOException {
|
||||
if (value == 0) {
|
||||
return;
|
||||
}
|
||||
writeUInt64(field, value);
|
||||
}
|
||||
|
||||
/** Writes a protobuf {@code int64} field, even if it matches the default value. */
|
||||
public abstract void writeInt64(ProtoFieldInfo field, long value) throws IOException;
|
||||
|
||||
/** Writes a protobuf {@code uint64} field, even if it matches the default value. */
|
||||
public abstract void writeUInt64(ProtoFieldInfo field, long value) throws IOException;
|
||||
|
||||
/** Serializes a protobuf {@code fixed64} field. */
|
||||
public void serializeFixed64(ProtoFieldInfo field, long value) throws IOException {
|
||||
if (value == 0) {
|
||||
|
@ -340,6 +351,24 @@ public abstract class Serializer implements AutoCloseable {
|
|||
writeEndRepeatedVarint();
|
||||
}
|
||||
|
||||
/** Serializes a {@code repeated uint64} field. */
|
||||
public void serializeRepeatedUInt64(ProtoFieldInfo field, List<Long> values) throws IOException {
|
||||
if (values.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int payloadSize = 0;
|
||||
for (long v : values) {
|
||||
payloadSize += CodedOutputStream.computeUInt64SizeNoTag(v);
|
||||
}
|
||||
|
||||
writeStartRepeatedVarint(field, payloadSize);
|
||||
for (long value : values) {
|
||||
writeUInt64Value(value);
|
||||
}
|
||||
writeEndRepeatedVarint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes a {@code repeated uint64} field.
|
||||
*
|
||||
|
@ -366,6 +395,24 @@ public abstract class Serializer implements AutoCloseable {
|
|||
writeEndRepeatedVarint();
|
||||
}
|
||||
|
||||
/** Serializes a {@code repeated int64} field. */
|
||||
public void serializeRepeatedInt64(ProtoFieldInfo field, List<Long> values) throws IOException {
|
||||
if (values.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int payloadSize = 0;
|
||||
for (long v : values) {
|
||||
payloadSize += CodedOutputStream.computeInt64SizeNoTag(v);
|
||||
}
|
||||
|
||||
writeStartRepeatedVarint(field, payloadSize);
|
||||
for (long value : values) {
|
||||
writeUInt64Value(value);
|
||||
}
|
||||
writeEndRepeatedVarint();
|
||||
}
|
||||
|
||||
/** Serializes a {@code repeated double} field. */
|
||||
public void serializeRepeatedDouble(ProtoFieldInfo field, List<Double> values)
|
||||
throws IOException {
|
||||
|
|
|
@ -42,6 +42,7 @@ wire {
|
|||
"opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest",
|
||||
"opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest",
|
||||
"opentelemetry.proto.collector.logs.v1.ExportLogsServiceRequest",
|
||||
"opentelemetry.proto.collector.profiles.v1experimental.ExportProfilesServiceRequest"
|
||||
)
|
||||
|
||||
custom {
|
||||
|
|
|
@ -9,8 +9,15 @@ plugins {
|
|||
description = "OpenTelemetry - Profiles Exporter"
|
||||
otelJava.moduleName.set("io.opentelemetry.exporter.otlp.profiles")
|
||||
|
||||
val versions: Map<String, String> by project
|
||||
dependencies {
|
||||
api(project(":sdk:common"))
|
||||
api(project(":exporters:common"))
|
||||
implementation(project(":exporters:otlp:common"))
|
||||
|
||||
annotationProcessor("com.google.auto.value:auto-value")
|
||||
|
||||
testImplementation("com.fasterxml.jackson.core:jackson-databind")
|
||||
testImplementation("com.google.protobuf:protobuf-java-util")
|
||||
testImplementation("io.opentelemetry.proto:opentelemetry-proto")
|
||||
}
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* 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.proto.profiles.v1experimental.internal.AttributeUnit;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
final class AttributeUnitMarshaler extends MarshalerWithSize {
|
||||
|
||||
private static final AttributeUnitMarshaler[] EMPTY_REPEATED = new AttributeUnitMarshaler[0];
|
||||
|
||||
private final long attributeKey;
|
||||
private final long unitIndex;
|
||||
|
||||
static AttributeUnitMarshaler create(AttributeUnitData attributeUnitData) {
|
||||
return new AttributeUnitMarshaler(
|
||||
attributeUnitData.getAttributeKey(), attributeUnitData.getUnitIndex());
|
||||
}
|
||||
|
||||
static AttributeUnitMarshaler[] createRepeated(List<AttributeUnitData> items) {
|
||||
if (items.isEmpty()) {
|
||||
return EMPTY_REPEATED;
|
||||
}
|
||||
|
||||
AttributeUnitMarshaler[] attributeUnitMarshalers = new AttributeUnitMarshaler[items.size()];
|
||||
items.forEach(
|
||||
item ->
|
||||
new Consumer<AttributeUnitData>() {
|
||||
int index = 0;
|
||||
|
||||
@Override
|
||||
public void accept(AttributeUnitData attributeUnitData) {
|
||||
attributeUnitMarshalers[index++] = AttributeUnitMarshaler.create(attributeUnitData);
|
||||
}
|
||||
});
|
||||
return attributeUnitMarshalers;
|
||||
}
|
||||
|
||||
private AttributeUnitMarshaler(long attributeKey, long unitIndex) {
|
||||
super(calculateSize(attributeKey, unitIndex));
|
||||
this.attributeKey = attributeKey;
|
||||
this.unitIndex = unitIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeTo(Serializer output) throws IOException {
|
||||
output.serializeInt64(AttributeUnit.ATTRIBUTE_KEY, attributeKey);
|
||||
output.serializeInt64(AttributeUnit.UNIT, unitIndex);
|
||||
}
|
||||
|
||||
private static int calculateSize(long attributeKey, long unitIndex) {
|
||||
int size;
|
||||
size = 0;
|
||||
size += MarshalerUtil.sizeInt64(AttributeUnit.ATTRIBUTE_KEY, attributeKey);
|
||||
size += MarshalerUtil.sizeInt64(AttributeUnit.UNIT, unitIndex);
|
||||
return size;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* 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.proto.profiles.v1experimental.internal.Function;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
final class FunctionMarshaler extends MarshalerWithSize {
|
||||
|
||||
private static final FunctionMarshaler[] EMPTY_REPEATED = new FunctionMarshaler[0];
|
||||
|
||||
private final long nameIndex;
|
||||
private final long systemNameIndex;
|
||||
private final long filenameIndex;
|
||||
private final long startLine;
|
||||
|
||||
static FunctionMarshaler create(FunctionData functionData) {
|
||||
return new FunctionMarshaler(
|
||||
functionData.getNameIndex(),
|
||||
functionData.getSystemNameIndex(),
|
||||
functionData.getFilenameIndex(),
|
||||
functionData.getStartLine());
|
||||
}
|
||||
|
||||
static FunctionMarshaler[] createRepeated(List<FunctionData> items) {
|
||||
if (items.isEmpty()) {
|
||||
return EMPTY_REPEATED;
|
||||
}
|
||||
|
||||
FunctionMarshaler[] functionMarshalers = new FunctionMarshaler[items.size()];
|
||||
items.forEach(
|
||||
item ->
|
||||
new Consumer<FunctionData>() {
|
||||
int index = 0;
|
||||
|
||||
@Override
|
||||
public void accept(FunctionData functionData) {
|
||||
functionMarshalers[index++] = FunctionMarshaler.create(functionData);
|
||||
}
|
||||
});
|
||||
return functionMarshalers;
|
||||
}
|
||||
|
||||
private FunctionMarshaler(
|
||||
long nameIndex, long systemNameIndex, long filenameIndex, long startLine) {
|
||||
super(calculateSize(nameIndex, systemNameIndex, filenameIndex, startLine));
|
||||
this.nameIndex = nameIndex;
|
||||
this.systemNameIndex = systemNameIndex;
|
||||
this.filenameIndex = filenameIndex;
|
||||
this.startLine = startLine;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeTo(Serializer output) throws IOException {
|
||||
output.serializeInt64(Function.NAME, nameIndex);
|
||||
output.serializeInt64(Function.SYSTEM_NAME, systemNameIndex);
|
||||
output.serializeInt64(Function.FILENAME, filenameIndex);
|
||||
output.serializeInt64(Function.START_LINE, startLine);
|
||||
}
|
||||
|
||||
private static int calculateSize(
|
||||
long nameIndex, long systemNameIndex, long filenameIndex, long startLine) {
|
||||
int size = 0;
|
||||
size += MarshalerUtil.sizeInt64(Function.NAME, nameIndex);
|
||||
size += MarshalerUtil.sizeInt64(Function.SYSTEM_NAME, systemNameIndex);
|
||||
size += MarshalerUtil.sizeInt64(Function.FILENAME, filenameIndex);
|
||||
size += MarshalerUtil.sizeInt64(Function.START_LINE, startLine);
|
||||
return size;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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.proto.profiles.v1experimental.internal.Line;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
final class LineMarshaler extends MarshalerWithSize {
|
||||
|
||||
private static final LineMarshaler[] EMPTY_REPEATED = new LineMarshaler[0];
|
||||
|
||||
private final long functionIndex;
|
||||
private final long line;
|
||||
private final long column;
|
||||
|
||||
static LineMarshaler create(LineData lineData) {
|
||||
return new LineMarshaler(lineData.getFunctionIndex(), lineData.getLine(), lineData.getColumn());
|
||||
}
|
||||
|
||||
static LineMarshaler[] createRepeated(List<LineData> items) {
|
||||
if (items.isEmpty()) {
|
||||
return EMPTY_REPEATED;
|
||||
}
|
||||
|
||||
LineMarshaler[] lineMarshalers = new LineMarshaler[items.size()];
|
||||
items.forEach(
|
||||
item ->
|
||||
new Consumer<LineData>() {
|
||||
int index = 0;
|
||||
|
||||
@Override
|
||||
public void accept(LineData lineData) {
|
||||
lineMarshalers[index++] = LineMarshaler.create(lineData);
|
||||
}
|
||||
});
|
||||
return lineMarshalers;
|
||||
}
|
||||
|
||||
private LineMarshaler(long functionIndex, long line, long column) {
|
||||
super(calculateSize(functionIndex, line, column));
|
||||
this.functionIndex = functionIndex;
|
||||
this.line = line;
|
||||
this.column = column;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeTo(Serializer output) throws IOException {
|
||||
output.serializeUInt64(Line.FUNCTION_INDEX, functionIndex);
|
||||
output.serializeInt64(Line.LINE, line);
|
||||
output.serializeInt64(Line.COLUMN, column);
|
||||
}
|
||||
|
||||
private static int calculateSize(long functionIndex, long line, long column) {
|
||||
int size = 0;
|
||||
size += MarshalerUtil.sizeUInt64(Line.FUNCTION_INDEX, functionIndex);
|
||||
size += MarshalerUtil.sizeInt64(Line.LINE, line);
|
||||
size += MarshalerUtil.sizeInt64(Line.COLUMN, column);
|
||||
return size;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.exporter.otlp.profiles;
|
||||
|
||||
import io.opentelemetry.api.internal.OtelEncodingUtils;
|
||||
import io.opentelemetry.api.trace.SpanId;
|
||||
import io.opentelemetry.api.trace.TraceId;
|
||||
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.profiles.v1experimental.internal.Link;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
final class LinkMarshaler extends MarshalerWithSize {
|
||||
|
||||
private static final LinkMarshaler[] EMPTY_REPEATED = new LinkMarshaler[0];
|
||||
|
||||
private final byte[] traceId;
|
||||
private final byte[] spanId;
|
||||
|
||||
static LinkMarshaler create(LinkData linkData) {
|
||||
// in tracing this conversion is handled by utility methods on SpanContext,
|
||||
// but we don't have a SpanContext here...
|
||||
byte[] traceId = OtelEncodingUtils.bytesFromBase16(linkData.getTraceId(), TraceId.getLength());
|
||||
byte[] spanId = OtelEncodingUtils.bytesFromBase16(linkData.getSpanId(), SpanId.getLength());
|
||||
|
||||
return new LinkMarshaler(traceId, spanId);
|
||||
}
|
||||
|
||||
static LinkMarshaler[] createRepeated(List<LinkData> items) {
|
||||
if (items.isEmpty()) {
|
||||
return EMPTY_REPEATED;
|
||||
}
|
||||
|
||||
LinkMarshaler[] linkMarshalers = new LinkMarshaler[items.size()];
|
||||
items.forEach(
|
||||
item ->
|
||||
new Consumer<LinkData>() {
|
||||
int index = 0;
|
||||
|
||||
@Override
|
||||
public void accept(LinkData linkData) {
|
||||
linkMarshalers[index++] = LinkMarshaler.create(linkData);
|
||||
}
|
||||
});
|
||||
return linkMarshalers;
|
||||
}
|
||||
|
||||
private LinkMarshaler(byte[] traceId, byte[] spanId) {
|
||||
super(calculateSize(traceId, spanId));
|
||||
this.traceId = traceId;
|
||||
this.spanId = spanId;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeTo(Serializer output) throws IOException {
|
||||
output.serializeBytes(Link.TRACE_ID, traceId);
|
||||
output.serializeBytes(Link.SPAN_ID, spanId);
|
||||
}
|
||||
|
||||
private static int calculateSize(byte[] traceId, byte[] spanId) {
|
||||
int size = 0;
|
||||
size += MarshalerUtil.sizeBytes(Link.TRACE_ID, traceId);
|
||||
size += MarshalerUtil.sizeBytes(Link.SPAN_ID, spanId);
|
||||
return size;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* 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.proto.profiles.v1experimental.internal.Location;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
final class LocationMarshaler extends MarshalerWithSize {
|
||||
|
||||
private static final LocationMarshaler[] EMPTY_REPEATED = new LocationMarshaler[0];
|
||||
|
||||
private final long mappingIndex;
|
||||
private final long address;
|
||||
private final LineMarshaler[] lineMarshalers;
|
||||
private final boolean isFolded;
|
||||
private final int typeIndex;
|
||||
private final List<Long> attributes;
|
||||
|
||||
static LocationMarshaler create(LocationData locationData) {
|
||||
return new LocationMarshaler(
|
||||
locationData.getMappingIndex(),
|
||||
locationData.getAddress(),
|
||||
LineMarshaler.createRepeated(locationData.getLines()),
|
||||
locationData.isFolded(),
|
||||
locationData.getTypeIndex(),
|
||||
locationData.getAttributes());
|
||||
}
|
||||
|
||||
static LocationMarshaler[] createRepeated(List<LocationData> items) {
|
||||
if (items.isEmpty()) {
|
||||
return EMPTY_REPEATED;
|
||||
}
|
||||
|
||||
LocationMarshaler[] locationMarshalers = new LocationMarshaler[items.size()];
|
||||
items.forEach(
|
||||
item ->
|
||||
new Consumer<LocationData>() {
|
||||
int index = 0;
|
||||
|
||||
@Override
|
||||
public void accept(LocationData locationData) {
|
||||
locationMarshalers[index++] = LocationMarshaler.create(locationData);
|
||||
}
|
||||
});
|
||||
return locationMarshalers;
|
||||
}
|
||||
|
||||
private LocationMarshaler(
|
||||
long mappingIndex,
|
||||
long address,
|
||||
LineMarshaler[] lineMarshalers,
|
||||
boolean isFolded,
|
||||
int typeIndex,
|
||||
List<Long> attributes) {
|
||||
super(calculateSize(mappingIndex, address, lineMarshalers, isFolded, typeIndex, attributes));
|
||||
this.mappingIndex = mappingIndex;
|
||||
this.address = address;
|
||||
this.lineMarshalers = lineMarshalers;
|
||||
this.isFolded = isFolded;
|
||||
this.typeIndex = typeIndex;
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeTo(Serializer output) throws IOException {
|
||||
output.serializeUInt64(Location.MAPPING_INDEX, mappingIndex);
|
||||
output.serializeUInt64(Location.ADDRESS, address);
|
||||
output.serializeRepeatedMessage(Location.LINE, lineMarshalers);
|
||||
output.serializeBool(Location.IS_FOLDED, isFolded);
|
||||
output.serializeUInt32(Location.TYPE_INDEX, typeIndex);
|
||||
output.serializeRepeatedUInt64(Location.ATTRIBUTES, attributes);
|
||||
}
|
||||
|
||||
private static int calculateSize(
|
||||
long mappingIndex,
|
||||
long address,
|
||||
LineMarshaler[] lineMarshalers,
|
||||
boolean isFolded,
|
||||
int typeIndex,
|
||||
List<Long> attributes) {
|
||||
int size = 0;
|
||||
size += MarshalerUtil.sizeUInt64(Location.MAPPING_INDEX, mappingIndex);
|
||||
size += MarshalerUtil.sizeUInt64(Location.ADDRESS, address);
|
||||
size += MarshalerUtil.sizeRepeatedMessage(Location.LINE, lineMarshalers);
|
||||
size += MarshalerUtil.sizeBool(Location.IS_FOLDED, isFolded);
|
||||
size += MarshalerUtil.sizeUInt32(Location.TYPE_INDEX, typeIndex);
|
||||
size += MarshalerUtil.sizeRepeatedUInt64(Location.ATTRIBUTES, attributes);
|
||||
return size;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* 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.ProtoEnumInfo;
|
||||
import io.opentelemetry.exporter.internal.marshal.Serializer;
|
||||
import io.opentelemetry.proto.profiles.v1experimental.internal.BuildIdKind;
|
||||
import io.opentelemetry.proto.profiles.v1experimental.internal.Mapping;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
final class MappingMarshaler extends MarshalerWithSize {
|
||||
|
||||
private static final MappingMarshaler[] EMPTY_REPEATED = new MappingMarshaler[0];
|
||||
|
||||
private final long memoryStart;
|
||||
private final long memoryLimit;
|
||||
private final long fileOffset;
|
||||
private final long filenameIndex;
|
||||
private final long buildIdIndex;
|
||||
private final ProtoEnumInfo buildIdKind;
|
||||
private final List<Long> attributeIndices;
|
||||
private final boolean hasFunctions;
|
||||
private final boolean hasFilenames;
|
||||
private final boolean hasLineNumbers;
|
||||
private final boolean hasInlineFrames;
|
||||
|
||||
static MappingMarshaler create(MappingData mappingData) {
|
||||
ProtoEnumInfo buildKind = BuildIdKind.BUILD_ID_LINKER;
|
||||
switch (mappingData.getBuildIdKind()) {
|
||||
case LINKER:
|
||||
buildKind = BuildIdKind.BUILD_ID_LINKER;
|
||||
break;
|
||||
case BINARY_HASH:
|
||||
buildKind = BuildIdKind.BUILD_ID_BINARY_HASH;
|
||||
break;
|
||||
}
|
||||
return new MappingMarshaler(
|
||||
mappingData.getMemoryStart(),
|
||||
mappingData.getMemoryLimit(),
|
||||
mappingData.getFileOffset(),
|
||||
mappingData.getFilenameIndex(),
|
||||
mappingData.getBuildIdIndex(),
|
||||
buildKind,
|
||||
mappingData.getAttributeIndices(),
|
||||
mappingData.hasFunctions(),
|
||||
mappingData.hasFilenames(),
|
||||
mappingData.hasLineNumbers(),
|
||||
mappingData.hasInlineFrames());
|
||||
}
|
||||
|
||||
static MappingMarshaler[] createRepeated(List<MappingData> items) {
|
||||
if (items.isEmpty()) {
|
||||
return EMPTY_REPEATED;
|
||||
}
|
||||
|
||||
MappingMarshaler[] mappingMarshalers = new MappingMarshaler[items.size()];
|
||||
items.forEach(
|
||||
item ->
|
||||
new Consumer<MappingData>() {
|
||||
int index = 0;
|
||||
|
||||
@Override
|
||||
public void accept(MappingData mappingData) {
|
||||
mappingMarshalers[index++] = MappingMarshaler.create(mappingData);
|
||||
}
|
||||
});
|
||||
return mappingMarshalers;
|
||||
}
|
||||
|
||||
private MappingMarshaler(
|
||||
long memoryStart,
|
||||
long memoryLimit,
|
||||
long fileOffset,
|
||||
long filenameIndex,
|
||||
long buildIdIndex,
|
||||
ProtoEnumInfo buildIdKind,
|
||||
List<Long> attributeIndices,
|
||||
boolean hasFunctions,
|
||||
boolean hasFilenames,
|
||||
boolean hasLineNumbers,
|
||||
boolean hasInlineFrames) {
|
||||
super(
|
||||
calculateSize(
|
||||
memoryStart,
|
||||
memoryLimit,
|
||||
fileOffset,
|
||||
filenameIndex,
|
||||
buildIdIndex,
|
||||
buildIdKind,
|
||||
attributeIndices,
|
||||
hasFunctions,
|
||||
hasFilenames,
|
||||
hasLineNumbers,
|
||||
hasInlineFrames));
|
||||
this.memoryStart = memoryStart;
|
||||
this.memoryLimit = memoryLimit;
|
||||
this.fileOffset = fileOffset;
|
||||
this.filenameIndex = filenameIndex;
|
||||
this.buildIdIndex = buildIdIndex;
|
||||
this.buildIdKind = buildIdKind;
|
||||
this.attributeIndices = attributeIndices;
|
||||
this.hasFunctions = hasFunctions;
|
||||
this.hasFilenames = hasFilenames;
|
||||
this.hasLineNumbers = hasLineNumbers;
|
||||
this.hasInlineFrames = hasInlineFrames;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeTo(Serializer output) throws IOException {
|
||||
output.serializeUInt64(Mapping.MEMORY_START, memoryStart);
|
||||
output.serializeUInt64(Mapping.MEMORY_LIMIT, memoryLimit);
|
||||
output.serializeUInt64(Mapping.FILE_OFFSET, fileOffset);
|
||||
output.serializeInt64(Mapping.FILENAME, filenameIndex);
|
||||
output.serializeInt64(Mapping.BUILD_ID, buildIdIndex);
|
||||
output.serializeEnum(Mapping.BUILD_ID_KIND, buildIdKind);
|
||||
output.serializeRepeatedUInt64(Mapping.ATTRIBUTES, attributeIndices);
|
||||
output.serializeBool(Mapping.HAS_FUNCTIONS, hasFunctions);
|
||||
output.serializeBool(Mapping.HAS_FILENAMES, hasFilenames);
|
||||
output.serializeBool(Mapping.HAS_LINE_NUMBERS, hasLineNumbers);
|
||||
output.serializeBool(Mapping.HAS_INLINE_FRAMES, hasInlineFrames);
|
||||
}
|
||||
|
||||
private static int calculateSize(
|
||||
long memoryStart,
|
||||
long memoryLimit,
|
||||
long fileOffset,
|
||||
long filenameIndex,
|
||||
long buildIdIndex,
|
||||
ProtoEnumInfo buildIdKind,
|
||||
List<Long> attributeIndices,
|
||||
boolean hasFunctions,
|
||||
boolean hasFilenames,
|
||||
boolean hasLineNumbers,
|
||||
boolean hasInlineFrames) {
|
||||
int size = 0;
|
||||
size += MarshalerUtil.sizeUInt64(Mapping.MEMORY_START, memoryStart);
|
||||
size += MarshalerUtil.sizeUInt64(Mapping.MEMORY_LIMIT, memoryLimit);
|
||||
size += MarshalerUtil.sizeUInt64(Mapping.FILE_OFFSET, fileOffset);
|
||||
size += MarshalerUtil.sizeInt64(Mapping.FILENAME, filenameIndex);
|
||||
size += MarshalerUtil.sizeInt64(Mapping.BUILD_ID, buildIdIndex);
|
||||
size += MarshalerUtil.sizeEnum(Mapping.BUILD_ID_KIND, buildIdKind);
|
||||
size += MarshalerUtil.sizeRepeatedUInt64(Mapping.ATTRIBUTES, attributeIndices);
|
||||
size += MarshalerUtil.sizeBool(Mapping.HAS_FUNCTIONS, hasFunctions);
|
||||
size += MarshalerUtil.sizeBool(Mapping.HAS_FILENAMES, hasFilenames);
|
||||
size += MarshalerUtil.sizeBool(Mapping.HAS_LINE_NUMBERS, hasLineNumbers);
|
||||
size += MarshalerUtil.sizeBool(Mapping.HAS_INLINE_FRAMES, hasInlineFrames);
|
||||
return size;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
* 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.v1experimental.internal.Profile;
|
||||
import java.io.IOException;
|
||||
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[] mappingMarshalers;
|
||||
private final LocationMarshaler[] locationMarshalers;
|
||||
private final List<Long> locationIndices;
|
||||
private final FunctionMarshaler[] functionMarshalers;
|
||||
private final KeyValueMarshaler[] attributeMarshalers;
|
||||
private final AttributeUnitMarshaler[] attributeUnitMarshalers;
|
||||
private final LinkMarshaler[] linkMarshalers;
|
||||
private final byte[][] stringTable;
|
||||
private final long dropFrames;
|
||||
private final long keepFrames;
|
||||
private final long timeNanos;
|
||||
private final long durationNanos;
|
||||
private final ValueTypeMarshaler periodTypeMarshaler;
|
||||
private final long period;
|
||||
private final List<Long> comment;
|
||||
private final long defaultSampleType;
|
||||
|
||||
static ProfileMarshaler create(ProfileData profileData) {
|
||||
|
||||
ValueTypeMarshaler[] sampleTypeMarshalers =
|
||||
ValueTypeMarshaler.createRepeated(profileData.getSampleTypes());
|
||||
SampleMarshaler[] sampleMarshalers = SampleMarshaler.createRepeated(profileData.getSamples());
|
||||
MappingMarshaler[] mappingMarshalers =
|
||||
MappingMarshaler.createRepeated(profileData.getMappings());
|
||||
LocationMarshaler[] locationMarshalers =
|
||||
LocationMarshaler.createRepeated(profileData.getLocations());
|
||||
FunctionMarshaler[] functionMarshalers =
|
||||
FunctionMarshaler.createRepeated(profileData.getFunctions());
|
||||
KeyValueMarshaler[] attributeMarshalers =
|
||||
KeyValueMarshaler.createForAttributes(profileData.getAttributes());
|
||||
AttributeUnitMarshaler[] attributeUnitsMarshalers =
|
||||
AttributeUnitMarshaler.createRepeated(profileData.getAttributeUnits());
|
||||
LinkMarshaler[] linkMarshalers = LinkMarshaler.createRepeated(profileData.getLinks());
|
||||
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);
|
||||
}
|
||||
|
||||
return new ProfileMarshaler(
|
||||
sampleTypeMarshalers,
|
||||
sampleMarshalers,
|
||||
mappingMarshalers,
|
||||
locationMarshalers,
|
||||
profileData.getLocationIndices(),
|
||||
functionMarshalers,
|
||||
attributeMarshalers,
|
||||
attributeUnitsMarshalers,
|
||||
linkMarshalers,
|
||||
convertedStrings,
|
||||
profileData.getDropFrames(),
|
||||
profileData.getKeepFrames(),
|
||||
profileData.getTimeNanos(),
|
||||
profileData.getDurationNanos(),
|
||||
periodTypeMarshaler,
|
||||
profileData.getPeriod(),
|
||||
profileData.getComment(),
|
||||
profileData.getDefaultSampleType());
|
||||
}
|
||||
|
||||
private ProfileMarshaler(
|
||||
ValueTypeMarshaler[] sampleTypeMarshalers,
|
||||
SampleMarshaler[] sampleMarshalers,
|
||||
MappingMarshaler[] mappingMarshalers,
|
||||
LocationMarshaler[] locationMarshalers,
|
||||
List<Long> locationIndices,
|
||||
FunctionMarshaler[] functionMarshalers,
|
||||
KeyValueMarshaler[] attributeMarshalers,
|
||||
AttributeUnitMarshaler[] attributeUnitMarshalers,
|
||||
LinkMarshaler[] linkMarshalers,
|
||||
byte[][] stringTableUtf8,
|
||||
long dropFrames,
|
||||
long keepFrames,
|
||||
long timeNanos,
|
||||
long durationNanos,
|
||||
ValueTypeMarshaler periodTypeMarshaler,
|
||||
long period,
|
||||
List<Long> comment,
|
||||
long defaultSampleType) {
|
||||
super(
|
||||
calculateSize(
|
||||
sampleTypeMarshalers,
|
||||
sampleMarshalers,
|
||||
mappingMarshalers,
|
||||
locationMarshalers,
|
||||
locationIndices,
|
||||
functionMarshalers,
|
||||
attributeMarshalers,
|
||||
attributeUnitMarshalers,
|
||||
linkMarshalers,
|
||||
stringTableUtf8,
|
||||
dropFrames,
|
||||
keepFrames,
|
||||
timeNanos,
|
||||
durationNanos,
|
||||
periodTypeMarshaler,
|
||||
period,
|
||||
comment,
|
||||
defaultSampleType));
|
||||
this.sampleTypeMarshalers = sampleTypeMarshalers;
|
||||
this.sampleMarshalers = sampleMarshalers;
|
||||
this.mappingMarshalers = mappingMarshalers;
|
||||
this.locationMarshalers = locationMarshalers;
|
||||
this.locationIndices = locationIndices;
|
||||
this.functionMarshalers = functionMarshalers;
|
||||
this.attributeMarshalers = attributeMarshalers;
|
||||
this.attributeUnitMarshalers = attributeUnitMarshalers;
|
||||
this.linkMarshalers = linkMarshalers;
|
||||
this.stringTable = stringTableUtf8;
|
||||
this.dropFrames = dropFrames;
|
||||
this.keepFrames = keepFrames;
|
||||
this.timeNanos = timeNanos;
|
||||
this.durationNanos = durationNanos;
|
||||
this.periodTypeMarshaler = periodTypeMarshaler;
|
||||
this.period = period;
|
||||
this.comment = comment;
|
||||
this.defaultSampleType = defaultSampleType;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeTo(Serializer output) throws IOException {
|
||||
output.serializeRepeatedMessage(Profile.SAMPLE_TYPE, sampleTypeMarshalers);
|
||||
output.serializeRepeatedMessage(Profile.SAMPLE, sampleMarshalers);
|
||||
output.serializeRepeatedMessage(Profile.MAPPING, mappingMarshalers);
|
||||
output.serializeRepeatedMessage(Profile.LOCATION, locationMarshalers);
|
||||
output.serializeRepeatedInt64(Profile.LOCATION_INDICES, locationIndices);
|
||||
output.serializeRepeatedMessage(Profile.FUNCTION, functionMarshalers);
|
||||
output.serializeRepeatedMessage(Profile.ATTRIBUTE_TABLE, attributeMarshalers);
|
||||
output.serializeRepeatedMessage(Profile.ATTRIBUTE_UNITS, attributeUnitMarshalers);
|
||||
output.serializeRepeatedMessage(Profile.LINK_TABLE, linkMarshalers);
|
||||
for (byte[] i : stringTable) {
|
||||
output.serializeString(Profile.STRING_TABLE, i);
|
||||
}
|
||||
output.serializeInt64(Profile.DROP_FRAMES, dropFrames);
|
||||
output.serializeInt64(Profile.KEEP_FRAMES, keepFrames);
|
||||
output.serializeInt64(Profile.TIME_NANOS, timeNanos);
|
||||
output.serializeInt64(Profile.DURATION_NANOS, durationNanos);
|
||||
output.serializeMessage(Profile.PERIOD_TYPE, periodTypeMarshaler);
|
||||
output.serializeInt64(Profile.PERIOD, period);
|
||||
output.serializeRepeatedInt64(Profile.COMMENT, comment);
|
||||
output.serializeInt64(Profile.DEFAULT_SAMPLE_TYPE, defaultSampleType);
|
||||
}
|
||||
|
||||
private static int calculateSize(
|
||||
ValueTypeMarshaler[] sampleTypeMarshalers,
|
||||
SampleMarshaler[] sampleMarshalers,
|
||||
MappingMarshaler[] mappingMarshalers,
|
||||
LocationMarshaler[] locationMarshalers,
|
||||
List<Long> locationIndices,
|
||||
FunctionMarshaler[] functionMarshalers,
|
||||
KeyValueMarshaler[] attributeMarshalers,
|
||||
AttributeUnitMarshaler[] attributeUnitMarshalers,
|
||||
LinkMarshaler[] linkMarshalers,
|
||||
byte[][] stringTable,
|
||||
long dropFrames,
|
||||
long keepFrames,
|
||||
long timeNanos,
|
||||
long durationNanos,
|
||||
ValueTypeMarshaler periodTypeMarshaler,
|
||||
long period,
|
||||
List<Long> comment,
|
||||
long defaultSampleType) {
|
||||
int size;
|
||||
size = 0;
|
||||
size += MarshalerUtil.sizeRepeatedMessage(Profile.SAMPLE_TYPE, sampleTypeMarshalers);
|
||||
size += MarshalerUtil.sizeRepeatedMessage(Profile.SAMPLE, sampleMarshalers);
|
||||
size += MarshalerUtil.sizeRepeatedMessage(Profile.MAPPING, mappingMarshalers);
|
||||
size += MarshalerUtil.sizeRepeatedMessage(Profile.LOCATION, locationMarshalers);
|
||||
size += MarshalerUtil.sizeRepeatedInt64(Profile.LOCATION_INDICES, locationIndices);
|
||||
size += MarshalerUtil.sizeRepeatedMessage(Profile.FUNCTION, functionMarshalers);
|
||||
size += MarshalerUtil.sizeRepeatedMessage(Profile.ATTRIBUTE_TABLE, attributeMarshalers);
|
||||
size += MarshalerUtil.sizeRepeatedMessage(Profile.ATTRIBUTE_UNITS, attributeUnitMarshalers);
|
||||
size += MarshalerUtil.sizeRepeatedMessage(Profile.LINK_TABLE, linkMarshalers);
|
||||
for (byte[] i : stringTable) {
|
||||
size += MarshalerUtil.sizeBytes(Profile.STRING_TABLE, i);
|
||||
}
|
||||
size += MarshalerUtil.sizeInt64(Profile.DROP_FRAMES, dropFrames);
|
||||
size += MarshalerUtil.sizeInt64(Profile.KEEP_FRAMES, keepFrames);
|
||||
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.sizeRepeatedInt64(Profile.COMMENT, comment);
|
||||
size += MarshalerUtil.sizeInt64(Profile.DEFAULT_SAMPLE_TYPE, defaultSampleType);
|
||||
return size;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* 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.proto.profiles.v1experimental.internal.Sample;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
final class SampleMarshaler extends MarshalerWithSize {
|
||||
|
||||
private static final SampleMarshaler[] EMPTY_REPEATED = new SampleMarshaler[0];
|
||||
|
||||
private final long locationsStartIndex;
|
||||
private final long locationsLength;
|
||||
private final int stacktraceIdIndex;
|
||||
private final List<Long> values;
|
||||
private final List<Long> attributes;
|
||||
private final long link;
|
||||
private final List<Long> timestamps;
|
||||
|
||||
static SampleMarshaler create(SampleData sampleData) {
|
||||
|
||||
return new SampleMarshaler(
|
||||
sampleData.getLocationsStartIndex(),
|
||||
sampleData.getLocationsLength(),
|
||||
sampleData.getStacktraceIdIndex(),
|
||||
sampleData.getValues(),
|
||||
sampleData.getAttributes(),
|
||||
sampleData.getLink(),
|
||||
sampleData.getTimestamps());
|
||||
}
|
||||
|
||||
static SampleMarshaler[] createRepeated(List<SampleData> items) {
|
||||
if (items.isEmpty()) {
|
||||
return EMPTY_REPEATED;
|
||||
}
|
||||
|
||||
SampleMarshaler[] sampleMarshalers = new SampleMarshaler[items.size()];
|
||||
items.forEach(
|
||||
item ->
|
||||
new Consumer<SampleData>() {
|
||||
int index = 0;
|
||||
|
||||
@Override
|
||||
public void accept(SampleData sampleData) {
|
||||
sampleMarshalers[index++] = SampleMarshaler.create(sampleData);
|
||||
}
|
||||
});
|
||||
return sampleMarshalers;
|
||||
}
|
||||
|
||||
private SampleMarshaler(
|
||||
long locationsStartIndex,
|
||||
long locationsLength,
|
||||
int stacktraceIdIndex,
|
||||
List<Long> values,
|
||||
List<Long> attributes,
|
||||
long link,
|
||||
List<Long> timestamps) {
|
||||
super(
|
||||
calculateSize(
|
||||
locationsStartIndex,
|
||||
locationsLength,
|
||||
stacktraceIdIndex,
|
||||
values,
|
||||
attributes,
|
||||
link,
|
||||
timestamps));
|
||||
this.locationsStartIndex = locationsStartIndex;
|
||||
this.locationsLength = locationsLength;
|
||||
this.stacktraceIdIndex = stacktraceIdIndex;
|
||||
this.values = values;
|
||||
this.attributes = attributes;
|
||||
this.link = link;
|
||||
this.timestamps = timestamps;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeTo(Serializer output) throws IOException {
|
||||
output.serializeUInt64(Sample.LOCATIONS_START_INDEX, locationsStartIndex);
|
||||
output.serializeUInt64(Sample.LOCATIONS_LENGTH, locationsLength);
|
||||
output.serializeUInt32(Sample.STACKTRACE_ID_INDEX, stacktraceIdIndex);
|
||||
output.serializeRepeatedInt64(Sample.VALUE, values);
|
||||
output.serializeRepeatedUInt64(Sample.ATTRIBUTES, attributes);
|
||||
output.serializeUInt64(Sample.LINK, link);
|
||||
output.serializeRepeatedUInt64(Sample.TIMESTAMPS_UNIX_NANO, timestamps);
|
||||
}
|
||||
|
||||
private static int calculateSize(
|
||||
long locationsStartIndex,
|
||||
long locationsLength,
|
||||
int stacktraceIdIndex,
|
||||
List<Long> values,
|
||||
List<Long> attributes,
|
||||
long link,
|
||||
List<Long> timestamps) {
|
||||
int size;
|
||||
size = 0;
|
||||
size += MarshalerUtil.sizeUInt64(Sample.LOCATIONS_START_INDEX, locationsStartIndex);
|
||||
size += MarshalerUtil.sizeUInt64(Sample.LOCATIONS_LENGTH, locationsLength);
|
||||
size += MarshalerUtil.sizeUInt32(Sample.STACKTRACE_ID_INDEX, stacktraceIdIndex);
|
||||
size += MarshalerUtil.sizeRepeatedInt64(Sample.VALUE, values);
|
||||
size += MarshalerUtil.sizeRepeatedUInt64(Sample.ATTRIBUTES, attributes);
|
||||
size += MarshalerUtil.sizeUInt64(Sample.LINK, link);
|
||||
size += MarshalerUtil.sizeRepeatedUInt64(Sample.TIMESTAMPS_UNIX_NANO, timestamps);
|
||||
return size;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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.ProtoEnumInfo;
|
||||
import io.opentelemetry.exporter.internal.marshal.Serializer;
|
||||
import io.opentelemetry.proto.profiles.v1experimental.internal.AggregationTemporality;
|
||||
import io.opentelemetry.proto.profiles.v1experimental.internal.ValueType;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
final class ValueTypeMarshaler extends MarshalerWithSize {
|
||||
|
||||
private static final ValueTypeMarshaler[] EMPTY_REPEATED = new ValueTypeMarshaler[0];
|
||||
|
||||
private final long type;
|
||||
private final long unit;
|
||||
private final ProtoEnumInfo aggregationTemporality;
|
||||
|
||||
static ValueTypeMarshaler create(ValueTypeData valueTypeData) {
|
||||
ProtoEnumInfo aggregationTemporality =
|
||||
AggregationTemporality.AGGREGATION_TEMPORALITY_UNSPECIFIED;
|
||||
if (valueTypeData.aggregationTemporality() != null) {
|
||||
switch (valueTypeData.aggregationTemporality()) {
|
||||
case DELTA:
|
||||
aggregationTemporality = AggregationTemporality.AGGREGATION_TEMPORALITY_DELTA;
|
||||
break;
|
||||
case CUMULATIVE:
|
||||
aggregationTemporality = AggregationTemporality.AGGREGATION_TEMPORALITY_CUMULATIVE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new ValueTypeMarshaler(
|
||||
valueTypeData.type(), valueTypeData.unit(), aggregationTemporality);
|
||||
}
|
||||
|
||||
static ValueTypeMarshaler[] createRepeated(List<ValueTypeData> items) {
|
||||
if (items.isEmpty()) {
|
||||
return EMPTY_REPEATED;
|
||||
}
|
||||
|
||||
ValueTypeMarshaler[] valueTypeMarshalers = new ValueTypeMarshaler[items.size()];
|
||||
items.forEach(
|
||||
item ->
|
||||
new Consumer<ValueTypeData>() {
|
||||
int index = 0;
|
||||
|
||||
@Override
|
||||
public void accept(ValueTypeData valueTypeData) {
|
||||
valueTypeMarshalers[index++] = ValueTypeMarshaler.create(valueTypeData);
|
||||
}
|
||||
});
|
||||
return valueTypeMarshalers;
|
||||
}
|
||||
|
||||
private ValueTypeMarshaler(long type, long unit, ProtoEnumInfo aggregationTemporality) {
|
||||
super(calculateSize(type, unit, aggregationTemporality));
|
||||
this.type = type;
|
||||
this.unit = unit;
|
||||
this.aggregationTemporality = aggregationTemporality;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeTo(Serializer output) throws IOException {
|
||||
output.serializeInt64(ValueType.TYPE, type);
|
||||
output.serializeInt64(ValueType.UNIT, unit);
|
||||
output.serializeEnum(ValueType.AGGREGATION_TEMPORALITY, aggregationTemporality);
|
||||
}
|
||||
|
||||
private static int calculateSize(long type, long unit, ProtoEnumInfo aggregationTemporality) {
|
||||
int size;
|
||||
size = 0;
|
||||
size += MarshalerUtil.sizeInt64(ValueType.TYPE, type);
|
||||
size += MarshalerUtil.sizeInt64(ValueType.UNIT, unit);
|
||||
size += MarshalerUtil.sizeEnum(ValueType.AGGREGATION_TEMPORALITY, aggregationTemporality);
|
||||
return size;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,273 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.exporter.otlp.profiles;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
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.exporter.otlp.internal.data.ImmutableAttributeUnitData;
|
||||
import io.opentelemetry.exporter.otlp.internal.data.ImmutableFunctionData;
|
||||
import io.opentelemetry.exporter.otlp.internal.data.ImmutableLineData;
|
||||
import io.opentelemetry.exporter.otlp.internal.data.ImmutableLinkData;
|
||||
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.ImmutableSampleData;
|
||||
import io.opentelemetry.exporter.otlp.internal.data.ImmutableValueTypeData;
|
||||
import io.opentelemetry.proto.profiles.v1experimental.AttributeUnit;
|
||||
import io.opentelemetry.proto.profiles.v1experimental.Function;
|
||||
import io.opentelemetry.proto.profiles.v1experimental.Line;
|
||||
import io.opentelemetry.proto.profiles.v1experimental.Link;
|
||||
import io.opentelemetry.proto.profiles.v1experimental.Location;
|
||||
import io.opentelemetry.proto.profiles.v1experimental.Mapping;
|
||||
import io.opentelemetry.proto.profiles.v1experimental.Profile;
|
||||
import io.opentelemetry.proto.profiles.v1experimental.Sample;
|
||||
import io.opentelemetry.proto.profiles.v1experimental.ValueType;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class ProfilesRequestMarshalerTest {
|
||||
|
||||
@Test
|
||||
void compareAttributeUnitMarshaling() {
|
||||
AttributeUnitData input = ImmutableAttributeUnitData.create(1, 2);
|
||||
AttributeUnit builderResult = AttributeUnit.newBuilder().setAttributeKey(1).setUnit(2).build();
|
||||
|
||||
AttributeUnit roundTripResult =
|
||||
parse(AttributeUnit.getDefaultInstance(), AttributeUnitMarshaler.create(input));
|
||||
assertThat(roundTripResult).isEqualTo(builderResult);
|
||||
}
|
||||
|
||||
@Test
|
||||
void compareFunctionMarshaling() {
|
||||
FunctionData input = ImmutableFunctionData.create(1, 2, 3, 4);
|
||||
Function builderResult =
|
||||
Function.newBuilder().setName(1).setSystemName(2).setFilename(3).setStartLine(4).build();
|
||||
|
||||
Function roundTripResult =
|
||||
parse(Function.getDefaultInstance(), FunctionMarshaler.create(input));
|
||||
assertThat(roundTripResult).isEqualTo(builderResult);
|
||||
}
|
||||
|
||||
@Test
|
||||
void compareLineMarshaling() {
|
||||
LineData input = ImmutableLineData.create(1, 2, 3);
|
||||
Line builderResult = Line.newBuilder().setFunctionIndex(1).setLine(2).setColumn(3).build();
|
||||
|
||||
Line roundTripResult = parse(Line.getDefaultInstance(), LineMarshaler.create(input));
|
||||
assertThat(roundTripResult).isEqualTo(builderResult);
|
||||
}
|
||||
|
||||
@Test
|
||||
void compareLinkMarshaling() {
|
||||
String traceId = "0123456789abcdef0123456789abcdef";
|
||||
String spanId = "fedcba9876543210";
|
||||
LinkData input = ImmutableLinkData.create(traceId, spanId);
|
||||
Link builderResult =
|
||||
Link.newBuilder()
|
||||
.setTraceId(ByteString.fromHex(traceId))
|
||||
.setSpanId(ByteString.fromHex(spanId))
|
||||
.build();
|
||||
|
||||
Link roundTripResult = parse(Link.getDefaultInstance(), LinkMarshaler.create(input));
|
||||
assertThat(roundTripResult).isEqualTo(builderResult);
|
||||
}
|
||||
|
||||
@Test
|
||||
void compareLocationMarshaling() {
|
||||
LocationData input =
|
||||
ImmutableLocationData.create(1, 2, Collections.emptyList(), true, 3, listOf(5L, 6L));
|
||||
Location builderResult =
|
||||
Location.newBuilder()
|
||||
.setMappingIndex(1)
|
||||
.setAddress(2)
|
||||
.setIsFolded(true)
|
||||
.setTypeIndex(3)
|
||||
.addAllAttributes(listOf(5L, 6L))
|
||||
.build();
|
||||
|
||||
Location roundTripResult =
|
||||
parse(Location.getDefaultInstance(), LocationMarshaler.create(input));
|
||||
assertThat(roundTripResult).isEqualTo(builderResult);
|
||||
}
|
||||
|
||||
@Test
|
||||
void compareMappingMarshaling() {
|
||||
MappingData input =
|
||||
ImmutableMappingData.create(
|
||||
1, 2, 3, 4, 5, BuildIdKind.LINKER, listOf(6L, 7L), true, true, true, true);
|
||||
Mapping builderResult =
|
||||
Mapping.newBuilder()
|
||||
.setMemoryStart(1)
|
||||
.setMemoryLimit(2)
|
||||
.setFileOffset(3)
|
||||
.setFilename(4)
|
||||
.setBuildId(5)
|
||||
.setBuildIdKind(
|
||||
io.opentelemetry.proto.profiles.v1experimental.BuildIdKind.BUILD_ID_LINKER)
|
||||
.addAllAttributes(listOf(6L, 7L))
|
||||
.setHasFunctions(true)
|
||||
.setHasFilenames(true)
|
||||
.setHasLineNumbers(true)
|
||||
.setHasInlineFrames(true)
|
||||
.build();
|
||||
|
||||
Mapping roundTripResult = parse(Mapping.getDefaultInstance(), MappingMarshaler.create(input));
|
||||
assertThat(roundTripResult).isEqualTo(builderResult);
|
||||
}
|
||||
|
||||
@Test
|
||||
void compareProfileMarshaling() {
|
||||
ProfileData input =
|
||||
ImmutableProfileData.create(
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList(),
|
||||
listOf(1L, 2L),
|
||||
Collections.emptyList(),
|
||||
Attributes.empty(),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList(),
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
ImmutableValueTypeData.create(1, 2, AggregationTemporality.CUMULATIVE),
|
||||
7,
|
||||
listOf(8L, 9L),
|
||||
10);
|
||||
Profile builderResult =
|
||||
Profile.newBuilder()
|
||||
.addAllLocationIndices(listOf(1L, 2L))
|
||||
.setDropFrames(3)
|
||||
.setKeepFrames(4)
|
||||
.setTimeNanos(5)
|
||||
.setDurationNanos(6)
|
||||
.setPeriod(7)
|
||||
.setPeriodType(
|
||||
ValueType.newBuilder()
|
||||
.setType(1)
|
||||
.setUnit(2)
|
||||
.setAggregationTemporality(
|
||||
io.opentelemetry.proto.profiles.v1experimental.AggregationTemporality
|
||||
.AGGREGATION_TEMPORALITY_CUMULATIVE)
|
||||
.build())
|
||||
.addAllComment(listOf(8L, 9L))
|
||||
.setDefaultSampleType(10)
|
||||
.build();
|
||||
|
||||
Profile roundTripResult = parse(Profile.getDefaultInstance(), ProfileMarshaler.create(input));
|
||||
assertThat(roundTripResult).isEqualTo(builderResult);
|
||||
}
|
||||
|
||||
@Test
|
||||
void compareSampleMarshaling() {
|
||||
SampleData input =
|
||||
ImmutableSampleData.create(1, 2, 3, listOf(4L, 5L), listOf(6L, 7L), 8L, listOf(9L, 10L));
|
||||
Sample builderResult =
|
||||
Sample.newBuilder()
|
||||
.setLocationsStartIndex(1)
|
||||
.setLocationsLength(2)
|
||||
.setStacktraceIdIndex(3)
|
||||
.addAllValue(listOf(4L, 5L))
|
||||
.addAllAttributes(listOf(6L, 7L))
|
||||
.setLink(8)
|
||||
.addAllTimestampsUnixNano(listOf(9L, 10L))
|
||||
.build();
|
||||
|
||||
Sample roundTripResult = parse(Sample.getDefaultInstance(), SampleMarshaler.create(input));
|
||||
assertThat(roundTripResult).isEqualTo(builderResult);
|
||||
}
|
||||
|
||||
@Test
|
||||
void compareValueTypeMarshaling() {
|
||||
ValueTypeData input = ImmutableValueTypeData.create(1, 2, AggregationTemporality.CUMULATIVE);
|
||||
ValueType builderResult =
|
||||
ValueType.newBuilder()
|
||||
.setType(1)
|
||||
.setUnit(2)
|
||||
.setAggregationTemporality(
|
||||
io.opentelemetry.proto.profiles.v1experimental.AggregationTemporality
|
||||
.AGGREGATION_TEMPORALITY_CUMULATIVE)
|
||||
.build();
|
||||
|
||||
ValueType roundTripResult =
|
||||
parse(ValueType.getDefaultInstance(), ValueTypeMarshaler.create(input));
|
||||
assertThat(roundTripResult).isEqualTo(builderResult);
|
||||
}
|
||||
|
||||
private static <T> List<T> listOf(T a, T b) {
|
||||
ArrayList<T> list = new ArrayList<>();
|
||||
list.add(a);
|
||||
list.add(b);
|
||||
return Collections.unmodifiableList(list);
|
||||
}
|
||||
|
||||
@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);
|
||||
|
||||
// We don't compare JSON strings due to some differences (particularly serializing enums as
|
||||
// numbers instead of names). This may improve in the future but what matters is what we produce
|
||||
// can be parsed.
|
||||
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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue