Skip to content

Commit 4c8c5ea

Browse files
committed
spans
1 parent 43b6682 commit 4c8c5ea

16 files changed

Lines changed: 144 additions & 64 deletions

File tree

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,12 @@ public Attributes asAttributes() {
6464
AttributeKey<Object> attributeKey =
6565
(AttributeKey<Object>) extendedAttributeKey.asAttributeKey();
6666
if (attributeKey != null) {
67-
builder.put(attributeKey, value);
67+
if (attributeKey.getType() == io.opentelemetry.api.common.AttributeType.MAP
68+
&& value instanceof ExtendedAttributes) {
69+
builder.put(attributeKey, ((ExtendedAttributes) value).asAttributes());
70+
} else {
71+
builder.put(attributeKey, value);
72+
}
6873
}
6974
});
7075
attributes = builder.build();

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

Lines changed: 14 additions & 3 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;
@@ -93,8 +94,18 @@ static ExtendedAttributeKey<List<Double>> doubleArrayKey(String key) {
9394
return fromAttributeKey(AttributeKey.doubleArrayKey(key));
9495
}
9596

96-
/** Returns a new ExtendedAttributeKey for Map valued attributes. */
97-
static ExtendedAttributeKey<ExtendedAttributes> extendedAttributesKey(String key) {
98-
return InternalExtendedAttributeKeyImpl.create(key, ExtendedAttributeType.EXTENDED_ATTRIBUTES);
97+
/** Returns a new ExtendedAttributeKey for byte array valued attributes. */
98+
static ExtendedAttributeKey<byte[]> byteArrayKey(String key) {
99+
return InternalExtendedAttributeKeyImpl.create(key, ExtendedAttributeType.BYTE_ARRAY);
100+
}
101+
102+
/** Returns a new ExtendedAttributeKey for List&lt;Value&lt;?&gt;&gt; valued attributes. */
103+
static ExtendedAttributeKey<List<Value<?>>> valueArrayKey(String key) {
104+
return InternalExtendedAttributeKeyImpl.create(key, ExtendedAttributeType.VALUE_ARRAY);
105+
}
106+
107+
/** Returns a new ExtendedAttributeKey for {@link ExtendedAttributes} valued attributes. */
108+
static ExtendedAttributeKey<ExtendedAttributes> mapKey(String key) {
109+
return InternalExtendedAttributeKeyImpl.create(key, ExtendedAttributeType.MAP);
99110
}
100111
}

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@ public enum ExtendedAttributeType {
2121
BOOLEAN_ARRAY,
2222
LONG_ARRAY,
2323
DOUBLE_ARRAY,
24+
// Extended types unique to ExtendedAttributes
2425
BYTE_ARRAY,
2526
VALUE_ARRAY,
26-
MAP,
27-
// Extended types unique to ExtendedAttributes
28-
EXTENDED_ATTRIBUTES;
27+
MAP;
2928
}

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

