From c70994ee9db249f25fd8ea0f325dc7e80cbef173 Mon Sep 17 00:00:00 2001 From: DamonXue Date: Sun, 2 Mar 2025 19:43:47 +0800 Subject: [PATCH] feat: add proc-macro support for timed logging and update console output --- Cargo.lock | 4 ++++ rustfs/Cargo.toml | 10 ++++++++++ rustfs/src/console.rs | 9 +++++---- rustfs/src/macro/mod.rs | 39 +++++++++++++++++++++++++++++++++++++++ rustfs/src/main.rs | 33 +++++++++++++++++++-------------- 5 files changed, 77 insertions(+), 18 deletions(-) create mode 100644 rustfs/src/macro/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 7f70e83c..ab06299a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5440,11 +5440,13 @@ dependencies = [ "mime_guess", "netif", "pin-project-lite", + "proc-macro2", "prost", "prost-build", "prost-types", "protobuf", "protos", + "quote", "rmp-serde", "rust-embed", "s3s", @@ -5452,6 +5454,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "shadow-rs", + "syn 2.0.98", "time", "tokio", "tokio-stream", @@ -5565,6 +5568,7 @@ dependencies = [ "async-trait", "atoi", "base64-simd", + "block-buffer 0.11.0-rc.3", "bytes", "bytestring", "chrono", diff --git a/rustfs/Cargo.toml b/rustfs/Cargo.toml index b6fa08d1..7e715938 100644 --- a/rustfs/Cargo.toml +++ b/rustfs/Cargo.toml @@ -11,6 +11,12 @@ rust-version.workspace = true name = "rustfs" path = "src/main.rs" +# 添加proc-macro库声明 +[lib] +name = "rustfs_macro" +path = "src/macro/mod.rs" +proc-macro = true + [lints] workspace = true @@ -76,6 +82,10 @@ mime_guess = "2.0.5" rust-embed = { version = "8.5.0", features = ["interpolate-folder-path"] } local-ip-address = "0.6.3" chrono = "0.4" +# 添加proc-macro所需依赖 +proc-macro2 = "1.0" +quote = "1.0" +syn = { version = "2.0", features = ["full"] } [build-dependencies] prost-build.workspace = true diff --git a/rustfs/src/console.rs b/rustfs/src/console.rs index 6c7d64bd..e9654e85 100644 --- a/rustfs/src/console.rs +++ b/rustfs/src/console.rs @@ -8,6 +8,7 @@ use axum::{ use mime_guess::from_path; use rust_embed::RustEmbed; +use rustfs_macro::timed_println; use serde::Serialize; use shadow_rs::shadow; use tracing::info; @@ -162,10 +163,10 @@ pub async fn start_static_file_server(addrs: &str, local_ip: Ipv4Addr, access_ke let listener = tokio::net::TcpListener::bind(addrs).await.unwrap(); let local_addr = listener.local_addr().unwrap(); - info!("WebUI: http://{}:{} http://127.0.0.1:{}", - local_ip, local_addr.port(), local_addr.port()); - info!(" RootUser: {}", access_key); - info!(" RootPass: {}", secret_key); + timed_println!(format!("WebUI: http://{}:{} http://127.0.0.1:{}", + local_ip, local_addr.port(), local_addr.port())); + timed_println!(format!(" RootUser: {}", access_key)); + timed_println!(format!(" RootPass: {}", secret_key)); axum::serve(listener, app).await.unwrap(); } diff --git a/rustfs/src/macro/mod.rs b/rustfs/src/macro/mod.rs new file mode 100644 index 00000000..69122487 --- /dev/null +++ b/rustfs/src/macro/mod.rs @@ -0,0 +1,39 @@ +use proc_macro::TokenStream; +use quote::{quote, ToTokens}; +use syn::{parse_macro_input, Expr, LitStr}; + +#[proc_macro] +pub fn timed_println(input: TokenStream) -> TokenStream { + // 解析输入 + let expr = parse_macro_input!(input as Expr); + + // 生成带有时间戳的打印代码 + let expanded = quote! { + { + let now = chrono::Utc::now(); + let timestamp = now.format("%Y-%m-%dT%H:%M:%S.%6fZ"); + println!("{} rustfs: {}", timestamp, #expr); + } + }; + + TokenStream::from(expanded) +} + + +#[proc_macro] +pub fn timed_println_str(input: TokenStream) -> TokenStream { + // 尝试将输入解析为字符串字面量 + let input_str = parse_macro_input!(input as LitStr); + let str_value = input_str.value(); + + // 生成带有时间戳的打印代码 + let expanded = quote! { + { + let now = chrono::Utc::now(); + let timestamp = now.format("%Y-%m-%dT%H:%M:%S.%6fZ"); + println!("{} rustfs: {}", timestamp, #str_value); + } + }; + + TokenStream::from(expanded) +} \ No newline at end of file diff --git a/rustfs/src/main.rs b/rustfs/src/main.rs index 2748f321..257c5335 100644 --- a/rustfs/src/main.rs +++ b/rustfs/src/main.rs @@ -6,6 +6,11 @@ mod grpc; mod service; mod storage; mod utils; + +// 导入过程宏 +extern crate rustfs_macro; +use rustfs_macro::timed_println; + use crate::auth::IAMAuth; use crate::console::{init_console_cfg, CONSOLE_CONFIG}; use clap::Parser; @@ -75,11 +80,13 @@ fn check_auth(req: Request<()>) -> Result, Status> { fn print_server_info() { let cfg = CONSOLE_CONFIG.get().unwrap(); let current_year = chrono::Utc::now().year(); - info!("RustFS Object Storage Server"); - info!("Copyright: 2024-{} RustFS, Inc", current_year); - info!("License: {}", cfg.license()); - info!("Version: {}", cfg.version()); - info!("Docs: {}", cfg.doc()) + + // 使用过程宏打印服务器信息 + timed_println!("RustFS Object Storage Server"); + timed_println!(format!("Copyright: 2024-{} RustFS, Inc", current_year)); + timed_println!(format!("License: {}", cfg.license())); + timed_println!(format!("Version: {}", cfg.version())); + timed_println!(format!("Docs: {}", cfg.doc())); } fn main() -> Result<()> { @@ -139,15 +146,15 @@ async fn run(opt: config::Opt) -> Result<()> { } } - // Print MinIO-style server information - info!("RustFS Object Storage Server"); - // Detailed endpoint information (showing all API endpoints) let api_endpoints = format!("http://{}:{}", local_ip, server_port); let localhost_endpoint = format!("http://127.0.0.1:{}", server_port); - info!("API: {} {}", api_endpoints, localhost_endpoint); - info!(" RootUser: {}", opt.access_key.clone()); - info!(" RootPass: {}", opt.secret_key.clone()); + timed_println!(format!("API: {} {}", api_endpoints, localhost_endpoint)); + timed_println!(format!(" RootUser: {}", opt.access_key.clone())); + timed_println!(format!(" RootPass: {}", opt.secret_key.clone())); + if DEFAULT_ACCESS_KEY.eq(&opt.access_key) && DEFAULT_SECRET_KEY.eq(&opt.secret_key) { + warn!("Detected default credentials '{}:{}', we recommend that you change these values with 'RUSTFS_ACCESS_KEY' and 'RUSTFS_SECRET_KEY' environment variables", DEFAULT_ACCESS_KEY, DEFAULT_SECRET_KEY); + } for (i, eps) in endpoint_pools.as_ref().iter().enumerate() { info!( @@ -283,9 +290,7 @@ async fn run(opt: config::Opt) -> Result<()> { let srv_addr = format!("http://{}:{}", local_ip, server_port); init_console_cfg(&srv_addr); print_server_info(); - if DEFAULT_ACCESS_KEY.eq(&opt.access_key) && DEFAULT_SECRET_KEY.eq(&opt.secret_key) { - warn!("Detected default credentials '{}:{}', we recommend that you change these values with 'RUSTFS_ACCESS_KEY' and 'RUSTFS_SECRET_KEY' environment variables", DEFAULT_ACCESS_KEY, DEFAULT_SECRET_KEY); - } + if opt.console_enable { debug!("console is enabled");