Skip to content
Closed
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 @@ -5,8 +5,10 @@

package io.opentelemetry.api.common;

import static io.opentelemetry.api.common.ArrayBackedAttributes.sortAndFilterToAttributes;
import static io.opentelemetry.api.internal.ArrayBackedAttributes.sortAndFilterToAttributes;

import io.opentelemetry.api.internal.ArrayBackedAttributes;
import io.opentelemetry.api.internal.ArrayBackedAttributesBuilder;
import java.util.Map;
import java.util.function.BiConsumer;
import javax.annotation.Nullable;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

package io.opentelemetry.api.common;

import static io.opentelemetry.api.common.ArrayBackedAttributesBuilder.toList;
import static io.opentelemetry.api.common.AttributeKey.booleanArrayKey;
import static io.opentelemetry.api.common.AttributeKey.booleanKey;
import static io.opentelemetry.api.common.AttributeKey.doubleArrayKey;
Expand Down Expand Up @@ -166,7 +165,11 @@ default AttributesBuilder put(String key, long... value) {
if (value == null) {
return this;
}
return put(longArrayKey(key), toList(value));
Long[] boxed = new Long[value.length];
for (int i = 0; i < value.length; i++) {
boxed[i] = value[i];
}
return put(longArrayKey(key), Arrays.asList(boxed));
}

