Skip to content

Commit 77ae46c

Browse files
committed
Revert "feat: Add Suppression flag to context (open-telemetry#2821)"
This reverts commit 2971467.
1 parent 24b92cb commit 77ae46c

File tree

5 files changed

+6
-334
lines changed

5 files changed

+6
-334
lines changed

opentelemetry/CHANGELOG.md

-23
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,6 @@
22

33
## vNext
44

5-
[#2821](https://github.com/open-telemetry/opentelemetry-rust/pull/2821) Context
6-
based suppression capabilities added: Added the ability to prevent recursive
7-
telemetry generation through new context-based suppression mechanisms. This
8-
feature helps prevent feedback loops and excessive telemetry when OpenTelemetry
9-
components perform their own operations.
10-
11-
New methods added to `Context`:
12-
13-
- `is_telemetry_suppressed()` - Checks if telemetry is suppressed in this
14-
context
15-
- `with_telemetry_suppressed()` - Creates a new context with telemetry
16-
suppression enabled
17-
- `is_current_telemetry_suppressed()` - Efficiently checks if the current thread's context
18-
has telemetry suppressed
19-
- `enter_telemetry_suppressed_scope()` - Convenience method to enter a scope where telemetry is
20-
suppressed
21-
22-
These methods allow SDK components, exporters, and processors to temporarily
23-
disable telemetry generation during their internal operations, ensuring more
24-
predictable and efficient observability pipelines.
25-
26-
- re-export `tracing` for `internal-logs` feature to remove the need of adding `tracing` as a dependency
27-
285
## 0.29.1
296

307
Release 2025-Apr-01

opentelemetry/Cargo.toml

-4
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,6 @@ name = "context_attach"
6666
harness = false
6767
required-features = ["tracing"]
6868

69-
[[bench]]
70-
name = "context_suppression"
71-
harness = false
72-
7369
[[bench]]
7470
name = "baggage"
7571
harness = false

opentelemetry/benches/context_suppression.rs

-65
This file was deleted.

opentelemetry/src/context.rs

+4-240
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ pub struct Context {
9797
#[cfg(feature = "trace")]
9898
pub(crate) span: Option<Arc<SynchronizedSpan>>,
9999
entries: Option<Arc<EntryMap>>,
100-
suppress_telemetry: bool,
101100
}
102101

103102
type EntryMap = HashMap<TypeId, Arc<dyn Any + Sync + Send>, BuildHasherDefault<IdHasher>>;
@@ -245,7 +244,6 @@ impl Context {
245244
entries,
246245
#[cfg(feature = "trace")]
247246
span: self.span.clone(),
248-
suppress_telemetry: self.suppress_telemetry,
249247
}
250248
}
251249

@@ -332,97 +330,19 @@ impl Context {
332330
}
333331
}
334332

335-
/// Returns whether telemetry is suppressed in this context.
336-
#[inline]
337-
pub fn is_telemetry_suppressed(&self) -> bool {
338-
self.suppress_telemetry
339-
}
340-
341-
/// Returns a new context with telemetry suppression enabled.
342-
pub fn with_telemetry_suppressed(&self) -> Self {
343-
Context {
344-
entries: self.entries.clone(),
345-
#[cfg(feature = "trace")]
346-
span: self.span.clone(),
347-
suppress_telemetry: true,
348-
}
349-
}
350-
351-
/// Enters a scope where telemetry is suppressed.
352-
///
353-
/// This method is specifically designed for OpenTelemetry components (like Exporters,
354-
/// Processors etc.) to prevent generating recursive or self-referential
355-
/// telemetry data when performing their own operations.
356-
///
357-
/// Without suppression, we have a telemetry-induced-telemetry situation
358-
/// where, operations like exporting telemetry could generate new telemetry
359-
/// about the export process itself, potentially causing:
360-
/// - Infinite telemetry feedback loops
361-
/// - Excessive resource consumption
362-
///
363-
/// This method:
364-
/// 1. Takes the current context
365-
/// 2. Creates a new context from current, with `suppress_telemetry` set to `true`
366-
/// 3. Attaches it to the current thread
367-
/// 4. Returns a guard that restores the previous context when dropped
368-
///
369-
/// OTel SDK components would check `is_current_telemetry_suppressed()` before
370-
/// generating new telemetry, but not end users.
371-
///
372-
/// # Examples
373-
///
374-
/// ```
375-
/// use opentelemetry::Context;
376-
///
377-
/// // Example: Inside an exporter's implementation
378-
/// fn example_export_function() {
379-
/// // Prevent telemetry-generating operations from creating more telemetry
380-
/// let _guard = Context::enter_telemetry_suppressed_scope();
381-
///
382-
/// // Verify suppression is active
383-
/// assert_eq!(Context::is_current_telemetry_suppressed(), true);
384-
///
385-
/// // Here you would normally perform operations that might generate telemetry
386-
/// // but now they won't because the context has suppression enabled
387-
/// }
388-
///
389-
/// // Demonstrate the function
390-
/// example_export_function();
391-
/// ```
392-
pub fn enter_telemetry_suppressed_scope() -> ContextGuard {
393-
Self::map_current(|cx| cx.with_telemetry_suppressed()).attach()
394-
}
395-
396-
/// Returns whether telemetry is suppressed in the current context.
397-
///
398-
/// This method is used by OpenTelemetry components to determine whether they should
399-
/// generate new telemetry in the current execution context. It provides a performant
400-
/// way to check the suppression state.
401-
///
402-
/// End-users generally should not use this method directly, as it is primarily intended for
403-
/// OpenTelemetry SDK components.
404-
///
405-
///
406-
#[inline]
407-
pub fn is_current_telemetry_suppressed() -> bool {
408-
Self::map_current(|cx| cx.is_telemetry_suppressed())
409-
}
410-
411333
#[cfg(feature = "trace")]
412334
pub(crate) fn current_with_synchronized_span(value: SynchronizedSpan) -> Self {
413-
Self::map_current(|cx| Context {
335+
Context {
414336
span: Some(Arc::new(value)),
415-
entries: cx.entries.clone(),
416-
suppress_telemetry: cx.suppress_telemetry,
417-
})
337+
entries: Context::map_current(|cx| cx.entries.clone()),
338+
}
418339
}
419340

