Comments (11)
@hawkw and I chatted about instrumenting async functions. Below is a brief summary.
An async function like the one below...
async fn call(req: Request<Body>) -> Result<Response<Body>, Error>> {
// function body
}
...desugars to something like:
fn call(req: Request<Body>) -> impl Future<Output=Result<Response<Body>, Error>>> {
async move {
// function body
}
}
We can use this knowledge and a sprinkling of syn-mid to instrument an async function's future. syn-mid exposes two structs: ItemFn and Block. The latter is a block whose body is not parsed. We can use this to instrument futures emitted by an async fn
by writing something similar to:
use syn_mid::{Block, ItemFn};
use quote::quote;
use proc_macro::TokenStream;
#[proc_macro_attribute]
pub fn instrument(args: TokenStream, function: TokenStream) -> TokenStream {
let mut function: ItemFn = parse_macro_input!(body);
let body = function.body;
*function.body = quote! {
async move {
#body
}.instrument!(span)
};
function.into()
}
(cc: @yaahallo, this might be of interest to you given your interest in #15)
from tracing.
@davidbarsky yea I'm interested, I'll look into this more in depth tonight :)
from tracing.
I don't know how related this is but it does deal with the std::future::GenFuture
returned from async
functions.
I tried to write an Instrumented
implementation for std::future::Future
, but ran into issues because GenFuture
implements !Unpin
so you can't do Pin::new(inner)
if you go by the futures::Future
implementation.
I got around this by adding a boxed_instrument
method which does Box::pin(self)
and then I have an Instrumented<Pin<Box<T>>>
to handle the actual polling of that.
from tracing.
@mbilker this is definitely relevant, thanks! I think having tokio-trace-futures
support futures 0.3 is definitely a prerequisite for supporting async-await in the proc macros, thanks for looking into it. I'd love to see a branch with your solution!
from tracing.
Since I only have experience with futures 0.1, I took a look at futures 0.3 and futures::future::Future
appears to be a re-export of std::future::Future
, which means the code I have should work for futures 0.3.
from tracing.
I put up my changes at https://github.com/mbilker/tokio-trace-nursery/tree/std-future
from tracing.
If tokio-trace-futures is targeting versions before 1.33.0, then boxed_instrument
needs to have an alternate implementation to use Box::new
instead Box::pin
as Box::pin
was stabilized in 1.33.0.
from tracing.
async move {
#body
}.instrument!(span)
This isn't a thing right? As in quote!
doesn't do magic to allow postfix macros?
For context, my interest in proc-macros is based on a desire to learn them, not previous experience.
from tracing.
@yaahallo sorry, I didn't mean to do make .instrument!()
a macro! I mean to use point at something like this: https://github.com/tokio-rs/tokio-trace-nursery/blob/08db36d475c4af28821434f60d4f4ed9748452ee/tokio-trace-futures/examples/proxy_server.rs#L76
from tracing.
Erm, the entire block, which looks is:
let client_to_server = copy(client_reader, server_writer)
.and_then(|(n, _, server_writer)| {
info!(size = n);
shutdown(server_writer).map(move |_| n)
}).instrument(span!(Level::TRACE, "client_to_server"));
from tracing.
async move { #body }.instrument!(span)This isn't a thing right? As in
quote!
doesn't do magic to allow postfix macros?
Pretty sure that's a typo...
Edit: oh lol david beat me to it
from tracing.
Related Issues (20)
- multiple app instances, same log file HOT 1
- potential binary bloat caused by `matchers` HOT 2
- Level filtering is broken when depending on tracing-subscriber from crates.io HOT 7
- EnvFilters do not work when using `Vec<Box<dyn Layer>>` HOT 1
- Custom format fails to find span and trace ids only for new/close events.
- Intuition footgun: `only_key` is ignored when not assigned a value in `#[instrument(fields(only_key))]` HOT 1
- Dynamic control over tracing-flame span name HOT 2
- parsing multiple field values in EnvFilter is broken
- max_log_files canβ work HOT 7
- Add trait `StreamInstrument ` HOT 1
- Documentation bug in `FmtContext::visit_spans`
- Separate out `Timings` extension from `FmtSubscriber`
- EnvFilter lockfree implementation HOT 7
- Publish tracing-macros package?
- Add a way to dynamically set the span event configuration in a fmt::Layer
- #[instrument(ret)] behaviour does not match documentation, also reports errors HOT 6
- Consider using "WARNING" instead of "WARN" for the log level. HOT 1
- `tracing::span!` missing `fields` HOT 3
- info_span!/error_span!/warn_span! macros accept constants for field names, but `#[instrument(fields(...))]` seemingly doesnt HOT 1
- Rolling by file size HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from tracing.