Annotation alias? (tracing, instrument)

Is there any way to "configure" the tracing instrument macro for a module? I have a module (with some submodules) where I want a whole bunch of functions to be instrumented with consistent arguments, like so:

#[instrument(skip(state), ret(level = Level::DEBUG), err(level = Level::WARN))]
async fn handler(state: State, other: Args) -> Result<Json<T>, MyErr> {
   ...
}

... and, If I ever want to change the instrumentation, I'll probably want to do that for all those functions.

So is there any way, either in tracing or in general for declarative macros, to set those args for all the instrument annotations in a module, or to define an annotation alias so I can just say #[instrument_handle] on all the handler functions and define the details once?

I don't think there's such mechanism in general, either you need to wirte your own attribute proc-macro, or the tracing crate needs to support such uses (which I don't think it does).

Thanks for the reply, that was, unfortunately, what I thought.

if what you need can be implemented with declarative macros, you can try out the macro_rules_attribute crate, but I'm not sure if the hygiene of macro_rules would get in the way (e.g level = Level::DEBUG might not be parsable by the tracing::instrumentation proc-macro). anyway, it worth a try before you go write your own proc-macro crate, as macro_rules is much easier to deal with IMO. here's an exmaple:

macro_rules! instrument_handle {
    {
        $(#[$attr:meta])*
        async fn $name:ident ($state:ident : $State:ty, $($params:tt)*) $(-> $ret:ty)? {
            $($body:tt)*
        }
    } => {
        $(#[$attr])*
        #[instrument(skip($state), ret(level = Level::DEBUG), err(level = Level::WARN))]
        async fn $name ($state: $State, $($params)*) $(-> $ret) {
            $($body)*
        }
    }
}
2 Likes