420341
#[cfg(feature = "trace")]
421342
pub(crate) fn with_synchronized_span(&self, value: SynchronizedSpan) -> Self {
422343
Context {
423344
span: Some(Arc::new(value)),
424345
entries: self.entries.clone(),
425-
suppress_telemetry: self.suppress_telemetry,
426346
}
427347
}
428348
}
@@ -445,9 +365,7 @@ impl fmt::Debug for Context {
445365
#[cfg(not(feature = "trace"))]
446366
let entries = self.entries.as_ref().map_or(0, |e| e.len());
447367

448-
dbg.field("entries count", &entries)
449-
.field("suppress_telemetry", &self.suppress_telemetry)
450-
.finish()
368+
dbg.field("entries count", &entries).finish()
451369
}
452370
}
453371

@@ -985,158 +903,4 @@ mod tests {
985903
assert_eq!(Context::current().get::<ValueA>(), None);
986904
assert_eq!(Context::current().get::<ValueB>(), None);
987905
}
988-
989-
#[test]
990-
fn test_is_telemetry_suppressed() {
991-
// Default context has suppression disabled
992-
let cx = Context::new();
993-
assert!(!cx.is_telemetry_suppressed());
994-
995-
// With suppression enabled
996-
let suppressed = cx.with_telemetry_suppressed();
997-
assert!(suppressed.is_telemetry_suppressed());
998-
}
999-
1000-
#[test]
1001-
fn test_with_telemetry_suppressed() {
1002-
// Start with a normal context
1003-
let cx = Context::new();
1004-
assert!(!cx.is_telemetry_suppressed());
1005-
1006-
// Create a suppressed context
1007-
let suppressed = cx.with_telemetry_suppressed();
1008-
1009-
// Original should remain unchanged
1010-
assert!(!cx.is_telemetry_suppressed());
1011-
1012-
// New context should be suppressed
1013-
assert!(suppressed.is_telemetry_suppressed());
1014-
1015-
// Test with values to ensure they're preserved
1016-
let cx_with_value = cx.with_value(ValueA(42));
1017-
let suppressed_with_value = cx_with_value.with_telemetry_suppressed();
1018-
1019-
assert!(!cx_with_value.is_telemetry_suppressed());
1020-
assert!(suppressed_with_value.is_telemetry_suppressed());
1021-
assert_eq!(suppressed_with_value.get::<ValueA>(), Some(&ValueA(42)));
1022-
}
1023-
1024-
#[test]
1025-
fn test_enter_telemetry_suppressed_scope() {
1026-
// Ensure we start with a clean context
1027-
let _reset_guard = Context::new().attach();
1028-
1029-
// Default context should not be suppressed
1030-
assert!(!Context::is_current_telemetry_suppressed());
1031-
1032-
// Add an entry to the current context
1033-
let cx_with_value = Context::current().with_value(ValueA(42));
1034-
let _guard_with_value = cx_with_value.attach();
1035-
1036-
// Verify the entry is present and context is not suppressed
1037-
assert_eq!(Context::current().get::<ValueA>(), Some(&ValueA(42)));
1038-
assert!(!Context::is_current_telemetry_suppressed());
1039-
1040-
// Enter a suppressed scope
1041-
{
1042-
let _guard = Context::enter_telemetry_suppressed_scope();
1043-
1044-
// Verify suppression is active and the entry is still present
1045-
assert!(Context::is_current_telemetry_suppressed());
1046-
assert!(Context::current().is_telemetry_suppressed());
1047-
assert_eq!(Context::current().get::<ValueA>(), Some(&ValueA(42)));
1048-
}
1049-
1050-
// After guard is dropped, should be back to unsuppressed and entry should still be present
1051-
assert!(!Context::is_current_telemetry_suppressed());
1052-
assert!(!Context::current().is_telemetry_suppressed());
1053-
assert_eq!(Context::current().get::<ValueA>(), Some(&ValueA(42)));
1054-
}
1055-
1056-
#[test]
1057-
fn test_nested_suppression_scopes() {
1058-
// Ensure we start with a clean context
1059-
let _reset_guard = Context::new().attach();
1060-
1061-
// Default context should not be suppressed
1062-
assert!(!Context::is_current_telemetry_suppressed());
1063-
1064-
// First level suppression
1065-
{
1066-
let _outer = Context::enter_telemetry_suppressed_scope();
1067-
assert!(Context::is_current_telemetry_suppressed());
1068-
1069-
// Second level. This component is unaware of Suppression,
1070-
// and just attaches a new context. Since it is from current,
1071-
// it'll already have suppression enabled.
1072-
{
1073-
let _inner = Context::current().with_value(ValueA(1)).attach();
1074-
assert!(Context::is_current_telemetry_suppressed());
1075-
assert_eq!(Context::current().get::<ValueA>(), Some(&ValueA(1)));
1076-
}
1077-
1078-
// Another scenario. This component is unaware of Suppression,
1079-
// and just attaches a new context, not from Current. Since it is
1080-
// not from current it will not have suppression enabled.
1081-
{
1082-
let _inner = Context::new().with_value(ValueA(1)).attach();
1083-
assert!(!Context::is_current_telemetry_suppressed());
1084-
assert_eq!(Context::current().get::<ValueA>(), Some(&ValueA(1)));
1085-
}
1086-
1087-
// Still suppressed after inner scope
1088-
assert!(Context::is_current_telemetry_suppressed());
1089-
}
1090-
1091-
// Back to unsuppressed
1092-
assert!(!Context::is_current_telemetry_suppressed());
1093-
}
1094-
1095-
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
1096-
async fn test_async_suppression() {
1097-
async fn nested_operation() {
1098-
assert!(Context::is_current_telemetry_suppressed());
1099-
1100-
let cx_with_additional_value = Context::current().with_value(ValueB(24));
1101-
1102-
async {
1103-
assert_eq!(
1104-
Context::current().get::<ValueB>(),
1105-
Some(&ValueB(24)),
1106-
"Parent value should still be available after adding new value"
1107-
);
1108-
assert!(Context::is_current_telemetry_suppressed());
1109-
1110-
// Do some async work to simulate real-world scenario
1111-
sleep(Duration::from_millis(10)).await;
1112-
1113-
// Values should still be available after async work
1114-
assert_eq!(
1115-
Context::current().get::<ValueB>(),
1116-
Some(&ValueB(24)),
1117-
"Parent value should still be available after adding new value"
1118-
);
1119-
assert!(Context::is_current_telemetry_suppressed());
1120-
}
1121-
.with_context(cx_with_additional_value)
1122-
.await;
1123-
}
1124-
1125-
// Set up suppressed context, but don't attach it to current
1126-
let suppressed_parent = Context::new().with_telemetry_suppressed();
1127-
// Current should not be suppressed as we haven't attached it
1128-
assert!(!Context::is_current_telemetry_suppressed());
1129-
1130-
// Create and run async operation with the suppressed context explicitly propagated
1131-
nested_operation()
1132-
.with_context(suppressed_parent.clone())
1133-
.await;
1134-
1135-
// After async operation completes:
1136-
// Suppression should be active
1137-
assert!(suppressed_parent.is_telemetry_suppressed());
1138-
1139-
// Current should still be not suppressed
1140-
assert!(!Context::is_current_telemetry_suppressed());
1141-
}
1142906
}

0 commit comments

Comments
 (0)