Skip to content

Can not use TraceLayer from tower_http crate #438

@yotaro-shimose

Description

@yotaro-shimose

Hi.
I'm enjoying this library to create http server using lambda with rust's low memory consumption and speed.
I'm new to rust so this might be stupid question.

I want to log any (successful or failed) response in cloud watch using layer like we can in actix_web just by adding a line of code like

App::new()
    .wrap(Logger::default())
    .route("/path, web::get().to(my_handler))

So I tried

use lambda_http::{self, tower::ServiceBuilder, Error};
use lambda_http::{Request, Response};
use tower_http::trace::TraceLayer;

#[tokio::main]
async fn main() -> Result<(), Error> {
    std::env::set_var("RUST_LOG", "info");
    env_logger::init();
    let service = ServiceBuilder::new()
        .layer(TraceLayer::new_for_http())
        .service_fn(handler);
    lambda_http::run(service).await?;
    Ok(())
}

async fn handler(req: Request) -> Result<Response<String>, Error> {
    Ok(Response::new("Success".to_string()))
}

but this code does not compile.

The compiler says

the trait bound `lambda_http::Body: std::convert::From<tower_http::trace::ResponseBody<std::string::String, tower_http::classify::NeverClassifyEos<tower_http::classify::ServerErrorsFailureClass>, tower_http::trace::DefaultOnBodyChunk, tower_http::trace::DefaultOnEos, tower_http::trace::DefaultOnFailure>>` is not satisfied
the following implementations were found:
  <lambda_http::Body as std::convert::From<&'a [u8]>>
  <lambda_http::Body as std::convert::From<&'a str>>
  <lambda_http::Body as std::convert::From<()>>
  <lambda_http::Body as std::convert::From<std::borrow::Cow<'static, [u8]>>>
and 3 others
required because of the requirements on the impl of `std::convert::Into<lambda_http::Body>` for `tower_http::trace::ResponseBody<std::string::String, tower_http::classify::NeverClassifyEos<tower_http::classify::ServerErrorsFailureClass>, tower_http::trace::DefaultOnBodyChunk, tower_http::trace::DefaultOnEos, tower_http::trace::DefaultOnFailure>`
required because of the requirements on the impl of `lambda_http::IntoResponse` for `lambda_http::Response<tower_http::trace::ResponseBody<std::string::String, tower_http::classify::NeverClassifyEos<tower_http::classify::ServerErrorsFailureClass>, tower_http::trace::DefaultOnBodyChunk, tower_http::trace::DefaultOnEos, tower_http::trace::DefaultOnFailure>>`

I'm not confident but it seems the Trace service's call method's return type is not compatible with lambda_http::run;
It doesn't make sense to me because the reason we replaced handler_fn with service_fn is to reutilize existing tower services and layers.

So question is

  1. Is there any way to utilize existing logging response layer in lambda_http?
  2. Any workaround to accomplish logging response? I saw this workaround and i liked it. But I think there might be cleaner and more abstract implementation like tower's Layer.
    Any idea or suggestion is really appriciated.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions