-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(graphql): Removed Application Insights SDK, added OpenTelemetry (…
…#1349) <!--- Provide a general summary of your changes in the Title above --> ## Description Removed Application Insights SDK, added OpenTelemetry <!--- Describe your changes in detail --> ## Related Issue(s) - #1101 ## Verification - [x] **Your** code builds clean without any errors or warnings - [x] Manual testing done (required) - [ ] Relevant automated test added (if you find this hard, leave it and we'll help out) ## Documentation - [ ] Documentation is updated (either in `docs`-directory, Altinnpedia or a separate linked PR in [altinn-studio-docs.](https://github.com/Altinn/altinn-studio-docs), if applicable) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced `OpenTelemetryEventListener` for enhanced tracing and monitoring of GraphQL requests. - Updated telemetry configuration to streamline logging and ensure consistent telemetry setup. - **Bug Fixes** - Removed the deprecated `ApplicationInsightEventListener`, improving the overall telemetry approach. - **Refactor** - Adjusted service collection to replace the event listener for GraphQL with the new OpenTelemetry implementation. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Ole Jørgen Skogstad <skogstad@softis.net>
- Loading branch information
Showing
4 changed files
with
126 additions
and
120 deletions.
There are no files selected for viewing
114 changes: 0 additions & 114 deletions
114
src/Digdir.Domain.Dialogporten.GraphQL/ApplicationInsightEventListener.cs
This file was deleted.
Oops, something went wrong.
112 changes: 112 additions & 0 deletions
112
src/Digdir.Domain.Dialogporten.GraphQL/OpenTelemetryEventListener.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
using System.Diagnostics; | ||
using HotChocolate.Execution; | ||
using HotChocolate.Execution.Instrumentation; | ||
using Microsoft.AspNetCore.Http.Extensions; | ||
using OpenTelemetry.Trace; | ||
|
||
namespace Digdir.Domain.Dialogporten.GraphQL; | ||
|
||
public sealed class OpenTelemetryEventListener : ExecutionDiagnosticEventListener | ||
{ | ||
private static readonly ActivitySource ActivitySource = new("Dialogporten.GraphQL"); | ||
|
||
public override IDisposable ExecuteRequest(IRequestContext context) | ||
{ | ||
var httpContext = GetHttpContextFrom(context); | ||
if (httpContext == null) | ||
return EmptyScope; | ||
|
||
#if DEBUG | ||
if (context.Request.OperationName == "IntrospectionQuery") | ||
return EmptyScope; | ||
#endif | ||
|
||
var operationName = context.Request.OperationName ?? "UnknownOperation"; | ||
var operationPath = $"{operationName} - {context.Request.QueryHash}"; | ||
|
||
var activity = ActivitySource.StartActivity($"GraphQL {operationPath}", ActivityKind.Server); | ||
|
||
if (activity == null) | ||
return EmptyScope; | ||
|
||
activity.SetTag("graphql.operation_name", operationName); | ||
activity.SetTag("graphql.query_hash", context.Request.QueryHash); | ||
activity.SetTag("http.url", httpContext.Request.GetDisplayUrl()); | ||
activity.SetTag("user.id", httpContext.User.Identity?.Name ?? "Not authenticated"); | ||
activity.SetTag("http.method", httpContext.Request.Method); | ||
activity.SetTag("http.route", httpContext.Request.Path); | ||
|
||
return new ScopeWithEndAction(() => OnEndRequest(context, activity)); | ||
} | ||
|
||
public override void RequestError(IRequestContext context, Exception exception) | ||
{ | ||
var currentActivity = Activity.Current; | ||
if (currentActivity != null) | ||
{ | ||
currentActivity.RecordException(exception); | ||
currentActivity.SetStatus(ActivityStatusCode.Error, exception.Message); | ||
} | ||
base.RequestError(context, exception); | ||
} | ||
|
||
public override void ValidationErrors(IRequestContext context, IReadOnlyList<IError> errors) | ||
{ | ||
foreach (var error in errors) | ||
{ | ||
var currentActivity = Activity.Current; | ||
currentActivity?.AddEvent(new ActivityEvent("ValidationError", default, new ActivityTagsCollection | ||
{ | ||
{ "message", error.Message } | ||
})); | ||
} | ||
|
||
base.ValidationErrors(context, errors); | ||
} | ||
|
||
private static HttpContext? GetHttpContextFrom(IRequestContext context) => | ||
context.ContextData.TryGetValue("HttpContext", out var value) ? value as HttpContext : null; | ||
|
||
private static void OnEndRequest(IRequestContext context, Activity activity) | ||
{ | ||
var httpContext = GetHttpContextFrom(context); | ||
if (context.Exception != null) | ||
{ | ||
activity.RecordException(context.Exception); | ||
activity.SetStatus(ActivityStatusCode.Error, context.Exception.Message); | ||
} | ||
|
||
if (context.Result is QueryResult { Errors: not null } queryResult) | ||
{ | ||
foreach (var error in queryResult.Errors) | ||
{ | ||
if (error.Exception is null) | ||
{ | ||
continue; | ||
} | ||
|
||
activity.RecordException(error.Exception); | ||
activity.SetStatus(ActivityStatusCode.Error, error.Exception.Message); | ||
} | ||
} | ||
|
||
if (httpContext != null) | ||
{ | ||
activity.SetTag("http.status_code", httpContext.Response.StatusCode); | ||
} | ||
|
||
activity.Dispose(); | ||
} | ||
} | ||
|
||
internal sealed class ScopeWithEndAction : IDisposable | ||
{ | ||
private readonly Action _disposeAction; | ||
|
||
public ScopeWithEndAction(Action disposeAction) | ||
{ | ||
_disposeAction = disposeAction; | ||
} | ||
|
||
public void Dispose() => _disposeAction.Invoke(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters