Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import com.google.auto.service.AutoService;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;
import io.opentelemetry.sdk.internal.IncludeExcludePredicate;
import io.opentelemetry.sdk.common.internal.IncludeExcludePredicate;
import io.opentelemetry.sdk.logs.LogRecordProcessor;

@AutoService(ComponentProvider.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import com.google.auto.service.AutoService;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;
import io.opentelemetry.sdk.internal.IncludeExcludePredicate;
import io.opentelemetry.sdk.common.internal.IncludeExcludePredicate;
import io.opentelemetry.sdk.trace.SpanProcessor;

@AutoService(ComponentProvider.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,13 @@
package io.opentelemetry.contrib.compressor.zstd;

import com.github.luben.zstd.ZstdOutputStream;
import io.opentelemetry.exporter.internal.compression.Compressor;
import io.opentelemetry.sdk.common.export.Compressor;
import java.io.IOException;
import java.io.OutputStream;

public final class ZstdCompressor implements Compressor {

private static final ZstdCompressor INSTANCE = new ZstdCompressor();

private ZstdCompressor() {}

public static ZstdCompressor getInstance() {
return INSTANCE;
}
public ZstdCompressor() {}

@Override
public String getEncoding() {
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
io.opentelemetry.contrib.compressor.zstd.ZstdCompressor
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import static org.assertj.core.api.Assertions.assertThat;

import com.github.luben.zstd.ZstdInputStream;
import io.opentelemetry.sdk.common.export.Compressor;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
Expand All @@ -23,7 +24,8 @@ void roundTrip() throws IOException {
String content = "hello world";

ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = ZstdCompressor.getInstance().compress(baos);
Compressor compressor = new ZstdCompressor();
OutputStream os = compressor.compress(baos);
os.write(content.getBytes(StandardCharsets.UTF_8));
os.close();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import io.opentelemetry.api.trace.TraceState;
import io.opentelemetry.context.Context;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.internal.DaemonThreadFactory;
import io.opentelemetry.sdk.common.internal.DaemonThreadFactory;
import io.opentelemetry.sdk.trace.ReadWriteSpan;
import io.opentelemetry.sdk.trace.ReadableSpan;
import io.opentelemetry.sdk.trace.SpanProcessor;
Expand Down
2 changes: 1 addition & 1 deletion dependencyManagement/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ plugins {
`java-platform`
}

val otelInstrumentationVersion = "2.24.0-alpha"
val otelInstrumentationVersion = "2.25.0-alpha"
val semconvVersion = "1.39.0"

javaPlatform {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,38 @@

package io.opentelemetry.contrib.disk.buffering.internal.serialization.mapping.common;

import static java.util.Collections.emptyList;

import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.AttributeType;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.common.Value;
import io.opentelemetry.proto.common.v1.AnyValue;
import io.opentelemetry.proto.common.v1.ArrayValue;
import io.opentelemetry.proto.common.v1.KeyValue;
import io.opentelemetry.proto.common.v1.KeyValueList;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import okio.ByteString;

public final class AttributesMapper {

private static final AttributesMapper INSTANCE = new AttributesMapper();

/** Represents the type of value stored in a proto AnyValue. */
private enum ProtoValueType {
STRING,
BOOL,
INT,
DOUBLE,
BYTES,
ARRAY,
KVLIST,
EMPTY
}

public static AttributesMapper getInstance() {
return INSTANCE;
}
Expand All @@ -44,7 +62,8 @@ private static KeyValue attributeEntryToProto(AttributeKey<?> key, Object value)
return builder.build();
}

@SuppressWarnings("unchecked") // data type is checked before casting
// Type is checked via AttributeType before casting
@SuppressWarnings("unchecked")
private static AnyValue attributeValueToProto(AttributeType type, Object value) {
switch (type) {
case STRING:
Expand All @@ -63,10 +82,72 @@ private static AnyValue attributeValueToProto(AttributeType type, Object value)
return arrayToAnyValue(longListToAnyValue((List<Long>) value));
case DOUBLE_ARRAY:
return arrayToAnyValue(doubleListToAnyValue((List<Double>) value));
case VALUE:
return valueToAnyValue((Value<?>) value);
}
throw new UnsupportedOperationException();
}

// Type is checked via ValueType before casting
@SuppressWarnings("unchecked")
private static AnyValue valueToAnyValue(Value<?> value) {
switch (value.getType()) {
case STRING:
return stringToAnyValue((String) value.getValue());
case BOOLEAN:
return booleanToAnyValue((Boolean) value.getValue());
case LONG:
return longToAnyValue((Long) value.getValue());
case DOUBLE:
return doubleToAnyValue((Double) value.getValue());
case BYTES:
ByteBuffer byteBuffer = (ByteBuffer) value.getValue();
byte[] bytes = new byte[byteBuffer.remaining()];
byteBuffer.get(bytes);
return bytesToAnyValue(bytes);
case ARRAY:
List<Value<?>> arrayValues = (List<Value<?>>) value.getValue();
return arrayValueToAnyValue(arrayValues);
case KEY_VALUE_LIST:
List<io.opentelemetry.api.common.KeyValue> kvList =
(List<io.opentelemetry.api.common.KeyValue>) value.getValue();
return keyValueListToAnyValue(kvList);
case EMPTY:
return new AnyValue.Builder().build();
}
throw new UnsupportedOperationException("Unsupported ValueType: " + value.getType());
}

private static AnyValue bytesToAnyValue(byte[] bytes) {
AnyValue.Builder anyValue = new AnyValue.Builder();
anyValue.bytes_value(ByteString.of(bytes));
return anyValue.build();
}

private static AnyValue arrayValueToAnyValue(List<Value<?>> values) {
List<AnyValue> anyValues = new ArrayList<>(values.size());
for (Value<?> v : values) {
anyValues.add(valueToAnyValue(v));
}
return new AnyValue.Builder()
.array_value(new ArrayValue.Builder().values(anyValues).build())
.build();
}

private static AnyValue keyValueListToAnyValue(
List<io.opentelemetry.api.common.KeyValue> kvList) {
List<KeyValue> protoKeyValues = new ArrayList<>(kvList.size());
for (io.opentelemetry.api.common.KeyValue kv : kvList) {
KeyValue.Builder kvBuilder = new KeyValue.Builder();
kvBuilder.key(kv.getKey());
kvBuilder.value(valueToAnyValue(kv.getValue()));
protoKeyValues.add(kvBuilder.build());
}
return new AnyValue.Builder()
.kvlist_value(new KeyValueList.Builder().values(protoKeyValues).build())
.build();
}

private static AnyValue arrayToAnyValue(List<AnyValue> value) {
return new AnyValue.Builder()
.array_value(new ArrayValue.Builder().values(value).build())
Expand All @@ -84,30 +165,106 @@ private static void addValue(AttributesBuilder builder, String key, AnyValue val
builder.put(AttributeKey.doubleKey(key), value.double_value);
} else if (value.array_value != null) {
addArray(builder, key, value.array_value);
} else if (value.bytes_value != null) {
builder.put(AttributeKey.valueKey(key), Value.of(value.bytes_value.toByteArray()));
} else if (value.kvlist_value != null) {
builder.put(AttributeKey.valueKey(key), anyValueToValue(value));
} else {
// Until we have complex attribute types that could potentially yield
// empty objects, we MUST assume here that the writer put an empty string
// into the value of the attribute. This will need to change later, when complex
// types arrive and the spec issue is resolved.
//
// See spec issue: https://github.com/open-telemetry/opentelemetry-specification/issues/4660
// Update after SDK v1.60.0 is released which includes:
// https://github.com/open-telemetry/opentelemetry-java/pull/8014
builder.put(AttributeKey.stringKey(key), "");
Comment on lines -88 to 175
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

disk buffering / android folks (@LikeTheSalad @zeitlinger @breedx-splk) please review the changes here

in particular, I'm not sure whether you prefer to support complex attributes or not until this bug is fixed

}
}

private static Value<?> anyValueToValue(AnyValue value) {
if (value.string_value != null) {
return Value.of(value.string_value);
} else if (value.bool_value != null) {
return Value.of(value.bool_value);
} else if (value.int_value != null) {
return Value.of(value.int_value);
} else if (value.double_value != null) {
return Value.of(value.double_value);
} else if (value.bytes_value != null) {
return Value.of(value.bytes_value.toByteArray());
} else if (value.array_value != null) {
List<Value<?>> values = new ArrayList<>();
for (AnyValue anyValue : value.array_value.values) {
values.add(anyValueToValue(anyValue));
}
return Value.of(values);
} else if (value.kvlist_value != null) {
List<io.opentelemetry.api.common.KeyValue> kvList = new ArrayList<>();
for (KeyValue kv : value.kvlist_value.values) {
kvList.add(io.opentelemetry.api.common.KeyValue.of(kv.key, anyValueToValue(kv.value)));
}
return Value.of(kvList.toArray(new io.opentelemetry.api.common.KeyValue[0]));
} else {
return Value.empty();
}
}

private static void addArray(AttributesBuilder builder, String key, ArrayValue arrayValue) {
List<AnyValue> values = arrayValue.values;
AnyValue anyValue = values.get(0);
if (anyValue.string_value != null) {
builder.put(AttributeKey.stringArrayKey(key), anyValuesToStrings(values));
} else if (anyValue.bool_value != null) {
builder.put(AttributeKey.booleanArrayKey(key), anyValuesToBooleans(values));
} else if (anyValue.int_value != null) {
builder.put(AttributeKey.longArrayKey(key), anyValuesToLongs(values));
} else if (anyValue.double_value != null) {
builder.put(AttributeKey.doubleArrayKey(key), anyValuesToDoubles(values));

// Per SDK behavior (ArrayBackedAttributesBuilder#attributeType):
// "VALUE if the array is empty, non-homogeneous, or contains unsupported element types"
if (values.isEmpty()) {
builder.put(AttributeKey.valueKey(key), Value.of(emptyList()));
return;
}

// Check if array is homogeneous and of a primitive type
AnyValue firstValue = values.get(0);
boolean isHomogeneous = true;
ProtoValueType arrayType = getProtoValueType(firstValue);

for (int i = 1; i < values.size(); i++) {
if (getProtoValueType(values.get(i)) != arrayType) {
isHomogeneous = false;
break;
}
}

// If homogeneous and primitive, use typed array keys
if (isHomogeneous) {
if (firstValue.string_value != null) {
builder.put(AttributeKey.stringArrayKey(key), anyValuesToStrings(values));
return;
} else if (firstValue.bool_value != null) {
builder.put(AttributeKey.booleanArrayKey(key), anyValuesToBooleans(values));
return;
} else if (firstValue.int_value != null) {
builder.put(AttributeKey.longArrayKey(key), anyValuesToLongs(values));
return;
} else if (firstValue.double_value != null) {
builder.put(AttributeKey.doubleArrayKey(key), anyValuesToDoubles(values));
return;
}
}

// Heterogeneous or complex array - use VALUE type
AnyValue anyValue = new AnyValue.Builder().array_value(arrayValue).build();
builder.put(AttributeKey.valueKey(key), anyValueToValue(anyValue));
}

private static ProtoValueType getProtoValueType(AnyValue value) {
if (value.string_value != null) {
return ProtoValueType.STRING;
} else if (value.bool_value != null) {
return ProtoValueType.BOOL;
} else if (value.int_value != null) {
return ProtoValueType.INT;
} else if (value.double_value != null) {
return ProtoValueType.DOUBLE;
} else if (value.bytes_value != null) {
return ProtoValueType.BYTES;
} else if (value.array_value != null) {
return ProtoValueType.ARRAY;
} else if (value.kvlist_value != null) {
return ProtoValueType.KVLIST;
} else {
throw new UnsupportedOperationException();
return ProtoValueType.EMPTY;
}
}

Expand Down
Loading
Loading