public sealed class ILoggerHttpPipelinePolicy()

in tools/code/common/Http.cs [301:387]


public sealed class ILoggerHttpPipelinePolicy(ILogger logger) : HttpPipelinePolicy
{
    public override void Process(HttpMessage message, ReadOnlyMemory<HttpPipelinePolicy> pipeline)
    {
        ProcessAsync(message, pipeline).AsTask().GetAwaiter().GetResult();
    }

    public override async ValueTask ProcessAsync(HttpMessage message, ReadOnlyMemory<HttpPipelinePolicy> pipeline)
    {
        if (logger.IsEnabled(LogLevel.Trace))
        {
            logger.LogTrace("""
                            Starting request
                            Method: {HttpMethod}
                            Uri: {Uri}
                            Content: {RequestContent}
                            """, message.Request.Method, message.Request.Uri, await GetRequestContent(message, message.CancellationToken));
        }
        else if (logger.IsEnabled(LogLevel.Debug))
        {
            logger.LogDebug("""
                            Starting request
                            Method: {HttpMethod}
                            Uri: {Uri}
                            """, message.Request.Method, message.Request.Uri);
        }

        var startTime = Stopwatch.GetTimestamp();
        await ProcessNextAsync(message, pipeline);
        var endTime = Stopwatch.GetTimestamp();
        var duration = TimeSpan.FromSeconds((endTime - startTime) / (double)Stopwatch.Frequency);

        if (logger.IsEnabled(LogLevel.Trace))
        {
            logger.LogTrace("""
                            Received response
                            Method: {HttpMethod}
                            Uri: {Uri}
                            Status code: {StatusCode}
                            Duration (hh:mm:ss): {Duration}
                            Content: {ResponseContent}
                            """, message.Request.Method, message.Request.Uri, message.Response.Status, duration.ToString("c"), GetResponseContent(message));
        }
        else if (logger.IsEnabled(LogLevel.Debug))
        {
            logger.LogDebug("""
                            Received response
                            Method: {HttpMethod}
                            Uri: {Uri}
                            Status code: {StatusCode}
                            Duration (hh:mm:ss): {Duration}
                            """, message.Request.Method, message.Request.Uri, message.Response.Status, duration.ToString("c"));
        }
    }

    private static async ValueTask<string> GetRequestContent(HttpMessage message, CancellationToken cancellationToken)
    {
        if (message.Request.Content is null)
        {
            return "<null>";
        }
        else if (HeaderIsJson(message.Request.Headers))
        {
            using var stream = new MemoryStream();
            await message.Request.Content.WriteToAsync(stream, cancellationToken);
            stream.Position = 0;
            var data = await BinaryData.FromStreamAsync(stream, cancellationToken);

            return data.ToString();
        }
        else
        {
            return "<non-json>";
        }
    }

    private static bool HeaderIsJson(IEnumerable<HttpHeader> headers) =>
        headers.Any(header => header.Name.Equals("Content-Type", StringComparison.OrdinalIgnoreCase)
                                && header.Value.Contains("application/json", StringComparison.OrdinalIgnoreCase));

    private static string GetResponseContent(HttpMessage message) =>
        message.Response.Content is null
        ? "<null>"
        : HeaderIsJson(message.Response.Headers)
            ? message.Response.Content.ToString()
            : "<non-json>";
}