-
Notifications
You must be signed in to change notification settings - Fork 1k
Extend Attribute API with optional AttributesLimits, including count, length, and depth #8656
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
jack-berg
wants to merge
7
commits into
open-telemetry:main
Choose a base branch
from
jack-berg:api-attribute-limits
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+1,236
−368
Draft
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
21ae409
Add attribute limits to opentelemetry-api
jack-berg 1967cc5
Rename attribute limits to better match spec, add depth limit
jack-berg 4e1085d
Merge branch 'main' of https://github.com/open-telemetry/opentelemetr…
jack-berg 7b2d12d
Extend attributes benchmark
jack-berg 94efe28
Fix build
jack-berg 0be54ba
Cleanup, improve coverage
jack-berg 4c65a22
Remove since, add TODOs
jack-berg File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
91 changes: 91 additions & 0 deletions
91
api/all/src/main/java/io/opentelemetry/api/common/AttributeLimits.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| /* | ||
| * Copyright The OpenTelemetry Authors | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| package io.opentelemetry.api.common; | ||
|
|
||
| import com.google.auto.value.AutoValue; | ||
| import javax.annotation.concurrent.Immutable; | ||
|
|
||
| /** | ||
| * Limits enforced by an {@link AttributesBuilder} created via {@link | ||
| * Attributes#builder(AttributeLimits)}. | ||
| * | ||
| * <p>A builder configured with limits applies last-value-wins semantics on {@link | ||
| * AttributesBuilder#put put} (by {@link AttributeKey#getKey() key name}, regardless of {@link | ||
| * AttributeType}), truncates over-length string and byte values, replaces over-nested array and map | ||
| * values with empty containers, and drops entries added beyond the configured count limit. This | ||
| * differs from the default builder ({@link Attributes#builder()}) which defers de-duplication to | ||
| * {@link AttributesBuilder#build()} and applies no truncation, depth, or count limits. | ||
| * | ||
| * <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. | ||
| */ | ||
| public abstract class AttributeLimits { | ||
|
|
||
| private static final AttributeLimits NO_LIMITS = new AttributeLimitsBuilder().build(); | ||
|
|
||
| /** Returns an {@link AttributeLimits} that imposes no count, length, or depth limits. */ | ||
| public static AttributeLimits noLimits() { | ||
| return NO_LIMITS; | ||
| } | ||
|
|
||
| /** Returns a new {@link AttributeLimitsBuilder} initialized to {@link #noLimits()}. */ | ||
| public static AttributeLimitsBuilder builder() { | ||
| return new AttributeLimitsBuilder(); | ||
| } | ||
|
|
||
| static AttributeLimits create(int countLimit, int valueLengthLimit, int valueDepthLimit) { | ||
| return new AutoValue_AttributeLimits_AttributeLimitsValue( | ||
| 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(); | ||
|
|
||
| /** | ||
| * Returns an {@link AttributeLimitsBuilder} initialized to the same property values as this | ||
| * instance. | ||
| */ | ||
| public AttributeLimitsBuilder toBuilder() { | ||
| return builder() | ||
| .setCountLimit(getCountLimit()) | ||
| .setValueLengthLimit(getValueLengthLimit()) | ||
| .setValueDepthLimit(getValueDepthLimit()); | ||
| } | ||
|
|
||
| @AutoValue | ||
| @Immutable | ||
| abstract static class AttributeLimitsValue extends AttributeLimits {} | ||
| } |
73 changes: 73 additions & 0 deletions
73
api/all/src/main/java/io/opentelemetry/api/common/AttributeLimitsBuilder.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| /* | ||
| * Copyright The OpenTelemetry Authors | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| package io.opentelemetry.api.common; | ||
|
|
||
| import static io.opentelemetry.api.internal.Utils.checkArgument; | ||
|
|
||
| /** Builder for {@link AttributeLimits}. */ | ||
| public final class AttributeLimitsBuilder { | ||
|
|
||
| private int countLimit = Integer.MAX_VALUE; | ||
| private int valueLengthLimit = Integer.MAX_VALUE; | ||
|
|
||
| // TODO(jack-berg): before merging, decide whether to default this to 64 (spec-recommended, | ||
| // matches System.Text.Json, provides stack safety when callers set a length limit but forget | ||
| // depth). Since depth is net new we can pick a non-infinite default without breaking anyone; | ||
| // count and length must stay at Integer.MAX_VALUE for back-compat. Would diverge builder | ||
| // defaults from AttributeLimits.noLimits(). | ||
| private int valueDepthLimit = Integer.MAX_VALUE; | ||
|
|
||
| AttributeLimitsBuilder() {} | ||
|
|
||
| /** | ||
| * Sets 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. | ||
| * | ||
| * @param countLimit non-negative maximum, or {@link Integer#MAX_VALUE} for no limit | ||
| * @throws IllegalArgumentException if {@code countLimit} is negative | ||
| */ | ||
| public AttributeLimitsBuilder setCountLimit(int countLimit) { | ||
| checkArgument(countLimit >= 0, "countLimit must be non-negative"); | ||
| this.countLimit = countLimit; | ||
| return this; | ||
| } | ||
|
|
||
| /** | ||
| * Sets the maximum length for string and byte-array attribute values ({@code | ||
| * AttributeValueLengthLimit}). Applies recursively to string and byte-array values within {@link | ||
| * Value}-typed and array attributes. | ||
| * | ||
| * @param valueLengthLimit non-negative maximum, or {@link Integer#MAX_VALUE} for no limit | ||
| * @throws IllegalArgumentException if {@code valueLengthLimit} is negative | ||
| */ | ||
| public AttributeLimitsBuilder setValueLengthLimit(int valueLengthLimit) { | ||
| checkArgument(valueLengthLimit >= 0, "valueLengthLimit must be non-negative"); | ||
| this.valueLengthLimit = valueLengthLimit; | ||
| return this; | ||
| } | ||
|
|
||
| /** | ||
| * Sets the maximum nesting depth for array and map attribute values ({@code | ||
| * AttributeValueDepthLimit}). Depth is 1-indexed (top-level attribute value = depth 1); the limit | ||
| * must therefore be at least 1. Arrays and maps at a depth greater than the limit are replaced | ||
| * with an empty container of the same shape. | ||
| * | ||
| * @param valueDepthLimit maximum nesting depth, minimum 1, or {@link Integer#MAX_VALUE} for no | ||
| * limit | ||
| * @throws IllegalArgumentException if {@code valueDepthLimit} is less than 1 | ||
| */ | ||
| public AttributeLimitsBuilder setValueDepthLimit(int valueDepthLimit) { | ||
| checkArgument(valueDepthLimit >= 1, "valueDepthLimit must be at least 1"); | ||
| this.valueDepthLimit = valueDepthLimit; | ||
| return this; | ||
| } | ||
|
|
||
| /** Builds the {@link AttributeLimits}. */ | ||
| public AttributeLimits build() { | ||
| return AttributeLimits.create(countLimit, valueLengthLimit, valueDepthLimit); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reminder to self