use std::fmt::Debug; use std::io; use tracing::{Event, info, Subscriber}; use tracing_appender_timezone::non_blocking::WorkerGuard; use tracing_subscriber::{fmt, Layer}; use tracing_subscriber::layer::{Context, SubscriberExt}; use tracing::field::{Field, Visit}; use tracing_appender_timezone::rolling::{RollingFileAppender, Rotation}; struct ErrorMessageVisitor { message: String } impl Visit for ErrorMessageVisitor { fn record_debug(&mut self, field: &Field, value: &dyn Debug) { if field.name() == "message" { self.message = format!("{:?}", value); } } } // 错误报告发送到指定服务器 struct ReportingLayer { account_name: String, } impl Layer for ReportingLayer where S: Subscriber + for<'a> tracing_subscriber::registry::LookupSpan<'a>, { fn on_event(&self, event: &Event<'_>, _ctx: Context<'_, S>) { if event.metadata().level() == &tracing::Level::ERROR { let mut visitor = ErrorMessageVisitor { message: String::new() }; event.record(&mut visitor); let msg = format!("account={}, type=error, msg={}", self.account_name.clone(), visitor.message); info!(msg) // send_remote_err_log(msg) } } } // pub fn send_remote_err_log(msg: String) { // tokio::spawn(async move { // let encoded_str = base64::encode(msg.clone()); // let mut request_json_data = HashMap::new(); // request_json_data.insert("serverName", "As"); // request_json_data.insert("data", encoded_str.as_str()); // // let res = Client::new().post("https://hhh.liangjiang.cc/api/log/addError?key=d64a8sc874sa8c4as5") // .json(&request_json_data) // .send() // .await; // // match res { // Ok(_resp) => { // // let body = _resp.text().await.unwrap(); // } // Err(err) => { // warn!("log的error监听器发送远端报错失败:{:?}", err); // } // } // }); // } pub fn init_log_with_debug() { let _ = final_init(tracing::Level::DEBUG.as_str(), 0, "test".to_string()); } pub fn init_log_with_trace() { let _ = final_init(tracing::Level::TRACE.as_str(), 0, "test".to_string()); } pub fn init_log_with_info() { let _ = final_init(tracing::Level::INFO.as_str(), 0, "test".to_string()); } pub fn final_init(level: &str, port: u32, account_name: String) -> WorkerGuard { let mut path = String::new(); path.push_str("./logs"); path.push_str(port.to_string().as_str()); let file_appender = RollingFileAppender::builder() .time_zone(8) .rotation(Rotation::DAILY) .filename_suffix("log") .build(path) .expect("initializing rolling file appender failed"); let (non_blocking, guard) = tracing_appender_timezone::non_blocking(file_appender); use time::{macros::format_description, UtcOffset}; use tracing_subscriber::{fmt::time::OffsetTime}; let local_time = OffsetTime::new( UtcOffset::from_hms(8, 0, 0).unwrap(), format_description!("[month]-[day] [hour]:[minute]:[second].[subsecond digits:3]"), ); let fmt_layer = fmt::layer() .with_timer(local_time.clone()) .with_target(true) .with_line_number(true) .with_level(true) .with_writer(io::stdout) .with_span_events(fmt::format::FmtSpan::FULL); let file_layer = fmt::layer() .with_timer(local_time.clone()) .with_target(true) .with_ansi(false) .with_level(true) .with_writer(non_blocking.clone()) .with_span_events(fmt::format::FmtSpan::FULL); let reporting_layer = ReportingLayer { account_name }; let layer = tracing_subscriber::Registry::default() .with(fmt_layer) .with(file_layer) .with(reporting_layer) .with(tracing_subscriber::EnvFilter::new(level)); tracing::subscriber::set_global_default(layer).unwrap(); return guard; }