mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-05-25 01:10:37 +00:00
feat: enable tokio console in cluster mode (#1512)
* feat: enable tokio console subscriber * fix: resolve PR comments * fix: resolve PR comments * fix: resolve PR comments
This commit is contained in:
@@ -8,6 +8,8 @@ license.workspace = true
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
common-telemetry = { path = "../telemetry" }
|
||||
backtrace = "0.3"
|
||||
quote = "1.0"
|
||||
syn = "1.0"
|
||||
proc-macro2 = "1.0"
|
||||
|
||||
@@ -15,11 +15,13 @@
|
||||
mod range_fn;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use quote::{quote, quote_spanned};
|
||||
use quote::{quote, quote_spanned, ToTokens};
|
||||
use range_fn::process_range_fn;
|
||||
use syn::parse::Parser;
|
||||
use syn::spanned::Spanned;
|
||||
use syn::{parse_macro_input, DeriveInput, ItemStruct};
|
||||
use syn::{
|
||||
parse_macro_input, AttributeArgs, DeriveInput, ItemFn, ItemStruct, Lit, Meta, NestedMeta,
|
||||
};
|
||||
|
||||
/// Make struct implemented trait [AggrFuncTypeStore], which is necessary when writing UDAF.
|
||||
/// This derive macro is expect to be used along with attribute macro [as_aggr_func_creator].
|
||||
@@ -114,3 +116,109 @@ pub fn as_aggr_func_creator(_args: TokenStream, input: TokenStream) -> TokenStre
|
||||
pub fn range_fn(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
process_range_fn(args, input)
|
||||
}
|
||||
|
||||
/// Attribute macro to print the caller to the annotated function.
|
||||
/// The caller is printed as its filename and the call site line number.
|
||||
///
|
||||
/// This macro works like this: inject the tracking codes as the first statement to the annotated
|
||||
/// function body. The tracking codes use [backtrace-rs](https://crates.io/crates/backtrace) to get
|
||||
/// the callers. So you must dependent on the `backtrace-rs` crate.
|
||||
///
|
||||
/// # Arguments
|
||||
/// - `depth`: The max depth of call stack to print. Optional, defaults to 1.
|
||||
///
|
||||
/// # Example
|
||||
/// ```rust, ignore
|
||||
///
|
||||
/// #[print_caller(depth = 3)]
|
||||
/// fn foo() {}
|
||||
/// ```
|
||||
#[proc_macro_attribute]
|
||||
pub fn print_caller(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let mut depth = 1;
|
||||
|
||||
let args = parse_macro_input!(args as AttributeArgs);
|
||||
for meta in args.iter() {
|
||||
if let NestedMeta::Meta(Meta::NameValue(name_value)) = meta {
|
||||
let ident = name_value
|
||||
.path
|
||||
.get_ident()
|
||||
.expect("Expected an ident!")
|
||||
.to_string();
|
||||
if ident == "depth" {
|
||||
let Lit::Int(i) = &name_value.lit else { panic!("Expected 'depth' to be a valid int!") };
|
||||
depth = i.base10_parse::<usize>().expect("Invalid 'depth' value");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let tokens: TokenStream = quote! {
|
||||
{
|
||||
let curr_file = file!();
|
||||
|
||||
let bt = backtrace::Backtrace::new();
|
||||
let call_stack = bt
|
||||
.frames()
|
||||
.iter()
|
||||
.skip_while(|f| {
|
||||
!f.symbols().iter().any(|s| {
|
||||
s.filename()
|
||||
.map(|p| p.ends_with(curr_file))
|
||||
.unwrap_or(false)
|
||||
})
|
||||
})
|
||||
.skip(1)
|
||||
.take(#depth);
|
||||
|
||||
let call_stack = call_stack
|
||||
.map(|f| {
|
||||
f.symbols()
|
||||
.iter()
|
||||
.map(|s| {
|
||||
let filename = s
|
||||
.filename()
|
||||
.map(|p| format!("{:?}", p))
|
||||
.unwrap_or_else(|| "unknown".to_string());
|
||||
|
||||
let lineno = s
|
||||
.lineno()
|
||||
.map(|l| format!("{}", l))
|
||||
.unwrap_or_else(|| "unknown".to_string());
|
||||
|
||||
format!("filename: {}, lineno: {}", filename, lineno)
|
||||
})
|
||||
.collect::<Vec<String>>()
|
||||
.join(", ")
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
match call_stack.len() {
|
||||
0 => common_telemetry::info!("unable to find call stack"),
|
||||
1 => common_telemetry::info!("caller: {}", call_stack[0]),
|
||||
_ => {
|
||||
let mut s = String::new();
|
||||
s.push_str("[\n");
|
||||
for e in call_stack {
|
||||
s.push_str("\t");
|
||||
s.push_str(&e);
|
||||
s.push_str("\n");
|
||||
}
|
||||
s.push_str("]");
|
||||
common_telemetry::info!("call stack: {}", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.into();
|
||||
|
||||
let stmt = match syn::parse(tokens) {
|
||||
Ok(stmt) => stmt,
|
||||
Err(e) => return e.into_compile_error().into(),
|
||||
};
|
||||
|
||||
let mut item = parse_macro_input!(input as ItemFn);
|
||||
item.block.stmts.insert(0, stmt);
|
||||
|
||||
item.into_token_stream().into()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user