#![allow(clippy::type_complexity)]
use bevy::prelude::{App, Plugin};
#[cfg(feature = "metrics")]
use metrics_tracing_context::{MetricsLayer, TracingContextLayer};
#[cfg(feature = "metrics")]
use metrics_util::layers::Layer;
use tracing::{warn, Level};
use tracing_subscriber::{prelude::*, registry::Registry, EnvFilter};
use tracing_log::LogTracer;
pub struct LogPlugin {
pub config: LogConfig,
}
#[derive(Clone)]
pub struct LogConfig {
pub filter: String,
pub level: Level,
}
impl Default for LogConfig {
fn default() -> Self {
Self {
filter: "wgpu=error,wgpu_hal=error,naga=warn,bevy_app=info".to_string(),
level: Level::INFO,
}
}
}
impl Plugin for LogPlugin {
fn build(&self, app: &mut App) {
let finished_subscriber;
let default_filter = { format!("{},{}", self.config.level, self.config.filter) };
let filter_layer = EnvFilter::try_from_default_env()
.or_else(|_| EnvFilter::try_new(&default_filter))
.unwrap();
println!("Log filter: {:?}", default_filter);
let subscriber = Registry::default().with(filter_layer);
let fmt_layer = tracing_subscriber::fmt::Layer::default()
.with_span_events(tracing_subscriber::fmt::format::FmtSpan::ENTER)
.with_writer(std::io::stderr);
let subscriber = subscriber.with(fmt_layer);
cfg_if::cfg_if! {
if #[cfg(feature = "metrics")] {
let subscriber = subscriber.with(MetricsLayer::new());
let builder = metrics_exporter_prometheus::PrometheusBuilder::new();
let runtime = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap();
let (recorder, exporter) = {
let _g = runtime.enter();
builder.build().unwrap()
};
let traced_recorder = TracingContextLayer::all().layer(recorder);
std::thread::Builder::new()
.spawn(move || runtime.block_on(exporter))
.unwrap();
metrics::set_boxed_recorder(Box::new(traced_recorder));
} else {
}
}
finished_subscriber = subscriber;
let subscriber_already_set =
tracing::subscriber::set_global_default(finished_subscriber).is_err();
}
}