Skip to content

Commit 1a1101a

Browse files
committed
Complex attributes incubating support
1 parent e2a9dd9 commit 1a1101a

File tree

10 files changed

+67
-4
lines changed

10 files changed

+67
-4
lines changed

api/incubator/src/main/java/io/opentelemetry/api/incubator/common/ExtendedAttributeKey.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package io.opentelemetry.api.incubator.common;
77

88
import io.opentelemetry.api.common.AttributeKey;
9+
import io.opentelemetry.api.common.Value;
910
import io.opentelemetry.api.incubator.internal.InternalExtendedAttributeKeyImpl;
1011
import java.util.List;
1112
import javax.annotation.Nullable;
@@ -97,4 +98,9 @@ static ExtendedAttributeKey<List<Double>> doubleArrayKey(String key) {
9798
static ExtendedAttributeKey<ExtendedAttributes> mapKey(String key) {
9899
return InternalExtendedAttributeKeyImpl.create(key, ExtendedAttributeType.MAP);
99100
}
101+
102+
/** Returns a new ExtendedAttributeKey for {@link Value} valued attributes. */
103+
static ExtendedAttributeKey<Value<?>> valueKey(String key) {
104+
return InternalExtendedAttributeKeyImpl.create(key, ExtendedAttributeType.VALUE);
105+
}
100106
}

api/incubator/src/main/java/io/opentelemetry/api/incubator/common/ExtendedAttributeType.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,6 @@ public enum ExtendedAttributeType {
2222
LONG_ARRAY,
2323
DOUBLE_ARRAY,
2424
// Extended types unique to ExtendedAttributes
25-
MAP;
25+
MAP,
26+
VALUE;
2627
}

