Skip to content

Commit

Permalink
Merge branch 'feature/fix_disposed_content_stream' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
Jericho committed Apr 23, 2019
2 parents 9454c7f + e73bafe commit a9ebab5
Showing 1 changed file with 63 additions and 23 deletions.
86 changes: 63 additions & 23 deletions Source/StrongGrid/Utilities/DiagnosticHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ internal class DiagnosticHandler : IHttpFilter
private const string DIAGNOSTIC_ID_HEADER_NAME = "StrongGrid-Diagnostic-Id";
private const string DIAGNOSTIC_TIMESTAMP_HEADER_NAME = "StrongGrid-Diagnostic-Timestamp";
private static readonly ILog _logger = LogProvider.For<DiagnosticHandler>();
private readonly IDictionary<WeakReference<HttpRequestMessage>, (StringBuilder, long)> _diagnostics = new Dictionary<WeakReference<HttpRequestMessage>, (StringBuilder, long)>();

#endregion

Expand All @@ -34,8 +35,20 @@ public void OnRequest(IRequest request)
// Add a unique ID to the request header
request.WithHeader(DIAGNOSTIC_ID_HEADER_NAME, Guid.NewGuid().ToString("N"));

// Add a timestamp to the request header
request.WithHeader(DIAGNOSTIC_TIMESTAMP_HEADER_NAME, Stopwatch.GetTimestamp().ToString());
// Log the request
var httpRequest = request.Message;
var diagnostic = new StringBuilder();

diagnostic.AppendLine("REQUEST:");
diagnostic.AppendLine($" {httpRequest.Method.Method} {httpRequest.RequestUri}");
LogHeaders(diagnostic, httpRequest.Headers);
LogContent(diagnostic, httpRequest.Content);

// Add the diagnotic info to our cache
lock (_diagnostics)
{
_diagnostics.Add(new WeakReference<HttpRequestMessage>(request.Message), (diagnostic, Stopwatch.GetTimestamp()));
}
}

/// <summary>Method invoked just after the HTTP response is received. This method can modify the incoming HTTP response.</summary>
Expand All @@ -44,19 +57,11 @@ public void OnRequest(IRequest request)
public void OnResponse(IResponse response, bool httpErrorAsException)
{
var responseTimestamp = Stopwatch.GetTimestamp();
var diagnostic = new StringBuilder();
var httpResponse = response.Message;
var (diagnostic, requestTimestamp) = GetDiagnosticInfo(response.Message.RequestMessage);

try
{
var httpRequest = response.Message.RequestMessage;
var httpResponse = response.Message;

// Log the request
diagnostic.AppendLine("REQUEST:");
diagnostic.AppendLine($" {httpRequest.Method.Method} {httpRequest.RequestUri}");
LogHeaders(diagnostic, httpRequest.Headers);
LogContent(diagnostic, httpRequest.Content);

// Log the response
diagnostic.AppendLine();
diagnostic.AppendLine("RESPONSE:");
Expand All @@ -65,17 +70,16 @@ public void OnResponse(IResponse response, bool httpErrorAsException)
LogContent(diagnostic, httpResponse.Content);

// Log diagnostic
if (httpRequest.Headers.TryGetValues(DIAGNOSTIC_TIMESTAMP_HEADER_NAME, out IEnumerable<string> timestampHeaderValues))
diagnostic.AppendLine();
diagnostic.AppendLine("DIAGNOSTIC:");
if (requestTimestamp == long.MinValue)
{
var diagnosticTimestamp = timestampHeaderValues.FirstOrDefault();
if (long.TryParse(diagnosticTimestamp, out long requestTimestamp))
{
var elapsed = TimeSpan.FromTicks(responseTimestamp - requestTimestamp);

diagnostic.AppendLine();
diagnostic.AppendLine("DIAGNOSTIC:");
diagnostic.AppendLine($" The request took {elapsed.ToDurationString()}");
}
diagnostic.AppendLine(" Unable to calculate how long the request took");
}
else
{
var elapsed = TimeSpan.FromTicks(responseTimestamp - requestTimestamp);
diagnostic.AppendLine($" The request took {elapsed.ToDurationString()}");
}
}
catch (Exception e)
Expand Down Expand Up @@ -130,7 +134,11 @@ private void LogHeaders(StringBuilder diagnostic, HttpHeaders httpHeaders)

private void LogContent(StringBuilder diagnostic, HttpContent httpContent)
{
if (httpContent != null)
if (httpContent == null)
{
diagnostic.AppendLine(" Content-Length: 0");
}
else
{
LogHeaders(diagnostic, httpContent.Headers);

Expand All @@ -148,6 +156,38 @@ private void LogContent(StringBuilder diagnostic, HttpContent httpContent)
}
}

private (StringBuilder, long) GetDiagnosticInfo(HttpRequestMessage requestMessage)
{
var diagnosticId = requestMessage.Headers.GetValues(DIAGNOSTIC_ID_HEADER_NAME).FirstOrDefault();

foreach (WeakReference<HttpRequestMessage> key in _diagnostics.Keys.ToArray())
{
// Check if garbage collected
if (!key.TryGetTarget(out HttpRequestMessage request))
{
_diagnostics.Remove(key);
continue;
}

// Check if different request
var requestDiagnosticId = request.Headers.GetValues(DIAGNOSTIC_ID_HEADER_NAME).FirstOrDefault();
if (requestDiagnosticId != diagnosticId)
{
continue;
}

// Get the diagnostic info from dictionary
var diagnosticInfo = _diagnostics[key];

// Remove the diagnostic info from dictionary
_diagnostics.Remove(key);

return diagnosticInfo;
}

return (new StringBuilder(), long.MinValue);
}

#endregion
}
}

0 comments on commit a9ebab5

Please sign in to comment.