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

GRPC TraceLayer example with custom methods #366

Open
starsoccer opened this issue May 8, 2023 · 2 comments
Open

GRPC TraceLayer example with custom methods #366

starsoccer opened this issue May 8, 2023 · 2 comments

Comments

@starsoccer
Copy link

starsoccer commented May 8, 2023

Following the example here, I am able to create a very bare bones example of logging with grpc, but Id like to be able to define custom methods for on_request, and on_response but cant seem to figure out the correct way to do so.

Ive tried tweaking the ServiceBuilder in the above example to look as follows:

    let channel = ServiceBuilder::new()
        // Decompress response bodies
        .layer(DecompressionLayer::new())
        // Set a `User-Agent` header
        .layer(SetRequestHeaderLayer::overriding(
            header::USER_AGENT,
            HeaderValue::from_static("tonic-key-value-store"),
        ))
        // Log all requests and responses
        .layer(
           /// SECTION I CHANGED BELOW
            TraceLayer::new_for_grpc().make_span_with(DefaultMakeSpan::new().include_headers(true))
            .on_request(|request: &Request<Body>, _span: &Span| {
                tracing::debug!("started")
            }),
        )
        // Build our final `Service`
        .service(channel);

This provides an error saying:

error[E0631]: type mismatch in closure arguments
   --> src\main.rs:311:8
    |
303 |             .on_request(|request: &Request<Body>, _span: &Span| {
    |                         --------------------------------------- found signature defined here
...
311 |     Ok(KeyValueStoreClient::new(channel))
    |        ^^^^^^^^^^^^^^^^^^^^^^^^ expected due to this
    |
    = note: expected closure signature `for<'r, 's> fn(&'r hyper::Request<http_body::combinators::box_body::BoxBody<bytes::Bytes, Status>>, &'s Span) -> _`
               found closure signature `for<'r, 's> fn(&'r tonic::Request<hyper::Body>, &'s Span) -> _`
    = note: required for `[closure@src\main.rs:303:25: 303:64]` to implement `OnRequest<http_body::combinators::box_body::BoxBody<bytes::Bytes, Status>>`
    = note: required for `tower_http::trace::Trace<Channel, SharedClassifier<GrpcErrorsAsFailures>, DefaultMakeSpan, [closure@src\main.rs:303:25: 303:64]>` to implement `Service<hyper::Request<http_body::combinators::box_body::BoxBody<bytes::Bytes, Status>>>`
    = note: required for `Decompression<SetRequestHeader<tower_http::trace::Trace<Channel, SharedClassifier<GrpcErrorsAsFailures>, DefaultMakeSpan, [closure@src\main.rs:303:25: 303:64]>, HeaderValue>>` to implement `GrpcService<http_body::combinators::box_body::BoxBody<bytes::Bytes, Status>>`
@erebe
Copy link
Contributor

erebe commented May 20, 2023

Hello,

Your function need to be generic over the RequestBody. Or in your case be specific to http_body::combinators::box_body::BoxBody<bytes::Bytes, Status>>

You can use free function to introduce the generic.

    fn on_request<B>(self, request: &Request<B>,  _span: &Span) {
         tracing::debug!("started")
    }
    
    TraceLayer::new_for_grpc()
    .make_span_with(DefaultMakeSpan::new().include_headers(true))
    .on_request(on_request)

or if you want to use a lambda

    TraceLayer::new_for_grpc()
    .make_span_with(DefaultMakeSpan::new().include_headers(true))
    .on_request(|request: &Request<_>, _span: &Span| {
                    tracing::debug!("started")
                }
   )

@starsoccer
Copy link
Author

Thanks the above works, but how would I go about actually logging the request body or response body? For requests the body seems to just be Body(Streaming) and the response is just UnsyncBoxBody

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants