How can I instrument async-graphql functions with tracing?

505 views Asked by At

Copying the starwars example for actix-web I'm having issues understanding these errors when trying to instrument:

#[derive(Debug)] // adding this
struct AppState {
    gql_schema: Schema<QueryRoot, EmptyMutation, EmptySubscription>, // errors here (description below)
    // other fields here...
}

async fn main() -> std::io::Result<()> {
    let schema = Schema::build(QueryRoot, EmptyMutation, EmptySubscription)
        .data(StarWars::new())
        .finish();

    println!("Playground: http://localhost:8000");

    HttpServer::new(move || {
        App::new()
            .app_data(Data::new(AppState {
                gql_schema: gql_schema.clone(), // using it here
            }))
        .service(web::resource("/").guard(guard::Post()).to(index))
        .service(web::resource("/").guard(guard::Get()).to(index_playground))
    })
    .bind("127.0.0.1:8000")?
    .run()
    .await
}

#[tracing::instrument()] // here another error
async fn index(app_state: web::Data<AppState>, req: GraphQLRequest) -> GraphQLResponse {
    app_state.gql_schema.execute(req.into_inner()).await.into()
}

the errors are:

`async_graphql::Schema<starwars::QueryRoot, async_graphql::EmptyMutation, async_graphql::EmptySubscription>` doesn't implement `std::fmt::Debug`
the trait `std::fmt::Debug` is not implemented for `async_graphql::Schema<starwars::QueryRoot, async_graphql::EmptyMutation, async_graphql::EmptySubscription>` rustc E0277

server.rs(13, 10): Error originated from macro call here
`async_graphql_actix_web::GraphQLRequest` doesn't implement `std::fmt::Debug`
the trait `std::fmt::Debug` is not implemented for `async_graphql_actix_web::GraphQLRequest`
the trait `tracing::Value` is implemented for `tracing::field::DebugValue<T>`
required because of the requirements on the impl of `std::fmt::Debug` for `&async_graphql_actix_web::GraphQLRequest`
required because of the requirements on the impl of `tracing::Value` for `tracing::field::DebugValue<&async_graphql_actix_web::GraphQLRequest>`
required for the cast to the object type `dyn tracing::Value` rustc E0277

I tried to add tracing feature too in Cargo.toml, but it's the same:

async-graphql = { version = "4.0.6", features = ["tracing"] }

How can I fix?

1

There are 1 answers

0
Dylan Anthony On

I think that, rather than attempting to #[instrument] the handler yourself, you should use the Tracing extension. This will put a span around each entry point to the schema, which you can then see whenever a tracing event is emitted from a resolver.

You already have the "tracing" feature, so you'll want to add these lines:

use async_graphql::extensions::Tracing;

let schema = Schema::build(QueryRoot, EmptyMutation, EmptySubscription)
    .data(StarWars::new())
    .extension(Tracing) // Add this line
    .finish();

I put in the line tracing::info!("Human::name"); in the Human::name resolver in the StarWars data, and got out this log line when querying it (using tracing-subcriber::fmt):

INFO request:execute:field{path=hero parent_type=QueryRoot return_type=Character!}:field{path=hero.name parent_type=Character return_type=String!}: starwars::model: Human::name