ugly_smart_lib 0.1.1

jonny's ugly smart lib for Rust
Documentation
//! src/smart_log.rs

use std::path::Path;

use tracing::Subscriber;
use tracing_subscriber::{
    self,
    filter::EnvFilter,
    fmt::{self, writer::MakeWriterExt},
    layer::SubscriberExt,
    Layer, Registry,
};

/// 将多个层次组合成 `tracing` 的订阅器
///
/// # 注意事项
///
/// 将 `impl Subscriber` 做为返回值的类型,以避免写出烦琐的真实类型
/// 我们需要显示地将返回类型标记为 `Send` 和 `Sync` ,以便后面只可以将其传递给 `init_subscriber`
///
/// # Argments
///
/// - 'env_filter_str' 日志文件级别[从环境变量里面获取]
/// - `directory` 日志文件目录
/// - `file_name_prefix` 日志文件名格式
///
/// # Returns
/// - impl Subscriber
pub fn get_log_subscriber(
    env_filter_str: String,
    directory: impl AsRef<Path>,
    file_name_prefix: impl AsRef<Path>,
) -> impl Subscriber + Send + Sync
{
    println!("{env_filter_str}");
    // 如果没有设置 `RUST_LOG` 环境变量,则输出所有 `info` 及以上级别的跨度
    let env_filter = EnvFilter::try_from_default_env()
        .unwrap_or_else(|_| EnvFilter::new(env_filter_str.clone()));

    // let offset = time::UtcOffset::current_local_offset().expect("should get local offset!");
    let offset = time::UtcOffset::from_hms(8, 0, 0).unwrap_or(time::UtcOffset::UTC);

    // 时间格式为  年-月-日 时:分:秒 格式
    let logger_time = fmt::time::OffsetTime::new(
        offset,
        time::macros::format_description!("[year]-[month]-[day] [hour]:[minute]:[second]"),
    );

    // 输出到文件中
    let file_appender = tracing_appender::rolling::daily(directory, file_name_prefix);
    // let (non_blocking_appender, _guard) = tracing_appender::non_blocking(file_appender);

    let console_file = std::io::stdout.with_max_level(tracing::Level::TRACE);

    let console_layer = fmt::layer()
        .json()
        .with_ansi(false)
        .with_file(true)
        .pretty()
        .with_timer(logger_time.clone())
        .with_writer(console_file.and(file_appender))
        .with_filter(env_filter);

    // `with` 方法由 `SubscriberExt` 提供,可以扩展 `tracing_subscriber` 的 `Subscriber`
    let subscriber = Registry::default().with(console_layer);
    subscriber
}

/// 将 `log` 中的记录导入 `trace` 中
///
/// - 'subscriber' 日志跟踪器
///
/// # Returns
/// - 无
pub fn log_init_subscriber(subscriber: impl Subscriber + Send + Sync) {
    // LogTracer::init().expect("Failed to set logger");
    tracing::subscriber::set_global_default(subscriber).expect("Failed to set subacriber");
}

pub fn config_default_log() {
    let mut log_level = "info".to_string();
    if cfg!(debug_assertions) {
        log_level = "debug".into();
    }
    log_init_subscriber(get_log_subscriber(log_level, "./logs", "tan_middleware.log"));
}

pub fn spawn_blocking_with_tracing<F, R>(f: F) -> tokio::task::JoinHandle<R>
where
    F: FnOnce() -> R + Send + 'static,
    R: Send + 'static,
{
    let current_span = tracing::Span::current();
    tokio::task::spawn_blocking(move || {
        // 解决跨度问题
        current_span.in_scope(f)
    })
}