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

Implement span processor's OnEnding #5756

Open
wants to merge 16 commits into
base: main
Choose a base branch
from

Conversation

dmathieu
Copy link
Member

This allows span processors to implement the new, in development specification, OnEnding.

Spec PR: open-telemetry/opentelemetry-specification#4024

pkg: go.opentelemetry.io/otel/sdk/trace
cpu: Apple M1 Max
           │ bench-main  │         bench-branch          │
           │   sec/op    │   sec/op     vs base          │
SpanEnd-10   151.9n ± 9%   154.6n ± 8%  ~ (p=0.684 n=10)

           │ bench-main │          bench-branch          │
           │    B/op    │    B/op     vs base            │
SpanEnd-10   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=10) ¹
¹ all samples are equal

           │ bench-main │          bench-branch          │
           │ allocs/op  │ allocs/op   vs base            │
SpanEnd-10   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=10) ¹
¹ all samples are equal

Copy link

codecov bot commented Aug 29, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 84.5%. Comparing base (be328ac) to head (f4ae0f4).
Report is 1 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@          Coverage Diff          @@
##            main   #5756   +/-   ##
=====================================
  Coverage   84.5%   84.5%           
=====================================
  Files        272     272           
  Lines      22734   22746   +12     
=====================================
+ Hits       19226   19238   +12     
  Misses      3165    3165           
  Partials     343     343           

see 1 file with indirect coverage changes

@dmathieu dmathieu marked this pull request as ready for review August 29, 2024 08:51
Copy link
Contributor

@MrAlias MrAlias left a comment

Choose a reason for hiding this comment

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

This PR looks fine in general. However, this is adding a non-stable portion of the specification into this stable package. For that reason I'm blocking this PR. We do not want to add something we do not plan to support in the long term.

@dmathieu
Copy link
Member Author

Would you rather the interface be in sdk/internal/x?

@MrAlias
Copy link
Contributor

MrAlias commented Aug 29, 2024

Would you rather the interface be in sdk/internal/x?

SGTM

@dashpole
Copy link
Contributor

SGTM as well.

Copy link
Member

@pellared pellared left a comment

Choose a reason for hiding this comment

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

Could you make the docs better? Look at #5692 for reference.

sdk/internal/x/onending_processor.go Outdated Show resolved Hide resolved
sdk/trace/internal/x/onending_processor.go Outdated Show resolved Hide resolved
sdk/trace/internal/x/onending_processor.go Outdated Show resolved Hide resolved
sdk/trace/internal/x/onending_processor.go Show resolved Hide resolved
@dmathieu
Copy link
Member Author

@open-telemetry/go-approvers ping for review?

@dmathieu
Copy link
Member Author

@MrAlias since you requested changes, can you review/approve this PR?

oesp.OnEnding(s)
}
}
s.mu.Lock()
Copy link
Contributor

Choose a reason for hiding this comment

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

This acquires the lock twice. Can this be avoided instead?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not really, as we need to set the end time, and later on, mark the span as having ended.

Copy link
Contributor

Choose a reason for hiding this comment

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

This is going to impact the performance of users who are not using the experimental feature. We need to look into alternatives.

Copy link
Member Author

Choose a reason for hiding this comment

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

I've changed to only lock once if there are no onending processors.

sdk/trace/span.go Outdated Show resolved Hide resolved
@MrAlias
Copy link
Contributor

MrAlias commented Oct 2, 2024

The SDK MUST guarantee that the span can no longer be modified by any other thread before invoking OnEnding of the first SpanProcessor. From that point on, modifications are only allowed synchronously from within the invoked OnEnding callbacks.

This does not prevent the span from being modified by any other goroutine that holds a reference to the span.

@dmathieu
Copy link
Member Author

dmathieu commented Oct 3, 2024

I'm open to ideas about that.
@pellared wondered about this too: https://github.com/open-telemetry/opentelemetry-specification/pull/4024/files#r1656569090
However, the proposal to acquire a lock while we execute OnEnding doesn't seem like it would work. It would prevent modifications of the span within the processor, since they would wait for the lock too.

There are two other implementations so far:

@pellared pellared self-requested a review October 3, 2024 11:58
Copy link
Member

@pellared pellared left a comment

Choose a reason for hiding this comment

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

Not compliant with the spec per #5756 (comment). Maybe the spec should be revisited? If I understand correctly then this proposal is also not compliant with the spec.

@MrAlias
Copy link
Contributor

MrAlias commented Oct 3, 2024

I'm open to ideas about that. @pellared wondered about this too: https://github.com/open-telemetry/opentelemetry-specification/pull/4024/files#r1656569090 However, the proposal to acquire a lock while we execute OnEnding doesn't seem like it would work. It would prevent modifications of the span within the processor, since they would wait for the lock too.

There are two other implementations so far:

Have you looked into ending the original span, and passing a wrapped version of that span to the OnEnding methods? That wrapped version would report that it is still recording and be the sole way to modify the wrapped span.

@dmathieu
Copy link
Member Author

dmathieu commented Oct 3, 2024

If the original span is ended, the wrapper couldn't propagate changes to it.

@MrAlias
Copy link
Contributor

MrAlias commented Oct 3, 2024

If the original span is ended, the wrapper couldn't propagate changes to it.

If you are doing so from within the sdk/trace package you should be able to. You have access to all the internal fields and methods. Why wouldn't that work?

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.

4 participants