feat: add proc-macro support for timed logging and update console output

This commit is contained in:
DamonXue
2025-03-02 19:43:47 +08:00
parent 7e59bfa877
commit 145bb6ac7c
5 changed files with 77 additions and 18 deletions
Generated
+4
View File
@@ -5440,11 +5440,13 @@ dependencies = [
"mime_guess", "mime_guess",
"netif", "netif",
"pin-project-lite", "pin-project-lite",
"proc-macro2",
"prost", "prost",
"prost-build", "prost-build",
"prost-types", "prost-types",
"protobuf", "protobuf",
"protos", "protos",
"quote",
"rmp-serde", "rmp-serde",
"rust-embed", "rust-embed",
"s3s", "s3s",
@@ -5452,6 +5454,7 @@ dependencies = [
"serde_json", "serde_json",
"serde_urlencoded", "serde_urlencoded",
"shadow-rs", "shadow-rs",
"syn 2.0.98",
"time", "time",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
@@ -5565,6 +5568,7 @@ dependencies = [
"async-trait", "async-trait",
"atoi", "atoi",
"base64-simd", "base64-simd",
"block-buffer 0.11.0-rc.3",
"bytes", "bytes",
"bytestring", "bytestring",
"chrono", "chrono",
+10
View File
@@ -11,6 +11,12 @@ rust-version.workspace = true
name = "rustfs" name = "rustfs"
path = "src/main.rs" path = "src/main.rs"
# 添加proc-macro库声明
[lib]
name = "rustfs_macro"
path = "src/macro/mod.rs"
proc-macro = true
[lints] [lints]
workspace = true workspace = true
@@ -76,6 +82,10 @@ mime_guess = "2.0.5"
rust-embed = { version = "8.5.0", features = ["interpolate-folder-path"] } rust-embed = { version = "8.5.0", features = ["interpolate-folder-path"] }
local-ip-address = "0.6.3" local-ip-address = "0.6.3"
chrono = "0.4" chrono = "0.4"
# 添加proc-macro所需依赖
proc-macro2 = "1.0"
quote = "1.0"
syn = { version = "2.0", features = ["full"] }
[build-dependencies] [build-dependencies]
prost-build.workspace = true prost-build.workspace = true
+5 -4
View File
@@ -8,6 +8,7 @@ use axum::{
use mime_guess::from_path; use mime_guess::from_path;
use rust_embed::RustEmbed; use rust_embed::RustEmbed;
use rustfs_macro::timed_println;
use serde::Serialize; use serde::Serialize;
use shadow_rs::shadow; use shadow_rs::shadow;
use tracing::info; 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 listener = tokio::net::TcpListener::bind(addrs).await.unwrap();
let local_addr = listener.local_addr().unwrap(); let local_addr = listener.local_addr().unwrap();
info!("WebUI: http://{}:{} http://127.0.0.1:{}", timed_println!(format!("WebUI: http://{}:{} http://127.0.0.1:{}",
local_ip, local_addr.port(), local_addr.port()); local_ip, local_addr.port(), local_addr.port()));
info!(" RootUser: {}", access_key); timed_println!(format!(" RootUser: {}", access_key));
info!(" RootPass: {}", secret_key); timed_println!(format!(" RootPass: {}", secret_key));
axum::serve(listener, app).await.unwrap(); axum::serve(listener, app).await.unwrap();
} }
+39
View File
@@ -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)
}
+19 -14
View File
@@ -6,6 +6,11 @@ mod grpc;
mod service; mod service;
mod storage; mod storage;
mod utils; mod utils;
// 导入过程宏
extern crate rustfs_macro;
use rustfs_macro::timed_println;
use crate::auth::IAMAuth; use crate::auth::IAMAuth;
use crate::console::{init_console_cfg, CONSOLE_CONFIG}; use crate::console::{init_console_cfg, CONSOLE_CONFIG};
use clap::Parser; use clap::Parser;
@@ -75,11 +80,13 @@ fn check_auth(req: Request<()>) -> Result<Request<()>, Status> {
fn print_server_info() { fn print_server_info() {
let cfg = CONSOLE_CONFIG.get().unwrap(); let cfg = CONSOLE_CONFIG.get().unwrap();
let current_year = chrono::Utc::now().year(); let current_year = chrono::Utc::now().year();
info!("RustFS Object Storage Server");
info!("Copyright: 2024-{} RustFS, Inc", current_year); // 使用过程宏打印服务器信息
info!("License: {}", cfg.license()); timed_println!("RustFS Object Storage Server");
info!("Version: {}", cfg.version()); timed_println!(format!("Copyright: 2024-{} RustFS, Inc", current_year));
info!("Docs: {}", cfg.doc()) timed_println!(format!("License: {}", cfg.license()));
timed_println!(format!("Version: {}", cfg.version()));
timed_println!(format!("Docs: {}", cfg.doc()));
} }
fn main() -> Result<()> { fn main() -> Result<()> {
@@ -139,15 +146,15 @@ async fn run(opt: config::Opt) -> Result<()> {
} }
} }
// Print RustFS-style server information
info!("RustFS Object Storage Server");
// Detailed endpoint information (showing all API endpoints) // Detailed endpoint information (showing all API endpoints)
let api_endpoints = format!("http://{}:{}", local_ip, server_port); let api_endpoints = format!("http://{}:{}", local_ip, server_port);
let localhost_endpoint = format!("http://127.0.0.1:{}", server_port); let localhost_endpoint = format!("http://127.0.0.1:{}", server_port);
info!("API: {} {}", api_endpoints, localhost_endpoint); timed_println!(format!("API: {} {}", api_endpoints, localhost_endpoint));
info!(" RootUser: {}", opt.access_key.clone()); timed_println!(format!(" RootUser: {}", opt.access_key.clone()));
info!(" RootPass: {}", opt.secret_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() { for (i, eps) in endpoint_pools.as_ref().iter().enumerate() {
info!( info!(
@@ -283,9 +290,7 @@ async fn run(opt: config::Opt) -> Result<()> {
let srv_addr = format!("http://{}:{}", local_ip, server_port); let srv_addr = format!("http://{}:{}", local_ip, server_port);
init_console_cfg(&srv_addr); init_console_cfg(&srv_addr);
print_server_info(); 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 { if opt.console_enable {
debug!("console is enabled"); debug!("console is enabled");