feat: 升级日志系统为 tracing 结构化日志
- 替换 env_logger 为 tracing + tracing-subscriber
- 统一使用 tracing::{debug, error, info, warn} 日志宏
- 消除所有 eprintln!/println 调用
- 添加 JSON 格式日志输出便于 ELK Stack 收集
- 添加文件日志轮转(每天一个新文件 ./logs/rust-backend-{date}.log)
- 日志等级过滤:rust_backend=info, actix_web=info, sqlx=warn
- 更新 IMPROVEMENTS.md 标记 6.1 日志系统两项完成
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
use std::env;
|
||||
use dotenvy::dotenv;
|
||||
use tracing;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Config {
|
||||
@@ -14,7 +15,7 @@ impl Config {
|
||||
pub fn load() -> Result<Self, String> {
|
||||
// 加载.env文件
|
||||
if let Err(e) = dotenv() {
|
||||
eprintln!("警告: 无法加载.env文件 - {}", e);
|
||||
tracing::warn!("无法加载.env文件 - {}", e);
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
|
||||
38
src/main.rs
38
src/main.rs
@@ -1,7 +1,7 @@
|
||||
use actix_web::middleware::from_fn;
|
||||
use actix_web::{App, HttpResponse, HttpServer, Responder, delete, get, post, put, web};
|
||||
use include_dir::{Dir, include_dir};
|
||||
use log::{debug, error, info, warn};
|
||||
use tracing::{debug, error, info, warn};
|
||||
use openssl::ssl::{SslAcceptor, SslAcceptorBuilder, SslFiletype, SslMethod};
|
||||
use reqwest::Client;
|
||||
use serde::Deserialize;
|
||||
@@ -717,11 +717,41 @@ fn create_server_config(
|
||||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
if let Err(e) = dotenvy::dotenv() {
|
||||
eprintln!("警告:加载.env文件失败,使用系统环境变量: {}", e);
|
||||
tracing::warn!("加载.env文件失败,使用系统环境变量: {}", e);
|
||||
}
|
||||
|
||||
env_logger::init();
|
||||
info!("logger init successful");
|
||||
// 初始化文件日志(JSON 格式,带轮转)
|
||||
let log_dir = std::path::Path::new("./logs");
|
||||
std::fs::create_dir_all(log_dir).ok(); // 确保日志目录存在
|
||||
|
||||
let file_appender = tracing_appender::rolling::Builder::new()
|
||||
.rotation(tracing_appender::rolling::Rotation::DAILY)
|
||||
.filename_prefix("rust-backend")
|
||||
.filename_suffix("log")
|
||||
.build(log_dir)
|
||||
.expect("无法创建日志文件");
|
||||
|
||||
let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender);
|
||||
|
||||
// 保持文件 guard 存活(使用 Box 泄漏)
|
||||
std::mem::forget(_guard);
|
||||
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter(
|
||||
tracing_subscriber::EnvFilter::from_default_env()
|
||||
.add_directive("rust_backend=info".parse().unwrap())
|
||||
.add_directive("actix_web=info".parse().unwrap())
|
||||
.add_directive("sqlx=warn".parse().unwrap()) // SQLx 日志太多,降级
|
||||
)
|
||||
.with_target(true)
|
||||
.with_thread_ids(false) // 生产环境可开启
|
||||
.with_file(true)
|
||||
.with_line_number(true)
|
||||
.with_writer(non_blocking)
|
||||
.with_ansi(false) // 文件中不使用 ANSI 颜色
|
||||
.json() // JSON 格式便于 ELK 解析
|
||||
.init();
|
||||
info!("日志系统初始化成功,JSON格式,输出到 ./logs/");
|
||||
|
||||
let app_state = match AppState::load() {
|
||||
Ok(state) => state,
|
||||
|
||||
Reference in New Issue
Block a user