graphql-platform icon indicating copy to clipboard operation
graphql-platform copied to clipboard

All registered diagnostic event listeners are executed regardless of which .AddGraphQLServer() they were added to

Open treet opened this issue 2 years ago • 2 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Product

Hot Chocolate

Describe the bug

When adding more than one schema through multiple calls to AddGraphQLServer(), subsequent calls to AddDiagnosticEventListener() seems to register the listener globally. If I register two listeners one for each schema both of the listeners are executed for every request, regardless of which schema/route was used. This results in logging/diagnostics/telemetry performed in the listener being duplicated.

  1. Shouldn't diagnostic event listeners added using .AddGraphQLServer().AddDiagnosticEventListener() be scoped to their respective schema?
  2. How is the AddDiagnosticEventListener() method supposed to be used when using multiple schemas?

Steps to reproduce

  1. Clone the reproduce case defined here: https://github.com/treet/hotchocolate-repro
  2. dotnet run
  3. Make any GraphQL call to one of the schemas, e.g: curl http://localhost:5041/schema1/graphql -H 'content-type: application/json' -d'{"query":"query { book { title }}"}'

Expected result: Only one message ExecuteHttpRequest of kind HttpPost should be logged by the application. Actual result: Two messages are logged, since both diagnostic events listeners were executed.

Here's the most important portion of the code:

using hotchocolate_repro;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddGraphQLServer("schema1")
    .AddQueryType<Query1>()
    .AddDiagnosticEventListener<ExampleDiagnosticsEventListener1>();

builder.Services
    .AddGraphQLServer("schema2")
    .AddQueryType<Query2>()
    .AddDiagnosticEventListener<ExampleDiagnosticsEventListener2>();

var app = builder.Build();

app
    .UseRouting()
    .UseEndpoints(endpoints =>
    {
        endpoints.MapGraphQL("/schema1", schemaName: "schema1");
        endpoints.MapGraphQL("/schema2", schemaName: "schema2");
    });

app.Run();

Relevant log output

No response

Additional Context?

No response

Version

13.2.1

treet avatar Jun 14 '23 16:06 treet

The diagnostic listeners are global dependencies and we just added this as a helper method. I can see that this is confusing in this case but there are no plans to change this for the next couple of releases.

What is your use-case?

michaelstaib avatar Jun 16 '23 13:06 michaelstaib

Our current use case is that we want telemetry and logging of all GraphQL requests. Since we're creating multiple servers/schemas we thought we had to add a listener for each invokation to AddGraphQLServer, since that's the only way of getting a reference to a IRequestExecutorBuilder which has the AddDiagnosticEventListener method.

Is there a way of reaching the IRequestExecutorBuilder without going through AddGraphQLServer? From my limited perspective it would make more sense to have a global helper extension method on IServiceCollection instead.

treet avatar Jun 19 '23 15:06 treet