Skip to content

feat(span_processor): add on_ending callback #3010

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

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

Conversation

paullegranddc
Copy link
Contributor

@paullegranddc paullegranddc commented May 30, 2025

Issues

SpanProcessor API refactor #2940

Changes

Add on_ending method on thr SpanProcessor trait. Spec link

This method is called during span ending, before on_end. it is given a mutable span and is very useful to implement obfuscation for instance.
It makes possible the use cases that were the motivation for passing mutable data to on_end while respecting the spec.

The feature is still marked as Development in the spec so it's kept behind an experimental feature flag.

This PR cherry picked from #2962

Merge requirement checklist

  • CONTRIBUTING guidelines followed
  • Unit tests added/updated (if applicable)
  • Appropriate CHANGELOG.md files updated for non-trivial, user-facing changes
  • Changes in public API reviewed (if applicable)

@paullegranddc paullegranddc requested a review from a team as a code owner May 30, 2025 11:59
Copy link

codecov bot commented May 30, 2025

Codecov Report

Attention: Patch coverage is 90.16393% with 6 lines in your changes missing coverage. Please review.

Project coverage is 81.1%. Comparing base (8882c31) to head (574242d).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
opentelemetry-sdk/src/trace/span.rs 89.2% 6 Missing ⚠️
Additional details and impacted files
@@          Coverage Diff          @@
##            main   #3010   +/-   ##
=====================================
  Coverage   81.0%   81.1%           
=====================================
  Files        126     126           
  Lines      24753   24807   +54     
=====================================
+ Hits       20070   20126   +56     
+ Misses      4683    4681    -2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

};
for KeyValue { key, value, .. } in span.attributes {
if let Some(redacted_uri) = obfuscate_http_auth_url(value.as_str().as_ref()) {
obfuscated_attributes.push((key.clone(), KeyValue::new(key.clone(), redacted_uri)));
Copy link
Member

Choose a reason for hiding this comment

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

mm...doesn't looks like the span is mutated with the updated attribute?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I forgot to add the add_attribute call at the end 🙈

@@ -105,6 +105,49 @@ async fn router(
response
}

fn obfuscate_http_auth_url(s: &str) -> Option<String> {
Copy link
Member

Choose a reason for hiding this comment

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

lets use a simpler example to show the purpose of on_ending?
eg : checking for a specific attribute and if not present, add it.

/// `on_ending` is called when a `Span` is ending. The end timestamp has already
/// been computed.
/// This method is called synchronously within the `Span::end` API, therefore it
/// should not block or throw an exception.
Copy link
Member

Choose a reason for hiding this comment

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

nit: remove the "throw exception" part as it won't fit Rust...

/// in the order the span processors have been registered, and mutations to the span
/// will be visible to the next processor.
///
/// The tracer will call `on_ending` for all span processors before calling `on_end`
Copy link
Member

Choose a reason for hiding this comment

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

nit: skip details about who is calling. It's good enough to mention that ending is called before end.
Also mention the difference between overriding on_start vs on_ending, as on_start only has those span attributes provide at span_cration time.

.with_span_processor(SecondProcessor)
.with_simple_exporter(exporter)
.build();
provider.tracer("test").start("test_span");
Copy link
Member

Choose a reason for hiding this comment

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

test suggestion:
start the span with some attributes.
then add few more attributes to it.
validate that on_start sees only those attributes added at start time.
validate that on_ending sees attributes added at start time, attributes added via span.setattribute, attributes added by any previous processor.

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.

3 participants