Log your Optimizely Graph queries
Log Graph calls from .NET in in a way where it's easy to copy the query and parameters to GraphiQL.
Using a DelegatingHandler is the recommended way of intercepting and logging HttpClient requests.
Add one that reads the outgoing request body into a JsonNode and extracts the query and variables.
using System;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Threading.Tasks;
using EPiServer.Logging;
public class GraphClientLoggerDelegatingHandler : DelegatingHandler
{
private static readonly ILogger log = LogManager.GetLogger();
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// ReSharper disable once InvertIf
if (log.IsInformationEnabled() && request.Content != null)
{
JsonNode? jsonNode = null;
try
{
jsonNode = await JsonNode.ParseAsync(
await request.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false),
cancellationToken: cancellationToken)!.ConfigureAwait(false);
}
catch (JsonException e)
{
log.Error("Error parsing body", e);
}
if (jsonNode is null)
{
log.Error("jsonNode is null");
}
else
{
var options = new JsonSerializerOptions { WriteIndented = true };
log.Information(jsonNode["query"]?.ToJsonString(options)?.Trim('"'));
log.Information(jsonNode["variables"]?.ToJsonString(options));
}
}
return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
}
}
Register it in the dependency injection container.
services.AddTransient<GraphClientLoggerDelegatingHandler>();
For use with Strawberry Shake.
var queryOptions = configuration
.GetSection(Optimizely.Graph.Core.Configuration.GraphOptions.ConfigurationSectionName)
.Get<Optimizely.Graph.Core.Configuration.GraphOptions>() ?? throw new InvalidOperationException("Optimizely:ContentGraph configuration is missing.");
var contentGraphUrl = new Uri(queryOptions.GatewayAddress, "content/v2?auth=" + queryOptions.SingleKey);
services
.AddCustomGraphClient()
.ConfigureHttpClient(
client => client.BaseAddress = contentGraphUrl,
configureClientBuilder => configureClientBuilder.AddHttpMessageHandler<GraphClientLoggerDelegatingHandler>());
For the Graph C# SDK package.
// Attach to the existing named HttpClient
services.Configure<HttpClientFactoryOptions>(
"Optimizely.Graph.Core.Client.Authenticated",
options =>
{
options.HttpMessageHandlerBuilderActions.Add(builder =>
{
var handler = builder.Services.GetRequiredService<GraphClientLoggerDelegatingHandler>();
builder.AdditionalHandlers.Add(handler);
});
});
Now you will get the query logged, when pasting to GraphiQL you can use the format option there to prettify it.
The variables used are already logged in a readable and copy/paste-friendly format.
Comments?
Published and tagged with these categories: Optimizely