-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Implement span processor's OnEnding #5756
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
Changes from 8 commits
440d0b1
999175e
fb6bba5
5b53cc5
34a68be
793d5fd
3613902
6c04318
675b6f4
67a67f0
c7fe407
27565c9
2537c50
80c873a
43e3438
f4ae0f4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| # Experimental Features | ||
|
|
||
| The Trace SDK contains features that have not yet stabilized. | ||
| These features are added to the OpenTelemetry Go Trace SDK prior to | ||
| stabilization so that users can start experimenting with them and provide | ||
| feedback. | ||
|
|
||
| These feature may change in backwards incompatible ways as feedback is applied. | ||
| See the [Compatibility and Stability](#compatibility-and-stability) section for | ||
| more information. | ||
|
|
||
| ## Features | ||
|
|
||
| - [OnEnding Processor](#onending-processor) | ||
|
|
||
| ### OnEnding Processor | ||
|
|
||
| Processor implementations sometimes want to be able to modify a span after it | ||
| ended, but before it becomes immutable. | ||
| A processor that implements the `OnEnding` method can use that callback to | ||
| perform such modifications. | ||
|
|
||
| It can be used to implement tail-based sampling for example. | ||
|
|
||
| ## Compatibility and Stability | ||
|
|
||
| Experimental features do not fall within the scope of the OpenTelemetry Go | ||
| versioning and stability [policy](../../../../VERSIONING.md). | ||
| These features may be removed or modified in successive version releases, | ||
| including patch versions. | ||
|
|
||
| When an experimental feature is promoted to a stable feature, a migration path | ||
| will be included in the changelog entry of the release. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| // Copyright The OpenTelemetry Authors | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| package x // import "go.opentelemetry.io/otel/sdk/trace/internal/x" | ||
|
|
||
| import "go.opentelemetry.io/otel/trace" | ||
|
|
||
| // OnEndingSpanProcessor represents span processors that allow mutating spans | ||
| // just before they are ended and made immutable. | ||
| // | ||
| // This is useful for custom processor implementations that want to mutate | ||
| // spans when they are finished, and before they are made immutable, such as | ||
| // implementing tail-based sampling. | ||
| type OnEndingSpanProcessor interface { | ||
| // OnEnding is called while the span is finished, and spans are still | ||
| // mutable. | ||
| // | ||
| // This method is called synchronously during the span's End operation, | ||
| // therefore it should not block or throw an exception. | ||
| // If multiple [SpanProcessor] are registered, their OnEnding callbacks are | ||
| // invoked in the order they have been registered. | ||
| // | ||
| // [SpanProcessor]: https://pkg.go.dev/go.opentelemetry.io/otel/sdk/trace#SpanProcessor | ||
| OnEnding(trace.Span) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,6 +20,7 @@ import ( | |
| "go.opentelemetry.io/otel/internal/global" | ||
| "go.opentelemetry.io/otel/sdk/instrumentation" | ||
| "go.opentelemetry.io/otel/sdk/resource" | ||
| "go.opentelemetry.io/otel/sdk/trace/internal/x" | ||
| semconv "go.opentelemetry.io/otel/semconv/v1.26.0" | ||
| "go.opentelemetry.io/otel/trace" | ||
| "go.opentelemetry.io/otel/trace/embedded" | ||
|
|
@@ -120,6 +121,9 @@ type recordingSpan struct { | |
| // value of time.Time until the span is ended. | ||
| endTime time.Time | ||
|
|
||
| // hasEnded records whether the span is fully ended. | ||
| hasEnded bool | ||
|
|
||
| // status is the status of this span. | ||
| status Status | ||
|
|
||
|
|
@@ -171,10 +175,8 @@ func (s *recordingSpan) IsRecording() bool { | |
| if s == nil { | ||
| return false | ||
| } | ||
| s.mu.Lock() | ||
| defer s.mu.Unlock() | ||
|
|
||
| return s.endTime.IsZero() | ||
| return !s.hasEnded | ||
dmathieu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| // SetStatus sets the status of the Span in the form of a code and a | ||
|
|
@@ -417,7 +419,6 @@ func (s *recordingSpan) End(options ...trace.SpanEndOption) { | |
| } | ||
|
|
||
| s.mu.Lock() | ||
| // Setting endTime to non-zero marks the span as ended and not recording. | ||
| if config.Timestamp().IsZero() { | ||
| s.endTime = et | ||
| } else { | ||
|
|
@@ -426,6 +427,15 @@ func (s *recordingSpan) End(options ...trace.SpanEndOption) { | |
| s.mu.Unlock() | ||
|
|
||
| sps := s.tracer.provider.getSpanProcessors() | ||
| for _, sp := range sps { | ||
| if oesp, ok := sp.sp.(x.OnEndingSpanProcessor); ok { | ||
| oesp.OnEnding(s) | ||
| } | ||
| } | ||
dmathieu marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| s.mu.Lock() | ||
|
||
| s.hasEnded = true | ||
| s.mu.Unlock() | ||
|
|
||
| if len(sps) == 0 { | ||
| return | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.