Search code examples
graphqlhotchocolate

How can I log resolver/operation name and duration in HotChocolate?


I'm trying to log some basic gql method details - resolver/operation name and duration. I've started looking at using .AddHttpRequestInterceptor((context, executor, builder, ct) and getting the info from the builder, but even though I can see it in the debugger, the method name is buried in private members like: ((HotChocolate.Execution.QueryRequestBuilder)builder)._query.Document.Definitions[0].SelectionSet.Selections[0].Name.Value

I'm sure there's an easier and better way to hook into the pipeline to get the method name and log it with the call duration.

I found an article written about GraphQL.Net that uses DefaultGraphQLExecuter - public class GraphQLExecutorWithDiagnostics<TSchema> : DefaultGraphQLExecuter<TSchema> which provides an operationName parameter within the Task<ExecutionResult> ExecuteAsync( , which looks ideal.

I'll be logging to AppInsights, but that's not relevant for now, I just want to get the info first. I'm using v11.0.8


Solution

  • What you are looking for is the DiagnosticEventListener

    You can just extend this base class and override the methods that you need for you logging.

    public class CustomDiagnosticListener : DiagnosticEventListener
    {
        public override IActivityScope ExecuteRequest(IRequestContext context)
        {
            return EmptyScope;
        }
    
        public virtual IActivityScope ResolveFieldValue(IMiddlewareContext context)
        {
            return EmptyScope;
        }
    }
    

    To use this diagnostic listener you have to add it to the schema

    services.AddGraphQLServer()
        ...
       .AddDiagnosticEventListener<CustomDiagnosticListener>()
    

    In case you have dependencies that you listener has to reslove you have to reslove them manually:

    services.AddGraphQLServer()
        ...
       .AddDiagnosticEventListener<CustomDiagnosticListener>(
             sp => new CustomDiagnosticListener(
                    sp.GetApplicationService<MyDependency>()))