api/incubator/src/main/java/io/opentelemetry/api/incubator/common/ExtendedAttributes.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
*
1919
* <p>"extended" refers an extended set of allowed value types compared to standard {@link
2020
* Attributes}. Notably, {@link ExtendedAttributes} values can be of type {@link
21-
* ExtendedAttributeType#MAP}, allowing nested {@link ExtendedAttributes} of arbitrary depth.
21+
* ExtendedAttributeType#MAP}, allowing nested {@link ExtendedAttributes} of arbitrary depth, or
22+
* {@link ExtendedAttributeType#VALUE}, enabling usage of {@link io.opentelemetry.api.common.Value}
23+
* instances.
2224
*
2325
* <p>Where standard {@link Attributes} are accepted everyone that OpenTelemetry represents key /
2426
* value pairs, {@link ExtendedAttributes} are only accepted in select places, such as log records

api/incubator/src/main/java/io/opentelemetry/api/incubator/common/ExtendedAttributesBuilder.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import io.opentelemetry.api.common.AttributeKey;
1919
import io.opentelemetry.api.common.Attributes;
20+
import io.opentelemetry.api.common.Value;
2021
import java.util.Arrays;
2122
import java.util.List;
2223
import java.util.function.Predicate;
@@ -97,6 +98,21 @@ default <T> ExtendedAttributesBuilder put(String key, ExtendedAttributes value)
9798
return put(ExtendedAttributeKey.mapKey(key), value);
9899
}
99100

101+
/**
102+
* Puts a {@link Value} attribute into this.
103+
*
104+
* <p>Note: It is strongly recommended to use {@link #put(ExtendedAttributeKey, Object)}, and
105+
* pre-allocate your keys, if possible.
106+
*
107+
* @return this Builder
108+
*/
109+
default ExtendedAttributesBuilder put(String key, Value<?> value) {
110+
if (value == null) {
111+
return this;
112+
}
113+
return put(ExtendedAttributeKey.valueKey(key), value);
114+
}
115+
100116
/**
101117
* Puts a String array attribute into this.
102118
*

api/incubator/src/main/java/io/opentelemetry/api/incubator/internal/InternalExtendedAttributeKeyImpl.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ public static <T> AttributeKey<T> toAttributeKey(ExtendedAttributeKey<T> extende
139139
return InternalAttributeKeyImpl.create(
140140
extendedAttributeKey.getKey(), AttributeType.DOUBLE_ARRAY);
141141
case MAP:
142+
case VALUE:
142143
return null;
143144
}
144145
throw new IllegalArgumentException(

api/incubator/src/test/java/io/opentelemetry/api/incubator/common/ExtendedAttributeKeyTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ private static Stream<Arguments> attributeKeyArgs() {
7676
"key",
7777
ExtendedAttributeType.DOUBLE_ARRAY,
7878
AttributeKey.doubleArrayKey("key")),
79-
Arguments.of(ExtendedAttributeKey.mapKey("key"), "key", ExtendedAttributeType.MAP, null));
79+
Arguments.of(ExtendedAttributeKey.mapKey("key"), "key", ExtendedAttributeType.MAP, null),
80+
Arguments.of(
81+
ExtendedAttributeKey.valueKey("key"), "key", ExtendedAttributeType.VALUE, null));
8082
}
8183
}

api/incubator/src/test/java/io/opentelemetry/api/incubator/common/ExtendedAttributesTest.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.google.common.collect.ImmutableMap;
1111
import io.opentelemetry.api.common.AttributeKey;
1212
import io.opentelemetry.api.common.Attributes;
13+
import io.opentelemetry.api.common.Value;
1314
import java.util.Arrays;
1415
import java.util.Collections;
1516
import java.util.HashMap;
@@ -116,7 +117,9 @@ void asAttributes(ExtendedAttributes extendedAttributes, Map<String, Object> exp
116117
});
117118

118119
long expectedSize =
119-
expectedMap.values().stream().filter(value -> !(value instanceof Map)).count();
120+
expectedMap.values().stream()
121+
.filter(value -> !(value instanceof Map) && !(value instanceof Value))
122+
.count();
120123
assertThat(attributes.size()).isEqualTo(expectedSize);
121124
}
122125

@@ -212,6 +215,9 @@ private static Stream<Arguments> attributesArgs() {
212215
ImmutableMap.builder()
213216
.put("key", ImmutableMap.builder().put("child", "value").build())
214217
.build()),
218+
Arguments.of(
219+
ExtendedAttributes.builder().put("key", Value.of("value")).build(),
220+
ImmutableMap.builder().put("key", Value.of("value")).build()),
215221
Arguments.of(
216222
ExtendedAttributes.builder()
217223
.put(ExtendedAttributeKey.stringKey("key"), "value")
@@ -255,6 +261,11 @@ private static Stream<Arguments> attributesArgs() {
255261
ImmutableMap.builder()
256262
.put("key", ImmutableMap.builder().put("child", "value").build())
257263
.build()),
264+
Arguments.of(
265+
ExtendedAttributes.builder()
266+
.put(ExtendedAttributeKey.valueKey("key"), Value.of("value"))
267+
.build(),
268+
ImmutableMap.builder().put("key", Value.of("value")).build()),
258269
// Multiple entries
259270
Arguments.of(
260271
ExtendedAttributes.builder()
@@ -268,6 +279,7 @@ private static Stream<Arguments> attributesArgs() {
268279
.put("key8", 1L, 2L)
269280
.put("key9", 1.1, 2.2)
270281
.put("key10", ExtendedAttributes.builder().put("child", "value").build())
282+
.put("key11", Value.of("value"))
271283
.build(),
272284
ImmutableMap.builder()
273285
.put("key1", "value1")
@@ -280,6 +292,7 @@ private static Stream<Arguments> attributesArgs() {
280292
.put("key8", Arrays.asList(1L, 2L))
281293
.put("key9", Arrays.asList(1.1, 2.2))
282294
.put("key10", ImmutableMap.builder().put("child", "value").build())
295+
.put("key11", Value.of("value"))
283296
.build()));
284297
}
285298

@@ -316,6 +329,8 @@ private static ExtendedAttributeKey<?> getKey(String key, Object value) {
316329
return ExtendedAttributeKey.doubleArrayKey(key);
317330
case MAP:
318331
return ExtendedAttributeKey.mapKey(key);
332+
case VALUE:
333+
return ExtendedAttributeKey.valueKey(key);
319334
}
320335
throw new IllegalArgumentException();
321336
}
@@ -355,6 +370,9 @@ private static ExtendedAttributeType getType(Object value) {
355370
if ((value instanceof Map)) {
356371
return ExtendedAttributeType.MAP;
357372
}
373+
if (value instanceof Value) {
374+
return ExtendedAttributeType.VALUE;
375+
}
358376
throw new IllegalArgumentException("Unrecognized value type: " + value);
359377
}
360378
}

api/incubator/src/test/java/io/opentelemetry/api/incubator/logs/ExtendedLogsBridgeApiUsageTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import io.opentelemetry.api.common.AttributeKey;
1313
import io.opentelemetry.api.common.Attributes;
14+
import io.opentelemetry.api.common.Value;
1415
import io.opentelemetry.api.incubator.common.ExtendedAttributeKey;
1516
import io.opentelemetry.api.incubator.common.ExtendedAttributes;
1617
import io.opentelemetry.api.logs.Logger;
@@ -105,6 +106,7 @@ private static String flipCoin() {
105106

106107
// Extended keys
107108
ExtendedAttributeKey<ExtendedAttributes> mapKey = ExtendedAttributeKey.mapKey("acme.map");
109+
ExtendedAttributeKey<Value<?>> valueKey = ExtendedAttributeKey.valueKey("acme.value");
108110

109111
@Test
110112
@SuppressLogger(ExtendedLogsBridgeApiUsageTest.class)
@@ -124,6 +126,7 @@ void extendedAttributesUsage() {
124126
.put(
125127
mapKey,
126128
ExtendedAttributes.builder().put("childStr", "value").put("childLong", 1L).build())
129+
.put(valueKey, Value.of("value"))
127130
.build();
128131

129132
// Retrieval
@@ -138,6 +141,7 @@ void extendedAttributesUsage() {
138141
assertThat(extendedAttributes.get(mapKey))
139142
.isEqualTo(
140143
ExtendedAttributes.builder().put("childStr", "value").put("childLong", 1L).build());
144+
assertThat(extendedAttributes.get(valueKey)).isEqualTo(Value.of("value"));
141145

142146
// Iteration
143147
// Output:
@@ -148,6 +152,7 @@ void extendedAttributesUsage() {
148152
// acme.long(LONG): 1
149153
// acme.long_array(LONG_ARRAY): [1, 2]
150154
// acme.map(MAP): {childLong=1, childStr="value"}
155+
// acme.value(VALUE): ValueString{value}
151156
// acme.string(STRING): value
152157
// acme.string_array(STRING_ARRAY): [value1, value2]
153158
extendedAttributes.forEach(
@@ -183,6 +188,7 @@ void logRecordBuilder_ExtendedAttributes() {
183188
.setAttribute(
184189
mapKey,
185190
ExtendedAttributes.builder().put("childStr", "value").put("childLong", 1L).build())
191+
.setAttribute(valueKey, Value.of("value"))
186192
.setAllAttributes(Attributes.builder().put("key1", "value").build())
187193
.setAllAttributes(ExtendedAttributes.builder().put("key2", "value").build())
188194
.emit();
@@ -228,6 +234,7 @@ void logRecordBuilder_ExtendedAttributes() {
228234
.put("childStr", "value")
229235
.put("childLong", 1L)
230236
.build())
237+
.put(valueKey, Value.of("value"))
231238
.put("key1", "value")
232239
.put("key2", "value")
233240
.build());

exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/ExtendedAttributeKeyValueStatelessMarshaler.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package io.opentelemetry.exporter.internal.otlp;
77

8+
import io.opentelemetry.api.common.Value;
89
import io.opentelemetry.api.incubator.common.ExtendedAttributeKey;
910
import io.opentelemetry.api.incubator.common.ExtendedAttributeType;
1011
import io.opentelemetry.api.incubator.common.ExtendedAttributes;
@@ -174,6 +175,9 @@ public int getBinarySerializedSize(
174175
(ExtendedAttributes) value,
175176
ExtendedAttributesKeyValueListStatelessMarshaler.INSTANCE,
176177
context);
178+
case VALUE:
179+
return AnyValueStatelessMarshaler.INSTANCE.getBinarySerializedSize(
180+
(Value<?>) value, context);
177181
}
178182
// Error prone ensures the switch statement is complete, otherwise only can happen with
179183
// unaligned versions which are not supported.
@@ -220,6 +224,9 @@ public void writeTo(
220224
ExtendedAttributesKeyValueListStatelessMarshaler.INSTANCE,
221225
context);
222226
return;
227+
case VALUE:
228+
AnyValueStatelessMarshaler.INSTANCE.writeTo(output, (Value<?>) value, context);
229+
return;
223230
}
224231
// Error prone ensures the switch statement is complete, otherwise only can happen with
225232
// unaligned versions which are not supported.

exporters/otlp/common/src/main/java/io/opentelemetry/exporter/internal/otlp/IncubatingUtil.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package io.opentelemetry.exporter.internal.otlp;
77

8+
import io.opentelemetry.api.common.Value;
89
import io.opentelemetry.api.incubator.common.ExtendedAttributeKey;
910
import io.opentelemetry.api.incubator.common.ExtendedAttributes;
1011
import io.opentelemetry.api.incubator.internal.InternalExtendedAttributeKeyImpl;
@@ -116,6 +117,8 @@ private static KeyValueMarshaler create(ExtendedAttributeKey<?> attributeKey, Ob
116117
new KeyValueListAnyValueMarshaler(
117118
new KeyValueListAnyValueMarshaler.KeyValueListMarshaler(
118119
createForExtendedAttributes((ExtendedAttributes) value))));
120+
case VALUE:
121+
return new KeyValueMarshaler(keyUtf8, AnyValueMarshaler.create((Value<?>) value));
119122
}
120123
// Error prone ensures the switch statement is complete, otherwise only can happen with
121124
// unaligned versions which are not supported.

0 commit comments

Comments
 (0)