Skip to content

Commit 7762c16

Browse files
committed
Skip exporting spans that are not part of / descendants of the allowed root spans list.
1 parent 5acfd53 commit 7762c16

File tree

2 files changed

+105
-22
lines changed

2 files changed

+105
-22
lines changed

beacon_node/lighthouse_tracing/src/lib.rs

Lines changed: 100 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
use tracing::{Metadata, Subscriber};
2-
use tracing_subscriber::layer::{Context, Filter};
1+
use tracing::Subscriber;
32

43
/// DA checker spans
54
pub const SPAN_PENDING_COMPONENTS: &str = "pending_components";
@@ -51,28 +50,112 @@ pub const LH_BN_ROOT_SPAN_NAMES: &[&str] = &[
5150
SPAN_HANDLE_LIGHT_CLIENT_FINALITY_UPDATE,
5251
];
5352

54-
/// Filter that only allows spans that either:
55-
/// - Have a parent span, or
56-
/// - Are root spans with names matching the predefined allowed list
57-
pub struct AllowedRootSpanFilter(&'static [&'static str]);
53+
use std::collections::HashSet;
54+
use tracing::span::Id;
55+
use tracing_subscriber::Layer;
5856

59-
impl AllowedRootSpanFilter {
60-
pub fn new(allowed_names: &'static [&'static str]) -> Self {
61-
AllowedRootSpanFilter(allowed_names)
57+
/// A filtering layer that wraps another layer and only forwards spans from allowed root spans and their descendants
58+
pub struct AllowedRootSpanLayer<L> {
59+
inner: L,
60+
allowed_names: &'static [&'static str],
61+
allowed_spans: std::sync::Mutex<HashSet<Id>>,
62+
}
63+
64+
impl<L> AllowedRootSpanLayer<L> {
65+
pub fn new(inner: L, allowed_names: &'static [&'static str]) -> Self {
66+
AllowedRootSpanLayer {
67+
inner,
68+
allowed_names,
69+
allowed_spans: std::sync::Mutex::new(HashSet::new()),
70+
}
71+
}
72+
73+
fn is_span_allowed(&self, span_id: &Id) -> bool {
74+
self.allowed_spans.lock().unwrap().contains(span_id)
75+
}
76+
77+
fn mark_span_allowed(&self, span_id: Id) {
78+
self.allowed_spans.lock().unwrap().insert(span_id);
79+
}
80+
81+
fn remove_span(&self, span_id: &Id) {
82+
self.allowed_spans.lock().unwrap().remove(span_id);
6283
}
6384
}
6485

65-
impl<S> Filter<S> for AllowedRootSpanFilter
86+
impl<S, L> Layer<S> for AllowedRootSpanLayer<L>
6687
where
67-
S: Subscriber,
88+
S: Subscriber + for<'lookup> tracing_subscriber::registry::LookupSpan<'lookup>,
89+
L: Layer<S>,
6890
{
69-
fn enabled(&self, metadata: &Metadata<'_>, ctx: &Context<'_, S>) -> bool {
70-
// Has a parent span: allow
71-
if ctx.current_span().id().is_some() {
72-
return true;
91+
fn on_new_span(
92+
&self,
93+
attrs: &tracing::span::Attributes<'_>,
94+
id: &Id,
95+
ctx: tracing_subscriber::layer::Context<'_, S>,
96+
) {
97+
let should_allow = if let Some(parent_id) = ctx.current_span().id() {
98+
// This span has a parent - allow it if the parent is allowed
99+
self.is_span_allowed(parent_id)
100+
} else {
101+
// This is a root span - allow it if it's in the allowed list
102+
self.allowed_names.contains(&attrs.metadata().name())
103+
};
104+
105+
if should_allow {
106+
self.mark_span_allowed(id.clone());
107+
self.inner.on_new_span(attrs, id, ctx);
73108
}
109+
}
110+
111+
fn on_record(
112+
&self,
113+
span: &Id,
114+
values: &tracing::span::Record<'_>,
115+
ctx: tracing_subscriber::layer::Context<'_, S>,
116+
) {
117+
if self.is_span_allowed(span) {
118+
self.inner.on_record(span, values, ctx);
119+
}
120+
}
74121

75-
// Root span: only allow if in allowed list
76-
self.0.contains(&metadata.name())
122+
fn on_follows_from(
123+
&self,
124+
span: &Id,
125+
follows: &Id,
126+
ctx: tracing_subscriber::layer::Context<'_, S>,
127+
) {
128+
if self.is_span_allowed(span) {
129+
self.inner.on_follows_from(span, follows, ctx);
130+
}
131+
}
132+
133+
fn on_event(&self, event: &tracing::Event<'_>, ctx: tracing_subscriber::layer::Context<'_, S>) {
134+
// Check if we're in an allowed span context
135+
if let Some(current_span_id) = ctx.current_span().id()
136+
&& self.is_span_allowed(current_span_id)
137+
{
138+
self.inner.on_event(event, ctx);
139+
}
140+
// If no current span, we could choose to allow or disallow events - for now, disallow
141+
}
142+
143+
fn on_enter(&self, id: &Id, ctx: tracing_subscriber::layer::Context<'_, S>) {
144+
if self.is_span_allowed(id) {
145+
self.inner.on_enter(id, ctx);
146+
}
147+
}
148+
149+
fn on_exit(&self, id: &Id, ctx: tracing_subscriber::layer::Context<'_, S>) {
150+
if self.is_span_allowed(id) {
151+
self.inner.on_exit(id, ctx);
152+
}
153+
}
154+
155+
fn on_close(&self, id: Id, ctx: tracing_subscriber::layer::Context<'_, S>) {
156+
if self.is_span_allowed(&id) {
157+
self.inner.on_close(id.clone(), ctx);
158+
}
159+
self.remove_span(&id);
77160
}
78161
}

lighthouse/src/main.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use environment::{EnvironmentBuilder, LoggerConfig};
1616
use eth2_network_config::{DEFAULT_HARDCODED_NETWORK, Eth2NetworkConfig, HARDCODED_NET_NAMES};
1717
use ethereum_hashing::have_sha_extensions;
1818
use futures::TryFutureExt;
19-
use lighthouse_tracing::{AllowedRootSpanFilter, LH_BN_ROOT_SPAN_NAMES};
19+
use lighthouse_tracing::{AllowedRootSpanLayer, LH_BN_ROOT_SPAN_NAMES};
2020
use lighthouse_version::VERSION;
2121
use logging::{MetricsLayer, build_workspace_filter, crit};
2222
use malloc_utils::configure_memory_allocator;
@@ -721,12 +721,12 @@ fn run<E: EthSpec>(
721721
.build();
722722

723723
let tracer = provider.tracer("lighthouse");
724-
Ok::<_, String>(
724+
Ok::<_, String>(AllowedRootSpanLayer::new(
725725
tracing_opentelemetry::layer()
726726
.with_tracer(tracer)
727-
.with_filter(workspace_filter)
728-
.with_filter(AllowedRootSpanFilter::new(LH_BN_ROOT_SPAN_NAMES)),
729-
)
727+
.with_filter(workspace_filter),
728+
LH_BN_ROOT_SPAN_NAMES,
729+
))
730730
})?;
731731

732732
logging_layers.push(telemetry_layer.boxed());

0 commit comments

Comments
 (0)