Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tracing Middleware (opentracing) #982

Closed
nicholasamorim opened this issue Apr 29, 2019 · 15 comments
Closed

Tracing Middleware (opentracing) #982

nicholasamorim opened this issue Apr 29, 2019 · 15 comments
Labels
enhancement A minor feature request request Request for new functionality

Comments

@nicholasamorim
Copy link

Is there any opentracing middleware available for Rocket?

I know that middlewares have been added since #55 has been closed but before putting in some work create this middleware, I'd like to understand if there's any implementation available or contrib repository of sorts.

@jebrosen
Copy link
Collaborator

Glancing at https://crates.io/search?q=opentracing I don't see any opentracing middleware for Rocket, and the Rust libraries for opentracing itself look stale.

If you or anyone else were to implement it in a resuable way, it might be accepted into rocket_contrib. But it will likely be easier for it get more traction as a separate crate first, similarly to rocket_cors.

@jebrosen jebrosen added enhancement A minor feature request request Request for new functionality labels Apr 30, 2019
@SergioBenitez
Copy link
Member

Exactly as @jebrosen states. Happy to accept a PR, but it's not something the project itself should take on. As such, closing out.

@oren0e
Copy link

oren0e commented Jan 4, 2022

Did anyone do something? I'm in a desperate need of something that will attach requestIDs to rocket status responses etc.
I might try to implement something myself, but I just need some guidelines like how can I access the default rocket logger etc.

@somehowchris
Copy link

@oren0e I'm not an expert on that but since Sergio is off due to personal matters let me try to help out.

Fairings are kind of middleware steps. You can mutate responses and look into requests. Tough I am not aware of any rewuest-ids stored in rocket.

@oren0e
Copy link

oren0e commented Jan 5, 2022

Thanks. about the request ids, they will probably need to be created.
But I am not sure - does the middleware should replace the native logging sort of like in tracing-actix-web crate for actix-web?

@somehowchris
Copy link

I never used actix, so what you mean with replaces the native logging?

@oren0e
Copy link

oren0e commented Jan 5, 2022

I never used actix as well, but I know it's pretty similar to rocket so I figured that I might take a look at the library in order to get some ideas for how to implement a similar middleware for rocket.
From the crate, middleware.rs doc strings:

/// `TracingLogger` is a middleware to capture structured diagnostic when processing an HTTP request.
/// Check the crate-level documentation for an in-depth introduction.
///
/// `TracingLogger` is designed as a drop-in replacement of [`actix-web`]'s [`Logger`].

@oren0e
Copy link

oren0e commented Jan 5, 2022

Bottom line of what I'm trying to say is that if someone from the rocket team is willing to help me writing this fairing then I'll try to tackle this.

@oren0e
Copy link

oren0e commented Jan 5, 2022

I've done some reading about fairings and I think the minimum satisfying implementation comes down to enriching the Request with a request_id that was created in a tracing span, so that responses like 400, 200, 500 etc. will have an id that can be traced to the original span in which it was created.

@somehowchris
Copy link

Well the this.service.call(fut) in the TracingLoggerMiddleware of tracing-actix-web can’t be translated 1:1 in rocket. What you could use instead in Rocket is the request-local-cache feature, storing and then retrieving the span.

Is there a need of the Logger as it seems to me that this is an actual stdout logger, does it have something to do with opentracing?

@oren0e
Copy link

oren0e commented Jan 5, 2022

I read about request-local-cache and it's not clear to me how do I retrieve something from the cache. My idea was:

#[derive(Clone, Copy, Debug)]
pub struct RequestId(Uuid);

impl RequestId {
    pub(crate) fn generate() -> Self {
        Self(Uuid::new_v4())
    }
}

pub struct RequestIdFairing;

impl Fairing for RequestIdFairing {
    fn info(&self) -> Info {
        Info {
            name: "Request ID Attacher",
            kind: Kind::Request | Kind::Response,
        }
    }

    fn on_request(&self, request: &mut Request, _: &Data) {
        request.local_cache(|| RequestId::generate());
    }

    fn on_response(&self, request: &Request, response: &mut Response) {
        let request_id = request.local_cache(|| RequestId); // it's not clear what should I specify here to retrieve the request_id I've stored in the on_request method
        response.set_raw_header("request_id", request_id.0);
    }
}

So the Idea with this fairing is that every request will get a request_id attached and then, in response, will retrieve this id and attach it to the response as well. But it's not working currently because clearly the retrieval is wrong:

error[E0609]: no field `0` on type `&fn(uuid::Uuid) -> RequestId {RequestId}`

I think after this works, there is indeed no need for a logger, but just to connect it to a tracing subscriber somehow.

@oren0e
Copy link

oren0e commented Jan 6, 2022

Well, I've made it work with this:

pub struct RequestIdFairing;

impl Fairing for RequestIdFairing {
    fn info(&self) -> Info {
        Info {
            name: "Request ID Attacher",
            kind: Kind::Request | Kind::Response,
        }
    }

    fn on_request(&self, request: &mut Request, _: &Data) {
        request.local_cache(|| RequestId::generate());
    }

    fn on_response(&self, request: &Request, response: &mut Response) {
        let request_id = request.local_cache(|| RequestId::generate());
        response.set_raw_header("request_id", request_id.0.to_string());
    }
}

I also have a request guard with FromRequest implemented which takes the RequestId from cache, but I am still not satisfied because I get only one log line (the response headers) with a requestID where what I want is a requestID next to each Status response logged (like 200 OK, 400 BadRequest etc.)

@somehowchris
Copy link

Due to some further questions and comment I have created the following repository https://github.com/somehowchris/rocket-tracing-fairing-example might it be of any help?

@oren0e
Copy link

oren0e commented Jan 8, 2022

Due to some further questions and comment I have created the following repository https://github.com/somehowchris/rocket-tracing-fairing-example might it be of any help?

Thanks, the repo is helpful indeed. I posted an issue there.

@ZackMattor
Copy link

@somehowchris thanks so much for putting that together! I've been recently working on instrumenting a high throughput rocket frontend and have had issues with tracing the async tasks without having access to the root spans. At a quick glance i'm not sure if your method will solve what I was seeing but i'll probably poke at it a bit sometime soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement A minor feature request request Request for new functionality
Projects
None yet
Development

No branches or pull requests

6 participants