diff --git a/README.md b/README.md index 8b1f5f1..322fcb4 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ new MassTransitDiagnosticsSubscriber(o => ``` The same can be used also for `SendLabel` ## HotChocolate +### Usage HotChocolate by default is not emitting diagnostic events, but has the infrastructure to instrument each request. ```csharp public class Startup @@ -57,6 +58,19 @@ public class Startup } } ``` +### Options +Elastic APM Transaction can be enriched by registering a delegate on configure parameter. In this way you can add custom data to the transaction. +```csharp +services + .AddGraphQLServer() + .AddObservability(o => + o.Enrich = (transaction, operationDetails) => + { + transaction.SetLabel("GraphQLResult", operationDetails.HasFailed); + transaction.SetLabel("Department", Environment.GetEnvironmentVariable("DEPARTMENT")); + }); +``` + ## Community This project has adopted the code of conduct defined by the [Contributor Covenant](https://contributor-covenant.org/) diff --git a/src/Elastic.Apm.GraphQL.HotChocolate/HotChocolateDiagnosticListener.cs b/src/Elastic.Apm.GraphQL.HotChocolate/HotChocolateDiagnosticListener.cs index 219760b..726ee67 100644 --- a/src/Elastic.Apm.GraphQL.HotChocolate/HotChocolateDiagnosticListener.cs +++ b/src/Elastic.Apm.GraphQL.HotChocolate/HotChocolateDiagnosticListener.cs @@ -18,17 +18,17 @@ internal class HotChocolateDiagnosticListener : DiagnosticEventListener private readonly IApmAgent _apmAgent; private readonly IConfigurationReader _configuration; - private readonly EnrichTransaction? _enrich; + private readonly HotChocolateDiagnosticOptions _options; private readonly IApmLogger _apmLogger; internal HotChocolateDiagnosticListener( IApmAgent apmAgent, IConfigurationReader configuration, - EnrichTransaction? enrich) + HotChocolateDiagnosticOptions options) { _apmAgent = apmAgent; _configuration = configuration; - _enrich = enrich; + _options = options; _apmLogger = _apmAgent.Logger; } @@ -36,7 +36,7 @@ public override IActivityScope ExecuteRequest(IRequestContext context) { ITransaction? transaction = _apmAgent.Tracer.CurrentTransaction; return transaction != null - ? new RequestActivityScope(context, transaction, _apmAgent, _enrich) + ? new RequestActivityScope(context, transaction, _apmAgent, _options) : EmptyScope; } diff --git a/src/Elastic.Apm.GraphQL.HotChocolate/HotChocolateDiagnosticOptions.cs b/src/Elastic.Apm.GraphQL.HotChocolate/HotChocolateDiagnosticOptions.cs new file mode 100644 index 0000000..6af1e8b --- /dev/null +++ b/src/Elastic.Apm.GraphQL.HotChocolate/HotChocolateDiagnosticOptions.cs @@ -0,0 +1,13 @@ +using System; +using Elastic.Apm.Api; + +namespace Elastic.Apm.GraphQL.HotChocolate +{ + public class HotChocolateDiagnosticOptions + { + /// + /// Gives the possibility to enrich transaction data just before gets disposed. + /// + public Action? Enrich { get; set; } + } +} diff --git a/src/Elastic.Apm.GraphQL.HotChocolate/RequestExecutorBuilderExtensions.cs b/src/Elastic.Apm.GraphQL.HotChocolate/RequestExecutorBuilderExtensions.cs index 3e7c1f0..8fed4e1 100644 --- a/src/Elastic.Apm.GraphQL.HotChocolate/RequestExecutorBuilderExtensions.cs +++ b/src/Elastic.Apm.GraphQL.HotChocolate/RequestExecutorBuilderExtensions.cs @@ -1,18 +1,10 @@ using System; -using Elastic.Apm.Api; using Elastic.Apm.Config; using HotChocolate.Execution.Configuration; using Microsoft.Extensions.DependencyInjection; namespace Elastic.Apm.GraphQL.HotChocolate { - /// - /// Gives the possibility to enrich transaction data just before gets disposed. - /// - /// - /// - public delegate void EnrichTransaction(ITransaction transaction, OperationDetails details); - /// /// Report diagnostic events to Elastic /// @@ -20,18 +12,21 @@ public static class RequestExecutorBuilderExtensions { public static IRequestExecutorBuilder AddObservability( this IRequestExecutorBuilder builder, - EnrichTransaction? enrich = default) + Action? configure = default) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } + var options = new HotChocolateDiagnosticOptions(); + configure?.Invoke(options); + return builder.AddDiagnosticEventListener(sp => { IApmAgent apmAgent = sp.GetApplicationService(); IConfigurationReader configuration = sp.GetApplicationService(); - return new HotChocolateDiagnosticListener(apmAgent, configuration, enrich); + return new HotChocolateDiagnosticListener(apmAgent, configuration, options); }); } } diff --git a/src/Elastic.Apm.GraphQL.HotChocolate/Scopes/RequestActivityScope.cs b/src/Elastic.Apm.GraphQL.HotChocolate/Scopes/RequestActivityScope.cs index 3039958..568e70c 100644 --- a/src/Elastic.Apm.GraphQL.HotChocolate/Scopes/RequestActivityScope.cs +++ b/src/Elastic.Apm.GraphQL.HotChocolate/Scopes/RequestActivityScope.cs @@ -18,17 +18,18 @@ internal class RequestActivityScope : IActivityScope private readonly IRequestContext _context; private readonly ITransaction _transaction; private readonly IApmAgent _apmAgent; - private readonly EnrichTransaction? _enrich; + private readonly HotChocolateDiagnosticOptions _options; - internal RequestActivityScope(IRequestContext context, + internal RequestActivityScope( + IRequestContext context, ITransaction transaction, IApmAgent apmAgent, - EnrichTransaction? enrich) + HotChocolateDiagnosticOptions options) { _context = context; _transaction = transaction; _apmAgent = apmAgent; - _enrich = enrich; + _options = options; } public void Dispose() @@ -51,7 +52,7 @@ public void Dispose() _apmAgent.CaptureException(exception); } - _enrich?.Invoke(_transaction, operationDetails); + _options.Enrich?.Invoke(_transaction, operationDetails); } catch (Exception ex) { diff --git a/src/Elastic.Apm.Messaging.MassTransit/MassTransitDiagnosticsSubscriber.cs b/src/Elastic.Apm.Messaging.MassTransit/MassTransitDiagnosticsSubscriber.cs index d7d4b94..d753a42 100644 --- a/src/Elastic.Apm.Messaging.MassTransit/MassTransitDiagnosticsSubscriber.cs +++ b/src/Elastic.Apm.Messaging.MassTransit/MassTransitDiagnosticsSubscriber.cs @@ -9,7 +9,7 @@ namespace Elastic.Apm.Messaging.MassTransit /// public class MassTransitDiagnosticsSubscriber : IDiagnosticsSubscriber { - private MassTransitDiagnosticOptions _options; + private readonly MassTransitDiagnosticOptions _options; public MassTransitDiagnosticsSubscriber(Action? configure = default) {