Skip to content

Instantly share code, notes, and snippets.

@orjan
Created May 26, 2024 20:42

Revisions

  1. orjan created this gist May 26, 2024.
    50 changes: 50 additions & 0 deletions CosmosDebugRequestHandler.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,50 @@
    using System.Text;
    using System.Text.Json;
    using Microsoft.Azure.Cosmos;
    using Serilog;

    namespace api.Setup;

    internal class CosmosDebugRequestHandler : RequestHandler
    {
    private readonly static JsonSerializerOptions CosmosJsonSerializerOptions = new()
    {
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    };

    public record RequestParameter(string Name, object Value);

    public record CosmosRequestContent(string Query, RequestParameter[] Parameters);

    public override async Task<ResponseMessage> SendAsync(RequestMessage request, CancellationToken cancellationToken)
    {
    var response = await base.SendAsync(request, cancellationToken);

    if (response.Headers.RequestCharge > 0 && request.Headers["Content-Type"] == "application/query+json")
    {
    var deserializeAsync = await JsonSerializer.DeserializeAsync<CosmosRequestContent>(request.Content, CosmosJsonSerializerOptions, cancellationToken);
    var partitionKey = request.Headers.GetValueOrDefault("x-ms-documentdb-partitionkey");
    var metrics = response.Headers.GetValueOrDefault("x-ms-documentdb-query-metrics")
    .Split(";").Select(s => s.Split("="))
    .ToDictionary(strings => strings[0], strings => strings[1]);
    Log.Information("{RequestUri} {PartitionKey} [{RequestCharge}]\n{@Query}\n{@Metrics:j}",
    request.RequestUri,
    partitionKey,
    response.Headers.RequestCharge,
    deserializeAsync.Query,
    metrics);
    }

    return response;
    }

    // ReSharper disable once UnusedMember.Local
    private async static Task DebugRequestContent(RequestMessage request, CancellationToken cancellationToken)
    {
    request.Content.Position = 0;
    using var requestContentStream = new MemoryStream();
    await request.Content.CopyToAsync(requestContentStream, cancellationToken);
    var requestContent = Encoding.ASCII.GetString(requestContentStream.ToArray());
    Log.Information("Debug, {RequestContent}", requestContent);
    }
    }