/**
Expand All @@ -181,7 +184,11 @@ default AttributesBuilder put(String key, double... value) {
if (value == null) {
return this;
}
return put(doubleArrayKey(key), toList(value));
Double[] boxed = new Double[value.length];
for (int i = 0; i < value.length; i++) {
boxed[i] = value[i];
}
return put(doubleArrayKey(key), Arrays.asList(boxed));
}

/**
Expand All @@ -196,7 +203,11 @@ default AttributesBuilder put(String key, boolean... value) {
if (value == null) {
return this;
}
return put(booleanArrayKey(key), toList(value));
Boolean[] boxed = new Boolean[value.length];
for (int i = 0; i < value.length; i++) {
boxed[i] = value[i];
}
return put(booleanArrayKey(key), Arrays.asList(boxed));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,37 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.api.common;
package io.opentelemetry.api.internal;

import io.opentelemetry.api.internal.ImmutableKeyValuePairs;
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.api.common.ValueType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;

/**
* Default {@link Attributes} implementation. Not intended for external use.
*
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
* at any time.
*/
@Immutable
final class ArrayBackedAttributes extends ImmutableKeyValuePairs<AttributeKey<?>, Object>
public final class ArrayBackedAttributes extends ImmutableKeyValuePairs<AttributeKey<?>, Object>
implements Attributes {

// We only compare the key name, not type, when constructing, to allow deduping keys with the
// same name but different type.
private static final Comparator<AttributeKey<?>> KEY_COMPARATOR_FOR_CONSTRUCTION =
Comparator.comparing(AttributeKey::getKey);

static final Attributes EMPTY = Attributes.builder().build();
public static final Attributes EMPTY = Attributes.builder().build();

private ArrayBackedAttributes(Object[] data, Comparator<AttributeKey<?>> keyComparator) {
super(data, keyComparator);
Expand All @@ -34,7 +45,8 @@ private ArrayBackedAttributes(Object[] data, Comparator<AttributeKey<?>> keyComp
*
* @param data the raw data
*/
ArrayBackedAttributes(Object[] data) {
@SuppressWarnings("AvoidObjectArrays")
public ArrayBackedAttributes(Object[] data) {
super(data);
}

Expand Down Expand Up @@ -158,7 +170,7 @@ private static Value<?> asValue(AttributeType type, Object value) {
return null;
}

static Attributes sortAndFilterToAttributes(Object... data) {
public static Attributes sortAndFilterToAttributes(Object... data) {
// null out any empty keys or keys with null values
// so they will then be removed by the sortAndFilter method.
for (int i = 0; i < data.length; i += 2) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.api.common;
package io.opentelemetry.api.internal;

import static io.opentelemetry.api.common.AttributeKey.booleanArrayKey;
import static io.opentelemetry.api.common.AttributeKey.booleanKey;
Expand All @@ -14,20 +14,37 @@
import static io.opentelemetry.api.common.AttributeKey.stringArrayKey;
import static io.opentelemetry.api.common.AttributeKey.stringKey;

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.api.common.ValueType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import javax.annotation.Nullable;

class ArrayBackedAttributesBuilder implements AttributesBuilder {
private final List<Object> data;
/**
* Default {@link AttributesBuilder} implementation. Storage is a flat {@link List} of alternating
* {@link AttributeKey}/value pairs; {@link #build()} sorts and de-dupes on demand.
*
* <p>Subclasses may override {@link #addPair(AttributeKey, Object)} to intercept every entry going
* into storage (used by SDK code to enforce attribute limits) and {@link #removeIf(Predicate)} to
* observe removals.
*
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
* at any time.
*/
public class ArrayBackedAttributesBuilder implements AttributesBuilder {

protected final List<Object> data;

ArrayBackedAttributesBuilder() {
data = new ArrayList<>();
public ArrayBackedAttributesBuilder() {
this.data = new ArrayList<>();
}

ArrayBackedAttributesBuilder(List<Object> data) {
public ArrayBackedAttributesBuilder(List<Object> data) {
this.data = data;
}

Expand Down Expand Up @@ -55,9 +72,17 @@ public <T> AttributesBuilder put(AttributeKey<T> key, @Nullable T value) {
putValue(key, (Value<?>) value);
return this;
}
addPair(key, value);
return this;
}

/**
* Extension point: append {@code key}/{@code value} to storage. Default appends without further
* processing.
*/
protected void addPair(AttributeKey<?> key, Object value) {
data.add(key);
data.add(value);
return this;
}

@SuppressWarnings("unchecked")
Expand Down Expand Up @@ -111,8 +136,7 @@ private void putValue(AttributeKey<?> key, Value<?> valueObj) {
return;
case VALUE:
// Not coercible (empty, non-homogeneous, or unsupported element type)
data.add(key);
data.add(valueObj);
addPair(key, valueObj);
return;
default:
throw new IllegalArgumentException("Unexpected array attribute type: " + attributeType);
Expand All @@ -121,8 +145,7 @@ private void putValue(AttributeKey<?> key, Value<?> valueObj) {
case BYTES:
case EMPTY:
// Keep as VALUE type
data.add(key);
data.add(valueObj);
addPair(key, valueObj);
}
}

Expand Down Expand Up @@ -195,28 +218,4 @@ public AttributesBuilder removeIf(Predicate<AttributeKey<?>> predicate) {
}
return this;
}

static List<Double> toList(double... values) {
Double[] boxed = new Double[values.length];
for (int i = 0; i < values.length; i++) {
boxed[i] = values[i];
}
return Arrays.asList(boxed);
}

static List<Long> toList(long... values) {
Long[] boxed = new Long[values.length];
for (int i = 0; i < values.length; i++) {
boxed[i] = values[i];
}
return Arrays.asList(boxed);
}

static List<Boolean> toList(boolean... values) {
Boolean[] boxed = new Boolean[values.length];
for (int i = 0; i < values.length; i++) {
boxed[i] = values[i];
}
return Arrays.asList(boxed);
}
}
33 changes: 32 additions & 1 deletion docs/apidiffs/current_vs_latest/opentelemetry-sdk-common.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,33 @@
Comparing source compatibility of opentelemetry-sdk-common-1.65.0-SNAPSHOT.jar against opentelemetry-sdk-common-1.64.0.jar
No changes.
+++ NEW CLASS: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.common.AttributeLimits (not serializable)
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
+++ NEW SUPERCLASS: java.lang.Object
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.AttributeLimitsBuilder builder()
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) int getCountLimit()
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) int getValueDepthLimit()
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) int getValueLengthLimit()
+++ NEW CLASS: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.common.AttributeLimitsBuilder (not serializable)
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
+++ NEW SUPERCLASS: java.lang.Object
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.AttributeLimits build()
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.AttributeLimitsBuilder setCountLimit(int)
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.AttributeLimitsBuilder setValueDepthLimit(int)
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.AttributeLimitsBuilder setValueLengthLimit(int)
+++ NEW CLASS: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.common.LimitedAttributes (not serializable)
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
+++ NEW INTERFACE: io.opentelemetry.api.common.Attributes
+++ NEW INTERFACE: io.opentelemetry.api.common.AttributesBuilder
+++ NEW SUPERCLASS: io.opentelemetry.api.internal.ArrayBackedAttributesBuilder
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.api.common.Attributes applyLimits(io.opentelemetry.sdk.common.AttributeLimits, io.opentelemetry.api.common.Attributes)
+++ NEW METHOD: PUBLIC(+) java.util.Map<io.opentelemetry.api.common.AttributeKey<?>,java.lang.Object> asMap()
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.common.Attributes build()
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.common.LimitedAttributes builder(io.opentelemetry.sdk.common.AttributeLimits)
+++ NEW METHOD: PUBLIC(+) void forEach(java.util.function.BiConsumer<? super io.opentelemetry.api.common.AttributeKey<? super ?>,? super java.lang.Object>)
+++ NEW METHOD: PUBLIC(+) java.lang.Object get(io.opentelemetry.api.common.AttributeKey<T>)
+++ NEW ANNOTATION: javax.annotation.Nullable
GENERIC TEMPLATES: +++ T:java.lang.Object
+++ NEW METHOD: PUBLIC(+) int getTotalAddedValues()
+++ NEW METHOD: PUBLIC(+) boolean isEmpty()
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.common.AttributesBuilder removeIf(java.util.function.Predicate<io.opentelemetry.api.common.AttributeKey<?>>)
+++ NEW METHOD: PUBLIC(+) int size()
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.api.common.AttributesBuilder toBuilder()
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.common;

import com.google.auto.value.AutoValue;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.common.Value;
import javax.annotation.concurrent.Immutable;

/**
* Limits enforced by an {@link AttributesBuilder} created via {@link
* LimitedAttributes#builder(AttributeLimits)}.
*
* <p>The three parameters correspond to the {@code AttributeCountLimit}, {@code
* AttributeValueLengthLimit}, and {@code AttributeValueDepthLimit} configurable parameters in the
* OpenTelemetry <a
* href="https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/common#attribute-limits">common
* attribute-limits</a> specification.
*/
@AutoValue
@Immutable
public abstract class AttributeLimits {

/** Returns a new {@link AttributeLimitsBuilder} initialized to spec-recommended defaults. */
public static AttributeLimitsBuilder builder() {
return new AttributeLimitsBuilder();
}

static AttributeLimits create(int countLimit, int valueLengthLimit, int valueDepthLimit) {
return new AutoValue_AttributeLimits(countLimit, valueLengthLimit, valueDepthLimit);
}

AttributeLimits() {}

/**
* Returns the maximum number of unique attribute keys ({@code AttributeCountLimit}). Additional
* entries with new key names are dropped once the limit is reached. Overwrites of existing keys
* do not consume against the limit.
*
* <p>{@link Integer#MAX_VALUE} means no count limit.
*/
public abstract int getCountLimit();

/**
* Returns the maximum length for string and byte-array attribute values ({@code
* AttributeValueLengthLimit}). Longer values are truncated to this length. Applies recursively to
* string and byte-array values within {@link Value}-typed and array attributes.
*
* <p>{@link Integer#MAX_VALUE} means no length limit.
*/
public abstract int getValueLengthLimit();

/**
* Returns the maximum nesting depth for array and map attribute values ({@code
* AttributeValueDepthLimit}). Depth counting starts at 1 for the top-level attribute value and
* increments when descending into array elements or map values. Arrays and maps at a depth
* greater than this limit are replaced with an empty container of the same shape.
*
* <p>{@link Integer#MAX_VALUE} means no depth limit.
*/
public abstract int getValueDepthLimit();
}
Loading
Loading