diff --git a/src/All.slnx b/src/All.slnx
index 5e0b2b5508e..2603e79eaf4 100644
--- a/src/All.slnx
+++ b/src/All.slnx
@@ -173,6 +173,7 @@
+
diff --git a/src/HotChocolate/Core/src/Execution.Abstractions/Path.cs b/src/HotChocolate/Core/src/Execution.Abstractions/Path.cs
index 506e38d3417..e4f1644a208 100644
--- a/src/HotChocolate/Core/src/Execution.Abstractions/Path.cs
+++ b/src/HotChocolate/Core/src/Execution.Abstractions/Path.cs
@@ -131,7 +131,7 @@ public string Print()
{
if (this is RootPathSegment)
{
- return "/";
+ return string.Empty;
}
// On first pass we calculate the total length
@@ -147,7 +147,11 @@ public string Print()
break;
case NamePathSegment name:
- totalLength += 1 + name.Name.Length; // '/' + name
+ totalLength += name.Name.Length;
+ if (current.Parent is not RootPathSegment)
+ {
+ totalLength++;
+ }
break;
default:
@@ -158,10 +162,13 @@ public string Print()
}
// On second pass we fill from right to left using string.Create
- return string.Create(totalLength, this, static (span, path) =>
+ return string.Create(
+ totalLength,
+ this,
+ static (span, state) =>
{
var pos = span.Length;
- var current = path;
+ var current = state;
while (current is not RootPathSegment)
{
@@ -188,7 +195,10 @@ public string Print()
case NamePathSegment name:
pos -= name.Name.Length;
name.Name.AsSpan().CopyTo(span[pos..]);
- span[--pos] = '/';
+ if (current.Parent is not RootPathSegment)
+ {
+ span[--pos] = '.';
+ }
break;
}
diff --git a/src/HotChocolate/Core/src/Types/Execution/Instrumentation/AggregateExecutionDiagnosticEvents.cs b/src/HotChocolate/Core/src/Types/Execution/Instrumentation/AggregateExecutionDiagnosticEvents.cs
index 6b7d1a7c81e..b05de0028f0 100644
--- a/src/HotChocolate/Core/src/Types/Execution/Instrumentation/AggregateExecutionDiagnosticEvents.cs
+++ b/src/HotChocolate/Core/src/Types/Execution/Instrumentation/AggregateExecutionDiagnosticEvents.cs
@@ -186,30 +186,6 @@ public IDisposable ExecuteOperation(RequestContext context)
return new AggregateActivityScope(scopes);
}
- public IDisposable ExecuteStream(IOperation operation)
- {
- var scopes = new IDisposable[_listeners.Length];
-
- for (var i = 0; i < _listeners.Length; i++)
- {
- scopes[i] = _listeners[i].ExecuteStream(operation);
- }
-
- return new AggregateActivityScope(scopes);
- }
-
- public IDisposable ExecuteDeferredTask()
- {
- var scopes = new IDisposable[_listeners.Length];
-
- for (var i = 0; i < _listeners.Length; i++)
- {
- scopes[i] = _listeners[i].ExecuteDeferredTask();
- }
-
- return new AggregateActivityScope(scopes);
- }
-
public IDisposable ResolveFieldValue(IMiddlewareContext context)
{
if (_resolverListener.Length == 0)
@@ -235,14 +211,6 @@ public void ResolverError(IMiddlewareContext context, IError error)
}
}
- public void ResolverError(RequestContext context, ISelection selection, IError error)
- {
- for (var i = 0; i < _listeners.Length; i++)
- {
- _listeners[i].ResolverError(context, selection, error);
- }
- }
-
public IDisposable RunTask(IExecutionTask task)
{
if (_resolverListener.Length == 0)
@@ -316,18 +284,6 @@ public void SubscriptionEventError(RequestContext context, ulong subscriptionId,
}
}
- public IDisposable DispatchBatch(RequestContext context)
- {
- var scopes = new IDisposable[_listeners.Length];
-
- for (var i = 0; i < _listeners.Length; i++)
- {
- scopes[i] = _listeners[i].DispatchBatch(context);
- }
-
- return new AggregateActivityScope(scopes);
- }
-
public void ExecutorCreated(string name, IRequestExecutor executor)
{
for (var i = 0; i < _listeners.Length; i++)
diff --git a/src/HotChocolate/Core/src/Types/Execution/Instrumentation/IExecutionDiagnosticEvents.cs b/src/HotChocolate/Core/src/Types/Execution/Instrumentation/IExecutionDiagnosticEvents.cs
index c5082be738b..99d7bcd44c9 100644
--- a/src/HotChocolate/Core/src/Types/Execution/Instrumentation/IExecutionDiagnosticEvents.cs
+++ b/src/HotChocolate/Core/src/Types/Execution/Instrumentation/IExecutionDiagnosticEvents.cs
@@ -79,29 +79,6 @@ public interface IExecutionDiagnosticEvents : ICoreExecutionDiagnosticEvents
///
IDisposable CompileOperation(RequestContext context);
- ///
- /// Called within the execute operation scope when the result is a streamed result.
- /// The ExecuteStream scope will run longer than the ExecuteOperation scope.
- /// The ExecuteOperation scope completes once the initial operation is executed,
- /// while all deferred elements are executed and delivered within the ExecuteStream scope.
- ///
- ///
- /// The compiled operation that is being streamed.
- ///
- ///
- /// A scope that will be disposed when the streaming execution has finished.
- ///
- IDisposable ExecuteStream(IOperation operation);
-
- ///
- /// Called when starting to execute a deferred part of an operation
- /// within the ExecuteStream scope or ExecuteSubscription scope.
- ///
- ///
- /// A scope that will be disposed when the deferred task execution has finished.
- ///
- IDisposable ExecuteDeferredTask();
-
///
/// Called when starting to resolve a field value.
///
@@ -131,26 +108,6 @@ public interface IExecutionDiagnosticEvents : ICoreExecutionDiagnosticEvents
///
void ResolverError(IMiddlewareContext context, IError error);
- ///
- /// Called for field errors that occur outside the resolver task execution,
- /// typically during result processing or validation.
- ///
- ///
- /// The request context encapsulates all GraphQL-specific information about an
- /// individual GraphQL request.
- ///
- ///
- /// The field selection that is affected by the error.
- ///
- ///
- /// The error that occurred during field processing.
- ///
- ///
- /// Some field-level errors are handled after the resolver completes and these
- /// are processed in the request scope rather than the resolver scope.
- ///
- void ResolverError(RequestContext context, ISelection selection, IError error);
-
///
/// Called when starting to execute an execution engine task.
///
@@ -215,19 +172,4 @@ public interface IExecutionDiagnosticEvents : ICoreExecutionDiagnosticEvents
/// individual GraphQL request.
///
void RetrievedOperationFromCache(RequestContext context);
-
- ///
- /// Called when the execution engine dispatches deferred execution batches.
- /// During execution, components like DataLoader defer data resolver execution
- /// to be processed in batches. When the execution engine has no immediate work,
- /// these batches are dispatched for execution.
- ///
- ///
- /// The request context encapsulates all GraphQL-specific information about an
- /// individual GraphQL request.
- ///
- ///
- /// A scope that will be disposed when the batch dispatch has finished.
- ///
- IDisposable DispatchBatch(RequestContext context);
}
diff --git a/src/HotChocolate/Core/test/Execution.Abstractions.Tests/ErrorBuilderTests.cs b/src/HotChocolate/Core/test/Execution.Abstractions.Tests/ErrorBuilderTests.cs
index f4ef80d374f..b057bc5eeb4 100644
--- a/src/HotChocolate/Core/test/Execution.Abstractions.Tests/ErrorBuilderTests.cs
+++ b/src/HotChocolate/Core/test/Execution.Abstractions.Tests/ErrorBuilderTests.cs
@@ -192,7 +192,7 @@ public void SetPath_Foo_PathIsFooWithCount1()
.Build();
// assert
- Assert.Equal("/foo", error.Path?.Print());
+ Assert.Equal("foo", error.Path?.Print());
}
[Fact]
@@ -206,7 +206,7 @@ public void SetPathObject_Foo_PathIsFooWithCount1()
.Build();
// assert
- Assert.Equal("/foo", error.Path?.Print());
+ Assert.Equal("foo", error.Path?.Print());
}
[Fact]
diff --git a/src/HotChocolate/Core/test/Execution.Abstractions.Tests/ErrorTests.cs b/src/HotChocolate/Core/test/Execution.Abstractions.Tests/ErrorTests.cs
index c3492e593dc..545a35c5fe6 100644
--- a/src/HotChocolate/Core/test/Execution.Abstractions.Tests/ErrorTests.cs
+++ b/src/HotChocolate/Core/test/Execution.Abstractions.Tests/ErrorTests.cs
@@ -204,6 +204,6 @@ public void WithPath()
error = error.WithPath(Path.FromList(["foo"]));
// assert
- Assert.Equal("/foo", error.Path!.Print());
+ Assert.Equal("foo", error.Path!.Print());
}
}
diff --git a/src/HotChocolate/Core/test/Execution.Abstractions.Tests/PathTests.cs b/src/HotChocolate/Core/test/Execution.Abstractions.Tests/PathTests.cs
index e1edf4dada5..7b8058db7e4 100644
--- a/src/HotChocolate/Core/test/Execution.Abstractions.Tests/PathTests.cs
+++ b/src/HotChocolate/Core/test/Execution.Abstractions.Tests/PathTests.cs
@@ -28,7 +28,30 @@ public void Path_ToString()
var result = path.ToString();
// assert
- Assert.Equal("/hero/friends[0]/name", result);
+ Assert.Equal("hero.friends[0].name", result);
+ }
+
+ [Fact]
+ public void Path_Print()
+ {
+ // arrange
+ var path = Path.Root.Append("person").Append(0).Append("address");
+
+ // act
+ var result = path.Print();
+
+ // assert
+ Assert.Equal("person[0].address", result);
+ }
+
+ [Fact]
+ public void Path_Print_Root()
+ {
+ // act
+ var result = Path.Root.Print();
+
+ // assert
+ Assert.Equal(string.Empty, result);
}
[Fact]
@@ -172,12 +195,12 @@ public void Complex_Ordering()
string[] expected =
[
- "/bar",
- "/bar[3]",
- "/bar[3][2]",
- "/bar[3]/foo",
- "/foo",
- "/foo[0]"
+ "bar",
+ "bar[3]",
+ "bar[3][2]",
+ "bar[3].foo",
+ "foo",
+ "foo[0]"
];
for (var i = 0; i < paths.Length; i++)
diff --git a/src/HotChocolate/Core/test/Execution.Tests/ArgumentNonNullValidatorTests.cs b/src/HotChocolate/Core/test/Execution.Tests/ArgumentNonNullValidatorTests.cs
index 204f3bc70c7..b18252aa979 100644
--- a/src/HotChocolate/Core/test/Execution.Tests/ArgumentNonNullValidatorTests.cs
+++ b/src/HotChocolate/Core/test/Execution.Tests/ArgumentNonNullValidatorTests.cs
@@ -62,6 +62,6 @@ input Bar {
// assert
Assert.True(report.HasErrors);
- Assert.Equal("/root/a", report.Path.ToString());
+ Assert.Equal("root.a", report.Path.ToString());
}
}
diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/DirectiveTypeTests.Directive_ValidateArgs_ArgMissing.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/DirectiveTypeTests.Directive_ValidateArgs_ArgMissing.snap
index f15f7688408..8d6c72af09c 100644
--- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/DirectiveTypeTests.Directive_ValidateArgs_ArgMissing.snap
+++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/DirectiveTypeTests.Directive_ValidateArgs_ArgMissing.snap
@@ -1,2 +1,2 @@
-The directive arguments have invalid values: 'The required input field `d` is missing.' at /d.
+The directive arguments have invalid values: 'The required input field `d` is missing.' at d.
@a
diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/DirectiveTypeTests.Directive_ValidateArgs_InvalidArg.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/DirectiveTypeTests.Directive_ValidateArgs_InvalidArg.snap
index f0be062aa3e..800f228a1b0 100644
--- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/DirectiveTypeTests.Directive_ValidateArgs_InvalidArg.snap
+++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/DirectiveTypeTests.Directive_ValidateArgs_InvalidArg.snap
@@ -1,2 +1,2 @@
-The directive arguments have invalid values: 'Int cannot coerce the given literal of type `BooleanValue` to a runtime value.' at /e.
+The directive arguments have invalid values: 'Int cannot coerce the given literal of type `BooleanValue` to a runtime value.' at e.
@a(d: 1, e: true)
diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/DirectiveTypeTests.Directive_ValidateArgs_NonNullArgIsNull.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/DirectiveTypeTests.Directive_ValidateArgs_NonNullArgIsNull.snap
index 5f94dc0e628..1e61efe51b6 100644
--- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/DirectiveTypeTests.Directive_ValidateArgs_NonNullArgIsNull.snap
+++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/DirectiveTypeTests.Directive_ValidateArgs_NonNullArgIsNull.snap
@@ -1,2 +1,2 @@
-The directive arguments have invalid values: 'Cannot accept null for non-nullable input.' at /d.
+The directive arguments have invalid values: 'Cannot accept null for non-nullable input.' at d.
@a(d: null)
diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/DirectiveTypeTests.Directive_ValidateArgs_Overflow.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/DirectiveTypeTests.Directive_ValidateArgs_Overflow.snap
index 47d5dd351d8..1bba165cbe6 100644
--- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/DirectiveTypeTests.Directive_ValidateArgs_Overflow.snap
+++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/DirectiveTypeTests.Directive_ValidateArgs_Overflow.snap
@@ -1,2 +1,2 @@
-The directive arguments have invalid values: 'Int cannot coerce the given literal of type `IntValue` to a runtime value.' at /d.
+The directive arguments have invalid values: 'Int cannot coerce the given literal of type `IntValue` to a runtime value.' at d.
@a(d: 9223372036854775807)
diff --git a/src/HotChocolate/Diagnostics/HotChocolate.Diagnostics.slnx b/src/HotChocolate/Diagnostics/HotChocolate.Diagnostics.slnx
index 3c4f93bf3f9..a1b11b2c50d 100644
--- a/src/HotChocolate/Diagnostics/HotChocolate.Diagnostics.slnx
+++ b/src/HotChocolate/Diagnostics/HotChocolate.Diagnostics.slnx
@@ -1,6 +1,7 @@
+
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics.Core/ActivityEnricherBase.cs b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/ActivityEnricherBase.cs
new file mode 100644
index 00000000000..a5f9fab1732
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/ActivityEnricherBase.cs
@@ -0,0 +1,103 @@
+using System.Diagnostics;
+using Microsoft.AspNetCore.Http;
+using HotChocolate.AspNetCore.Instrumentation;
+using HotChocolate.Execution;
+using HotChocolate.Language;
+
+namespace HotChocolate.Diagnostics;
+
+///
+/// Base class for activity enrichers that allows adding additional information
+/// to the activity spans created by the diagnostics system.
+///
+public abstract class ActivityEnricherBase
+{
+ public virtual void EnrichExecuteHttpRequest(
+ HttpContext httpContext,
+ HttpRequestKind kind,
+ Activity activity) { }
+
+ public virtual void EnrichSingleRequest(
+ HttpContext httpContext,
+ GraphQLRequest request,
+ Activity activity) { }
+
+ public virtual void EnrichBatchRequest(
+ HttpContext httpContext,
+ IReadOnlyList batch,
+ Activity activity) { }
+
+ public virtual void EnrichOperationBatchRequest(
+ HttpContext httpContext,
+ GraphQLRequest request,
+ IReadOnlyList operations,
+ Activity activity) { }
+
+ public virtual void EnrichHttpRequestError(
+ HttpContext httpContext,
+ IError error,
+ Activity activity) { }
+
+ public virtual void EnrichHttpRequestError(
+ HttpContext httpContext,
+ Exception exception,
+ Activity activity) { }
+
+ public virtual void EnrichParseHttpRequest(
+ HttpContext httpContext,
+ Activity activity) { }
+
+ public virtual void EnrichParserErrors(
+ HttpContext httpContext,
+ IReadOnlyList errors,
+ Activity activity) { }
+
+ public virtual void EnrichFormatHttpResponse(
+ HttpContext httpContext,
+ Activity activity) { }
+
+ public virtual void EnrichExecuteRequest(
+ RequestContext context,
+ Activity activity) { }
+
+ public virtual void EnrichRequestError(
+ RequestContext context,
+ Exception exception,
+ Activity activity) { }
+
+ public virtual void EnrichRequestError(
+ RequestContext context,
+ IError error,
+ Activity activity) { }
+
+ public virtual void EnrichParseDocument(
+ RequestContext context,
+ Activity activity) { }
+
+ public virtual void EnrichValidateDocument(
+ RequestContext context,
+ Activity activity) { }
+
+ public virtual void EnrichValidationErrors(
+ RequestContext context,
+ IReadOnlyList errors,
+ Activity activity) { }
+
+ public virtual void EnrichAnalyzeOperationCost(
+ RequestContext context,
+ Activity activity) { }
+
+ public virtual void EnrichOperationCost(
+ RequestContext context,
+ double fieldCost,
+ double typeCost,
+ Activity activity) { }
+
+ public virtual void EnrichCoerceVariables(
+ RequestContext context,
+ Activity activity) { }
+
+ public virtual void EnrichExecuteOperation(
+ RequestContext context,
+ Activity activity) { }
+}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Extensions/ActivityExtensions.cs b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Extensions/ActivityExtensions.cs
new file mode 100644
index 00000000000..7a1e602c086
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Extensions/ActivityExtensions.cs
@@ -0,0 +1,105 @@
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using HotChocolate.Execution;
+using HotChocolate.Language;
+
+namespace HotChocolate.Diagnostics;
+
+internal static class ActivityExtensions
+{
+ extension(Activity activity)
+ {
+#if !NET9_0_OR_GREATER
+ public void AddException(Exception exception)
+ {
+ activity.AddEvent(
+ new ActivityEvent(
+ "exception",
+ tags: new ActivityTagsCollection
+ {
+ { "exception.message", exception.Message },
+ { "exception.stacktrace", exception.ToString() },
+ { "exception.type", exception.GetType().ToString() }
+ }));
+ }
+#endif
+
+ public void AddGraphQLError(IError error)
+ {
+ var tags = new ActivityTagsCollection
+ {
+ [SemanticConventions.GraphQL.Error.Message] = error.Message
+ };
+
+ if (error.Exception is { } exception)
+ {
+ tags["exception.message"] = exception.Message;
+ tags["exception.stacktrace"] = exception.ToString();
+ tags["exception.type"] = exception.GetType().ToString();
+ }
+
+ if (error.Path is not null)
+ {
+ tags[SemanticConventions.GraphQL.Error.Path] = error.Path.Print();
+ }
+
+ if (!string.IsNullOrEmpty(error.Code))
+ {
+ tags[SemanticConventions.GraphQL.Error.Code] = error.Code;
+ }
+
+ if (error.Locations is { Count: > 0 })
+ {
+ var locations = new object[error.Locations.Count];
+ for (var i = 0; i < error.Locations.Count; i++)
+ {
+ var location = error.Locations[i];
+ locations[i] = new Dictionary
+ {
+ [SemanticConventions.GraphQL.Error.Location.Line] = location.Line,
+ [SemanticConventions.GraphQL.Error.Location.Column] = location.Column
+ };
+ }
+
+ tags[SemanticConventions.GraphQL.Error.Locations] = locations;
+ }
+
+ activity.AddEvent(new ActivityEvent("exception", default, tags));
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void EnrichDocumentInfo(OperationDocumentInfo documentInfo)
+ {
+ var hash = documentInfo.Hash;
+
+ if (!hash.IsEmpty)
+ {
+ activity.SetTag(
+ SemanticConventions.GraphQL.Document.Hash,
+ $"{hash.AlgorithmName}:{hash.Value}");
+ }
+
+ if (documentInfo is { IsPersisted: true, Id.HasValue: true })
+ {
+ activity.SetTag(
+ SemanticConventions.GraphQL.Document.Id,
+ documentInfo.Id.Value);
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void EnrichOperation(OperationType operationType, string? operationName)
+ {
+ activity.SetTag(
+ SemanticConventions.GraphQL.Operation.Type,
+ SemanticConventions.GraphQL.Operation.TypeValues[operationType]);
+
+ if (!string.IsNullOrEmpty(operationName))
+ {
+ activity.SetTag(
+ SemanticConventions.GraphQL.Operation.Name,
+ operationName);
+ }
+ }
+ }
+}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics.Core/HotChocolate.Diagnostics.Core.csproj b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/HotChocolate.Diagnostics.Core.csproj
new file mode 100644
index 00000000000..51a678de338
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/HotChocolate.Diagnostics.Core.csproj
@@ -0,0 +1,26 @@
+
+
+
+ HotChocolate.Diagnostics.Core
+ HotChocolate.Diagnostics.Core
+ HotChocolate.Diagnostics
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics.Core/InstrumentationOptionsBase.cs b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/InstrumentationOptionsBase.cs
new file mode 100644
index 00000000000..adbdac41253
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/InstrumentationOptionsBase.cs
@@ -0,0 +1,16 @@
+namespace HotChocolate.Diagnostics;
+
+public abstract class InstrumentationOptionsBase
+{
+ ///
+ /// Specifies the request details that shall be included into the tracing activities.
+ ///
+ public RequestDetails RequestDetails { get; set; } = RequestDetails.Default;
+
+ ///
+ /// Specifies if the parsed document shall be included into the tracing data.
+ ///
+ public bool IncludeDocument { get; set; }
+
+ internal bool IncludeRequestDetails => RequestDetails is not RequestDetails.None;
+}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics.Core/RequestDetails.cs b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/RequestDetails.cs
new file mode 100644
index 00000000000..5ae53788ea1
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/RequestDetails.cs
@@ -0,0 +1,15 @@
+namespace HotChocolate.Diagnostics;
+
+[Flags]
+public enum RequestDetails
+{
+ None = 0,
+ Id = 1,
+ Hash = 2,
+ OperationName = 4,
+ Variables = 8,
+ Extensions = 16,
+ Document = 32,
+ Default = Id | Hash | OperationName | Extensions,
+ All = Id | Hash | OperationName | Variables | Extensions | Document
+}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics.Core/SemanticConventions.cs b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/SemanticConventions.cs
new file mode 100644
index 00000000000..a51c1e5d158
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/SemanticConventions.cs
@@ -0,0 +1,202 @@
+using System.Collections.Frozen;
+using HotChocolate.Language;
+
+namespace HotChocolate.Diagnostics;
+
+internal static class SemanticConventions
+{
+ public static class GraphQL
+ {
+ public static class Document
+ {
+ public const string Id = "graphql.document.id";
+ public const string Hash = "graphql.document.hash";
+
+ // Note: This is not part of the OTEL semantic conventions
+ public const string Body = "graphql.document.body";
+
+ // Note: This is not part of the OTEL semantic conventions
+ public const string Valid = "graphql.document.valid";
+ }
+
+ public static class Operation
+ {
+ // Note: This is not part of the OTEL semantic conventions
+ public const string Id = "graphql.operation.id";
+
+ public const string Name = "graphql.operation.name";
+ public const string Type = "graphql.operation.type";
+
+ // Note: This is not part of the OTEL semantic conventions
+ public const string FieldCost = "graphql.operation.fieldCost";
+
+ // Note: This is not part of the OTEL semantic conventions
+ public const string TypeCost = "graphql.operation.typeCost";
+
+ public static FrozenDictionary TypeValues { get; } =
+ new Dictionary
+ {
+ [OperationType.Query] = "query",
+ [OperationType.Mutation] = "mutation",
+ [OperationType.Subscription] = "subscription"
+ }.ToFrozenDictionary();
+
+ public static class Step
+ {
+ public const string Id = "graphql.operation.step.id";
+ public const string Kind = "graphql.operation.step.kind";
+
+ // Note: This is not part of the OTEL semantic conventions
+ public static class KindValues
+ {
+ public const string Operation = "operation";
+ public const string OperationBatch = "operation_batch";
+ public const string Introspection = "introspection";
+ public const string Node = "node";
+ }
+
+ public static class Plan
+ {
+ public const string Id = "graphql.operation.step.plan.id";
+ }
+ }
+ }
+
+ public static class Processing
+ {
+ public const string Type = "graphql.processing.type";
+
+ public static class TypeValues
+ {
+ public const string Parse = "parse";
+ public const string Validate = "validate";
+ public const string VariableCoercion = "variable_coercion";
+ public const string Plan = "plan";
+ public const string Execute = "execute";
+ public const string StepExecute = "step_execute";
+ public const string Resolve = "resolve";
+ public const string DataLoaderDispatch = "dataloader_dispatch";
+ public const string DataLoaderBatch = "dataloader_batch";
+ }
+ }
+
+ public static class Selection
+ {
+ public const string Name = "graphql.selection.name";
+ public const string Path = "graphql.selection.path";
+
+ // Note: This is not part of the OTEL semantic conventions
+ public const string Hierarchy = "graphql.selection.hierarchy";
+
+ public static class Field
+ {
+ public const string Name = "graphql.selection.field.name";
+ public const string ParentType = "graphql.selection.field.parent_type";
+ public const string Coordinate = "graphql.selection.field.coordinate";
+
+ // Note: This is not part of the OTEL semantic conventions
+ public const string IsDeprecated = "graphql.selection.field.isDeprecated";
+
+ // Note: This is not part of the OTEL semantic conventions
+ public const string Type = "graphql.selection.type";
+ }
+ }
+
+ public static class DataLoader
+ {
+ public const string Name = "graphql.dataloader.name";
+
+ public static class Batch
+ {
+ public const string Size = "graphql.dataloader.batch.size";
+ public const string Keys = "graphql.dataloader.batch.keys";
+ }
+
+ public static class Cache
+ {
+ public const string HitCount = "graphql.dataloader.cache.hit_count";
+ public const string MissCount = "graphql.dataloader.cache.miss_count";
+ }
+ }
+
+ public static class Source
+ {
+ public const string Name = "graphql.source.name";
+ public const string Id = "graphql.source.id";
+
+ public static class Operation
+ {
+ public const string Name = "graphql.source.operation.name";
+ public const string Kind = "graphql.source.operation.kind";
+ public const string Hash = "graphql.source.operation.hash";
+ }
+ }
+
+ public static class Error
+ {
+ public const string Message = "graphql.error.message";
+ public const string Locations = "graphql.error.locations";
+ public const string Path = "graphql.error.path";
+ public const string Code = "graphql.error.code";
+
+ public static class Location
+ {
+ public const string Column = "column";
+ public const string Line = "line";
+ }
+ }
+
+ public static class Subscription
+ {
+ public const string Id = "graphql.subscription.id";
+ }
+
+ // Note: This is not part of the OTEL semantic conventions
+ public static class Http
+ {
+ public const string Kind = "graphql.http.kind";
+
+ public static class Request
+ {
+ public const string Type = "graphql.http.request.type";
+ public const string QueryId = "graphql.http.request.query.id";
+ public const string QueryHash = "graphql.http.request.query.hash";
+ public const string QueryBody = "graphql.http.request.query.body";
+ public const string OperationName = "graphql.http.request.operation";
+ public const string Operations = "graphql.http.request.operations";
+ public const string Variables = "graphql.http.request.variables";
+ public const string Extensions = "graphql.http.request.extensions";
+
+ // Note: This is not part of the OTEL semantic conventions
+ public static class Types
+ {
+ public const string Single = "single";
+ public const string Batch = "batch";
+ public const string OperationBatch = "operation_batch";
+ }
+
+ // Note: This is not part of the OTEL semantic conventions
+ public static class BatchRequest
+ {
+ public static string QueryId(int index) => $"graphql.http.request[{index}].query.id";
+
+ public static string QueryHash(int index) => $"graphql.http.request[{index}].query.hash";
+
+ public static string QueryBody(int index) => $"graphql.http.request[{index}].query.body";
+
+ public static string OperationName(int index) => $"graphql.http.request[{index}].operation";
+
+ public static string Variables(int index) => $"graphql.http.request[{index}].variables";
+
+ public static string Extensions(int index) => $"graphql.http.request[{index}].extensions";
+ }
+ }
+ }
+
+ // Note: This is not part of the OTEL semantic conventions
+ public static class Schema
+ {
+ public const string Name = "graphql.schema.name";
+ }
+ }
+}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/AnalyzeOperationComplexitySpan.cs b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/AnalyzeOperationComplexitySpan.cs
new file mode 100644
index 00000000000..ad2a778f7c7
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/AnalyzeOperationComplexitySpan.cs
@@ -0,0 +1,50 @@
+using System.Diagnostics;
+using HotChocolate.Execution;
+using static HotChocolate.Diagnostics.SemanticConventions;
+
+namespace HotChocolate.Diagnostics;
+
+internal sealed class AnalyzeOperationComplexitySpan(
+ Activity activity,
+ RequestContext context,
+ ActivityEnricherBase enricher) : SpanBase(activity)
+{
+ private bool _costSet;
+
+ public static AnalyzeOperationComplexitySpan? Start(
+ ActivitySource source,
+ RequestContext context,
+ ActivityEnricherBase enricher)
+ {
+ var activity = source.StartActivity("GraphQL Complexity Analysis");
+
+ if (activity is null)
+ {
+ return null;
+ }
+
+ activity.EnrichDocumentInfo(context.OperationDocumentInfo);
+
+ return new AnalyzeOperationComplexitySpan(activity, context, enricher);
+ }
+
+ public void SetCost(double fieldCost, double typeCost)
+ {
+ Activity.SetTag(GraphQL.Operation.FieldCost, fieldCost);
+ Activity.SetTag(GraphQL.Operation.TypeCost, typeCost);
+
+ _costSet = true;
+
+ enricher.EnrichOperationCost(context, fieldCost, typeCost, Activity);
+ }
+
+ protected override void OnComplete()
+ {
+ if (_costSet)
+ {
+ Activity.SetStatus(ActivityStatusCode.Ok);
+ }
+
+ enricher.EnrichAnalyzeOperationCost(context, Activity);
+ }
+}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/ExecuteOperationSpan.cs b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/ExecuteOperationSpan.cs
new file mode 100644
index 00000000000..50d3604bc2b
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/ExecuteOperationSpan.cs
@@ -0,0 +1,49 @@
+using System.Diagnostics;
+using HotChocolate.Execution;
+using HotChocolate.Language;
+using OpenTelemetry.Trace;
+using static HotChocolate.Diagnostics.SemanticConventions;
+
+namespace HotChocolate.Diagnostics;
+
+internal sealed class ExecuteOperationSpan(
+ Activity activity,
+ RequestContext context,
+ ActivityEnricherBase enricher) : SpanBase(activity)
+{
+ public static ExecuteOperationSpan? Start(
+ ActivitySource source,
+ RequestContext context,
+ OperationType operationType,
+ string? operationName,
+ ActivityEnricherBase enricher)
+ {
+ var activity = source.StartActivity("GraphQL Operation Execution");
+
+ if (activity is null)
+ {
+ return null;
+ }
+
+ activity.SetTag(GraphQL.Processing.Type, GraphQL.Processing.TypeValues.Execute);
+
+ activity.EnrichOperation(operationType, operationName);
+ activity.EnrichDocumentInfo(context.OperationDocumentInfo);
+
+ return new ExecuteOperationSpan(activity, context, enricher);
+ }
+
+ protected override void OnComplete()
+ {
+ if (context.Result is null or OperationResult { Errors: [_, ..] })
+ {
+ Activity.SetStatus(ActivityStatusCode.Error);
+ }
+ else
+ {
+ Activity.SetStatus(ActivityStatusCode.Ok);
+ }
+
+ enricher.EnrichExecuteOperation(context, Activity);
+ }
+}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/ExecuteRequestSpanBase.cs b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/ExecuteRequestSpanBase.cs
new file mode 100644
index 00000000000..d3cc3bef269
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/ExecuteRequestSpanBase.cs
@@ -0,0 +1,56 @@
+using System.Diagnostics;
+using HotChocolate.Execution;
+using HotChocolate.Language;
+using HotChocolate.Language.Utilities;
+using static HotChocolate.Diagnostics.SemanticConventions;
+
+namespace HotChocolate.Diagnostics;
+
+internal abstract class ExecuteRequestSpanBase(
+ Activity activity,
+ RequestContext context,
+ InstrumentationOptionsBase options,
+ ActivityEnricherBase? enricher,
+ bool shouldDisposeActivity) : SpanBase(activity, shouldDisposeActivity)
+{
+ public RequestContext Context { get; } = context;
+
+ protected static Activity? StartActivity(ActivitySource source)
+ {
+ return source.StartActivity("GraphQL Operation", ActivityKind.Server);
+ }
+
+ protected abstract bool TryGetOperationInfo(
+ out OperationType operationType,
+ out string? operationName);
+
+ protected override void OnComplete()
+ {
+ if (TryGetOperationInfo(out var operationType, out var operationName))
+ {
+ var operationTypeValue = GraphQL.Operation.TypeValues[operationType];
+ Activity.DisplayName = operationTypeValue;
+ Activity.EnrichOperation(operationType, operationName);
+ }
+
+ var documentInfo = Context.OperationDocumentInfo;
+
+ Activity.EnrichDocumentInfo(documentInfo);
+
+ if (options.IncludeDocument && documentInfo.Document is not null)
+ {
+ Activity.SetTag(GraphQL.Document.Body, documentInfo.Document.Print());
+ }
+
+ if (Context.Result is null or OperationResult { Errors: [_, ..] })
+ {
+ Activity.SetStatus(ActivityStatusCode.Error);
+ }
+ else if (Activity.Status != ActivityStatusCode.Error)
+ {
+ Activity.SetStatus(ActivityStatusCode.Ok);
+ }
+
+ enricher?.EnrichExecuteRequest(Context, Activity);
+ }
+}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/Http/ExecuteHttpRequestSpan.cs b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/Http/ExecuteHttpRequestSpan.cs
new file mode 100644
index 00000000000..94373731cf5
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/Http/ExecuteHttpRequestSpan.cs
@@ -0,0 +1,249 @@
+using System.Diagnostics;
+using Microsoft.AspNetCore.Http;
+using HotChocolate.AspNetCore.Instrumentation;
+using HotChocolate.Execution;
+using HotChocolate.Language;
+using HotChocolate.Language.Utilities;
+using OpenTelemetry.Trace;
+using static HotChocolate.Diagnostics.SemanticConventions;
+using static HotChocolate.WellKnownContextData;
+
+namespace HotChocolate.Diagnostics;
+
+internal sealed class ExecuteHttpRequestSpan(
+ Activity activity,
+ HttpContext httpContext,
+ HttpRequestKind kind,
+ ActivityEnricherBase enricher,
+ InstrumentationOptionsBase options) : SpanBase(activity)
+{
+ public static ExecuteHttpRequestSpan? Start(
+ ActivitySource source,
+ HttpContext httpContext,
+ HttpRequestKind kind,
+ ActivityEnricherBase enricher,
+ InstrumentationOptionsBase options)
+ {
+ var activity = source.StartActivity("ExecuteHttpRequest");
+
+ if (activity is null)
+ {
+ return null;
+ }
+
+ switch (kind)
+ {
+ case HttpRequestKind.HttpPost:
+ activity.DisplayName = "GraphQL HTTP POST";
+ break;
+ case HttpRequestKind.HttpMultiPart:
+ activity.DisplayName = "GraphQL HTTP POST MultiPart";
+ break;
+ case HttpRequestKind.HttpGet:
+ activity.DisplayName = "GraphQL HTTP GET";
+ break;
+ case HttpRequestKind.HttpGetSchema:
+ activity.DisplayName = "GraphQL HTTP GET SDL";
+ break;
+ }
+
+ activity.SetTag(GraphQL.Http.Kind, kind.ToString());
+
+ if (!(httpContext.Items.TryGetValue(SchemaName, out var value)
+ && value is string schemaName))
+ {
+ schemaName = ISchemaDefinition.DefaultName;
+ }
+
+ activity.SetTag(GraphQL.Schema.Name, schemaName);
+
+ return new ExecuteHttpRequestSpan(activity, httpContext, kind, enricher, options);
+ }
+
+ public void SetSingleRequestDetails(GraphQLRequest request)
+ {
+ Activity.SetTag(GraphQL.Http.Request.Type, GraphQL.Http.Request.Types.Single);
+
+ if (request.DocumentId is not null
+ && (options.RequestDetails & RequestDetails.Id) == RequestDetails.Id)
+ {
+ Activity.SetTag(GraphQL.Http.Request.QueryId, request.DocumentId.Value.Value);
+ }
+
+ if (request.DocumentHash is not null
+ && (options.RequestDetails & RequestDetails.Hash) == RequestDetails.Hash)
+ {
+ Activity.SetTag(GraphQL.Http.Request.QueryHash, request.DocumentHash.Value.Value);
+ }
+
+ if (request.Document is not null
+ && (options.RequestDetails & RequestDetails.Document) == RequestDetails.Document)
+ {
+ Activity.SetTag(GraphQL.Http.Request.QueryBody, request.Document.Print());
+ }
+
+ if (request.OperationName is not null
+ && (options.RequestDetails & RequestDetails.OperationName) == RequestDetails.OperationName)
+ {
+ Activity.SetTag(GraphQL.Http.Request.OperationName, request.OperationName);
+ }
+
+ if (request.Variables is not null
+ && (options.RequestDetails & RequestDetails.Variables) == RequestDetails.Variables)
+ {
+ Activity.SetTag(GraphQL.Http.Request.Variables, request.Variables.RootElement.ToString());
+ }
+
+ if (request.Extensions is not null
+ && (options.RequestDetails & RequestDetails.Extensions) == RequestDetails.Extensions)
+ {
+ try
+ {
+ Activity.SetTag(GraphQL.Http.Request.Extensions, request.Extensions.RootElement.ToString());
+ }
+ catch
+ {
+ // Ignore any errors
+ }
+ }
+
+ enricher.EnrichSingleRequest(httpContext, request, Activity);
+ }
+
+ public void SetBatchRequestDetails(IReadOnlyList batch)
+ {
+ Activity.SetTag(GraphQL.Http.Request.Type, GraphQL.Http.Request.Types.Batch);
+
+ for (var i = 0; i < batch.Count; i++)
+ {
+ var request = batch[i];
+
+ if (request.DocumentId is not null
+ && (options.RequestDetails & RequestDetails.Id) == RequestDetails.Id)
+ {
+ Activity.SetTag(GraphQL.Http.Request.BatchRequest.QueryId(i), request.DocumentId.Value);
+ }
+
+ if (request.DocumentHash is not null
+ && (options.RequestDetails & RequestDetails.Hash) == RequestDetails.Hash)
+ {
+ Activity.SetTag(GraphQL.Http.Request.BatchRequest.QueryHash(i), request.DocumentHash.Value);
+ }
+
+ if (request.Document is not null
+ && (options.RequestDetails & RequestDetails.Document) == RequestDetails.Document)
+ {
+ Activity.SetTag(GraphQL.Http.Request.BatchRequest.QueryBody(i), request.Document.Print());
+ }
+
+ if (request.OperationName is not null
+ && (options.RequestDetails & RequestDetails.OperationName) == RequestDetails.OperationName)
+ {
+ Activity.SetTag(GraphQL.Http.Request.BatchRequest.OperationName(i), request.OperationName);
+ }
+
+ if (request.Variables is not null
+ && (options.RequestDetails & RequestDetails.Variables) == RequestDetails.Variables)
+ {
+ Activity.SetTag(
+ GraphQL.Http.Request.BatchRequest.Variables(i),
+ request.Variables.RootElement.ToString());
+ }
+
+ if (request.Extensions is not null
+ && (options.RequestDetails & RequestDetails.Extensions) == RequestDetails.Extensions)
+ {
+ try
+ {
+ Activity.SetTag(
+ GraphQL.Http.Request.BatchRequest.Extensions(i),
+ request.Extensions.RootElement.ToString());
+ }
+ catch
+ {
+ // Ignore any errors
+ }
+ }
+ }
+
+ enricher.EnrichBatchRequest(httpContext, batch, Activity);
+ }
+
+ public void SetOperationBatchRequestDetails(
+ GraphQLRequest request,
+ IReadOnlyList operations)
+ {
+ Activity.SetTag(GraphQL.Http.Request.Type, GraphQL.Http.Request.Types.OperationBatch);
+
+ if (request.DocumentId is not null
+ && (options.RequestDetails & RequestDetails.Id) == RequestDetails.Id)
+ {
+ Activity.SetTag(GraphQL.Http.Request.QueryId, request.DocumentId.Value.Value);
+ }
+
+ if (request.DocumentHash is not null
+ && (options.RequestDetails & RequestDetails.Hash) == RequestDetails.Hash)
+ {
+ Activity.SetTag(GraphQL.Http.Request.QueryHash, request.DocumentHash.Value.Value);
+ }
+
+ if (request.Document is not null
+ && (options.RequestDetails & RequestDetails.Document) == RequestDetails.Document)
+ {
+ Activity.SetTag(GraphQL.Http.Request.QueryBody, request.Document.Print());
+ }
+
+ if (request.OperationName is not null
+ && (options.RequestDetails & RequestDetails.OperationName) == RequestDetails.OperationName)
+ {
+ Activity.SetTag(GraphQL.Http.Request.Operations, string.Join(" -> ", operations));
+ }
+
+ if (request.Variables is not null
+ && (options.RequestDetails & RequestDetails.Variables) == RequestDetails.Variables)
+ {
+ Activity.SetTag(GraphQL.Http.Request.Variables, request.Variables.RootElement.ToString());
+ }
+
+ if (request.Extensions is not null
+ && (options.RequestDetails & RequestDetails.Extensions) == RequestDetails.Extensions)
+ {
+ try
+ {
+ Activity.SetTag(GraphQL.Http.Request.Extensions, request.Extensions.RootElement.ToString());
+ }
+ catch
+ {
+ // Ignore any errors
+ }
+ }
+
+ enricher.EnrichOperationBatchRequest(httpContext, request, operations, Activity);
+ }
+
+ protected override void OnComplete()
+ {
+ if (Activity.Status != ActivityStatusCode.Error)
+ {
+ Activity.SetStatus(ActivityStatusCode.Ok);
+ }
+
+ enricher.EnrichExecuteHttpRequest(httpContext, kind, Activity);
+ }
+
+ public void RecordError(IError error)
+ {
+ Activity.SetStatus(ActivityStatusCode.Error);
+ Activity.AddGraphQLError(error);
+
+ enricher.EnrichHttpRequestError(httpContext, error, Activity);
+ }
+
+ public void RecordError(Exception exception)
+ {
+ Activity.SetStatus(ActivityStatusCode.Error);
+ Activity.AddException(exception);
+
+ enricher.EnrichHttpRequestError(httpContext, exception, Activity);
+ }
+}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/Http/FormatHttpResponseSpan.cs b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/Http/FormatHttpResponseSpan.cs
new file mode 100644
index 00000000000..e8cf5d8e580
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/Http/FormatHttpResponseSpan.cs
@@ -0,0 +1,36 @@
+using System.Diagnostics;
+using Microsoft.AspNetCore.Http;
+using OpenTelemetry.Trace;
+
+namespace HotChocolate.Diagnostics;
+
+internal sealed class FormatHttpResponseSpan(
+ Activity activity,
+ HttpContext httpContext,
+ ActivityEnricherBase enricher) : SpanBase(activity)
+{
+ public static FormatHttpResponseSpan? Start(
+ ActivitySource source,
+ HttpContext httpContext,
+ ActivityEnricherBase enricher)
+ {
+ var activity = source.StartActivity("Format HTTP Response");
+
+ if (activity is null)
+ {
+ return null;
+ }
+
+ return new FormatHttpResponseSpan(activity, httpContext, enricher);
+ }
+
+ protected override void OnComplete()
+ {
+ if (Activity.Status != ActivityStatusCode.Error)
+ {
+ Activity.SetStatus(ActivityStatusCode.Ok);
+ }
+
+ enricher.EnrichFormatHttpResponse(httpContext, Activity);
+ }
+}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/Http/ParseHttpRequestSpan.cs b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/Http/ParseHttpRequestSpan.cs
new file mode 100644
index 00000000000..8f809d2b0df
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/Http/ParseHttpRequestSpan.cs
@@ -0,0 +1,48 @@
+using System.Diagnostics;
+using Microsoft.AspNetCore.Http;
+using OpenTelemetry.Trace;
+
+namespace HotChocolate.Diagnostics;
+
+internal sealed class ParseHttpRequestSpan(
+ Activity activity,
+ HttpContext httpContext,
+ ActivityEnricherBase enricher) : SpanBase(activity)
+{
+ public static ParseHttpRequestSpan? Start(
+ ActivitySource source,
+ HttpContext httpContext,
+ ActivityEnricherBase enricher)
+ {
+ var activity = source.StartActivity("Parse HTTP Request");
+
+ if (activity is null)
+ {
+ return null;
+ }
+
+ return new ParseHttpRequestSpan(activity, httpContext, enricher);
+ }
+
+ public void RecordErrors(IReadOnlyList errors)
+ {
+ Activity.SetStatus(ActivityStatusCode.Error);
+
+ foreach (var error in errors)
+ {
+ Activity.AddGraphQLError(error);
+ }
+
+ enricher.EnrichParserErrors(httpContext, errors, Activity);
+ }
+
+ protected override void OnComplete()
+ {
+ if (Activity.Status != ActivityStatusCode.Error)
+ {
+ Activity.SetStatus(ActivityStatusCode.Ok);
+ }
+
+ enricher.EnrichParseHttpRequest(httpContext, Activity);
+ }
+}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/ParsingSpan.cs b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/ParsingSpan.cs
new file mode 100644
index 00000000000..7cedcfbc343
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/ParsingSpan.cs
@@ -0,0 +1,45 @@
+using System.Diagnostics;
+using HotChocolate.Execution;
+using OpenTelemetry.Trace;
+using static HotChocolate.Diagnostics.SemanticConventions;
+
+namespace HotChocolate.Diagnostics;
+
+internal sealed class ParsingSpan(
+ Activity activity,
+ RequestContext context,
+ ActivityEnricherBase enricher) : SpanBase(activity)
+{
+ public static ParsingSpan? Start(
+ ActivitySource source,
+ RequestContext context,
+ ActivityEnricherBase enricher)
+ {
+ var activity = source.StartActivity("GraphQL Document Parsing");
+
+ if (activity is null)
+ {
+ return null;
+ }
+
+ // We do not set this here, as parsing can happen in the HTTP middleware
+ // or the HotChocolate pipeline.
+ // For the moment we just track both as regular spans.
+ // Maybe in the future we can reconcile this.
+ // activity.SetTag(GraphQL.Processing.Type, GraphQL.Processing.TypeValues.Parse);
+
+ return new ParsingSpan(activity, context, enricher);
+ }
+
+ protected override void OnComplete()
+ {
+ if (context.TryGetOperationDocument(out _, out _))
+ {
+ Activity.SetStatus(ActivityStatusCode.Ok);
+ }
+
+ Activity.EnrichDocumentInfo(context.OperationDocumentInfo);
+
+ enricher.EnrichParseDocument(context, Activity);
+ }
+}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/SpanBase.cs b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/SpanBase.cs
new file mode 100644
index 00000000000..a5fd63b5965
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/SpanBase.cs
@@ -0,0 +1,27 @@
+using System.Diagnostics;
+
+namespace HotChocolate.Diagnostics;
+
+internal abstract class SpanBase(Activity activity, bool shouldDisposeActivity = true) : IDisposable
+{
+ private bool _disposed;
+
+ public Activity Activity { get; } = activity;
+
+ protected virtual void OnComplete() { }
+
+ public void Dispose()
+ {
+ if (!_disposed)
+ {
+ _disposed = true;
+
+ OnComplete();
+
+ if (shouldDisposeActivity)
+ {
+ Activity.Dispose();
+ }
+ }
+ }
+}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/SubscriptionEventSpan.cs b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/SubscriptionEventSpan.cs
new file mode 100644
index 00000000000..31e83e1e6e5
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/SubscriptionEventSpan.cs
@@ -0,0 +1,42 @@
+using System.Diagnostics;
+using System.Globalization;
+using HotChocolate.Execution;
+using HotChocolate.Language;
+using static HotChocolate.Diagnostics.SemanticConventions;
+
+namespace HotChocolate.Diagnostics;
+
+internal sealed class SubscriptionEventSpan(Activity activity) : SpanBase(activity)
+{
+ public static SubscriptionEventSpan? Start(
+ ActivitySource source,
+ RequestContext context,
+ string? operationName,
+ ulong subscriptionId,
+ ActivityContext? subscriptionContext = null)
+ {
+ var activity = subscriptionContext is { } parent
+ ? source.StartActivity("GraphQL Subscription Event", ActivityKind.Internal, parent)
+ : source.StartActivity("GraphQL Subscription Event");
+
+ if (activity is null)
+ {
+ return null;
+ }
+
+ activity.SetTag(GraphQL.Processing.Type, GraphQL.Processing.TypeValues.Execute);
+ activity.EnrichOperation(OperationType.Subscription, operationName);
+ activity.EnrichDocumentInfo(context.OperationDocumentInfo);
+ activity.SetTag(GraphQL.Subscription.Id, subscriptionId.ToString(CultureInfo.InvariantCulture));
+
+ return new SubscriptionEventSpan(activity);
+ }
+
+ protected override void OnComplete()
+ {
+ if (Activity.Status != ActivityStatusCode.Error)
+ {
+ Activity.SetStatus(ActivityStatusCode.Ok);
+ }
+ }
+}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/ValidationSpan.cs b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/ValidationSpan.cs
new file mode 100644
index 00000000000..62df9746771
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/ValidationSpan.cs
@@ -0,0 +1,41 @@
+using System.Diagnostics;
+using HotChocolate.Execution;
+using OpenTelemetry.Trace;
+using static HotChocolate.Diagnostics.SemanticConventions;
+
+namespace HotChocolate.Diagnostics;
+
+internal sealed class ValidationSpan(
+ Activity activity,
+ RequestContext context,
+ ActivityEnricherBase enricher) : SpanBase(activity)
+{
+ public static ValidationSpan? Start(
+ ActivitySource source,
+ RequestContext context,
+ ActivityEnricherBase enricher)
+ {
+ var activity = source.StartActivity("GraphQL Document Validation");
+
+ if (activity is null)
+ {
+ return null;
+ }
+
+ activity.SetTag(GraphQL.Processing.Type, GraphQL.Processing.TypeValues.Validate);
+
+ activity.EnrichDocumentInfo(context.OperationDocumentInfo);
+
+ return new ValidationSpan(activity, context, enricher);
+ }
+
+ protected override void OnComplete()
+ {
+ if (context.IsOperationDocumentValid())
+ {
+ Activity.SetStatus(ActivityStatusCode.Ok);
+ }
+
+ enricher.EnrichValidateDocument(context, Activity);
+ }
+}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/VariableCoercionSpan.cs b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/VariableCoercionSpan.cs
new file mode 100644
index 00000000000..c54786d9387
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics.Core/Spans/VariableCoercionSpan.cs
@@ -0,0 +1,45 @@
+using System.Diagnostics;
+using HotChocolate.Execution;
+using HotChocolate.Language;
+using OpenTelemetry.Trace;
+using static HotChocolate.Diagnostics.SemanticConventions;
+
+namespace HotChocolate.Diagnostics;
+
+internal sealed class VariableCoercionSpan(
+ Activity activity,
+ RequestContext context,
+ ActivityEnricherBase enricher) : SpanBase(activity)
+{
+ public static VariableCoercionSpan? Start(
+ ActivitySource source,
+ RequestContext context,
+ OperationType operationType,
+ string? operationName,
+ ActivityEnricherBase enricher)
+ {
+ var activity = source.StartActivity("GraphQL Variable Coercion");
+
+ if (activity is null)
+ {
+ return null;
+ }
+
+ activity.SetTag(GraphQL.Processing.Type, GraphQL.Processing.TypeValues.VariableCoercion);
+
+ activity.EnrichOperation(operationType, operationName);
+ activity.EnrichDocumentInfo(context.OperationDocumentInfo);
+
+ return new VariableCoercionSpan(activity, context, enricher);
+ }
+
+ protected override void OnComplete()
+ {
+ if (context.VariableValues.Length > 0)
+ {
+ Activity.SetStatus(ActivityStatusCode.Ok);
+ }
+
+ enricher.EnrichCoerceVariables(context, Activity);
+ }
+}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics/ActivityEnricher.cs b/src/HotChocolate/Diagnostics/src/Diagnostics/ActivityEnricher.cs
index 41b16cac147..896c1b3fcfc 100644
--- a/src/HotChocolate/Diagnostics/src/Diagnostics/ActivityEnricher.cs
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics/ActivityEnricher.cs
@@ -1,623 +1,47 @@
using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Text;
-using System.Text.Json;
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.ObjectPool;
using GreenDonut;
-using HotChocolate.AspNetCore.Instrumentation;
using HotChocolate.Execution;
-using HotChocolate.Execution.Processing;
-using HotChocolate.Language;
-using HotChocolate.Language.Utilities;
using HotChocolate.Resolvers;
-using HotChocolate.Types;
-using OpenTelemetry.Trace;
-using static HotChocolate.Diagnostics.SemanticConventions;
-using static HotChocolate.WellKnownContextData;
namespace HotChocolate.Diagnostics;
///
-/// The activity enricher is used to add information to the activity spans.
-/// You can inherit from this class and override the enricher methods to provide more or
-/// less information.
+/// The activity enricher allows adding additional information to the activity spans
+/// created by the Hot Chocolate diagnostics system.
+/// You can inherit from this class and override the enricher methods to add
+/// additional information to the spans.
///
-public class ActivityEnricher
+public class ActivityEnricher(InstrumentationOptions options) : ActivityEnricherBase
{
- private readonly InstrumentationOptions _options;
- private readonly ConditionalWeakTable _queryCache = [];
+ protected InstrumentationOptions Options { get; } = options;
- ///
- /// Initializes a new instance of .
- ///
- ///
- ///
- protected ActivityEnricher(
- ObjectPool stringBuilderPool,
- InstrumentationOptions options)
- {
- StringBuilderPool = stringBuilderPool;
- _options = options;
- }
-
- ///
- /// Gets the pool used by this enricher.
- ///
- protected ObjectPool StringBuilderPool { get; }
-
- public virtual void EnrichExecuteHttpRequest(
- HttpContext context,
- HttpRequestKind kind,
- Activity activity)
- {
- switch (kind)
- {
- case HttpRequestKind.HttpPost:
- activity.DisplayName = "GraphQL HTTP POST";
- break;
- case HttpRequestKind.HttpMultiPart:
- activity.DisplayName = "GraphQL HTTP POST MultiPart";
- break;
- case HttpRequestKind.HttpGet:
- activity.DisplayName = "GraphQL HTTP GET";
- break;
- case HttpRequestKind.HttpGetSchema:
- activity.DisplayName = "GraphQL HTTP GET SDL";
- break;
- }
-
- if (_options.RenameRootActivity)
- {
- UpdateRootActivityName(activity, $"Begin {activity.DisplayName}");
- }
-
- activity.SetTag("graphql.http.kind", kind);
-
- var isDefault = false;
- if (!(context.Items.TryGetValue(SchemaName, out var value)
- && value is string schemaName))
- {
- schemaName = ISchemaDefinition.DefaultName;
- isDefault = true;
- }
-
- activity.SetTag("graphql.schema.name", schemaName);
- activity.SetTag("graphql.schema.isDefault", isDefault);
- }
-
- public virtual void EnrichSingleRequest(
- HttpContext context,
- GraphQLRequest request,
- Activity activity)
- {
- activity.SetTag("graphql.http.request.type", "single");
-
- if (request.DocumentId is not null
- && (_options.RequestDetails & RequestDetails.Id) == RequestDetails.Id)
- {
- activity.SetTag("graphql.http.request.query.id", request.DocumentId.Value);
- }
-
- if (request.DocumentHash is not null
- && (_options.RequestDetails & RequestDetails.Hash) == RequestDetails.Hash)
- {
- activity.SetTag("graphql.http.request.query.hash", request.DocumentHash.Value);
- }
-
- if (request.Document is not null
- && (_options.RequestDetails & RequestDetails.Query) == RequestDetails.Query)
- {
- if (!_queryCache.TryGetValue(request.Document, out var query))
- {
- query = request.Document.Print();
- _queryCache.Add(request.Document, query);
- }
-
- activity.SetTag("graphql.http.request.query.body", query);
- }
-
- if (request.OperationName is not null
- && (_options.RequestDetails & RequestDetails.Operation) == RequestDetails.Operation)
- {
- activity.SetTag("graphql.http.request.operation", request.OperationName);
- }
-
- if (request.Variables is not null
- && (_options.RequestDetails & RequestDetails.Variables) == RequestDetails.Variables)
- {
- EnrichRequestVariables(context, request, request.Variables, activity);
- }
-
- if (request.Extensions is not null
- && (_options.RequestDetails & RequestDetails.Extensions) == RequestDetails.Extensions)
- {
- EnrichRequestExtensions(context, request, request.Extensions, activity);
- }
- }
-
- public virtual void EnrichBatchRequest(
- HttpContext context,
- IReadOnlyList batch,
- Activity activity)
- {
- activity.SetTag("graphql.http.request.type", "batch");
-
- for (var i = 0; i < batch.Count; i++)
- {
- var request = batch[i];
-
- if (request.DocumentId is not null
- && (_options.RequestDetails & RequestDetails.Id) == RequestDetails.Id)
- {
- activity.SetTag($"graphql.http.request[{i}].query.id", request.DocumentId.Value);
- }
-
- if (request.DocumentHash is not null
- && (_options.RequestDetails & RequestDetails.Hash) == RequestDetails.Hash)
- {
- activity.SetTag($"graphql.http.request[{i}].query.hash", request.DocumentHash.Value);
- }
-
- if (request.Document is not null
- && (_options.RequestDetails & RequestDetails.Query) == RequestDetails.Query)
- {
- activity.SetTag($"graphql.http.request[{i}].query.body", request.Document.Print());
- }
-
- if (request.OperationName is not null
- && (_options.RequestDetails & RequestDetails.Operation) == RequestDetails.Operation)
- {
- activity.SetTag($"graphql.http.request[{i}].operation", request.OperationName);
- }
-
- if (request.Variables is not null
- && (_options.RequestDetails & RequestDetails.Variables) == RequestDetails.Variables)
- {
- EnrichBatchVariables(context, request, request.Variables, i, activity);
- }
-
- if (request.Extensions is not null
- && (_options.RequestDetails & RequestDetails.Extensions) == RequestDetails.Extensions)
- {
- EnrichBatchExtensions(context, request, request.Extensions, i, activity);
- }
- }
- }
-
- public virtual void EnrichOperationBatchRequest(
- HttpContext context,
- GraphQLRequest request,
- IReadOnlyList operations,
- Activity activity)
- {
- activity.SetTag("graphql.http.request.type", "operationBatch");
-
- if (request.DocumentId is not null
- && (_options.RequestDetails & RequestDetails.Id) == RequestDetails.Id)
- {
- activity.SetTag("graphql.http.request.query.id", request.DocumentId.Value);
- }
-
- if (request.DocumentHash is not null
- && (_options.RequestDetails & RequestDetails.Hash) == RequestDetails.Hash)
- {
- activity.SetTag("graphql.http.request.query.hash", request.DocumentHash.Value);
- }
-
- if (request.Document is not null
- && (_options.RequestDetails & RequestDetails.Query) == RequestDetails.Query)
- {
- activity.SetTag("graphql.http.request.query.body", request.Document.Print());
- }
-
- if (request.OperationName is not null
- && (_options.RequestDetails & RequestDetails.Operation) == RequestDetails.Operation)
- {
- activity.SetTag("graphql.http.request.operations", string.Join(" -> ", operations));
- }
-
- if (request.Variables is not null
- && (_options.RequestDetails & RequestDetails.Variables) == RequestDetails.Variables)
- {
- EnrichRequestVariables(context, request, request.Variables, activity);
- }
-
- if (request.Extensions is not null
- && (_options.RequestDetails & RequestDetails.Extensions) == RequestDetails.Extensions)
- {
- EnrichRequestExtensions(context, request, request.Extensions, activity);
- }
- }
-
- protected virtual void EnrichRequestVariables(
- HttpContext context,
- GraphQLRequest request,
- JsonDocument variables,
- Activity activity)
- => activity.SetTag("graphql.http.request.variables", variables.RootElement.ToString());
-
- protected virtual void EnrichBatchVariables(
- HttpContext context,
- GraphQLRequest request,
- JsonDocument variables,
- int index,
- Activity activity)
- => activity.SetTag($"graphql.http.request[{index}].variables", variables.RootElement.ToString());
-
- protected virtual void EnrichRequestExtensions(
- HttpContext context,
- GraphQLRequest request,
- JsonDocument extensions,
- Activity activity)
- {
- try
- {
- activity.SetTag(
- "graphql.http.request.extensions",
- extensions.RootElement.ToString());
- }
- catch
- {
- // Ignore any errors
- }
- }
-
- protected virtual void EnrichBatchExtensions(
- HttpContext context,
- GraphQLRequest request,
- JsonDocument extensions,
- int index,
- Activity activity)
- {
- try
- {
- activity.SetTag(
- $"graphql.http.request[{index}].extensions",
- extensions.RootElement.ToString());
- }
- catch
- {
- // Ignore any errors
- }
- }
-
- public virtual void EnrichHttpRequestError(
- HttpContext context,
- IError error,
- Activity activity)
- => EnrichError(error, activity);
-
- public virtual void EnrichHttpRequestError(
- HttpContext context,
- Exception exception,
- Activity activity)
- {
- }
-
- public virtual void EnrichParseHttpRequest(HttpContext context, Activity activity)
- {
- activity.DisplayName = "Parse HTTP Request";
-
- if (_options.RenameRootActivity)
- {
- UpdateRootActivityName(activity, $"Begin {activity.DisplayName}");
- }
- }
-
- public virtual void EnrichParserErrors(HttpContext context, IError error, Activity activity)
- => EnrichError(error, activity);
-
- public virtual void EnrichFormatHttpResponse(HttpContext context, Activity activity)
- {
- activity.DisplayName = "Format HTTP Response";
- }
-
- public virtual void EnrichExecuteRequest(RequestContext context, Activity activity)
- {
- context.TryGetOperation(out var operation);
- var documentInfo = context.OperationDocumentInfo;
- var operationDisplayName = CreateOperationDisplayName(context, operation);
-
- if (_options.RenameRootActivity && operationDisplayName is not null)
- {
- UpdateRootActivityName(activity, operationDisplayName);
- }
-
- activity.DisplayName = operationDisplayName ?? "Execute Request";
- activity.SetTag("graphql.document.id", documentInfo.Id.Value);
- activity.SetTag("graphql.document.hash", documentInfo.Hash.Value);
- activity.SetTag("graphql.document.valid", documentInfo.IsValidated);
- activity.SetTag("graphql.operation.id", operation?.Id);
- activity.SetTag("graphql.operation.kind", operation?.Kind);
- activity.SetTag("graphql.operation.name", operation?.Name);
-
- if (_options.IncludeDocument && documentInfo.Document is not null)
- {
- activity.SetTag("graphql.document.body", documentInfo.Document.Print());
- }
-
- if (context.Result is OperationResult result)
- {
- var errorCount = result.Errors.Count;
- activity.SetTag("graphql.errors.count", errorCount);
- }
- }
- protected virtual string? CreateOperationDisplayName(RequestContext context, Operation? operation)
- {
- if (operation is null)
- {
- return null;
- }
-
- var displayName = StringBuilderPool.Get();
-
- try
- {
- var rootSelectionSet = operation.RootSelectionSet;
- var selectionCount = rootSelectionSet.Selections.Length;
-
- displayName.Append('{');
- displayName.Append(' ');
-
- foreach (var selection in rootSelectionSet.Selections[..Math.Min(3, selectionCount)])
- {
- if (displayName.Length > 2)
- {
- displayName.Append(' ');
- }
-
- displayName.Append(selection.ResponseName);
- }
-
- if (rootSelectionSet.Selections.Length > 3)
- {
- displayName.Append(' ');
- displayName.Append('.');
- displayName.Append('.');
- displayName.Append('.');
- }
-
- displayName.Append(' ');
- displayName.Append('}');
-
- if (operation.Name is { } name)
- {
- displayName.Insert(0, ' ');
- displayName.Insert(0, name);
- }
-
- displayName.Insert(0, ' ');
- displayName.Insert(0, operation.Definition.Operation.ToString().ToLowerInvariant());
-
- return displayName.ToString();
- }
- finally
- {
- StringBuilderPool.Return(displayName);
- }
- }
-
- private void UpdateRootActivityName(Activity activity, string displayName)
- {
- var current = activity;
-
- while (current.Parent is not null)
- {
- current = current.Parent;
- }
-
- if (current != activity)
- {
- current.DisplayName = CreateRootActivityName(activity, current, displayName);
- }
- }
-
- protected virtual string CreateRootActivityName(
- Activity activity,
- Activity root,
- string displayName)
- {
- const string key = "originalDisplayName";
-
- if (root.GetCustomProperty(key) is not string rootDisplayName)
- {
- rootDisplayName = root.DisplayName;
- root.SetCustomProperty(key, rootDisplayName);
- }
-
- return $"{rootDisplayName}: {displayName}";
- }
-
- public virtual void EnrichParseDocument(RequestContext context, Activity activity)
- {
- activity.DisplayName = "Parse Document";
-
- if (_options.RenameRootActivity)
- {
- UpdateRootActivityName(activity, $"Begin {activity.DisplayName}");
- }
- }
-
- public virtual void EnrichRequestError(
- RequestContext context,
- Activity activity,
- Exception error)
- => EnrichError(ErrorBuilder.FromException(error).Build(), activity);
-
- public virtual void EnrichRequestError(
- RequestContext context,
- Activity activity,
- IError error)
- => EnrichError(error, activity);
-
- public virtual void EnrichValidateDocument(RequestContext context, Activity activity)
- {
- activity.DisplayName = "Validate Document";
-
- if (_options.RenameRootActivity)
- {
- UpdateRootActivityName(activity, $"Begin {activity.DisplayName}");
- }
-
- var documentInfo = context.OperationDocumentInfo;
- activity.SetTag("graphql.document.id", documentInfo.Id.Value);
- activity.SetTag("graphql.document.hash", documentInfo.Hash.Value);
- }
-
- public virtual void EnrichValidationError(
+ public virtual void EnrichCompileOperation(
RequestContext context,
- Activity activity,
- IError error)
- => EnrichError(error, activity);
-
- public virtual void EnrichAnalyzeOperationComplexity(RequestContext context, Activity activity)
- {
- activity.DisplayName = "Analyze Operation Complexity";
- }
-
- public virtual void EnrichCoerceVariables(RequestContext context, Activity activity)
- {
- activity.DisplayName = "Coerce Variable";
- }
-
- public virtual void EnrichCompileOperation(RequestContext context, Activity activity)
- {
- activity.DisplayName = "Compile Operation";
- }
+ Activity activity) { }
- public virtual void EnrichExecuteOperation(RequestContext context, Activity activity)
- {
- context.TryGetOperation(out var operation);
- activity.DisplayName =
- operation?.Name is { } op
- ? $"Execute Operation {op}"
- : "Execute Operation";
- }
-
- public virtual void EnrichResolveFieldValue(IMiddlewareContext context, Activity activity)
- {
- string path;
- string hierarchy;
- BuildPath();
-
- var selection = context.Selection;
- var coordinate = selection.Field.Coordinate;
-
- activity.DisplayName = path;
- activity.SetTag("graphql.selection.name", selection.ResponseName);
- activity.SetTag("graphql.selection.type", selection.Field.Type.Print());
- activity.SetTag("graphql.selection.path", path);
- activity.SetTag("graphql.selection.hierarchy", hierarchy);
- activity.SetTag("graphql.selection.field.name", coordinate.MemberName);
- activity.SetTag("graphql.selection.field.coordinate", coordinate.ToString());
- activity.SetTag("graphql.selection.field.declaringType", coordinate.Name);
- activity.SetTag("graphql.selection.field.isDeprecated", selection.Field.IsDeprecated);
-
- void BuildPath()
- {
- var p = StringBuilderPool.Get();
- var h = StringBuilderPool.Get();
- var index = StringBuilderPool.Get();
-
- var current = context.Path;
-
- do
- {
- if (current is NamePathSegment n)
- {
- p.Insert(0, '/');
- h.Insert(0, '/');
- p.Insert(1, n.Name);
- h.Insert(1, n.Name);
-
- if (index.Length > 0)
- {
- p.Insert(1 + n.Name.Length, index);
- }
-
- index.Clear();
- }
-
- if (current is IndexerPathSegment i)
- {
- var number = i.Index.ToString();
- index.Insert(0, '[');
- index.Insert(1, number);
- index.Insert(1 + number.Length, ']');
- }
-
- current = current.Parent;
- } while (!current.IsRoot);
-
- path = p.ToString();
- hierarchy = h.ToString();
-
- StringBuilderPool.Return(p);
- StringBuilderPool.Return(h);
- StringBuilderPool.Return(index);
- }
- }
+ public virtual void EnrichResolveFieldValue(
+ IMiddlewareContext context,
+ Activity activity) { }
public virtual void EnrichResolverError(
- RequestContext context,
- IError error,
- Activity activity)
- => EnrichError(error, activity);
-
- public virtual void EnrichResolverError(
- IMiddlewareContext middlewareContext,
+ IMiddlewareContext context,
IError error,
- Activity activity)
- => EnrichError(error, activity);
+ Activity activity) { }
- public virtual void EnrichDataLoaderBatch(
+ public virtual void EnrichExecuteBatch(
IDataLoader dataLoader,
IReadOnlyList keys,
- Activity activity)
- where TKey : notnull
- {
- activity.DisplayName = $"Execute {dataLoader.GetType().Name} Batch";
- activity.SetTag("graphql.dataLoader.keys.count", keys.Count);
-
- if (_options.IncludeDataLoaderKeys)
- {
- var temp = keys.Select(t => t.ToString()).ToArray();
- activity.SetTag("graphql.dataLoader.keys", temp);
- }
- }
-
- protected virtual void EnrichError(IError error, Activity activity)
- {
- if (error.Exception is { } exception)
- {
- activity.RecordException(exception);
- }
+ Activity activity) where TKey : notnull { }
- var tags = new ActivityTagsCollection
- {
- new(AttributeExceptionMessage, error.Message),
- new(AttributeExceptionType, error.Code ?? "GRAPHQL_ERROR")
- };
+ public virtual void EnrichRunBatchDispatchCoordinator(
+ Activity activity) { }
- if (error.Path is not null)
- {
- tags["graphql.error.path"] = error.Path.ToString();
- }
-
- if (error.Locations is { Count: > 0 })
- {
- tags["graphql.error.location.column"] = error.Locations[0].Column;
- tags["graphql.error.location.line"] = error.Locations[0].Line;
- }
-
- activity.AddEvent(new ActivityEvent(AttributeExceptionEventName, default, tags));
- }
-}
+ public virtual void EnrichBatchDispatchError(
+ Exception exception,
+ Activity activity) { }
-file static class SemanticConventions
-{
- public const string AttributeExceptionEventName = "exception";
- public const string AttributeExceptionType = "exception.type";
- public const string AttributeExceptionMessage = "exception.message";
+ public virtual void EnrichOnSubscriptionEvent(
+ RequestContext context,
+ ulong subscriptionId,
+ Activity activity) { }
}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics/ContextKeys.cs b/src/HotChocolate/Diagnostics/src/Diagnostics/ContextKeys.cs
deleted file mode 100644
index d2771522e7a..00000000000
--- a/src/HotChocolate/Diagnostics/src/Diagnostics/ContextKeys.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace HotChocolate.Diagnostics;
-
-internal static class ContextKeys
-{
- public const string HttpRequestActivity = "HotChocolate.Diagnostics.HttpRequest";
- public const string ParseHttpRequestActivity = "HotChocolate.Diagnostics.ParseHttpRequest";
- public const string FormatHttpResponseActivity = "HotChocolate.Diagnostics.FormatHttpResponse";
- public const string WebSocketSessionActivity = "HotChocolate.Diagnostics.WebSocketSession";
- public const string RequestActivity = "HotChocolate.Diagnostics.Request";
- public const string ValidateActivity = "HotChocolate.Diagnostics.Validate";
- public const string ComplexityActivity = "HotChocolate.Diagnostics.AnalyzeOperationComplexity";
- public const string ResolverActivity = "HotChocolate.Diagnostics.Resolver";
-}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics/Extensions/DiagnosticsRequestExecutorBuilderExtensions.cs b/src/HotChocolate/Diagnostics/src/Diagnostics/Extensions/DiagnosticsRequestExecutorBuilderExtensions.cs
index 47493fa3a0b..d3b40ac99cd 100644
--- a/src/HotChocolate/Diagnostics/src/Diagnostics/Extensions/DiagnosticsRequestExecutorBuilderExtensions.cs
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics/Extensions/DiagnosticsRequestExecutorBuilderExtensions.cs
@@ -80,8 +80,5 @@ public static IRequestExecutorBuilder AddInstrumentation(
return builder;
}
- private sealed class InternalActivityEnricher(
- ObjectPool stringBuilderPool,
- InstrumentationOptions options)
- : ActivityEnricher(stringBuilderPool, options);
+ private sealed class InternalActivityEnricher(InstrumentationOptions options) : ActivityEnricher(options);
}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics/HotChocolate.Diagnostics.csproj b/src/HotChocolate/Diagnostics/src/Diagnostics/HotChocolate.Diagnostics.csproj
index 49885604251..a1a4cf24a90 100644
--- a/src/HotChocolate/Diagnostics/src/Diagnostics/HotChocolate.Diagnostics.csproj
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics/HotChocolate.Diagnostics.csproj
@@ -16,6 +16,7 @@
+
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics/InstrumentationOptions.cs b/src/HotChocolate/Diagnostics/src/Diagnostics/InstrumentationOptions.cs
index a28fe4fbd41..1da0a36eb94 100644
--- a/src/HotChocolate/Diagnostics/src/Diagnostics/InstrumentationOptions.cs
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics/InstrumentationOptions.cs
@@ -5,35 +5,18 @@ namespace HotChocolate.Diagnostics;
///
/// The Hot Chocolate instrumentation options.
///
-public sealed class InstrumentationOptions
+public sealed class InstrumentationOptions : InstrumentationOptionsBase
{
- ///
- /// Specifies the request detail that shall be included into the tracing activities.
- ///
- public RequestDetails RequestDetails { get; set; } = RequestDetails.Default;
-
///
/// Specifies the activity scopes that shall be instrumented.
///
public ActivityScopes Scopes { get; set; } = Default;
- ///
- /// Specifies if the parsed document shall be included into the tracing data.
- ///
- public bool IncludeDocument { get; set; }
-
///
/// Specifies if DataLoader batch keys shall be included into the tracing data.
///
public bool IncludeDataLoaderKeys { get; set; }
- ///
- /// Defines if the operation display name shall be included in the root activity.
- ///
- public bool RenameRootActivity { get; set; }
-
- internal bool IncludeRequestDetails => RequestDetails is not RequestDetails.None;
-
internal bool SkipExecuteHttpRequest => (Scopes & ExecuteHttpRequest) != ExecuteHttpRequest;
internal bool SkipParseHttpRequest => (Scopes & ParseHttpRequest) != ParseHttpRequest;
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics/Listeners/ActivityDataLoaderDiagnosticListener.cs b/src/HotChocolate/Diagnostics/src/Diagnostics/Listeners/ActivityDataLoaderDiagnosticListener.cs
index a0eeffcedd6..785291a1891 100644
--- a/src/HotChocolate/Diagnostics/src/Diagnostics/Listeners/ActivityDataLoaderDiagnosticListener.cs
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics/Listeners/ActivityDataLoaderDiagnosticListener.cs
@@ -1,56 +1,55 @@
using System.Diagnostics;
using GreenDonut;
-using HotChocolate.Diagnostics.Scopes;
using static HotChocolate.Diagnostics.HotChocolateActivitySource;
namespace HotChocolate.Diagnostics.Listeners;
-internal sealed class ActivityDataLoaderDiagnosticListener : DataLoaderDiagnosticEventListener
+internal sealed class ActivityDataLoaderDiagnosticListener(
+ ActivityEnricher enricher,
+ InstrumentationOptions options)
+ : DataLoaderDiagnosticEventListener
{
- private readonly InstrumentationOptions _options;
- private readonly ActivityEnricher _enricher;
-
- public ActivityDataLoaderDiagnosticListener(
- ActivityEnricher enricher,
- InstrumentationOptions options)
- {
- _enricher = enricher ?? throw new ArgumentNullException(nameof(enricher));
- _options = options ?? throw new ArgumentNullException(nameof(options));
- }
-
public override IDisposable ExecuteBatch(
IDataLoader dataLoader,
IReadOnlyList keys)
{
- if (_options.SkipDataLoaderBatch)
+ if (options.SkipDataLoaderBatch)
{
return EmptyScope;
}
- var activity = Source.StartActivity();
+ var span = DataLoaderBatchSpan.Start(Source, dataLoader, keys, enricher);
- if (activity is null)
+ if (span is null)
{
return EmptyScope;
}
- return new DataLoaderBatchScope(_enricher, dataLoader, keys, activity);
+ if (options.IncludeDataLoaderKeys)
+ {
+ var temp = keys.Select(t => t.ToString()).ToArray();
+ span.Activity.SetTag(SemanticConventions.GraphQL.DataLoader.Batch.Keys, temp);
+ }
+
+ return span;
}
public override IDisposable RunBatchDispatchCoordinator()
{
- var activity = Source.StartActivity("BatchCoordinator");
- activity?.DisplayName = "Coordinate DataLoader Batches";
- return activity ?? EmptyScope;
+ var span = DataLoaderDispatchSpan.Start(Source, enricher);
+
+ return span ?? EmptyScope;
}
public override void BatchDispatchError(Exception error)
{
-#if NET9_0_OR_GREATER
- Activity.Current?.AddException(error);
-#else
- Activity.Current?.SetStatus(ActivityStatusCode.Error, error.Message);
-#endif
+ if (Activity.Current is { } activity)
+ {
+ activity.SetStatus(ActivityStatusCode.Error);
+ activity.AddException(error);
+
+ enricher.EnrichBatchDispatchError(error, activity);
+ }
}
public override void BatchEvaluated(int openBatches)
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics/Listeners/ActivityExecutionDiagnosticListener.cs b/src/HotChocolate/Diagnostics/src/Diagnostics/Listeners/ActivityExecutionDiagnosticListener.cs
index e9450965209..8c5cdb9cbea 100644
--- a/src/HotChocolate/Diagnostics/src/Diagnostics/Listeners/ActivityExecutionDiagnosticListener.cs
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics/Listeners/ActivityExecutionDiagnosticListener.cs
@@ -1,46 +1,32 @@
using System.Diagnostics;
-using HotChocolate.Diagnostics.Scopes;
using HotChocolate.Execution;
using HotChocolate.Execution.Instrumentation;
using HotChocolate.Resolvers;
using Microsoft.AspNetCore.Http;
using OpenTelemetry.Trace;
-using static HotChocolate.Diagnostics.ContextKeys;
using static HotChocolate.Diagnostics.HotChocolateActivitySource;
namespace HotChocolate.Diagnostics.Listeners;
-internal sealed class ActivityExecutionDiagnosticListener : ExecutionDiagnosticEventListener
+internal sealed class ActivityExecutionDiagnosticListener(
+ ActivityEnricher enricher,
+ InstrumentationOptions options) : ExecutionDiagnosticEventListener
{
- private readonly InstrumentationOptions _options;
- private readonly ActivityEnricher _enricher;
-
- public ActivityExecutionDiagnosticListener(
- ActivityEnricher enricher,
- InstrumentationOptions options)
- {
- ArgumentNullException.ThrowIfNull(enricher);
- ArgumentNullException.ThrowIfNull(options);
-
- _enricher = enricher;
- _options = options;
- }
+ private const string ResolveFieldSpanKey = "HotChocolate.Diagnostics.ResolveFieldSpan";
public override bool EnableResolveFieldValue => true;
public override IDisposable ExecuteRequest(RequestContext context)
{
- Activity? activity = null;
+ Activity? httpContextActivity = null;
- if (_options.SkipExecuteRequest)
+ if (options.SkipExecuteRequest)
{
- if (!_options.SkipExecuteHttpRequest
- && context.ContextData.TryGetValue(nameof(HttpContext), out var value)
- && value is HttpContext httpContext
- && httpContext.Items.TryGetValue(HttpRequestActivity, out value)
- && value is not null)
+ if (!options.SkipExecuteHttpRequest
+ && context.Features.TryGet(out var httpContext)
+ && httpContext.Features.Get() is { } httpRequestSpan)
{
- activity = (Activity)value;
+ httpContextActivity = httpRequestSpan.Activity;
}
else
{
@@ -48,291 +34,303 @@ public override IDisposable ExecuteRequest(RequestContext context)
}
}
- activity ??= Source.StartActivity();
+ var span = httpContextActivity is not null
+ ? new ExecuteRequestSpan(httpContextActivity, context, options, enricher, false)
+ : ExecuteRequestSpan.Start(Source, context, options, enricher);
- if (activity is null)
+ if (span is null)
{
return EmptyScope;
}
- context.ContextData[RequestActivity] = activity;
+ context.Features.Set(span);
- return new ExecuteRequestScope(_enricher, context, activity);
+ return span;
}
- public override void RetrievedDocumentFromCache(RequestContext context)
+ public override void RequestError(RequestContext context, Exception error)
{
- if (context.ContextData.TryGetValue(RequestActivity, out var activity))
+ if (context.Features.TryGet(out var span))
{
- Debug.Assert(activity is not null, "The activity mustn't be null!");
- ((Activity)activity).AddEvent(new(nameof(RetrievedDocumentFromCache)));
- }
- }
+ var activity = span.Activity;
- public override void RetrievedDocumentFromStorage(RequestContext context)
- {
- if (context.ContextData.TryGetValue(RequestActivity, out var activity))
- {
- Debug.Assert(activity is not null, "The activity mustn't be null!");
- ((Activity)activity).AddEvent(new(nameof(RetrievedDocumentFromStorage)));
+ activity.SetStatus(ActivityStatusCode.Error);
+ activity.AddException(error);
+
+ enricher.EnrichRequestError(context, error, activity);
}
}
- public override void AddedDocumentToCache(RequestContext context)
+ public override void RequestError(RequestContext context, IError error)
{
- if (context.ContextData.TryGetValue(RequestActivity, out var activity))
+ if (context.Features.TryGet(out var span))
{
- Debug.Assert(activity is not null, "The activity mustn't be null!");
- ((Activity)activity).AddEvent(new(nameof(AddedDocumentToCache)));
+ var activity = span.Activity;
+
+ activity.SetStatus(ActivityStatusCode.Error);
+ activity.AddGraphQLError(error);
+
+ enricher.EnrichRequestError(context, error, activity);
}
}
- public override void AddedOperationToCache(RequestContext context)
+ public override IDisposable ParseDocument(RequestContext context)
{
- if (context.ContextData.TryGetValue(RequestActivity, out var activity))
+ if (options.SkipParseDocument)
{
- Debug.Assert(activity is not null, "The activity mustn't be null!");
- ((Activity)activity).AddEvent(new(nameof(AddedOperationToCache)));
+ return EmptyScope;
}
+
+ var span = ParsingSpan.Start(Source, context, enricher);
+
+ return span ?? EmptyScope;
}
- public override IDisposable ParseDocument(RequestContext context)
+ public override IDisposable ValidateDocument(RequestContext context)
{
- if (_options.SkipParseDocument)
+ if (options.SkipValidateDocument)
{
return EmptyScope;
}
- var activity = Source.StartActivity();
+ var span = ValidationSpan.Start(Source, context, enricher);
- if (activity is null)
+ if (span is null)
{
return EmptyScope;
}
- context.ContextData[RequestActivity] = activity;
+ context.Features.Set(span);
- return new ParseDocumentScope(_enricher, context, activity);
+ return span;
}
- public override void RequestError(RequestContext context, Exception error)
+ public override void ValidationErrors(RequestContext context, IReadOnlyList errors)
{
- if (context.ContextData.TryGetValue(RequestActivity, out var value))
+ if (!context.Features.TryGet(out var span))
{
- Debug.Assert(value is not null, "The activity mustn't be null!");
-
- var activity = (Activity)value;
- _enricher.EnrichRequestError(context, activity, error);
- activity.SetStatus(Status.Error);
- activity.SetStatus(ActivityStatusCode.Error);
+ return;
}
- }
- public override void RequestError(RequestContext context, IError error)
- {
- if (context.ContextData.TryGetValue(RequestActivity, out var value))
- {
- Debug.Assert(value is not null, "The activity mustn't be null!");
+ var activity = span.Activity;
- var activity = (Activity)value;
- _enricher.EnrichRequestError(context, activity, error);
- activity.SetStatus(Status.Error);
- activity.SetStatus(ActivityStatusCode.Error);
+ activity.SetStatus(ActivityStatusCode.Error);
+
+ foreach (var error in errors)
+ {
+ activity.AddGraphQLError(error);
}
+
+ enricher.EnrichValidationErrors(context, errors, activity);
}
- public override void ValidationErrors(RequestContext context, IReadOnlyList errors)
+ public override IDisposable AnalyzeOperationCost(RequestContext context)
{
- if (context.ContextData.TryGetValue(ValidateActivity, out var value))
+ if (options.SkipAnalyzeComplexity)
{
- Debug.Assert(value is not null, "The activity mustn't be null!");
-
- var activity = (Activity)value;
+ return EmptyScope;
+ }
- foreach (var error in errors)
- {
- _enricher.EnrichValidationError(context, activity, error);
- }
+ var span = AnalyzeOperationComplexitySpan.Start(Source, context, enricher);
- activity.SetStatus(Status.Error);
- activity.SetStatus(ActivityStatusCode.Error);
+ if (span is null)
+ {
+ return EmptyScope;
}
+
+ context.Features.Set(span);
+
+ return span;
}
- public override void ResolverError(IMiddlewareContext context, IError error)
+ public override void OperationCost(RequestContext context, double fieldCost, double typeCost)
{
- if (context.LocalContextData.TryGetValue(ResolverActivity, out var localValue)
- && localValue is Activity activity)
+ if (!context.Features.TryGet(out var span))
{
- _enricher.EnrichResolverError(context, error, activity);
- activity.SetStatus(Status.Error);
- activity.SetStatus(ActivityStatusCode.Error);
+ return;
}
+
+ span.SetCost(fieldCost, typeCost);
}
- public override void ResolverError(RequestContext context, ISelection selection, IError error)
+ public override IDisposable CompileOperation(RequestContext context)
{
- if (context.ContextData.TryGetValue(RequestActivity, out var value))
+ if (options.SkipCompileOperation)
{
- Debug.Assert(value is not null, "The activity mustn't be null!");
-
- var activity = (Activity)value;
+ return EmptyScope;
+ }
- _enricher.EnrichResolverError(context, error, activity);
+ var span = CompileOperationSpan.Start(Source, context, enricher);
- activity.SetStatus(Status.Error);
- activity.SetStatus(ActivityStatusCode.Error);
- }
+ return span ?? EmptyScope;
}
- public override IDisposable ValidateDocument(RequestContext context)
+ public override IDisposable CoerceVariables(RequestContext context)
{
- if (_options.SkipValidateDocument)
+ if (options.SkipCoerceVariables)
{
return EmptyScope;
}
- var activity = Source.StartActivity();
-
- if (activity is null)
+ if (!context.TryGetOperation(out var operation))
{
return EmptyScope;
}
- context.ContextData[ValidateActivity] = activity;
+ var span = VariableCoercionSpan.Start(
+ Source,
+ context,
+ operation.Kind,
+ operation.Name,
+ enricher);
- return new ValidateDocumentScope(_enricher, context, activity);
+ return span ?? EmptyScope;
}
- public override IDisposable AnalyzeOperationCost(RequestContext context)
+ public override IDisposable ExecuteOperation(RequestContext context)
{
- if (_options.SkipAnalyzeComplexity)
+ if (options.SkipExecuteOperation)
{
return EmptyScope;
}
- var activity = Source.StartActivity();
-
- if (activity is null)
+ if (!context.TryGetOperation(out var operation))
{
return EmptyScope;
}
- context.ContextData[ComplexityActivity] = activity;
+ var span = ExecuteOperationSpan.Start(
+ Source,
+ context,
+ operation.Kind,
+ operation.Name,
+ enricher);
- return new AnalyzeOperationComplexityScope(_enricher, context, activity);
- }
-
- public override void OperationCost(RequestContext context, double fieldCost, double typeCost)
- {
- if (context.ContextData.TryGetValue(ComplexityActivity, out var value))
- {
- Debug.Assert(value is not null, "The activity mustn't be null!");
-
- var activity = (Activity)value;
-
- var documentInfo = context.OperationDocumentInfo;
- activity.SetTag("graphql.operation.id", documentInfo.Id.Value);
- activity.SetTag("graphql.operation.fieldCost", fieldCost);
- activity.SetTag("graphql.operation.typeCost", typeCost);
- }
+ return span ?? EmptyScope;
}
- public override IDisposable CoerceVariables(RequestContext context)
+ public override IDisposable ResolveFieldValue(IMiddlewareContext context)
{
- if (_options.SkipCoerceVariables)
+ if (options.SkipResolveFieldValue)
{
return EmptyScope;
}
- var activity = Source.StartActivity();
+ var span = ResolveFieldSpan.Start(Source, context, enricher);
- if (activity is null)
+ if (span is null)
{
return EmptyScope;
}
- return new CoerceVariablesScope(_enricher, context, activity);
+ context.LocalContextData = context.LocalContextData.SetItem(ResolveFieldSpanKey, span);
+
+ return span;
}
- public override IDisposable CompileOperation(RequestContext context)
+ public override void ResolverError(IMiddlewareContext context, IError error)
{
- if (_options.SkipCompileOperation)
+ if (context.LocalContextData.TryGetValue(ResolveFieldSpanKey, out var value)
+ && value is ResolveFieldSpan span)
{
- return EmptyScope;
- }
+ span.Activity.SetStatus(ActivityStatusCode.Error);
+ span.Activity.AddGraphQLError(error);
- var activity = Source.StartActivity();
+ enricher.EnrichResolverError(context, error, span.Activity);
+ }
+ }
- if (activity is null)
+ public override IDisposable ExecuteSubscription(
+ RequestContext context,
+ ulong subscriptionId)
+ {
+ if (Activity.Current is not { } currentActivity)
{
return EmptyScope;
}
- return new CompileOperationScope(_enricher, context, activity);
+ context.Features.Set(
+ new SubscriptionContextFeature
+ {
+ SubscriptionContext = currentActivity.Context
+ });
+
+ return EmptyScope;
}
- public override IDisposable ExecuteOperation(RequestContext context)
+ public override IDisposable OnSubscriptionEvent(RequestContext context, ulong subscriptionId)
{
- if (_options.SkipExecuteOperation)
+ ActivityContext? subscriptionContext = null;
+
+ if (context.Features.TryGet(out var feature)
+ && feature.SubscriptionContext is { } storedSubscriptionContext)
{
- return EmptyScope;
+ subscriptionContext = storedSubscriptionContext;
}
- var activity = Source.StartActivity();
+ var span = SubscriptionEventSpan.Start(
+ Source,
+ context,
+ context.TryGetOperation(out var operation) ? operation.Name : null,
+ subscriptionId,
+ subscriptionContext);
- if (activity is null)
+ if (span is null)
{
return EmptyScope;
}
- return new ExecuteOperationScope(_enricher, context, activity);
+ enricher.EnrichOnSubscriptionEvent(context, subscriptionId, span.Activity);
+
+ return span;
}
- public override IDisposable ExecuteStream(IOperation operation)
+ public override void SubscriptionEventError(
+ RequestContext context,
+ ulong subscriptionId,
+ Exception exception)
{
- var activity = Source.StartActivity();
-
- if (activity is null)
+ if (Activity.Current is { } activity)
{
- return EmptyScope;
+ activity.SetStatus(ActivityStatusCode.Error);
+ activity.AddException(exception);
}
-
- return activity;
}
- public override IDisposable OnSubscriptionEvent(RequestContext context, ulong subscriptionId)
+ public override void RetrievedDocumentFromCache(RequestContext context)
{
- var activity = Source.StartActivity();
-
- if (activity is null)
+ if (context.Features.TryGet(out var span))
{
- return EmptyScope;
+ span.Activity.AddEvent(new(nameof(RetrievedDocumentFromCache)));
}
-
- return activity;
}
- public override IDisposable ResolveFieldValue(IMiddlewareContext context)
+ public override void RetrievedDocumentFromStorage(RequestContext context)
{
- if (_options.SkipResolveFieldValue)
+ if (context.Features.TryGet(out var span))
{
- return EmptyScope;
+ span.Activity.AddEvent(new(nameof(RetrievedDocumentFromStorage)));
}
+ }
- var activity = Source.StartActivity();
-
- if (activity is null)
+ public override void AddedDocumentToCache(RequestContext context)
+ {
+ if (context.Features.TryGet(out var span))
{
- return EmptyScope;
+ span.Activity.AddEvent(new(nameof(AddedDocumentToCache)));
}
+ }
- _enricher.EnrichResolveFieldValue(context, activity);
- activity.SetStatus(Status.Ok);
- activity.SetStatus(ActivityStatusCode.Ok);
-
- context.SetLocalState(ResolverActivity, activity);
+ public override void AddedOperationToCache(RequestContext context)
+ {
+ if (context.Features.TryGet(out var span))
+ {
+ span.Activity.AddEvent(new(nameof(AddedOperationToCache)));
+ }
+ }
- return activity;
+ private sealed class SubscriptionContextFeature
+ {
+ public ActivityContext? SubscriptionContext { get; set; }
}
}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics/Listeners/ActivityServerDiagnosticListener.cs b/src/HotChocolate/Diagnostics/src/Diagnostics/Listeners/ActivityServerDiagnosticListener.cs
index 7f803428364..b10d244b12a 100644
--- a/src/HotChocolate/Diagnostics/src/Diagnostics/Listeners/ActivityServerDiagnosticListener.cs
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics/Listeners/ActivityServerDiagnosticListener.cs
@@ -1,62 +1,50 @@
-using System.Diagnostics;
using Microsoft.AspNetCore.Http;
using HotChocolate.AspNetCore.Instrumentation;
using HotChocolate.Execution;
using HotChocolate.Language;
-using OpenTelemetry.Trace;
-using static HotChocolate.Diagnostics.ContextKeys;
+using static HotChocolate.Diagnostics.HotChocolateActivitySource;
namespace HotChocolate.Diagnostics.Listeners;
-internal sealed class ActivityServerDiagnosticListener : ServerDiagnosticEventListener
+internal sealed class ActivityServerDiagnosticListener(
+ ActivityEnricher enricher,
+ InstrumentationOptions options)
+ : ServerDiagnosticEventListener
{
- private readonly InstrumentationOptions _options;
- private readonly ActivityEnricher _enricher;
-
- public ActivityServerDiagnosticListener(
- ActivityEnricher enricher,
- InstrumentationOptions options)
- {
- _enricher = enricher ?? throw new ArgumentNullException(nameof(enricher));
- _options = options ?? throw new ArgumentNullException(nameof(options));
- }
-
public override IDisposable ExecuteHttpRequest(HttpContext context, HttpRequestKind kind)
{
- if (_options.SkipExecuteHttpRequest)
+ if (options.SkipExecuteHttpRequest)
{
return EmptyScope;
}
- var activity = HotChocolateActivitySource.Source.StartActivity();
+ var span = ExecuteHttpRequestSpan.Start(Source, context, kind, enricher, options);
- if (activity is null)
+ if (span is null)
{
return EmptyScope;
}
- _enricher.EnrichExecuteHttpRequest(context, kind, activity);
- activity.SetStatus(ActivityStatusCode.Ok);
- context.Items[HttpRequestActivity] = activity;
+ context.Features.Set(span);
- return activity;
+ return span;
}
public override void StartSingleRequest(HttpContext context, GraphQLRequest request)
{
- if (_options.IncludeRequestDetails
- && context.Items.TryGetValue(HttpRequestActivity, out var activity))
+ if (options.IncludeRequestDetails
+ && context.Features.Get() is { } span)
{
- _enricher.EnrichSingleRequest(context, request, (Activity)activity!);
+ span.SetSingleRequestDetails(request);
}
}
public override void StartBatchRequest(HttpContext context, IReadOnlyList batch)
{
- if (_options.IncludeRequestDetails
- && context.Items.TryGetValue(HttpRequestActivity, out var activity))
+ if (options.IncludeRequestDetails
+ && context.Features.Get() is { } span)
{
- _enricher.EnrichBatchRequest(context, batch, (Activity)activity!);
+ span.SetBatchRequestDetails(batch);
}
}
@@ -65,93 +53,65 @@ public override void StartOperationBatchRequest(
GraphQLRequest request,
IReadOnlyList operations)
{
- if (_options.IncludeRequestDetails
- && context.Items.TryGetValue(HttpRequestActivity, out var activity))
+ if (options.IncludeRequestDetails
+ && context.Features.Get() is { } span)
{
- _enricher.EnrichOperationBatchRequest(
- context,
- request,
- operations,
- (Activity)activity!);
+ span.SetOperationBatchRequestDetails(request, operations);
}
}
public override void HttpRequestError(HttpContext context, IError error)
{
- if (context.Items.TryGetValue(HttpRequestActivity, out var value))
+ if (context.Features.Get() is { } span)
{
- var activity = (Activity)value!;
- _enricher.EnrichHttpRequestError(context, error, activity);
- activity.SetStatus(Status.Error);
+ span.RecordError(error);
}
}
public override void HttpRequestError(HttpContext context, Exception exception)
{
- if (context.Items.TryGetValue(HttpRequestActivity, out var value))
+ if (context.Features.Get() is { } span)
{
- var activity = (Activity)value!;
- _enricher.EnrichHttpRequestError(context, exception, activity);
- activity.SetStatus(Status.Error);
+ span.RecordError(exception);
}
}
public override IDisposable ParseHttpRequest(HttpContext context)
{
- if (_options.SkipParseHttpRequest)
+ if (options.SkipParseHttpRequest)
{
return EmptyScope;
}
- var activity = HotChocolateActivitySource.Source.StartActivity();
+ var span = ParseHttpRequestSpan.Start(Source, context, enricher);
- if (activity is null)
+ if (span is null)
{
return EmptyScope;
}
- _enricher.EnrichParseHttpRequest(context, activity);
- activity.SetStatus(Status.Ok);
- activity.SetStatus(ActivityStatusCode.Ok);
- context.Items[ParseHttpRequestActivity] = activity;
+ context.Features.Set(span);
- return activity;
+ return span;
}
public override void ParserErrors(HttpContext context, IReadOnlyList errors)
{
- if (context.Items.TryGetValue(ParseHttpRequestActivity, out var value))
+ if (context.Features.Get() is { } span)
{
- var activity = (Activity)value!;
-
- foreach (var error in errors)
- {
- _enricher.EnrichParserErrors(context, error, activity);
- }
-
- activity.SetStatus(Status.Error);
- activity.SetStatus(ActivityStatusCode.Error);
+ span.RecordErrors(errors);
}
}
public override IDisposable FormatHttpResponse(HttpContext context, OperationResult result)
{
- if (_options.SkipFormatHttpResponse)
- {
- return EmptyScope;
- }
-
- var activity = HotChocolateActivitySource.Source.StartActivity();
-
- if (activity is null)
+ if (options.SkipFormatHttpResponse)
{
return EmptyScope;
}
- _enricher.EnrichFormatHttpResponse(context, activity);
- activity.SetStatus(ActivityStatusCode.Ok);
- context.Items[FormatHttpResponseActivity] = activity;
+ var span = FormatHttpResponseSpan.Start(Source, context, enricher);
- return activity;
+ return span ?? EmptyScope;
}
}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics/RequestDetails.cs b/src/HotChocolate/Diagnostics/src/Diagnostics/RequestDetails.cs
deleted file mode 100644
index 58a8e5d33e1..00000000000
--- a/src/HotChocolate/Diagnostics/src/Diagnostics/RequestDetails.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-namespace HotChocolate.Diagnostics;
-
-[Flags]
-public enum RequestDetails
-{
- None = 0,
- Id = 1,
- Hash = 2,
- Operation = 4,
- Variables = 8,
- Extensions = 16,
- Query = 32,
- Default = Id | Hash | Operation | Extensions,
- All = Id | Hash | Operation | Variables | Extensions | Query
-}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/AnalyzeOperationComplexityScope.cs b/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/AnalyzeOperationComplexityScope.cs
deleted file mode 100644
index f4845164f4b..00000000000
--- a/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/AnalyzeOperationComplexityScope.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Diagnostics;
-using HotChocolate.Execution;
-
-namespace HotChocolate.Diagnostics.Scopes;
-
-internal sealed class AnalyzeOperationComplexityScope : RequestScopeBase
-{
- public AnalyzeOperationComplexityScope(
- ActivityEnricher enricher,
- RequestContext context,
- Activity activity)
- : base(enricher, context, activity)
- {
- }
-
- protected override void EnrichActivity()
- => Enricher.EnrichAnalyzeOperationComplexity(Context, Activity);
-}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/CoerceVariablesScope.cs b/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/CoerceVariablesScope.cs
deleted file mode 100644
index 258f8d78059..00000000000
--- a/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/CoerceVariablesScope.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System.Diagnostics;
-using HotChocolate.Execution;
-using OpenTelemetry.Trace;
-
-namespace HotChocolate.Diagnostics.Scopes;
-
-internal sealed class CoerceVariablesScope : RequestScopeBase
-{
- public CoerceVariablesScope(
- ActivityEnricher enricher,
- RequestContext context,
- Activity activity)
- : base(enricher, context, activity)
- {
- }
-
- protected override void EnrichActivity()
- => Enricher.EnrichCoerceVariables(Context, Activity);
-
- protected override void SetStatus()
- {
- if (Context.VariableValues.Length > 0)
- {
- Activity.SetStatus(Status.Ok);
- Activity.SetStatus(ActivityStatusCode.Ok);
- }
- }
-}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/CompileOperationScope.cs b/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/CompileOperationScope.cs
deleted file mode 100644
index ed07a17dea6..00000000000
--- a/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/CompileOperationScope.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System.Diagnostics;
-using HotChocolate.Execution;
-using OpenTelemetry.Trace;
-
-namespace HotChocolate.Diagnostics.Scopes;
-
-internal sealed class CompileOperationScope : RequestScopeBase
-{
- public CompileOperationScope(
- ActivityEnricher enricher,
- RequestContext context,
- Activity activity)
- : base(enricher, context, activity)
- {
- }
-
- protected override void EnrichActivity()
- => Enricher.EnrichCompileOperation(Context, Activity);
-
- protected override void SetStatus()
- {
- if (Context.TryGetOperation(out _))
- {
- Activity.SetStatus(Status.Ok);
- Activity.SetStatus(ActivityStatusCode.Ok);
- }
- }
-}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/DataLoaderBatchScope.cs b/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/DataLoaderBatchScope.cs
deleted file mode 100644
index 245b0481fac..00000000000
--- a/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/DataLoaderBatchScope.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using System.Diagnostics;
-using GreenDonut;
-
-namespace HotChocolate.Diagnostics.Scopes;
-
-internal sealed class DataLoaderBatchScope : IDisposable where TKey : notnull
-{
- private readonly ActivityEnricher _enricher;
- private readonly IDataLoader _dataLoader;
- private readonly IReadOnlyList _keys;
- private readonly Activity _activity;
- private bool _disposed;
-
- public DataLoaderBatchScope(
- ActivityEnricher enricher,
- IDataLoader dataLoader,
- IReadOnlyList keys,
- Activity activity)
- {
- _enricher = enricher;
- _dataLoader = dataLoader;
- _keys = keys;
- _activity = activity;
- }
-
- public void Dispose()
- {
- if (!_disposed)
- {
- _enricher.EnrichDataLoaderBatch(_dataLoader, _keys, _activity);
- _activity.Dispose();
- _disposed = true;
- }
- }
-}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/ExecuteOperationScope.cs b/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/ExecuteOperationScope.cs
deleted file mode 100644
index 2c7915ad6d0..00000000000
--- a/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/ExecuteOperationScope.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using System.Diagnostics;
-using HotChocolate.Execution;
-using OpenTelemetry.Trace;
-
-namespace HotChocolate.Diagnostics.Scopes;
-
-internal sealed class ExecuteOperationScope : RequestScopeBase
-{
- public ExecuteOperationScope(
- ActivityEnricher enricher,
- RequestContext context,
- Activity activity)
- : base(enricher, context, activity)
- {
- }
-
- protected override void EnrichActivity()
- => Enricher.EnrichExecuteOperation(Context, Activity);
-
- protected override void SetStatus()
- {
- if (Context.Result is null or OperationResult { Errors: [_, ..] })
- {
- Activity.SetStatus(Status.Error);
- Activity.SetStatus(ActivityStatusCode.Error);
- }
- else
- {
- Activity.SetStatus(Status.Ok);
- Activity.SetStatus(ActivityStatusCode.Ok);
- }
- }
-}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/ExecuteRequestScope.cs b/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/ExecuteRequestScope.cs
deleted file mode 100644
index 32c4affad3f..00000000000
--- a/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/ExecuteRequestScope.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System.Diagnostics;
-using HotChocolate.Execution;
-using OpenTelemetry.Trace;
-
-namespace HotChocolate.Diagnostics.Scopes;
-
-internal sealed class ExecuteRequestScope : RequestScopeBase
-{
- public ExecuteRequestScope(
- ActivityEnricher enricher,
- RequestContext context,
- Activity activity)
- : base(enricher, context, activity)
- {
- }
-
- protected override void EnrichActivity()
- => Enricher.EnrichExecuteRequest(Context, Activity);
-
- protected override void SetStatus()
- {
- if (Context.Result is null or OperationResult { Errors: [_, ..] })
- {
- Activity.SetStatus(Status.Error);
- Activity.SetStatus(ActivityStatusCode.Error);
- }
- }
-}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/ParseDocumentScope.cs b/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/ParseDocumentScope.cs
deleted file mode 100644
index 3a3d26c166a..00000000000
--- a/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/ParseDocumentScope.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System.Diagnostics;
-using HotChocolate.Execution;
-using OpenTelemetry.Trace;
-
-namespace HotChocolate.Diagnostics.Scopes;
-
-internal sealed class ParseDocumentScope : RequestScopeBase
-{
- public ParseDocumentScope(
- ActivityEnricher enricher,
- RequestContext context,
- Activity activity)
- : base(enricher, context, activity)
- {
- }
-
- protected override void EnrichActivity()
- => Enricher.EnrichParseDocument(Context, Activity);
-
- protected override void SetStatus()
- {
- if (Context.TryGetOperationDocument(out _, out _))
- {
- Activity.SetStatus(Status.Ok);
- Activity.SetStatus(ActivityStatusCode.Ok);
- }
- }
-}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/RequestScopeBase.cs b/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/RequestScopeBase.cs
deleted file mode 100644
index 00e263db91a..00000000000
--- a/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/RequestScopeBase.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using System.Diagnostics;
-using HotChocolate.Execution;
-
-namespace HotChocolate.Diagnostics.Scopes;
-
-internal class RequestScopeBase : IDisposable
-{
- private bool _disposed;
-
- protected RequestScopeBase(
- ActivityEnricher enricher,
- RequestContext context,
- Activity activity)
- {
- Enricher = enricher ?? throw new ArgumentNullException(nameof(enricher));
- Context = context ?? throw new ArgumentNullException(nameof(context));
- Activity = activity ?? throw new ArgumentNullException(nameof(activity));
- }
-
- protected ActivityEnricher Enricher { get; }
-
- protected RequestContext Context { get; }
-
- protected Activity Activity { get; }
-
- protected virtual void EnrichActivity() { }
-
- protected virtual void SetStatus() { }
-
- public void Dispose()
- {
- if (!_disposed)
- {
- EnrichActivity();
- SetStatus();
- Activity.Dispose();
- _disposed = true;
- }
- }
-}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/ValidateDocumentScope.cs b/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/ValidateDocumentScope.cs
deleted file mode 100644
index 291126ba469..00000000000
--- a/src/HotChocolate/Diagnostics/src/Diagnostics/Scopes/ValidateDocumentScope.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System.Diagnostics;
-using HotChocolate.Execution;
-using OpenTelemetry.Trace;
-
-namespace HotChocolate.Diagnostics.Scopes;
-
-internal sealed class ValidateDocumentScope : RequestScopeBase
-{
- public ValidateDocumentScope(
- ActivityEnricher enricher,
- RequestContext context,
- Activity activity)
- : base(enricher, context, activity)
- {
- }
-
- protected override void EnrichActivity()
- => Enricher.EnrichValidateDocument(Context, Activity);
-
- protected override void SetStatus()
- {
- if (Context.IsOperationDocumentValid())
- {
- Activity.SetStatus(Status.Ok);
- Activity.SetStatus(ActivityStatusCode.Ok);
- }
- }
-}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics/Spans/CompileOperationSpan.cs b/src/HotChocolate/Diagnostics/src/Diagnostics/Spans/CompileOperationSpan.cs
new file mode 100644
index 00000000000..78d40a07a6b
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics/Spans/CompileOperationSpan.cs
@@ -0,0 +1,42 @@
+using System.Diagnostics;
+using HotChocolate.Execution;
+using static HotChocolate.Diagnostics.SemanticConventions;
+
+namespace HotChocolate.Diagnostics;
+
+internal sealed class CompileOperationSpan(
+ Activity activity,
+ RequestContext context,
+ ActivityEnricher enricher) : SpanBase(activity)
+{
+ public static CompileOperationSpan? Start(
+ ActivitySource source,
+ RequestContext context,
+ ActivityEnricher enricher)
+ {
+ var activity = source.StartActivity("GraphQL Operation Planning");
+
+ if (activity is null)
+ {
+ return null;
+ }
+
+ activity.SetTag(GraphQL.Processing.Type, GraphQL.Processing.TypeValues.Plan);
+
+ activity.EnrichDocumentInfo(context.OperationDocumentInfo);
+
+ return new CompileOperationSpan(activity, context, enricher);
+ }
+
+ protected override void OnComplete()
+ {
+ if (context.TryGetOperation(out var operation))
+ {
+ Activity.SetStatus(ActivityStatusCode.Ok);
+
+ Activity.EnrichOperation(operation.Kind, operation.Name);
+ }
+
+ enricher.EnrichCompileOperation(context, Activity);
+ }
+}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics/Spans/DataLoaderBatchSpan.cs b/src/HotChocolate/Diagnostics/src/Diagnostics/Spans/DataLoaderBatchSpan.cs
new file mode 100644
index 00000000000..108a2e35cf6
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics/Spans/DataLoaderBatchSpan.cs
@@ -0,0 +1,45 @@
+using System.Diagnostics;
+using GreenDonut;
+using static HotChocolate.Diagnostics.SemanticConventions;
+
+namespace HotChocolate.Diagnostics;
+
+internal sealed class DataLoaderBatchSpan(
+ Activity activity,
+ IDataLoader dataLoader,
+ IReadOnlyList keys,
+ ActivityEnricher enricher) : SpanBase(activity) where TKey : notnull
+{
+ public static DataLoaderBatchSpan? Start(
+ ActivitySource source,
+ IDataLoader dataLoader,
+ IReadOnlyList keys,
+ ActivityEnricher enricher)
+ {
+ var dataLoaderName = dataLoader.GetType().Name;
+
+ var activity = source.StartActivity($"GraphQL DataLoader Batch {dataLoaderName}");
+
+ if (activity is null)
+ {
+ return null;
+ }
+
+ activity.SetTag(GraphQL.Processing.Type, GraphQL.Processing.TypeValues.DataLoaderBatch);
+
+ activity.SetTag(GraphQL.DataLoader.Name, dataLoaderName);
+ activity.SetTag(GraphQL.DataLoader.Batch.Size, keys.Count);
+
+ return new DataLoaderBatchSpan(activity, dataLoader, keys, enricher);
+ }
+
+ protected override void OnComplete()
+ {
+ if (Activity.Status != ActivityStatusCode.Error)
+ {
+ Activity.SetStatus(ActivityStatusCode.Ok);
+ }
+
+ enricher.EnrichExecuteBatch(dataLoader, keys, Activity);
+ }
+}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics/Spans/DataLoaderDispatchSpan.cs b/src/HotChocolate/Diagnostics/src/Diagnostics/Spans/DataLoaderDispatchSpan.cs
new file mode 100644
index 00000000000..d7f8b1d8f9f
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics/Spans/DataLoaderDispatchSpan.cs
@@ -0,0 +1,35 @@
+using System.Diagnostics;
+using static HotChocolate.Diagnostics.SemanticConventions;
+
+namespace HotChocolate.Diagnostics;
+
+internal sealed class DataLoaderDispatchSpan(
+ Activity activity,
+ ActivityEnricher enricher) : SpanBase(activity)
+{
+ public static DataLoaderDispatchSpan? Start(
+ ActivitySource source,
+ ActivityEnricher enricher)
+ {
+ var activity = source.StartActivity("GraphQL DataLoader Dispatch");
+
+ if (activity is null)
+ {
+ return null;
+ }
+
+ activity.SetTag(GraphQL.Processing.Type, GraphQL.Processing.TypeValues.DataLoaderDispatch);
+
+ return new DataLoaderDispatchSpan(activity, enricher);
+ }
+
+ protected override void OnComplete()
+ {
+ if (Activity.Status != ActivityStatusCode.Error)
+ {
+ Activity.SetStatus(ActivityStatusCode.Ok);
+ }
+
+ enricher.EnrichRunBatchDispatchCoordinator(Activity);
+ }
+}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics/Spans/ExecuteRequestSpan.cs b/src/HotChocolate/Diagnostics/src/Diagnostics/Spans/ExecuteRequestSpan.cs
new file mode 100644
index 00000000000..8a60d10a264
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics/Spans/ExecuteRequestSpan.cs
@@ -0,0 +1,51 @@
+using System.Diagnostics;
+using HotChocolate.Execution;
+using HotChocolate.Language;
+
+namespace HotChocolate.Diagnostics;
+
+internal sealed class ExecuteRequestSpan(
+ Activity activity,
+ RequestContext context,
+ InstrumentationOptionsBase options,
+ ActivityEnricherBase? enricher,
+ bool shouldDisposeActivity)
+ : ExecuteRequestSpanBase(activity, context, options, enricher, shouldDisposeActivity)
+{
+ public static ExecuteRequestSpan? Start(
+ ActivitySource source,
+ RequestContext context,
+ InstrumentationOptionsBase options,
+ ActivityEnricherBase enricher)
+ {
+ var activity = StartActivity(source);
+
+ if (activity is null)
+ {
+ return null;
+ }
+
+ return new ExecuteRequestSpan(
+ activity,
+ context,
+ options,
+ enricher,
+ true);
+ }
+
+ protected override bool TryGetOperationInfo(
+ out OperationType operationType,
+ out string? operationName)
+ {
+ if (Context.TryGetOperation(out var operation))
+ {
+ operationType = operation.Kind;
+ operationName = operation.Name;
+ return true;
+ }
+
+ operationType = default;
+ operationName = null;
+ return false;
+ }
+}
diff --git a/src/HotChocolate/Diagnostics/src/Diagnostics/Spans/ResolveFieldSpan.cs b/src/HotChocolate/Diagnostics/src/Diagnostics/Spans/ResolveFieldSpan.cs
new file mode 100644
index 00000000000..5efaf83d4ef
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/src/Diagnostics/Spans/ResolveFieldSpan.cs
@@ -0,0 +1,49 @@
+using System.Diagnostics;
+using HotChocolate.Execution;
+using HotChocolate.Resolvers;
+using OpenTelemetry.Trace;
+using static HotChocolate.Diagnostics.SemanticConventions;
+
+namespace HotChocolate.Diagnostics;
+
+internal sealed class ResolveFieldSpan(
+ Activity activity,
+ IMiddlewareContext context,
+ ActivityEnricher enricher) : SpanBase(activity)
+{
+ public static ResolveFieldSpan? Start(
+ ActivitySource source,
+ IMiddlewareContext context,
+ ActivityEnricher enricher)
+ {
+ var selection = context.Selection;
+ var coordinate = selection.Field.Coordinate;
+
+ var activity = source.StartActivity(coordinate.ToString());
+
+ if (activity is null)
+ {
+ return null;
+ }
+
+ activity.SetTag(GraphQL.Processing.Type, GraphQL.Processing.TypeValues.Resolve);
+
+ activity.SetTag(GraphQL.Selection.Name, selection.ResponseName);
+ activity.SetTag(GraphQL.Selection.Path, context.Path.Print());
+ activity.SetTag(GraphQL.Selection.Field.Name, coordinate.MemberName);
+ activity.SetTag(GraphQL.Selection.Field.Coordinate, activity.DisplayName);
+ activity.SetTag(GraphQL.Selection.Field.ParentType, coordinate.Name);
+
+ return new ResolveFieldSpan(activity, context, enricher);
+ }
+
+ protected override void OnComplete()
+ {
+ if (Activity.Status != ActivityStatusCode.Error)
+ {
+ Activity.SetStatus(ActivityStatusCode.Ok);
+ }
+
+ enricher.EnrichResolveFieldValue(context, Activity);
+ }
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/ActivityDataLoaderDiagnosticListenerTests.cs b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/ActivityDataLoaderDiagnosticListenerTests.cs
new file mode 100644
index 00000000000..c8c6558cd1f
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/ActivityDataLoaderDiagnosticListenerTests.cs
@@ -0,0 +1,49 @@
+using static HotChocolate.Diagnostics.ActivityTestHelper;
+
+namespace HotChocolate.Diagnostics;
+
+[Collection("Instrumentation")]
+public class ActivityDataLoaderDiagnosticListenerTests
+{
+ [Fact]
+ public void Run_Batch_Dispatch_Coordinator_Emits_Activity()
+ {
+ using (CaptureActivities(out var activities))
+ {
+ var listener = CreateListener(ActivityScopes.DataLoaderBatch);
+
+ using (listener.RunBatchDispatchCoordinator())
+ {
+ }
+
+ activities.MatchSnapshot();
+ }
+ }
+
+ [Fact]
+ public void Run_Batch_Dispatch_Coordinator_Tracks_Dispatch_Events()
+ {
+ using (CaptureActivities(out var activities))
+ {
+ var listener = CreateListener(ActivityScopes.DataLoaderBatch);
+
+ using (listener.RunBatchDispatchCoordinator())
+ {
+ listener.BatchEvaluated(2);
+ listener.BatchDispatched(1);
+ }
+
+ activities.MatchSnapshot();
+ }
+ }
+
+ private static Listeners.ActivityDataLoaderDiagnosticListener CreateListener(ActivityScopes scopes)
+ {
+ var options = new InstrumentationOptions
+ {
+ Scopes = scopes
+ };
+ var enricher = new ActivityEnricher(options);
+ return new Listeners.ActivityDataLoaderDiagnosticListener(enricher, options);
+ }
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/ActivityExecutionDiagnosticListenerTests.cs b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/ActivityExecutionDiagnosticListenerTests.cs
new file mode 100644
index 00000000000..0afb95988a2
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/ActivityExecutionDiagnosticListenerTests.cs
@@ -0,0 +1,524 @@
+using Microsoft.Extensions.DependencyInjection;
+using HotChocolate.Execution;
+using HotChocolate.Language;
+using HotChocolate.PersistedOperations;
+using HotChocolate.Subscriptions;
+using HotChocolate.Types;
+using static HotChocolate.Diagnostics.ActivityTestHelper;
+
+namespace HotChocolate.Diagnostics;
+
+[Collection("Instrumentation")]
+public partial class ActivityExecutionDiagnosticListenerTests
+{
+ [Fact]
+ public async Task Track_Events_Of_A_Simple_Query_Default()
+ {
+ using (CaptureActivities(out var activities))
+ {
+ // arrange & act
+ await new ServiceCollection()
+ .AddGraphQL()
+ .AddInstrumentation()
+ .AddQueryType()
+ .ExecuteRequestAsync("{ sayHello }");
+
+ // assert
+ activities.MatchSnapshot();
+ }
+ }
+
+ [Fact]
+ public async Task Allow_Document_To_Be_Captured()
+ {
+ using (CaptureActivities(out var activities))
+ {
+ // arrange & act
+ await new ServiceCollection()
+ .AddGraphQL()
+ .AddInstrumentation(o =>
+ {
+ o.Scopes = ActivityScopes.All;
+ o.IncludeDocument = true;
+ })
+ .AddQueryType()
+ .ExecuteRequestAsync("query SayHelloOperation { sayHello }");
+
+ // assert
+ activities.MatchSnapshot();
+ }
+ }
+
+ [Fact]
+ public async Task Ensure_That_The_Validation_Activity_Has_An_Error_Status()
+ {
+ using (CaptureActivities(out var activities))
+ {
+ // arrange & act
+ await new ServiceCollection()
+ .AddGraphQL()
+ .AddInstrumentation(o =>
+ {
+ o.Scopes = ActivityScopes.All;
+ o.IncludeDocument = true;
+ })
+ .AddQueryType()
+ .ExecuteRequestAsync("query SayHelloOperation { sayHello_ }");
+
+ // assert
+ activities.MatchSnapshot();
+ }
+ }
+
+ [Fact]
+ public async Task Cause_A_Resolver_Error_That_Deletes_The_Whole_Result()
+ {
+ using (CaptureActivities(out var activities))
+ {
+ // arrange & act
+ await new ServiceCollection()
+ .AddGraphQL()
+ .AddInstrumentation(o =>
+ {
+ o.Scopes = ActivityScopes.All;
+ o.IncludeDocument = true;
+ })
+ .AddQueryType()
+ .ExecuteRequestAsync("query SayHelloOperation { causeFatalError }");
+
+ // assert
+ activities.MatchSnapshot();
+ }
+ }
+
+ [Fact]
+ public async Task PersistedOperation_LoadsFromStorage_DefaultScopes()
+ {
+ using (CaptureActivities(out var activities))
+ {
+ // arrange
+ var storage = new InMemoryOperationDocumentStorage();
+ storage.Add("sayHelloOp", "{ sayHello }");
+
+ var services = new ServiceCollection()
+ .AddGraphQL()
+ .AddInstrumentation()
+ .AddQueryType()
+ .UsePersistedOperationPipeline()
+ .ConfigureSchemaServices(
+ s => s.AddSingleton(storage))
+ .Services
+ .BuildServiceProvider();
+
+ var executor = await services.GetRequestExecutorAsync();
+
+ // act
+ await executor.ExecuteAsync(OperationRequest.FromId("sayHelloOp"));
+
+ // assert
+ activities.MatchSnapshot();
+ }
+ }
+
+ [Fact]
+ public async Task ParsingError_InvalidGraphQLDocument_ReportsErrorStatus()
+ {
+ using (CaptureActivities(out var activities))
+ {
+ // arrange & act
+ await new ServiceCollection()
+ .AddGraphQL()
+ .AddInstrumentation(o => o.Scopes = ActivityScopes.All)
+ .AddQueryType()
+ .ExecuteRequestAsync("{ sayHello");
+
+ // assert
+ activities.MatchSnapshot();
+ }
+ }
+
+ [Fact]
+ public async Task ValidationError_UnknownField_ReportsErrorStatus()
+ {
+ using (CaptureActivities(out var activities))
+ {
+ // arrange & act
+ await new ServiceCollection()
+ .AddGraphQL()
+ .AddInstrumentation(o => o.Scopes = ActivityScopes.All)
+ .AddQueryType()
+ .ExecuteRequestAsync("{ unknownField123 }");
+
+ // assert
+ activities.MatchSnapshot();
+ }
+ }
+
+ // TODO: Not sure if we want this
+ [Fact]
+ public async Task DefaultScopes_ExcludesExecuteRequestAndParseDocumentSpans()
+ {
+ using (CaptureActivities(out var activities))
+ {
+ // arrange & act
+ await new ServiceCollection()
+ .AddGraphQL()
+ .AddInstrumentation()
+ .AddQueryType()
+ .ExecuteRequestAsync("{ sayHello }");
+
+ // assert
+ activities.MatchSnapshot();
+ }
+ }
+
+ [Fact]
+ public async Task AllScopes_IncludesExecuteRequestAndParseDocumentSpans()
+ {
+ using (CaptureActivities(out var activities))
+ {
+ // arrange & act
+ await new ServiceCollection()
+ .AddGraphQL()
+ .AddInstrumentation(o => o.Scopes = ActivityScopes.All)
+ .AddQueryType()
+ .ExecuteRequestAsync("{ sayHello }");
+
+ // assert
+ activities.MatchSnapshot();
+ }
+ }
+
+ [Fact]
+ public async Task CustomScopes_OnlyValidateAndCompile_LimitsSpans()
+ {
+ using (CaptureActivities(out var activities))
+ {
+ // arrange & act
+ await new ServiceCollection()
+ .AddGraphQL()
+ .AddInstrumentation(o =>
+ o.Scopes = ActivityScopes.ValidateDocument | ActivityScopes.CompileOperation)
+ .AddQueryType()
+ .ExecuteRequestAsync("{ sayHello }");
+
+ // assert
+ activities.MatchSnapshot();
+ }
+ }
+
+ [Fact]
+ public async Task ResolverError_AtRootLevel_MarksOperationAsError()
+ {
+ using (CaptureActivities(out var activities))
+ {
+ // arrange & act
+ await new ServiceCollection()
+ .AddGraphQL()
+ .AddInstrumentation(o =>
+ {
+ o.Scopes = ActivityScopes.All;
+ o.IncludeDocument = true;
+ })
+ .AddQueryType()
+ .ExecuteRequestAsync("{ causeFatalError }");
+
+ // assert
+ activities.MatchSnapshot();
+ }
+ }
+
+ [Fact]
+ public async Task ResolverError_DeepInTree_MarksNestedFieldAsError()
+ {
+ using (CaptureActivities(out var activities))
+ {
+ // arrange & act
+ await new ServiceCollection()
+ .AddGraphQL()
+ .AddInstrumentation(o =>
+ {
+ o.Scopes = ActivityScopes.All;
+ o.IncludeDocument = true;
+ })
+ .AddQueryType()
+ .ExecuteRequestAsync(
+ """
+ {
+ deep {
+ deeper {
+ deeps {
+ deeper {
+ causeFatalError
+ }
+ }
+ }
+ }
+ }
+ """);
+
+ // assert
+ activities.MatchSnapshot();
+ }
+ }
+
+ [Fact]
+ public async Task ComplexityAnalysis_Enabled_RecordsCostInSpan()
+ {
+ using (CaptureActivities(out var activities))
+ {
+ // arrange & act
+ await new ServiceCollection()
+ .AddGraphQL()
+ .AddInstrumentation(o =>
+ o.Scopes = ActivityScopes.All)
+ .AddCostAnalyzer()
+ .AddQueryType()
+ .ExecuteRequestAsync("{ sayHello }");
+
+ // assert
+ activities.MatchSnapshot();
+ }
+ }
+
+ [Fact]
+ public async Task DataLoader_BatchExecution_RecordsBatchSpan()
+ {
+ using (CaptureActivities(out var activities))
+ {
+ // arrange & act
+ await new ServiceCollection()
+ .AddGraphQL()
+ .AddInstrumentation(o => o.Scopes = ActivityScopes.All)
+ .AddQueryType()
+ .ExecuteRequestAsync("{ dataLoader(key: \"abc\") }");
+
+ // assert
+ activities.MatchSnapshot();
+ }
+ }
+
+ [Fact]
+ public async Task DataLoader_BatchExecution_With_Keys_RecordsBatchSpan()
+ {
+ using (CaptureActivities(out var activities))
+ {
+ // arrange & act
+ await new ServiceCollection()
+ .AddGraphQL()
+ .AddInstrumentation(o =>
+ {
+ o.Scopes = ActivityScopes.All;
+ o.IncludeDataLoaderKeys = true;
+ })
+ .AddQueryType()
+ .ExecuteRequestAsync("{ dataLoader(key: \"abc\") }");
+
+ // assert
+ activities.MatchSnapshot();
+ }
+ }
+
+ [Fact]
+ public async Task VariableCoercion_WithAllScopes_RecordsCoercionSpan()
+ {
+ using (CaptureActivities(out var activities))
+ {
+ // arrange & act
+ await new ServiceCollection()
+ .AddGraphQL()
+ .AddInstrumentation(o => o.Scopes = ActivityScopes.All)
+ .AddQueryType()
+ .ExecuteRequestAsync(
+ OperationRequestBuilder.New()
+ .SetDocument("query($name: String!) { greeting(name: $name) }")
+ .SetVariableValues(
+ new Dictionary { { "name", "World" } })
+ .Build());
+
+ // assert
+ activities.MatchSnapshot();
+ }
+ }
+
+ [Fact]
+ public async Task DocumentCache_SecondExecution_RecordsCacheHitEvent()
+ {
+ // arrange
+ var services = new ServiceCollection()
+ .AddGraphQL()
+ .AddInstrumentation(o => o.Scopes = ActivityScopes.All)
+ .AddQueryType()
+ .Services
+ .BuildServiceProvider();
+
+ var executor = await services.GetRequestExecutorAsync();
+
+ var request = OperationRequestBuilder.New()
+ .SetDocument("{ sayHello }")
+ .SetDocumentHash(new OperationDocumentHash("abc", "sha256", HashFormat.Hex))
+ .Build();
+
+ // act - execute twice so second uses cached document
+ await executor.ExecuteAsync(request);
+
+ using (CaptureActivities(out var activities))
+ {
+ await executor.ExecuteAsync(request);
+
+ // assert
+ activities.MatchSnapshot();
+ }
+ }
+
+ [Fact]
+ public async Task SubscriptionEvent_Records_Subscription_Event_Span()
+ {
+ using var cts = new CancellationTokenSource(5000);
+
+ using (CaptureActivities(out var activities))
+ {
+ // arrange
+ var services = new ServiceCollection()
+ .AddGraphQL()
+ .AddInstrumentation(o => o.Scopes = ActivityScopes.All)
+ .AddQueryType()
+ .AddSubscriptionType()
+ .AddInMemorySubscriptions()
+ .Services
+ .BuildServiceProvider();
+
+ var executor = await services.GetRequestExecutorAsync();
+ var sender = services.GetRequiredService();
+
+ await using var result = await executor.ExecuteAsync(
+ "subscription OnMessageSubscription { onMessage }");
+ await using var responseStream = result.ExpectResponseStream();
+
+ var results = responseStream.ReadResultsAsync().GetAsyncEnumerator(cts.Token);
+
+ try
+ {
+ var moveNext = results.MoveNextAsync().AsTask();
+ await sender.SendAsync("OnMessage", "hello", cts.Token);
+ Assert.True(await moveNext);
+ await sender.CompleteAsync("OnMessage");
+ }
+ finally
+ {
+ await results.DisposeAsync();
+ }
+
+ // assert
+ activities.MatchSnapshot();
+ }
+ }
+
+ [Fact]
+ public async Task SubscriptionEventError_Records_Subscription_Event_Error()
+ {
+ using var cts = new CancellationTokenSource(5000);
+
+ using (CaptureActivities(out var activities))
+ {
+ // arrange
+ var services = new ServiceCollection()
+ .AddGraphQL()
+ .AddInstrumentation(o => o.Scopes = ActivityScopes.All)
+ .AddQueryType()
+ .AddSubscriptionType()
+ .AddInMemorySubscriptions()
+ .Services
+ .BuildServiceProvider();
+
+ var executor = await services.GetRequestExecutorAsync();
+ var sender = services.GetRequiredService();
+
+ await using var result = await executor.ExecuteAsync(
+ "subscription OnFailingMessageSubscription { onFailingMessage }");
+ await using var responseStream = result.ExpectResponseStream();
+
+ var results = responseStream.ReadResultsAsync().GetAsyncEnumerator(cts.Token);
+
+ try
+ {
+ var moveNext = results.MoveNextAsync().AsTask();
+ await sender.SendAsync("OnFailingMessage", "hello", cts.Token);
+ Assert.True(await moveNext);
+ await sender.CompleteAsync("OnFailingMessage");
+ }
+ finally
+ {
+ await results.DisposeAsync();
+ }
+
+ // assert
+ activities.MatchSnapshot();
+ }
+ }
+
+ public class SimpleQuery
+ {
+ public string SayHello() => "hello";
+
+ public string Greeting(string name) => $"Hello, {name}!";
+
+ public string CauseFatalError() => throw new GraphQLException("fail");
+
+ public Deep Deep() => new();
+
+ public Task DataLoader(CustomDataLoader dataLoader, string key)
+ => dataLoader.LoadAsync(key);
+ }
+
+ public class Deep
+ {
+ public Deeper Deeper() => new();
+
+ public string CauseFatalError() => throw new GraphQLException("fail");
+ }
+
+ public class Deeper
+ {
+ public Deep[] Deeps() => [new Deep()];
+ }
+
+ public class SimpleSubscription
+ {
+ [Subscribe]
+ public string OnMessage([EventMessage] string message) => message;
+
+ [Subscribe]
+ public string OnFailingMessage([EventMessage] string message)
+ => throw new InvalidOperationException("Subscription event failed.");
+ }
+
+ private sealed class InMemoryOperationDocumentStorage : IOperationDocumentStorage
+ {
+ private readonly Dictionary _cache = [];
+
+ public void Add(string id, string document)
+ => _cache[id] = Utf8GraphQLParser.Parse(document);
+
+ public ValueTask TryReadAsync(
+ OperationDocumentId documentId,
+ CancellationToken cancellationToken = default)
+ {
+ if (_cache.TryGetValue(documentId.Value, out var document))
+ {
+ return new ValueTask(new OperationDocument(document));
+ }
+
+ return new ValueTask(default(IOperationDocument));
+ }
+
+ public ValueTask SaveAsync(
+ OperationDocumentId documentId,
+ IOperationDocument document,
+ CancellationToken cancellationToken = default)
+ {
+ _cache[documentId.Value] = Utf8GraphQLParser.Parse(document.AsSpan());
+ return default;
+ }
+ }
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/ServerInstrumentationTests.cs b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/ActivityServerDiagnosticListenerTests.cs
similarity index 60%
rename from src/HotChocolate/Diagnostics/test/Diagnostics.Tests/ServerInstrumentationTests.cs
rename to src/HotChocolate/Diagnostics/test/Diagnostics.Tests/ActivityServerDiagnosticListenerTests.cs
index bc07c2f38fb..f4da56a8650 100644
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/ServerInstrumentationTests.cs
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/ActivityServerDiagnosticListenerTests.cs
@@ -1,17 +1,16 @@
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using HotChocolate.AspNetCore.Tests.Utilities;
+using HotChocolate.Transport.Http;
using static HotChocolate.Diagnostics.ActivityTestHelper;
+using OperationRequest = HotChocolate.Transport.OperationRequest;
namespace HotChocolate.Diagnostics;
[Collection("Instrumentation")]
-public class ServerInstrumentationTests : ServerTestBase
+public class ActivityServerDiagnosticListenerTests(TestServerFactory serverFactory) : ServerTestBase(serverFactory)
{
- public ServerInstrumentationTests(TestServerFactory serverFactory)
- : base(serverFactory)
- {
- }
+ private static readonly Uri s_url = new("http://localhost:5000/graphql");
[Fact]
public async Task Http_Post_SingleRequest_GetHeroName_Default()
@@ -20,17 +19,18 @@ public async Task Http_Post_SingleRequest_GetHeroName_Default()
{
// arrange
using var server = CreateInstrumentedServer();
+ using var client = GraphQLHttpClient.Create(server.CreateClient());
// act
- await server.PostAsync(new ClientQueryRequest
- {
- Query = @"
+ var request = new OperationRequest(
+ @"
{
hero {
name
}
- }"
- });
+ }");
+ using var result = await client.PostAsync(request, s_url);
+ await result.ReadAsResultAsync();
// assert
activities.MatchSnapshot();
@@ -45,17 +45,18 @@ public async Task Http_Post_SingleRequest_GetHeroName()
// arrange
using var server = CreateInstrumentedServer(
o => o.Scopes = ActivityScopes.All);
+ using var client = GraphQLHttpClient.Create(server.CreateClient());
// act
- await server.PostAsync(new ClientQueryRequest
- {
- Query = @"
+ var request = new OperationRequest(
+ @"
{
hero {
name
}
- }"
- });
+ }");
+ using var result = await client.PostAsync(request, s_url);
+ await result.ReadAsResultAsync();
// assert
activities.MatchSnapshot();
@@ -70,17 +71,18 @@ public async Task Http_Get_SingleRequest_GetHeroName()
// arrange
using var server = CreateInstrumentedServer(
o => o.Scopes = ActivityScopes.All);
+ using var client = GraphQLHttpClient.Create(server.CreateClient());
// act
- await server.GetAsync(new ClientQueryRequest
- {
- Query = @"
+ var request = new OperationRequest(
+ @"
{
hero {
name
}
- }"
- });
+ }");
+ using var result = await client.GetAsync(request, s_url);
+ await result.ReadAsResultAsync();
// assert
activities.MatchSnapshot();
@@ -88,25 +90,26 @@ await server.GetAsync(new ClientQueryRequest
}
[Fact]
- public async Task Http_Post_variables_are_not_automatically_added_to_activities()
+ public async Task Http_Post_Variables_Are_Not_Automatically_Added_To_Activities()
{
using (CaptureActivities(out var activities))
{
// arrange
using var server = CreateInstrumentedServer(
o => o.Scopes = ActivityScopes.All);
+ using var client = GraphQLHttpClient.Create(server.CreateClient());
// act
- await server.PostAsync(new ClientQueryRequest
- {
- Query = @"
+ var request = new OperationRequest(
+ query: @"
query ($episode: Episode!) {
hero(episode: $episode) {
name
}
}",
- Variables = new Dictionary { { "episode", "NEW_HOPE" } }
- });
+ variables: new Dictionary { { "episode", "NEW_HOPE" } });
+ using var result = await client.PostAsync(request, s_url);
+ await result.ReadAsResultAsync();
// assert
activities.MatchSnapshot();
@@ -114,7 +117,7 @@ await server.PostAsync(new ClientQueryRequest
}
[Fact]
- public async Task Http_Post_add_variables_to_http_activity()
+ public async Task Http_Post_Add_Variables_To_Http_Activity()
{
using (CaptureActivities(out var activities))
{
@@ -125,48 +128,19 @@ public async Task Http_Post_add_variables_to_http_activity()
o.Scopes = ActivityScopes.All;
o.RequestDetails = RequestDetails.Default | RequestDetails.Variables;
});
+ using var client = GraphQLHttpClient.Create(server.CreateClient());
// act
- await server.PostAsync(new ClientQueryRequest
- {
- Query = @"
- query ($episode: Episode!) {
- hero(episode: $episode) {
- name
- }
- }",
- Variables = new Dictionary { { "episode", "NEW_HOPE" } }
- });
-
- // assert
- activities.MatchSnapshot();
- }
- }
-
- [Fact]
- public async Task Http_Post_add_query_to_http_activity()
- {
- using (CaptureActivities(out var activities))
- {
- // arrange
- using var server = CreateInstrumentedServer(
- o =>
- {
- o.Scopes = ActivityScopes.All;
- o.RequestDetails = RequestDetails.Default | RequestDetails.Operation;
- });
-
- // act
- await server.PostAsync(new ClientQueryRequest
- {
- Query = @"
+ var request = new OperationRequest(
+ query: @"
query ($episode: Episode!) {
hero(episode: $episode) {
name
}
}",
- Variables = new Dictionary { { "episode", "NEW_HOPE" } }
- });
+ variables: new Dictionary { { "episode", "NEW_HOPE" } });
+ using var result = await client.PostAsync(request, s_url);
+ await result.ReadAsResultAsync();
// assert
activities.MatchSnapshot();
@@ -174,26 +148,27 @@ await server.PostAsync(new ClientQueryRequest
}
[Fact]
- public async Task Http_Post_with_extensions_map()
+ public async Task Http_Post_With_Extensions_Map()
{
using (CaptureActivities(out var activities))
{
// arrange
using var server = CreateInstrumentedServer(
o => o.Scopes = ActivityScopes.All);
+ using var client = GraphQLHttpClient.Create(server.CreateClient());
// act
- await server.PostAsync(new ClientQueryRequest
- {
- Query = @"
+ var request = new OperationRequest(
+ query: @"
query ($episode: Episode!) {
hero(episode: $episode) {
name
}
}",
- Variables = new Dictionary { { "episode", "NEW_HOPE" } },
- Extensions = new Dictionary { { "test", "abc" } }
- });
+ variables: new Dictionary { { "episode", "NEW_HOPE" } },
+ extensions: new Dictionary { { "test", "abc" } });
+ using var result = await client.PostAsync(request, s_url);
+ await result.ReadAsResultAsync();
// assert
activities.MatchSnapshot();
@@ -201,7 +176,7 @@ await server.PostAsync(new ClientQueryRequest
}
[Fact]
- public async Task Http_Get_SDL_download()
+ public async Task Http_Get_SDL_Download()
{
using (CaptureActivities(out var activities))
{
@@ -222,7 +197,7 @@ public async Task Http_Get_SDL_download()
}
[Fact]
- public async Task Http_Post_capture_deferred_response()
+ public async Task Http_Post_Capture_Deferred_Response()
{
using (CaptureActivities(out var activities))
{
@@ -251,7 +226,7 @@ ... on Droid @defer(label: "my_id") {
}
[Fact]
- public async Task Http_Post_ensure_list_path_is_correctly_built()
+ public async Task Http_Post_Ensure_List_Path_Is_Correctly_Built()
{
using (CaptureActivities(out var activities))
{
@@ -286,7 +261,7 @@ await server.PostRawAsync(new ClientQueryRequest
}
[Fact]
- public async Task Http_Post_parser_error()
+ public async Task Http_Post_Parser_Error()
{
using (CaptureActivities(out var activities))
{
@@ -322,7 +297,7 @@ await server.PostRawAsync(new ClientQueryRequest
}
[Fact]
- public async Task Parsing_error_when_rename_root_is_activated()
+ public async Task RequestDetails_None_ExcludesAllDetails()
{
using (CaptureActivities(out var activities))
{
@@ -331,18 +306,54 @@ public async Task Parsing_error_when_rename_root_is_activated()
o =>
{
o.Scopes = ActivityScopes.All;
- o.RenameRootActivity = true;
+ o.RequestDetails = RequestDetails.None;
});
+ using var client = GraphQLHttpClient.Create(server.CreateClient());
// act
- await server.PostRawAsync(new ClientQueryRequest
- {
- // lang=text
- Query = @"
+ var request = new OperationRequest(
+ query: @"
+ query GetHero($episode: Episode!) {
+ hero(episode: $episode) {
+ name
+ }
+ }",
+ variables: new Dictionary { { "episode", "NEW_HOPE" } },
+ extensions: new Dictionary { { "test", "abc" } });
+ using var result = await client.PostAsync(request, s_url);
+ await result.ReadAsResultAsync();
+
+ // assert
+ activities.MatchSnapshot();
+ }
+ }
+
+ [Fact]
+ public async Task RequestDetails_All_IncludesAllDetails()
+ {
+ using (CaptureActivities(out var activities))
+ {
+ // arrange
+ using var server = CreateInstrumentedServer(
+ o =>
{
- 1
- }"
- });
+ o.Scopes = ActivityScopes.All;
+ o.RequestDetails = RequestDetails.All;
+ });
+ using var client = GraphQLHttpClient.Create(server.CreateClient());
+
+ // act
+ var request = new OperationRequest(
+ query: @"
+ query GetHero($episode: Episode!) {
+ hero(episode: $episode) {
+ name
+ }
+ }",
+ variables: new Dictionary { { "episode", "NEW_HOPE" } },
+ extensions: new Dictionary { { "test", "abc" } });
+ using var result = await client.PostAsync(request, s_url);
+ await result.ReadAsResultAsync();
// assert
activities.MatchSnapshot();
@@ -350,7 +361,7 @@ await server.PostRawAsync(new ClientQueryRequest
}
[Fact]
- public async Task Validation_error_when_rename_root_is_activated()
+ public async Task RequestDetails_DocumentOnly_IncludesDocumentTag()
{
using (CaptureActivities(out var activities))
{
@@ -359,17 +370,47 @@ public async Task Validation_error_when_rename_root_is_activated()
o =>
{
o.Scopes = ActivityScopes.All;
- o.RenameRootActivity = true;
+ o.RequestDetails = RequestDetails.Document;
});
+ using var client = GraphQLHttpClient.Create(server.CreateClient());
// act
- await server.PostRawAsync(new ClientQueryRequest
- {
- Query = @"
+ var request = new OperationRequest(
+ @"
{
- abc
- }"
- });
+ hero {
+ name
+ }
+ }");
+ using var result = await client.PostAsync(request, s_url);
+ await result.ReadAsResultAsync();
+
+ // assert
+ activities.MatchSnapshot();
+ }
+ }
+
+ [Fact]
+ public async Task RequestDetails_Default_IncludesIdHashOperationNameExtensions()
+ {
+ using (CaptureActivities(out var activities))
+ {
+ // arrange
+ using var server = CreateInstrumentedServer(
+ o => o.Scopes = ActivityScopes.All);
+ using var client = GraphQLHttpClient.Create(server.CreateClient());
+
+ // act
+ var request = new OperationRequest(
+ query: @"
+ query GetHero {
+ hero {
+ name
+ }
+ }",
+ extensions: new Dictionary { { "test", "abc" } });
+ using var result = await client.PostAsync(request, s_url);
+ await result.ReadAsResultAsync();
// assert
activities.MatchSnapshot();
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/ActivityTestHelper.cs b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/ActivityTestHelper.cs
index 783ca73a4fc..97bd9804ec2 100644
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/ActivityTestHelper.cs
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/ActivityTestHelper.cs
@@ -1,16 +1,23 @@
using System.Diagnostics;
+using System.Text.RegularExpressions;
using HotChocolate.Utilities;
namespace HotChocolate.Diagnostics;
-public static class ActivityTestHelper
+public static partial class ActivityTestHelper
{
+ [GeneratedRegex(@" in (?.+?):line (?\d+)", RegexOptions.CultureInvariant)]
+ private static partial Regex StackTracePathRegex();
+ [GeneratedRegex(@"lambda_method\d+", RegexOptions.CultureInvariant)]
+ private static partial Regex LambdaMethodRegex();
+
public static IDisposable CaptureActivities(out object activities)
{
var sync = new object();
var listener = new ActivityListener();
var root = new OrderedDictionary();
var lookup = new Dictionary>();
+ var spanLookup = new Dictionary>();
Activity rootActivity = null!;
listener.ShouldListenTo = source => source.Name.EqualsOrdinal("HotChocolate.Diagnostics");
@@ -31,6 +38,17 @@ public static IDisposable CaptureActivities(out object activities)
{
RegisterActivity(a, parentData);
lookup[a] = (OrderedDictionary)a.GetCustomProperty("test.data")!;
+ spanLookup[a.SpanId] = (OrderedDictionary)a.GetCustomProperty("test.data")!;
+ return;
+ }
+
+ if (a.Parent is null
+ && a.ParentSpanId != default
+ && spanLookup.TryGetValue(a.ParentSpanId, out parentData))
+ {
+ RegisterActivity(a, parentData);
+ lookup[a] = (OrderedDictionary)a.GetCustomProperty("test.data")!;
+ spanLookup[a.SpanId] = (OrderedDictionary)a.GetCustomProperty("test.data")!;
}
}
};
@@ -42,6 +60,7 @@ public static IDisposable CaptureActivities(out object activities)
rootActivity = HotChocolateActivitySource.Source.StartActivity()!;
rootActivity.SetCustomProperty("test.data", root);
lookup[rootActivity] = root;
+ spanLookup[rootActivity.SpanId] = root;
activities = root;
return new Session(rootActivity, listener);
@@ -75,8 +94,44 @@ private static void SerializeActivity(Activity activity)
data["OperationName"] = activity.OperationName;
data["DisplayName"] = activity.DisplayName;
data["Status"] = activity.Status;
- data["tags"] = activity.Tags;
- data["event"] = activity.Events.Select(t => new { t.Name, t.Tags });
+ data["tags"] = activity.TagObjects;
+ data["event"] = activity.Events.Select(t => new
+ {
+ t.Name,
+ Tags = ScrubEventTags(t.Tags)
+ });
+ }
+
+ private static IEnumerable> ScrubEventTags(
+ IEnumerable>? tags)
+ {
+ if (tags is null)
+ {
+ yield break;
+ }
+
+ foreach (var tag in tags)
+ {
+ if (tag.Value is string stackTrace
+ && (tag.Key.Equals("exception.stacktrace", StringComparison.Ordinal)
+ || tag.Key.EndsWith(".stacktrace", StringComparison.Ordinal)))
+ {
+ var scrubbedStackTrace = StackTracePathRegex().Replace(stackTrace, match =>
+ {
+ var fileName = System.IO.Path.GetFileName(match.Groups["path"].Value);
+ var lineNumber = match.Groups["line"].Value;
+ return $" in {fileName}:line {lineNumber}";
+ });
+
+ yield return new KeyValuePair(
+ tag.Key,
+ LambdaMethodRegex().Replace(scrubbedStackTrace, "lambda_method"));
+ }
+ else
+ {
+ yield return tag;
+ }
+ }
}
private sealed class Session : IDisposable
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/CustomDataLoader.cs b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/CustomDataLoader.cs
index 06d8ebdf422..255914f2b0e 100644
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/CustomDataLoader.cs
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/CustomDataLoader.cs
@@ -2,7 +2,7 @@
namespace HotChocolate.Diagnostics;
-public partial class QueryInstrumentationTests
+public partial class ActivityExecutionDiagnosticListenerTests
{
public class CustomDataLoader(IBatchScheduler batchScheduler, DataLoaderOptions options)
: BatchDataLoader(batchScheduler, options)
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/HotChocolate.Diagnostics.Tests.csproj b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/HotChocolate.Diagnostics.Tests.csproj
index f3d92a3b4f1..2f7b559fa8a 100644
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/HotChocolate.Diagnostics.Tests.csproj
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/HotChocolate.Diagnostics.Tests.csproj
@@ -8,6 +8,7 @@
+
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/QueryInstrumentationTests.cs b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/QueryInstrumentationTests.cs
deleted file mode 100644
index f2c4475cb3d..00000000000
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/QueryInstrumentationTests.cs
+++ /dev/null
@@ -1,364 +0,0 @@
-using System.Diagnostics;
-using Microsoft.Extensions.DependencyInjection;
-using HotChocolate.Execution;
-using static HotChocolate.Diagnostics.ActivityTestHelper;
-
-namespace HotChocolate.Diagnostics;
-
-[Collection("Instrumentation")]
-public partial class QueryInstrumentationTests
-{
- [Fact]
- public async Task Track_events_of_a_simple_query_default()
- {
- using (CaptureActivities(out var activities))
- {
- // arrange & act
- await new ServiceCollection()
- .AddGraphQL()
- .AddInstrumentation()
- .AddQueryType()
- .ExecuteRequestAsync("{ sayHello }");
-
- // assert
- activities.MatchSnapshot();
- }
- }
-
- [Fact(Skip = "This test is flaky with the new DL batching.")]
- public async Task Track_data_loader_events()
- {
- using (CaptureActivities(out var activities))
- {
- // arrange & act
- await new ServiceCollection()
- .AddGraphQL()
- .AddInstrumentation()
- .AddQueryType()
- .ExecuteRequestAsync("{ dataLoader(key: \"abc\") }");
-
- // assert
- activities.MatchSnapshot();
- }
- }
-
- [Fact(Skip = "This test is flaky with the new DL batching.")]
- public async Task Track_data_loader_events_with_keys()
- {
- using (CaptureActivities(out var activities))
- {
- // arrange & act
- await new ServiceCollection()
- .AddGraphQL()
- .AddInstrumentation(o => o.IncludeDataLoaderKeys = true)
- .AddQueryType()
- .ExecuteRequestAsync("{ dataLoader(key: \"abc\") }");
-
- // assert
- activities.MatchSnapshot();
- }
- }
-
- [Fact]
- public async Task Track_events_of_a_simple_query_default_rename_root()
- {
- using (CaptureActivities(out _))
- {
- // arrange & act
- await new ServiceCollection()
- .AddGraphQL()
- .AddInstrumentation(o =>
- {
- o.RenameRootActivity = true;
- o.Scopes = ActivityScopes.All;
- })
- .AddQueryType()
- .ExecuteRequestAsync("{ sayHello }");
-
- // assert
- Assert.Equal("CaptureActivities: query { sayHello }", Activity.Current!.DisplayName);
- }
- }
-
- [Fact]
- public async Task Parsing_error_when_rename_root_is_activated()
- {
- using (CaptureActivities(out _))
- {
- // arrange & act
- await new ServiceCollection()
- .AddGraphQL()
- .AddInstrumentation(o =>
- {
- o.RenameRootActivity = true;
- o.Scopes = ActivityScopes.All;
- })
- .AddQueryType()
- .ExecuteRequestAsync("{ sayHello");
-
- // assert
- Assert.Equal("CaptureActivities: Begin Parse Document", Activity.Current!.DisplayName);
- }
- }
-
- [Fact]
- public async Task Validation_error_when_rename_root_is_activated()
- {
- using (CaptureActivities(out _))
- {
- // arrange & act
- await new ServiceCollection()
- .AddGraphQL()
- .AddInstrumentation(o =>
- {
- o.RenameRootActivity = true;
- o.Scopes = ActivityScopes.All;
- })
- .AddQueryType()
- .ExecuteRequestAsync("{ abc123 }");
-
- // assert
- Assert.Equal("CaptureActivities: Begin Validate Document",
- Activity.Current!.DisplayName);
- }
- }
-
- [Fact]
- public async Task Create_operation_display_name_with_1_field()
- {
- using (CaptureActivities(out var activities))
- {
- // arrange & act
- await new ServiceCollection()
- .AddGraphQL()
- .AddInstrumentation(o =>
- {
- o.RenameRootActivity = true;
- o.Scopes = ActivityScopes.All;
- })
- .AddQueryType()
- .ExecuteRequestAsync("{ a: sayHello }");
-
- // assert
- activities.MatchSnapshot();
- }
- }
-
- [Fact]
- public async Task Create_operation_display_name_with_1_field_and_op()
- {
- using (CaptureActivities(out var activities))
- {
- // arrange & act
- await new ServiceCollection()
- .AddGraphQL()
- .AddInstrumentation(o =>
- {
- o.RenameRootActivity = true;
- o.Scopes = ActivityScopes.All;
- })
- .AddQueryType()
- .ExecuteRequestAsync("query GetA { a: sayHello }");
-
- // assert
- activities.MatchSnapshot();
- }
- }
-
- [Fact]
- public async Task Create_operation_display_name_with_3_field()
- {
- using (CaptureActivities(out var activities))
- {
- // arrange & act
- await new ServiceCollection()
- .AddGraphQL()
- .AddInstrumentation(o =>
- {
- o.RenameRootActivity = true;
- o.Scopes = ActivityScopes.All;
- })
- .AddQueryType()
- .ExecuteRequestAsync("{ a: sayHello b: sayHello c: sayHello }");
-
- // assert
- activities.MatchSnapshot();
- }
- }
-
- [Fact]
- public async Task Create_operation_display_name_with_4_field()
- {
- using (CaptureActivities(out var activities))
- {
- // arrange & act
- await new ServiceCollection()
- .AddGraphQL()
- .AddInstrumentation(o =>
- {
- o.RenameRootActivity = true;
- o.Scopes = ActivityScopes.All;
- })
- .AddQueryType()
- .ExecuteRequestAsync("{ a: sayHello b: sayHello c: sayHello d: sayHello }");
-
- // assert
- activities.MatchSnapshot();
- }
- }
-
- [Fact]
- public async Task Track_events_of_a_simple_query_detailed()
- {
- using (CaptureActivities(out var activities))
- {
- // arrange & act
- await new ServiceCollection()
- .AddGraphQL()
- .AddInstrumentation(o => o.Scopes = ActivityScopes.All)
- .AddQueryType()
- .ExecuteRequestAsync("{ sayHello }");
-
- // assert
- activities.MatchSnapshot();
- }
- }
-
- [Fact]
- public async Task Ensure_operation_name_is_used_as_request_name()
- {
- using (CaptureActivities(out var activities))
- {
- // arrange & act
- await new ServiceCollection()
- .AddGraphQL()
- .AddInstrumentation(o => o.Scopes = ActivityScopes.All)
- .AddQueryType()
- .ExecuteRequestAsync("query SayHelloOperation { sayHello }");
-
- // assert
- activities.MatchSnapshot();
- }
- }
-
- [Fact]
- public async Task Allow_document_to_be_captured()
- {
- using (CaptureActivities(out var activities))
- {
- // arrange & act
- await new ServiceCollection()
- .AddGraphQL()
- .AddInstrumentation(o =>
- {
- o.Scopes = ActivityScopes.All;
- o.IncludeDocument = true;
- })
- .AddQueryType()
- .ExecuteRequestAsync("query SayHelloOperation { sayHello }");
-
- // assert
- activities.MatchSnapshot();
- }
- }
-
- [Fact]
- public async Task Ensure_that_the_validation_activity_has_an_error_status()
- {
- using (CaptureActivities(out var activities))
- {
- // arrange & act
- await new ServiceCollection()
- .AddGraphQL()
- .AddInstrumentation(o =>
- {
- o.Scopes = ActivityScopes.All;
- o.IncludeDocument = true;
- })
- .AddQueryType()
- .ExecuteRequestAsync("query SayHelloOperation { sayHello_ }");
-
- // assert
- activities.MatchSnapshot();
- }
- }
-
- [Fact]
- public async Task Cause_a_resolver_error_that_deletes_the_whole_result()
- {
- using (CaptureActivities(out var activities))
- {
- // arrange & act
- await new ServiceCollection()
- .AddGraphQL()
- .AddInstrumentation(o =>
- {
- o.Scopes = ActivityScopes.All;
- o.IncludeDocument = true;
- })
- .AddQueryType()
- .ExecuteRequestAsync("query SayHelloOperation { causeFatalError }");
-
- // assert
- activities.MatchSnapshot();
- }
- }
-
- [Fact]
- public async Task Cause_a_resolver_error_that_deletes_the_whole_result_deep()
- {
- using (CaptureActivities(out var activities))
- {
- // arrange & act
- await new ServiceCollection()
- .AddGraphQL()
- .AddInstrumentation(o =>
- {
- o.Scopes = ActivityScopes.All;
- o.IncludeDocument = true;
- })
- .AddQueryType()
- .ExecuteRequestAsync(
- """
- query SayHelloOperation {
- deep {
- deeper {
- deeps {
- deeper {
- causeFatalError
- }
- }
- }
- }
- }
- """);
-
- // assert
- activities.MatchSnapshot();
- }
- }
-
- public class SimpleQuery
- {
- public string SayHello() => "hello";
-
- public string CauseFatalError() => throw new GraphQLException("fail");
-
- public Deep Deep() => new();
-
- public Task DataLoader(CustomDataLoader dataLoader, string key)
- => dataLoader.LoadAsync(key);
- }
-
- public class Deep
- {
- public Deeper Deeper() => new();
-
- public string CauseFatalError() => throw new GraphQLException("fail");
- }
-
- public class Deeper
- {
- public Deep[] Deeps() => [new Deep()];
- }
-}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityDataLoaderDiagnosticListenerTests.Run_Batch_Dispatch_Coordinator_Emits_Activity.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityDataLoaderDiagnosticListenerTests.Run_Batch_Dispatch_Coordinator_Emits_Activity.snap
new file mode 100644
index 00000000000..a7bc715d1b7
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityDataLoaderDiagnosticListenerTests.Run_Batch_Dispatch_Coordinator_Emits_Activity.snap
@@ -0,0 +1,16 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL DataLoader Dispatch",
+ "DisplayName": "GraphQL DataLoader Dispatch",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "dataloader_dispatch"
+ }
+ ],
+ "event": []
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityDataLoaderDiagnosticListenerTests.Run_Batch_Dispatch_Coordinator_Tracks_Dispatch_Events.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityDataLoaderDiagnosticListenerTests.Run_Batch_Dispatch_Coordinator_Tracks_Dispatch_Events.snap
new file mode 100644
index 00000000000..f835ed1a85a
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityDataLoaderDiagnosticListenerTests.Run_Batch_Dispatch_Coordinator_Tracks_Dispatch_Events.snap
@@ -0,0 +1,35 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL DataLoader Dispatch",
+ "DisplayName": "GraphQL DataLoader Dispatch",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "dataloader_dispatch"
+ }
+ ],
+ "event": [
+ {
+ "Name": "BatchEvaluated",
+ "Tags": [
+ {
+ "Key": "openBatches",
+ "Value": 2
+ }
+ ]
+ },
+ {
+ "Name": "BatchDispatched",
+ "Tags": [
+ {
+ "Key": "dispatchedBatches",
+ "Value": 1
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.AllScopes_IncludesExecuteRequestAndParseDocumentSpans.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.AllScopes_IncludesExecuteRequestAndParseDocumentSpans.snap
new file mode 100644
index 00000000000..49f7e009662
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.AllScopes_IncludesExecuteRequestAndParseDocumentSpans.snap
@@ -0,0 +1,133 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Parsing",
+ "DisplayName": "GraphQL Document Parsing",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "SimpleQuery.sayHello",
+ "DisplayName": "SimpleQuery.sayHello",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
+ },
+ {
+ "Key": "graphql.selection.name",
+ "Value": "sayHello"
+ },
+ {
+ "Key": "graphql.selection.path",
+ "Value": "sayHello"
+ },
+ {
+ "Key": "graphql.selection.field.name",
+ "Value": "sayHello"
+ },
+ {
+ "Key": "graphql.selection.field.coordinate",
+ "Value": "SimpleQuery.sayHello"
+ },
+ {
+ "Key": "graphql.selection.field.parent_type",
+ "Value": "SimpleQuery"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.Allow_Document_To_Be_Captured.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.Allow_Document_To_Be_Captured.snap
new file mode 100644
index 00000000000..1a00249e432
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.Allow_Document_To_Be_Captured.snap
@@ -0,0 +1,149 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "SayHelloOperation"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:6af18618ae20c266f6ffc352b78cb69b"
+ },
+ {
+ "Key": "graphql.document.body",
+ "Value": "query SayHelloOperation {\n sayHello\n}"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Parsing",
+ "DisplayName": "GraphQL Document Parsing",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:6af18618ae20c266f6ffc352b78cb69b"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:6af18618ae20c266f6ffc352b78cb69b"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:6af18618ae20c266f6ffc352b78cb69b"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "SayHelloOperation"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "SayHelloOperation"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:6af18618ae20c266f6ffc352b78cb69b"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "SimpleQuery.sayHello",
+ "DisplayName": "SimpleQuery.sayHello",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
+ },
+ {
+ "Key": "graphql.selection.name",
+ "Value": "sayHello"
+ },
+ {
+ "Key": "graphql.selection.path",
+ "Value": "sayHello"
+ },
+ {
+ "Key": "graphql.selection.field.name",
+ "Value": "sayHello"
+ },
+ {
+ "Key": "graphql.selection.field.coordinate",
+ "Value": "SimpleQuery.sayHello"
+ },
+ {
+ "Key": "graphql.selection.field.parent_type",
+ "Value": "SimpleQuery"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.Cause_A_Resolver_Error_That_Deletes_The_Whole_Result.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.Cause_A_Resolver_Error_That_Deletes_The_Whole_Result.snap
new file mode 100644
index 00000000000..6b24042cac8
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.Cause_A_Resolver_Error_That_Deletes_The_Whole_Result.snap
@@ -0,0 +1,163 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "SayHelloOperation"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:851fb754d9ba6b5cc5a55ebcbea2621d"
+ },
+ {
+ "Key": "graphql.document.body",
+ "Value": "query SayHelloOperation {\n causeFatalError\n}"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Parsing",
+ "DisplayName": "GraphQL Document Parsing",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:851fb754d9ba6b5cc5a55ebcbea2621d"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:851fb754d9ba6b5cc5a55ebcbea2621d"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:851fb754d9ba6b5cc5a55ebcbea2621d"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "SayHelloOperation"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "SayHelloOperation"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:851fb754d9ba6b5cc5a55ebcbea2621d"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "SimpleQuery.causeFatalError",
+ "DisplayName": "SimpleQuery.causeFatalError",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
+ },
+ {
+ "Key": "graphql.selection.name",
+ "Value": "causeFatalError"
+ },
+ {
+ "Key": "graphql.selection.path",
+ "Value": "causeFatalError"
+ },
+ {
+ "Key": "graphql.selection.field.name",
+ "Value": "causeFatalError"
+ },
+ {
+ "Key": "graphql.selection.field.coordinate",
+ "Value": "SimpleQuery.causeFatalError"
+ },
+ {
+ "Key": "graphql.selection.field.parent_type",
+ "Value": "SimpleQuery"
+ }
+ ],
+ "event": [
+ {
+ "Name": "exception",
+ "Tags": [
+ {
+ "Key": "graphql.error.message",
+ "Value": "fail"
+ },
+ {
+ "Key": "graphql.error.path",
+ "Value": "causeFatalError"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.ComplexityAnalysis_Enabled_RecordsCostInSpan.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.ComplexityAnalysis_Enabled_RecordsCostInSpan.snap
new file mode 100644
index 00000000000..18b75c1afa7
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.ComplexityAnalysis_Enabled_RecordsCostInSpan.snap
@@ -0,0 +1,153 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Parsing",
+ "DisplayName": "GraphQL Document Parsing",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Complexity Analysis",
+ "DisplayName": "GraphQL Complexity Analysis",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.fieldCost",
+ "Value": 0.0
+ },
+ {
+ "Key": "graphql.operation.typeCost",
+ "Value": 1.0
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "SimpleQuery.sayHello",
+ "DisplayName": "SimpleQuery.sayHello",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
+ },
+ {
+ "Key": "graphql.selection.name",
+ "Value": "sayHello"
+ },
+ {
+ "Key": "graphql.selection.path",
+ "Value": "sayHello"
+ },
+ {
+ "Key": "graphql.selection.field.name",
+ "Value": "sayHello"
+ },
+ {
+ "Key": "graphql.selection.field.coordinate",
+ "Value": "SimpleQuery.sayHello"
+ },
+ {
+ "Key": "graphql.selection.field.parent_type",
+ "Value": "SimpleQuery"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.CustomScopes_OnlyValidateAndCompile_LimitsSpans.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.CustomScopes_OnlyValidateAndCompile_LimitsSpans.snap
new file mode 100644
index 00000000000..6e5564554ca
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.CustomScopes_OnlyValidateAndCompile_LimitsSpans.snap
@@ -0,0 +1,40 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.DataLoader_BatchExecution_RecordsBatchSpan.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.DataLoader_BatchExecution_RecordsBatchSpan.snap
new file mode 100644
index 00000000000..3a1922dc668
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.DataLoader_BatchExecution_RecordsBatchSpan.snap
@@ -0,0 +1,186 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:9b20745108c8de5afccc35cd56ead9fc"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Parsing",
+ "DisplayName": "GraphQL Document Parsing",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:9b20745108c8de5afccc35cd56ead9fc"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:9b20745108c8de5afccc35cd56ead9fc"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:9b20745108c8de5afccc35cd56ead9fc"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:9b20745108c8de5afccc35cd56ead9fc"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "SimpleQuery.dataLoader",
+ "DisplayName": "SimpleQuery.dataLoader",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
+ },
+ {
+ "Key": "graphql.selection.name",
+ "Value": "dataLoader"
+ },
+ {
+ "Key": "graphql.selection.path",
+ "Value": "dataLoader"
+ },
+ {
+ "Key": "graphql.selection.field.name",
+ "Value": "dataLoader"
+ },
+ {
+ "Key": "graphql.selection.field.coordinate",
+ "Value": "SimpleQuery.dataLoader"
+ },
+ {
+ "Key": "graphql.selection.field.parent_type",
+ "Value": "SimpleQuery"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL DataLoader Dispatch",
+ "DisplayName": "GraphQL DataLoader Dispatch",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "dataloader_dispatch"
+ }
+ ],
+ "event": [
+ {
+ "Name": "BatchEvaluated",
+ "Tags": [
+ {
+ "Key": "openBatches",
+ "Value": 1
+ }
+ ]
+ },
+ {
+ "Name": "BatchDispatched",
+ "Tags": [
+ {
+ "Key": "dispatchedBatches",
+ "Value": 1
+ }
+ ]
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL DataLoader Batch CustomDataLoader",
+ "DisplayName": "GraphQL DataLoader Batch CustomDataLoader",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "dataloader_batch"
+ },
+ {
+ "Key": "graphql.dataloader.name",
+ "Value": "CustomDataLoader"
+ },
+ {
+ "Key": "graphql.dataloader.batch.size",
+ "Value": 1
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.DataLoader_BatchExecution_With_Keys_RecordsBatchSpan.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.DataLoader_BatchExecution_With_Keys_RecordsBatchSpan.snap
new file mode 100644
index 00000000000..f36210d5447
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.DataLoader_BatchExecution_With_Keys_RecordsBatchSpan.snap
@@ -0,0 +1,192 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:9b20745108c8de5afccc35cd56ead9fc"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Parsing",
+ "DisplayName": "GraphQL Document Parsing",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:9b20745108c8de5afccc35cd56ead9fc"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:9b20745108c8de5afccc35cd56ead9fc"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:9b20745108c8de5afccc35cd56ead9fc"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:9b20745108c8de5afccc35cd56ead9fc"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "SimpleQuery.dataLoader",
+ "DisplayName": "SimpleQuery.dataLoader",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
+ },
+ {
+ "Key": "graphql.selection.name",
+ "Value": "dataLoader"
+ },
+ {
+ "Key": "graphql.selection.path",
+ "Value": "dataLoader"
+ },
+ {
+ "Key": "graphql.selection.field.name",
+ "Value": "dataLoader"
+ },
+ {
+ "Key": "graphql.selection.field.coordinate",
+ "Value": "SimpleQuery.dataLoader"
+ },
+ {
+ "Key": "graphql.selection.field.parent_type",
+ "Value": "SimpleQuery"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL DataLoader Dispatch",
+ "DisplayName": "GraphQL DataLoader Dispatch",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "dataloader_dispatch"
+ }
+ ],
+ "event": [
+ {
+ "Name": "BatchEvaluated",
+ "Tags": [
+ {
+ "Key": "openBatches",
+ "Value": 1
+ }
+ ]
+ },
+ {
+ "Name": "BatchDispatched",
+ "Tags": [
+ {
+ "Key": "dispatchedBatches",
+ "Value": 1
+ }
+ ]
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL DataLoader Batch CustomDataLoader",
+ "DisplayName": "GraphQL DataLoader Batch CustomDataLoader",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "dataloader_batch"
+ },
+ {
+ "Key": "graphql.dataloader.name",
+ "Value": "CustomDataLoader"
+ },
+ {
+ "Key": "graphql.dataloader.batch.size",
+ "Value": 1
+ },
+ {
+ "Key": "graphql.dataloader.batch.keys",
+ "Value": [
+ "abc"
+ ]
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Track_events_of_a_simple_query_default.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.DefaultScopes_ExcludesExecuteRequestAndParseDocumentSpans.snap
similarity index 50%
rename from src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Track_events_of_a_simple_query_default.snap
rename to src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.DefaultScopes_ExcludesExecuteRequestAndParseDocumentSpans.snap
index 31c920d0d93..2386d6e2307 100644
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Track_events_of_a_simple_query_default.snap
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.DefaultScopes_ExcludesExecuteRequestAndParseDocumentSpans.snap
@@ -1,57 +1,57 @@
-{
+{
"activities": [
{
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
"Status": "Ok",
"tags": [
{
- "Key": "graphql.document.id",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
+ "Key": "graphql.processing.type",
+ "Value": "validate"
},
{
"Key": "graphql.document.hash",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
}
],
"event": []
},
{
- "OperationName": "CompileOperation",
- "DisplayName": "Compile Operation",
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
"Status": "Ok",
"tags": [
{
- "Key": "otel.status_code",
- "Value": "OK"
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
}
],
"event": []
},
{
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/sayHello",
+ "OperationName": "SimpleQuery.sayHello",
+ "DisplayName": "SimpleQuery.sayHello",
"Status": "Ok",
"tags": [
{
- "Key": "graphql.selection.name",
- "Value": "sayHello"
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
},
{
- "Key": "graphql.selection.type",
- "Value": "String!"
+ "Key": "graphql.selection.name",
+ "Value": "sayHello"
},
{
"Key": "graphql.selection.path",
- "Value": "/sayHello"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/sayHello"
+ "Value": "sayHello"
},
{
"Key": "graphql.selection.field.name",
@@ -62,12 +62,8 @@
"Value": "SimpleQuery.sayHello"
},
{
- "Key": "graphql.selection.field.declaringType",
+ "Key": "graphql.selection.field.parent_type",
"Value": "SimpleQuery"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
}
],
"event": []
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.DocumentCache_SecondExecution_RecordsCacheHitEvent.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.DocumentCache_SecondExecution_RecordsCacheHitEvent.snap
new file mode 100644
index 00000000000..e6b686d9426
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.DocumentCache_SecondExecution_RecordsCacheHitEvent.snap
@@ -0,0 +1,81 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": [
+ {
+ "Name": "RetrievedDocumentFromCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "SimpleQuery.sayHello",
+ "DisplayName": "SimpleQuery.sayHello",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
+ },
+ {
+ "Key": "graphql.selection.name",
+ "Value": "sayHello"
+ },
+ {
+ "Key": "graphql.selection.path",
+ "Value": "sayHello"
+ },
+ {
+ "Key": "graphql.selection.field.name",
+ "Value": "sayHello"
+ },
+ {
+ "Key": "graphql.selection.field.coordinate",
+ "Value": "SimpleQuery.sayHello"
+ },
+ {
+ "Key": "graphql.selection.field.parent_type",
+ "Value": "SimpleQuery"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.Ensure_That_The_Validation_Activity_Has_An_Error_Status.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.Ensure_That_The_Validation_Activity_Has_An_Error_Status.snap
new file mode 100644
index 00000000000..16d3fd1d1f8
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.Ensure_That_The_Validation_Activity_Has_An_Error_Status.snap
@@ -0,0 +1,69 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "GraphQL Operation",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:bb1d246465341a97bdc727d6cd8ead5c"
+ },
+ {
+ "Key": "graphql.document.body",
+ "Value": "query SayHelloOperation {\n sayHello_\n}"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Parsing",
+ "DisplayName": "GraphQL Document Parsing",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:bb1d246465341a97bdc727d6cd8ead5c"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:bb1d246465341a97bdc727d6cd8ead5c"
+ }
+ ],
+ "event": [
+ {
+ "Name": "exception",
+ "Tags": [
+ {
+ "Key": "graphql.error.message",
+ "Value": "The field `sayHello_` does not exist on the type `SimpleQuery`."
+ },
+ {
+ "Key": "graphql.error.locations",
+ "Value": [
+ {
+ "line": 1,
+ "column": 27
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.ParsingError_InvalidGraphQLDocument_ReportsErrorStatus.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.ParsingError_InvalidGraphQLDocument_ReportsErrorStatus.snap
new file mode 100644
index 00000000000..aec02c711c2
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.ParsingError_InvalidGraphQLDocument_ReportsErrorStatus.snap
@@ -0,0 +1,48 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "GraphQL Operation",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:bb507ba78696fc3c6ff3a17fb06784d5"
+ }
+ ],
+ "event": [
+ {
+ "Name": "exception",
+ "Tags": [
+ {
+ "Key": "exception.message",
+ "Value": "Expected a `RightBrace`-token, but found a `EndOfFile`-token."
+ },
+ {
+ "Key": "exception.stacktrace",
+ "Value": "HotChocolate.Language.SyntaxException: Expected a `RightBrace`-token, but found a `EndOfFile`-token.\n at HotChocolate.Language.Utf8GraphQLParser.ParseSelectionSet() in Utf8GraphQLParser.Operations.cs:line 221\n at HotChocolate.Language.Utf8GraphQLParser.ParseShortOperationDefinition() in Utf8GraphQLParser.Operations.cs:line 73\n at HotChocolate.Language.Utf8GraphQLParser.ParseDefinition() in Utf8GraphQLParser.cs:line 215\n at HotChocolate.Language.Utf8GraphQLParser.Parse() in Utf8GraphQLParser.cs:line 98\n at HotChocolate.Language.Utf8GraphQLParser.Parse(String sourceText, ParserOptions options) in Utf8GraphQLParser.cs:line 326\n at HotChocolate.Execution.Pipeline.DocumentParserMiddleware.InvokeAsync(RequestContext context) in DocumentParserMiddleware.cs:line 63"
+ },
+ {
+ "Key": "exception.type",
+ "Value": "HotChocolate.Language.SyntaxException"
+ }
+ ]
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Parsing",
+ "DisplayName": "GraphQL Document Parsing",
+ "Status": "Unset",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:bb507ba78696fc3c6ff3a17fb06784d5"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.PersistedOperation_LoadsFromStorage_DefaultScopes.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.PersistedOperation_LoadsFromStorage_DefaultScopes.snap
new file mode 100644
index 00000000000..b85b922a120
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.PersistedOperation_LoadsFromStorage_DefaultScopes.snap
@@ -0,0 +1,80 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.document.id",
+ "Value": "sayHelloOp"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.document.id",
+ "Value": "sayHelloOp"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "SimpleQuery.sayHello",
+ "DisplayName": "SimpleQuery.sayHello",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
+ },
+ {
+ "Key": "graphql.selection.name",
+ "Value": "sayHello"
+ },
+ {
+ "Key": "graphql.selection.path",
+ "Value": "sayHello"
+ },
+ {
+ "Key": "graphql.selection.field.name",
+ "Value": "sayHello"
+ },
+ {
+ "Key": "graphql.selection.field.coordinate",
+ "Value": "SimpleQuery.sayHello"
+ },
+ {
+ "Key": "graphql.selection.field.parent_type",
+ "Value": "SimpleQuery"
+ }
+ ],
+ "event": []
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.ResolverError_AtRootLevel_MarksOperationAsError.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.ResolverError_AtRootLevel_MarksOperationAsError.snap
new file mode 100644
index 00000000000..6031fca24ee
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.ResolverError_AtRootLevel_MarksOperationAsError.snap
@@ -0,0 +1,151 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:ae3f9af1d2570e25f30a1ad002172b82"
+ },
+ {
+ "Key": "graphql.document.body",
+ "Value": "{\n causeFatalError\n}"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Parsing",
+ "DisplayName": "GraphQL Document Parsing",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:ae3f9af1d2570e25f30a1ad002172b82"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:ae3f9af1d2570e25f30a1ad002172b82"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:ae3f9af1d2570e25f30a1ad002172b82"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:ae3f9af1d2570e25f30a1ad002172b82"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "SimpleQuery.causeFatalError",
+ "DisplayName": "SimpleQuery.causeFatalError",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
+ },
+ {
+ "Key": "graphql.selection.name",
+ "Value": "causeFatalError"
+ },
+ {
+ "Key": "graphql.selection.path",
+ "Value": "causeFatalError"
+ },
+ {
+ "Key": "graphql.selection.field.name",
+ "Value": "causeFatalError"
+ },
+ {
+ "Key": "graphql.selection.field.coordinate",
+ "Value": "SimpleQuery.causeFatalError"
+ },
+ {
+ "Key": "graphql.selection.field.parent_type",
+ "Value": "SimpleQuery"
+ }
+ ],
+ "event": [
+ {
+ "Name": "exception",
+ "Tags": [
+ {
+ "Key": "graphql.error.message",
+ "Value": "fail"
+ },
+ {
+ "Key": "graphql.error.path",
+ "Value": "causeFatalError"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.ResolverError_DeepInTree_MarksNestedFieldAsError.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.ResolverError_DeepInTree_MarksNestedFieldAsError.snap
new file mode 100644
index 00000000000..dd5f4d13d99
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.ResolverError_DeepInTree_MarksNestedFieldAsError.snap
@@ -0,0 +1,69 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "GraphQL Operation",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:2bf0466e723c1bad3a65089b6fb0dbfc"
+ },
+ {
+ "Key": "graphql.document.body",
+ "Value": "{\n deep {\n deeper {\n deeps {\n deeper {\n causeFatalError\n }\n }\n }\n }\n}"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Parsing",
+ "DisplayName": "GraphQL Document Parsing",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:2bf0466e723c1bad3a65089b6fb0dbfc"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:2bf0466e723c1bad3a65089b6fb0dbfc"
+ }
+ ],
+ "event": [
+ {
+ "Name": "exception",
+ "Tags": [
+ {
+ "Key": "graphql.error.message",
+ "Value": "The field `causeFatalError` does not exist on the type `Deeper`."
+ },
+ {
+ "Key": "graphql.error.locations",
+ "Value": [
+ {
+ "line": 6,
+ "column": 21
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.SubscriptionEventError_Records_Subscription_Event_Error.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.SubscriptionEventError_Records_Subscription_Event_Error.snap
new file mode 100644
index 00000000000..f96698c579d
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.SubscriptionEventError_Records_Subscription_Event_Error.snap
@@ -0,0 +1,201 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "subscription",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "subscription"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "OnFailingMessageSubscription"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:1f38a1bfe720ad0cb6083bf8b309d3aa"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Parsing",
+ "DisplayName": "GraphQL Document Parsing",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:1f38a1bfe720ad0cb6083bf8b309d3aa"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:1f38a1bfe720ad0cb6083bf8b309d3aa"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:1f38a1bfe720ad0cb6083bf8b309d3aa"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "subscription"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "OnFailingMessageSubscription"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "subscription"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "OnFailingMessageSubscription"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:1f38a1bfe720ad0cb6083bf8b309d3aa"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "GraphQL Subscription Event",
+ "DisplayName": "GraphQL Subscription Event",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "subscription"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "OnFailingMessageSubscription"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:1f38a1bfe720ad0cb6083bf8b309d3aa"
+ },
+ {
+ "Key": "graphql.subscription.id",
+ "Value": "1"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "SimpleSubscription.onFailingMessage",
+ "DisplayName": "SimpleSubscription.onFailingMessage",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
+ },
+ {
+ "Key": "graphql.selection.name",
+ "Value": "onFailingMessage"
+ },
+ {
+ "Key": "graphql.selection.path",
+ "Value": "onFailingMessage"
+ },
+ {
+ "Key": "graphql.selection.field.name",
+ "Value": "onFailingMessage"
+ },
+ {
+ "Key": "graphql.selection.field.coordinate",
+ "Value": "SimpleSubscription.onFailingMessage"
+ },
+ {
+ "Key": "graphql.selection.field.parent_type",
+ "Value": "SimpleSubscription"
+ }
+ ],
+ "event": [
+ {
+ "Name": "exception",
+ "Tags": [
+ {
+ "Key": "graphql.error.message",
+ "Value": "Unexpected Execution Error"
+ },
+ {
+ "Key": "exception.message",
+ "Value": "Subscription event failed."
+ },
+ {
+ "Key": "exception.stacktrace",
+ "Value": "System.InvalidOperationException: Subscription event failed.\n at HotChocolate.Diagnostics.ActivityExecutionDiagnosticListenerTests.SimpleSubscription.OnFailingMessage(String message) in ActivityExecutionDiagnosticListenerTests.cs:line 493\n at lambda_method(Closure, IResolverContext)\n at HotChocolate.Types.Helpers.FieldMiddlewareCompiler.<>c__DisplayClass9_0.<b__0>d.MoveNext() in FieldMiddlewareCompiler.cs:line 127\n--- End of stack trace from previous location ---\n at HotChocolate.Execution.Processing.Tasks.ResolverTask.ExecuteResolverPipelineAsync(CancellationToken cancellationToken) in ResolverTask.Execute.cs:line 135\n at HotChocolate.Execution.Processing.Tasks.ResolverTask.TryExecuteAsync(CancellationToken cancellationToken) in ResolverTask.Execute.cs:line 81"
+ },
+ {
+ "Key": "exception.type",
+ "Value": "System.InvalidOperationException"
+ },
+ {
+ "Key": "graphql.error.path",
+ "Value": "onFailingMessage"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.SubscriptionEvent_Records_Subscription_Event_Span.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.SubscriptionEvent_Records_Subscription_Event_Span.snap
new file mode 100644
index 00000000000..dab79a8bcac
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.SubscriptionEvent_Records_Subscription_Event_Span.snap
@@ -0,0 +1,175 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "subscription",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "subscription"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "OnMessageSubscription"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:ef859b98c9d8c17038c8fd9aeecdb1e2"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Parsing",
+ "DisplayName": "GraphQL Document Parsing",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:ef859b98c9d8c17038c8fd9aeecdb1e2"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:ef859b98c9d8c17038c8fd9aeecdb1e2"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:ef859b98c9d8c17038c8fd9aeecdb1e2"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "subscription"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "OnMessageSubscription"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "subscription"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "OnMessageSubscription"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:ef859b98c9d8c17038c8fd9aeecdb1e2"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "GraphQL Subscription Event",
+ "DisplayName": "GraphQL Subscription Event",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "subscription"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "OnMessageSubscription"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:ef859b98c9d8c17038c8fd9aeecdb1e2"
+ },
+ {
+ "Key": "graphql.subscription.id",
+ "Value": "1"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "SimpleSubscription.onMessage",
+ "DisplayName": "SimpleSubscription.onMessage",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
+ },
+ {
+ "Key": "graphql.selection.name",
+ "Value": "onMessage"
+ },
+ {
+ "Key": "graphql.selection.path",
+ "Value": "onMessage"
+ },
+ {
+ "Key": "graphql.selection.field.name",
+ "Value": "onMessage"
+ },
+ {
+ "Key": "graphql.selection.field.coordinate",
+ "Value": "SimpleSubscription.onMessage"
+ },
+ {
+ "Key": "graphql.selection.field.parent_type",
+ "Value": "SimpleSubscription"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.Track_Events_Of_A_Simple_Query_Default.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.Track_Events_Of_A_Simple_Query_Default.snap
new file mode 100644
index 00000000000..2386d6e2307
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.Track_Events_Of_A_Simple_Query_Default.snap
@@ -0,0 +1,72 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "SimpleQuery.sayHello",
+ "DisplayName": "SimpleQuery.sayHello",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
+ },
+ {
+ "Key": "graphql.selection.name",
+ "Value": "sayHello"
+ },
+ {
+ "Key": "graphql.selection.path",
+ "Value": "sayHello"
+ },
+ {
+ "Key": "graphql.selection.field.name",
+ "Value": "sayHello"
+ },
+ {
+ "Key": "graphql.selection.field.coordinate",
+ "Value": "SimpleQuery.sayHello"
+ },
+ {
+ "Key": "graphql.selection.field.parent_type",
+ "Value": "SimpleQuery"
+ }
+ ],
+ "event": []
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.ValidationError_UnknownField_ReportsErrorStatus.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.ValidationError_UnknownField_ReportsErrorStatus.snap
new file mode 100644
index 00000000000..c0dc8f03d3c
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.ValidationError_UnknownField_ReportsErrorStatus.snap
@@ -0,0 +1,65 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "GraphQL Operation",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:1526f207d516803b71eb8a0db419b57b"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Parsing",
+ "DisplayName": "GraphQL Document Parsing",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:1526f207d516803b71eb8a0db419b57b"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:1526f207d516803b71eb8a0db419b57b"
+ }
+ ],
+ "event": [
+ {
+ "Name": "exception",
+ "Tags": [
+ {
+ "Key": "graphql.error.message",
+ "Value": "The field `unknownField123` does not exist on the type `SimpleQuery`."
+ },
+ {
+ "Key": "graphql.error.locations",
+ "Value": [
+ {
+ "line": 1,
+ "column": 3
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.VariableCoercion_WithAllScopes_RecordsCoercionSpan.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.VariableCoercion_WithAllScopes_RecordsCoercionSpan.snap
new file mode 100644
index 00000000000..e9d8d435d16
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityExecutionDiagnosticListenerTests.VariableCoercion_WithAllScopes_RecordsCoercionSpan.snap
@@ -0,0 +1,153 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:c46cf8c9811934ddea095f10ee722dc4"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Parsing",
+ "DisplayName": "GraphQL Document Parsing",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:c46cf8c9811934ddea095f10ee722dc4"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:c46cf8c9811934ddea095f10ee722dc4"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:c46cf8c9811934ddea095f10ee722dc4"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Variable Coercion",
+ "DisplayName": "GraphQL Variable Coercion",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "variable_coercion"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:c46cf8c9811934ddea095f10ee722dc4"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:c46cf8c9811934ddea095f10ee722dc4"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "SimpleQuery.greeting",
+ "DisplayName": "SimpleQuery.greeting",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
+ },
+ {
+ "Key": "graphql.selection.name",
+ "Value": "greeting"
+ },
+ {
+ "Key": "graphql.selection.path",
+ "Value": "greeting"
+ },
+ {
+ "Key": "graphql.selection.field.name",
+ "Value": "greeting"
+ },
+ {
+ "Key": "graphql.selection.field.coordinate",
+ "Value": "SimpleQuery.greeting"
+ },
+ {
+ "Key": "graphql.selection.field.parent_type",
+ "Value": "SimpleQuery"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Get_SDL_Download.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Get_SDL_Download.snap
similarity index 75%
rename from src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Get_SDL_Download.snap
rename to src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Get_SDL_Download.snap
index 1669a6a2090..d77edd7831a 100644
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Get_SDL_Download.snap
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Get_SDL_Download.snap
@@ -5,6 +5,10 @@
"DisplayName": "GraphQL HTTP GET SDL",
"Status": "Ok",
"tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpGetSchema"
+ },
{
"Key": "graphql.schema.name",
"Value": "_Default"
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_add_variables_to_http_activity.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Get_SingleRequest_GetHeroName.snap
similarity index 50%
rename from src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_add_variables_to_http_activity.snap
rename to src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Get_SingleRequest_GetHeroName.snap
index c6b48eaef41..549d391b410 100644
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_add_variables_to_http_activity.snap
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Get_SingleRequest_GetHeroName.snap
@@ -2,9 +2,13 @@
"activities": [
{
"OperationName": "ExecuteHttpRequest",
- "DisplayName": "GraphQL HTTP POST",
+ "DisplayName": "GraphQL HTTP GET",
"Status": "Ok",
"tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpGet"
+ },
{
"Key": "graphql.schema.name",
"Value": "_Default"
@@ -14,40 +18,31 @@
"Value": "single"
},
{
- "Key": "graphql.http.request.variables",
- "Value": "{\"episode\":\"NEW_HOPE\"}"
+ "Key": "graphql.http.request.query.hash",
+ "Value": "a570a6bff748b5916eadf153261d9c6d"
}
],
"event": [],
"activities": [
{
- "OperationName": "ParseHttpRequest",
+ "OperationName": "Parse HTTP Request",
"DisplayName": "Parse HTTP Request",
"Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
+ "tags": [],
"event": []
},
{
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { hero }",
- "Status": "Unset",
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
"tags": [
{
- "Key": "graphql.document.id",
- "Value": "1d4bca4d0dff630390ddf48e9085589d"
+ "Key": "graphql.operation.type",
+ "Value": "query"
},
{
"Key": "graphql.document.hash",
- "Value": "cc68dfd8c0c54a586a03c35296c5d1f9"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "_Default-1-1d4bca4d0dff630390ddf48e9085589d"
+ "Value": "md5:acb8d5d513c260b3cef3e3a12b0e29af"
}
],
"event": [
@@ -62,93 +57,97 @@
],
"activities": [
{
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
"Status": "Ok",
"tags": [
{
- "Key": "graphql.document.id",
- "Value": "1d4bca4d0dff630390ddf48e9085589d"
+ "Key": "graphql.processing.type",
+ "Value": "validate"
},
{
"Key": "graphql.document.hash",
- "Value": "cc68dfd8c0c54a586a03c35296c5d1f9"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
+ "Value": "md5:acb8d5d513c260b3cef3e3a12b0e29af"
}
],
"event": []
},
{
- "OperationName": "AnalyzeOperationCost",
- "DisplayName": "Analyze Operation Complexity",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.operation.id",
- "Value": "1d4bca4d0dff630390ddf48e9085589d"
- }
- ],
- "event": []
- },
- {
- "OperationName": "CompileOperation",
- "DisplayName": "Compile Operation",
+ "OperationName": "GraphQL Complexity Analysis",
+ "DisplayName": "GraphQL Complexity Analysis",
"Status": "Ok",
"tags": [
{
- "Key": "otel.status_code",
- "Value": "OK"
+ "Key": "graphql.document.hash",
+ "Value": "md5:acb8d5d513c260b3cef3e3a12b0e29af"
+ },
+ {
+ "Key": "graphql.operation.fieldCost",
+ "Value": 1.0
+ },
+ {
+ "Key": "graphql.operation.typeCost",
+ "Value": 2.0
}
],
"event": []
},
{
- "OperationName": "CoerceVariables",
- "DisplayName": "Coerce Variable",
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
"Status": "Ok",
"tags": [
{
- "Key": "otel.status_code",
- "Value": "OK"
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:acb8d5d513c260b3cef3e3a12b0e29af"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
}
],
"event": []
},
{
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
"Status": "Ok",
"tags": [
{
- "Key": "otel.status_code",
- "Value": "OK"
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:acb8d5d513c260b3cef3e3a12b0e29af"
}
],
"event": [],
"activities": [
{
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/hero",
+ "OperationName": "Query.hero",
+ "DisplayName": "Query.hero",
"Status": "Ok",
"tags": [
{
- "Key": "graphql.selection.name",
- "Value": "hero"
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
},
{
- "Key": "graphql.selection.type",
- "Value": "Character"
+ "Key": "graphql.selection.name",
+ "Value": "hero"
},
{
"Key": "graphql.selection.path",
- "Value": "/hero"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/hero"
+ "Value": "hero"
},
{
"Key": "graphql.selection.field.name",
@@ -159,12 +158,8 @@
"Value": "Query.hero"
},
{
- "Key": "graphql.selection.field.declaringType",
+ "Key": "graphql.selection.field.parent_type",
"Value": "Query"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
}
],
"event": []
@@ -174,7 +169,7 @@
]
},
{
- "OperationName": "FormatHttpResponse",
+ "OperationName": "Format HTTP Response",
"DisplayName": "Format HTTP Response",
"Status": "Ok",
"tags": [],
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Post_Add_Variables_To_Http_Activity.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Post_Add_Variables_To_Http_Activity.snap
new file mode 100644
index 00000000000..f0a0844464d
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Post_Add_Variables_To_Http_Activity.snap
@@ -0,0 +1,209 @@
+{
+ "activities": [
+ {
+ "OperationName": "ExecuteHttpRequest",
+ "DisplayName": "GraphQL HTTP POST",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpPost"
+ },
+ {
+ "Key": "graphql.schema.name",
+ "Value": "_Default"
+ },
+ {
+ "Key": "graphql.http.request.type",
+ "Value": "single"
+ },
+ {
+ "Key": "graphql.http.request.query.id",
+ "Value": "1d4bca4d0dff630390ddf48e9085589d"
+ },
+ {
+ "Key": "graphql.http.request.query.hash",
+ "Value": "1d4bca4d0dff630390ddf48e9085589d"
+ },
+ {
+ "Key": "graphql.http.request.variables",
+ "Value": "{\"episode\":\"NEW_HOPE\"}"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "Parse HTTP Request",
+ "DisplayName": "Parse HTTP Request",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:cc68dfd8c0c54a586a03c35296c5d1f9"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:cc68dfd8c0c54a586a03c35296c5d1f9"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Complexity Analysis",
+ "DisplayName": "GraphQL Complexity Analysis",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:cc68dfd8c0c54a586a03c35296c5d1f9"
+ },
+ {
+ "Key": "graphql.operation.fieldCost",
+ "Value": 1.0
+ },
+ {
+ "Key": "graphql.operation.typeCost",
+ "Value": 2.0
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:cc68dfd8c0c54a586a03c35296c5d1f9"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Variable Coercion",
+ "DisplayName": "GraphQL Variable Coercion",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "variable_coercion"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:cc68dfd8c0c54a586a03c35296c5d1f9"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:cc68dfd8c0c54a586a03c35296c5d1f9"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "Query.hero",
+ "DisplayName": "Query.hero",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
+ },
+ {
+ "Key": "graphql.selection.name",
+ "Value": "hero"
+ },
+ {
+ "Key": "graphql.selection.path",
+ "Value": "hero"
+ },
+ {
+ "Key": "graphql.selection.field.name",
+ "Value": "hero"
+ },
+ {
+ "Key": "graphql.selection.field.coordinate",
+ "Value": "Query.hero"
+ },
+ {
+ "Key": "graphql.selection.field.parent_type",
+ "Value": "Query"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "OperationName": "Format HTTP Response",
+ "DisplayName": "Format HTTP Response",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_capture_deferred_response.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Post_Capture_Deferred_Response.snap
similarity index 53%
rename from src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_capture_deferred_response.snap
rename to src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Post_Capture_Deferred_Response.snap
index 88a26adcf95..16356a5b239 100644
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_capture_deferred_response.snap
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Post_Capture_Deferred_Response.snap
@@ -5,6 +5,10 @@
"DisplayName": "GraphQL HTTP POST",
"Status": "Ok",
"tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpPost"
+ },
{
"Key": "graphql.schema.name",
"Value": "_Default"
@@ -12,38 +16,37 @@
{
"Key": "graphql.http.request.type",
"Value": "single"
+ },
+ {
+ "Key": "graphql.http.request.query.id",
+ "Value": "dd31323224a6428d4dc301134352aeab"
+ },
+ {
+ "Key": "graphql.http.request.query.hash",
+ "Value": "dd31323224a6428d4dc301134352aeab"
}
],
"event": [],
"activities": [
{
- "OperationName": "ParseHttpRequest",
+ "OperationName": "Parse HTTP Request",
"DisplayName": "Parse HTTP Request",
"Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
+ "tags": [],
"event": []
},
{
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { hero }",
- "Status": "Unset",
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
"tags": [
{
- "Key": "graphql.document.id",
- "Value": "dd31323224a6428d4dc301134352aeab"
+ "Key": "graphql.operation.type",
+ "Value": "query"
},
{
"Key": "graphql.document.hash",
- "Value": "3beaca4ee1714ac9c9dfec8e445529df"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "_Default-1-dd31323224a6428d4dc301134352aeab"
+ "Value": "md5:3beaca4ee1714ac9c9dfec8e445529df"
}
],
"event": [
@@ -58,81 +61,97 @@
],
"activities": [
{
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
"Status": "Ok",
"tags": [
{
- "Key": "graphql.document.id",
- "Value": "dd31323224a6428d4dc301134352aeab"
+ "Key": "graphql.processing.type",
+ "Value": "validate"
},
{
"Key": "graphql.document.hash",
- "Value": "3beaca4ee1714ac9c9dfec8e445529df"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
+ "Value": "md5:3beaca4ee1714ac9c9dfec8e445529df"
}
],
"event": []
},
{
- "OperationName": "AnalyzeOperationCost",
- "DisplayName": "Analyze Operation Complexity",
- "Status": "Unset",
+ "OperationName": "GraphQL Complexity Analysis",
+ "DisplayName": "GraphQL Complexity Analysis",
+ "Status": "Ok",
"tags": [
{
- "Key": "graphql.operation.id",
- "Value": "dd31323224a6428d4dc301134352aeab"
+ "Key": "graphql.document.hash",
+ "Value": "md5:3beaca4ee1714ac9c9dfec8e445529df"
+ },
+ {
+ "Key": "graphql.operation.fieldCost",
+ "Value": 1.0
+ },
+ {
+ "Key": "graphql.operation.typeCost",
+ "Value": 2.0
}
],
"event": []
},
{
- "OperationName": "CompileOperation",
- "DisplayName": "Compile Operation",
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
"Status": "Ok",
"tags": [
{
- "Key": "otel.status_code",
- "Value": "OK"
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:3beaca4ee1714ac9c9dfec8e445529df"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
}
],
"event": []
},
{
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
"Status": "Ok",
"tags": [
{
- "Key": "otel.status_code",
- "Value": "OK"
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:3beaca4ee1714ac9c9dfec8e445529df"
}
],
"event": [],
"activities": [
{
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/hero",
+ "OperationName": "Query.hero",
+ "DisplayName": "Query.hero",
"Status": "Ok",
"tags": [
{
- "Key": "graphql.selection.name",
- "Value": "hero"
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
},
{
- "Key": "graphql.selection.type",
- "Value": "Character"
+ "Key": "graphql.selection.name",
+ "Value": "hero"
},
{
"Key": "graphql.selection.path",
- "Value": "/hero"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/hero"
+ "Value": "hero"
},
{
"Key": "graphql.selection.field.name",
@@ -143,36 +162,28 @@
"Value": "Query.hero"
},
{
- "Key": "graphql.selection.field.declaringType",
+ "Key": "graphql.selection.field.parent_type",
"Value": "Query"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
}
],
"event": []
},
{
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/hero/id",
+ "OperationName": "Droid.id",
+ "DisplayName": "Droid.id",
"Status": "Ok",
"tags": [
{
- "Key": "graphql.selection.name",
- "Value": "id"
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
},
{
- "Key": "graphql.selection.type",
- "Value": "ID!"
+ "Key": "graphql.selection.name",
+ "Value": "id"
},
{
"Key": "graphql.selection.path",
- "Value": "/hero/id"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/hero/id"
+ "Value": "hero.id"
},
{
"Key": "graphql.selection.field.name",
@@ -183,12 +194,8 @@
"Value": "Droid.id"
},
{
- "Key": "graphql.selection.field.declaringType",
+ "Key": "graphql.selection.field.parent_type",
"Value": "Droid"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
}
],
"event": []
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_ensure_list_path_is_correctly_built.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Post_Ensure_List_Path_Is_Correctly_Built.snap
similarity index 55%
rename from src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_ensure_list_path_is_correctly_built.snap
rename to src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Post_Ensure_List_Path_Is_Correctly_Built.snap
index 8a5b3455d73..a4c809a7deb 100644
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_ensure_list_path_is_correctly_built.snap
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Post_Ensure_List_Path_Is_Correctly_Built.snap
@@ -5,6 +5,10 @@
"DisplayName": "GraphQL HTTP POST",
"Status": "Ok",
"tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpPost"
+ },
{
"Key": "graphql.schema.name",
"Value": "_Default"
@@ -12,38 +16,37 @@
{
"Key": "graphql.http.request.type",
"Value": "single"
+ },
+ {
+ "Key": "graphql.http.request.query.id",
+ "Value": "c0513b4b6f0cf7430f64de4aa3dcd7c6"
+ },
+ {
+ "Key": "graphql.http.request.query.hash",
+ "Value": "c0513b4b6f0cf7430f64de4aa3dcd7c6"
}
],
"event": [],
"activities": [
{
- "OperationName": "ParseHttpRequest",
+ "OperationName": "Parse HTTP Request",
"DisplayName": "Parse HTTP Request",
"Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
+ "tags": [],
"event": []
},
{
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { hero }",
- "Status": "Unset",
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
"tags": [
{
- "Key": "graphql.document.id",
- "Value": "c0513b4b6f0cf7430f64de4aa3dcd7c6"
+ "Key": "graphql.operation.type",
+ "Value": "query"
},
{
"Key": "graphql.document.hash",
- "Value": "668e9631148921208d08dbb69513fa8e"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "_Default-1-c0513b4b6f0cf7430f64de4aa3dcd7c6"
+ "Value": "md5:668e9631148921208d08dbb69513fa8e"
}
],
"event": [
@@ -58,81 +61,97 @@
],
"activities": [
{
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
"Status": "Ok",
"tags": [
{
- "Key": "graphql.document.id",
- "Value": "c0513b4b6f0cf7430f64de4aa3dcd7c6"
+ "Key": "graphql.processing.type",
+ "Value": "validate"
},
{
"Key": "graphql.document.hash",
- "Value": "668e9631148921208d08dbb69513fa8e"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
+ "Value": "md5:668e9631148921208d08dbb69513fa8e"
}
],
"event": []
},
{
- "OperationName": "AnalyzeOperationCost",
- "DisplayName": "Analyze Operation Complexity",
- "Status": "Unset",
+ "OperationName": "GraphQL Complexity Analysis",
+ "DisplayName": "GraphQL Complexity Analysis",
+ "Status": "Ok",
"tags": [
{
- "Key": "graphql.operation.id",
- "Value": "c0513b4b6f0cf7430f64de4aa3dcd7c6"
+ "Key": "graphql.document.hash",
+ "Value": "md5:668e9631148921208d08dbb69513fa8e"
+ },
+ {
+ "Key": "graphql.operation.fieldCost",
+ "Value": 1.0
+ },
+ {
+ "Key": "graphql.operation.typeCost",
+ "Value": 2.0
}
],
"event": []
},
{
- "OperationName": "CompileOperation",
- "DisplayName": "Compile Operation",
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
"Status": "Ok",
"tags": [
{
- "Key": "otel.status_code",
- "Value": "OK"
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:668e9631148921208d08dbb69513fa8e"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
}
],
"event": []
},
{
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
"Status": "Ok",
"tags": [
{
- "Key": "otel.status_code",
- "Value": "OK"
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:668e9631148921208d08dbb69513fa8e"
}
],
"event": [],
"activities": [
{
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/hero",
+ "OperationName": "Query.hero",
+ "DisplayName": "Query.hero",
"Status": "Ok",
"tags": [
{
- "Key": "graphql.selection.name",
- "Value": "hero"
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
},
{
- "Key": "graphql.selection.type",
- "Value": "Character"
+ "Key": "graphql.selection.name",
+ "Value": "hero"
},
{
"Key": "graphql.selection.path",
- "Value": "/hero"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/hero"
+ "Value": "hero"
},
{
"Key": "graphql.selection.field.name",
@@ -143,36 +162,28 @@
"Value": "Query.hero"
},
{
- "Key": "graphql.selection.field.declaringType",
+ "Key": "graphql.selection.field.parent_type",
"Value": "Query"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
}
],
"event": []
},
{
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/hero/friends",
+ "OperationName": "Droid.friends",
+ "DisplayName": "Droid.friends",
"Status": "Ok",
"tags": [
{
- "Key": "graphql.selection.name",
- "Value": "friends"
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
},
{
- "Key": "graphql.selection.type",
- "Value": "FriendsConnection"
+ "Key": "graphql.selection.name",
+ "Value": "friends"
},
{
"Key": "graphql.selection.path",
- "Value": "/hero/friends"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/hero/friends"
+ "Value": "hero.friends"
},
{
"Key": "graphql.selection.field.name",
@@ -183,36 +194,28 @@
"Value": "Droid.friends"
},
{
- "Key": "graphql.selection.field.declaringType",
+ "Key": "graphql.selection.field.parent_type",
"Value": "Droid"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
}
],
"event": []
},
{
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/hero/friends/nodes[0]/friends",
+ "OperationName": "Human.friends",
+ "DisplayName": "Human.friends",
"Status": "Ok",
"tags": [
{
- "Key": "graphql.selection.name",
- "Value": "friends"
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
},
{
- "Key": "graphql.selection.type",
- "Value": "FriendsConnection"
+ "Key": "graphql.selection.name",
+ "Value": "friends"
},
{
"Key": "graphql.selection.path",
- "Value": "/hero/friends/nodes[0]/friends"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/hero/friends/nodes/friends"
+ "Value": "hero.friends.nodes[0].friends"
},
{
"Key": "graphql.selection.field.name",
@@ -223,36 +226,28 @@
"Value": "Human.friends"
},
{
- "Key": "graphql.selection.field.declaringType",
+ "Key": "graphql.selection.field.parent_type",
"Value": "Human"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
}
],
"event": []
},
{
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/hero/friends/nodes[1]/friends",
+ "OperationName": "Human.friends",
+ "DisplayName": "Human.friends",
"Status": "Ok",
"tags": [
{
- "Key": "graphql.selection.name",
- "Value": "friends"
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
},
{
- "Key": "graphql.selection.type",
- "Value": "FriendsConnection"
+ "Key": "graphql.selection.name",
+ "Value": "friends"
},
{
"Key": "graphql.selection.path",
- "Value": "/hero/friends/nodes[1]/friends"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/hero/friends/nodes/friends"
+ "Value": "hero.friends.nodes[1].friends"
},
{
"Key": "graphql.selection.field.name",
@@ -263,36 +258,28 @@
"Value": "Human.friends"
},
{
- "Key": "graphql.selection.field.declaringType",
+ "Key": "graphql.selection.field.parent_type",
"Value": "Human"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
}
],
"event": []
},
{
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/hero/friends/nodes[2]/friends",
+ "OperationName": "Human.friends",
+ "DisplayName": "Human.friends",
"Status": "Ok",
"tags": [
{
- "Key": "graphql.selection.name",
- "Value": "friends"
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
},
{
- "Key": "graphql.selection.type",
- "Value": "FriendsConnection"
+ "Key": "graphql.selection.name",
+ "Value": "friends"
},
{
"Key": "graphql.selection.path",
- "Value": "/hero/friends/nodes[2]/friends"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/hero/friends/nodes/friends"
+ "Value": "hero.friends.nodes[2].friends"
},
{
"Key": "graphql.selection.field.name",
@@ -303,12 +290,8 @@
"Value": "Human.friends"
},
{
- "Key": "graphql.selection.field.declaringType",
+ "Key": "graphql.selection.field.parent_type",
"Value": "Human"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
}
],
"event": []
@@ -318,7 +301,7 @@
]
},
{
- "OperationName": "FormatHttpResponse",
+ "OperationName": "Format HTTP Response",
"DisplayName": "Format HTTP Response",
"Status": "Ok",
"tags": [],
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_parser_error.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Post_Parser_Error.snap
similarity index 63%
rename from src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_parser_error.snap
rename to src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Post_Parser_Error.snap
index e33490a9a8c..774711bad83 100644
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_parser_error.snap
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Post_Parser_Error.snap
@@ -1,10 +1,14 @@
-{
+{
"activities": [
{
"OperationName": "ExecuteHttpRequest",
"DisplayName": "GraphQL HTTP POST",
"Status": "Ok",
"tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpPost"
+ },
{
"Key": "graphql.schema.name",
"Value": "_Default"
@@ -13,41 +17,37 @@
"event": [],
"activities": [
{
- "OperationName": "ParseHttpRequest",
+ "OperationName": "Parse HTTP Request",
"DisplayName": "Parse HTTP Request",
"Status": "Error",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "ERROR"
- }
- ],
+ "tags": [],
"event": [
{
"Name": "exception",
"Tags": [
{
- "Key": "exception.message",
+ "Key": "graphql.error.message",
"Value": "Found a NameStart character `n` (110) following a number, which is disallowed."
},
{
- "Key": "exception.type",
+ "Key": "graphql.error.code",
"Value": "HC0011"
},
{
- "Key": "graphql.error.location.column",
- "Value": 37
- },
- {
- "Key": "graphql.error.location.line",
- "Value": 10
+ "Key": "graphql.error.locations",
+ "Value": [
+ {
+ "line": 10,
+ "column": 37
+ }
+ ]
}
]
}
]
},
{
- "OperationName": "FormatHttpResponse",
+ "OperationName": "Format HTTP Response",
"DisplayName": "Format HTTP Response",
"Status": "Ok",
"tags": [],
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_add_query_to_http_activity.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Post_SingleRequest_GetHeroName.snap
similarity index 50%
rename from src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_add_query_to_http_activity.snap
rename to src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Post_SingleRequest_GetHeroName.snap
index ed74db6956e..5735177229f 100644
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_add_query_to_http_activity.snap
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Post_SingleRequest_GetHeroName.snap
@@ -5,6 +5,10 @@
"DisplayName": "GraphQL HTTP POST",
"Status": "Ok",
"tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpPost"
+ },
{
"Key": "graphql.schema.name",
"Value": "_Default"
@@ -12,38 +16,37 @@
{
"Key": "graphql.http.request.type",
"Value": "single"
+ },
+ {
+ "Key": "graphql.http.request.query.id",
+ "Value": "a570a6bff748b5916eadf153261d9c6d"
+ },
+ {
+ "Key": "graphql.http.request.query.hash",
+ "Value": "a570a6bff748b5916eadf153261d9c6d"
}
],
"event": [],
"activities": [
{
- "OperationName": "ParseHttpRequest",
+ "OperationName": "Parse HTTP Request",
"DisplayName": "Parse HTTP Request",
"Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
+ "tags": [],
"event": []
},
{
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { hero }",
- "Status": "Unset",
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
"tags": [
{
- "Key": "graphql.document.id",
- "Value": "1d4bca4d0dff630390ddf48e9085589d"
+ "Key": "graphql.operation.type",
+ "Value": "query"
},
{
"Key": "graphql.document.hash",
- "Value": "cc68dfd8c0c54a586a03c35296c5d1f9"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "_Default-1-1d4bca4d0dff630390ddf48e9085589d"
+ "Value": "md5:acb8d5d513c260b3cef3e3a12b0e29af"
}
],
"event": [
@@ -58,93 +61,97 @@
],
"activities": [
{
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
"Status": "Ok",
"tags": [
{
- "Key": "graphql.document.id",
- "Value": "1d4bca4d0dff630390ddf48e9085589d"
+ "Key": "graphql.processing.type",
+ "Value": "validate"
},
{
"Key": "graphql.document.hash",
- "Value": "cc68dfd8c0c54a586a03c35296c5d1f9"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "AnalyzeOperationCost",
- "DisplayName": "Analyze Operation Complexity",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.operation.id",
- "Value": "1d4bca4d0dff630390ddf48e9085589d"
+ "Value": "md5:acb8d5d513c260b3cef3e3a12b0e29af"
}
],
"event": []
},
{
- "OperationName": "CompileOperation",
- "DisplayName": "Compile Operation",
+ "OperationName": "GraphQL Complexity Analysis",
+ "DisplayName": "GraphQL Complexity Analysis",
"Status": "Ok",
"tags": [
{
- "Key": "otel.status_code",
- "Value": "OK"
+ "Key": "graphql.document.hash",
+ "Value": "md5:acb8d5d513c260b3cef3e3a12b0e29af"
+ },
+ {
+ "Key": "graphql.operation.fieldCost",
+ "Value": 1.0
+ },
+ {
+ "Key": "graphql.operation.typeCost",
+ "Value": 2.0
}
],
"event": []
},
{
- "OperationName": "CoerceVariables",
- "DisplayName": "Coerce Variable",
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
"Status": "Ok",
"tags": [
{
- "Key": "otel.status_code",
- "Value": "OK"
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:acb8d5d513c260b3cef3e3a12b0e29af"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
}
],
"event": []
},
{
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
"Status": "Ok",
"tags": [
{
- "Key": "otel.status_code",
- "Value": "OK"
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:acb8d5d513c260b3cef3e3a12b0e29af"
}
],
"event": [],
"activities": [
{
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/hero",
+ "OperationName": "Query.hero",
+ "DisplayName": "Query.hero",
"Status": "Ok",
"tags": [
{
- "Key": "graphql.selection.name",
- "Value": "hero"
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
},
{
- "Key": "graphql.selection.type",
- "Value": "Character"
+ "Key": "graphql.selection.name",
+ "Value": "hero"
},
{
"Key": "graphql.selection.path",
- "Value": "/hero"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/hero"
+ "Value": "hero"
},
{
"Key": "graphql.selection.field.name",
@@ -155,12 +162,8 @@
"Value": "Query.hero"
},
{
- "Key": "graphql.selection.field.declaringType",
+ "Key": "graphql.selection.field.parent_type",
"Value": "Query"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
}
],
"event": []
@@ -170,7 +173,7 @@
]
},
{
- "OperationName": "FormatHttpResponse",
+ "OperationName": "Format HTTP Response",
"DisplayName": "Format HTTP Response",
"Status": "Ok",
"tags": [],
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_SingleRequest_GetHeroName_Default.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Post_SingleRequest_GetHeroName_Default.snap
similarity index 57%
rename from src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_SingleRequest_GetHeroName_Default.snap
rename to src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Post_SingleRequest_GetHeroName_Default.snap
index f5cc8ff4b80..007fefef81a 100644
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_SingleRequest_GetHeroName_Default.snap
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Post_SingleRequest_GetHeroName_Default.snap
@@ -2,9 +2,13 @@
"activities": [
{
"OperationName": "ExecuteHttpRequest",
- "DisplayName": "query { hero }",
+ "DisplayName": "query",
"Status": "Ok",
"tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpPost"
+ },
{
"Key": "graphql.schema.name",
"Value": "_Default"
@@ -14,16 +18,20 @@
"Value": "single"
},
{
- "Key": "graphql.document.id",
+ "Key": "graphql.http.request.query.id",
"Value": "a570a6bff748b5916eadf153261d9c6d"
},
{
- "Key": "graphql.document.hash",
- "Value": "acb8d5d513c260b3cef3e3a12b0e29af"
+ "Key": "graphql.http.request.query.hash",
+ "Value": "a570a6bff748b5916eadf153261d9c6d"
},
{
- "Key": "graphql.operation.id",
- "Value": "_Default-1-a570a6bff748b5916eadf153261d9c6d"
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:acb8d5d513c260b3cef3e3a12b0e29af"
}
],
"event": [
@@ -38,69 +46,64 @@
],
"activities": [
{
- "OperationName": "ParseHttpRequest",
+ "OperationName": "Parse HTTP Request",
"DisplayName": "Parse HTTP Request",
"Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
+ "tags": [],
"event": []
},
{
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
"Status": "Ok",
"tags": [
{
- "Key": "graphql.document.id",
- "Value": "a570a6bff748b5916eadf153261d9c6d"
+ "Key": "graphql.processing.type",
+ "Value": "validate"
},
{
"Key": "graphql.document.hash",
- "Value": "acb8d5d513c260b3cef3e3a12b0e29af"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
+ "Value": "md5:acb8d5d513c260b3cef3e3a12b0e29af"
}
],
"event": []
},
{
- "OperationName": "CompileOperation",
- "DisplayName": "Compile Operation",
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
"Status": "Ok",
"tags": [
{
- "Key": "otel.status_code",
- "Value": "OK"
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:acb8d5d513c260b3cef3e3a12b0e29af"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
}
],
"event": []
},
{
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/hero",
+ "OperationName": "Query.hero",
+ "DisplayName": "Query.hero",
"Status": "Ok",
"tags": [
{
- "Key": "graphql.selection.name",
- "Value": "hero"
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
},
{
- "Key": "graphql.selection.type",
- "Value": "Character"
+ "Key": "graphql.selection.name",
+ "Value": "hero"
},
{
"Key": "graphql.selection.path",
- "Value": "/hero"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/hero"
+ "Value": "hero"
},
{
"Key": "graphql.selection.field.name",
@@ -111,18 +114,14 @@
"Value": "Query.hero"
},
{
- "Key": "graphql.selection.field.declaringType",
+ "Key": "graphql.selection.field.parent_type",
"Value": "Query"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
}
],
"event": []
},
{
- "OperationName": "FormatHttpResponse",
+ "OperationName": "Format HTTP Response",
"DisplayName": "Format HTTP Response",
"Status": "Ok",
"tags": [],
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Post_Variables_Are_Not_Automatically_Added_To_Activities.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Post_Variables_Are_Not_Automatically_Added_To_Activities.snap
new file mode 100644
index 00000000000..357e78284ce
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Post_Variables_Are_Not_Automatically_Added_To_Activities.snap
@@ -0,0 +1,205 @@
+{
+ "activities": [
+ {
+ "OperationName": "ExecuteHttpRequest",
+ "DisplayName": "GraphQL HTTP POST",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpPost"
+ },
+ {
+ "Key": "graphql.schema.name",
+ "Value": "_Default"
+ },
+ {
+ "Key": "graphql.http.request.type",
+ "Value": "single"
+ },
+ {
+ "Key": "graphql.http.request.query.id",
+ "Value": "1d4bca4d0dff630390ddf48e9085589d"
+ },
+ {
+ "Key": "graphql.http.request.query.hash",
+ "Value": "1d4bca4d0dff630390ddf48e9085589d"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "Parse HTTP Request",
+ "DisplayName": "Parse HTTP Request",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:cc68dfd8c0c54a586a03c35296c5d1f9"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:cc68dfd8c0c54a586a03c35296c5d1f9"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Complexity Analysis",
+ "DisplayName": "GraphQL Complexity Analysis",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:cc68dfd8c0c54a586a03c35296c5d1f9"
+ },
+ {
+ "Key": "graphql.operation.fieldCost",
+ "Value": 1.0
+ },
+ {
+ "Key": "graphql.operation.typeCost",
+ "Value": 2.0
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:cc68dfd8c0c54a586a03c35296c5d1f9"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Variable Coercion",
+ "DisplayName": "GraphQL Variable Coercion",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "variable_coercion"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:cc68dfd8c0c54a586a03c35296c5d1f9"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:cc68dfd8c0c54a586a03c35296c5d1f9"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "Query.hero",
+ "DisplayName": "Query.hero",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
+ },
+ {
+ "Key": "graphql.selection.name",
+ "Value": "hero"
+ },
+ {
+ "Key": "graphql.selection.path",
+ "Value": "hero"
+ },
+ {
+ "Key": "graphql.selection.field.name",
+ "Value": "hero"
+ },
+ {
+ "Key": "graphql.selection.field.coordinate",
+ "Value": "Query.hero"
+ },
+ {
+ "Key": "graphql.selection.field.parent_type",
+ "Value": "Query"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "OperationName": "Format HTTP Response",
+ "DisplayName": "Format HTTP Response",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Post_With_Extensions_Map.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Post_With_Extensions_Map.snap
new file mode 100644
index 00000000000..66aac757f7e
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.Http_Post_With_Extensions_Map.snap
@@ -0,0 +1,209 @@
+{
+ "activities": [
+ {
+ "OperationName": "ExecuteHttpRequest",
+ "DisplayName": "GraphQL HTTP POST",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpPost"
+ },
+ {
+ "Key": "graphql.schema.name",
+ "Value": "_Default"
+ },
+ {
+ "Key": "graphql.http.request.type",
+ "Value": "single"
+ },
+ {
+ "Key": "graphql.http.request.query.id",
+ "Value": "1d4bca4d0dff630390ddf48e9085589d"
+ },
+ {
+ "Key": "graphql.http.request.query.hash",
+ "Value": "1d4bca4d0dff630390ddf48e9085589d"
+ },
+ {
+ "Key": "graphql.http.request.extensions",
+ "Value": "{\"test\":\"abc\"}"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "Parse HTTP Request",
+ "DisplayName": "Parse HTTP Request",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:cc68dfd8c0c54a586a03c35296c5d1f9"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:cc68dfd8c0c54a586a03c35296c5d1f9"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Complexity Analysis",
+ "DisplayName": "GraphQL Complexity Analysis",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:cc68dfd8c0c54a586a03c35296c5d1f9"
+ },
+ {
+ "Key": "graphql.operation.fieldCost",
+ "Value": 1.0
+ },
+ {
+ "Key": "graphql.operation.typeCost",
+ "Value": 2.0
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:cc68dfd8c0c54a586a03c35296c5d1f9"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Variable Coercion",
+ "DisplayName": "GraphQL Variable Coercion",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "variable_coercion"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:cc68dfd8c0c54a586a03c35296c5d1f9"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:cc68dfd8c0c54a586a03c35296c5d1f9"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "Query.hero",
+ "DisplayName": "Query.hero",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
+ },
+ {
+ "Key": "graphql.selection.name",
+ "Value": "hero"
+ },
+ {
+ "Key": "graphql.selection.path",
+ "Value": "hero"
+ },
+ {
+ "Key": "graphql.selection.field.name",
+ "Value": "hero"
+ },
+ {
+ "Key": "graphql.selection.field.coordinate",
+ "Value": "Query.hero"
+ },
+ {
+ "Key": "graphql.selection.field.parent_type",
+ "Value": "Query"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "OperationName": "Format HTTP Response",
+ "DisplayName": "Format HTTP Response",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.RequestDetails_All_IncludesAllDetails.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.RequestDetails_All_IncludesAllDetails.snap
new file mode 100644
index 00000000000..3ae9d85ab7e
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.RequestDetails_All_IncludesAllDetails.snap
@@ -0,0 +1,233 @@
+{
+ "activities": [
+ {
+ "OperationName": "ExecuteHttpRequest",
+ "DisplayName": "GraphQL HTTP POST",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpPost"
+ },
+ {
+ "Key": "graphql.schema.name",
+ "Value": "_Default"
+ },
+ {
+ "Key": "graphql.http.request.type",
+ "Value": "single"
+ },
+ {
+ "Key": "graphql.http.request.query.id",
+ "Value": "b45805c675e9fff20b0367e5ff31735f"
+ },
+ {
+ "Key": "graphql.http.request.query.hash",
+ "Value": "b45805c675e9fff20b0367e5ff31735f"
+ },
+ {
+ "Key": "graphql.http.request.query.body",
+ "Value": "query GetHero(\n $episode: Episode!\n) {\n hero(episode: $episode) {\n name\n }\n}"
+ },
+ {
+ "Key": "graphql.http.request.variables",
+ "Value": "{\"episode\":\"NEW_HOPE\"}"
+ },
+ {
+ "Key": "graphql.http.request.extensions",
+ "Value": "{\"test\":\"abc\"}"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "Parse HTTP Request",
+ "DisplayName": "Parse HTTP Request",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetHero"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:9335388c19fd2e230b6294a596d13a93"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:9335388c19fd2e230b6294a596d13a93"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Complexity Analysis",
+ "DisplayName": "GraphQL Complexity Analysis",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:9335388c19fd2e230b6294a596d13a93"
+ },
+ {
+ "Key": "graphql.operation.fieldCost",
+ "Value": 1.0
+ },
+ {
+ "Key": "graphql.operation.typeCost",
+ "Value": 2.0
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:9335388c19fd2e230b6294a596d13a93"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetHero"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Variable Coercion",
+ "DisplayName": "GraphQL Variable Coercion",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "variable_coercion"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetHero"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:9335388c19fd2e230b6294a596d13a93"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetHero"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:9335388c19fd2e230b6294a596d13a93"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "Query.hero",
+ "DisplayName": "Query.hero",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
+ },
+ {
+ "Key": "graphql.selection.name",
+ "Value": "hero"
+ },
+ {
+ "Key": "graphql.selection.path",
+ "Value": "hero"
+ },
+ {
+ "Key": "graphql.selection.field.name",
+ "Value": "hero"
+ },
+ {
+ "Key": "graphql.selection.field.coordinate",
+ "Value": "Query.hero"
+ },
+ {
+ "Key": "graphql.selection.field.parent_type",
+ "Value": "Query"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "OperationName": "Format HTTP Response",
+ "DisplayName": "Format HTTP Response",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.RequestDetails_Default_IncludesIdHashOperationNameExtensions.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.RequestDetails_Default_IncludesIdHashOperationNameExtensions.snap
new file mode 100644
index 00000000000..62db38168d3
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.RequestDetails_Default_IncludesIdHashOperationNameExtensions.snap
@@ -0,0 +1,201 @@
+{
+ "activities": [
+ {
+ "OperationName": "ExecuteHttpRequest",
+ "DisplayName": "GraphQL HTTP POST",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpPost"
+ },
+ {
+ "Key": "graphql.schema.name",
+ "Value": "_Default"
+ },
+ {
+ "Key": "graphql.http.request.type",
+ "Value": "single"
+ },
+ {
+ "Key": "graphql.http.request.query.id",
+ "Value": "029e67e1b2d8493b3dd23fdaf6545b03"
+ },
+ {
+ "Key": "graphql.http.request.query.hash",
+ "Value": "029e67e1b2d8493b3dd23fdaf6545b03"
+ },
+ {
+ "Key": "graphql.http.request.extensions",
+ "Value": "{\"test\":\"abc\"}"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "Parse HTTP Request",
+ "DisplayName": "Parse HTTP Request",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetHero"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:06731ff10fea3ec8e9b2aabceee6ddd9"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:06731ff10fea3ec8e9b2aabceee6ddd9"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Complexity Analysis",
+ "DisplayName": "GraphQL Complexity Analysis",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:06731ff10fea3ec8e9b2aabceee6ddd9"
+ },
+ {
+ "Key": "graphql.operation.fieldCost",
+ "Value": 1.0
+ },
+ {
+ "Key": "graphql.operation.typeCost",
+ "Value": 2.0
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:06731ff10fea3ec8e9b2aabceee6ddd9"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetHero"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetHero"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:06731ff10fea3ec8e9b2aabceee6ddd9"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "Query.hero",
+ "DisplayName": "Query.hero",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
+ },
+ {
+ "Key": "graphql.selection.name",
+ "Value": "hero"
+ },
+ {
+ "Key": "graphql.selection.path",
+ "Value": "hero"
+ },
+ {
+ "Key": "graphql.selection.field.name",
+ "Value": "hero"
+ },
+ {
+ "Key": "graphql.selection.field.coordinate",
+ "Value": "Query.hero"
+ },
+ {
+ "Key": "graphql.selection.field.parent_type",
+ "Value": "Query"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "OperationName": "Format HTTP Response",
+ "DisplayName": "Format HTTP Response",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_with_extensions_map.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.RequestDetails_DocumentOnly_IncludesDocumentTag.snap
similarity index 51%
rename from src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_with_extensions_map.snap
rename to src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.RequestDetails_DocumentOnly_IncludesDocumentTag.snap
index 3b5136f879a..a8ba3e91332 100644
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_with_extensions_map.snap
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.RequestDetails_DocumentOnly_IncludesDocumentTag.snap
@@ -5,6 +5,10 @@
"DisplayName": "GraphQL HTTP POST",
"Status": "Ok",
"tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpPost"
+ },
{
"Key": "graphql.schema.name",
"Value": "_Default"
@@ -14,40 +18,31 @@
"Value": "single"
},
{
- "Key": "graphql.http.request.extensions",
- "Value": "{\"test\":\"abc\"}"
+ "Key": "graphql.http.request.query.body",
+ "Value": "{\n hero {\n name\n }\n}"
}
],
"event": [],
"activities": [
{
- "OperationName": "ParseHttpRequest",
+ "OperationName": "Parse HTTP Request",
"DisplayName": "Parse HTTP Request",
"Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
+ "tags": [],
"event": []
},
{
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { hero }",
- "Status": "Unset",
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
"tags": [
{
- "Key": "graphql.document.id",
- "Value": "1d4bca4d0dff630390ddf48e9085589d"
+ "Key": "graphql.operation.type",
+ "Value": "query"
},
{
"Key": "graphql.document.hash",
- "Value": "cc68dfd8c0c54a586a03c35296c5d1f9"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "_Default-1-1d4bca4d0dff630390ddf48e9085589d"
+ "Value": "md5:acb8d5d513c260b3cef3e3a12b0e29af"
}
],
"event": [
@@ -62,93 +57,97 @@
],
"activities": [
{
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
"Status": "Ok",
"tags": [
{
- "Key": "graphql.document.id",
- "Value": "1d4bca4d0dff630390ddf48e9085589d"
+ "Key": "graphql.processing.type",
+ "Value": "validate"
},
{
"Key": "graphql.document.hash",
- "Value": "cc68dfd8c0c54a586a03c35296c5d1f9"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
+ "Value": "md5:acb8d5d513c260b3cef3e3a12b0e29af"
}
],
"event": []
},
{
- "OperationName": "AnalyzeOperationCost",
- "DisplayName": "Analyze Operation Complexity",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.operation.id",
- "Value": "1d4bca4d0dff630390ddf48e9085589d"
- }
- ],
- "event": []
- },
- {
- "OperationName": "CompileOperation",
- "DisplayName": "Compile Operation",
+ "OperationName": "GraphQL Complexity Analysis",
+ "DisplayName": "GraphQL Complexity Analysis",
"Status": "Ok",
"tags": [
{
- "Key": "otel.status_code",
- "Value": "OK"
+ "Key": "graphql.document.hash",
+ "Value": "md5:acb8d5d513c260b3cef3e3a12b0e29af"
+ },
+ {
+ "Key": "graphql.operation.fieldCost",
+ "Value": 1.0
+ },
+ {
+ "Key": "graphql.operation.typeCost",
+ "Value": 2.0
}
],
"event": []
},
{
- "OperationName": "CoerceVariables",
- "DisplayName": "Coerce Variable",
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
"Status": "Ok",
"tags": [
{
- "Key": "otel.status_code",
- "Value": "OK"
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:acb8d5d513c260b3cef3e3a12b0e29af"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
}
],
"event": []
},
{
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
"Status": "Ok",
"tags": [
{
- "Key": "otel.status_code",
- "Value": "OK"
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:acb8d5d513c260b3cef3e3a12b0e29af"
}
],
"event": [],
"activities": [
{
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/hero",
+ "OperationName": "Query.hero",
+ "DisplayName": "Query.hero",
"Status": "Ok",
"tags": [
{
- "Key": "graphql.selection.name",
- "Value": "hero"
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
},
{
- "Key": "graphql.selection.type",
- "Value": "Character"
+ "Key": "graphql.selection.name",
+ "Value": "hero"
},
{
"Key": "graphql.selection.path",
- "Value": "/hero"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/hero"
+ "Value": "hero"
},
{
"Key": "graphql.selection.field.name",
@@ -159,12 +158,8 @@
"Value": "Query.hero"
},
{
- "Key": "graphql.selection.field.declaringType",
+ "Key": "graphql.selection.field.parent_type",
"Value": "Query"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
}
],
"event": []
@@ -174,7 +169,7 @@
]
},
{
- "OperationName": "FormatHttpResponse",
+ "OperationName": "Format HTTP Response",
"DisplayName": "Format HTTP Response",
"Status": "Ok",
"tags": [],
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.RequestDetails_None_ExcludesAllDetails.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.RequestDetails_None_ExcludesAllDetails.snap
new file mode 100644
index 00000000000..d79cffdd6df
--- /dev/null
+++ b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ActivityServerDiagnosticListenerTests.RequestDetails_None_ExcludesAllDetails.snap
@@ -0,0 +1,209 @@
+{
+ "activities": [
+ {
+ "OperationName": "ExecuteHttpRequest",
+ "DisplayName": "GraphQL HTTP POST",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpPost"
+ },
+ {
+ "Key": "graphql.schema.name",
+ "Value": "_Default"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "Parse HTTP Request",
+ "DisplayName": "Parse HTTP Request",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetHero"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:9335388c19fd2e230b6294a596d13a93"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:9335388c19fd2e230b6294a596d13a93"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Complexity Analysis",
+ "DisplayName": "GraphQL Complexity Analysis",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:9335388c19fd2e230b6294a596d13a93"
+ },
+ {
+ "Key": "graphql.operation.fieldCost",
+ "Value": 1.0
+ },
+ {
+ "Key": "graphql.operation.typeCost",
+ "Value": 2.0
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:9335388c19fd2e230b6294a596d13a93"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetHero"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Variable Coercion",
+ "DisplayName": "GraphQL Variable Coercion",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "variable_coercion"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetHero"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:9335388c19fd2e230b6294a596d13a93"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetHero"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:9335388c19fd2e230b6294a596d13a93"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "Query.hero",
+ "DisplayName": "Query.hero",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "resolve"
+ },
+ {
+ "Key": "graphql.selection.name",
+ "Value": "hero"
+ },
+ {
+ "Key": "graphql.selection.path",
+ "Value": "hero"
+ },
+ {
+ "Key": "graphql.selection.field.name",
+ "Value": "hero"
+ },
+ {
+ "Key": "graphql.selection.field.coordinate",
+ "Value": "Query.hero"
+ },
+ {
+ "Key": "graphql.selection.field.parent_type",
+ "Value": "Query"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "OperationName": "Format HTTP Response",
+ "DisplayName": "Format HTTP Response",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Allow_document_to_be_captured.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Allow_document_to_be_captured.snap
deleted file mode 100644
index 523e91ae3ae..00000000000
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Allow_document_to_be_captured.snap
+++ /dev/null
@@ -1,132 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query SayHelloOperation { sayHello }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "6af18618ae20c266f6ffc352b78cb69b"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "6af18618ae20c266f6ffc352b78cb69b"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "_Default-1-6af18618ae20c266f6ffc352b78cb69b"
- },
- {
- "Key": "graphql.operation.name",
- "Value": "SayHelloOperation"
- },
- {
- "Key": "graphql.document.body",
- "Value": "query SayHelloOperation {\n sayHello\n}"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseDocument",
- "DisplayName": "Parse Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "6af18618ae20c266f6ffc352b78cb69b"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "6af18618ae20c266f6ffc352b78cb69b"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "CompileOperation",
- "DisplayName": "Compile Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation SayHelloOperation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/sayHello",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.selection.name",
- "Value": "sayHello"
- },
- {
- "Key": "graphql.selection.type",
- "Value": "String!"
- },
- {
- "Key": "graphql.selection.path",
- "Value": "/sayHello"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/sayHello"
- },
- {
- "Key": "graphql.selection.field.name",
- "Value": "sayHello"
- },
- {
- "Key": "graphql.selection.field.coordinate",
- "Value": "SimpleQuery.sayHello"
- },
- {
- "Key": "graphql.selection.field.declaringType",
- "Value": "SimpleQuery"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Cause_a_resolver_error_that_deletes_the_whole_result.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Cause_a_resolver_error_that_deletes_the_whole_result.snap
deleted file mode 100644
index 121d1b09cd0..00000000000
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Cause_a_resolver_error_that_deletes_the_whole_result.snap
+++ /dev/null
@@ -1,154 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query SayHelloOperation { causeFatalError }",
- "Status": "Error",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "851fb754d9ba6b5cc5a55ebcbea2621d"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "851fb754d9ba6b5cc5a55ebcbea2621d"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "_Default-1-851fb754d9ba6b5cc5a55ebcbea2621d"
- },
- {
- "Key": "graphql.operation.name",
- "Value": "SayHelloOperation"
- },
- {
- "Key": "graphql.document.body",
- "Value": "query SayHelloOperation {\n causeFatalError\n}"
- },
- {
- "Key": "otel.status_code",
- "Value": "ERROR"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseDocument",
- "DisplayName": "Parse Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "851fb754d9ba6b5cc5a55ebcbea2621d"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "851fb754d9ba6b5cc5a55ebcbea2621d"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "CompileOperation",
- "DisplayName": "Compile Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation SayHelloOperation",
- "Status": "Error",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "ERROR"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/causeFatalError",
- "Status": "Error",
- "tags": [
- {
- "Key": "graphql.selection.name",
- "Value": "causeFatalError"
- },
- {
- "Key": "graphql.selection.type",
- "Value": "String!"
- },
- {
- "Key": "graphql.selection.path",
- "Value": "/causeFatalError"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/causeFatalError"
- },
- {
- "Key": "graphql.selection.field.name",
- "Value": "causeFatalError"
- },
- {
- "Key": "graphql.selection.field.coordinate",
- "Value": "SimpleQuery.causeFatalError"
- },
- {
- "Key": "graphql.selection.field.declaringType",
- "Value": "SimpleQuery"
- },
- {
- "Key": "otel.status_code",
- "Value": "ERROR"
- }
- ],
- "event": [
- {
- "Name": "exception",
- "Tags": [
- {
- "Key": "exception.message",
- "Value": "fail"
- },
- {
- "Key": "exception.type",
- "Value": "GRAPHQL_ERROR"
- },
- {
- "Key": "graphql.error.path",
- "Value": "/causeFatalError"
- }
- ]
- }
- ]
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Cause_a_resolver_error_that_deletes_the_whole_result_deep.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Cause_a_resolver_error_that_deletes_the_whole_result_deep.snap
deleted file mode 100644
index 158121c23ce..00000000000
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Cause_a_resolver_error_that_deletes_the_whole_result_deep.snap
+++ /dev/null
@@ -1,84 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "Execute Request",
- "Status": "Error",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "803df9346db185e9dc0b22dd3909aa70"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "803df9346db185e9dc0b22dd3909aa70"
- },
- {
- "Key": "graphql.document.body",
- "Value": "query SayHelloOperation {\n deep {\n deeper {\n deeps {\n deeper {\n causeFatalError\n }\n }\n }\n }\n}"
- },
- {
- "Key": "otel.status_code",
- "Value": "ERROR"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseDocument",
- "DisplayName": "Parse Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Error",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "ERROR"
- },
- {
- "Key": "graphql.document.id",
- "Value": "803df9346db185e9dc0b22dd3909aa70"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "803df9346db185e9dc0b22dd3909aa70"
- }
- ],
- "event": [
- {
- "Name": "exception",
- "Tags": [
- {
- "Key": "exception.message",
- "Value": "The field `causeFatalError` does not exist on the type `Deeper`."
- },
- {
- "Key": "exception.type",
- "Value": "GRAPHQL_ERROR"
- },
- {
- "Key": "graphql.error.location.column",
- "Value": 21
- },
- {
- "Key": "graphql.error.location.line",
- "Value": 6
- }
- ]
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Create_operation_display_name_with_1_field.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Create_operation_display_name_with_1_field.snap
deleted file mode 100644
index 4f621b6ca2d..00000000000
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Create_operation_display_name_with_1_field.snap
+++ /dev/null
@@ -1,124 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { a }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "452ea802c4d1bf2a81a7411b0b361d9f"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "452ea802c4d1bf2a81a7411b0b361d9f"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "_Default-1-452ea802c4d1bf2a81a7411b0b361d9f"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseDocument",
- "DisplayName": "Parse Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "452ea802c4d1bf2a81a7411b0b361d9f"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "452ea802c4d1bf2a81a7411b0b361d9f"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "CompileOperation",
- "DisplayName": "Compile Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/a",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.selection.name",
- "Value": "a"
- },
- {
- "Key": "graphql.selection.type",
- "Value": "String!"
- },
- {
- "Key": "graphql.selection.path",
- "Value": "/a"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/a"
- },
- {
- "Key": "graphql.selection.field.name",
- "Value": "sayHello"
- },
- {
- "Key": "graphql.selection.field.coordinate",
- "Value": "SimpleQuery.sayHello"
- },
- {
- "Key": "graphql.selection.field.declaringType",
- "Value": "SimpleQuery"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Create_operation_display_name_with_1_field_and_op.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Create_operation_display_name_with_1_field_and_op.snap
deleted file mode 100644
index 6adee85c424..00000000000
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Create_operation_display_name_with_1_field_and_op.snap
+++ /dev/null
@@ -1,128 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query GetA { a }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "cee0e2939ece72d650cb0331f4be4669"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "cee0e2939ece72d650cb0331f4be4669"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "_Default-1-cee0e2939ece72d650cb0331f4be4669"
- },
- {
- "Key": "graphql.operation.name",
- "Value": "GetA"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseDocument",
- "DisplayName": "Parse Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "cee0e2939ece72d650cb0331f4be4669"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "cee0e2939ece72d650cb0331f4be4669"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "CompileOperation",
- "DisplayName": "Compile Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation GetA",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/a",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.selection.name",
- "Value": "a"
- },
- {
- "Key": "graphql.selection.type",
- "Value": "String!"
- },
- {
- "Key": "graphql.selection.path",
- "Value": "/a"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/a"
- },
- {
- "Key": "graphql.selection.field.name",
- "Value": "sayHello"
- },
- {
- "Key": "graphql.selection.field.coordinate",
- "Value": "SimpleQuery.sayHello"
- },
- {
- "Key": "graphql.selection.field.declaringType",
- "Value": "SimpleQuery"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Create_operation_display_name_with_3_field.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Create_operation_display_name_with_3_field.snap
deleted file mode 100644
index 321f860a750..00000000000
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Create_operation_display_name_with_3_field.snap
+++ /dev/null
@@ -1,204 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { a b c }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "2e55fbe10a9e3ddf26935a8f8d15ec89"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "2e55fbe10a9e3ddf26935a8f8d15ec89"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "_Default-1-2e55fbe10a9e3ddf26935a8f8d15ec89"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseDocument",
- "DisplayName": "Parse Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "2e55fbe10a9e3ddf26935a8f8d15ec89"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "2e55fbe10a9e3ddf26935a8f8d15ec89"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "CompileOperation",
- "DisplayName": "Compile Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/a",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.selection.name",
- "Value": "a"
- },
- {
- "Key": "graphql.selection.type",
- "Value": "String!"
- },
- {
- "Key": "graphql.selection.path",
- "Value": "/a"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/a"
- },
- {
- "Key": "graphql.selection.field.name",
- "Value": "sayHello"
- },
- {
- "Key": "graphql.selection.field.coordinate",
- "Value": "SimpleQuery.sayHello"
- },
- {
- "Key": "graphql.selection.field.declaringType",
- "Value": "SimpleQuery"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/b",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.selection.name",
- "Value": "b"
- },
- {
- "Key": "graphql.selection.type",
- "Value": "String!"
- },
- {
- "Key": "graphql.selection.path",
- "Value": "/b"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/b"
- },
- {
- "Key": "graphql.selection.field.name",
- "Value": "sayHello"
- },
- {
- "Key": "graphql.selection.field.coordinate",
- "Value": "SimpleQuery.sayHello"
- },
- {
- "Key": "graphql.selection.field.declaringType",
- "Value": "SimpleQuery"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/c",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.selection.name",
- "Value": "c"
- },
- {
- "Key": "graphql.selection.type",
- "Value": "String!"
- },
- {
- "Key": "graphql.selection.path",
- "Value": "/c"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/c"
- },
- {
- "Key": "graphql.selection.field.name",
- "Value": "sayHello"
- },
- {
- "Key": "graphql.selection.field.coordinate",
- "Value": "SimpleQuery.sayHello"
- },
- {
- "Key": "graphql.selection.field.declaringType",
- "Value": "SimpleQuery"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Create_operation_display_name_with_4_field.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Create_operation_display_name_with_4_field.snap
deleted file mode 100644
index 677ff97b674..00000000000
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Create_operation_display_name_with_4_field.snap
+++ /dev/null
@@ -1,244 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { a b c ... }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "a5f924bb2f5f8651014e92e1cc2428c7"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "a5f924bb2f5f8651014e92e1cc2428c7"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "_Default-1-a5f924bb2f5f8651014e92e1cc2428c7"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseDocument",
- "DisplayName": "Parse Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "a5f924bb2f5f8651014e92e1cc2428c7"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "a5f924bb2f5f8651014e92e1cc2428c7"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "CompileOperation",
- "DisplayName": "Compile Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/a",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.selection.name",
- "Value": "a"
- },
- {
- "Key": "graphql.selection.type",
- "Value": "String!"
- },
- {
- "Key": "graphql.selection.path",
- "Value": "/a"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/a"
- },
- {
- "Key": "graphql.selection.field.name",
- "Value": "sayHello"
- },
- {
- "Key": "graphql.selection.field.coordinate",
- "Value": "SimpleQuery.sayHello"
- },
- {
- "Key": "graphql.selection.field.declaringType",
- "Value": "SimpleQuery"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/b",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.selection.name",
- "Value": "b"
- },
- {
- "Key": "graphql.selection.type",
- "Value": "String!"
- },
- {
- "Key": "graphql.selection.path",
- "Value": "/b"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/b"
- },
- {
- "Key": "graphql.selection.field.name",
- "Value": "sayHello"
- },
- {
- "Key": "graphql.selection.field.coordinate",
- "Value": "SimpleQuery.sayHello"
- },
- {
- "Key": "graphql.selection.field.declaringType",
- "Value": "SimpleQuery"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/c",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.selection.name",
- "Value": "c"
- },
- {
- "Key": "graphql.selection.type",
- "Value": "String!"
- },
- {
- "Key": "graphql.selection.path",
- "Value": "/c"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/c"
- },
- {
- "Key": "graphql.selection.field.name",
- "Value": "sayHello"
- },
- {
- "Key": "graphql.selection.field.coordinate",
- "Value": "SimpleQuery.sayHello"
- },
- {
- "Key": "graphql.selection.field.declaringType",
- "Value": "SimpleQuery"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/d",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.selection.name",
- "Value": "d"
- },
- {
- "Key": "graphql.selection.type",
- "Value": "String!"
- },
- {
- "Key": "graphql.selection.path",
- "Value": "/d"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/d"
- },
- {
- "Key": "graphql.selection.field.name",
- "Value": "sayHello"
- },
- {
- "Key": "graphql.selection.field.coordinate",
- "Value": "SimpleQuery.sayHello"
- },
- {
- "Key": "graphql.selection.field.declaringType",
- "Value": "SimpleQuery"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Ensure_operation_name_is_used_as_request_name.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Ensure_operation_name_is_used_as_request_name.snap
deleted file mode 100644
index b0ea2c00d2c..00000000000
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Ensure_operation_name_is_used_as_request_name.snap
+++ /dev/null
@@ -1,128 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query SayHelloOperation { sayHello }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "6af18618ae20c266f6ffc352b78cb69b"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "6af18618ae20c266f6ffc352b78cb69b"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "_Default-1-6af18618ae20c266f6ffc352b78cb69b"
- },
- {
- "Key": "graphql.operation.name",
- "Value": "SayHelloOperation"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseDocument",
- "DisplayName": "Parse Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "6af18618ae20c266f6ffc352b78cb69b"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "6af18618ae20c266f6ffc352b78cb69b"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "CompileOperation",
- "DisplayName": "Compile Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation SayHelloOperation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/sayHello",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.selection.name",
- "Value": "sayHello"
- },
- {
- "Key": "graphql.selection.type",
- "Value": "String!"
- },
- {
- "Key": "graphql.selection.path",
- "Value": "/sayHello"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/sayHello"
- },
- {
- "Key": "graphql.selection.field.name",
- "Value": "sayHello"
- },
- {
- "Key": "graphql.selection.field.coordinate",
- "Value": "SimpleQuery.sayHello"
- },
- {
- "Key": "graphql.selection.field.declaringType",
- "Value": "SimpleQuery"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Ensure_that_the_validation_activity_has_an_error_status.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Ensure_that_the_validation_activity_has_an_error_status.snap
deleted file mode 100644
index c13dbaa8b92..00000000000
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Ensure_that_the_validation_activity_has_an_error_status.snap
+++ /dev/null
@@ -1,84 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "Execute Request",
- "Status": "Error",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "bb1d246465341a97bdc727d6cd8ead5c"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "bb1d246465341a97bdc727d6cd8ead5c"
- },
- {
- "Key": "graphql.document.body",
- "Value": "query SayHelloOperation {\n sayHello_\n}"
- },
- {
- "Key": "otel.status_code",
- "Value": "ERROR"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseDocument",
- "DisplayName": "Parse Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Error",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "ERROR"
- },
- {
- "Key": "graphql.document.id",
- "Value": "bb1d246465341a97bdc727d6cd8ead5c"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "bb1d246465341a97bdc727d6cd8ead5c"
- }
- ],
- "event": [
- {
- "Name": "exception",
- "Tags": [
- {
- "Key": "exception.message",
- "Value": "The field `sayHello_` does not exist on the type `SimpleQuery`."
- },
- {
- "Key": "exception.type",
- "Value": "GRAPHQL_ERROR"
- },
- {
- "Key": "graphql.error.location.column",
- "Value": 27
- },
- {
- "Key": "graphql.error.location.line",
- "Value": 1
- }
- ]
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Track_data_loader_events.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Track_data_loader_events.snap
deleted file mode 100644
index 04ebef7195e..00000000000
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Track_data_loader_events.snap
+++ /dev/null
@@ -1,111 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "9b20745108c8de5afccc35cd56ead9fc"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "9b20745108c8de5afccc35cd56ead9fc"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "CompileOperation",
- "DisplayName": "Compile Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/dataLoader",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.selection.name",
- "Value": "dataLoader"
- },
- {
- "Key": "graphql.selection.type",
- "Value": "String"
- },
- {
- "Key": "graphql.selection.path",
- "Value": "/dataLoader"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/dataLoader"
- },
- {
- "Key": "graphql.selection.field.name",
- "Value": "dataLoader"
- },
- {
- "Key": "graphql.selection.field.coordinate",
- "Value": "SimpleQuery.dataLoader"
- },
- {
- "Key": "graphql.selection.field.declaringType",
- "Value": "SimpleQuery"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "BatchCoordinator",
- "DisplayName": "Coordinate DataLoader Batches",
- "Status": "Unset",
- "tags": [],
- "event": [
- {
- "Name": "BatchEvaluated",
- "Tags": [
- {
- "Key": "openBatches",
- "Value": 1
- }
- ]
- },
- {
- "Name": "BatchDispatched",
- "Tags": [
- {
- "Key": "dispatchedBatches",
- "Value": 1
- }
- ]
- }
- ],
- "activities": [
- {
- "OperationName": "ExecuteBatch",
- "DisplayName": "Execute CustomDataLoader Batch",
- "Status": "Unset",
- "tags": [],
- "event": []
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Track_data_loader_events_with_keys.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Track_data_loader_events_with_keys.snap
deleted file mode 100644
index 04ebef7195e..00000000000
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Track_data_loader_events_with_keys.snap
+++ /dev/null
@@ -1,111 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "9b20745108c8de5afccc35cd56ead9fc"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "9b20745108c8de5afccc35cd56ead9fc"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "CompileOperation",
- "DisplayName": "Compile Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/dataLoader",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.selection.name",
- "Value": "dataLoader"
- },
- {
- "Key": "graphql.selection.type",
- "Value": "String"
- },
- {
- "Key": "graphql.selection.path",
- "Value": "/dataLoader"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/dataLoader"
- },
- {
- "Key": "graphql.selection.field.name",
- "Value": "dataLoader"
- },
- {
- "Key": "graphql.selection.field.coordinate",
- "Value": "SimpleQuery.dataLoader"
- },
- {
- "Key": "graphql.selection.field.declaringType",
- "Value": "SimpleQuery"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "BatchCoordinator",
- "DisplayName": "Coordinate DataLoader Batches",
- "Status": "Unset",
- "tags": [],
- "event": [
- {
- "Name": "BatchEvaluated",
- "Tags": [
- {
- "Key": "openBatches",
- "Value": 1
- }
- ]
- },
- {
- "Name": "BatchDispatched",
- "Tags": [
- {
- "Key": "dispatchedBatches",
- "Value": 1
- }
- ]
- }
- ],
- "activities": [
- {
- "OperationName": "ExecuteBatch",
- "DisplayName": "Execute CustomDataLoader Batch",
- "Status": "Unset",
- "tags": [],
- "event": []
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Track_events_of_a_simple_query_detailed.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Track_events_of_a_simple_query_detailed.snap
deleted file mode 100644
index d528c17e108..00000000000
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Track_events_of_a_simple_query_detailed.snap
+++ /dev/null
@@ -1,124 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { sayHello }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "_Default-1-f7e9989fbb67af7fa747a9983313c9e5"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseDocument",
- "DisplayName": "Parse Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "CompileOperation",
- "DisplayName": "Compile Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/sayHello",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.selection.name",
- "Value": "sayHello"
- },
- {
- "Key": "graphql.selection.type",
- "Value": "String!"
- },
- {
- "Key": "graphql.selection.path",
- "Value": "/sayHello"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/sayHello"
- },
- {
- "Key": "graphql.selection.field.name",
- "Value": "sayHello"
- },
- {
- "Key": "graphql.selection.field.coordinate",
- "Value": "SimpleQuery.sayHello"
- },
- {
- "Key": "graphql.selection.field.declaringType",
- "Value": "SimpleQuery"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Get_SingleRequest_GetHeroName.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Get_SingleRequest_GetHeroName.snap
deleted file mode 100644
index 8f7af550618..00000000000
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Get_SingleRequest_GetHeroName.snap
+++ /dev/null
@@ -1,170 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteHttpRequest",
- "DisplayName": "GraphQL HTTP GET",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.schema.name",
- "Value": "_Default"
- },
- {
- "Key": "graphql.http.request.type",
- "Value": "single"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseHttpRequest",
- "DisplayName": "Parse HTTP Request",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { hero }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "530cb46cabc38757c74c05cc7a96b636"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "acb8d5d513c260b3cef3e3a12b0e29af"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "_Default-1-530cb46cabc38757c74c05cc7a96b636"
- }
- ],
- "event": [
- {
- "Name": "AddedOperationToCache",
- "Tags": []
- },
- {
- "Name": "AddedDocumentToCache",
- "Tags": []
- }
- ],
- "activities": [
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "530cb46cabc38757c74c05cc7a96b636"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "acb8d5d513c260b3cef3e3a12b0e29af"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "AnalyzeOperationCost",
- "DisplayName": "Analyze Operation Complexity",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.operation.id",
- "Value": "530cb46cabc38757c74c05cc7a96b636"
- }
- ],
- "event": []
- },
- {
- "OperationName": "CompileOperation",
- "DisplayName": "Compile Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/hero",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.selection.name",
- "Value": "hero"
- },
- {
- "Key": "graphql.selection.type",
- "Value": "Character"
- },
- {
- "Key": "graphql.selection.path",
- "Value": "/hero"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/hero"
- },
- {
- "Key": "graphql.selection.field.name",
- "Value": "hero"
- },
- {
- "Key": "graphql.selection.field.coordinate",
- "Value": "Query.hero"
- },
- {
- "Key": "graphql.selection.field.declaringType",
- "Value": "Query"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- },
- {
- "OperationName": "FormatHttpResponse",
- "DisplayName": "Format HTTP Response",
- "Status": "Ok",
- "tags": [],
- "event": []
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_SingleRequest_GetHeroName.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_SingleRequest_GetHeroName.snap
deleted file mode 100644
index ea5e73977d3..00000000000
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_SingleRequest_GetHeroName.snap
+++ /dev/null
@@ -1,170 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteHttpRequest",
- "DisplayName": "GraphQL HTTP POST",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.schema.name",
- "Value": "_Default"
- },
- {
- "Key": "graphql.http.request.type",
- "Value": "single"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseHttpRequest",
- "DisplayName": "Parse HTTP Request",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { hero }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "a570a6bff748b5916eadf153261d9c6d"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "acb8d5d513c260b3cef3e3a12b0e29af"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "_Default-1-a570a6bff748b5916eadf153261d9c6d"
- }
- ],
- "event": [
- {
- "Name": "AddedOperationToCache",
- "Tags": []
- },
- {
- "Name": "AddedDocumentToCache",
- "Tags": []
- }
- ],
- "activities": [
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "a570a6bff748b5916eadf153261d9c6d"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "acb8d5d513c260b3cef3e3a12b0e29af"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "AnalyzeOperationCost",
- "DisplayName": "Analyze Operation Complexity",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.operation.id",
- "Value": "a570a6bff748b5916eadf153261d9c6d"
- }
- ],
- "event": []
- },
- {
- "OperationName": "CompileOperation",
- "DisplayName": "Compile Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/hero",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.selection.name",
- "Value": "hero"
- },
- {
- "Key": "graphql.selection.type",
- "Value": "Character"
- },
- {
- "Key": "graphql.selection.path",
- "Value": "/hero"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/hero"
- },
- {
- "Key": "graphql.selection.field.name",
- "Value": "hero"
- },
- {
- "Key": "graphql.selection.field.coordinate",
- "Value": "Query.hero"
- },
- {
- "Key": "graphql.selection.field.declaringType",
- "Value": "Query"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- },
- {
- "OperationName": "FormatHttpResponse",
- "DisplayName": "Format HTTP Response",
- "Status": "Ok",
- "tags": [],
- "event": []
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_variables_are_not_automatically_added_to_activities.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_variables_are_not_automatically_added_to_activities.snap
deleted file mode 100644
index ed74db6956e..00000000000
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_variables_are_not_automatically_added_to_activities.snap
+++ /dev/null
@@ -1,182 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteHttpRequest",
- "DisplayName": "GraphQL HTTP POST",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.schema.name",
- "Value": "_Default"
- },
- {
- "Key": "graphql.http.request.type",
- "Value": "single"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseHttpRequest",
- "DisplayName": "Parse HTTP Request",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { hero }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "1d4bca4d0dff630390ddf48e9085589d"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "cc68dfd8c0c54a586a03c35296c5d1f9"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "_Default-1-1d4bca4d0dff630390ddf48e9085589d"
- }
- ],
- "event": [
- {
- "Name": "AddedOperationToCache",
- "Tags": []
- },
- {
- "Name": "AddedDocumentToCache",
- "Tags": []
- }
- ],
- "activities": [
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "1d4bca4d0dff630390ddf48e9085589d"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "cc68dfd8c0c54a586a03c35296c5d1f9"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "AnalyzeOperationCost",
- "DisplayName": "Analyze Operation Complexity",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.operation.id",
- "Value": "1d4bca4d0dff630390ddf48e9085589d"
- }
- ],
- "event": []
- },
- {
- "OperationName": "CompileOperation",
- "DisplayName": "Compile Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "CoerceVariables",
- "DisplayName": "Coerce Variable",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ResolveFieldValue",
- "DisplayName": "/hero",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.selection.name",
- "Value": "hero"
- },
- {
- "Key": "graphql.selection.type",
- "Value": "Character"
- },
- {
- "Key": "graphql.selection.path",
- "Value": "/hero"
- },
- {
- "Key": "graphql.selection.hierarchy",
- "Value": "/hero"
- },
- {
- "Key": "graphql.selection.field.name",
- "Value": "hero"
- },
- {
- "Key": "graphql.selection.field.coordinate",
- "Value": "Query.hero"
- },
- {
- "Key": "graphql.selection.field.declaringType",
- "Value": "Query"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- },
- {
- "OperationName": "FormatHttpResponse",
- "DisplayName": "Format HTTP Response",
- "Status": "Ok",
- "tags": [],
- "event": []
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Parsing_error_when_rename_root_is_activated.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Parsing_error_when_rename_root_is_activated.snap
deleted file mode 100644
index b0834861a59..00000000000
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Parsing_error_when_rename_root_is_activated.snap
+++ /dev/null
@@ -1,59 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteHttpRequest",
- "DisplayName": "GraphQL HTTP POST: Begin Parse HTTP Request",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.schema.name",
- "Value": "_Default"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseHttpRequest",
- "DisplayName": "Parse HTTP Request",
- "Status": "Error",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "ERROR"
- }
- ],
- "event": [
- {
- "Name": "exception",
- "Tags": [
- {
- "Key": "exception.message",
- "Value": "Expected a `Name`-token, but found a `Integer`-token."
- },
- {
- "Key": "exception.type",
- "Value": "HC0011"
- },
- {
- "Key": "graphql.error.location.column",
- "Value": 21
- },
- {
- "Key": "graphql.error.location.line",
- "Value": 3
- }
- ]
- }
- ]
- },
- {
- "OperationName": "FormatHttpResponse",
- "DisplayName": "Format HTTP Response",
- "Status": "Ok",
- "tags": [],
- "event": []
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Validation_error_when_rename_root_is_activated.snap b/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Validation_error_when_rename_root_is_activated.snap
deleted file mode 100644
index 97a0396c0dc..00000000000
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Validation_error_when_rename_root_is_activated.snap
+++ /dev/null
@@ -1,105 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteHttpRequest",
- "DisplayName": "GraphQL HTTP POST: Begin Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.schema.name",
- "Value": "_Default"
- },
- {
- "Key": "graphql.http.request.type",
- "Value": "single"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseHttpRequest",
- "DisplayName": "Parse HTTP Request",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "Execute Request",
- "Status": "Error",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "e2b13c5332af8a70da160fcb96894e5c"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "346f68539881f0624dca2927281d1a2f"
- },
- {
- "Key": "otel.status_code",
- "Value": "ERROR"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Error",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "ERROR"
- },
- {
- "Key": "graphql.document.id",
- "Value": "e2b13c5332af8a70da160fcb96894e5c"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "346f68539881f0624dca2927281d1a2f"
- }
- ],
- "event": [
- {
- "Name": "exception",
- "Tags": [
- {
- "Key": "exception.message",
- "Value": "The field `abc` does not exist on the type `Query`."
- },
- {
- "Key": "exception.type",
- "Value": "GRAPHQL_ERROR"
- },
- {
- "Key": "graphql.error.location.column",
- "Value": 21
- },
- {
- "Key": "graphql.error.location.line",
- "Value": 3
- }
- ]
- }
- ]
- }
- ]
- },
- {
- "OperationName": "FormatHttpResponse",
- "DisplayName": "Format HTTP Response",
- "Status": "Ok",
- "tags": [],
- "event": []
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Aspire/SchemaComposition.cs b/src/HotChocolate/Fusion/src/Fusion.Aspire/SchemaComposition.cs
index e490475a394..8fc4e228186 100644
--- a/src/HotChocolate/Fusion/src/Fusion.Aspire/SchemaComposition.cs
+++ b/src/HotChocolate/Fusion/src/Fusion.Aspire/SchemaComposition.cs
@@ -7,6 +7,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
+using IOPath = System.IO.Path;
namespace HotChocolate.Fusion.Aspire;
@@ -94,7 +95,7 @@ private async Task ComposeSchemaAsync(
try
{
var gatewayDirectory = GetProjectPath(compositionResource)!;
- var archivePath = Path.Combine(Path.GetDirectoryName(gatewayDirectory)!, settings.OutputFileName);
+ var archivePath = IOPath.Combine(IOPath.GetDirectoryName(gatewayDirectory)!, settings.OutputFileName);
return await ComposeSchemaAsync(archivePath, sourceSchemas, settings, cancellationToken);
}
finally
@@ -277,7 +278,7 @@ private List GetReferencedResources(
// For file schemas, settings file is named after the schema file
// e.g., "foo.graphql" -> "foo-settings.json"
var schemaFileName = annotation.SchemaPath ?? "schema.graphql";
- var settingsFileName = $"{Path.GetFileNameWithoutExtension(schemaFileName)}-settings.json";
+ var settingsFileName = $"{IOPath.GetFileNameWithoutExtension(schemaFileName)}-settings.json";
var schemaSettings = await GetSourceSchemaSettingsAsync(resource, settingsFileName, cancellationToken);
if (schemaSettings == null)
@@ -309,8 +310,8 @@ private List GetReferencedResources(
return null;
}
- var projectDirectory = Path.GetDirectoryName(projectPath);
- var settingsFile = Path.Combine(projectDirectory!, settingsFileName);
+ var projectDirectory = IOPath.GetDirectoryName(projectPath);
+ var settingsFile = IOPath.Combine(projectDirectory!, settingsFileName);
if (!File.Exists(settingsFile))
{
@@ -373,8 +374,8 @@ private List GetReferencedResources(
return null;
}
- var projectDirectory = Path.GetDirectoryName(projectPath);
- var schemaFile = Path.Combine(projectDirectory!, fileName ?? "schema.graphql");
+ var projectDirectory = IOPath.GetDirectoryName(projectPath);
+ var schemaFile = IOPath.Combine(projectDirectory!, fileName ?? "schema.graphql");
if (!File.Exists(schemaFile))
{
@@ -487,7 +488,7 @@ private async Task ComposeSchemaAsync(
GraphQLSchemaCompositionAnnotation settings,
CancellationToken cancellationToken)
{
- var tempArchivePath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
+ var tempArchivePath = IOPath.Combine(IOPath.GetTempPath(), IOPath.GetRandomFileName());
try
{
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/ContextKeys.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/ContextKeys.cs
deleted file mode 100644
index f35bd4946f0..00000000000
--- a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/ContextKeys.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace HotChocolate.Fusion.Diagnostics;
-
-internal static class ContextKeys
-{
- public const string HttpRequestActivity = "HotChocolate.Fusion.Diagnostics.HttpRequest";
- public const string ParseHttpRequestActivity = "HotChocolate.Fusion.Diagnostics.ParseHttpRequest";
- public const string FormatHttpResponseActivity = "HotChocolate.Fusion.Diagnostics.FormatHttpResponse";
- public const string RequestActivity = "HotChocolate.Fusion.Diagnostics.Request";
- public const string ValidateActivity = "HotChocolate.Fusion.Diagnostics.Validate";
-}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Extensions/DiagnosticsFusionGatewayBuilderExtensions.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Extensions/DiagnosticsFusionGatewayBuilderExtensions.cs
index 689f319827a..d475f4fd2a6 100644
--- a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Extensions/DiagnosticsFusionGatewayBuilderExtensions.cs
+++ b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Extensions/DiagnosticsFusionGatewayBuilderExtensions.cs
@@ -35,13 +35,13 @@ public static IFusionGatewayBuilder AddInstrumentation(
builder.AddApplicationService();
builder.AddDiagnosticEventListener(
- sp => new ActivityFusionExecutionDiagnosticEventListener(
+ sp => new FusionActivityExecutionDiagnosticEventListener(
sp.GetService() ??
sp.GetRequiredService(),
sp.GetRequiredService()));
builder.AddDiagnosticEventListener(
- sp => new ActivityServerDiagnosticListener(
+ sp => new FusionActivityServerDiagnosticListener(
sp.GetService() ??
sp.GetRequiredService(),
sp.GetRequiredService()));
@@ -49,8 +49,5 @@ public static IFusionGatewayBuilder AddInstrumentation(
return builder;
}
- private sealed class InternalActivityEnricher(
- ObjectPool stringBuilderPool,
- InstrumentationOptions options)
- : FusionActivityEnricher(stringBuilderPool, options);
+ private sealed class InternalActivityEnricher(InstrumentationOptions options) : FusionActivityEnricher(options);
}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/FusionActivityEnricher.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/FusionActivityEnricher.cs
index e5afc4e0c28..8a430c4b744 100644
--- a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/FusionActivityEnricher.cs
+++ b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/FusionActivityEnricher.cs
@@ -1,592 +1,78 @@
using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Text;
-using System.Text.Json;
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.ObjectPool;
-using HotChocolate.AspNetCore.Instrumentation;
+using HotChocolate.Diagnostics;
using HotChocolate.Execution;
using HotChocolate.Fusion.Execution;
using HotChocolate.Fusion.Execution.Nodes;
-using HotChocolate.Language;
-using HotChocolate.Language.Utilities;
-using OpenTelemetry.Trace;
-using static HotChocolate.Fusion.Diagnostics.SemanticConventions;
-using static HotChocolate.WellKnownContextData;
namespace HotChocolate.Fusion.Diagnostics;
///
-/// The activity enricher is used to add information to the activity spans.
-/// You can inherit from this class and override the enricher methods to provide more or
-/// less information.
+/// The activity enricher allows adding additional information to the activity spans
+/// created by the Fusion diagnostics system.
+/// You can inherit from this class and override the enricher methods to add
+/// additional information to the spans.
///
-public class FusionActivityEnricher
+public class FusionActivityEnricher(InstrumentationOptions options) : ActivityEnricherBase
{
- private readonly InstrumentationOptions _options;
- private readonly ConditionalWeakTable _queryCache = [];
+ protected InstrumentationOptions Options { get; } = options;
- ///
- /// Initializes a new instance of .
- ///
- ///
- ///
- protected FusionActivityEnricher(
- ObjectPool stringBuilderPool,
- InstrumentationOptions options)
- {
- StringBuilderPool = stringBuilderPool;
- _options = options;
- }
-
- ///
- /// Gets the pool used by this enricher.
- ///
- protected ObjectPool StringBuilderPool { get; }
-
- public virtual void EnrichExecuteHttpRequest(
- HttpContext context,
- HttpRequestKind kind,
- Activity activity)
- {
- switch (kind)
- {
- case HttpRequestKind.HttpPost:
- activity.DisplayName = "GraphQL HTTP POST";
- break;
- case HttpRequestKind.HttpMultiPart:
- activity.DisplayName = "GraphQL HTTP POST MultiPart";
- break;
- case HttpRequestKind.HttpGet:
- activity.DisplayName = "GraphQL HTTP GET";
- break;
- case HttpRequestKind.HttpGetSchema:
- activity.DisplayName = "GraphQL HTTP GET SDL";
- break;
- }
-
- if (_options.RenameRootActivity)
- {
- UpdateRootActivityName(activity, $"Begin {activity.DisplayName}");
- }
-
- activity.SetTag("graphql.http.kind", kind);
-
- var isDefault = false;
- if (!(context.Items.TryGetValue(SchemaName, out var value)
- && value is string schemaName))
- {
- schemaName = ISchemaDefinition.DefaultName;
- isDefault = true;
- }
-
- activity.SetTag("graphql.schema.name", schemaName);
- activity.SetTag("graphql.schema.isDefault", isDefault);
- }
-
- public virtual void EnrichSingleRequest(
- HttpContext context,
- GraphQLRequest request,
- Activity activity)
- {
- activity.SetTag("graphql.http.request.type", "single");
-
- if (request.DocumentId is not null
- && (_options.RequestDetails & RequestDetails.Id) == RequestDetails.Id)
- {
- activity.SetTag("graphql.http.request.query.id", request.DocumentId.Value);
- }
-
- if (request.DocumentHash is not null
- && (_options.RequestDetails & RequestDetails.Hash) == RequestDetails.Hash)
- {
- activity.SetTag("graphql.http.request.query.hash", request.DocumentHash.Value);
- }
-
- if (request.Document is not null
- && (_options.RequestDetails & RequestDetails.Query) == RequestDetails.Query)
- {
- if (!_queryCache.TryGetValue(request.Document, out var query))
- {
- query = request.Document.Print();
- _queryCache.Add(request.Document, query);
- }
-
- activity.SetTag("graphql.http.request.query.body", query);
- }
-
- if (request.OperationName is not null
- && (_options.RequestDetails & RequestDetails.Operation) == RequestDetails.Operation)
- {
- activity.SetTag("graphql.http.request.operation", request.OperationName);
- }
-
- if (request.Variables is not null
- && (_options.RequestDetails & RequestDetails.Variables) == RequestDetails.Variables)
- {
- EnrichRequestVariables(context, request, request.Variables, activity);
- }
-
- if (request.Extensions is not null
- && (_options.RequestDetails & RequestDetails.Extensions) == RequestDetails.Extensions)
- {
- EnrichRequestExtensions(context, request, request.Extensions, activity);
- }
- }
-
- public virtual void EnrichBatchRequest(
- HttpContext context,
- IReadOnlyList batch,
- Activity activity)
- {
- activity.SetTag("graphql.http.request.type", "batch");
-
- for (var i = 0; i < batch.Count; i++)
- {
- var request = batch[i];
-
- if (request.DocumentId is not null
- && (_options.RequestDetails & RequestDetails.Id) == RequestDetails.Id)
- {
- activity.SetTag($"graphql.http.request[{i}].query.id", request.DocumentId.Value);
- }
-
- if (request.DocumentHash is not null
- && (_options.RequestDetails & RequestDetails.Hash) == RequestDetails.Hash)
- {
- activity.SetTag($"graphql.http.request[{i}].query.hash", request.DocumentHash.Value);
- }
-
- if (request.Document is not null
- && (_options.RequestDetails & RequestDetails.Query) == RequestDetails.Query)
- {
- activity.SetTag($"graphql.http.request[{i}].query.body", request.Document.Print());
- }
-
- if (request.OperationName is not null
- && (_options.RequestDetails & RequestDetails.Operation) == RequestDetails.Operation)
- {
- activity.SetTag($"graphql.http.request[{i}].operation", request.OperationName);
- }
-
- if (request.Variables is not null
- && (_options.RequestDetails & RequestDetails.Variables) == RequestDetails.Variables)
- {
- EnrichBatchVariables(context, request, request.Variables, i, activity);
- }
-
- if (request.Extensions is not null
- && (_options.RequestDetails & RequestDetails.Extensions) == RequestDetails.Extensions)
- {
- EnrichBatchExtensions(context, request, request.Extensions, i, activity);
- }
- }
- }
-
- public virtual void EnrichOperationBatchRequest(
- HttpContext context,
- GraphQLRequest request,
- IReadOnlyList operations,
- Activity activity)
- {
- activity.SetTag("graphql.http.request.type", "operationBatch");
-
- if (request.DocumentId is not null
- && (_options.RequestDetails & RequestDetails.Id) == RequestDetails.Id)
- {
- activity.SetTag("graphql.http.request.query.id", request.DocumentId.Value);
- }
-
- if (request.DocumentHash is not null
- && (_options.RequestDetails & RequestDetails.Hash) == RequestDetails.Hash)
- {
- activity.SetTag("graphql.http.request.query.hash", request.DocumentHash.Value);
- }
-
- if (request.Document is not null
- && (_options.RequestDetails & RequestDetails.Query) == RequestDetails.Query)
- {
- activity.SetTag("graphql.http.request.query.body", request.Document.Print());
- }
-
- if (request.OperationName is not null
- && (_options.RequestDetails & RequestDetails.Operation) == RequestDetails.Operation)
- {
- activity.SetTag("graphql.http.request.operations", string.Join(" -> ", operations));
- }
-
- if (request.Variables is not null
- && (_options.RequestDetails & RequestDetails.Variables) == RequestDetails.Variables)
- {
- EnrichRequestVariables(context, request, request.Variables, activity);
- }
-
- if (request.Extensions is not null
- && (_options.RequestDetails & RequestDetails.Extensions) == RequestDetails.Extensions)
- {
- EnrichRequestExtensions(context, request, request.Extensions, activity);
- }
- }
-
- protected virtual void EnrichRequestVariables(
- HttpContext context,
- GraphQLRequest request,
- JsonDocument variables,
- Activity activity)
- {
- activity.SetTag("graphql.http.request.variables", variables.RootElement.ToString());
- }
-
- protected virtual void EnrichBatchVariables(
- HttpContext context,
- GraphQLRequest request,
- JsonDocument variables,
- int index,
- Activity activity)
- {
- activity.SetTag($"graphql.http.request[{index}].variables", variables.RootElement.ToString());
- }
-
- protected virtual void EnrichRequestExtensions(
- HttpContext context,
- GraphQLRequest request,
- JsonDocument extensions,
+ public virtual void EnrichPlanOperation(
+ RequestContext context,
+ string operationPlanId,
Activity activity)
{
- try
- {
- activity.SetTag(
- "graphql.http.request.extensions",
- extensions.RootElement.ToString());
- }
- catch
- {
- // Ignore any errors
- }
}
- protected virtual void EnrichBatchExtensions(
- HttpContext context,
- GraphQLRequest request,
- JsonDocument extensions,
- int index,
+ public virtual void EnrichExecutePlanNode(
+ OperationPlanContext context,
+ ExecutionNode node,
+ string? schemaName,
Activity activity)
{
- try
- {
- activity.SetTag(
- $"graphql.http.request[{index}].extensions",
- extensions.RootElement.ToString());
- }
- catch
- {
- // Ignore any errors
- }
}
- public virtual void EnrichHttpRequestError(
- HttpContext context,
- IError error,
- Activity activity)
- => EnrichError(error, activity);
-
- public virtual void EnrichHttpRequestError(
- HttpContext context,
+ public virtual void EnrichExecutionNodeError(
+ OperationPlanContext context,
+ ExecutionNode node,
Exception exception,
Activity activity)
{
}
- public virtual void EnrichParseHttpRequest(HttpContext context, Activity activity)
- {
- activity.DisplayName = "Parse HTTP Request";
-
- if (_options.RenameRootActivity)
- {
- UpdateRootActivityName(activity, $"Begin {activity.DisplayName}");
- }
- }
-
- public virtual void EnrichParserErrors(HttpContext context, IError error, Activity activity)
- => EnrichError(error, activity);
-
- public virtual void EnrichFormatHttpResponse(HttpContext context, Activity activity)
- {
- activity.DisplayName = "Format HTTP Response";
- }
-
- public virtual void EnrichExecuteRequest(RequestContext context, Activity activity)
- {
- var plan = context.GetOperationPlan();
- var documentInfo = context.OperationDocumentInfo;
- var operationDisplayName = CreateOperationDisplayName(context, plan);
-
- if (_options.RenameRootActivity && operationDisplayName is not null)
- {
- UpdateRootActivityName(activity, operationDisplayName);
- }
-
- activity.DisplayName = operationDisplayName ?? "Execute Request";
- activity.SetTag("graphql.document.id", documentInfo.Id.Value);
- activity.SetTag("graphql.document.hash", documentInfo.Hash.Value);
- activity.SetTag("graphql.document.valid", documentInfo.IsValidated);
- activity.SetTag("graphql.operation.id", plan?.Id);
- activity.SetTag("graphql.operation.kind", plan?.Operation.Definition.Operation);
- activity.SetTag("graphql.operation.name", plan?.OperationName);
-
- if (_options.IncludeDocument && documentInfo.Document is not null)
- {
- activity.SetTag("graphql.document.body", documentInfo.Document.Print());
- }
-
- if (context.Result is OperationResult { Errors: [_, ..] errors })
- {
- activity.SetTag("graphql.errors.count", errors.Count);
- }
- }
-
- protected virtual string? CreateOperationDisplayName(RequestContext context, OperationPlan? plan)
- {
- if (plan is null)
- {
- return null;
- }
-
- var displayName = StringBuilderPool.Get();
-
- try
- {
- var rootSelectionSet = plan.Operation.RootSelectionSet;
- var selectionCount = rootSelectionSet.Selections.Length;
-
- displayName.Append('{');
- displayName.Append(' ');
-
- foreach (var selection in rootSelectionSet.Selections[..Math.Min(3, selectionCount)])
- {
- if (displayName.Length > 2)
- {
- displayName.Append(' ');
- }
-
- displayName.Append(selection.ResponseName);
- }
-
- if (rootSelectionSet.Selections.Length > 3)
- {
- displayName.Append(' ');
- displayName.Append('.');
- displayName.Append('.');
- displayName.Append('.');
- }
-
- displayName.Append(' ');
- displayName.Append('}');
-
- if (plan.OperationName is { } name)
- {
- displayName.Insert(0, ' ');
- displayName.Insert(0, name);
- }
-
- displayName.Insert(0, ' ');
- displayName.Insert(0, plan.Operation.Definition.Operation.ToString().ToLowerInvariant());
-
- return displayName.ToString();
- }
- finally
- {
- StringBuilderPool.Return(displayName);
- }
- }
-
- private void UpdateRootActivityName(Activity activity, string displayName)
- {
- var current = activity;
-
- while (current.Parent is not null)
- {
- current = current.Parent;
- }
-
- if (current != activity)
- {
- current.DisplayName = CreateRootActivityName(activity, current, displayName);
- }
- }
-
- protected virtual string CreateRootActivityName(
- Activity activity,
- Activity root,
- string displayName)
- {
- const string key = "originalDisplayName";
-
- if (root.GetCustomProperty(key) is not string rootDisplayName)
- {
- rootDisplayName = root.DisplayName;
- root.SetCustomProperty(key, rootDisplayName);
- }
-
- return $"{rootDisplayName}: {displayName}";
- }
-
- public virtual void EnrichParseDocument(RequestContext context, Activity activity)
- {
- activity.DisplayName = "Parse Document";
-
- if (_options.RenameRootActivity)
- {
- UpdateRootActivityName(activity, $"Begin {activity.DisplayName}");
- }
- }
-
- public virtual void EnrichRequestError(
- RequestContext context,
- Activity activity,
- Exception error)
- => EnrichError(ErrorBuilder.FromException(error).Build(), activity);
-
- public virtual void EnrichRequestError(
- RequestContext context,
- Activity activity,
- IError error)
- => EnrichError(error, activity);
-
- public virtual void EnrichValidateDocument(RequestContext context, Activity activity)
- {
- activity.DisplayName = "Validate Document";
-
- if (_options.RenameRootActivity)
- {
- UpdateRootActivityName(activity, $"Begin {activity.DisplayName}");
- }
-
- var documentInfo = context.OperationDocumentInfo;
- activity.SetTag("graphql.document.id", documentInfo.Id.Value);
- activity.SetTag("graphql.document.hash", documentInfo.Hash.Value);
- }
-
- public virtual void EnrichValidationError(
- RequestContext context,
- Activity activity,
- IError error)
- => EnrichError(error, activity);
-
- public virtual void EnrichAnalyzeOperationComplexity(RequestContext context, Activity activity)
- {
- activity.DisplayName = "Analyze Operation Complexity";
- }
-
- public virtual void EnrichCoerceVariables(RequestContext context, Activity activity)
- {
- activity.DisplayName = "Coerce Variable";
- }
-
- public virtual void EnrichPlanOperationScope(RequestContext context, Activity activity)
- {
- activity.DisplayName = "Plan Operation";
- }
-
- public virtual void EnrichExecuteOperation(RequestContext context, Activity activity)
- {
- var plan = context.GetOperationPlan();
- activity.DisplayName =
- plan?.OperationName is { } op
- ? $"Execute Operation {op}"
- : "Execute Operation";
- }
-
- public virtual void EnrichExecuteOperationNode(
+ public virtual void EnrichSourceSchemaTransportError(
OperationPlanContext context,
- OperationExecutionNode node,
+ ExecutionNode node,
string schemaName,
+ Exception exception,
Activity activity)
{
- activity.DisplayName = $"Execute Operation Node ({schemaName})";
- activity.SetTag("graphql.fusion.node.id", node.Id);
- activity.SetTag("graphql.fusion.node.type", node.Type.ToString());
- activity.SetTag("graphql.fusion.node.schema", schemaName);
}
- public virtual void EnrichExecuteOperationBatchNode(
+ public virtual void EnrichSourceSchemaStoreError(
OperationPlanContext context,
ExecutionNode node,
string schemaName,
+ Exception exception,
Activity activity)
{
- activity.DisplayName = $"Execute Operation Batch Node ({schemaName})";
- activity.SetTag("graphql.fusion.node.id", node.Id);
- activity.SetTag("graphql.fusion.node.type", node.Type.ToString());
- activity.SetTag("graphql.fusion.node.schema", schemaName);
- }
-
- public virtual void EnrichExecuteNodeFieldNode(
- OperationPlanContext context,
- NodeFieldExecutionNode node,
- Activity activity)
- {
- activity.DisplayName = "Execute Node Field Node";
- activity.SetTag("graphql.fusion.node.id", node.Id);
- activity.SetTag("graphql.fusion.node.type", node.Type.ToString());
}
- public virtual void EnrichExecuteIntrospectionNode(
+ public virtual void EnrichOnSubscriptionEvent(
OperationPlanContext context,
- IntrospectionExecutionNode node,
+ ExecutionNode node,
+ string schemaName,
+ ulong subscriptionId,
Activity activity)
{
- activity.DisplayName = "Execute Introspection Node";
- activity.SetTag("graphql.fusion.node.id", node.Id);
- activity.SetTag("graphql.fusion.node.type", node.Type.ToString());
}
- public virtual void EnrichExecutionNodeError(
- OperationPlanContext context,
- ExecutionNode node,
- Exception error,
- Activity activity)
- => activity.RecordException(error);
-
- public virtual void EnrichSourceSchemaError(
+ public virtual void EnrichSubscriptionEventError(
OperationPlanContext context,
ExecutionNode node,
string schemaName,
- Exception error,
- Activity activity)
- => activity.RecordException(error);
-
- protected virtual void EnrichError(IError error, Activity activity)
+ ulong subscriptionId,
+ Exception exception,
+ Activity featureActivity)
{
- if (error.Exception is { } exception)
- {
- activity.RecordException(exception);
- }
-
- var tags = new ActivityTagsCollection
- {
- new(AttributeExceptionMessage, error.Message),
- new(AttributeExceptionType, error.Code ?? "GRAPHQL_ERROR")
- };
-
- if (error.Path is not null)
- {
- tags["graphql.error.path"] = error.Path.ToString();
- }
-
- if (error.Locations is { Count: > 0 })
- {
- tags["graphql.error.location.column"] = error.Locations[0].Column;
- tags["graphql.error.location.line"] = error.Locations[0].Line;
- }
-
- activity.AddEvent(new ActivityEvent(AttributeExceptionEventName, default, tags));
}
}
-
-file static class SemanticConventions
-{
- public const string AttributeExceptionEventName = "exception";
- public const string AttributeExceptionType = "exception.type";
- public const string AttributeExceptionMessage = "exception.message";
-}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/FusionActivityScopes.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/FusionActivityScopes.cs
index f0ef6bd29e2..e2208344cd3 100644
--- a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/FusionActivityScopes.cs
+++ b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/FusionActivityScopes.cs
@@ -14,13 +14,13 @@ public enum FusionActivityScopes
CoerceVariables = 128,
PlanOperation = 256,
ExecuteOperation = 512,
- ExecuteNodes = 1024,
+ ExecutePlanNodes = 1024,
Default =
ExecuteHttpRequest
| ParseHttpRequest
| ValidateDocument
| PlanOperation
- | ExecuteNodes
+ | ExecutePlanNodes
| FormatHttpResponse,
All =
ExecuteHttpRequest
@@ -33,5 +33,5 @@ public enum FusionActivityScopes
| CoerceVariables
| PlanOperation
| ExecuteOperation
- | ExecuteNodes
+ | ExecutePlanNodes
}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/HotChocolate.Fusion.Diagnostics.csproj b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/HotChocolate.Fusion.Diagnostics.csproj
index 28e5ea8fabe..c5ca6371cb5 100644
--- a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/HotChocolate.Fusion.Diagnostics.csproj
+++ b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/HotChocolate.Fusion.Diagnostics.csproj
@@ -16,6 +16,7 @@
+
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/HotChocolateFusionActivitySource.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/HotChocolateFusionActivitySource.cs
index dda5993f72b..dd6db410510 100644
--- a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/HotChocolateFusionActivitySource.cs
+++ b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/HotChocolateFusionActivitySource.cs
@@ -8,8 +8,8 @@ internal static class HotChocolateFusionActivitySource
public static ActivitySource Source { get; } = new(GetName(), GetVersion());
public static string GetName()
- => typeof(ActivityFusionExecutionDiagnosticEventListener).Assembly.GetName().Name!;
+ => typeof(FusionActivityExecutionDiagnosticEventListener).Assembly.GetName().Name!;
private static string GetVersion()
- => typeof(ActivityFusionExecutionDiagnosticEventListener).Assembly.GetName().Version!.ToString();
+ => typeof(FusionActivityExecutionDiagnosticEventListener).Assembly.GetName().Version!.ToString();
}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/InstrumentationOptions.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/InstrumentationOptions.cs
index 74ae97005eb..9237f91b67a 100644
--- a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/InstrumentationOptions.cs
+++ b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/InstrumentationOptions.cs
@@ -1,3 +1,4 @@
+using HotChocolate.Diagnostics;
using static HotChocolate.Fusion.Diagnostics.FusionActivityScopes;
namespace HotChocolate.Fusion.Diagnostics;
@@ -5,30 +6,13 @@ namespace HotChocolate.Fusion.Diagnostics;
///
/// The Hot Chocolate Fusion instrumentation options.
///
-public sealed class InstrumentationOptions
+public sealed class InstrumentationOptions : InstrumentationOptionsBase
{
- ///
- /// Specifies the request detail that shall be included into the tracing activities.
- ///
- public RequestDetails RequestDetails { get; set; } = RequestDetails.Default;
-
///
/// Specifies the activity scopes that shall be instrumented.
///
public FusionActivityScopes Scopes { get; set; } = Default;
- ///
- /// Specifies if the parsed document shall be included into the tracing data.
- ///
- public bool IncludeDocument { get; set; }
-
- ///
- /// Defines if the operation display name shall be included in the root activity.
- ///
- public bool RenameRootActivity { get; set; }
-
- internal bool IncludeRequestDetails => RequestDetails is not RequestDetails.None;
-
internal bool SkipExecuteHttpRequest => (Scopes & ExecuteHttpRequest) != ExecuteHttpRequest;
internal bool SkipParseHttpRequest => (Scopes & ParseHttpRequest) != ParseHttpRequest;
@@ -41,11 +25,13 @@ public sealed class InstrumentationOptions
internal bool SkipValidateDocument => (Scopes & ValidateDocument) != ValidateDocument;
+ internal bool SkipAnalyzeComplexity => (Scopes & AnalyzeComplexity) != AnalyzeComplexity;
+
internal bool SkipCoerceVariables => (Scopes & CoerceVariables) != CoerceVariables;
internal bool SkipPlanOperation => (Scopes & PlanOperation) != PlanOperation;
internal bool SkipExecuteOperation => (Scopes & ExecuteOperation) != ExecuteOperation;
- internal bool SkipExecuteNodes => (Scopes & ExecuteNodes) != ExecuteNodes;
+ internal bool SkipExecutePlanNodes => (Scopes & ExecutePlanNodes) != ExecutePlanNodes;
}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Listeners/ActivityFusionExecutionDiagnosticEventListener.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Listeners/ActivityFusionExecutionDiagnosticEventListener.cs
deleted file mode 100644
index 985b74a2334..00000000000
--- a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Listeners/ActivityFusionExecutionDiagnosticEventListener.cs
+++ /dev/null
@@ -1,358 +0,0 @@
-using System.Diagnostics;
-using HotChocolate.Fusion.Diagnostics.Scopes;
-using HotChocolate.Execution;
-using HotChocolate.Fusion.Execution;
-using HotChocolate.Fusion.Execution.Nodes;
-using Microsoft.AspNetCore.Http;
-using OpenTelemetry.Trace;
-using static HotChocolate.Fusion.Diagnostics.ContextKeys;
-using static HotChocolate.Fusion.Diagnostics.HotChocolateFusionActivitySource;
-
-namespace HotChocolate.Fusion.Diagnostics.Listeners;
-
-internal sealed class ActivityFusionExecutionDiagnosticEventListener : FusionExecutionDiagnosticEventListener
-{
- private readonly InstrumentationOptions _options;
- private readonly FusionActivityEnricher _enricher;
-
- public ActivityFusionExecutionDiagnosticEventListener(
- FusionActivityEnricher enricher,
- InstrumentationOptions options)
- {
- ArgumentNullException.ThrowIfNull(enricher);
- ArgumentNullException.ThrowIfNull(options);
-
- _enricher = enricher;
- _options = options;
- }
-
- public override IDisposable ExecuteRequest(RequestContext context)
- {
- Activity? activity = null;
-
- if (_options.SkipExecuteRequest)
- {
- if (!_options.SkipExecuteHttpRequest
- && context.ContextData.TryGetValue(nameof(HttpContext), out var value)
- && value is HttpContext httpContext
- && httpContext.Items.TryGetValue(HttpRequestActivity, out value)
- && value is not null)
- {
- activity = (Activity)value;
- }
- else
- {
- return EmptyScope;
- }
- }
-
- activity ??= Source.StartActivity();
-
- if (activity is null)
- {
- return EmptyScope;
- }
-
- context.ContextData[RequestActivity] = activity;
-
- return new ExecuteRequestScope(_enricher, context, activity);
- }
-
- public override void RetrievedDocumentFromCache(RequestContext context)
- {
- if (context.ContextData.TryGetValue(RequestActivity, out var activity))
- {
- Debug.Assert(activity is not null, "The activity mustn't be null!");
- ((Activity)activity).AddEvent(new(nameof(RetrievedDocumentFromCache)));
- }
- }
-
- public override void RetrievedDocumentFromStorage(RequestContext context)
- {
- if (context.ContextData.TryGetValue(RequestActivity, out var activity))
- {
- Debug.Assert(activity is not null, "The activity mustn't be null!");
- ((Activity)activity).AddEvent(new(nameof(RetrievedDocumentFromStorage)));
- }
- }
-
- public override void AddedDocumentToCache(RequestContext context)
- {
- if (context.ContextData.TryGetValue(RequestActivity, out var activity))
- {
- Debug.Assert(activity is not null, "The activity mustn't be null!");
- ((Activity)activity).AddEvent(new(nameof(AddedDocumentToCache)));
- }
- }
-
- public override void AddedOperationPlanToCache(RequestContext context, string operationPlanId)
- {
- if (context.ContextData.TryGetValue(RequestActivity, out var activity))
- {
- Debug.Assert(activity is not null, "The activity mustn't be null!");
- ((Activity)activity).AddEvent(new(nameof(AddedOperationPlanToCache)));
- }
- }
-
- public override IDisposable ParseDocument(RequestContext context)
- {
- if (_options.SkipParseDocument)
- {
- return EmptyScope;
- }
-
- var activity = Source.StartActivity();
-
- if (activity is null)
- {
- return EmptyScope;
- }
-
- context.ContextData[RequestActivity] = activity;
-
- return new ParseDocumentScope(_enricher, context, activity);
- }
-
- public override void RequestError(RequestContext context, Exception error)
- {
- if (context.ContextData.TryGetValue(RequestActivity, out var value))
- {
- Debug.Assert(value is not null, "The activity mustn't be null!");
-
- var activity = (Activity)value;
- _enricher.EnrichRequestError(context, activity, error);
- activity.SetStatus(Status.Error);
- activity.SetStatus(ActivityStatusCode.Error);
- }
- }
-
- public override void RequestError(RequestContext context, IError error)
- {
- if (context.ContextData.TryGetValue(RequestActivity, out var value))
- {
- Debug.Assert(value is not null, "The activity mustn't be null!");
-
- var activity = (Activity)value;
- _enricher.EnrichRequestError(context, activity, error);
- activity.SetStatus(Status.Error);
- activity.SetStatus(ActivityStatusCode.Error);
- }
- }
-
- public override void ValidationErrors(RequestContext context, IReadOnlyList errors)
- {
- if (context.ContextData.TryGetValue(ValidateActivity, out var value))
- {
- Debug.Assert(value is not null, "The activity mustn't be null!");
-
- var activity = (Activity)value;
-
- foreach (var error in errors)
- {
- _enricher.EnrichValidationError(context, activity, error);
- }
-
- activity.SetStatus(Status.Error);
- activity.SetStatus(ActivityStatusCode.Error);
- }
- }
-
- public override IDisposable ValidateDocument(RequestContext context)
- {
- if (_options.SkipValidateDocument)
- {
- return EmptyScope;
- }
-
- var activity = Source.StartActivity();
-
- if (activity is null)
- {
- return EmptyScope;
- }
-
- context.ContextData[ValidateActivity] = activity;
-
- return new ValidateDocumentScope(_enricher, context, activity);
- }
-
- public override IDisposable CoerceVariables(RequestContext context)
- {
- if (_options.SkipCoerceVariables)
- {
- return EmptyScope;
- }
-
- var activity = Source.StartActivity();
-
- if (activity is null)
- {
- return EmptyScope;
- }
-
- return new CoerceVariablesScope(_enricher, context, activity);
- }
-
- public override IDisposable PlanOperation(RequestContext context, string operationPlanId)
- {
- if (_options.SkipPlanOperation)
- {
- return EmptyScope;
- }
-
- var activity = Source.StartActivity();
-
- if (activity is null)
- {
- return EmptyScope;
- }
-
- return new PlanOperationScope(_enricher, context, activity);
- }
-
- public override IDisposable ExecuteOperation(RequestContext context)
- {
- if (_options.SkipExecuteOperation)
- {
- return EmptyScope;
- }
-
- var activity = Source.StartActivity();
-
- if (activity is null)
- {
- return EmptyScope;
- }
-
- return new ExecuteOperationScope(_enricher, context, activity);
- }
-
- public override IDisposable ExecuteOperationNode(
- OperationPlanContext context,
- OperationExecutionNode node,
- string schemaName)
- {
- if (_options.SkipExecuteNodes)
- {
- return EmptyScope;
- }
-
- var activity = Source.StartActivity();
-
- if (activity is null)
- {
- return EmptyScope;
- }
-
- return new ExecuteOperationNodeScope(_enricher, context, node, schemaName, activity);
- }
-
- public override IDisposable ExecuteOperationBatchNode(
- OperationPlanContext context,
- ExecutionNode node,
- string schemaName)
- {
- if (_options.SkipExecuteNodes)
- {
- return EmptyScope;
- }
-
- var activity = Source.StartActivity();
-
- if (activity is null)
- {
- return EmptyScope;
- }
-
- return new ExecuteOperationBatchNodeScope(_enricher, context, node, schemaName, activity);
- }
-
- public override IDisposable ExecuteNodeFieldNode(
- OperationPlanContext context,
- NodeFieldExecutionNode node)
- {
- if (_options.SkipExecuteNodes)
- {
- return EmptyScope;
- }
-
- var activity = Source.StartActivity();
-
- if (activity is null)
- {
- return EmptyScope;
- }
-
- return new ExecuteNodeFieldNodeScope(_enricher, context, node, activity);
- }
-
- public override IDisposable ExecuteIntrospectionNode(
- OperationPlanContext context,
- IntrospectionExecutionNode node)
- {
- if (_options.SkipExecuteNodes)
- {
- return EmptyScope;
- }
-
- var activity = Source.StartActivity();
-
- if (activity is null)
- {
- return EmptyScope;
- }
-
- return new ExecuteIntrospectionNodeScope(_enricher, context, node, activity);
- }
-
- public override void ExecutionNodeError(
- OperationPlanContext context,
- ExecutionNode node,
- Exception error)
- {
- if (Activity.Current is { } activity)
- {
- _enricher.EnrichExecutionNodeError(context, node, error, activity);
- }
- }
-
- public override void SourceSchemaTransportError(
- OperationPlanContext context,
- ExecutionNode node,
- string schemaName,
- Exception error)
- {
- if (Activity.Current is { } activity)
- {
- _enricher.EnrichSourceSchemaError(context, node, schemaName, error, activity);
- }
- }
-
- public override void SourceSchemaStoreError(
- OperationPlanContext context,
- ExecutionNode node,
- string schemaName,
- Exception error)
- {
- if (Activity.Current is { } activity)
- {
- _enricher.EnrichSourceSchemaError(context, node, schemaName, error, activity);
- }
- }
-
- public override IDisposable OnSubscriptionEvent(
- OperationPlanContext context,
- ExecutionNode node,
- string schemaName,
- ulong subscriptionId)
- {
- var activity = Source.StartActivity();
-
- if (activity is null)
- {
- return EmptyScope;
- }
-
- return activity;
- }
-}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Listeners/ActivityServerDiagnosticListener.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Listeners/ActivityServerDiagnosticListener.cs
deleted file mode 100644
index 1eb078b2f3f..00000000000
--- a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Listeners/ActivityServerDiagnosticListener.cs
+++ /dev/null
@@ -1,152 +0,0 @@
-using System.Diagnostics;
-using Microsoft.AspNetCore.Http;
-using HotChocolate.AspNetCore.Instrumentation;
-using HotChocolate.Execution;
-using HotChocolate.Language;
-using OpenTelemetry.Trace;
-using static HotChocolate.Fusion.Diagnostics.ContextKeys;
-
-namespace HotChocolate.Fusion.Diagnostics.Listeners;
-
-internal sealed class ActivityServerDiagnosticListener(
- FusionActivityEnricher enricher,
- InstrumentationOptions options)
- : ServerDiagnosticEventListener
-{
- private readonly InstrumentationOptions _options = options ?? throw new ArgumentNullException(nameof(options));
- private readonly FusionActivityEnricher _enricher = enricher ?? throw new ArgumentNullException(nameof(enricher));
-
- public override IDisposable ExecuteHttpRequest(HttpContext context, HttpRequestKind kind)
- {
- if (_options.SkipExecuteHttpRequest)
- {
- return EmptyScope;
- }
-
- var activity = HotChocolateFusionActivitySource.Source.StartActivity();
-
- if (activity is null)
- {
- return EmptyScope;
- }
-
- _enricher.EnrichExecuteHttpRequest(context, kind, activity);
- activity.SetStatus(ActivityStatusCode.Ok);
- context.Items[HttpRequestActivity] = activity;
-
- return activity;
- }
-
- public override void StartSingleRequest(HttpContext context, GraphQLRequest request)
- {
- if (_options.IncludeRequestDetails
- && context.Items.TryGetValue(HttpRequestActivity, out var activity))
- {
- _enricher.EnrichSingleRequest(context, request, (Activity)activity!);
- }
- }
-
- public override void StartBatchRequest(HttpContext context, IReadOnlyList batch)
- {
- if (_options.IncludeRequestDetails
- && context.Items.TryGetValue(HttpRequestActivity, out var activity))
- {
- _enricher.EnrichBatchRequest(context, batch, (Activity)activity!);
- }
- }
-
- public override void StartOperationBatchRequest(
- HttpContext context,
- GraphQLRequest request,
- IReadOnlyList operations)
- {
- if (_options.IncludeRequestDetails
- && context.Items.TryGetValue(HttpRequestActivity, out var activity))
- {
- _enricher.EnrichOperationBatchRequest(
- context,
- request,
- operations,
- (Activity)activity!);
- }
- }
-
- public override void HttpRequestError(HttpContext context, IError error)
- {
- if (context.Items.TryGetValue(HttpRequestActivity, out var value))
- {
- var activity = (Activity)value!;
- _enricher.EnrichHttpRequestError(context, error, activity);
- activity.SetStatus(Status.Error);
- }
- }
-
- public override void HttpRequestError(HttpContext context, Exception exception)
- {
- if (context.Items.TryGetValue(HttpRequestActivity, out var value))
- {
- var activity = (Activity)value!;
- _enricher.EnrichHttpRequestError(context, exception, activity);
- activity.SetStatus(Status.Error);
- }
- }
-
- public override IDisposable ParseHttpRequest(HttpContext context)
- {
- if (_options.SkipParseHttpRequest)
- {
- return EmptyScope;
- }
-
- var activity = HotChocolateFusionActivitySource.Source.StartActivity();
-
- if (activity is null)
- {
- return EmptyScope;
- }
-
- _enricher.EnrichParseHttpRequest(context, activity);
- activity.SetStatus(Status.Ok);
- activity.SetStatus(ActivityStatusCode.Ok);
- context.Items[ParseHttpRequestActivity] = activity;
-
- return activity;
- }
-
- public override void ParserErrors(HttpContext context, IReadOnlyList errors)
- {
- if (context.Items.TryGetValue(ParseHttpRequestActivity, out var value))
- {
- var activity = (Activity)value!;
-
- foreach (var error in errors)
- {
- _enricher.EnrichParserErrors(context, error, activity);
- }
-
- activity.SetStatus(Status.Error);
- activity.SetStatus(ActivityStatusCode.Error);
- }
- }
-
- public override IDisposable FormatHttpResponse(HttpContext context, OperationResult result)
- {
- if (_options.SkipFormatHttpResponse)
- {
- return EmptyScope;
- }
-
- var activity = HotChocolateFusionActivitySource.Source.StartActivity();
-
- if (activity is null)
- {
- return EmptyScope;
- }
-
- _enricher.EnrichFormatHttpResponse(context, activity);
- activity.SetStatus(ActivityStatusCode.Ok);
- context.Items[FormatHttpResponseActivity] = activity;
-
- return activity;
- }
-}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Listeners/FusionActivityExecutionDiagnosticEventListener.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Listeners/FusionActivityExecutionDiagnosticEventListener.cs
new file mode 100644
index 00000000000..816544718d6
--- /dev/null
+++ b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Listeners/FusionActivityExecutionDiagnosticEventListener.cs
@@ -0,0 +1,362 @@
+using System.Diagnostics;
+using HotChocolate.Diagnostics;
+using HotChocolate.Execution;
+using HotChocolate.Fusion.Execution;
+using HotChocolate.Fusion.Execution.Nodes;
+using Microsoft.AspNetCore.Http;
+using static HotChocolate.Fusion.Diagnostics.HotChocolateFusionActivitySource;
+
+namespace HotChocolate.Fusion.Diagnostics.Listeners;
+
+internal sealed class FusionActivityExecutionDiagnosticEventListener(
+ FusionActivityEnricher enricher,
+ InstrumentationOptions options) : FusionExecutionDiagnosticEventListener
+{
+ public override IDisposable ExecuteRequest(RequestContext context)
+ {
+ Activity? httpContextActivity = null;
+
+ if (options.SkipExecuteRequest)
+ {
+ if (!options.SkipExecuteHttpRequest
+ && context.Features.TryGet(out var httpContext)
+ && httpContext.Features.Get() is { } httpRequestSpan)
+ {
+ httpContextActivity = httpRequestSpan.Activity;
+ }
+ else
+ {
+ return EmptyScope;
+ }
+ }
+
+ var span = httpContextActivity is not null
+ ? new ExecuteRequestSpan(httpContextActivity, context, options, enricher, false)
+ : ExecuteRequestSpan.Start(Source, context, options, enricher);
+
+ if (span is null)
+ {
+ return EmptyScope;
+ }
+
+ context.Features.Set(span);
+
+ return span;
+ }
+
+ public override void RequestError(RequestContext context, Exception error)
+ {
+ if (context.Features.TryGet(out var span))
+ {
+ var activity = span.Activity;
+
+ activity.SetStatus(ActivityStatusCode.Error);
+ activity.AddException(error);
+
+ enricher.EnrichRequestError(context, error, activity);
+ }
+ }
+
+ public override void RequestError(RequestContext context, IError error)
+ {
+ if (context.Features.TryGet(out var span))
+ {
+ var activity = span.Activity;
+
+ activity.SetStatus(ActivityStatusCode.Error);
+ activity.AddGraphQLError(error);
+
+ enricher.EnrichRequestError(context, error, activity);
+ }
+ }
+
+ public override IDisposable ParseDocument(RequestContext context)
+ {
+ if (options.SkipParseDocument)
+ {
+ return EmptyScope;
+ }
+
+ var span = ParsingSpan.Start(Source, context, enricher);
+
+ return span ?? EmptyScope;
+ }
+
+ public override IDisposable ValidateDocument(RequestContext context)
+ {
+ if (options.SkipValidateDocument)
+ {
+ return EmptyScope;
+ }
+
+ var span = ValidationSpan.Start(Source, context, enricher);
+
+ if (span is null)
+ {
+ return EmptyScope;
+ }
+
+ context.Features.Set(span);
+
+ return span;
+ }
+
+ public override void ValidationErrors(RequestContext context, IReadOnlyList errors)
+ {
+ if (!context.Features.TryGet(out var span))
+ {
+ return;
+ }
+
+ var activity = span.Activity;
+
+ activity.SetStatus(ActivityStatusCode.Error);
+
+ foreach (var error in errors)
+ {
+ activity.AddGraphQLError(error);
+ }
+
+ enricher.EnrichValidationErrors(context, errors, activity);
+ }
+
+ public override IDisposable PlanOperation(RequestContext context, string operationPlanId)
+ {
+ if (options.SkipPlanOperation)
+ {
+ return EmptyScope;
+ }
+
+ var span = PlanOperationSpan.Start(Source, context, enricher, operationPlanId);
+
+ return span ?? EmptyScope;
+ }
+
+ public override IDisposable CoerceVariables(RequestContext context)
+ {
+ if (options.SkipCoerceVariables)
+ {
+ return EmptyScope;
+ }
+
+ if (context.GetOperationPlan() is not { } plan)
+ {
+ return EmptyScope;
+ }
+
+ var span = VariableCoercionSpan.Start(
+ Source,
+ context,
+ plan.Operation.Definition.Operation,
+ plan.OperationName,
+ enricher);
+
+ return span ?? EmptyScope;
+ }
+
+ public override IDisposable ExecuteOperation(RequestContext context)
+ {
+ if (options.SkipExecuteOperation)
+ {
+ return EmptyScope;
+ }
+
+ if (context.GetOperationPlan() is not { } plan)
+ {
+ return EmptyScope;
+ }
+
+ var span = ExecuteOperationSpan.Start(
+ Source,
+ context,
+ plan.Operation.Definition.Operation,
+ plan.OperationName,
+ enricher);
+
+ return span ?? EmptyScope;
+ }
+
+ public override IDisposable ExecuteOperationNode(
+ OperationPlanContext context,
+ OperationExecutionNode node,
+ string schemaName)
+ => ExecuteNode(context, node, schemaName);
+
+ public override IDisposable ExecuteOperationBatchNode(
+ OperationPlanContext context,
+ OperationBatchExecutionNode node,
+ string schemaName)
+ => ExecuteNode(context, node, schemaName);
+
+ public override IDisposable ExecuteSubscriptionNode(
+ OperationPlanContext context,
+ ExecutionNode node,
+ string schemaName,
+ ulong subscriptionId)
+ {
+ var nodeScope = ExecuteNode(context, node, schemaName);
+ context.RequestContext.Features.Set(
+ new SubscriptionContextFeature
+ {
+ SubscriptionContext = Activity.Current?.Context
+ });
+
+ return nodeScope;
+ }
+
+ public override IDisposable ExecuteNodeFieldNode(
+ OperationPlanContext context,
+ NodeFieldExecutionNode node)
+ => ExecuteNode(context, node, null);
+
+ public override IDisposable ExecuteIntrospectionNode(
+ OperationPlanContext context,
+ IntrospectionExecutionNode node)
+ => ExecuteNode(context, node, null);
+
+ public override void ExecutionNodeError(
+ OperationPlanContext context,
+ ExecutionNode node,
+ Exception error)
+ {
+ if (Activity.Current is { } activity)
+ {
+ activity.SetStatus(ActivityStatusCode.Error);
+ activity.AddException(error);
+
+ enricher.EnrichExecutionNodeError(context, node, error, activity);
+ }
+ }
+
+ public override void SourceSchemaTransportError(
+ OperationPlanContext context,
+ ExecutionNode node,
+ string schemaName,
+ Exception error)
+ {
+ if (Activity.Current is { } activity)
+ {
+ activity.SetStatus(ActivityStatusCode.Error);
+ activity.AddException(error);
+
+ enricher.EnrichSourceSchemaTransportError(context, node, schemaName, error, activity);
+ }
+ }
+
+ public override void SourceSchemaStoreError(
+ OperationPlanContext context,
+ ExecutionNode node,
+ string schemaName,
+ Exception error)
+ {
+ if (Activity.Current is { } activity)
+ {
+ activity.SetStatus(ActivityStatusCode.Error);
+ activity.AddException(error);
+
+ enricher.EnrichSourceSchemaStoreError(context, node, schemaName, error, activity);
+ }
+ }
+
+ public override IDisposable OnSubscriptionEvent(
+ OperationPlanContext context,
+ ExecutionNode node,
+ string schemaName,
+ ulong subscriptionId)
+ {
+ ActivityContext? subscriptionContext = null;
+
+ if (context.RequestContext.Features.TryGet(out var feature)
+ && feature.SubscriptionContext is { } storedSubscriptionContext)
+ {
+ subscriptionContext = storedSubscriptionContext;
+ }
+
+ var span = SubscriptionEventSpan.Start(
+ Source,
+ context.RequestContext,
+ context.OperationPlan.Operation.Name,
+ subscriptionId,
+ subscriptionContext);
+
+ if (span is null)
+ {
+ return EmptyScope;
+ }
+
+ enricher.EnrichOnSubscriptionEvent(context, node, schemaName, subscriptionId, span.Activity);
+
+ return span;
+ }
+
+ public override void SubscriptionEventError(
+ OperationPlanContext context,
+ ExecutionNode node,
+ string schemaName,
+ ulong subscriptionId,
+ Exception exception)
+ {
+ if (Activity.Current is { } activity)
+ {
+ activity.SetStatus(ActivityStatusCode.Error);
+ activity.AddException(exception);
+
+ enricher.EnrichSubscriptionEventError(
+ context,
+ node,
+ schemaName,
+ subscriptionId,
+ exception,
+ activity);
+ }
+ }
+
+ public override void RetrievedDocumentFromCache(RequestContext context)
+ {
+ if (context.Features.TryGet(out var span))
+ {
+ span.Activity.AddEvent(new(nameof(RetrievedDocumentFromCache)));
+ }
+ }
+
+ public override void RetrievedDocumentFromStorage(RequestContext context)
+ {
+ if (context.Features.TryGet(out var span))
+ {
+ span.Activity.AddEvent(new(nameof(RetrievedDocumentFromStorage)));
+ }
+ }
+
+ public override void AddedDocumentToCache(RequestContext context)
+ {
+ if (context.Features.TryGet(out var span))
+ {
+ span.Activity.AddEvent(new(nameof(AddedDocumentToCache)));
+ }
+ }
+
+ public override void AddedOperationPlanToCache(RequestContext context, string operationPlanId)
+ {
+ if (context.Features.TryGet(out var span))
+ {
+ span.Activity.AddEvent(new(nameof(AddedOperationPlanToCache)));
+ }
+ }
+
+ private sealed class SubscriptionContextFeature
+ {
+ public ActivityContext? SubscriptionContext { get; set; }
+ }
+
+ private IDisposable ExecuteNode(OperationPlanContext context, ExecutionNode node, string? schemaName)
+ {
+ if (options.SkipExecutePlanNodes)
+ {
+ return EmptyScope;
+ }
+
+ var span = ExecutePlanNodeSpan.Start(Source, context, node, schemaName, enricher);
+
+ return span ?? EmptyScope;
+ }
+}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Listeners/FusionActivityServerDiagnosticListener.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Listeners/FusionActivityServerDiagnosticListener.cs
new file mode 100644
index 00000000000..2bfb286ed56
--- /dev/null
+++ b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Listeners/FusionActivityServerDiagnosticListener.cs
@@ -0,0 +1,118 @@
+using Microsoft.AspNetCore.Http;
+using HotChocolate.AspNetCore.Instrumentation;
+using HotChocolate.Diagnostics;
+using HotChocolate.Execution;
+using HotChocolate.Language;
+using static HotChocolate.Fusion.Diagnostics.HotChocolateFusionActivitySource;
+
+namespace HotChocolate.Fusion.Diagnostics.Listeners;
+
+internal sealed class FusionActivityServerDiagnosticListener(
+ FusionActivityEnricher enricher,
+ InstrumentationOptions options)
+ : ServerDiagnosticEventListener
+{
+ public override IDisposable ExecuteHttpRequest(HttpContext context, HttpRequestKind kind)
+ {
+ if (options.SkipExecuteHttpRequest)
+ {
+ return EmptyScope;
+ }
+
+ var span = ExecuteHttpRequestSpan.Start(Source, context, kind, enricher, options);
+
+ if (span is null)
+ {
+ return EmptyScope;
+ }
+
+ context.Features.Set(span);
+
+ return span;
+ }
+
+ public override void StartSingleRequest(HttpContext context, GraphQLRequest request)
+ {
+ if (options.IncludeRequestDetails
+ && context.Features.Get() is { } span)
+ {
+ span.SetSingleRequestDetails(request);
+ }
+ }
+
+ public override void StartBatchRequest(HttpContext context, IReadOnlyList batch)
+ {
+ if (options.IncludeRequestDetails
+ && context.Features.Get() is { } span)
+ {
+ span.SetBatchRequestDetails(batch);
+ }
+ }
+
+ public override void StartOperationBatchRequest(
+ HttpContext context,
+ GraphQLRequest request,
+ IReadOnlyList operations)
+ {
+ if (options.IncludeRequestDetails
+ && context.Features.Get() is { } span)
+ {
+ span.SetOperationBatchRequestDetails(request, operations);
+ }
+ }
+
+ public override void HttpRequestError(HttpContext context, IError error)
+ {
+ if (context.Features.Get() is { } span)
+ {
+ span.RecordError(error);
+ }
+ }
+
+ public override void HttpRequestError(HttpContext context, Exception exception)
+ {
+ if (context.Features.Get() is { } span)
+ {
+ span.RecordError(exception);
+ }
+ }
+
+ public override IDisposable ParseHttpRequest(HttpContext context)
+ {
+ if (options.SkipParseHttpRequest)
+ {
+ return EmptyScope;
+ }
+
+ var span = ParseHttpRequestSpan.Start(Source, context, enricher);
+
+ if (span is null)
+ {
+ return EmptyScope;
+ }
+
+ context.Features.Set(span);
+
+ return span;
+ }
+
+ public override void ParserErrors(HttpContext context, IReadOnlyList errors)
+ {
+ if (context.Features.Get() is { } span)
+ {
+ span.RecordErrors(errors);
+ }
+ }
+
+ public override IDisposable FormatHttpResponse(HttpContext context, OperationResult result)
+ {
+ if (options.SkipFormatHttpResponse)
+ {
+ return EmptyScope;
+ }
+
+ var span = FormatHttpResponseSpan.Start(Source, context, enricher);
+
+ return span ?? EmptyScope;
+ }
+}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/RequestDetails.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/RequestDetails.cs
deleted file mode 100644
index dd05a951ba2..00000000000
--- a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/RequestDetails.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-namespace HotChocolate.Fusion.Diagnostics;
-
-[Flags]
-public enum RequestDetails
-{
- None = 0,
- Id = 1,
- Hash = 2,
- Operation = 4,
- Variables = 8,
- Extensions = 16,
- Query = 32,
- Default = Id | Hash | Operation | Extensions,
- All = Id | Hash | Operation | Variables | Extensions | Query
-}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/CoerceVariablesScope.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/CoerceVariablesScope.cs
deleted file mode 100644
index 8361d9d044d..00000000000
--- a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/CoerceVariablesScope.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System.Diagnostics;
-using HotChocolate.Execution;
-using OpenTelemetry.Trace;
-
-namespace HotChocolate.Fusion.Diagnostics.Scopes;
-
-internal sealed class CoerceVariablesScope(
- FusionActivityEnricher enricher,
- RequestContext context,
- Activity activity)
- : RequestScopeBase(enricher, context, activity)
-{
- protected override void EnrichActivity()
- => Enricher.EnrichCoerceVariables(Context, Activity);
-
- protected override void SetStatus()
- {
- if (Context.VariableValues.Length > 0)
- {
- Activity.SetStatus(Status.Ok);
- Activity.SetStatus(ActivityStatusCode.Ok);
- }
- }
-}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/ExecuteIntrospectionNodeScope.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/ExecuteIntrospectionNodeScope.cs
deleted file mode 100644
index 622397a1e7d..00000000000
--- a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/ExecuteIntrospectionNodeScope.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System.Diagnostics;
-using HotChocolate.Fusion.Execution;
-using HotChocolate.Fusion.Execution.Nodes;
-using OpenTelemetry.Trace;
-
-namespace HotChocolate.Fusion.Diagnostics.Scopes;
-
-internal sealed class ExecuteIntrospectionNodeScope(
- FusionActivityEnricher enricher,
- OperationPlanContext context,
- IntrospectionExecutionNode node,
- Activity activity)
- : NodeScopeBase(enricher, context, activity)
-{
- protected override void EnrichActivity()
- => Enricher.EnrichExecuteIntrospectionNode(Context, node, Activity);
-
- protected override void SetStatus()
- {
- Activity.SetStatus(Status.Ok);
- Activity.SetStatus(ActivityStatusCode.Ok);
- }
-}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/ExecuteNodeFieldNodeScope.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/ExecuteNodeFieldNodeScope.cs
deleted file mode 100644
index 867b33786e5..00000000000
--- a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/ExecuteNodeFieldNodeScope.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System.Diagnostics;
-using HotChocolate.Fusion.Execution;
-using HotChocolate.Fusion.Execution.Nodes;
-using OpenTelemetry.Trace;
-
-namespace HotChocolate.Fusion.Diagnostics.Scopes;
-
-internal sealed class ExecuteNodeFieldNodeScope(
- FusionActivityEnricher enricher,
- OperationPlanContext context,
- NodeFieldExecutionNode node,
- Activity activity)
- : NodeScopeBase(enricher, context, activity)
-{
- protected override void EnrichActivity()
- => Enricher.EnrichExecuteNodeFieldNode(Context, node, Activity);
-
- protected override void SetStatus()
- {
- Activity.SetStatus(Status.Ok);
- Activity.SetStatus(ActivityStatusCode.Ok);
- }
-}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/ExecuteOperationBatchNodeScope.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/ExecuteOperationBatchNodeScope.cs
deleted file mode 100644
index 1363edffea5..00000000000
--- a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/ExecuteOperationBatchNodeScope.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System.Diagnostics;
-using HotChocolate.Fusion.Execution;
-using HotChocolate.Fusion.Execution.Nodes;
-using OpenTelemetry.Trace;
-
-namespace HotChocolate.Fusion.Diagnostics.Scopes;
-
-internal sealed class ExecuteOperationBatchNodeScope(
- FusionActivityEnricher enricher,
- OperationPlanContext context,
- ExecutionNode node,
- string schemaName,
- Activity activity)
- : NodeScopeBase(enricher, context, activity)
-{
- protected override void EnrichActivity()
- => Enricher.EnrichExecuteOperationBatchNode(Context, node, schemaName, Activity);
-
- protected override void SetStatus()
- {
- Activity.SetStatus(Status.Ok);
- Activity.SetStatus(ActivityStatusCode.Ok);
- }
-}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/ExecuteOperationNodeScope.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/ExecuteOperationNodeScope.cs
deleted file mode 100644
index 58e19e11185..00000000000
--- a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/ExecuteOperationNodeScope.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System.Diagnostics;
-using HotChocolate.Fusion.Execution;
-using HotChocolate.Fusion.Execution.Nodes;
-using OpenTelemetry.Trace;
-
-namespace HotChocolate.Fusion.Diagnostics.Scopes;
-
-internal sealed class ExecuteOperationNodeScope(
- FusionActivityEnricher enricher,
- OperationPlanContext context,
- OperationExecutionNode node,
- string schemaName,
- Activity activity)
- : NodeScopeBase(enricher, context, activity)
-{
- protected override void EnrichActivity()
- => Enricher.EnrichExecuteOperationNode(Context, node, schemaName, Activity);
-
- protected override void SetStatus()
- {
- Activity.SetStatus(Status.Ok);
- Activity.SetStatus(ActivityStatusCode.Ok);
- }
-}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/ExecuteOperationScope.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/ExecuteOperationScope.cs
deleted file mode 100644
index 1f69711d4e6..00000000000
--- a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/ExecuteOperationScope.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using System.Diagnostics;
-using HotChocolate.Execution;
-using OpenTelemetry.Trace;
-
-namespace HotChocolate.Fusion.Diagnostics.Scopes;
-
-internal sealed class ExecuteOperationScope(
- FusionActivityEnricher enricher,
- RequestContext context,
- Activity activity)
- : RequestScopeBase(enricher, context, activity)
-{
- protected override void EnrichActivity()
- => Enricher.EnrichExecuteOperation(Context, Activity);
-
- protected override void SetStatus()
- {
- if (Context.Result is null or OperationResult { Errors: [_, ..] })
- {
- Activity.SetStatus(Status.Error);
- Activity.SetStatus(ActivityStatusCode.Error);
- }
- else
- {
- Activity.SetStatus(Status.Ok);
- Activity.SetStatus(ActivityStatusCode.Ok);
- }
- }
-}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/ExecuteRequestScope.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/ExecuteRequestScope.cs
deleted file mode 100644
index 6ecca09cc07..00000000000
--- a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/ExecuteRequestScope.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System.Diagnostics;
-using HotChocolate.Execution;
-using OpenTelemetry.Trace;
-
-namespace HotChocolate.Fusion.Diagnostics.Scopes;
-
-internal sealed class ExecuteRequestScope(
- FusionActivityEnricher enricher,
- RequestContext context,
- Activity activity)
- : RequestScopeBase(enricher, context, activity)
-{
- protected override void EnrichActivity()
- => Enricher.EnrichExecuteRequest(Context, Activity);
-
- protected override void SetStatus()
- {
- if (Context.Result is null or OperationResult { Errors: [_, ..] })
- {
- Activity.SetStatus(Status.Error);
- Activity.SetStatus(ActivityStatusCode.Error);
- }
- }
-}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/NodeScopeBase.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/NodeScopeBase.cs
deleted file mode 100644
index e0c04291939..00000000000
--- a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/NodeScopeBase.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using System.Diagnostics;
-using HotChocolate.Fusion.Execution;
-
-namespace HotChocolate.Fusion.Diagnostics.Scopes;
-
-internal class NodeScopeBase : IDisposable
-{
- private bool _disposed;
-
- protected NodeScopeBase(
- FusionActivityEnricher enricher,
- OperationPlanContext context,
- Activity activity)
- {
- Enricher = enricher ?? throw new ArgumentNullException(nameof(enricher));
- Context = context ?? throw new ArgumentNullException(nameof(context));
- Activity = activity ?? throw new ArgumentNullException(nameof(activity));
- }
-
- protected FusionActivityEnricher Enricher { get; }
-
- protected OperationPlanContext Context { get; }
-
- protected Activity Activity { get; }
-
- protected virtual void EnrichActivity() { }
-
- protected virtual void SetStatus() { }
-
- public void Dispose()
- {
- if (!_disposed)
- {
- EnrichActivity();
- SetStatus();
- Activity.Dispose();
- _disposed = true;
- }
- }
-}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/ParseDocumentScope.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/ParseDocumentScope.cs
deleted file mode 100644
index 048af8072b1..00000000000
--- a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/ParseDocumentScope.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System.Diagnostics;
-using HotChocolate.Execution;
-using OpenTelemetry.Trace;
-
-namespace HotChocolate.Fusion.Diagnostics.Scopes;
-
-internal sealed class ParseDocumentScope(
- FusionActivityEnricher enricher,
- RequestContext context,
- Activity activity)
- : RequestScopeBase(enricher, context, activity)
-{
- protected override void EnrichActivity()
- => Enricher.EnrichParseDocument(Context, Activity);
-
- protected override void SetStatus()
- {
- if (Context.TryGetOperationDocument(out _, out _))
- {
- Activity.SetStatus(Status.Ok);
- Activity.SetStatus(ActivityStatusCode.Ok);
- }
- }
-}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/PlanOperationScope.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/PlanOperationScope.cs
deleted file mode 100644
index aad6df000df..00000000000
--- a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/PlanOperationScope.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System.Diagnostics;
-using HotChocolate.Execution;
-using OpenTelemetry.Trace;
-
-namespace HotChocolate.Fusion.Diagnostics.Scopes;
-
-internal sealed class PlanOperationScope(
- FusionActivityEnricher enricher,
- RequestContext context,
- Activity activity)
- : RequestScopeBase(enricher, context, activity)
-{
- protected override void EnrichActivity()
- => Enricher.EnrichPlanOperationScope(Context, Activity);
-
- protected override void SetStatus()
- {
- if (Context.GetOperationPlan() is not null)
- {
- Activity.SetStatus(Status.Ok);
- Activity.SetStatus(ActivityStatusCode.Ok);
- }
- }
-}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/RequestScopeBase.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/RequestScopeBase.cs
deleted file mode 100644
index 69403a62676..00000000000
--- a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/RequestScopeBase.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using System.Diagnostics;
-using HotChocolate.Execution;
-
-namespace HotChocolate.Fusion.Diagnostics.Scopes;
-
-internal class RequestScopeBase : IDisposable
-{
- private bool _disposed;
-
- protected RequestScopeBase(
- FusionActivityEnricher enricher,
- RequestContext context,
- Activity activity)
- {
- Enricher = enricher ?? throw new ArgumentNullException(nameof(enricher));
- Context = context ?? throw new ArgumentNullException(nameof(context));
- Activity = activity ?? throw new ArgumentNullException(nameof(activity));
- }
-
- protected FusionActivityEnricher Enricher { get; }
-
- protected RequestContext Context { get; }
-
- protected Activity Activity { get; }
-
- protected virtual void EnrichActivity() { }
-
- protected virtual void SetStatus() { }
-
- public void Dispose()
- {
- if (!_disposed)
- {
- EnrichActivity();
- SetStatus();
- Activity.Dispose();
- _disposed = true;
- }
- }
-}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/ValidateDocumentScope.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/ValidateDocumentScope.cs
deleted file mode 100644
index 2f4b9dc58cf..00000000000
--- a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Scopes/ValidateDocumentScope.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System.Diagnostics;
-using HotChocolate.Execution;
-using OpenTelemetry.Trace;
-
-namespace HotChocolate.Fusion.Diagnostics.Scopes;
-
-internal sealed class ValidateDocumentScope(
- FusionActivityEnricher enricher,
- RequestContext context,
- Activity activity)
- : RequestScopeBase(enricher, context, activity)
-{
- protected override void EnrichActivity()
- => Enricher.EnrichValidateDocument(Context, Activity);
-
- protected override void SetStatus()
- {
- if (Context.IsOperationDocumentValid())
- {
- Activity.SetStatus(Status.Ok);
- Activity.SetStatus(ActivityStatusCode.Ok);
- }
- }
-}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Spans/ExecutePlanNodeSpan.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Spans/ExecutePlanNodeSpan.cs
new file mode 100644
index 00000000000..c3f7b26f4fe
--- /dev/null
+++ b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Spans/ExecutePlanNodeSpan.cs
@@ -0,0 +1,84 @@
+using System.Collections.Frozen;
+using System.Diagnostics;
+using System.Globalization;
+using HotChocolate.Fusion.Diagnostics;
+using HotChocolate.Fusion.Execution;
+using HotChocolate.Fusion.Execution.Nodes;
+using static HotChocolate.Diagnostics.SemanticConventions;
+
+namespace HotChocolate.Diagnostics;
+
+internal sealed class ExecutePlanNodeSpan(
+ Activity activity,
+ OperationPlanContext context,
+ ExecutionNode node,
+ string? schemaName,
+ FusionActivityEnricher enricher) : SpanBase(activity)
+{
+ private static FrozenDictionary KindValues { get; } =
+ new Dictionary
+ {
+ [ExecutionNodeType.Operation] = GraphQL.Operation.Step.KindValues.Operation,
+ [ExecutionNodeType.OperationBatch] = GraphQL.Operation.Step.KindValues.OperationBatch,
+ [ExecutionNodeType.Introspection] = GraphQL.Operation.Step.KindValues.Introspection,
+ [ExecutionNodeType.Node] = GraphQL.Operation.Step.KindValues.Node
+ }.ToFrozenDictionary();
+
+ public static ExecutePlanNodeSpan? Start(
+ ActivitySource source,
+ OperationPlanContext context,
+ ExecutionNode node,
+ string? schemaName,
+ FusionActivityEnricher enricher)
+ {
+ var activity = source.StartActivity("GraphQL Step Execution");
+
+ if (activity is null)
+ {
+ return null;
+ }
+
+ activity.SetTag(GraphQL.Processing.Type, GraphQL.Processing.TypeValues.StepExecute);
+
+ var operation = context.OperationPlan.Operation;
+ activity.EnrichOperation(operation.Definition.Operation, operation.Name);
+ activity.EnrichDocumentInfo(context.RequestContext.OperationDocumentInfo);
+
+ activity.SetTag(GraphQL.Operation.Step.Id, node.Id.ToString(CultureInfo.InvariantCulture));
+ activity.SetTag(GraphQL.Operation.Step.Kind, KindValues[node.Type]);
+ activity.SetTag(GraphQL.Operation.Step.Plan.Id, context.OperationPlan.Id);
+
+ if (node is OperationExecutionNode operationExecutionNode)
+ {
+ SetSourceSchemaTags(activity, operationExecutionNode.Operation, schemaName);
+ }
+ else if (node is OperationBatchExecutionNode batchExecutionNode)
+ {
+ SetSourceSchemaTags(activity, batchExecutionNode.Operation, schemaName);
+ }
+
+ return new ExecutePlanNodeSpan(activity, context, node, schemaName, enricher);
+ }
+
+ protected override void OnComplete()
+ {
+ if (Activity.Status != ActivityStatusCode.Error)
+ {
+ Activity.SetStatus(ActivityStatusCode.Ok);
+ }
+
+ enricher.EnrichExecutePlanNode(context, node, schemaName, Activity);
+ }
+
+ private static void SetSourceSchemaTags(Activity activity, OperationSourceText operation, string? schemaName)
+ {
+ if (!string.IsNullOrWhiteSpace(schemaName))
+ {
+ activity.SetTag(GraphQL.Source.Name, schemaName);
+ }
+
+ activity.SetTag(GraphQL.Source.Operation.Name, operation.Name);
+ activity.SetTag(GraphQL.Source.Operation.Kind, GraphQL.Operation.TypeValues[operation.Type]);
+ activity.SetTag(GraphQL.Source.Operation.Hash, $"sha256:{operation.Hash}");
+ }
+}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Spans/ExecuteRequestSpan.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Spans/ExecuteRequestSpan.cs
new file mode 100644
index 00000000000..ab6e528af29
--- /dev/null
+++ b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Spans/ExecuteRequestSpan.cs
@@ -0,0 +1,51 @@
+using System.Diagnostics;
+using HotChocolate.Execution;
+using HotChocolate.Language;
+
+namespace HotChocolate.Diagnostics;
+
+internal sealed class ExecuteRequestSpan(
+ Activity activity,
+ RequestContext context,
+ InstrumentationOptionsBase options,
+ ActivityEnricherBase? enricher,
+ bool shouldDisposeActivity)
+ : ExecuteRequestSpanBase(activity, context, options, enricher, shouldDisposeActivity)
+{
+ public static ExecuteRequestSpan? Start(
+ ActivitySource source,
+ RequestContext context,
+ InstrumentationOptionsBase options,
+ ActivityEnricherBase enricher)
+ {
+ var activity = StartActivity(source);
+
+ if (activity is null)
+ {
+ return null;
+ }
+
+ return new ExecuteRequestSpan(
+ activity,
+ context,
+ options,
+ enricher,
+ true);
+ }
+
+ protected override bool TryGetOperationInfo(
+ out OperationType operationType,
+ out string? operationName)
+ {
+ if (Context.GetOperationPlan() is { Operation: var operation })
+ {
+ operationType = operation.Definition.Operation;
+ operationName = operation.Name;
+ return true;
+ }
+
+ operationType = default;
+ operationName = null;
+ return false;
+ }
+}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Spans/PlanOperationSpan.cs b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Spans/PlanOperationSpan.cs
new file mode 100644
index 00000000000..0fb245e03d8
--- /dev/null
+++ b/src/HotChocolate/Fusion/src/Fusion.Diagnostics/Spans/PlanOperationSpan.cs
@@ -0,0 +1,46 @@
+using System.Diagnostics;
+using HotChocolate.Execution;
+using HotChocolate.Fusion.Diagnostics;
+using static HotChocolate.Diagnostics.SemanticConventions;
+
+namespace HotChocolate.Diagnostics;
+
+internal sealed class PlanOperationSpan(
+ Activity activity,
+ RequestContext context,
+ FusionActivityEnricher enricher,
+ string operationPlanId) : SpanBase(activity)
+{
+ public static PlanOperationSpan? Start(
+ ActivitySource source,
+ RequestContext context,
+ FusionActivityEnricher enricher,
+ string operationPlanId)
+ {
+ var activity = source.StartActivity("GraphQL Operation Planning");
+
+ if (activity is null)
+ {
+ return null;
+ }
+
+ activity.SetTag(GraphQL.Processing.Type, GraphQL.Processing.TypeValues.Plan);
+
+ activity.EnrichDocumentInfo(context.OperationDocumentInfo);
+
+ return new PlanOperationSpan(activity, context, enricher, operationPlanId);
+ }
+
+ protected override void OnComplete()
+ {
+ if (context.GetOperationPlan() is { } plan)
+ {
+ Activity.SetStatus(ActivityStatusCode.Ok);
+
+ var operation = plan.Operation;
+ Activity.EnrichOperation(operation.Definition.Operation, operation.Name);
+ }
+
+ enricher.EnrichPlanOperation(context, operationPlanId, Activity);
+ }
+}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Execution/Diagnostics/AggregateFusionExecutionDiagnosticEvents.cs b/src/HotChocolate/Fusion/src/Fusion.Execution/Diagnostics/AggregateFusionExecutionDiagnosticEvents.cs
index 2f81373196f..c2ef7993abc 100644
--- a/src/HotChocolate/Fusion/src/Fusion.Execution/Diagnostics/AggregateFusionExecutionDiagnosticEvents.cs
+++ b/src/HotChocolate/Fusion/src/Fusion.Execution/Diagnostics/AggregateFusionExecutionDiagnosticEvents.cs
@@ -186,7 +186,7 @@ public IDisposable ExecuteOperationNode(
public IDisposable ExecuteOperationBatchNode(
OperationPlanContext context,
- ExecutionNode node,
+ OperationBatchExecutionNode node,
string schemaName)
{
var scopes = new IDisposable[listeners.Length];
@@ -259,24 +259,6 @@ public IDisposable ExecuteSubscriptionNode(
return new AggregateActivityScope(scopes);
}
- public void SubscriptionTransportError(
- OperationPlanContext context,
- ExecutionNode node,
- string schemaName,
- ulong subscriptionId,
- Exception exception)
- {
- for (var i = 0; i < listeners.Length; i++)
- {
- listeners[i].SubscriptionTransportError(
- context,
- node,
- schemaName,
- subscriptionId,
- exception);
- }
- }
-
public void SubscriptionEventError(
OperationPlanContext context,
ExecutionNode node,
diff --git a/src/HotChocolate/Fusion/src/Fusion.Execution/Diagnostics/FusionExecutionDiagnosticEventListener.cs b/src/HotChocolate/Fusion/src/Fusion.Execution/Diagnostics/FusionExecutionDiagnosticEventListener.cs
index f54cd83f3e2..aa224864e45 100644
--- a/src/HotChocolate/Fusion/src/Fusion.Execution/Diagnostics/FusionExecutionDiagnosticEventListener.cs
+++ b/src/HotChocolate/Fusion/src/Fusion.Execution/Diagnostics/FusionExecutionDiagnosticEventListener.cs
@@ -96,7 +96,7 @@ public virtual IDisposable ExecuteOperationNode(
///
public virtual IDisposable ExecuteOperationBatchNode(
OperationPlanContext context,
- ExecutionNode node,
+ OperationBatchExecutionNode node,
string schemaName)
=> EmptyScope;
@@ -137,16 +137,6 @@ public virtual IDisposable ExecuteSubscriptionNode(
ulong subscriptionId)
=> EmptyScope;
- ///
- public virtual void SubscriptionTransportError(
- OperationPlanContext context,
- ExecutionNode node,
- string schemaName,
- ulong subscriptionId,
- Exception exception)
- {
- }
-
///
public virtual void SubscriptionEventError(
OperationPlanContext context,
diff --git a/src/HotChocolate/Fusion/src/Fusion.Execution/Diagnostics/IFusionExecutionDiagnosticEvents.cs b/src/HotChocolate/Fusion/src/Fusion.Execution/Diagnostics/IFusionExecutionDiagnosticEvents.cs
index 56e50633fc0..81284ae5c0d 100644
--- a/src/HotChocolate/Fusion/src/Fusion.Execution/Diagnostics/IFusionExecutionDiagnosticEvents.cs
+++ b/src/HotChocolate/Fusion/src/Fusion.Execution/Diagnostics/IFusionExecutionDiagnosticEvents.cs
@@ -130,7 +130,7 @@ IDisposable ExecuteOperationNode(
///
IDisposable ExecuteOperationBatchNode(
OperationPlanContext context,
- ExecutionNode node,
+ OperationBatchExecutionNode node,
string schemaName);
///
@@ -234,33 +234,6 @@ void SourceSchemaStoreError(
string schemaName,
Exception error);
- ///
- /// Called when a transport error occurs while communicating with a source schema
- /// during subscription operations. This includes connection drops, network timeouts,
- /// and other communication failures specific to real-time subscriptions.
- ///
- ///
- /// The operation plan context.
- ///
- ///
- /// The execution node that was storing the response.
- ///
- ///
- /// The name of the source schema whose response could not be stored.
- ///
- ///
- /// An internal identifier for the subscription instance.
- ///
- ///
- /// The transport exception that occurred.
- ///
- void SubscriptionTransportError(
- OperationPlanContext context,
- ExecutionNode node,
- string schemaName,
- ulong subscriptionId,
- Exception exception);
-
///
/// Called when an error occurs while processing a subscription event result.
/// This covers errors in event handling, data transformation, or result generation
diff --git a/src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Nodes/OperationExecutionNode.cs b/src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Nodes/OperationExecutionNode.cs
index aae561d3d1d..e0a7d462099 100644
--- a/src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Nodes/OperationExecutionNode.cs
+++ b/src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Nodes/OperationExecutionNode.cs
@@ -317,7 +317,7 @@ internal async Task SubscribeAsync(
catch (Exception ex)
{
AddErrors(context, ex, variables, _responseNames);
- context.DiagnosticEvents.SubscriptionTransportError(context, this, schemaName, subscriptionId, ex);
+ context.DiagnosticEvents.SourceSchemaTransportError(context, this, schemaName, ex);
return SubscriptionResult.Failed(subscriptionId, ex);
}
}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Utilities/Extensions/OperationResolverHelper.cs b/src/HotChocolate/Fusion/src/Fusion.Utilities/Extensions/FusionDocumentNodeExtensions.cs
similarity index 57%
rename from src/HotChocolate/Fusion/src/Fusion.Utilities/Extensions/OperationResolverHelper.cs
rename to src/HotChocolate/Fusion/src/Fusion.Utilities/Extensions/FusionDocumentNodeExtensions.cs
index 42a6c4696d3..772487fbe6f 100644
--- a/src/HotChocolate/Fusion/src/Fusion.Utilities/Extensions/OperationResolverHelper.cs
+++ b/src/HotChocolate/Fusion/src/Fusion.Utilities/Extensions/FusionDocumentNodeExtensions.cs
@@ -27,15 +27,13 @@ public static OperationDefinitionNode GetOperation(
}
else
{
- // TODO : EXCEPTION
- throw new Exception("OperationResolverHelper_MultipleOperation");
+ throw OperationResolverHelper_MultipleOperation(operation, op);
}
}
if (operation is null)
{
- // TODO : EXCEPTION
- throw new Exception("OperationResolverHelper_NoOperationFound");
+ throw OperationResolverHelper_NoOperationFound(document);
}
return operation;
@@ -51,8 +49,7 @@ public static OperationDefinitionNode GetOperation(
}
}
- // TODO : EXCEPTION
- throw new Exception("OperationResolverHelper_InvalidOperationName");
+ throw OperationResolverHelper_InvalidOperationName(document, operationName);
}
}
@@ -73,4 +70,29 @@ public static Dictionary GetFragments(
return map;
}
+
+ private static GraphQLException OperationResolverHelper_NoOperationFound(
+ DocumentNode documentNode) =>
+ new(ErrorBuilder.New()
+ .SetMessage("There are no operations in the GraphQL document.")
+ .AddLocation(documentNode)
+ .Build());
+
+ private static GraphQLException OperationResolverHelper_MultipleOperation(
+ OperationDefinitionNode firstOperation,
+ OperationDefinitionNode secondOperation) =>
+ new(ErrorBuilder.New()
+ .SetMessage("The operation name can only be omitted if there is just one operation in a GraphQL document.")
+ .AddLocation(firstOperation)
+ .AddLocation(secondOperation)
+ .Build());
+
+ private static GraphQLException OperationResolverHelper_InvalidOperationName(
+ DocumentNode documentNode,
+ string operationName) =>
+ new(ErrorBuilder.New()
+ .SetMessage("The specified operation `{0}` cannot be found.", operationName)
+ .AddLocation(documentNode)
+ .SetExtension("operationName", operationName)
+ .Build());
}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Utilities/HotChocolate.Fusion.Utilities.csproj b/src/HotChocolate/Fusion/src/Fusion.Utilities/HotChocolate.Fusion.Utilities.csproj
index 0fcb3b3147e..52e0cb9bc72 100644
--- a/src/HotChocolate/Fusion/src/Fusion.Utilities/HotChocolate.Fusion.Utilities.csproj
+++ b/src/HotChocolate/Fusion/src/Fusion.Utilities/HotChocolate.Fusion.Utilities.csproj
@@ -6,6 +6,7 @@
+
diff --git a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/VariableCoercionTests.InputObject_Invalid_Field.yaml b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/VariableCoercionTests.InputObject_Invalid_Field.yaml
index 7b2490d8f64..ad5a138da57 100644
--- a/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/VariableCoercionTests.InputObject_Invalid_Field.yaml
+++ b/src/HotChocolate/Fusion/test/Fusion.AspNetCore.Tests/__snapshots__/VariableCoercionTests.InputObject_Invalid_Field.yaml
@@ -19,7 +19,7 @@ response:
{
"message": "The field \u0060invalidField\u0060 is not defined on the input object type \u0060Cat\u0060.",
"extensions": {
- "variable": "/cat"
+ "variable": "cat"
}
}
]
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/ActivityTestHelper.cs b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/ActivityTestHelper.cs
index f05657828b7..73d6efe9eac 100644
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/ActivityTestHelper.cs
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/ActivityTestHelper.cs
@@ -5,12 +5,16 @@ namespace HotChocolate.Fusion.Diagnostics;
public static partial class ActivityTestHelper
{
+ [GeneratedRegex(@" in (?.+?):line (?\d+)", RegexOptions.CultureInvariant)]
+ private static partial Regex StackTracePathRegex();
+
public static IDisposable CaptureActivities(out object activities)
{
var sync = new object();
var listener = new ActivityListener();
var root = new OrderedDictionary();
var lookup = new Dictionary>();
+ var spanLookup = new Dictionary>();
Activity rootActivity = null!;
listener.ShouldListenTo = source =>
@@ -32,6 +36,17 @@ public static IDisposable CaptureActivities(out object activities)
{
RegisterActivity(a, parentData);
lookup[a] = (OrderedDictionary)a.GetCustomProperty("test.data")!;
+ spanLookup[a.SpanId] = (OrderedDictionary)a.GetCustomProperty("test.data")!;
+ return;
+ }
+
+ if (a.Parent is null
+ && a.ParentSpanId != default
+ && spanLookup.TryGetValue(a.ParentSpanId, out parentData))
+ {
+ RegisterActivity(a, parentData);
+ lookup[a] = (OrderedDictionary)a.GetCustomProperty("test.data")!;
+ spanLookup[a.SpanId] = (OrderedDictionary)a.GetCustomProperty("test.data")!;
}
}
};
@@ -43,6 +58,7 @@ public static IDisposable CaptureActivities(out object activities)
rootActivity = HotChocolateFusionActivitySource.Source.StartActivity()!;
rootActivity.SetCustomProperty("test.data", root);
lookup[rootActivity] = root;
+ spanLookup[rootActivity.SpanId] = root;
activities = root;
return new Session(rootActivity, listener);
@@ -85,18 +101,25 @@ private static void SerializeActivity(Activity activity)
}
private static IEnumerable> ScrubEventTags(
- IEnumerable> tags)
+ IEnumerable>? tags)
{
+ if (tags is null)
+ {
+ yield break;
+ }
+
foreach (var tag in tags)
{
- if (tag is { Key: "exception.stacktrace", Value: string stackTrace })
+ if (tag.Value is string stackTrace
+ && (tag.Key.Equals("exception.stacktrace", StringComparison.Ordinal)
+ || tag.Key.EndsWith(".stacktrace", StringComparison.Ordinal)))
{
yield return new KeyValuePair(
tag.Key,
StackTracePathRegex().Replace(stackTrace, match =>
{
- var fileName = System.IO.Path.GetFileName(match.Groups[1].Value);
- var lineNumber = match.Groups[2].Value;
+ var fileName = System.IO.Path.GetFileName(match.Groups["path"].Value);
+ var lineNumber = match.Groups["line"].Value;
return $" in {fileName}:line {lineNumber}";
}));
}
@@ -107,9 +130,6 @@ private static void SerializeActivity(Activity activity)
}
}
- [GeneratedRegex(@" in (.+):line (\d+)")]
- private static partial Regex StackTracePathRegex();
-
private sealed class Session : IDisposable
{
private readonly Activity _activity;
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/QueryInstrumentationTests.cs b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/FusionActivityExecutionDiagnosticListenerTests.cs
similarity index 64%
rename from src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/QueryInstrumentationTests.cs
rename to src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/FusionActivityExecutionDiagnosticListenerTests.cs
index 333c442cb85..848b1658fc7 100644
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/QueryInstrumentationTests.cs
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/FusionActivityExecutionDiagnosticListenerTests.cs
@@ -1,12 +1,14 @@
-using System.Diagnostics;
using HotChocolate.Execution;
+using HotChocolate.Language;
+using HotChocolate.PersistedOperations;
+using HotChocolate.Types;
using Microsoft.Extensions.DependencyInjection;
using static HotChocolate.Fusion.Diagnostics.ActivityTestHelper;
namespace HotChocolate.Fusion.Diagnostics;
[Collection("Instrumentation")]
-public class QueryInstrumentationTests : FusionTestBase
+public class FusionActivityExecutionDiagnosticListenerTests : FusionTestBase
{
[Fact]
public async Task Track_Events_Of_A_Simple_Query_Default()
@@ -40,9 +42,9 @@ public async Task Track_Events_Of_A_Simple_Query_Default()
}
[Fact]
- public async Task Track_Events_Of_A_Simple_Query_Default_Rename_Root()
+ public async Task Allow_Document_To_Be_Captured()
{
- using (CaptureActivities(out _))
+ using (CaptureActivities(out var activities))
{
// arrange
using var server1 = CreateSourceSchema(
@@ -55,28 +57,28 @@ public async Task Track_Events_Of_A_Simple_Query_Default_Rename_Root()
],
configureGatewayBuilder: b => b.AddInstrumentation(o =>
{
- o.RenameRootActivity = true;
o.Scopes = FusionActivityScopes.All;
+ o.IncludeDocument = true;
}));
var executor = await gateway.Services.GetRequestExecutorAsync();
var request = OperationRequestBuilder.New()
- .SetDocument("{ sayHello }")
+ .SetDocument("query SayHelloOperation { sayHello }")
.Build();
// act
await executor.ExecuteAsync(request);
// assert
- Assert.Equal("CaptureActivities: query { sayHello }", Activity.Current!.DisplayName);
+ activities.MatchSnapshot();
}
}
[Fact]
- public async Task Parsing_Error_When_Rename_Root_Is_Activated()
+ public async Task Ensure_That_The_Validation_Activity_Has_An_Error_Status()
{
- using (CaptureActivities(out _))
+ using (CaptureActivities(out var activities))
{
// arrange
using var server1 = CreateSourceSchema(
@@ -89,28 +91,28 @@ public async Task Parsing_Error_When_Rename_Root_Is_Activated()
],
configureGatewayBuilder: b => b.AddInstrumentation(o =>
{
- o.RenameRootActivity = true;
o.Scopes = FusionActivityScopes.All;
+ o.IncludeDocument = true;
}));
var executor = await gateway.Services.GetRequestExecutorAsync();
var request = OperationRequestBuilder.New()
- .SetDocument("{ sayHello")
+ .SetDocument("query SayHelloOperation { sayHello_ }")
.Build();
// act
await executor.ExecuteAsync(request);
// assert
- Assert.Equal("CaptureActivities: Begin Parse Document", Activity.Current!.DisplayName);
+ activities.MatchSnapshot();
}
}
[Fact]
- public async Task Validation_Error_When_Rename_Root_Is_Activated()
+ public async Task Cause_A_Resolver_Error_That_Deletes_The_Whole_Result()
{
- using (CaptureActivities(out _))
+ using (CaptureActivities(out var activities))
{
// arrange
using var server1 = CreateSourceSchema(
@@ -123,34 +125,34 @@ public async Task Validation_Error_When_Rename_Root_Is_Activated()
],
configureGatewayBuilder: b => b.AddInstrumentation(o =>
{
- o.RenameRootActivity = true;
o.Scopes = FusionActivityScopes.All;
+ o.IncludeDocument = true;
}));
var executor = await gateway.Services.GetRequestExecutorAsync();
var request = OperationRequestBuilder.New()
- .SetDocument("{ abc123 }")
+ .SetDocument("query SayHelloOperation { causeFatalError }")
.Build();
// act
await executor.ExecuteAsync(request);
// assert
- Assert.Equal("CaptureActivities: Begin Validate Document",
- Activity.Current!.DisplayName);
+ activities.MatchSnapshot();
}
}
[Fact]
- public async Task Create_Operation_Display_Name_With_1_Field()
+ public async Task Source_Schema_Transport_Error()
{
using (CaptureActivities(out var activities))
{
// arrange
using var server1 = CreateSourceSchema(
"a",
- b => b.AddQueryType());
+ b => b.AddQueryType(),
+ isOffline: true);
using var gateway = await CreateCompositeSchemaAsync(
[
@@ -158,14 +160,14 @@ public async Task Create_Operation_Display_Name_With_1_Field()
],
configureGatewayBuilder: b => b.AddInstrumentation(o =>
{
- o.RenameRootActivity = true;
o.Scopes = FusionActivityScopes.All;
+ o.IncludeDocument = true;
}));
var executor = await gateway.Services.GetRequestExecutorAsync();
var request = OperationRequestBuilder.New()
- .SetDocument("{ a: sayHello }")
+ .SetDocument("{ sayHello }")
.Build();
// act
@@ -177,29 +179,31 @@ public async Task Create_Operation_Display_Name_With_1_Field()
}
[Fact]
- public async Task Create_Operation_Display_Name_With_1_Field_And_Op()
+ public async Task Track_Events_Of_A_Query_With_Multiple_Sources()
{
using (CaptureActivities(out var activities))
{
// arrange
using var server1 = CreateSourceSchema(
"a",
- b => b.AddQueryType());
+ b => b.AddQueryType());
+
+ using var server2 = CreateSourceSchema(
+ "b",
+ b => b.AddQueryType());
using var gateway = await CreateCompositeSchemaAsync(
[
- ("a", server1)
+ ("a", server1),
+ ("b", server2)
],
configureGatewayBuilder: b => b.AddInstrumentation(o =>
- {
- o.RenameRootActivity = true;
- o.Scopes = FusionActivityScopes.All;
- }));
+ o.Scopes = FusionActivityScopes.All));
var executor = await gateway.Services.GetRequestExecutorAsync();
var request = OperationRequestBuilder.New()
- .SetDocument("query GetA { a: sayHello }")
+ .SetDocument("{ sayHello sayGoodbye }")
.Build();
// act
@@ -211,11 +215,14 @@ public async Task Create_Operation_Display_Name_With_1_Field_And_Op()
}
[Fact]
- public async Task Create_Operation_Display_Name_With_3_Field()
+ public async Task PersistedOperation_LoadsFromStorage_DefaultScopes()
{
using (CaptureActivities(out var activities))
{
// arrange
+ var storage = new InMemoryOperationDocumentStorage();
+ storage.Add("sayHelloOp", "{ sayHello }");
+
using var server1 = CreateSourceSchema(
"a",
b => b.AddQueryType());
@@ -224,20 +231,16 @@ public async Task Create_Operation_Display_Name_With_3_Field()
[
("a", server1)
],
- configureGatewayBuilder: b => b.AddInstrumentation(o =>
- {
- o.RenameRootActivity = true;
- o.Scopes = FusionActivityScopes.All;
- }));
+ configureGatewayBuilder: b => b
+ .AddInstrumentation()
+ .ConfigureSchemaServices(
+ (_, s) => s.AddSingleton(storage))
+ .UsePersistedOperationPipeline());
var executor = await gateway.Services.GetRequestExecutorAsync();
- var request = OperationRequestBuilder.New()
- .SetDocument("{ a: sayHello b: sayHello c: sayHello }")
- .Build();
-
// act
- await executor.ExecuteAsync(request);
+ await executor.ExecuteAsync(OperationRequest.FromId("sayHelloOp"));
// assert
activities.MatchSnapshot();
@@ -245,7 +248,7 @@ public async Task Create_Operation_Display_Name_With_3_Field()
}
[Fact]
- public async Task Create_Operation_Display_Name_With_4_Field()
+ public async Task ParsingError_InvalidGraphQLDocument_ReportsErrorStatus()
{
using (CaptureActivities(out var activities))
{
@@ -259,15 +262,12 @@ public async Task Create_Operation_Display_Name_With_4_Field()
("a", server1)
],
configureGatewayBuilder: b => b.AddInstrumentation(o =>
- {
- o.RenameRootActivity = true;
- o.Scopes = FusionActivityScopes.All;
- }));
+ o.Scopes = FusionActivityScopes.All));
var executor = await gateway.Services.GetRequestExecutorAsync();
var request = OperationRequestBuilder.New()
- .SetDocument("{ a: sayHello b: sayHello c: sayHello d: sayHello }")
+ .SetDocument("{ sayHello")
.Build();
// act
@@ -279,7 +279,7 @@ public async Task Create_Operation_Display_Name_With_4_Field()
}
[Fact]
- public async Task Track_Events_Of_A_Simple_Query_Detailed()
+ public async Task ValidationError_UnknownField_ReportsErrorStatus()
{
using (CaptureActivities(out var activities))
{
@@ -298,7 +298,7 @@ public async Task Track_Events_Of_A_Simple_Query_Detailed()
var executor = await gateway.Services.GetRequestExecutorAsync();
var request = OperationRequestBuilder.New()
- .SetDocument("{ sayHello }")
+ .SetDocument("{ unknownField123 }")
.Build();
// act
@@ -310,7 +310,7 @@ public async Task Track_Events_Of_A_Simple_Query_Detailed()
}
[Fact]
- public async Task Ensure_Operation_Name_Is_Used_As_Request_Name()
+ public async Task DefaultScopes_ExcludesExecuteRequestAndParseDocumentSpans()
{
using (CaptureActivities(out var activities))
{
@@ -323,13 +323,12 @@ public async Task Ensure_Operation_Name_Is_Used_As_Request_Name()
[
("a", server1)
],
- configureGatewayBuilder: b => b.AddInstrumentation(o =>
- o.Scopes = FusionActivityScopes.All));
+ configureGatewayBuilder: b => b.AddInstrumentation());
var executor = await gateway.Services.GetRequestExecutorAsync();
var request = OperationRequestBuilder.New()
- .SetDocument("query SayHelloOperation { sayHello }")
+ .SetDocument("{ sayHello }")
.Build();
// act
@@ -341,7 +340,7 @@ public async Task Ensure_Operation_Name_Is_Used_As_Request_Name()
}
[Fact]
- public async Task Allow_Document_To_Be_Captured()
+ public async Task AllScopes_IncludesAllSpans()
{
using (CaptureActivities(out var activities))
{
@@ -355,15 +354,12 @@ public async Task Allow_Document_To_Be_Captured()
("a", server1)
],
configureGatewayBuilder: b => b.AddInstrumentation(o =>
- {
- o.Scopes = FusionActivityScopes.All;
- o.IncludeDocument = true;
- }));
+ o.Scopes = FusionActivityScopes.All));
var executor = await gateway.Services.GetRequestExecutorAsync();
var request = OperationRequestBuilder.New()
- .SetDocument("query SayHelloOperation { sayHello }")
+ .SetDocument("{ sayHello }")
.Build();
// act
@@ -375,7 +371,7 @@ public async Task Allow_Document_To_Be_Captured()
}
[Fact]
- public async Task Ensure_That_The_Validation_Activity_Has_An_Error_Status()
+ public async Task CustomScopes_OnlyValidateAndPlan_LimitsSpans()
{
using (CaptureActivities(out var activities))
{
@@ -389,15 +385,13 @@ public async Task Ensure_That_The_Validation_Activity_Has_An_Error_Status()
("a", server1)
],
configureGatewayBuilder: b => b.AddInstrumentation(o =>
- {
- o.Scopes = FusionActivityScopes.All;
- o.IncludeDocument = true;
- }));
+ o.Scopes = FusionActivityScopes.ValidateDocument
+ | FusionActivityScopes.PlanOperation));
var executor = await gateway.Services.GetRequestExecutorAsync();
var request = OperationRequestBuilder.New()
- .SetDocument("query SayHelloOperation { sayHello_ }")
+ .SetDocument("{ sayHello }")
.Build();
// act
@@ -408,19 +402,25 @@ public async Task Ensure_That_The_Validation_Activity_Has_An_Error_Status()
}
}
- [Fact]
- public async Task Cause_A_Resolver_Error_That_Deletes_The_Whole_Result()
+ [Fact(Skip = "This is flaky")]
+ public async Task MultipleSources_HttpRequestError_MarksNodeSpanAsError()
{
using (CaptureActivities(out var activities))
{
// arrange
using var server1 = CreateSourceSchema(
"a",
- b => b.AddQueryType());
+ b => b.AddQueryType());
+
+ using var server2 = CreateSourceSchema(
+ "b",
+ b => b.AddQueryType(),
+ isOffline: true);
using var gateway = await CreateCompositeSchemaAsync(
[
- ("a", server1)
+ ("a", server1),
+ ("b", server2)
],
configureGatewayBuilder: b => b.AddInstrumentation(o =>
{
@@ -431,7 +431,7 @@ public async Task Cause_A_Resolver_Error_That_Deletes_The_Whole_Result()
var executor = await gateway.Services.GetRequestExecutorAsync();
var request = OperationRequestBuilder.New()
- .SetDocument("query SayHelloOperation { causeFatalError }")
+ .SetDocument("{ sayHello sayGoodbye }")
.Build();
// act
@@ -443,18 +443,23 @@ public async Task Cause_A_Resolver_Error_That_Deletes_The_Whole_Result()
}
[Fact]
- public async Task Cause_A_Resolver_Error_That_Deletes_The_Whole_Result_Deep()
+ public async Task MultipleSources_SourceSchemaResolverError_RecordsDeeplyNestedError()
{
using (CaptureActivities(out var activities))
{
// arrange
using var server1 = CreateSourceSchema(
"a",
- b => b.AddQueryType());
+ b => b.AddQueryType());
+
+ using var server2 = CreateSourceSchema(
+ "b",
+ b => b.AddQueryType());
using var gateway = await CreateCompositeSchemaAsync(
[
- ("a", server1)
+ ("a", server1),
+ ("b", server2)
],
configureGatewayBuilder: b => b.AddInstrumentation(o =>
{
@@ -467,14 +472,11 @@ public async Task Cause_A_Resolver_Error_That_Deletes_The_Whole_Result_Deep()
var request = OperationRequestBuilder.New()
.SetDocument(
"""
- query SayHelloOperation {
- deep {
- deeper {
- deeps {
- deeper {
- causeFatalError
- }
- }
+ {
+ sayHello
+ deepB {
+ deeperB {
+ causeFatalError
}
}
}
@@ -490,14 +492,52 @@ query SayHelloOperation {
}
[Fact]
- public async Task Track_Events_Of_A_Simple_Query_With_Node_Scopes()
+ public async Task DocumentCache_SecondExecution_RecordsCacheHitEvent()
{
+ // arrange
+ using var server1 = CreateSourceSchema(
+ "a",
+ b => b.AddQueryType());
+
+ using var gateway = await CreateCompositeSchemaAsync(
+ [
+ ("a", server1)
+ ],
+ configureGatewayBuilder: b => b.AddInstrumentation(o =>
+ o.Scopes = FusionActivityScopes.All));
+
+ var executor = await gateway.Services.GetRequestExecutorAsync();
+
+ // act - execute twice so second uses cached document
+ var request = OperationRequestBuilder.New()
+ .SetDocument("{ sayHello }")
+ .SetDocumentHash(new OperationDocumentHash("abc", "sha256", HashFormat.Hex))
+ .Build();
+
+ await executor.ExecuteAsync(request);
+
+ using (CaptureActivities(out var activities))
+ {
+ await executor.ExecuteAsync(request);
+
+ // assert
+ activities.MatchSnapshot();
+ }
+ }
+
+ [Fact]
+ public async Task SubscriptionEvent_Records_Subscription_Event_Span()
+ {
+ using var cts = new CancellationTokenSource(5000);
+
using (CaptureActivities(out var activities))
{
// arrange
using var server1 = CreateSourceSchema(
"a",
- b => b.AddQueryType());
+ b => b
+ .AddQueryType()
+ .AddSubscriptionType());
using var gateway = await CreateCompositeSchemaAsync(
[
@@ -508,83 +548,110 @@ public async Task Track_Events_Of_A_Simple_Query_With_Node_Scopes()
var executor = await gateway.Services.GetRequestExecutorAsync();
- var request = OperationRequestBuilder.New()
- .SetDocument("{ sayHello }")
- .Build();
-
// act
- await executor.ExecuteAsync(request);
+ await using var result = await executor.ExecuteAsync(
+ "subscription OnMessageSubscription { onMessage }");
+ await using var responseStream = result.ExpectResponseStream();
+ var results = responseStream.ReadResultsAsync().GetAsyncEnumerator(cts.Token);
+
+ try
+ {
+ Assert.True(await results.MoveNextAsync());
+ }
+ finally
+ {
+ await results.DisposeAsync();
+ }
// assert
activities.MatchSnapshot();
}
}
- [Fact]
- public async Task Source_Schema_Transport_Error()
+ [Fact(Skip = "Errors are not correctly triggered")]
+ public async Task SubscriptionEventError_Records_Subscription_Event_Error()
{
+ using var cts = new CancellationTokenSource(5000);
+
using (CaptureActivities(out var activities))
{
// arrange
using var server1 = CreateSourceSchema(
"a",
- b => b.AddQueryType(),
- isOffline: true);
+ b => b
+ .AddQueryType()
+ .AddSubscriptionType());
using var gateway = await CreateCompositeSchemaAsync(
[
("a", server1)
],
configureGatewayBuilder: b => b.AddInstrumentation(o =>
- {
- o.Scopes = FusionActivityScopes.All;
- o.IncludeDocument = true;
- }));
+ o.Scopes = FusionActivityScopes.All));
var executor = await gateway.Services.GetRequestExecutorAsync();
- var request = OperationRequestBuilder.New()
- .SetDocument("{ sayHello }")
- .Build();
-
// act
- await executor.ExecuteAsync(request);
+ await using var result = await executor.ExecuteAsync(
+ "subscription OnFailingMessageSubscription { onFailingMessage }");
+ await using var responseStream = result.ExpectResponseStream();
+ var results = responseStream.ReadResultsAsync().GetAsyncEnumerator(cts.Token);
+
+ try
+ {
+ Assert.True(await results.MoveNextAsync());
+ }
+ finally
+ {
+ await results.DisposeAsync();
+ }
// assert
activities.MatchSnapshot();
}
}
- [Fact]
- public async Task Track_Events_Of_A_Query_With_Multiple_Sources()
+ [Fact(Skip = "Errors are not correctly triggered")]
+ public async Task SubscriptionRequestFails_When_SourceSchema_Is_Offline()
{
using (CaptureActivities(out var activities))
{
// arrange
using var server1 = CreateSourceSchema(
"a",
- b => b.AddQueryType());
-
- using var server2 = CreateSourceSchema(
- "b",
- b => b.AddQueryType());
+ b => b
+ .AddQueryType()
+ .AddSubscriptionType(),
+ isOffline: true);
using var gateway = await CreateCompositeSchemaAsync(
[
- ("a", server1),
- ("b", server2)
+ ("a", server1)
],
configureGatewayBuilder: b => b.AddInstrumentation(o =>
o.Scopes = FusionActivityScopes.All));
var executor = await gateway.Services.GetRequestExecutorAsync();
- var request = OperationRequestBuilder.New()
- .SetDocument("{ sayHello sayGoodbye }")
- .Build();
-
// act
- await executor.ExecuteAsync(request);
+ IExecutionResult? result = null;
+
+ try
+ {
+ result = await executor.ExecuteAsync(
+ "subscription OnMessageSubscription { onMessage }");
+ }
+ catch
+ {
+ // expected for failed subscription handshake.
+ }
+ finally
+ {
+ if (result is not null)
+ {
+ await result.DisposeAsync();
+ }
+ }
// assert
activities.MatchSnapshot();
@@ -612,6 +679,24 @@ public class QueryB
public string SayGoodbye() => "goodbye";
}
+ [GraphQLName("Query")]
+ public class QueryBWithDeepError
+ {
+ public string SayGoodbye() => "goodbye";
+
+ public DeepB DeepB() => new();
+ }
+
+ public class DeepB
+ {
+ public DeeperB DeeperB() => new();
+ }
+
+ public class DeeperB
+ {
+ public string CauseFatalError() => throw new GraphQLException("deep fail");
+ }
+
public class Deep
{
public Deeper Deeper() => new();
@@ -623,4 +708,55 @@ public class Deeper
{
public Deep[] Deeps() => [new Deep()];
}
+
+ public class Subscription
+ {
+ public async IAsyncEnumerable OnMessageStream()
+ {
+ yield return "hello";
+ await Task.CompletedTask;
+ }
+
+ [Subscribe(With = nameof(OnMessageStream))]
+ public string OnMessage([EventMessage] string message) => message;
+
+ public async IAsyncEnumerable OnFailingMessageStream()
+ {
+ yield return "hello";
+ await Task.CompletedTask;
+ }
+
+ [Subscribe(With = nameof(OnFailingMessageStream))]
+ public string OnFailingMessage([EventMessage] string message)
+ => throw new InvalidOperationException("Subscription event failed.");
+ }
+
+ private sealed class InMemoryOperationDocumentStorage : IOperationDocumentStorage
+ {
+ private readonly Dictionary _cache = [];
+
+ public void Add(string id, string document)
+ => _cache[id] = Utf8GraphQLParser.Parse(document);
+
+ public ValueTask TryReadAsync(
+ OperationDocumentId documentId,
+ CancellationToken cancellationToken = default)
+ {
+ if (_cache.TryGetValue(documentId.Value, out var document))
+ {
+ return new ValueTask(new OperationDocument(document));
+ }
+
+ return new ValueTask(default(IOperationDocument));
+ }
+
+ public ValueTask SaveAsync(
+ OperationDocumentId documentId,
+ IOperationDocument document,
+ CancellationToken cancellationToken = default)
+ {
+ _cache[documentId.Value] = Utf8GraphQLParser.Parse(document.AsSpan());
+ return default;
+ }
+ }
}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/ServerInstrumentationTests.cs b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/FusionActivityServerDiagnosticListenerTests.cs
similarity index 85%
rename from src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/ServerInstrumentationTests.cs
rename to src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/FusionActivityServerDiagnosticListenerTests.cs
index f5d49d69610..fd0d7d27498 100644
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/ServerInstrumentationTests.cs
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/FusionActivityServerDiagnosticListenerTests.cs
@@ -1,3 +1,4 @@
+using HotChocolate.Diagnostics;
using HotChocolate.Transport.Http;
using Microsoft.Extensions.DependencyInjection;
using static HotChocolate.Fusion.Diagnostics.ActivityTestHelper;
@@ -6,11 +7,11 @@
namespace HotChocolate.Fusion.Diagnostics;
[Collection("Instrumentation")]
-public class ServerInstrumentationTests : FusionTestBase
+public class FusionActivityServerDiagnosticListenerTests : FusionTestBase
{
private static readonly Uri s_url = new("http://localhost:5000/graphql");
- [Fact(Skip = "This is flaky")]
+ [Fact]
public async Task Http_Post_Single_Request_Default()
{
using (CaptureActivities(out var activities))
@@ -30,13 +31,14 @@ public async Task Http_Post_Single_Request_Default()
// act
using var result = await client.PostAsync(request, s_url);
+ await result.ReadAsResultAsync();
// assert
activities.MatchSnapshot();
}
}
- [Fact(Skip = "This is flaky")]
+ [Fact]
public async Task Http_Post_Single_Request()
{
using (CaptureActivities(out var activities))
@@ -57,13 +59,14 @@ public async Task Http_Post_Single_Request()
// act
using var result = await client.PostAsync(request, s_url);
+ await result.ReadAsResultAsync();
// assert
activities.MatchSnapshot();
}
}
- [Fact(Skip = "This is flaky")]
+ [Fact]
public async Task Http_Get_Single_Request()
{
using (CaptureActivities(out var activities))
@@ -84,13 +87,14 @@ public async Task Http_Get_Single_Request()
// act
using var result = await client.GetAsync(request, s_url);
+ await result.ReadAsResultAsync();
// assert
activities.MatchSnapshot();
}
}
- [Fact(Skip = "This is flaky")]
+ [Fact]
public async Task Http_Post_Variables_Are_Not_Automatically_Added_To_Activities()
{
using (CaptureActivities(out var activities))
@@ -117,13 +121,14 @@ public async Task Http_Post_Variables_Are_Not_Automatically_Added_To_Activities(
// act
using var result = await client.PostAsync(request, s_url);
+ await result.ReadAsResultAsync();
// assert
activities.MatchSnapshot();
}
}
- [Fact(Skip = "This is flaky")]
+ [Fact]
public async Task Http_Post_Add_Variables_To_Http_Activity()
{
using (CaptureActivities(out var activities))
@@ -154,14 +159,15 @@ public async Task Http_Post_Add_Variables_To_Http_Activity()
// act
using var result = await client.PostAsync(request, s_url);
+ await result.ReadAsResultAsync();
// assert
activities.MatchSnapshot();
}
}
- [Fact(Skip = "This is flaky")]
- public async Task Http_Post_Add_Query_To_Http_Activity()
+ [Fact]
+ public async Task Http_Post_With_Extensions_Map()
{
using (CaptureActivities(out var activities))
{
@@ -173,11 +179,7 @@ public async Task Http_Post_Add_Query_To_Http_Activity()
using var gateway = await CreateCompositeSchemaAsync(
[("a", server)],
configureGatewayBuilder: b => b.AddInstrumentation(
- o =>
- {
- o.Scopes = FusionActivityScopes.All;
- o.RequestDetails = RequestDetails.Default | RequestDetails.Operation;
- }));
+ o => o.Scopes = FusionActivityScopes.All));
using var client = GraphQLHttpClient.Create(gateway.CreateClient());
@@ -187,18 +189,20 @@ public async Task Http_Post_Add_Query_To_Http_Activity()
greeting(name: $name)
}
""",
- variables: new Dictionary { { "name", "World" } });
+ variables: new Dictionary { { "name", "World" } },
+ extensions: new Dictionary { { "test", "abc" } });
// act
using var result = await client.PostAsync(request, s_url);
+ await result.ReadAsResultAsync();
// assert
activities.MatchSnapshot();
}
}
- [Fact(Skip = "This is flaky")]
- public async Task Http_Post_With_Extensions_Map()
+ [Fact]
+ public async Task Http_Get_SDL_Download()
{
using (CaptureActivities(out var activities))
{
@@ -212,27 +216,20 @@ public async Task Http_Post_With_Extensions_Map()
configureGatewayBuilder: b => b.AddInstrumentation(
o => o.Scopes = FusionActivityScopes.All));
- using var client = GraphQLHttpClient.Create(gateway.CreateClient());
-
- var request = new OperationRequest(
- query: """
- query ($name: String!) {
- greeting(name: $name)
- }
- """,
- variables: new Dictionary { { "name", "World" } },
- extensions: new Dictionary { { "test", "abc" } });
+ var httpClient = gateway.CreateClient();
+ var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:5000/graphql?sdl");
// act
- using var result = await client.PostAsync(request, s_url);
+ var response = await httpClient.SendAsync(request);
// assert
+ await response.Content.ReadAsStringAsync();
activities.MatchSnapshot();
}
}
- [Fact(Skip = "This is flaky")]
- public async Task Http_Get_SDL_Download()
+ [Fact]
+ public async Task Http_Post_Parser_Error()
{
using (CaptureActivities(out var activities))
{
@@ -246,20 +243,33 @@ public async Task Http_Get_SDL_Download()
configureGatewayBuilder: b => b.AddInstrumentation(
o => o.Scopes = FusionActivityScopes.All));
- var httpClient = gateway.CreateClient();
- var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:5000/graphql?sdl");
+ using var client = GraphQLHttpClient.Create(gateway.CreateClient());
+
+ // lang=text
+ var request = new OperationRequest(
+ """
+ {
+ deep {
+ deeper {
+ 1deeps {
+ name
+ }
+ }
+ }
+ }
+ """);
// act
- var response = await httpClient.SendAsync(request);
+ using var result = await client.PostAsync(request, s_url);
+ await result.ReadAsResultAsync();
// assert
- await response.Content.ReadAsStringAsync();
activities.MatchSnapshot();
}
}
- [Fact(Skip = "Not yet implemented")]
- public async Task Http_Post_Capture_Deferred_Response()
+ [Fact]
+ public async Task RequestDetails_None_ExcludesAllDetails()
{
using (CaptureActivities(out var activities))
{
@@ -271,25 +281,34 @@ public async Task Http_Post_Capture_Deferred_Response()
using var gateway = await CreateCompositeSchemaAsync(
[("a", server)],
configureGatewayBuilder: b => b.AddInstrumentation(
- o => o.Scopes = FusionActivityScopes.All));
+ o =>
+ {
+ o.Scopes = FusionActivityScopes.All;
+ o.RequestDetails = RequestDetails.None;
+ }));
using var client = GraphQLHttpClient.Create(gateway.CreateClient());
var request = new OperationRequest(
- """
- TODO
- """);
+ query: """
+ query GetGreeting($name: String!) {
+ greeting(name: $name)
+ }
+ """,
+ variables: new Dictionary { { "name", "World" } },
+ extensions: new Dictionary { { "test", "abc" } });
// act
using var result = await client.PostAsync(request, s_url);
+ await result.ReadAsResultAsync();
// assert
activities.MatchSnapshot();
}
}
- [Fact(Skip = "This is flaky")]
- public async Task Http_Post_Parser_Error()
+ [Fact]
+ public async Task RequestDetails_All_IncludesAllDetails()
{
using (CaptureActivities(out var activities))
{
@@ -301,34 +320,34 @@ public async Task Http_Post_Parser_Error()
using var gateway = await CreateCompositeSchemaAsync(
[("a", server)],
configureGatewayBuilder: b => b.AddInstrumentation(
- o => o.Scopes = FusionActivityScopes.All));
+ o =>
+ {
+ o.Scopes = FusionActivityScopes.All;
+ o.RequestDetails = RequestDetails.All;
+ }));
using var client = GraphQLHttpClient.Create(gateway.CreateClient());
- // lang=text
var request = new OperationRequest(
- """
- {
- deep {
- deeper {
- 1deeps {
- name
- }
- }
+ query: """
+ query GetGreeting($name: String!) {
+ greeting(name: $name)
}
- }
- """);
+ """,
+ variables: new Dictionary { { "name", "World" } },
+ extensions: new Dictionary { { "test", "abc" } });
// act
using var result = await client.PostAsync(request, s_url);
+ await result.ReadAsResultAsync();
// assert
activities.MatchSnapshot();
}
}
- [Fact(Skip = "This is flaky")]
- public async Task Parsing_Error_When_Rename_Root_Is_Activated()
+ [Fact]
+ public async Task RequestDetails_DocumentOnly_IncludesDocumentTag()
{
using (CaptureActivities(out var activities))
{
@@ -343,24 +362,24 @@ public async Task Parsing_Error_When_Rename_Root_Is_Activated()
o =>
{
o.Scopes = FusionActivityScopes.All;
- o.RenameRootActivity = true;
+ o.RequestDetails = RequestDetails.Document;
}));
using var client = GraphQLHttpClient.Create(gateway.CreateClient());
- // lang=text
- var request = new OperationRequest("{ 1 }");
+ var request = new OperationRequest("{ sayHello }");
// act
using var result = await client.PostAsync(request, s_url);
+ await result.ReadAsResultAsync();
// assert
activities.MatchSnapshot();
}
}
- [Fact(Skip = "This is flaky")]
- public async Task Validation_Error_When_Rename_Root_Is_Activated()
+ [Fact]
+ public async Task RequestDetails_Default_IncludesIdHashOperationNameExtensions()
{
using (CaptureActivities(out var activities))
{
@@ -372,18 +391,21 @@ public async Task Validation_Error_When_Rename_Root_Is_Activated()
using var gateway = await CreateCompositeSchemaAsync(
[("a", server)],
configureGatewayBuilder: b => b.AddInstrumentation(
- o =>
- {
- o.Scopes = FusionActivityScopes.All;
- o.RenameRootActivity = true;
- }));
+ o => o.Scopes = FusionActivityScopes.All));
using var client = GraphQLHttpClient.Create(gateway.CreateClient());
- var request = new OperationRequest("{ abc }");
+ var request = new OperationRequest(
+ query: """
+ query GetGreeting {
+ sayHello
+ }
+ """,
+ extensions: new Dictionary { { "test", "abc" } });
// act
using var result = await client.PostAsync(request, s_url);
+ await result.ReadAsResultAsync();
// assert
activities.MatchSnapshot();
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/HotChocolate.Fusion.Diagnostics.Tests.csproj b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/HotChocolate.Fusion.Diagnostics.Tests.csproj
index 2cd3bc4c9ec..73db7d6bb3c 100644
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/HotChocolate.Fusion.Diagnostics.Tests.csproj
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/HotChocolate.Fusion.Diagnostics.Tests.csproj
@@ -7,6 +7,7 @@
+
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.AllScopes_IncludesAllSpans.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.AllScopes_IncludesAllSpans.snap
new file mode 100644
index 00000000000..3fef61eea55
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.AllScopes_IncludesAllSpans.snap
@@ -0,0 +1,149 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationPlanToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Parsing",
+ "DisplayName": "GraphQL Document Parsing",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "GraphQL Step Execution",
+ "DisplayName": "GraphQL Step Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "step_execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.step.id",
+ "Value": "1"
+ },
+ {
+ "Key": "graphql.operation.step.kind",
+ "Value": "operation"
+ },
+ {
+ "Key": "graphql.operation.step.plan.id",
+ "Value": "456132b93ebaf15a39534753bf72f9f4bfa1152a08d04bc8a88539feec1cb52c"
+ },
+ {
+ "Key": "graphql.source.name",
+ "Value": "a"
+ },
+ {
+ "Key": "graphql.source.operation.name",
+ "Value": "Op_f7e9989f_1"
+ },
+ {
+ "Key": "graphql.source.operation.kind",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.source.operation.hash",
+ "Value": "sha256:35c1feb1208268226c7d5d5d0ae122e4d38cb79621e862b1e252d37fc83c530a"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.Allow_Document_To_Be_Captured.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.Allow_Document_To_Be_Captured.snap
new file mode 100644
index 00000000000..fd10dc4ecf5
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.Allow_Document_To_Be_Captured.snap
@@ -0,0 +1,169 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "SayHelloOperation"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:6af18618ae20c266f6ffc352b78cb69b"
+ },
+ {
+ "Key": "graphql.document.body",
+ "Value": "query SayHelloOperation {\n sayHello\n}"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationPlanToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Parsing",
+ "DisplayName": "GraphQL Document Parsing",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:6af18618ae20c266f6ffc352b78cb69b"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:6af18618ae20c266f6ffc352b78cb69b"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:6af18618ae20c266f6ffc352b78cb69b"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "SayHelloOperation"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "SayHelloOperation"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:6af18618ae20c266f6ffc352b78cb69b"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "GraphQL Step Execution",
+ "DisplayName": "GraphQL Step Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "step_execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "SayHelloOperation"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:6af18618ae20c266f6ffc352b78cb69b"
+ },
+ {
+ "Key": "graphql.operation.step.id",
+ "Value": "1"
+ },
+ {
+ "Key": "graphql.operation.step.kind",
+ "Value": "operation"
+ },
+ {
+ "Key": "graphql.operation.step.plan.id",
+ "Value": "1334fb0da1250c6db5db84b6c98ccb2556f066942f8836d6ebd18fd870172787"
+ },
+ {
+ "Key": "graphql.source.name",
+ "Value": "a"
+ },
+ {
+ "Key": "graphql.source.operation.name",
+ "Value": "SayHelloOperation_6af18618_1"
+ },
+ {
+ "Key": "graphql.source.operation.kind",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.source.operation.hash",
+ "Value": "sha256:80b0d05aefd2459dcda18d0e26977b91c512e4ef58ab3e4e8a82c1ec98249b58"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.Cause_A_Resolver_Error_That_Deletes_The_Whole_Result.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.Cause_A_Resolver_Error_That_Deletes_The_Whole_Result.snap
new file mode 100644
index 00000000000..f00d97076dc
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.Cause_A_Resolver_Error_That_Deletes_The_Whole_Result.snap
@@ -0,0 +1,169 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "SayHelloOperation"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:851fb754d9ba6b5cc5a55ebcbea2621d"
+ },
+ {
+ "Key": "graphql.document.body",
+ "Value": "query SayHelloOperation {\n causeFatalError\n}"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationPlanToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Parsing",
+ "DisplayName": "GraphQL Document Parsing",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:851fb754d9ba6b5cc5a55ebcbea2621d"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:851fb754d9ba6b5cc5a55ebcbea2621d"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:851fb754d9ba6b5cc5a55ebcbea2621d"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "SayHelloOperation"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "SayHelloOperation"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:851fb754d9ba6b5cc5a55ebcbea2621d"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "GraphQL Step Execution",
+ "DisplayName": "GraphQL Step Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "step_execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "SayHelloOperation"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:851fb754d9ba6b5cc5a55ebcbea2621d"
+ },
+ {
+ "Key": "graphql.operation.step.id",
+ "Value": "1"
+ },
+ {
+ "Key": "graphql.operation.step.kind",
+ "Value": "operation"
+ },
+ {
+ "Key": "graphql.operation.step.plan.id",
+ "Value": "5f75eb886568e255310bed3eb3e1f7f1c91f1a22f71ac7c36f00d8df27400d8e"
+ },
+ {
+ "Key": "graphql.source.name",
+ "Value": "a"
+ },
+ {
+ "Key": "graphql.source.operation.name",
+ "Value": "SayHelloOperation_851fb754_1"
+ },
+ {
+ "Key": "graphql.source.operation.kind",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.source.operation.hash",
+ "Value": "sha256:1b35e9142c2e8235f31d2b3ae0de3d2ba54692a7aa6481803c3841fd135f4c4c"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.CustomScopes_OnlyValidateAndPlan_LimitsSpans.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.CustomScopes_OnlyValidateAndPlan_LimitsSpans.snap
new file mode 100644
index 00000000000..6e5564554ca
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.CustomScopes_OnlyValidateAndPlan_LimitsSpans.snap
@@ -0,0 +1,40 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.DefaultScopes_ExcludesExecuteRequestAndParseDocumentSpans.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.DefaultScopes_ExcludesExecuteRequestAndParseDocumentSpans.snap
new file mode 100644
index 00000000000..bfbb9fd1ca2
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.DefaultScopes_ExcludesExecuteRequestAndParseDocumentSpans.snap
@@ -0,0 +1,88 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Step Execution",
+ "DisplayName": "GraphQL Step Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "step_execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.step.id",
+ "Value": "1"
+ },
+ {
+ "Key": "graphql.operation.step.kind",
+ "Value": "operation"
+ },
+ {
+ "Key": "graphql.operation.step.plan.id",
+ "Value": "456132b93ebaf15a39534753bf72f9f4bfa1152a08d04bc8a88539feec1cb52c"
+ },
+ {
+ "Key": "graphql.source.name",
+ "Value": "a"
+ },
+ {
+ "Key": "graphql.source.operation.name",
+ "Value": "Op_f7e9989f_1"
+ },
+ {
+ "Key": "graphql.source.operation.kind",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.source.operation.hash",
+ "Value": "sha256:35c1feb1208268226c7d5d5d0ae122e4d38cb79621e862b1e252d37fc83c530a"
+ }
+ ],
+ "event": []
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.DocumentCache_SecondExecution_RecordsCacheHitEvent.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.DocumentCache_SecondExecution_RecordsCacheHitEvent.snap
new file mode 100644
index 00000000000..8f8fb30f6f4
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.DocumentCache_SecondExecution_RecordsCacheHitEvent.snap
@@ -0,0 +1,97 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": [
+ {
+ "Name": "RetrievedDocumentFromCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "GraphQL Step Execution",
+ "DisplayName": "GraphQL Step Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "step_execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.step.id",
+ "Value": "1"
+ },
+ {
+ "Key": "graphql.operation.step.kind",
+ "Value": "operation"
+ },
+ {
+ "Key": "graphql.operation.step.plan.id",
+ "Value": "456132b93ebaf15a39534753bf72f9f4bfa1152a08d04bc8a88539feec1cb52c"
+ },
+ {
+ "Key": "graphql.source.name",
+ "Value": "a"
+ },
+ {
+ "Key": "graphql.source.operation.name",
+ "Value": "Op_f7e9989f_1"
+ },
+ {
+ "Key": "graphql.source.operation.kind",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.source.operation.hash",
+ "Value": "sha256:35c1feb1208268226c7d5d5d0ae122e4d38cb79621e862b1e252d37fc83c530a"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.Ensure_That_The_Validation_Activity_Has_An_Error_Status.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.Ensure_That_The_Validation_Activity_Has_An_Error_Status.snap
new file mode 100644
index 00000000000..5312732e3a8
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.Ensure_That_The_Validation_Activity_Has_An_Error_Status.snap
@@ -0,0 +1,69 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "GraphQL Operation",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:bb1d246465341a97bdc727d6cd8ead5c"
+ },
+ {
+ "Key": "graphql.document.body",
+ "Value": "query SayHelloOperation {\n sayHello_\n}"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Parsing",
+ "DisplayName": "GraphQL Document Parsing",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:bb1d246465341a97bdc727d6cd8ead5c"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:bb1d246465341a97bdc727d6cd8ead5c"
+ }
+ ],
+ "event": [
+ {
+ "Name": "exception",
+ "Tags": [
+ {
+ "Key": "graphql.error.message",
+ "Value": "The field `sayHello_` does not exist on the type `Query`."
+ },
+ {
+ "Key": "graphql.error.locations",
+ "Value": [
+ {
+ "line": 1,
+ "column": 27
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.MultipleSources_SourceSchemaResolverError_RecordsDeeplyNestedError.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.MultipleSources_SourceSchemaResolverError_RecordsDeeplyNestedError.snap
new file mode 100644
index 00000000000..1f496ab6824
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.MultipleSources_SourceSchemaResolverError_RecordsDeeplyNestedError.snap
@@ -0,0 +1,201 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:241c617bf9ec34fef187d8b149fd8498"
+ },
+ {
+ "Key": "graphql.document.body",
+ "Value": "{\n sayHello\n deepB {\n deeperB {\n causeFatalError\n }\n }\n}"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationPlanToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Parsing",
+ "DisplayName": "GraphQL Document Parsing",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:241c617bf9ec34fef187d8b149fd8498"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:241c617bf9ec34fef187d8b149fd8498"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:241c617bf9ec34fef187d8b149fd8498"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:241c617bf9ec34fef187d8b149fd8498"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "GraphQL Step Execution",
+ "DisplayName": "GraphQL Step Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "step_execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:241c617bf9ec34fef187d8b149fd8498"
+ },
+ {
+ "Key": "graphql.operation.step.id",
+ "Value": "1"
+ },
+ {
+ "Key": "graphql.operation.step.kind",
+ "Value": "operation"
+ },
+ {
+ "Key": "graphql.operation.step.plan.id",
+ "Value": "6034e1863f163f1cf2ced76832d1f0f496fa230f34e6ea0bb0b1a9de5b0f7db5"
+ },
+ {
+ "Key": "graphql.source.name",
+ "Value": "b"
+ },
+ {
+ "Key": "graphql.source.operation.name",
+ "Value": "Op_241c617b_1"
+ },
+ {
+ "Key": "graphql.source.operation.kind",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.source.operation.hash",
+ "Value": "sha256:7dfcb1cc48aa6c4d4750dc471f2f71b0c1acf70356383ea909d2c5994dc65d6f"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Step Execution",
+ "DisplayName": "GraphQL Step Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "step_execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:241c617bf9ec34fef187d8b149fd8498"
+ },
+ {
+ "Key": "graphql.operation.step.id",
+ "Value": "2"
+ },
+ {
+ "Key": "graphql.operation.step.kind",
+ "Value": "operation"
+ },
+ {
+ "Key": "graphql.operation.step.plan.id",
+ "Value": "6034e1863f163f1cf2ced76832d1f0f496fa230f34e6ea0bb0b1a9de5b0f7db5"
+ },
+ {
+ "Key": "graphql.source.name",
+ "Value": "a"
+ },
+ {
+ "Key": "graphql.source.operation.name",
+ "Value": "Op_241c617b_2"
+ },
+ {
+ "Key": "graphql.source.operation.kind",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.source.operation.hash",
+ "Value": "sha256:23e6ec3292fdaf4949c838051e42d74bee6c27bed8b0720637c4b77d961f3ef3"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.ParsingError_InvalidGraphQLDocument_ReportsErrorStatus.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.ParsingError_InvalidGraphQLDocument_ReportsErrorStatus.snap
new file mode 100644
index 00000000000..aec02c711c2
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.ParsingError_InvalidGraphQLDocument_ReportsErrorStatus.snap
@@ -0,0 +1,48 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "GraphQL Operation",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:bb507ba78696fc3c6ff3a17fb06784d5"
+ }
+ ],
+ "event": [
+ {
+ "Name": "exception",
+ "Tags": [
+ {
+ "Key": "exception.message",
+ "Value": "Expected a `RightBrace`-token, but found a `EndOfFile`-token."
+ },
+ {
+ "Key": "exception.stacktrace",
+ "Value": "HotChocolate.Language.SyntaxException: Expected a `RightBrace`-token, but found a `EndOfFile`-token.\n at HotChocolate.Language.Utf8GraphQLParser.ParseSelectionSet() in Utf8GraphQLParser.Operations.cs:line 221\n at HotChocolate.Language.Utf8GraphQLParser.ParseShortOperationDefinition() in Utf8GraphQLParser.Operations.cs:line 73\n at HotChocolate.Language.Utf8GraphQLParser.ParseDefinition() in Utf8GraphQLParser.cs:line 215\n at HotChocolate.Language.Utf8GraphQLParser.Parse() in Utf8GraphQLParser.cs:line 98\n at HotChocolate.Language.Utf8GraphQLParser.Parse(String sourceText, ParserOptions options) in Utf8GraphQLParser.cs:line 326\n at HotChocolate.Execution.Pipeline.DocumentParserMiddleware.InvokeAsync(RequestContext context) in DocumentParserMiddleware.cs:line 63"
+ },
+ {
+ "Key": "exception.type",
+ "Value": "HotChocolate.Language.SyntaxException"
+ }
+ ]
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Parsing",
+ "DisplayName": "GraphQL Document Parsing",
+ "Status": "Unset",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:bb507ba78696fc3c6ff3a17fb06784d5"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.PersistedOperation_LoadsFromStorage_DefaultScopes.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.PersistedOperation_LoadsFromStorage_DefaultScopes.snap
new file mode 100644
index 00000000000..2021a373452
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.PersistedOperation_LoadsFromStorage_DefaultScopes.snap
@@ -0,0 +1,100 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.document.id",
+ "Value": "sayHelloOp"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.document.id",
+ "Value": "sayHelloOp"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Step Execution",
+ "DisplayName": "GraphQL Step Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "step_execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.document.id",
+ "Value": "sayHelloOp"
+ },
+ {
+ "Key": "graphql.operation.step.id",
+ "Value": "1"
+ },
+ {
+ "Key": "graphql.operation.step.kind",
+ "Value": "operation"
+ },
+ {
+ "Key": "graphql.operation.step.plan.id",
+ "Value": "456132b93ebaf15a39534753bf72f9f4bfa1152a08d04bc8a88539feec1cb52c"
+ },
+ {
+ "Key": "graphql.source.name",
+ "Value": "a"
+ },
+ {
+ "Key": "graphql.source.operation.name",
+ "Value": "Op_f7e9989f_1"
+ },
+ {
+ "Key": "graphql.source.operation.kind",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.source.operation.hash",
+ "Value": "sha256:35c1feb1208268226c7d5d5d0ae122e4d38cb79621e862b1e252d37fc83c530a"
+ }
+ ],
+ "event": []
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.Source_Schema_Transport_Error.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.Source_Schema_Transport_Error.snap
new file mode 100644
index 00000000000..9ccdbfeb3ed
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.Source_Schema_Transport_Error.snap
@@ -0,0 +1,171 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.document.body",
+ "Value": "{\n sayHello\n}"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationPlanToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Parsing",
+ "DisplayName": "GraphQL Document Parsing",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "GraphQL Step Execution",
+ "DisplayName": "GraphQL Step Execution",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "step_execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.step.id",
+ "Value": "1"
+ },
+ {
+ "Key": "graphql.operation.step.kind",
+ "Value": "operation"
+ },
+ {
+ "Key": "graphql.operation.step.plan.id",
+ "Value": "456132b93ebaf15a39534753bf72f9f4bfa1152a08d04bc8a88539feec1cb52c"
+ },
+ {
+ "Key": "graphql.source.name",
+ "Value": "a"
+ },
+ {
+ "Key": "graphql.source.operation.name",
+ "Value": "Op_f7e9989f_1"
+ },
+ {
+ "Key": "graphql.source.operation.kind",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.source.operation.hash",
+ "Value": "sha256:35c1feb1208268226c7d5d5d0ae122e4d38cb79621e862b1e252d37fc83c530a"
+ }
+ ],
+ "event": [
+ {
+ "Name": "exception",
+ "Tags": [
+ {
+ "Key": "exception.message",
+ "Value": "Response status code does not indicate success: 500 (Internal Server Error)."
+ },
+ {
+ "Key": "exception.stacktrace",
+ "Value": "System.Net.Http.HttpRequestException: Response status code does not indicate success: 500 (Internal Server Error).\n at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()\n at HotChocolate.Fusion.Transport.Http.GraphQLHttpResponse.ReadAsResultAsync(CancellationToken cancellationToken) in GraphQLHttpResponse.cs:line 292\n at HotChocolate.Fusion.Execution.Clients.SourceSchemaHttpClient.Response.ReadAsResultStreamAsync(CancellationToken cancellationToken)+MoveNext() in SourceSchemaHttpClient.cs:line 577\n at HotChocolate.Fusion.Execution.Clients.SourceSchemaHttpClient.Response.ReadAsResultStreamAsync(CancellationToken cancellationToken)+System.Threading.Tasks.Sources.IValueTaskSource.GetResult()\n at HotChocolate.Fusion.Execution.Nodes.OperationExecutionNode.OnExecuteAsync(OperationPlanContext context, CancellationToken cancellationToken) in OperationExecutionNode.cs:line 159\n at HotChocolate.Fusion.Execution.Nodes.OperationExecutionNode.OnExecuteAsync(OperationPlanContext context, CancellationToken cancellationToken) in OperationExecutionNode.cs:line 159"
+ },
+ {
+ "Key": "exception.type",
+ "Value": "System.Net.Http.HttpRequestException"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.SubscriptionEvent_Records_Subscription_Event_Span.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.SubscriptionEvent_Records_Subscription_Event_Span.snap
new file mode 100644
index 00000000000..255ef236318
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.SubscriptionEvent_Records_Subscription_Event_Span.snap
@@ -0,0 +1,193 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "subscription",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "subscription"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "OnMessageSubscription"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:ef859b98c9d8c17038c8fd9aeecdb1e2"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationPlanToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Parsing",
+ "DisplayName": "GraphQL Document Parsing",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:ef859b98c9d8c17038c8fd9aeecdb1e2"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:ef859b98c9d8c17038c8fd9aeecdb1e2"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:ef859b98c9d8c17038c8fd9aeecdb1e2"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "subscription"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "OnMessageSubscription"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "subscription"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "OnMessageSubscription"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:ef859b98c9d8c17038c8fd9aeecdb1e2"
+ }
+ ],
+ "event": []
+ }
+ ]
+ },
+ {
+ "OperationName": "GraphQL Step Execution",
+ "DisplayName": "GraphQL Step Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "step_execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "subscription"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "OnMessageSubscription"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:ef859b98c9d8c17038c8fd9aeecdb1e2"
+ },
+ {
+ "Key": "graphql.operation.step.id",
+ "Value": "1"
+ },
+ {
+ "Key": "graphql.operation.step.kind",
+ "Value": "operation"
+ },
+ {
+ "Key": "graphql.operation.step.plan.id",
+ "Value": "2e566740582971b4b247348976bca6cb8a84255526b80e73273aa94781bca0fc"
+ },
+ {
+ "Key": "graphql.source.name",
+ "Value": "a"
+ },
+ {
+ "Key": "graphql.source.operation.name",
+ "Value": "OnMessageSubscription_ef859b98_1"
+ },
+ {
+ "Key": "graphql.source.operation.kind",
+ "Value": "subscription"
+ },
+ {
+ "Key": "graphql.source.operation.hash",
+ "Value": "sha256:f9abddbb651ad8e118793eb7c4a7c8db7fe43cae95faba710a0ff35b26b17136"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "GraphQL Subscription Event",
+ "DisplayName": "GraphQL Subscription Event",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "subscription"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "OnMessageSubscription"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:ef859b98c9d8c17038c8fd9aeecdb1e2"
+ },
+ {
+ "Key": "graphql.subscription.id",
+ "Value": "1"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.Track_Events_Of_A_Query_With_Multiple_Sources.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.Track_Events_Of_A_Query_With_Multiple_Sources.snap
new file mode 100644
index 00000000000..5e45bdc3399
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.Track_Events_Of_A_Query_With_Multiple_Sources.snap
@@ -0,0 +1,197 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:073bf7696c078e52587c88890ef21bbe"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationPlanToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Parsing",
+ "DisplayName": "GraphQL Document Parsing",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:073bf7696c078e52587c88890ef21bbe"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:073bf7696c078e52587c88890ef21bbe"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:073bf7696c078e52587c88890ef21bbe"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:073bf7696c078e52587c88890ef21bbe"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "GraphQL Step Execution",
+ "DisplayName": "GraphQL Step Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "step_execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:073bf7696c078e52587c88890ef21bbe"
+ },
+ {
+ "Key": "graphql.operation.step.id",
+ "Value": "1"
+ },
+ {
+ "Key": "graphql.operation.step.kind",
+ "Value": "operation"
+ },
+ {
+ "Key": "graphql.operation.step.plan.id",
+ "Value": "9babcd211d7b162261fa15a119462370a3f30c61ea319946c30bc4051a265a5d"
+ },
+ {
+ "Key": "graphql.source.name",
+ "Value": "a"
+ },
+ {
+ "Key": "graphql.source.operation.name",
+ "Value": "Op_073bf769_1"
+ },
+ {
+ "Key": "graphql.source.operation.kind",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.source.operation.hash",
+ "Value": "sha256:b6db85f78e867baa06bf8b4f45ed381a2b6bc9f7abd15948f0bfff0967fbc308"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Step Execution",
+ "DisplayName": "GraphQL Step Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "step_execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:073bf7696c078e52587c88890ef21bbe"
+ },
+ {
+ "Key": "graphql.operation.step.id",
+ "Value": "2"
+ },
+ {
+ "Key": "graphql.operation.step.kind",
+ "Value": "operation"
+ },
+ {
+ "Key": "graphql.operation.step.plan.id",
+ "Value": "9babcd211d7b162261fa15a119462370a3f30c61ea319946c30bc4051a265a5d"
+ },
+ {
+ "Key": "graphql.source.name",
+ "Value": "b"
+ },
+ {
+ "Key": "graphql.source.operation.name",
+ "Value": "Op_073bf769_2"
+ },
+ {
+ "Key": "graphql.source.operation.kind",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.source.operation.hash",
+ "Value": "sha256:1fa50769ad5084334414d5ceb8029c7787ded48ac5cc01dac775b0b814348e88"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.Track_Events_Of_A_Simple_Query_Default.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.Track_Events_Of_A_Simple_Query_Default.snap
new file mode 100644
index 00000000000..bfbb9fd1ca2
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.Track_Events_Of_A_Simple_Query_Default.snap
@@ -0,0 +1,88 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Step Execution",
+ "DisplayName": "GraphQL Step Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "step_execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.step.id",
+ "Value": "1"
+ },
+ {
+ "Key": "graphql.operation.step.kind",
+ "Value": "operation"
+ },
+ {
+ "Key": "graphql.operation.step.plan.id",
+ "Value": "456132b93ebaf15a39534753bf72f9f4bfa1152a08d04bc8a88539feec1cb52c"
+ },
+ {
+ "Key": "graphql.source.name",
+ "Value": "a"
+ },
+ {
+ "Key": "graphql.source.operation.name",
+ "Value": "Op_f7e9989f_1"
+ },
+ {
+ "Key": "graphql.source.operation.kind",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.source.operation.hash",
+ "Value": "sha256:35c1feb1208268226c7d5d5d0ae122e4d38cb79621e862b1e252d37fc83c530a"
+ }
+ ],
+ "event": []
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.ValidationError_UnknownField_ReportsErrorStatus.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.ValidationError_UnknownField_ReportsErrorStatus.snap
new file mode 100644
index 00000000000..469d64a23ed
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityExecutionDiagnosticListenerTests.ValidationError_UnknownField_ReportsErrorStatus.snap
@@ -0,0 +1,65 @@
+{
+ "activities": [
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "GraphQL Operation",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:1526f207d516803b71eb8a0db419b57b"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Parsing",
+ "DisplayName": "GraphQL Document Parsing",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:1526f207d516803b71eb8a0db419b57b"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Error",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:1526f207d516803b71eb8a0db419b57b"
+ }
+ ],
+ "event": [
+ {
+ "Name": "exception",
+ "Tags": [
+ {
+ "Key": "graphql.error.message",
+ "Value": "The field `unknownField123` does not exist on the type `Query`."
+ },
+ {
+ "Key": "graphql.error.locations",
+ "Value": [
+ {
+ "line": 1,
+ "column": 3
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Get_SDL_download.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.Http_Get_SDL_Download.snap
similarity index 74%
rename from src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Get_SDL_download.snap
rename to src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.Http_Get_SDL_Download.snap
index 928bc599863..d77edd7831a 100644
--- a/src/HotChocolate/Diagnostics/test/Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Get_SDL_download.snap
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.Http_Get_SDL_Download.snap
@@ -1,10 +1,14 @@
-{
+{
"activities": [
{
"OperationName": "ExecuteHttpRequest",
"DisplayName": "GraphQL HTTP GET SDL",
"Status": "Ok",
"tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpGetSchema"
+ },
{
"Key": "graphql.schema.name",
"Value": "_Default"
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.Http_Get_Single_Request.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.Http_Get_Single_Request.snap
new file mode 100644
index 00000000000..9ff8b608f7b
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.Http_Get_Single_Request.snap
@@ -0,0 +1,177 @@
+{
+ "activities": [
+ {
+ "OperationName": "ExecuteHttpRequest",
+ "DisplayName": "GraphQL HTTP GET",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpGet"
+ },
+ {
+ "Key": "graphql.schema.name",
+ "Value": "_Default"
+ },
+ {
+ "Key": "graphql.http.request.type",
+ "Value": "single"
+ },
+ {
+ "Key": "graphql.http.request.query.hash",
+ "Value": "f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "Parse HTTP Request",
+ "DisplayName": "Parse HTTP Request",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationPlanToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "GraphQL Step Execution",
+ "DisplayName": "GraphQL Step Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "step_execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.step.id",
+ "Value": "1"
+ },
+ {
+ "Key": "graphql.operation.step.kind",
+ "Value": "operation"
+ },
+ {
+ "Key": "graphql.operation.step.plan.id",
+ "Value": "456132b93ebaf15a39534753bf72f9f4bfa1152a08d04bc8a88539feec1cb52c"
+ },
+ {
+ "Key": "graphql.source.name",
+ "Value": "a"
+ },
+ {
+ "Key": "graphql.source.operation.name",
+ "Value": "Op_f7e9989f_1"
+ },
+ {
+ "Key": "graphql.source.operation.kind",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.source.operation.hash",
+ "Value": "sha256:35c1feb1208268226c7d5d5d0ae122e4d38cb79621e862b1e252d37fc83c530a"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "OperationName": "Format HTTP Response",
+ "DisplayName": "Format HTTP Response",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.Http_Post_Add_Variables_To_Http_Activity.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.Http_Post_Add_Variables_To_Http_Activity.snap
new file mode 100644
index 00000000000..c85efc6ffab
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.Http_Post_Add_Variables_To_Http_Activity.snap
@@ -0,0 +1,205 @@
+{
+ "activities": [
+ {
+ "OperationName": "ExecuteHttpRequest",
+ "DisplayName": "GraphQL HTTP POST",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpPost"
+ },
+ {
+ "Key": "graphql.schema.name",
+ "Value": "_Default"
+ },
+ {
+ "Key": "graphql.http.request.type",
+ "Value": "single"
+ },
+ {
+ "Key": "graphql.http.request.query.id",
+ "Value": "bfa5986a5299f46421057dd3eb27ec5c"
+ },
+ {
+ "Key": "graphql.http.request.query.hash",
+ "Value": "bfa5986a5299f46421057dd3eb27ec5c"
+ },
+ {
+ "Key": "graphql.http.request.variables",
+ "Value": "{\"name\":\"World\"}"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "Parse HTTP Request",
+ "DisplayName": "Parse HTTP Request",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:c46cf8c9811934ddea095f10ee722dc4"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationPlanToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:c46cf8c9811934ddea095f10ee722dc4"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:c46cf8c9811934ddea095f10ee722dc4"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Variable Coercion",
+ "DisplayName": "GraphQL Variable Coercion",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "variable_coercion"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:c46cf8c9811934ddea095f10ee722dc4"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:c46cf8c9811934ddea095f10ee722dc4"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "GraphQL Step Execution",
+ "DisplayName": "GraphQL Step Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "step_execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:c46cf8c9811934ddea095f10ee722dc4"
+ },
+ {
+ "Key": "graphql.operation.step.id",
+ "Value": "1"
+ },
+ {
+ "Key": "graphql.operation.step.kind",
+ "Value": "operation"
+ },
+ {
+ "Key": "graphql.operation.step.plan.id",
+ "Value": "d58281f7cf44ca2751c4a435c0249e686bd1c146f6ddae23ed35ec6e4b83eb77"
+ },
+ {
+ "Key": "graphql.source.name",
+ "Value": "a"
+ },
+ {
+ "Key": "graphql.source.operation.name",
+ "Value": "Op_c46cf8c9_1"
+ },
+ {
+ "Key": "graphql.source.operation.kind",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.source.operation.hash",
+ "Value": "sha256:a6738007b3546a7458414ee647c93aa373bc22ca57256f4a4a5c8ef3aa886470"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "OperationName": "Format HTTP Response",
+ "DisplayName": "Format HTTP Response",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_Parser_Error.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.Http_Post_Parser_Error.snap
similarity index 63%
rename from src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_Parser_Error.snap
rename to src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.Http_Post_Parser_Error.snap
index 28a52eca1ac..955f4d24f0c 100644
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_Parser_Error.snap
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.Http_Post_Parser_Error.snap
@@ -5,6 +5,10 @@
"DisplayName": "GraphQL HTTP POST",
"Status": "Ok",
"tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpPost"
+ },
{
"Key": "graphql.schema.name",
"Value": "_Default"
@@ -13,41 +17,37 @@
"event": [],
"activities": [
{
- "OperationName": "ParseHttpRequest",
+ "OperationName": "Parse HTTP Request",
"DisplayName": "Parse HTTP Request",
"Status": "Error",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "ERROR"
- }
- ],
+ "tags": [],
"event": [
{
"Name": "exception",
"Tags": [
{
- "Key": "exception.message",
+ "Key": "graphql.error.message",
"Value": "Found a NameStart character `d` (100) following a number, which is disallowed."
},
{
- "Key": "exception.type",
+ "Key": "graphql.error.code",
"Value": "HC0011"
},
{
- "Key": "graphql.error.location.column",
- "Value": 13
- },
- {
- "Key": "graphql.error.location.line",
- "Value": 4
+ "Key": "graphql.error.locations",
+ "Value": [
+ {
+ "line": 4,
+ "column": 13
+ }
+ ]
}
]
}
]
},
{
- "OperationName": "FormatHttpResponse",
+ "OperationName": "Format HTTP Response",
"DisplayName": "Format HTTP Response",
"Status": "Ok",
"tags": [],
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.Http_Post_Single_Request.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.Http_Post_Single_Request.snap
new file mode 100644
index 00000000000..879f232de5c
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.Http_Post_Single_Request.snap
@@ -0,0 +1,181 @@
+{
+ "activities": [
+ {
+ "OperationName": "ExecuteHttpRequest",
+ "DisplayName": "GraphQL HTTP POST",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpPost"
+ },
+ {
+ "Key": "graphql.schema.name",
+ "Value": "_Default"
+ },
+ {
+ "Key": "graphql.http.request.type",
+ "Value": "single"
+ },
+ {
+ "Key": "graphql.http.request.query.id",
+ "Value": "f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.http.request.query.hash",
+ "Value": "f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "Parse HTTP Request",
+ "DisplayName": "Parse HTTP Request",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationPlanToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "GraphQL Step Execution",
+ "DisplayName": "GraphQL Step Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "step_execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.step.id",
+ "Value": "1"
+ },
+ {
+ "Key": "graphql.operation.step.kind",
+ "Value": "operation"
+ },
+ {
+ "Key": "graphql.operation.step.plan.id",
+ "Value": "456132b93ebaf15a39534753bf72f9f4bfa1152a08d04bc8a88539feec1cb52c"
+ },
+ {
+ "Key": "graphql.source.name",
+ "Value": "a"
+ },
+ {
+ "Key": "graphql.source.operation.name",
+ "Value": "Op_f7e9989f_1"
+ },
+ {
+ "Key": "graphql.source.operation.kind",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.source.operation.hash",
+ "Value": "sha256:35c1feb1208268226c7d5d5d0ae122e4d38cb79621e862b1e252d37fc83c530a"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "OperationName": "Format HTTP Response",
+ "DisplayName": "Format HTTP Response",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.Http_Post_Single_Request_Default.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.Http_Post_Single_Request_Default.snap
new file mode 100644
index 00000000000..4676e5c2059
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.Http_Post_Single_Request_Default.snap
@@ -0,0 +1,149 @@
+{
+ "activities": [
+ {
+ "OperationName": "ExecuteHttpRequest",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpPost"
+ },
+ {
+ "Key": "graphql.schema.name",
+ "Value": "_Default"
+ },
+ {
+ "Key": "graphql.http.request.type",
+ "Value": "single"
+ },
+ {
+ "Key": "graphql.http.request.query.id",
+ "Value": "f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.http.request.query.hash",
+ "Value": "f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationPlanToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "Parse HTTP Request",
+ "DisplayName": "Parse HTTP Request",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Step Execution",
+ "DisplayName": "GraphQL Step Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "step_execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.step.id",
+ "Value": "1"
+ },
+ {
+ "Key": "graphql.operation.step.kind",
+ "Value": "operation"
+ },
+ {
+ "Key": "graphql.operation.step.plan.id",
+ "Value": "456132b93ebaf15a39534753bf72f9f4bfa1152a08d04bc8a88539feec1cb52c"
+ },
+ {
+ "Key": "graphql.source.name",
+ "Value": "a"
+ },
+ {
+ "Key": "graphql.source.operation.name",
+ "Value": "Op_f7e9989f_1"
+ },
+ {
+ "Key": "graphql.source.operation.kind",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.source.operation.hash",
+ "Value": "sha256:35c1feb1208268226c7d5d5d0ae122e4d38cb79621e862b1e252d37fc83c530a"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "Format HTTP Response",
+ "DisplayName": "Format HTTP Response",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.Http_Post_Variables_Are_Not_Automatically_Added_To_Activities.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.Http_Post_Variables_Are_Not_Automatically_Added_To_Activities.snap
new file mode 100644
index 00000000000..5363d19dcde
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.Http_Post_Variables_Are_Not_Automatically_Added_To_Activities.snap
@@ -0,0 +1,201 @@
+{
+ "activities": [
+ {
+ "OperationName": "ExecuteHttpRequest",
+ "DisplayName": "GraphQL HTTP POST",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpPost"
+ },
+ {
+ "Key": "graphql.schema.name",
+ "Value": "_Default"
+ },
+ {
+ "Key": "graphql.http.request.type",
+ "Value": "single"
+ },
+ {
+ "Key": "graphql.http.request.query.id",
+ "Value": "bfa5986a5299f46421057dd3eb27ec5c"
+ },
+ {
+ "Key": "graphql.http.request.query.hash",
+ "Value": "bfa5986a5299f46421057dd3eb27ec5c"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "Parse HTTP Request",
+ "DisplayName": "Parse HTTP Request",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:c46cf8c9811934ddea095f10ee722dc4"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationPlanToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:c46cf8c9811934ddea095f10ee722dc4"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:c46cf8c9811934ddea095f10ee722dc4"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Variable Coercion",
+ "DisplayName": "GraphQL Variable Coercion",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "variable_coercion"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:c46cf8c9811934ddea095f10ee722dc4"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:c46cf8c9811934ddea095f10ee722dc4"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "GraphQL Step Execution",
+ "DisplayName": "GraphQL Step Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "step_execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:c46cf8c9811934ddea095f10ee722dc4"
+ },
+ {
+ "Key": "graphql.operation.step.id",
+ "Value": "1"
+ },
+ {
+ "Key": "graphql.operation.step.kind",
+ "Value": "operation"
+ },
+ {
+ "Key": "graphql.operation.step.plan.id",
+ "Value": "d58281f7cf44ca2751c4a435c0249e686bd1c146f6ddae23ed35ec6e4b83eb77"
+ },
+ {
+ "Key": "graphql.source.name",
+ "Value": "a"
+ },
+ {
+ "Key": "graphql.source.operation.name",
+ "Value": "Op_c46cf8c9_1"
+ },
+ {
+ "Key": "graphql.source.operation.kind",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.source.operation.hash",
+ "Value": "sha256:a6738007b3546a7458414ee647c93aa373bc22ca57256f4a4a5c8ef3aa886470"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "OperationName": "Format HTTP Response",
+ "DisplayName": "Format HTTP Response",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.Http_Post_With_Extensions_Map.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.Http_Post_With_Extensions_Map.snap
new file mode 100644
index 00000000000..3fa877086c4
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.Http_Post_With_Extensions_Map.snap
@@ -0,0 +1,205 @@
+{
+ "activities": [
+ {
+ "OperationName": "ExecuteHttpRequest",
+ "DisplayName": "GraphQL HTTP POST",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpPost"
+ },
+ {
+ "Key": "graphql.schema.name",
+ "Value": "_Default"
+ },
+ {
+ "Key": "graphql.http.request.type",
+ "Value": "single"
+ },
+ {
+ "Key": "graphql.http.request.query.id",
+ "Value": "bfa5986a5299f46421057dd3eb27ec5c"
+ },
+ {
+ "Key": "graphql.http.request.query.hash",
+ "Value": "bfa5986a5299f46421057dd3eb27ec5c"
+ },
+ {
+ "Key": "graphql.http.request.extensions",
+ "Value": "{\"test\":\"abc\"}"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "Parse HTTP Request",
+ "DisplayName": "Parse HTTP Request",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:c46cf8c9811934ddea095f10ee722dc4"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationPlanToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:c46cf8c9811934ddea095f10ee722dc4"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:c46cf8c9811934ddea095f10ee722dc4"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Variable Coercion",
+ "DisplayName": "GraphQL Variable Coercion",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "variable_coercion"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:c46cf8c9811934ddea095f10ee722dc4"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:c46cf8c9811934ddea095f10ee722dc4"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "GraphQL Step Execution",
+ "DisplayName": "GraphQL Step Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "step_execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:c46cf8c9811934ddea095f10ee722dc4"
+ },
+ {
+ "Key": "graphql.operation.step.id",
+ "Value": "1"
+ },
+ {
+ "Key": "graphql.operation.step.kind",
+ "Value": "operation"
+ },
+ {
+ "Key": "graphql.operation.step.plan.id",
+ "Value": "d58281f7cf44ca2751c4a435c0249e686bd1c146f6ddae23ed35ec6e4b83eb77"
+ },
+ {
+ "Key": "graphql.source.name",
+ "Value": "a"
+ },
+ {
+ "Key": "graphql.source.operation.name",
+ "Value": "Op_c46cf8c9_1"
+ },
+ {
+ "Key": "graphql.source.operation.kind",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.source.operation.hash",
+ "Value": "sha256:a6738007b3546a7458414ee647c93aa373bc22ca57256f4a4a5c8ef3aa886470"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "OperationName": "Format HTTP Response",
+ "DisplayName": "Format HTTP Response",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.RequestDetails_All_IncludesAllDetails.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.RequestDetails_All_IncludesAllDetails.snap
new file mode 100644
index 00000000000..90f30afb640
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.RequestDetails_All_IncludesAllDetails.snap
@@ -0,0 +1,233 @@
+{
+ "activities": [
+ {
+ "OperationName": "ExecuteHttpRequest",
+ "DisplayName": "GraphQL HTTP POST",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpPost"
+ },
+ {
+ "Key": "graphql.schema.name",
+ "Value": "_Default"
+ },
+ {
+ "Key": "graphql.http.request.type",
+ "Value": "single"
+ },
+ {
+ "Key": "graphql.http.request.query.id",
+ "Value": "08c6969c8d553f85d6541aa54ef01acb"
+ },
+ {
+ "Key": "graphql.http.request.query.hash",
+ "Value": "08c6969c8d553f85d6541aa54ef01acb"
+ },
+ {
+ "Key": "graphql.http.request.query.body",
+ "Value": "query GetGreeting(\n $name: String!\n) {\n greeting(name: $name)\n}"
+ },
+ {
+ "Key": "graphql.http.request.variables",
+ "Value": "{\"name\":\"World\"}"
+ },
+ {
+ "Key": "graphql.http.request.extensions",
+ "Value": "{\"test\":\"abc\"}"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "Parse HTTP Request",
+ "DisplayName": "Parse HTTP Request",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetGreeting"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:111e40f921c6c6a35bc7eb0e3873630e"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationPlanToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:111e40f921c6c6a35bc7eb0e3873630e"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:111e40f921c6c6a35bc7eb0e3873630e"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetGreeting"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Variable Coercion",
+ "DisplayName": "GraphQL Variable Coercion",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "variable_coercion"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetGreeting"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:111e40f921c6c6a35bc7eb0e3873630e"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetGreeting"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:111e40f921c6c6a35bc7eb0e3873630e"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "GraphQL Step Execution",
+ "DisplayName": "GraphQL Step Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "step_execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetGreeting"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:111e40f921c6c6a35bc7eb0e3873630e"
+ },
+ {
+ "Key": "graphql.operation.step.id",
+ "Value": "1"
+ },
+ {
+ "Key": "graphql.operation.step.kind",
+ "Value": "operation"
+ },
+ {
+ "Key": "graphql.operation.step.plan.id",
+ "Value": "12136be79ce453a7feac5df83310a20585dbdb9c9675bc55b25c2c2ea1f871e1"
+ },
+ {
+ "Key": "graphql.source.name",
+ "Value": "a"
+ },
+ {
+ "Key": "graphql.source.operation.name",
+ "Value": "GetGreeting_111e40f9_1"
+ },
+ {
+ "Key": "graphql.source.operation.kind",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.source.operation.hash",
+ "Value": "sha256:00692b6fbeb8014bcc1eb8932d5924dc0c5e5ea3e158e34979ec322c2e1b3c40"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "OperationName": "Format HTTP Response",
+ "DisplayName": "Format HTTP Response",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.RequestDetails_Default_IncludesIdHashOperationNameExtensions.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.RequestDetails_Default_IncludesIdHashOperationNameExtensions.snap
new file mode 100644
index 00000000000..d4b1970c371
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.RequestDetails_Default_IncludesIdHashOperationNameExtensions.snap
@@ -0,0 +1,201 @@
+{
+ "activities": [
+ {
+ "OperationName": "ExecuteHttpRequest",
+ "DisplayName": "GraphQL HTTP POST",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpPost"
+ },
+ {
+ "Key": "graphql.schema.name",
+ "Value": "_Default"
+ },
+ {
+ "Key": "graphql.http.request.type",
+ "Value": "single"
+ },
+ {
+ "Key": "graphql.http.request.query.id",
+ "Value": "82d594dc9843e825769c127e8ae2db6f"
+ },
+ {
+ "Key": "graphql.http.request.query.hash",
+ "Value": "82d594dc9843e825769c127e8ae2db6f"
+ },
+ {
+ "Key": "graphql.http.request.extensions",
+ "Value": "{\"test\":\"abc\"}"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "Parse HTTP Request",
+ "DisplayName": "Parse HTTP Request",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetGreeting"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:cf203f646caf64f424638bd2f09e490a"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationPlanToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:cf203f646caf64f424638bd2f09e490a"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:cf203f646caf64f424638bd2f09e490a"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetGreeting"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetGreeting"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:cf203f646caf64f424638bd2f09e490a"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "GraphQL Step Execution",
+ "DisplayName": "GraphQL Step Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "step_execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetGreeting"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:cf203f646caf64f424638bd2f09e490a"
+ },
+ {
+ "Key": "graphql.operation.step.id",
+ "Value": "1"
+ },
+ {
+ "Key": "graphql.operation.step.kind",
+ "Value": "operation"
+ },
+ {
+ "Key": "graphql.operation.step.plan.id",
+ "Value": "f274a33c8d687ab897e52e6be6346ef3ccdd10a864a4088c571073d755df2d92"
+ },
+ {
+ "Key": "graphql.source.name",
+ "Value": "a"
+ },
+ {
+ "Key": "graphql.source.operation.name",
+ "Value": "GetGreeting_cf203f64_1"
+ },
+ {
+ "Key": "graphql.source.operation.kind",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.source.operation.hash",
+ "Value": "sha256:579285518f37f039b04a0268fd6058a3903e369efccd77c48e7c045c35f25428"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "OperationName": "Format HTTP Response",
+ "DisplayName": "Format HTTP Response",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.RequestDetails_DocumentOnly_IncludesDocumentTag.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.RequestDetails_DocumentOnly_IncludesDocumentTag.snap
new file mode 100644
index 00000000000..b222a1e8ef9
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.RequestDetails_DocumentOnly_IncludesDocumentTag.snap
@@ -0,0 +1,177 @@
+{
+ "activities": [
+ {
+ "OperationName": "ExecuteHttpRequest",
+ "DisplayName": "GraphQL HTTP POST",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpPost"
+ },
+ {
+ "Key": "graphql.schema.name",
+ "Value": "_Default"
+ },
+ {
+ "Key": "graphql.http.request.type",
+ "Value": "single"
+ },
+ {
+ "Key": "graphql.http.request.query.body",
+ "Value": "{\n sayHello\n}"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "Parse HTTP Request",
+ "DisplayName": "Parse HTTP Request",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationPlanToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "GraphQL Step Execution",
+ "DisplayName": "GraphQL Step Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "step_execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
+ },
+ {
+ "Key": "graphql.operation.step.id",
+ "Value": "1"
+ },
+ {
+ "Key": "graphql.operation.step.kind",
+ "Value": "operation"
+ },
+ {
+ "Key": "graphql.operation.step.plan.id",
+ "Value": "456132b93ebaf15a39534753bf72f9f4bfa1152a08d04bc8a88539feec1cb52c"
+ },
+ {
+ "Key": "graphql.source.name",
+ "Value": "a"
+ },
+ {
+ "Key": "graphql.source.operation.name",
+ "Value": "Op_f7e9989f_1"
+ },
+ {
+ "Key": "graphql.source.operation.kind",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.source.operation.hash",
+ "Value": "sha256:35c1feb1208268226c7d5d5d0ae122e4d38cb79621e862b1e252d37fc83c530a"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "OperationName": "Format HTTP Response",
+ "DisplayName": "Format HTTP Response",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.RequestDetails_None_ExcludesAllDetails.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.RequestDetails_None_ExcludesAllDetails.snap
new file mode 100644
index 00000000000..271d5d3e822
--- /dev/null
+++ b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/FusionActivityServerDiagnosticListenerTests.RequestDetails_None_ExcludesAllDetails.snap
@@ -0,0 +1,209 @@
+{
+ "activities": [
+ {
+ "OperationName": "ExecuteHttpRequest",
+ "DisplayName": "GraphQL HTTP POST",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.http.kind",
+ "Value": "HttpPost"
+ },
+ {
+ "Key": "graphql.schema.name",
+ "Value": "_Default"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "Parse HTTP Request",
+ "DisplayName": "Parse HTTP Request",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation",
+ "DisplayName": "query",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetGreeting"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:111e40f921c6c6a35bc7eb0e3873630e"
+ }
+ ],
+ "event": [
+ {
+ "Name": "AddedOperationPlanToCache",
+ "Tags": []
+ },
+ {
+ "Name": "AddedDocumentToCache",
+ "Tags": []
+ }
+ ],
+ "activities": [
+ {
+ "OperationName": "GraphQL Document Validation",
+ "DisplayName": "GraphQL Document Validation",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "validate"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:111e40f921c6c6a35bc7eb0e3873630e"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Planning",
+ "DisplayName": "GraphQL Operation Planning",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "plan"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:111e40f921c6c6a35bc7eb0e3873630e"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetGreeting"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Variable Coercion",
+ "DisplayName": "GraphQL Variable Coercion",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "variable_coercion"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetGreeting"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:111e40f921c6c6a35bc7eb0e3873630e"
+ }
+ ],
+ "event": []
+ },
+ {
+ "OperationName": "GraphQL Operation Execution",
+ "DisplayName": "GraphQL Operation Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetGreeting"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:111e40f921c6c6a35bc7eb0e3873630e"
+ }
+ ],
+ "event": [],
+ "activities": [
+ {
+ "OperationName": "GraphQL Step Execution",
+ "DisplayName": "GraphQL Step Execution",
+ "Status": "Ok",
+ "tags": [
+ {
+ "Key": "graphql.processing.type",
+ "Value": "step_execute"
+ },
+ {
+ "Key": "graphql.operation.type",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.operation.name",
+ "Value": "GetGreeting"
+ },
+ {
+ "Key": "graphql.document.hash",
+ "Value": "md5:111e40f921c6c6a35bc7eb0e3873630e"
+ },
+ {
+ "Key": "graphql.operation.step.id",
+ "Value": "1"
+ },
+ {
+ "Key": "graphql.operation.step.kind",
+ "Value": "operation"
+ },
+ {
+ "Key": "graphql.operation.step.plan.id",
+ "Value": "12136be79ce453a7feac5df83310a20585dbdb9c9675bc55b25c2c2ea1f871e1"
+ },
+ {
+ "Key": "graphql.source.name",
+ "Value": "a"
+ },
+ {
+ "Key": "graphql.source.operation.name",
+ "Value": "GetGreeting_111e40f9_1"
+ },
+ {
+ "Key": "graphql.source.operation.kind",
+ "Value": "query"
+ },
+ {
+ "Key": "graphql.source.operation.hash",
+ "Value": "sha256:00692b6fbeb8014bcc1eb8932d5924dc0c5e5ea3e158e34979ec322c2e1b3c40"
+ }
+ ],
+ "event": []
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "OperationName": "Format HTTP Response",
+ "DisplayName": "Format HTTP Response",
+ "Status": "Ok",
+ "tags": [],
+ "event": []
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Allow_Document_To_Be_Captured.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Allow_Document_To_Be_Captured.snap
deleted file mode 100644
index d3e100c155c..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Allow_Document_To_Be_Captured.snap
+++ /dev/null
@@ -1,112 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query SayHelloOperation { sayHello }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "6af18618ae20c266f6ffc352b78cb69b"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "6af18618ae20c266f6ffc352b78cb69b"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "1334fb0da1250c6db5db84b6c98ccb2556f066942f8836d6ebd18fd870172787"
- },
- {
- "Key": "graphql.operation.name",
- "Value": "SayHelloOperation"
- },
- {
- "Key": "graphql.document.body",
- "Value": "query SayHelloOperation {\n sayHello\n}"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseDocument",
- "DisplayName": "Parse Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "6af18618ae20c266f6ffc352b78cb69b"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "6af18618ae20c266f6ffc352b78cb69b"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "PlanOperation",
- "DisplayName": "Plan Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation SayHelloOperation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ExecuteOperationNode",
- "DisplayName": "Execute Operation Node (a)",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.fusion.node.type",
- "Value": "Operation"
- },
- {
- "Key": "graphql.fusion.node.schema",
- "Value": "a"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Cause_A_Resolver_Error_That_Deletes_The_Whole_Result.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Cause_A_Resolver_Error_That_Deletes_The_Whole_Result.snap
deleted file mode 100644
index 86e0de8de0f..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Cause_A_Resolver_Error_That_Deletes_The_Whole_Result.snap
+++ /dev/null
@@ -1,116 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query SayHelloOperation { causeFatalError }",
- "Status": "Error",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "851fb754d9ba6b5cc5a55ebcbea2621d"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "851fb754d9ba6b5cc5a55ebcbea2621d"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "5f75eb886568e255310bed3eb3e1f7f1c91f1a22f71ac7c36f00d8df27400d8e"
- },
- {
- "Key": "graphql.operation.name",
- "Value": "SayHelloOperation"
- },
- {
- "Key": "graphql.document.body",
- "Value": "query SayHelloOperation {\n causeFatalError\n}"
- },
- {
- "Key": "otel.status_code",
- "Value": "ERROR"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseDocument",
- "DisplayName": "Parse Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "851fb754d9ba6b5cc5a55ebcbea2621d"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "851fb754d9ba6b5cc5a55ebcbea2621d"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "PlanOperation",
- "DisplayName": "Plan Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation SayHelloOperation",
- "Status": "Error",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "ERROR"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ExecuteOperationNode",
- "DisplayName": "Execute Operation Node (a)",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.fusion.node.type",
- "Value": "Operation"
- },
- {
- "Key": "graphql.fusion.node.schema",
- "Value": "a"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Cause_A_Resolver_Error_That_Deletes_The_Whole_Result_Deep.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Cause_A_Resolver_Error_That_Deletes_The_Whole_Result_Deep.snap
deleted file mode 100644
index 158121c23ce..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Cause_A_Resolver_Error_That_Deletes_The_Whole_Result_Deep.snap
+++ /dev/null
@@ -1,84 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "Execute Request",
- "Status": "Error",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "803df9346db185e9dc0b22dd3909aa70"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "803df9346db185e9dc0b22dd3909aa70"
- },
- {
- "Key": "graphql.document.body",
- "Value": "query SayHelloOperation {\n deep {\n deeper {\n deeps {\n deeper {\n causeFatalError\n }\n }\n }\n }\n}"
- },
- {
- "Key": "otel.status_code",
- "Value": "ERROR"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseDocument",
- "DisplayName": "Parse Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Error",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "ERROR"
- },
- {
- "Key": "graphql.document.id",
- "Value": "803df9346db185e9dc0b22dd3909aa70"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "803df9346db185e9dc0b22dd3909aa70"
- }
- ],
- "event": [
- {
- "Name": "exception",
- "Tags": [
- {
- "Key": "exception.message",
- "Value": "The field `causeFatalError` does not exist on the type `Deeper`."
- },
- {
- "Key": "exception.type",
- "Value": "GRAPHQL_ERROR"
- },
- {
- "Key": "graphql.error.location.column",
- "Value": 21
- },
- {
- "Key": "graphql.error.location.line",
- "Value": 6
- }
- ]
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Create_Operation_Display_Name_With_1_Field.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Create_Operation_Display_Name_With_1_Field.snap
deleted file mode 100644
index 85a94d3f7b2..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Create_Operation_Display_Name_With_1_Field.snap
+++ /dev/null
@@ -1,104 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { a }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "452ea802c4d1bf2a81a7411b0b361d9f"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "452ea802c4d1bf2a81a7411b0b361d9f"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "91d3f369067488892e5c81c27598c0d43b5ecfe5ad824925965ac60c70351919"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseDocument",
- "DisplayName": "Parse Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "452ea802c4d1bf2a81a7411b0b361d9f"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "452ea802c4d1bf2a81a7411b0b361d9f"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "PlanOperation",
- "DisplayName": "Plan Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ExecuteOperationNode",
- "DisplayName": "Execute Operation Node (a)",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.fusion.node.type",
- "Value": "Operation"
- },
- {
- "Key": "graphql.fusion.node.schema",
- "Value": "a"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Create_Operation_Display_Name_With_1_Field_And_Op.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Create_Operation_Display_Name_With_1_Field_And_Op.snap
deleted file mode 100644
index 0ed0deda928..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Create_Operation_Display_Name_With_1_Field_And_Op.snap
+++ /dev/null
@@ -1,108 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query GetA { a }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "cee0e2939ece72d650cb0331f4be4669"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "cee0e2939ece72d650cb0331f4be4669"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "155189958e55686347a7f921c0f7a1ef143f829f5b116365a297651606d5703f"
- },
- {
- "Key": "graphql.operation.name",
- "Value": "GetA"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseDocument",
- "DisplayName": "Parse Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "cee0e2939ece72d650cb0331f4be4669"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "cee0e2939ece72d650cb0331f4be4669"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "PlanOperation",
- "DisplayName": "Plan Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation GetA",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ExecuteOperationNode",
- "DisplayName": "Execute Operation Node (a)",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.fusion.node.type",
- "Value": "Operation"
- },
- {
- "Key": "graphql.fusion.node.schema",
- "Value": "a"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Create_Operation_Display_Name_With_3_Field.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Create_Operation_Display_Name_With_3_Field.snap
deleted file mode 100644
index f4870f0ca44..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Create_Operation_Display_Name_With_3_Field.snap
+++ /dev/null
@@ -1,104 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { a b c }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "2e55fbe10a9e3ddf26935a8f8d15ec89"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "2e55fbe10a9e3ddf26935a8f8d15ec89"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "8b26a2633c9b68833461d6b2249f54600493dfc632399469d5c108e79410ca7b"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseDocument",
- "DisplayName": "Parse Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "2e55fbe10a9e3ddf26935a8f8d15ec89"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "2e55fbe10a9e3ddf26935a8f8d15ec89"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "PlanOperation",
- "DisplayName": "Plan Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ExecuteOperationNode",
- "DisplayName": "Execute Operation Node (a)",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.fusion.node.type",
- "Value": "Operation"
- },
- {
- "Key": "graphql.fusion.node.schema",
- "Value": "a"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Create_Operation_Display_Name_With_4_Field.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Create_Operation_Display_Name_With_4_Field.snap
deleted file mode 100644
index 1af065e2ac9..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Create_Operation_Display_Name_With_4_Field.snap
+++ /dev/null
@@ -1,104 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { a b c ... }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "a5f924bb2f5f8651014e92e1cc2428c7"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "a5f924bb2f5f8651014e92e1cc2428c7"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "1c020b5562fde1e7673b1f4750bdf6d35f2789819d03bb6b5d088bf445231501"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseDocument",
- "DisplayName": "Parse Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "a5f924bb2f5f8651014e92e1cc2428c7"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "a5f924bb2f5f8651014e92e1cc2428c7"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "PlanOperation",
- "DisplayName": "Plan Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ExecuteOperationNode",
- "DisplayName": "Execute Operation Node (a)",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.fusion.node.type",
- "Value": "Operation"
- },
- {
- "Key": "graphql.fusion.node.schema",
- "Value": "a"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Ensure_Operation_Name_Is_Used_As_Request_Name.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Ensure_Operation_Name_Is_Used_As_Request_Name.snap
deleted file mode 100644
index b58f55ac83f..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Ensure_Operation_Name_Is_Used_As_Request_Name.snap
+++ /dev/null
@@ -1,108 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query SayHelloOperation { sayHello }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "6af18618ae20c266f6ffc352b78cb69b"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "6af18618ae20c266f6ffc352b78cb69b"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "1334fb0da1250c6db5db84b6c98ccb2556f066942f8836d6ebd18fd870172787"
- },
- {
- "Key": "graphql.operation.name",
- "Value": "SayHelloOperation"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseDocument",
- "DisplayName": "Parse Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "6af18618ae20c266f6ffc352b78cb69b"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "6af18618ae20c266f6ffc352b78cb69b"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "PlanOperation",
- "DisplayName": "Plan Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation SayHelloOperation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ExecuteOperationNode",
- "DisplayName": "Execute Operation Node (a)",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.fusion.node.type",
- "Value": "Operation"
- },
- {
- "Key": "graphql.fusion.node.schema",
- "Value": "a"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Ensure_That_The_Validation_Activity_Has_An_Error_Status.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Ensure_That_The_Validation_Activity_Has_An_Error_Status.snap
deleted file mode 100644
index 725e9a44a05..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Ensure_That_The_Validation_Activity_Has_An_Error_Status.snap
+++ /dev/null
@@ -1,84 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "Execute Request",
- "Status": "Error",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "bb1d246465341a97bdc727d6cd8ead5c"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "bb1d246465341a97bdc727d6cd8ead5c"
- },
- {
- "Key": "graphql.document.body",
- "Value": "query SayHelloOperation {\n sayHello_\n}"
- },
- {
- "Key": "otel.status_code",
- "Value": "ERROR"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseDocument",
- "DisplayName": "Parse Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Error",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "ERROR"
- },
- {
- "Key": "graphql.document.id",
- "Value": "bb1d246465341a97bdc727d6cd8ead5c"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "bb1d246465341a97bdc727d6cd8ead5c"
- }
- ],
- "event": [
- {
- "Name": "exception",
- "Tags": [
- {
- "Key": "exception.message",
- "Value": "The field `sayHello_` does not exist on the type `Query`."
- },
- {
- "Key": "exception.type",
- "Value": "GRAPHQL_ERROR"
- },
- {
- "Key": "graphql.error.location.column",
- "Value": 27
- },
- {
- "Key": "graphql.error.location.line",
- "Value": 1
- }
- ]
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Source_Schema_Transport_Error.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Source_Schema_Transport_Error.snap
deleted file mode 100644
index 4a93931c9fa..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Source_Schema_Transport_Error.snap
+++ /dev/null
@@ -1,130 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { sayHello }",
- "Status": "Error",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "456132b93ebaf15a39534753bf72f9f4bfa1152a08d04bc8a88539feec1cb52c"
- },
- {
- "Key": "graphql.document.body",
- "Value": "{\n sayHello\n}"
- },
- {
- "Key": "otel.status_code",
- "Value": "ERROR"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseDocument",
- "DisplayName": "Parse Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "PlanOperation",
- "DisplayName": "Plan Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
- "Status": "Error",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "ERROR"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ExecuteOperationNode",
- "DisplayName": "Execute Operation Node (a)",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.fusion.node.type",
- "Value": "Operation"
- },
- {
- "Key": "graphql.fusion.node.schema",
- "Value": "a"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [
- {
- "Name": "exception",
- "Tags": [
- {
- "Key": "exception.type",
- "Value": "System.Net.Http.HttpRequestException"
- },
- {
- "Key": "exception.stacktrace",
- "Value": "System.Net.Http.HttpRequestException: Response status code does not indicate success: 500 (Internal Server Error).\n at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()\n at HotChocolate.Fusion.Transport.Http.GraphQLHttpResponse.ReadAsResultAsync(CancellationToken cancellationToken) in GraphQLHttpResponse.cs:line 292\n at HotChocolate.Fusion.Execution.Clients.SourceSchemaHttpClient.Response.ReadAsResultStreamAsync(CancellationToken cancellationToken)+MoveNext() in SourceSchemaHttpClient.cs:line 577\n at HotChocolate.Fusion.Execution.Clients.SourceSchemaHttpClient.Response.ReadAsResultStreamAsync(CancellationToken cancellationToken)+System.Threading.Tasks.Sources.IValueTaskSource.GetResult()\n at HotChocolate.Fusion.Execution.Nodes.OperationExecutionNode.OnExecuteAsync(OperationPlanContext context, CancellationToken cancellationToken) in OperationExecutionNode.cs:line 159\n at HotChocolate.Fusion.Execution.Nodes.OperationExecutionNode.OnExecuteAsync(OperationPlanContext context, CancellationToken cancellationToken) in OperationExecutionNode.cs:line 159"
- },
- {
- "Key": "exception.message",
- "Value": "Response status code does not indicate success: 500 (Internal Server Error)."
- }
- ]
- }
- ]
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Track_Events_Of_A_Query_With_Multiple_Sources.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Track_Events_Of_A_Query_With_Multiple_Sources.snap
deleted file mode 100644
index fa4b3838f11..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Track_Events_Of_A_Query_With_Multiple_Sources.snap
+++ /dev/null
@@ -1,124 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { sayHello sayGoodbye }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "073bf7696c078e52587c88890ef21bbe"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "073bf7696c078e52587c88890ef21bbe"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "9babcd211d7b162261fa15a119462370a3f30c61ea319946c30bc4051a265a5d"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseDocument",
- "DisplayName": "Parse Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "073bf7696c078e52587c88890ef21bbe"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "073bf7696c078e52587c88890ef21bbe"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "PlanOperation",
- "DisplayName": "Plan Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ExecuteOperationNode",
- "DisplayName": "Execute Operation Node (a)",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.fusion.node.type",
- "Value": "Operation"
- },
- {
- "Key": "graphql.fusion.node.schema",
- "Value": "a"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperationNode",
- "DisplayName": "Execute Operation Node (b)",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.fusion.node.type",
- "Value": "Operation"
- },
- {
- "Key": "graphql.fusion.node.schema",
- "Value": "b"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Track_Events_Of_A_Simple_Query_Default.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Track_Events_Of_A_Simple_Query_Default.snap
deleted file mode 100644
index 5ecaa32bc36..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Track_Events_Of_A_Simple_Query_Default.snap
+++ /dev/null
@@ -1,56 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "PlanOperation",
- "DisplayName": "Plan Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperationNode",
- "DisplayName": "Execute Operation Node (a)",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.fusion.node.type",
- "Value": "Operation"
- },
- {
- "Key": "graphql.fusion.node.schema",
- "Value": "a"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
-}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Track_Events_Of_A_Simple_Query_Detailed.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Track_Events_Of_A_Simple_Query_Detailed.snap
deleted file mode 100644
index c2b6eb5d039..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Track_Events_Of_A_Simple_Query_Detailed.snap
+++ /dev/null
@@ -1,104 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { sayHello }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "456132b93ebaf15a39534753bf72f9f4bfa1152a08d04bc8a88539feec1cb52c"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseDocument",
- "DisplayName": "Parse Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "PlanOperation",
- "DisplayName": "Plan Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ExecuteOperationNode",
- "DisplayName": "Execute Operation Node (a)",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.fusion.node.type",
- "Value": "Operation"
- },
- {
- "Key": "graphql.fusion.node.schema",
- "Value": "a"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Track_Events_Of_A_Simple_Query_With_Node_Scopes.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Track_Events_Of_A_Simple_Query_With_Node_Scopes.snap
deleted file mode 100644
index c2b6eb5d039..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/QueryInstrumentationTests.Track_Events_Of_A_Simple_Query_With_Node_Scopes.snap
+++ /dev/null
@@ -1,104 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { sayHello }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "456132b93ebaf15a39534753bf72f9f4bfa1152a08d04bc8a88539feec1cb52c"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseDocument",
- "DisplayName": "Parse Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "PlanOperation",
- "DisplayName": "Plan Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ExecuteOperationNode",
- "DisplayName": "Execute Operation Node (a)",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.fusion.node.type",
- "Value": "Operation"
- },
- {
- "Key": "graphql.fusion.node.schema",
- "Value": "a"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Get_Single_Request.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Get_Single_Request.snap
deleted file mode 100644
index bb203ba5752..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Get_Single_Request.snap
+++ /dev/null
@@ -1,138 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteHttpRequest",
- "DisplayName": "GraphQL HTTP GET",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.schema.name",
- "Value": "_Default"
- },
- {
- "Key": "graphql.http.request.type",
- "Value": "single"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseHttpRequest",
- "DisplayName": "Parse HTTP Request",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { sayHello }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "456132b93ebaf15a39534753bf72f9f4bfa1152a08d04bc8a88539feec1cb52c"
- }
- ],
- "event": [
- {
- "Name": "AddedOperationPlanToCache",
- "Tags": []
- },
- {
- "Name": "AddedDocumentToCache",
- "Tags": []
- }
- ],
- "activities": [
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "PlanOperation",
- "DisplayName": "Plan Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ExecuteOperationNode",
- "DisplayName": "Execute Operation Node (a)",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.fusion.node.type",
- "Value": "Operation"
- },
- {
- "Key": "graphql.fusion.node.schema",
- "Value": "a"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- },
- {
- "OperationName": "FormatHttpResponse",
- "DisplayName": "Format HTTP Response",
- "Status": "Ok",
- "tags": [],
- "event": []
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_Add_Query_To_Http_Activity.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_Add_Query_To_Http_Activity.snap
deleted file mode 100644
index 1f787a37f1b..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_Add_Query_To_Http_Activity.snap
+++ /dev/null
@@ -1,150 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteHttpRequest",
- "DisplayName": "GraphQL HTTP POST",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.schema.name",
- "Value": "_Default"
- },
- {
- "Key": "graphql.http.request.type",
- "Value": "single"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseHttpRequest",
- "DisplayName": "Parse HTTP Request",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { greeting }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "bfa5986a5299f46421057dd3eb27ec5c"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "c46cf8c9811934ddea095f10ee722dc4"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "d58281f7cf44ca2751c4a435c0249e686bd1c146f6ddae23ed35ec6e4b83eb77"
- }
- ],
- "event": [
- {
- "Name": "AddedOperationPlanToCache",
- "Tags": []
- },
- {
- "Name": "AddedDocumentToCache",
- "Tags": []
- }
- ],
- "activities": [
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "bfa5986a5299f46421057dd3eb27ec5c"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "c46cf8c9811934ddea095f10ee722dc4"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "PlanOperation",
- "DisplayName": "Plan Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "CoerceVariables",
- "DisplayName": "Coerce Variable",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ExecuteOperationNode",
- "DisplayName": "Execute Operation Node (a)",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.fusion.node.type",
- "Value": "Operation"
- },
- {
- "Key": "graphql.fusion.node.schema",
- "Value": "a"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- },
- {
- "OperationName": "FormatHttpResponse",
- "DisplayName": "Format HTTP Response",
- "Status": "Ok",
- "tags": [],
- "event": []
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_Add_Variables_To_Http_Activity.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_Add_Variables_To_Http_Activity.snap
deleted file mode 100644
index 46c0ade8f33..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_Add_Variables_To_Http_Activity.snap
+++ /dev/null
@@ -1,154 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteHttpRequest",
- "DisplayName": "GraphQL HTTP POST",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.schema.name",
- "Value": "_Default"
- },
- {
- "Key": "graphql.http.request.type",
- "Value": "single"
- },
- {
- "Key": "graphql.http.request.variables",
- "Value": "{\"name\":\"World\"}"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseHttpRequest",
- "DisplayName": "Parse HTTP Request",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { greeting }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "bfa5986a5299f46421057dd3eb27ec5c"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "c46cf8c9811934ddea095f10ee722dc4"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "d58281f7cf44ca2751c4a435c0249e686bd1c146f6ddae23ed35ec6e4b83eb77"
- }
- ],
- "event": [
- {
- "Name": "AddedOperationPlanToCache",
- "Tags": []
- },
- {
- "Name": "AddedDocumentToCache",
- "Tags": []
- }
- ],
- "activities": [
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "bfa5986a5299f46421057dd3eb27ec5c"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "c46cf8c9811934ddea095f10ee722dc4"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "PlanOperation",
- "DisplayName": "Plan Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "CoerceVariables",
- "DisplayName": "Coerce Variable",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ExecuteOperationNode",
- "DisplayName": "Execute Operation Node (a)",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.fusion.node.type",
- "Value": "Operation"
- },
- {
- "Key": "graphql.fusion.node.schema",
- "Value": "a"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- },
- {
- "OperationName": "FormatHttpResponse",
- "DisplayName": "Format HTTP Response",
- "Status": "Ok",
- "tags": [],
- "event": []
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_Single_Request.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_Single_Request.snap
deleted file mode 100644
index 268c3ad7374..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_Single_Request.snap
+++ /dev/null
@@ -1,138 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteHttpRequest",
- "DisplayName": "GraphQL HTTP POST",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.schema.name",
- "Value": "_Default"
- },
- {
- "Key": "graphql.http.request.type",
- "Value": "single"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseHttpRequest",
- "DisplayName": "Parse HTTP Request",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { sayHello }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "456132b93ebaf15a39534753bf72f9f4bfa1152a08d04bc8a88539feec1cb52c"
- }
- ],
- "event": [
- {
- "Name": "AddedOperationPlanToCache",
- "Tags": []
- },
- {
- "Name": "AddedDocumentToCache",
- "Tags": []
- }
- ],
- "activities": [
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "PlanOperation",
- "DisplayName": "Plan Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ExecuteOperationNode",
- "DisplayName": "Execute Operation Node (a)",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.fusion.node.type",
- "Value": "Operation"
- },
- {
- "Key": "graphql.fusion.node.schema",
- "Value": "a"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- },
- {
- "OperationName": "FormatHttpResponse",
- "DisplayName": "Format HTTP Response",
- "Status": "Ok",
- "tags": [],
- "event": []
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_Single_Request_Default.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_Single_Request_Default.snap
deleted file mode 100644
index 86acae93e01..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_Single_Request_Default.snap
+++ /dev/null
@@ -1,114 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteHttpRequest",
- "DisplayName": "query { sayHello }",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.schema.name",
- "Value": "_Default"
- },
- {
- "Key": "graphql.http.request.type",
- "Value": "single"
- },
- {
- "Key": "graphql.document.id",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "456132b93ebaf15a39534753bf72f9f4bfa1152a08d04bc8a88539feec1cb52c"
- }
- ],
- "event": [
- {
- "Name": "AddedOperationPlanToCache",
- "Tags": []
- },
- {
- "Name": "AddedDocumentToCache",
- "Tags": []
- }
- ],
- "activities": [
- {
- "OperationName": "ParseHttpRequest",
- "DisplayName": "Parse HTTP Request",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "f7e9989fbb67af7fa747a9983313c9e5"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "PlanOperation",
- "DisplayName": "Plan Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperationNode",
- "DisplayName": "Execute Operation Node (a)",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.fusion.node.type",
- "Value": "Operation"
- },
- {
- "Key": "graphql.fusion.node.schema",
- "Value": "a"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "FormatHttpResponse",
- "DisplayName": "Format HTTP Response",
- "Status": "Ok",
- "tags": [],
- "event": []
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_Variables_Are_Not_Automatically_Added_To_Activities.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_Variables_Are_Not_Automatically_Added_To_Activities.snap
deleted file mode 100644
index 1f787a37f1b..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_Variables_Are_Not_Automatically_Added_To_Activities.snap
+++ /dev/null
@@ -1,150 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteHttpRequest",
- "DisplayName": "GraphQL HTTP POST",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.schema.name",
- "Value": "_Default"
- },
- {
- "Key": "graphql.http.request.type",
- "Value": "single"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseHttpRequest",
- "DisplayName": "Parse HTTP Request",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { greeting }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "bfa5986a5299f46421057dd3eb27ec5c"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "c46cf8c9811934ddea095f10ee722dc4"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "d58281f7cf44ca2751c4a435c0249e686bd1c146f6ddae23ed35ec6e4b83eb77"
- }
- ],
- "event": [
- {
- "Name": "AddedOperationPlanToCache",
- "Tags": []
- },
- {
- "Name": "AddedDocumentToCache",
- "Tags": []
- }
- ],
- "activities": [
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "bfa5986a5299f46421057dd3eb27ec5c"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "c46cf8c9811934ddea095f10ee722dc4"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "PlanOperation",
- "DisplayName": "Plan Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "CoerceVariables",
- "DisplayName": "Coerce Variable",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ExecuteOperationNode",
- "DisplayName": "Execute Operation Node (a)",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.fusion.node.type",
- "Value": "Operation"
- },
- {
- "Key": "graphql.fusion.node.schema",
- "Value": "a"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- },
- {
- "OperationName": "FormatHttpResponse",
- "DisplayName": "Format HTTP Response",
- "Status": "Ok",
- "tags": [],
- "event": []
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_With_Extensions_Map.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_With_Extensions_Map.snap
deleted file mode 100644
index 2baf19b2df6..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Http_Post_With_Extensions_Map.snap
+++ /dev/null
@@ -1,154 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteHttpRequest",
- "DisplayName": "GraphQL HTTP POST",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.schema.name",
- "Value": "_Default"
- },
- {
- "Key": "graphql.http.request.type",
- "Value": "single"
- },
- {
- "Key": "graphql.http.request.extensions",
- "Value": "{\"test\":\"abc\"}"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseHttpRequest",
- "DisplayName": "Parse HTTP Request",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "query { greeting }",
- "Status": "Unset",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "bfa5986a5299f46421057dd3eb27ec5c"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "c46cf8c9811934ddea095f10ee722dc4"
- },
- {
- "Key": "graphql.operation.id",
- "Value": "d58281f7cf44ca2751c4a435c0249e686bd1c146f6ddae23ed35ec6e4b83eb77"
- }
- ],
- "event": [
- {
- "Name": "AddedOperationPlanToCache",
- "Tags": []
- },
- {
- "Name": "AddedDocumentToCache",
- "Tags": []
- }
- ],
- "activities": [
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "bfa5986a5299f46421057dd3eb27ec5c"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "c46cf8c9811934ddea095f10ee722dc4"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "PlanOperation",
- "DisplayName": "Plan Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "CoerceVariables",
- "DisplayName": "Coerce Variable",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteOperation",
- "DisplayName": "Execute Operation",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ExecuteOperationNode",
- "DisplayName": "Execute Operation Node (a)",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.fusion.node.type",
- "Value": "Operation"
- },
- {
- "Key": "graphql.fusion.node.schema",
- "Value": "a"
- },
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- }
- ]
- }
- ]
- },
- {
- "OperationName": "FormatHttpResponse",
- "DisplayName": "Format HTTP Response",
- "Status": "Ok",
- "tags": [],
- "event": []
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Parsing_Error_When_Rename_Root_Is_Activated.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Parsing_Error_When_Rename_Root_Is_Activated.snap
deleted file mode 100644
index 71a7c84c3a4..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Parsing_Error_When_Rename_Root_Is_Activated.snap
+++ /dev/null
@@ -1,59 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteHttpRequest",
- "DisplayName": "GraphQL HTTP POST: Begin Parse HTTP Request",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.schema.name",
- "Value": "_Default"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseHttpRequest",
- "DisplayName": "Parse HTTP Request",
- "Status": "Error",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "ERROR"
- }
- ],
- "event": [
- {
- "Name": "exception",
- "Tags": [
- {
- "Key": "exception.message",
- "Value": "Expected a `Name`-token, but found a `Integer`-token."
- },
- {
- "Key": "exception.type",
- "Value": "HC0011"
- },
- {
- "Key": "graphql.error.location.column",
- "Value": 3
- },
- {
- "Key": "graphql.error.location.line",
- "Value": 1
- }
- ]
- }
- ]
- },
- {
- "OperationName": "FormatHttpResponse",
- "DisplayName": "Format HTTP Response",
- "Status": "Ok",
- "tags": [],
- "event": []
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Validation_Error_When_Rename_Root_Is_Activated.snap b/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Validation_Error_When_Rename_Root_Is_Activated.snap
deleted file mode 100644
index a8e45a9ef6d..00000000000
--- a/src/HotChocolate/Fusion/test/Fusion.Diagnostics.Tests/__snapshots__/ServerInstrumentationTests.Validation_Error_When_Rename_Root_Is_Activated.snap
+++ /dev/null
@@ -1,105 +0,0 @@
-{
- "activities": [
- {
- "OperationName": "ExecuteHttpRequest",
- "DisplayName": "GraphQL HTTP POST: Begin Validate Document",
- "Status": "Ok",
- "tags": [
- {
- "Key": "graphql.schema.name",
- "Value": "_Default"
- },
- {
- "Key": "graphql.http.request.type",
- "Value": "single"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ParseHttpRequest",
- "DisplayName": "Parse HTTP Request",
- "Status": "Ok",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "OK"
- }
- ],
- "event": []
- },
- {
- "OperationName": "ExecuteRequest",
- "DisplayName": "Execute Request",
- "Status": "Error",
- "tags": [
- {
- "Key": "graphql.document.id",
- "Value": "346f68539881f0624dca2927281d1a2f"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "346f68539881f0624dca2927281d1a2f"
- },
- {
- "Key": "otel.status_code",
- "Value": "ERROR"
- }
- ],
- "event": [],
- "activities": [
- {
- "OperationName": "ValidateDocument",
- "DisplayName": "Validate Document",
- "Status": "Error",
- "tags": [
- {
- "Key": "otel.status_code",
- "Value": "ERROR"
- },
- {
- "Key": "graphql.document.id",
- "Value": "346f68539881f0624dca2927281d1a2f"
- },
- {
- "Key": "graphql.document.hash",
- "Value": "346f68539881f0624dca2927281d1a2f"
- }
- ],
- "event": [
- {
- "Name": "exception",
- "Tags": [
- {
- "Key": "exception.message",
- "Value": "The field `abc` does not exist on the type `Query`."
- },
- {
- "Key": "exception.type",
- "Value": "GRAPHQL_ERROR"
- },
- {
- "Key": "graphql.error.location.column",
- "Value": 3
- },
- {
- "Key": "graphql.error.location.line",
- "Value": 1
- }
- ]
- }
- ]
- }
- ]
- },
- {
- "OperationName": "FormatHttpResponse",
- "DisplayName": "Format HTTP Response",
- "Status": "Ok",
- "tags": [],
- "event": []
- }
- ]
- }
- ]
-}
diff --git a/src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Text/Json/CompositeResultDocumentTests.cs b/src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Text/Json/CompositeResultDocumentTests.cs
index 0e6bfaffd23..7b5b6f04306 100644
--- a/src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Text/Json/CompositeResultDocumentTests.cs
+++ b/src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Text/Json/CompositeResultDocumentTests.cs
@@ -360,7 +360,7 @@ fragment Product on Product {
var path = productBySlug.GetProperty("name").Path;
// assert
- Assert.Equal("/productBySlug/name", path.ToString());
+ Assert.Equal("productBySlug.name", path.ToString());
}
[Fact]
@@ -413,7 +413,7 @@ public void Path_Array_Index()
var path = name.Path;
// assert
- Assert.Equal("/users/nodes[0]/name", path.ToString());
+ Assert.Equal("users.nodes[0].name", path.ToString());
}
[Fact]
diff --git a/src/HotChocolate/Language/src/Language.Web/DocumentHashProviderBase.cs b/src/HotChocolate/Language/src/Language.Web/DocumentHashProviderBase.cs
index 82495992d0d..fa72800232b 100644
--- a/src/HotChocolate/Language/src/Language.Web/DocumentHashProviderBase.cs
+++ b/src/HotChocolate/Language/src/Language.Web/DocumentHashProviderBase.cs
@@ -15,6 +15,8 @@ internal DocumentHashProviderBase(HashFormat format)
public abstract string Name { get; }
+ public abstract string AlgorithmName { get; }
+
public HashFormat Format { get; }
public OperationDocumentHash ComputeHash(ReadOnlySpan document)
@@ -27,7 +29,7 @@ public OperationDocumentHash ComputeHash(ReadOnlySpan document)
{
var hash = ComputeHash(rented, document.Length);
var formattedHash = FormatHash(hash, Format);
- return new OperationDocumentHash(formattedHash, Name, Format);
+ return new OperationDocumentHash(formattedHash, AlgorithmName, Format);
}
finally
{
@@ -35,7 +37,7 @@ public OperationDocumentHash ComputeHash(ReadOnlySpan document)
}
#else
var hash = ComputeHash(document, Format);
- return new OperationDocumentHash(hash, Name, Format);
+ return new OperationDocumentHash(hash, AlgorithmName, Format);
#endif
}
@@ -65,7 +67,7 @@ public OperationDocumentHash ComputeHash(ReadOnlySequence document)
}
#else
var hash = ComputeHash(document, Format);
- return new OperationDocumentHash(hash, Name, Format);
+ return new OperationDocumentHash(hash, AlgorithmName, Format);
#endif
}
diff --git a/src/HotChocolate/Language/src/Language.Web/IDocumentHashProvider.cs b/src/HotChocolate/Language/src/Language.Web/IDocumentHashProvider.cs
index e0264a71342..47c4ccc1d35 100644
--- a/src/HotChocolate/Language/src/Language.Web/IDocumentHashProvider.cs
+++ b/src/HotChocolate/Language/src/Language.Web/IDocumentHashProvider.cs
@@ -12,6 +12,11 @@ public interface IDocumentHashProvider
///
string Name { get; }
+ ///
+ /// The name of the algorithm used for hashing.
+ ///
+ string AlgorithmName { get; }
+
///
/// Gets the format of the document hash.
///
diff --git a/src/HotChocolate/Language/src/Language.Web/MD5DocumentHashProvider.cs b/src/HotChocolate/Language/src/Language.Web/MD5DocumentHashProvider.cs
index 70afad060b5..0196bba9b2b 100644
--- a/src/HotChocolate/Language/src/Language.Web/MD5DocumentHashProvider.cs
+++ b/src/HotChocolate/Language/src/Language.Web/MD5DocumentHashProvider.cs
@@ -18,6 +18,8 @@ public MD5DocumentHashProvider(HashFormat format)
public override string Name => "md5Hash";
+ public override string AlgorithmName => "md5";
+
#if NETSTANDARD2_0
protected override byte[] ComputeHash(byte[] document, int length)
{
diff --git a/src/HotChocolate/Language/src/Language.Web/Sha1DocumentHashProvider.cs b/src/HotChocolate/Language/src/Language.Web/Sha1DocumentHashProvider.cs
index 0d3547d1933..38f7e62f81e 100644
--- a/src/HotChocolate/Language/src/Language.Web/Sha1DocumentHashProvider.cs
+++ b/src/HotChocolate/Language/src/Language.Web/Sha1DocumentHashProvider.cs
@@ -22,6 +22,8 @@ public Sha1DocumentHashProvider(HashFormat format)
public override string Name => "sha1Hash";
+ public override string AlgorithmName => "sha1";
+
#if NETSTANDARD2_0
protected override byte[] ComputeHash(byte[] document, int length)
=> _sha.Value!.ComputeHash(document, 0, length);
diff --git a/src/HotChocolate/Language/src/Language.Web/Sha256DocumentHashProvider.cs b/src/HotChocolate/Language/src/Language.Web/Sha256DocumentHashProvider.cs
index 0bdfa968d02..6412260f720 100644
--- a/src/HotChocolate/Language/src/Language.Web/Sha256DocumentHashProvider.cs
+++ b/src/HotChocolate/Language/src/Language.Web/Sha256DocumentHashProvider.cs
@@ -22,6 +22,8 @@ public Sha256DocumentHashProvider(HashFormat format)
public override string Name => "sha256Hash";
+ public override string AlgorithmName => "sha256";
+
#if NETSTANDARD2_0
protected override byte[] ComputeHash(byte[] document, int length)
{
diff --git a/src/HotChocolate/Language/src/Language.Web/Utf8GraphQLRequestParser.cs b/src/HotChocolate/Language/src/Language.Web/Utf8GraphQLRequestParser.cs
index 014e690e2a3..f2cf19074eb 100644
--- a/src/HotChocolate/Language/src/Language.Web/Utf8GraphQLRequestParser.cs
+++ b/src/HotChocolate/Language/src/Language.Web/Utf8GraphQLRequestParser.cs
@@ -328,7 +328,7 @@ private readonly GraphQLRequest ParseRequest(ref Utf8JsonReader reader, Operatio
&& TryExtractHash(extensions, out var hash))
{
documentId = new OperationDocumentId(hash);
- documentHash = new OperationDocumentHash(hash, _hashProvider!.Name, _hashProvider.Format);
+ documentHash = new OperationDocumentHash(hash, _hashProvider!.AlgorithmName, _hashProvider.Format);
}
// Parse the GraphQL document if provided
diff --git a/src/HotChocolate/Language/test/Language.Web.Tests/Utf8GraphQLRequestParserTests.cs b/src/HotChocolate/Language/test/Language.Web.Tests/Utf8GraphQLRequestParserTests.cs
index cd729e3471c..cba67360c1c 100644
--- a/src/HotChocolate/Language/test/Language.Web.Tests/Utf8GraphQLRequestParserTests.cs
+++ b/src/HotChocolate/Language/test/Language.Web.Tests/Utf8GraphQLRequestParserTests.cs
@@ -458,7 +458,7 @@ public void Parse_Apollo_AQP_SignatureQuery()
Assert.True(request.Extensions!.RootElement.TryGetProperty("persistedQuery", out _));
Assert.Null(request.Document);
Assert.Equal("hashOfQuery", request.DocumentHash?.Value);
- Assert.Equal("sha256Hash", request.DocumentHash?.AlgorithmName);
+ Assert.Equal("sha256", request.DocumentHash?.AlgorithmName);
}
[Fact]
diff --git a/src/HotChocolate/PersistedOperations/src/PersistedOperations.Pipeline/Execution/Pipeline/ReadPersistedOperationMiddleware.cs b/src/HotChocolate/PersistedOperations/src/PersistedOperations.Pipeline/Execution/Pipeline/ReadPersistedOperationMiddleware.cs
index 43f23ce6e04..0905fb5d30d 100644
--- a/src/HotChocolate/PersistedOperations/src/PersistedOperations.Pipeline/Execution/Pipeline/ReadPersistedOperationMiddleware.cs
+++ b/src/HotChocolate/PersistedOperations/src/PersistedOperations.Pipeline/Execution/Pipeline/ReadPersistedOperationMiddleware.cs
@@ -86,7 +86,7 @@ private static DocumentNode GetOrParseDocument(IOperationDocument document)
private OperationDocumentHash GetDocumentHash(IOperationDocument document)
{
if (document is IOperationDocumentHashProvider hashProvider
- && _documentHashAlgorithm.Name.Equals(hashProvider.Hash.AlgorithmName)
+ && _documentHashAlgorithm.AlgorithmName.Equals(hashProvider.Hash.AlgorithmName)
&& _documentHashAlgorithm.Format.Equals(hashProvider.Hash.Format))
{
return hashProvider.Hash;
diff --git a/website/src/docs/hotchocolate/v16/migrating/migrate-from-15-to-16.md b/website/src/docs/hotchocolate/v16/migrating/migrate-from-15-to-16.md
index e47a95b9a5b..a9f75cf24c9 100644
--- a/website/src/docs/hotchocolate/v16/migrating/migrate-from-15-to-16.md
+++ b/website/src/docs/hotchocolate/v16/migrating/migrate-from-15-to-16.md
@@ -687,6 +687,128 @@ builder
.AddType(new DurationType("TimeSpan"));
```
+## AddInstrumentation
+
+### `InstrumentationOptions` changes
+
+- `RenameRootActivity` was removed.
+- `RequestDetails.Operation` was renamed to `RequestDetails.OperationName`.
+- `RequestDetails.Query` was renamed to `RequestDetails.Document`.
+
+## OpenTelemetry span and status changes
+
+The OpenTelemetry spans and attributes emitted by `AddInstrumentation()` have been updated to align with the [proposed OpenTelemetry semantic conventions for GraphQL](https://github.com/graphql/otel-wg/blob/main/spec).
+
+If you have dashboards or alerts that filter on the old attribute names or values, update them accordingly.
+
+Besides changes to the attributes, the most notable change is that the name of the root GraphQL span has been changed to just include the operation type (`query`, `mutation` or `subscription`), and no longer the operation name, to keep the cardinality low. The operation name can still be retrieved from the `graphql.operation.name` span attribute.
+
+### Removed attributes
+
+| Attribute |
+| ----------------------------- |
+| `graphql.operation.id` |
+| `graphql.selection.type` |
+| `graphql.selection.hierarchy` |
+
+### Renamed attributes
+
+| Old Attribute | New Attribute |
+| --------------------------------------- | ------------------------------------- |
+| `graphql.operation.kind` | `graphql.operation.type` |
+| `graphql.selection.field.declaringType` | `graphql.selection.field.parent_type` |
+| `graphql.dataLoader.keys.count` | `graphql.dataloader.batch.size` |
+| `graphql.dataLoader.keys` | `graphql.dataloader.batch.keys` |
+| `graphql.fusion.node.schema` | `graphql.source.name` |
+| `graphql.fusion.node.type` | `graphql.operation.step.kind` |
+| `graphql.error.location.line/column` | `graphql.error.locations` |
+
+### Changed attribute values
+
+| Attribute | Old Value | New Value |
+| ------------------------ | ------------------------------------- | --------------------------------------------------- |
+| `graphql.operation.type` | `Query` / `Mutation` / `Subscription` | `query` / `mutation` / `subscription` |
+| `graphql.http.kind` | `operation-batch` | `operation_batch` |
+| `graphql.document.hash` | `` | `:` , e.g. `md5:` |
+| `graphql.document.id` | - | Value is only set if document is a trusted document |
+
+### Custom enricher changes
+
+If you've implemented a custom `ActivityEnricher`, you no longer need to pass the `ObjectPool` down to the base class:
+
+```diff
+public class CustomActivityEnricher(
+- ObjectPool stringBuilderPool,
+ InstrumentationOptions options
+-) : ActivityEnricher(stringBuilderPool, options);
++) : ActivityEnricher(options);
+```
+
+There have also been some changes to the methods you can override in your enricher:
+
+| v15 | v16 |
+| ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `EnrichParserErrors(HttpContext, IError, Activity)` | Replaced by `EnrichParserErrors(HttpContext, IReadOnlyList, Activity)`. |
+| `EnrichRequestError(RequestContext, Activity, Exception)` | Replaced by `EnrichRequestError(RequestContext, Exception, Activity)`. |
+| `EnrichRequestError(RequestContext, Activity, IError)` | Replaced by `EnrichRequestError(RequestContext, IError, Activity)`. |
+| `EnrichValidationError(RequestContext, Activity, IError)` | Replaced by `EnrichValidationErrors(RequestContext, IReadOnlyList, Activity)`. |
+| `EnrichAnalyzeOperationComplexity(RequestContext, Activity)` | Replaced by `EnrichAnalyzeOperationCost(RequestContext, Activity)`. |
+| `EnrichDataLoaderBatch(IDataLoader, IReadOnlyList, Activity)` | Replaced by `EnrichExecuteBatch(IDataLoader, IReadOnlyList, Activity)`. |
+| `EnrichResolverError(RequestContext, IError, Activity)` | Removed. Use `EnrichRequestError(...)` for request-level errors and `EnrichResolverError(IMiddlewareContext, IError, Activity)` for field resolver errors. |
+| `EnrichRequestVariables(...)` | Removed. |
+| `EnrichBatchVariables(...)` | Removed. |
+| `EnrichRequestExtensions(...)` | Removed. |
+| `EnrichBatchExtensions(...)` | Removed. |
+| `CreateOperationDisplayName(...)` | Removed. |
+| `CreateRootActivityName(...)` | Removed. |
+| `EnrichError(...)` | Removed. |
+
+> Note: Overriding enricher methods without calling `base` no longer prevents the standard span attributes from being emitted. The semantic-convention attributes are now applied by the instrumentation itself, and custom enrichers are only intended for adding extra information.
+
+## Diagnostic Listeners
+
+We removed the following methods from the `IExecutionDiagnosticEventListener` since they no longer apply:
+
+- `ExecuteStream`
+- `ExecuteDeferredTask`
+- `DispatchBatch`
+- `SubscriptionTransportError`
+- `SubscriptionEventResult`
+
+Some other methods also had a change in their signature - simply override them again to fix any compilation issues.
+
+
+
# Deprecations
Things that will continue to function this release, but we encourage you to move away from.