feat: enable dispatch event using single thread (#3828)

* refactor: lib dispatch

* chore: type def

* chore: type def

* fix: local set spawn

* chore: replace tokio spawn

* chore: update log

* chore: boxed event

* chore: tauri lock
This commit is contained in:
Nathan.fooo
2023-10-30 12:35:06 +08:00
committed by GitHub
parent 7f4e7e6aa0
commit e08a1a6974
67 changed files with 822 additions and 554 deletions

View File

@ -7,10 +7,10 @@ edition = "2018"
[dependencies]
tracing-log = { version = "0.1.3"}
tracing-subscriber = { version = "0.2.25", features = ["registry", "env-filter", "ansi", "json"] }
tracing-bunyan-formatter = "0.2.6"
tracing-appender = "0.1"
tracing-log = { version = "0.2"}
tracing-subscriber = { version = "0.3.17", features = ["registry", "env-filter", "ansi", "json"] }
tracing-bunyan-formatter = "0.3.9"
tracing-appender = "0.2.2"
tracing-core = "0.1"
tracing = { version = "0.1", features = ["log"] }
log = "0.4.17"

View File

@ -4,7 +4,7 @@ use serde::ser::{SerializeMap, Serializer};
use serde_json::Value;
use tracing::{Event, Id, Subscriber};
use tracing_bunyan_formatter::JsonStorage;
use tracing_core::{metadata::Level, span::Attributes};
use tracing_core::metadata::Level;
use tracing_subscriber::{fmt::MakeWriter, layer::Context, registry::SpanRef, Layer};
const LEVEL: &str = "level";
@ -17,17 +17,22 @@ const LOG_TARGET_PATH: &str = "log.target";
const RESERVED_FIELDS: [&str; 3] = [LEVEL, TIME, MESSAGE];
const IGNORE_FIELDS: [&str; 2] = [LOG_MODULE_PATH, LOG_TARGET_PATH];
pub struct FlowyFormattingLayer<W: MakeWriter + 'static> {
pub struct FlowyFormattingLayer<'a, W: MakeWriter<'static> + 'static> {
make_writer: W,
with_target: bool,
phantom: std::marker::PhantomData<&'a ()>,
}
impl<W: MakeWriter + 'static> FlowyFormattingLayer<W> {
impl<'a, W> FlowyFormattingLayer<'a, W>
where
W: for<'writer> MakeWriter<'writer> + 'static,
{
#[allow(dead_code)]
pub fn new(make_writer: W) -> Self {
Self {
make_writer,
with_target: false,
phantom: std::marker::PhantomData,
}
}
@ -43,9 +48,9 @@ impl<W: MakeWriter + 'static> FlowyFormattingLayer<W> {
Ok(())
}
fn serialize_span<S: Subscriber + for<'a> tracing_subscriber::registry::LookupSpan<'a>>(
fn serialize_span<S: Subscriber + for<'b> tracing_subscriber::registry::LookupSpan<'b>>(
&self,
span: &SpanRef<S>,
span: &SpanRef<'a, S>,
ty: Type,
ctx: &Context<'_, S>,
) -> Result<Vec<u8>, std::io::Error> {
@ -86,6 +91,7 @@ impl<W: MakeWriter + 'static> FlowyFormattingLayer<W> {
/// The type of record we are dealing with: entering a span, exiting a span, an
/// event.
#[allow(dead_code)]
#[derive(Clone, Debug)]
pub enum Type {
EnterSpan,
@ -104,8 +110,8 @@ impl fmt::Display for Type {
}
}
fn format_span_context<S: Subscriber + for<'a> tracing_subscriber::registry::LookupSpan<'a>>(
span: &SpanRef<S>,
fn format_span_context<'b, S: Subscriber + for<'a> tracing_subscriber::registry::LookupSpan<'a>>(
span: &SpanRef<'b, S>,
ty: Type,
context: &Context<'_, S>,
) -> String {
@ -153,10 +159,10 @@ fn format_event_message<S: Subscriber + for<'a> tracing_subscriber::registry::Lo
message
}
impl<S, W> Layer<S> for FlowyFormattingLayer<W>
impl<S, W> Layer<S> for FlowyFormattingLayer<'static, W>
where
S: Subscriber + for<'a> tracing_subscriber::registry::LookupSpan<'a>,
W: MakeWriter + 'static,
W: for<'writer> MakeWriter<'writer> + 'static,
{
fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>) {
// Events do not necessarily happen in the context of a span, hence
@ -221,13 +227,6 @@ where
}
}
fn new_span(&self, _attrs: &Attributes, id: &Id, ctx: Context<'_, S>) {
let span = ctx.span(id).expect("Span not found, this is a bug");
if let Ok(serialized) = self.serialize_span(&span, Type::EnterSpan, &ctx) {
let _ = self.emit(serialized);
}
}
fn on_close(&self, id: Id, ctx: Context<'_, S>) {
let span = ctx.span(&id).expect("Span not found, this is a bug");
if let Ok(serialized) = self.serialize_span(&span, Type::ExitSpan, &ctx) {

View File

@ -1,16 +1,15 @@
use std::sync::RwLock;
use lazy_static::lazy_static;
use log::LevelFilter;
use tracing::subscriber::set_global_default;
use tracing_appender::{non_blocking::WorkerGuard, rolling::RollingFileAppender};
use tracing_bunyan_formatter::JsonStorageLayer;
use tracing_log::LogTracer;
use tracing_subscriber::{layer::SubscriberExt, EnvFilter};
use crate::layer::FlowyFormattingLayer;
mod layer;
lazy_static! {
static ref LOG_GUARD: RwLock<Option<WorkerGuard>> = RwLock::new(None);
}
@ -47,48 +46,17 @@ impl Builder {
.with_ansi(true)
.with_target(true)
.with_max_level(tracing::Level::TRACE)
.with_thread_ids(false)
.with_file(false)
.with_writer(std::io::stderr)
.with_thread_ids(true)
.json()
.with_current_span(true)
.with_span_list(true)
.compact()
.pretty()
.with_env_filter(env_filter)
.finish()
.with(env_filter)
.with(JsonStorageLayer)
.with(FlowyFormattingLayer::new(std::io::stdout))
.with(FlowyFormattingLayer::new(non_blocking));
set_global_default(subscriber).map_err(|e| format!("{:?}", e))?;
LogTracer::builder()
.with_max_level(LevelFilter::Trace)
.init()
.map_err(|e| format!("{:?}", e))?;
*LOG_GUARD.write().unwrap() = Some(guard);
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
// run cargo test --features="use_bunyan" or cargo test
#[test]
fn test_log() {
Builder::new("flowy", ".")
.env_filter("debug")
.build()
.unwrap();
tracing::info!("😁 tracing::info call");
log::debug!("😁 log::debug call");
say("hello world");
}
#[tracing::instrument(level = "trace", name = "say")]
fn say(s: &str) {
tracing::info!("{}", s);
}
}