Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ public void AddException(Exception exception)
{ "exception.stacktrace", exception.ToString() },
{ "exception.type", exception.GetType().ToString() }
}));

activity.SetErrorType(exception);
}
#endif

public void AddGraphQLError(IError error)
public void AddGraphQLError(IError error, string? operationType = null, string? operationName = null)
{
var tags = new ActivityTagsCollection
{
Expand Down Expand Up @@ -64,7 +66,33 @@ public void AddGraphQLError(IError error)
tags[SemanticConventions.GraphQL.Error.Locations] = locations;
}

activity.AddEvent(new ActivityEvent("exception", default, tags));
if (operationType is not null)
{
tags[SemanticConventions.GraphQL.Operation.Type] = operationType;
}

if (!string.IsNullOrEmpty(operationName))
{
tags[SemanticConventions.GraphQL.Operation.Name] = operationName;
}

activity.AddEvent(new ActivityEvent("graphql.error", default, tags));

if (activity.GetTagItem(SemanticConventions.ErrorType) is null)
{
var errorType = !string.IsNullOrEmpty(error.Code)
? error.Code
: error.Exception?.GetType().FullName ?? "GRAPHQL_ERROR";
activity.SetTag(SemanticConventions.ErrorType, errorType);
}
}

public void SetErrorType(Exception exception)
{
if (activity.GetTagItem(SemanticConventions.ErrorType) is null)
{
activity.SetTag(SemanticConventions.ErrorType, exception.GetType().FullName);
}
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ namespace HotChocolate.Diagnostics;

internal static class SemanticConventions
{
public const string ErrorType = "error.type";

public static class GraphQL
{
public static class Document
Expand Down Expand Up @@ -112,23 +114,18 @@ public static class Source
public static class Operation
{
public const string Name = "graphql.source.operation.name";
public const string Kind = "graphql.source.operation.kind";
public const string Type = "graphql.source.operation.type";
public const string Hash = "graphql.source.operation.hash";
}
}

// Note: This is not part of the OTEL semantic conventions
public static class Errors
{
public const string Count = "graphql.errors.count";
}

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 const string Count = "graphql.error.count";

public static class Location
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ protected override void OnComplete()
if (context.Result is null or OperationResult { Errors: [_, ..] })
{
Activity.SetStatus(ActivityStatusCode.Error);

if (Activity.GetTagItem(SemanticConventions.ErrorType) is null)
{
Activity.SetTag(SemanticConventions.ErrorType, "EXECUTION_ERROR");
}
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,17 @@ protected override void OnComplete()
if (Context.Result is OperationResult result)
{
// This was previously also always set to 0, so I just kept that behavior.
Activity.SetTag(GraphQL.Errors.Count, result.Errors.Count);
Activity.SetTag(GraphQL.Error.Count, result.Errors.Count);
}

if (Context.Result is null or OperationResult { Errors: [_, ..] })
{
Activity.SetStatus(ActivityStatusCode.Error);

if (Activity.GetTagItem(SemanticConventions.ErrorType) is null)
{
Activity.SetTag(SemanticConventions.ErrorType, "EXECUTION_ERROR");
}
}
else if (Activity.Status != ActivityStatusCode.Error)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ public void RecordError(Exception exception)
{
Activity.SetStatus(ActivityStatusCode.Error);
Activity.AddException(exception);
Activity.SetErrorType(exception);

enricher.EnrichHttpRequestError(httpContext, exception, Activity);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public override void BatchDispatchError(Exception error)
{
activity.SetStatus(ActivityStatusCode.Error);
activity.AddException(error);
activity.SetErrorType(error);

enricher.EnrichBatchDispatchError(error, activity);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public override void RequestError(RequestContext context, Exception error)

activity.SetStatus(ActivityStatusCode.Error);
activity.AddException(error);
activity.SetErrorType(error);

enricher.EnrichRequestError(context, error, activity);
}
Expand All @@ -67,8 +68,15 @@ public override void RequestError(RequestContext context, IError error)
{
var activity = span.Activity;

string? opType = null, opName = null;
if (context.TryGetOperation(out var operation))
{
opType = SemanticConventions.GraphQL.Operation.TypeValues[operation.Kind];
opName = operation.Name;
}

activity.SetStatus(ActivityStatusCode.Error);
activity.AddGraphQLError(error);
activity.AddGraphQLError(error, opType, opName);

enricher.EnrichRequestError(context, error, activity);
}
Expand Down Expand Up @@ -114,11 +122,18 @@ public override void ValidationErrors(RequestContext context, IReadOnlyList<IErr

var activity = span.Activity;

string? opType = null, opName = null;
if (context.TryGetOperation(out var operation))
{
opType = SemanticConventions.GraphQL.Operation.TypeValues[operation.Kind];
opName = operation.Name;
}

activity.SetStatus(ActivityStatusCode.Error);

foreach (var error in errors)
{
activity.AddGraphQLError(error);
activity.AddGraphQLError(error, opType, opName);
}

enricher.EnrichValidationErrors(context, errors, activity);
Expand Down Expand Up @@ -233,8 +248,11 @@ public override void ResolverError(IMiddlewareContext context, IError error)
if (context.LocalContextData.TryGetValue(ResolveFieldSpanKey, out var value)
&& value is ResolveFieldSpan span)
{
var opType = SemanticConventions.GraphQL.Operation.TypeValues[context.Operation.Kind];
var opName = context.Operation.Name;

span.Activity.SetStatus(ActivityStatusCode.Error);
span.Activity.AddGraphQLError(error);
span.Activity.AddGraphQLError(error, opType, opName);

enricher.EnrichResolverError(context, error, span.Activity);
}
Expand Down Expand Up @@ -294,6 +312,7 @@ public override void SubscriptionEventError(
{
activity.SetStatus(ActivityStatusCode.Error);
activity.AddException(exception);
activity.SetErrorType(exception);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ private static void SerializeActivity(Activity activity)

data["OperationName"] = activity.OperationName;
data["DisplayName"] = activity.DisplayName;
data["Kind"] = activity.Kind;
data["Status"] = activity.Status;
data["tags"] = activity.TagObjects;
data["event"] = activity.Events.Select(t => new
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
{
"OperationName": "GraphQL DataLoader Dispatch",
"DisplayName": "GraphQL DataLoader Dispatch",
"Kind": "Internal",
"Status": "Ok",
"tags": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
{
"OperationName": "GraphQL DataLoader Dispatch",
"DisplayName": "GraphQL DataLoader Dispatch",
"Kind": "Internal",
"Status": "Ok",
"tags": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
{
"OperationName": "GraphQL Operation",
"DisplayName": "query",
"Kind": "Internal",
"Status": "Ok",
"tags": [
{
Expand All @@ -14,7 +15,7 @@
"Value": "md5:f7e9989fbb67af7fa747a9983313c9e5"
},
{
"Key": "graphql.errors.count",
"Key": "graphql.error.count",
"Value": 0
}
],
Expand All @@ -32,6 +33,7 @@
{
"OperationName": "GraphQL Document Parsing",
"DisplayName": "GraphQL Document Parsing",
"Kind": "Internal",
"Status": "Ok",
"tags": [
{
Expand All @@ -44,6 +46,7 @@
{
"OperationName": "GraphQL Document Validation",
"DisplayName": "GraphQL Document Validation",
"Kind": "Internal",
"Status": "Ok",
"tags": [
{
Expand All @@ -60,6 +63,7 @@
{
"OperationName": "GraphQL Operation Planning",
"DisplayName": "GraphQL Operation Planning",
"Kind": "Internal",
"Status": "Ok",
"tags": [
{
Expand All @@ -80,6 +84,7 @@
{
"OperationName": "GraphQL Operation Execution",
"DisplayName": "GraphQL Operation Execution",
"Kind": "Internal",
"Status": "Ok",
"tags": [
{
Expand All @@ -100,6 +105,7 @@
{
"OperationName": "SimpleQuery.sayHello",
"DisplayName": "SimpleQuery.sayHello",
"Kind": "Internal",
"Status": "Ok",
"tags": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
{
"OperationName": "GraphQL Operation",
"DisplayName": "query",
"Kind": "Internal",
"Status": "Ok",
"tags": [
{
Expand All @@ -22,7 +23,7 @@
"Value": "query SayHelloOperation {\n sayHello\n}"
},
{
"Key": "graphql.errors.count",
"Key": "graphql.error.count",
"Value": 0
}
],
Expand All @@ -40,6 +41,7 @@
{
"OperationName": "GraphQL Document Parsing",
"DisplayName": "GraphQL Document Parsing",
"Kind": "Internal",
"Status": "Ok",
"tags": [
{
Expand All @@ -52,6 +54,7 @@
{
"OperationName": "GraphQL Document Validation",
"DisplayName": "GraphQL Document Validation",
"Kind": "Internal",
"Status": "Ok",
"tags": [
{
Expand All @@ -68,6 +71,7 @@
{
"OperationName": "GraphQL Operation Planning",
"DisplayName": "GraphQL Operation Planning",
"Kind": "Internal",
"Status": "Ok",
"tags": [
{
Expand All @@ -92,6 +96,7 @@
{
"OperationName": "GraphQL Operation Execution",
"DisplayName": "GraphQL Operation Execution",
"Kind": "Internal",
"Status": "Ok",
"tags": [
{
Expand All @@ -116,6 +121,7 @@
{
"OperationName": "SimpleQuery.sayHello",
"DisplayName": "SimpleQuery.sayHello",
"Kind": "Internal",
"Status": "Ok",
"tags": [
{
Expand Down
Loading
Loading