diff --git a/substrate/client/tracing/src/lib.rs b/substrate/client/tracing/src/lib.rs
index ebec8f2a8716a3eb81cc21aa48fd5f453af29845..2b0044a6f25b0629b5140d49acb46e3ac10acd6e 100644
--- a/substrate/client/tracing/src/lib.rs
+++ b/substrate/client/tracing/src/lib.rs
@@ -440,12 +440,11 @@ mod tests {
 		}
 	}
 
-	type TestSubscriber = tracing_subscriber::layer::Layered<
-		ProfilingLayer,
-		tracing_subscriber::fmt::Subscriber
-	>;
-
-	fn setup_subscriber() -> (TestSubscriber, Arc<Mutex<Vec<SpanDatum>>>, Arc<Mutex<Vec<TraceEvent>>>) {
+	fn setup_subscriber() -> (
+		impl tracing::Subscriber + Send + Sync,
+		Arc<Mutex<Vec<SpanDatum>>>,
+		Arc<Mutex<Vec<TraceEvent>>>
+	) {
 		let spans = Arc::new(Mutex::new(Vec::new()));
 		let events = Arc::new(Mutex::new(Vec::new()));
 		let handler = TestTraceHandler {
@@ -456,7 +455,7 @@ mod tests {
 			Box::new(handler),
 			"test_target",
 		);
-		let subscriber = tracing_subscriber::fmt().finish().with(layer);
+		let subscriber = tracing_subscriber::fmt().with_writer(std::io::sink).finish().with(layer);
 		(subscriber, spans, events)
 	}
 
@@ -560,64 +559,76 @@ mod tests {
 
 	#[test]
 	fn test_parent_id_with_threads() {
-		use std::sync::mpsc;
-		use std::thread;
-
-		let (sub, spans, events) = setup_subscriber();
-		let _sub_guard = tracing::subscriber::set_global_default(sub);
-		let span1 = tracing::info_span!(target: "test_target", "test_span1");
-		let _guard1 = span1.enter();
-
-		let (tx, rx) = mpsc::channel();
-		let handle = thread::spawn(move || {
-			let span2 = tracing::info_span!(target: "test_target", "test_span2");
-			let _guard2 = span2.enter();
-			// emit event
-			tracing::event!(target: "test_target", tracing::Level::INFO, "test_event1");
-			for msg in rx.recv() {
-				if msg == false {
-					break;
+		use std::{sync::mpsc, thread};
+
+		if std::env::var("RUN_TEST_PARENT_ID_WITH_THREADS").is_err() {
+			let executable = std::env::current_exe().unwrap();
+			let mut command = std::process::Command::new(executable);
+
+			let res = command
+				.env("RUN_TEST_PARENT_ID_WITH_THREADS", "1")
+				.args(&["--nocapture", "test_parent_id_with_threads"])
+				.output()
+				.unwrap()
+				.status;
+			assert!(res.success());
+		} else {
+			let (sub, spans, events) = setup_subscriber();
+			let _sub_guard = tracing::subscriber::set_global_default(sub);
+			let span1 = tracing::info_span!(target: "test_target", "test_span1");
+			let _guard1 = span1.enter();
+
+			let (tx, rx) = mpsc::channel();
+			let handle = thread::spawn(move || {
+				let span2 = tracing::info_span!(target: "test_target", "test_span2");
+				let _guard2 = span2.enter();
+				// emit event
+				tracing::event!(target: "test_target", tracing::Level::INFO, "test_event1");
+				for msg in rx.recv() {
+					if msg == false {
+						break;
+					}
 				}
-			}
-			// gard2 and span2 dropped / exited
-		});
+				// gard2 and span2 dropped / exited
+			});
 
-		// wait for Event to be dispatched and stored
-		while events.lock().is_empty() {
-			thread::sleep(Duration::from_millis(1));
-		}
+			// wait for Event to be dispatched and stored
+			while events.lock().is_empty() {
+				thread::sleep(Duration::from_millis(1));
+			}
 
-		// emit new event (will be second item in Vec) while span2 still active in other thread
-		tracing::event!(target: "test_target", tracing::Level::INFO, "test_event2");
+			// emit new event (will be second item in Vec) while span2 still active in other thread
+			tracing::event!(target: "test_target", tracing::Level::INFO, "test_event2");
 
-		// stop thread and drop span
-		let _ = tx.send(false);
-		let _ = handle.join();
+			// stop thread and drop span
+			let _ = tx.send(false);
+			let _ = handle.join();
 
-		// wait for Span to be dispatched and stored
-		while spans.lock().is_empty() {
-			thread::sleep(Duration::from_millis(1));
+			// wait for Span to be dispatched and stored
+			while spans.lock().is_empty() {
+				thread::sleep(Duration::from_millis(1));
+			}
+			let span2 = spans.lock().remove(0);
+			let event1 = events.lock().remove(0);
+			drop(_guard1);
+			drop(span1);
+
+			// emit event with no parent
+			tracing::event!(target: "test_target", tracing::Level::INFO, "test_event3");
+
+			let span1 = spans.lock().remove(0);
+			let event2 = events.lock().remove(0);
+
+			assert_eq!(event1.values.string_values.get("message").unwrap(), "test_event1");
+			assert_eq!(event2.values.string_values.get("message").unwrap(), "test_event2");
+			assert!(span1.parent_id.is_none());
+			assert!(span2.parent_id.is_none());
+			assert_eq!(span2.id, event1.parent_id.unwrap());
+			assert_eq!(span1.id, event2.parent_id.unwrap());
+			assert_ne!(span2.id, span1.id);
+
+			let event3 = events.lock().remove(0);
+			assert!(event3.parent_id.is_none());
 		}
-		let span2 = spans.lock().remove(0);
-		let event1 = events.lock().remove(0);
-		drop(_guard1);
-		drop(span1);
-
-		// emit event with no parent
-		tracing::event!(target: "test_target", tracing::Level::INFO, "test_event3");
-
-		let span1 = spans.lock().remove(0);
-		let event2 = events.lock().remove(0);
-
-		assert_eq!(event1.values.string_values.get("message").unwrap(), "test_event1");
-		assert_eq!(event2.values.string_values.get("message").unwrap(), "test_event2");
-		assert!(span1.parent_id.is_none());
-		assert!(span2.parent_id.is_none());
-		assert_eq!(span2.id, event1.parent_id.unwrap());
-		assert_eq!(span1.id, event2.parent_id.unwrap());
-		assert_ne!(span2.id, span1.id);
-
-		let event3 = events.lock().remove(0);
-		assert!(event3.parent_id.is_none());
 	}
 }
diff --git a/substrate/client/tracing/src/logging/mod.rs b/substrate/client/tracing/src/logging/mod.rs
index f74c3e664607373b4c12c40dc111dd4f5750cb6f..5674b50cb98e20cf22630c849b78c339b41b1a5e 100644
--- a/substrate/client/tracing/src/logging/mod.rs
+++ b/substrate/client/tracing/src/logging/mod.rs
@@ -38,7 +38,7 @@ use tracing_subscriber::{
 		format, FormatEvent, FormatFields, Formatter, Layer as FmtLayer, MakeWriter,
 		SubscriberBuilder,
 	},
-	layer::{self, SubscriberExt},
+	layer::{self, SubscriberExt}, filter::LevelFilter,
 	registry::LookupSpan,
 	EnvFilter, FmtSubscriber, Layer, Registry,
 };
@@ -73,7 +73,7 @@ macro_rules! enable_log_reloading {
 /// Common implementation to get the subscriber.
 fn prepare_subscriber<N, E, F, W>(
 	directives: &str,
-	max_level: Option<log::LevelFilter>,
+	profiling_targets: Option<&str>,
 	force_colors: Option<bool>,
 	telemetry_buffer_size: Option<usize>,
 	telemetry_external_transport: Option<ExtTransport>,
@@ -125,21 +125,27 @@ where
 	}
 
 	if directives != "" {
-		// We're not sure if log or tracing is available at this moment, so silently ignore the
-		// parse error.
 		env_filter = parse_user_directives(env_filter, directives)?;
 	}
 
+	if let Some(profiling_targets) = profiling_targets {
+		env_filter = parse_user_directives(env_filter, profiling_targets)?;
+		env_filter = env_filter
+			.add_directive(
+				parse_default_directive("sc_tracing=trace").expect("provided directive is valid")
+			);
+	}
+
 	let max_level_hint = Layer::<FmtSubscriber>::max_level_hint(&env_filter);
 
-	let max_level = max_level.unwrap_or_else(|| match max_level_hint {
-		Some(tracing_subscriber::filter::LevelFilter::INFO) | None => log::LevelFilter::Info,
-		Some(tracing_subscriber::filter::LevelFilter::TRACE) => log::LevelFilter::Trace,
-		Some(tracing_subscriber::filter::LevelFilter::WARN) => log::LevelFilter::Warn,
-		Some(tracing_subscriber::filter::LevelFilter::ERROR) => log::LevelFilter::Error,
-		Some(tracing_subscriber::filter::LevelFilter::DEBUG) => log::LevelFilter::Debug,
-		Some(tracing_subscriber::filter::LevelFilter::OFF) => log::LevelFilter::Off,
-	});
+	let max_level = match max_level_hint {
+		Some(LevelFilter::INFO) | None => log::LevelFilter::Info,
+		Some(LevelFilter::TRACE) => log::LevelFilter::Trace,
+		Some(LevelFilter::WARN) => log::LevelFilter::Warn,
+		Some(LevelFilter::ERROR) => log::LevelFilter::Error,
+		Some(LevelFilter::DEBUG) => log::LevelFilter::Debug,
+		Some(LevelFilter::OFF) => log::LevelFilter::Off,
+	};
 
 	tracing_log::LogTracer::builder()
 		.with_max_level(max_level)
@@ -251,13 +257,10 @@ impl LoggerBuilder {
 	/// This sets various global logging and tracing instances and thus may only be called once.
 	pub fn init(self) -> Result<TelemetryWorker> {
 		if let Some((tracing_receiver, profiling_targets)) = self.profiling {
-			// If profiling is activated, we require `trace` logging.
-			let max_level = Some(log::LevelFilter::Trace);
-
 			if self.log_reloading {
 				let (subscriber, telemetry_worker) = prepare_subscriber(
-					&format!("{},{},sc_tracing=trace", self.directives, profiling_targets),
-					max_level,
+					&self.directives,
+					Some(&profiling_targets),
 					self.force_colors,
 					self.telemetry_buffer_size,
 					self.telemetry_external_transport,
@@ -270,8 +273,8 @@ impl LoggerBuilder {
 				Ok(telemetry_worker)
 			} else {
 				let (subscriber, telemetry_worker) = prepare_subscriber(
-					&format!("{},{},sc_tracing=trace", self.directives, profiling_targets),
-					max_level,
+					&self.directives,
+					Some(&profiling_targets),
 					self.force_colors,
 					self.telemetry_buffer_size,
 					self.telemetry_external_transport,
@@ -329,57 +332,53 @@ mod tests {
 		let _ = LoggerBuilder::new(directives).init().unwrap();
 	}
 
-	fn run_in_process(test_name: &str) {
-		if env::var("RUN_IN_PROCESS").is_err() {
-			let status = Command::new(env::current_exe().unwrap())
-				.arg(test_name)
-				.env("RUN_IN_PROCESS", "true")
-				.status()
-				.unwrap();
-			assert!(status.success(), "process did not ended successfully");
-			std::process::exit(0);
-		}
-	}
-
 	#[test]
 	fn test_logger_filters() {
-		run_in_process("test_logger_filters");
-
-		let test_directives = "afg=debug,sync=trace,client=warn,telemetry,something-with-dash=error";
-		init_logger(&test_directives);
-
-		tracing::dispatcher::get_default(|dispatcher| {
-			let test_filter = |target, level| {
-				struct DummyCallSite;
-				impl Callsite for DummyCallSite {
-					fn set_interest(&self, _: Interest) {}
-					fn metadata(&self) -> &Metadata<'_> {
-						unreachable!();
+		if env::var("RUN_TEST_LOGGER_FILTERS").is_ok() {
+			let test_directives = "afg=debug,sync=trace,client=warn,telemetry,something-with-dash=error";
+			init_logger(&test_directives);
+
+			tracing::dispatcher::get_default(|dispatcher| {
+				let test_filter = |target, level| {
+					struct DummyCallSite;
+					impl Callsite for DummyCallSite {
+						fn set_interest(&self, _: Interest) {}
+						fn metadata(&self) -> &Metadata<'_> {
+							unreachable!();
+						}
 					}
-				}
-
-				let metadata = tracing::metadata!(
-					name: "",
-					target: target,
-					level: level,
-					fields: &[],
-					callsite: &DummyCallSite,
-					kind: Kind::SPAN,
-				);
-
-				dispatcher.enabled(&metadata)
-			};
-
-			assert!(test_filter("afg", Level::INFO));
-			assert!(test_filter("afg", Level::DEBUG));
-			assert!(!test_filter("afg", Level::TRACE));
-
-			assert!(test_filter("sync", Level::TRACE));
-			assert!(test_filter("client", Level::WARN));
-
-			assert!(test_filter("telemetry", Level::TRACE));
-			assert!(test_filter("something-with-dash", Level::ERROR));
-		});
+
+					let metadata = tracing::metadata!(
+						name: "",
+						target: target,
+						level: level,
+						fields: &[],
+						callsite: &DummyCallSite,
+						kind: Kind::SPAN,
+					);
+
+					dispatcher.enabled(&metadata)
+				};
+
+				assert!(test_filter("afg", Level::INFO));
+				assert!(test_filter("afg", Level::DEBUG));
+				assert!(!test_filter("afg", Level::TRACE));
+
+				assert!(test_filter("sync", Level::TRACE));
+				assert!(test_filter("client", Level::WARN));
+
+				assert!(test_filter("telemetry", Level::TRACE));
+				assert!(test_filter("something-with-dash", Level::ERROR));
+			});
+		} else {
+			let status = Command::new(env::current_exe().unwrap())
+				.arg("test_logger_filters")
+				.env("RUN_TEST_LOGGER_FILTERS", "1")
+				.output()
+				.unwrap()
+				.status;
+			assert!(status.success());
+		}
 	}
 
 	/// This test ensures that using dash (`-`) in the target name in logs and directives actually
@@ -500,11 +499,18 @@ mod tests {
 
 			let output = command.output().unwrap();
 
-			String::from_utf8(output.stderr).unwrap()
+			dbg!(String::from_utf8(output.stderr)).unwrap()
 		}
 
 		if env::var("PRINT_MAX_LOG_LEVEL").is_ok() {
-			init_logger(&env::var("TRACING_TARGETS").unwrap_or_default());
+			let mut builder = LoggerBuilder::new("");
+
+			if let Ok(targets) = env::var("TRACING_TARGETS") {
+				builder.with_profiling(crate::TracingReceiver::Log, targets);
+			}
+
+			builder.init().unwrap();
+
 			eprint!("MAX_LOG_LEVEL={:?}", log::max_level());
 		} else {
 			assert_eq!("MAX_LOG_LEVEL=Info", run_test(None, None));