Lines changed: 13 additions & 4 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.AttributeType;
910
import io.opentelemetry.api.common.Attributes;
1011
import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder;
1112
import java.util.Map;
@@ -17,9 +18,8 @@
1718
* An immutable container for extended attributes.
1819
*
1920
* <p>"extended" refers an extended set of allowed value types compared to standard {@link
20-
* Attributes}. Notably, {@link ExtendedAttributes} values can be of type {@link
21-
* ExtendedAttributeType#EXTENDED_ATTRIBUTES}, allowing nested {@link ExtendedAttributes} of
22-
* arbitrary depth.
21+
* Attributes}. Notably, {@link ExtendedAttributes} values can be nested {@link ExtendedAttributes}
22+
* via the {@link ExtendedAttributeType#MAP} type, allowing arbitrary depth.
2323
*
2424
* <p>Where standard {@link Attributes} are accepted everyone that OpenTelemetry represents key /
2525
* value pairs, {@link ExtendedAttributes} are only accepted in select places, such as log records
@@ -53,11 +53,20 @@ public interface ExtendedAttributes {
5353

5454
/** Returns the value for the given {@link AttributeKey}, or {@code null} if not found. */
5555
@Nullable
56+
@SuppressWarnings("unchecked")
5657
default <T> T get(AttributeKey<T> key) {
5758
if (key == null) {
5859
return null;
5960
}
60-
return get(ExtendedAttributeKey.fromAttributeKey(key));
61+
ExtendedAttributeKey<T> extendedAttributeKey = ExtendedAttributeKey.fromAttributeKey(key);
62+
Object value = get(extendedAttributeKey);
63+
if (value == null) {
64+
return null;
65+
}
66+
if (key.getType() == AttributeType.MAP && value instanceof ExtendedAttributes) {
67+
return (T) ((ExtendedAttributes) value).asAttributes();
68+
}
69+
return (T) value;
6170
}
6271

6372
/** Returns the value for the given {@link ExtendedAttributeKey}, or {@code null} if not found. */

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,19 @@ default ExtendedAttributesBuilder put(String key, boolean value) {
9393
*
9494
* @return this Builder
9595
*/
96-
default <T> ExtendedAttributesBuilder put(String key, ExtendedAttributes value) {
97-
return put(ExtendedAttributeKey.extendedAttributesKey(key), value);
96+
default ExtendedAttributesBuilder put(String key, ExtendedAttributes value) {
97+
if (value == null) {
98+
return this;
99+
}
100+
return put(ExtendedAttributeKey.mapKey(key), value);
98101
}
99102

100103
/** Puts a byte array attribute into this. */
101104
default ExtendedAttributesBuilder put(String key, byte[] value) {
102105
if (value == null) {
103106
return this;
104107
}
105-
return put(ExtendedAttributeKey.fromAttributeKey(AttributeKey.byteArrayKey(key)), value);
108+
return put(ExtendedAttributeKey.byteArrayKey(key), value);
106109
}
107110

108111
/** Puts an {@link Attributes} attribute into this. */

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,6 @@ public static <T> AttributeKey<T> toAttributeKey(ExtendedAttributeKey<T> extende
146146
extendedAttributeKey.getKey(), AttributeType.VALUE_ARRAY);
147147
case MAP:
148148
return InternalAttributeKeyImpl.create(extendedAttributeKey.getKey(), AttributeType.MAP);
149-
case EXTENDED_ATTRIBUTES:
150-
return null;
151149
}
152150
throw new IllegalArgumentException(
153151
"Unrecognized extendedAttributeKey type: " + extendedAttributeKey.getType());

api/incubator/src/main/java/io/opentelemetry/api/incubator/trace/ExtendedSpanBuilder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,8 @@ <E extends Throwable> void startAndRun(
134134
* <p>NOTE: all standard {@link AttributeKey}-value pairs can also be represented as {@link
135135
* ExtendedAttributeKey}-value pairs, but not all {@link ExtendedAttributeKey}-value pairs can be
136136
* represented as standard {@link AttributeKey}-value pairs. From the standpoint of the emitted
137-
* span, there is no difference between adding attributes using the standard or extended
138-
* attribute APIs.
137+
* span, there is no difference between adding attributes using the standard or extended attribute
138+
* APIs.
139139
*/
140140
<T> ExtendedSpanBuilder setAttribute(ExtendedAttributeKey<T> key, T value);
141141

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,12 @@ private static Stream<Arguments> attributeKeyArgs() {
7777
ExtendedAttributeType.DOUBLE_ARRAY,
7878
AttributeKey.doubleArrayKey("key")),
7979
Arguments.of(
80-
ExtendedAttributeKey.fromAttributeKey(AttributeKey.byteArrayKey("key")),
80+
ExtendedAttributeKey.byteArrayKey("key"),
8181
"key",
8282
ExtendedAttributeType.BYTE_ARRAY,
8383
AttributeKey.byteArrayKey("key")),
8484
Arguments.of(
85-
ExtendedAttributeKey.fromAttributeKey(AttributeKey.valueArrayKey("key")),
85+
ExtendedAttributeKey.valueArrayKey("key"),
8686
"key",
8787
ExtendedAttributeType.VALUE_ARRAY,
8888
AttributeKey.valueArrayKey("key")),
@@ -92,9 +92,9 @@ private static Stream<Arguments> attributeKeyArgs() {
9292
ExtendedAttributeType.MAP,
9393
AttributeKey.mapKey("key")),
9494
Arguments.of(
95-
ExtendedAttributeKey.extendedAttributesKey("key"),
95+
ExtendedAttributeKey.mapKey("key"),
9696
"key",
97-
ExtendedAttributeType.EXTENDED_ATTRIBUTES,
98-
null));
97+
ExtendedAttributeType.MAP,
98+
AttributeKey.mapKey("key")));
9999
}
100100
}

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

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ void get_AttributeKey(ExtendedAttributes extendedAttributes, Map<String, Object>
5757

5858
Object actualValue = extendedAttributes.get(attributeKey);
5959

60+
if (actualValue instanceof Attributes && value instanceof Map) {
61+
actualValue = toSimpleMap((Attributes) actualValue);
62+
}
63+
6064
assertThat(actualValue)
6165
.describedAs(key + "(" + attributeKey.getType() + ")")
6266
.isEqualTo(value);
@@ -96,9 +100,9 @@ private static void assertEquals(
96100
assertThat(actual.size()).isEqualTo(expected.size());
97101
actual.forEach(
98102
(key, value) -> {
99-
if (key.getType() == ExtendedAttributeType.EXTENDED_ATTRIBUTES) {
103+
if (value instanceof ExtendedAttributes) {
100104
assertEquals(
101-
((ExtendedAttributes) value).asMap(),
105+
toMap((ExtendedAttributes) value),
102106
(Map<String, Object>) expected.get(key.getKey()));
103107
return;
104108
}
@@ -113,12 +117,15 @@ void asAttributes(ExtendedAttributes extendedAttributes, Map<String, Object> exp
113117

114118
attributes.forEach(
115119
(key, value) -> {
116-
assertThat(value).isEqualTo(expectedMap.get(key.getKey()));
120+
Object expectedValue = expectedMap.get(key.getKey());
121+
if (value instanceof Attributes && expectedValue instanceof Map) {
122+
assertThat(toSimpleMap((Attributes) value)).isEqualTo(expectedValue);
123+
return;
124+
}
125+
assertThat(value).isEqualTo(expectedValue);
117126
});
118127

119-
long expectedSize =
120-
expectedMap.values().stream().filter(value -> !(value instanceof Map)).count();
121-
assertThat(attributes.size()).isEqualTo(expectedSize);
128+
assertThat(attributes.size()).isEqualTo(expectedMap.size());
122129
}
123130

124131
@ParameterizedTest
@@ -162,7 +169,7 @@ private static ExtendedAttributes fromMap(Map<String, Object> map) {
162169
map.forEach(
163170
(key, value) -> {
164171
ExtendedAttributeKey<?> extendedAttributeKey = getKey(key, value);
165-
if (extendedAttributeKey.getType() == ExtendedAttributeType.EXTENDED_ATTRIBUTES) {
172+
if (value instanceof Map) {
166173
builder.put(
167174
(ExtendedAttributeKey<ExtendedAttributes>) extendedAttributeKey,
168175
fromMap((Map<String, Object>) value));
@@ -271,7 +278,7 @@ private static Stream<Arguments> attributesArgs() {
271278
Arguments.of(
272279
ExtendedAttributes.builder()
273280
.put(
274-
ExtendedAttributeKey.extendedAttributesKey("key"),
281+
ExtendedAttributeKey.mapKey("key"),
275282
ExtendedAttributes.builder().put("child", "value").build())
276283
.build(),
277284
ImmutableMap.builder()
@@ -309,7 +316,7 @@ private static Map<String, Object> toMap(ExtendedAttributes extendedAttributes)
309316
Map<String, Object> map = new HashMap<>();
310317
extendedAttributes.forEach(
311318
(key, value) -> {
312-
if (key.getType() == ExtendedAttributeType.EXTENDED_ATTRIBUTES) {
319+
if (value instanceof ExtendedAttributes) {
313320
map.put(key.getKey(), toMap((ExtendedAttributes) value));
314321
return;
315322
}
@@ -318,6 +325,13 @@ private static Map<String, Object> toMap(ExtendedAttributes extendedAttributes)
318325
return map;
319326
}
320327

328+
private static Map<String, Object> toSimpleMap(Attributes attributes) {
329+
Map<String, Object> map = new HashMap<>();
330+
attributes.forEach(
331+
(attributeKey, attributeValue) -> map.put(attributeKey.getKey(), attributeValue));
332+
return map;
333+
}
334+
321335
private static ExtendedAttributeKey<?> getKey(String key, Object value) {
322336
switch (getType(value)) {
323337
case STRING:
@@ -337,13 +351,14 @@ private static ExtendedAttributeKey<?> getKey(String key, Object value) {
337351
case DOUBLE_ARRAY:
338352
return ExtendedAttributeKey.doubleArrayKey(key);
339353
case BYTE_ARRAY:
340-
return ExtendedAttributeKey.fromAttributeKey(AttributeKey.byteArrayKey(key));
354+
return ExtendedAttributeKey.byteArrayKey(key);
341355
case VALUE_ARRAY:
342-
return ExtendedAttributeKey.fromAttributeKey(AttributeKey.valueArrayKey(key));
356+
return ExtendedAttributeKey.valueArrayKey(key);
343357
case MAP:
344-
return ExtendedAttributeKey.fromAttributeKey(AttributeKey.mapKey(key));
345-
case EXTENDED_ATTRIBUTES:
346-
return ExtendedAttributeKey.extendedAttributesKey(key);
358+
if (value instanceof Attributes) {
359+
return ExtendedAttributeKey.fromAttributeKey(AttributeKey.mapKey(key));
360+
}
361+
return ExtendedAttributeKey.mapKey(key);
347362
}
348363
throw new IllegalArgumentException();
349364
}
@@ -390,7 +405,7 @@ private static ExtendedAttributeType getType(Object value) {
390405
return ExtendedAttributeType.MAP;
391406
}
392407
if ((value instanceof Map)) {
393-
return ExtendedAttributeType.EXTENDED_ATTRIBUTES;
408+
return ExtendedAttributeType.MAP;
394409
}
395410
throw new IllegalArgumentException("Unrecognized value type: " + value);
396411
}

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

Lines changed: 21 additions & 3 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;
@@ -104,14 +105,18 @@ private static String flipCoin() {
104105
AttributeKey<List<Double>> doubleArrKey = AttributeKey.doubleArrayKey("acme.double_array");
105106

106107
// Extended keys
107-
ExtendedAttributeKey<ExtendedAttributes> mapKey =
108-
ExtendedAttributeKey.extendedAttributesKey("acme.map");
108+
ExtendedAttributeKey<ExtendedAttributes> mapKey = ExtendedAttributeKey.mapKey("acme.map");
109+
ExtendedAttributeKey<byte[]> bytesKey = ExtendedAttributeKey.byteArrayKey("acme.bytes");
110+
ExtendedAttributeKey<List<Value<?>>> extendedValueArrayKey =
111+
ExtendedAttributeKey.valueArrayKey("acme.value_array");
109112

110113
@Test
111114
@SuppressLogger(ExtendedLogsBridgeApiUsageTest.class)
112115
void extendedAttributesUsage() {
113116
// Initialize from builder. Varargs style initialization (ExtendedAttributes.of(...) not
114117
// supported.
118+
List<Value<?>> heterogeneousValues =
119+
Arrays.asList(Value.of("value"), Value.of(1L), Value.of(true));
115120
ExtendedAttributes extendedAttributes =
116121
ExtendedAttributes.builder()
117122
.put(strKey, "value")
@@ -122,6 +127,8 @@ void extendedAttributesUsage() {
122127
.put(longArrKey, Arrays.asList(1L, 2L))
123128
.put(booleanArrKey, Arrays.asList(true, false))
124129
.put(doubleArrKey, Arrays.asList(1.1, 2.2))
130+
.put(bytesKey, new byte[] {(byte) 1, (byte) 2})
131+
.put(extendedValueArrayKey, heterogeneousValues)
125132
.put(
126133
mapKey,
127134
ExtendedAttributes.builder().put("childStr", "value").put("childLong", 1L).build())
@@ -136,6 +143,9 @@ void extendedAttributesUsage() {
136143
assertThat(extendedAttributes.get(longArrKey)).isEqualTo(Arrays.asList(1L, 2L));
137144
assertThat(extendedAttributes.get(booleanArrKey)).isEqualTo(Arrays.asList(true, false));
138145
assertThat(extendedAttributes.get(doubleArrKey)).isEqualTo(Arrays.asList(1.1, 2.2));
146+
assertThat((byte[]) extendedAttributes.get(bytesKey))
147+
.containsExactly((byte) 1, (byte) 2);
148+
assertThat(extendedAttributes.get(extendedValueArrayKey)).isEqualTo(heterogeneousValues);
139149
assertThat(extendedAttributes.get(mapKey))
140150
.isEqualTo(
141151
ExtendedAttributes.builder().put("childStr", "value").put("childLong", 1L).build());
@@ -148,7 +158,9 @@ void extendedAttributesUsage() {
148158
// acme.double_array(DOUBLE_ARRAY): [1.1, 2.2]
149159
// acme.long(LONG): 1
150160
// acme.long_array(LONG_ARRAY): [1, 2]
151-
// acme.map(EXTENDED_ATTRIBUTES): {childLong=1, childStr="value"}
161+
// acme.bytes(BYTE_ARRAY): [1, 2]
162+
// acme.value_array(VALUE_ARRAY): ["value", 1, true]
163+
// acme.map(MAP): {childLong=1, childStr="value"}
152164
// acme.string(STRING): value
153165
// acme.string_array(STRING_ARRAY): [value1, value2]
154166
extendedAttributes.forEach(
@@ -169,6 +181,8 @@ void logRecordBuilder_ExtendedAttributes() {
169181
.build();
170182

171183
Logger logger = loggerProvider.get("logger");
184+
List<Value<?>> heterogeneousValues =
185+
Arrays.asList(Value.of("value"), Value.of(1L), Value.of(true));
172186

173187
// Can set either standard or extended attributes on
174188
((ExtendedLogRecordBuilder) logger.logRecordBuilder())
@@ -181,6 +195,8 @@ void logRecordBuilder_ExtendedAttributes() {
181195
.setAttribute(longArrKey, Arrays.asList(1L, 2L))
182196
.setAttribute(booleanArrKey, Arrays.asList(true, false))
183197
.setAttribute(doubleArrKey, Arrays.asList(1.1, 2.2))
198+
.setAttribute(bytesKey, new byte[] {(byte) 1, (byte) 2})
199+
.setAttribute(extendedValueArrayKey, heterogeneousValues)
184200
.setAttribute(
185201
mapKey,
186202
ExtendedAttributes.builder().put("childStr", "value").put("childLong", 1L).build())
@@ -223,6 +239,8 @@ void logRecordBuilder_ExtendedAttributes() {
223239
.put(longArrKey, Arrays.asList(1L, 2L))
224240
.put(booleanArrKey, Arrays.asList(true, false))
225241
.put(doubleArrKey, Arrays.asList(1.1, 2.2))
242+
.put(bytesKey, new byte[] {(byte) 1, (byte) 2})
243+
.put(extendedValueArrayKey, heterogeneousValues)
226244
.put(
227245
mapKey,
228246
ExtendedAttributes.builder()

0 commit comments

Comments
 (0)