Skip to content
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

Enforce max span attribute size #4335

Merged
merged 13 commits into from
Jan 2, 2025
Merged

Enforce max span attribute size #4335

merged 13 commits into from
Jan 2, 2025

Conversation

ie-pham
Copy link
Contributor

@ie-pham ie-pham commented Nov 17, 2024

What this PR does: Add config for max_span_attr_size to enforce the max size a span attribute can be. If a span contains an attribute with either key or value over the limit is sent to Tempo, the attribute key/value will be truncated.

Which issue(s) this PR fixes:
Fixes #3985

benchmarks

4 traces, 300 batches and 5000 spans each run

with adding "_truncated"

                 │ before.out  │        after_add_truncated.out         │
                 │   sec/op    │   sec/op      vs base                  │
TestsByRequestID   402.3m ± 7%   2384.8m ± 10%  +492.83% (p=0.000 n=10)

without adding "_truncated" to truncated attribute values

                 │  before.out  │         after-notruncate.out         │
                 │    sec/op    │    sec/op     vs base                │
TestsByRequestID   357.1m ± 52%   594.0m ± 34%  +66.33% (p=0.001 n=10)

                 │  before.out  │      after-notruncate.out      │
                 │     B/op     │     B/op      vs base          │
TestsByRequestID   58.71Mi ± 0%   58.71Mi ± 0%  ~ (p=1.000 n=10)

                 │ before.out  │      after-notruncate.out       │
                 │  allocs/op  │  allocs/op   vs base            │
TestsByRequestID   5.100k ± 0%   5.100k ± 0%  ~ (p=1.000 n=10) ¹

Checklist

  • Tests updated
  • Documentation added
  • CHANGELOG.md updated - the order of entries should be [CHANGE], [FEATURE], [ENHANCEMENT], [BUGFIX]

@ie-pham ie-pham changed the title Enforce max span attribute size Enforce max span attribute size [wip] Nov 18, 2024

func spanContainsAttributeTooLarge(span *v1.Span, maxAttrSize int) bool {
for _, attr := range span.Attributes {
if len(attr.Key) > maxAttrSize || attr.Value.Size() > maxAttrSize {
Copy link
Contributor

Choose a reason for hiding this comment

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

Good call, checking the attribute name. I'm wondering if this calculation should be against the total Key.Size() + Value.Size()?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

if key is max/2 and value is max/2, does it still cause a problem?


for _, b := range batches {
spansByILS := make(map[uint32]*v1.ScopeSpans)

for _, ils := range b.ScopeSpans {
for _, span := range ils.Spans {
// drop spans with attributes that are too large
if spanContainsAttributeTooLarge(span, maxSpanAttrSize) {
Copy link
Contributor

Choose a reason for hiding this comment

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

If there is a way we could drop only the attribute that seems better than dropping the span (preserve as much information as possible). It doesn't fit as easily within our current metrics/logs though.

@@ -229,6 +229,10 @@ distributor:
# instruct the client how to retry.
[retry_after_on_resource_exhausted: <duration> | default = '0' ]

# Optional
# Configures the max size a span attribute can be. Any span with at least one attribute over this limit would be discarded with reason "attribute_too_large"
[max_span_attr_size: <int> | default = '10000']
Copy link
Contributor

Choose a reason for hiding this comment

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

Thinking if this should be max_attr_bytes to follow the pattern of other limits, and should it also apply to resource/event/link attributes?

Copy link
Contributor

@knylander-grafana knylander-grafana left a comment

Choose a reason for hiding this comment

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

Thank you for adding docs :)

@ie-pham
Copy link
Contributor Author

ie-pham commented Nov 22, 2024

benchmark updated but not looking too good :/

@ie-pham ie-pham changed the title Enforce max span attribute size [wip] Enforce max span attribute size Nov 27, 2024
modules/distributor/distributor.go Outdated Show resolved Hide resolved
modules/distributor/distributor.go Outdated Show resolved Hide resolved
modules/distributor/distributor.go Outdated Show resolved Hide resolved
modules/distributor/distributor.go Outdated Show resolved Hide resolved
@ie-pham ie-pham requested a review from joe-elliott January 2, 2025 20:20
if err != nil {
overrides.RecordDiscardedSpans(spanCount, reasonInternalError, userID)
logDiscardedResourceSpans(batches, userID, &d.cfg.LogDiscardedSpans, d.logger)
return nil, err
}

if truncatedAttributeCount > 0 {
level.Warn(d.logger).Log("msg", fmt.Sprintf("truncated %d resource/span attributes when adding spans for tenant %s", truncatedAttributeCount, userID))
Copy link
Member

@joe-elliott joe-elliott Jan 2, 2025

Choose a reason for hiding this comment

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

error message doesn't tell us anything that the is not already in the metric. remove? if we add some details that make it worth keeping i think we should consider dropping to debug b/c this could get spammy

Copy link
Member

@joe-elliott joe-elliott left a comment

Choose a reason for hiding this comment

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

one concern about the logged message, but other than that i think it's good

@ie-pham ie-pham merged commit d382b58 into grafana:main Jan 2, 2025
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add a limit that caps the maximum allowed size of an attribute
4 participants