Reduce allocations when Activity is enabled (#11020)
- Remove string allocations caused by DiagnosticSource.Stop/StartActivity - Pass the HttpContext directly as the object for StartActivity and StopActivity to avoid the anonymous object allocation. - Though it's a bit ugly, added an HttpContext property to DefaultHttpContext to avoid breaking back-compat (which had to do reflection to get the HttpContext property anyways)
This commit is contained in:
parent
c89055b9b0
commit
d4a982fefa
|
|
@ -16,7 +16,8 @@ namespace Microsoft.AspNetCore.Hosting.Internal
|
|||
private static readonly double TimestampToTicks = TimeSpan.TicksPerSecond / (double)Stopwatch.Frequency;
|
||||
|
||||
private const string ActivityName = "Microsoft.AspNetCore.Hosting.HttpRequestIn";
|
||||
private const string ActivityStartKey = "Microsoft.AspNetCore.Hosting.HttpRequestIn.Start";
|
||||
private const string ActivityStartKey = ActivityName + ".Start";
|
||||
private const string ActivityStopKey = ActivityName + ".Stop";
|
||||
|
||||
private const string DeprecatedDiagnosticsBeginRequestKey = "Microsoft.AspNetCore.Hosting.BeginRequest";
|
||||
private const string DeprecatedDiagnosticsEndRequestKey = "Microsoft.AspNetCore.Hosting.EndRequest";
|
||||
|
|
@ -278,7 +279,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal
|
|||
if (_diagnosticListener.IsEnabled(ActivityStartKey))
|
||||
{
|
||||
hasDiagnosticListener = true;
|
||||
_diagnosticListener.StartActivity(activity, new { HttpContext = httpContext });
|
||||
StartActivity(activity, httpContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -293,12 +294,32 @@ namespace Microsoft.AspNetCore.Hosting.Internal
|
|||
{
|
||||
if (hasDiagnosticListener)
|
||||
{
|
||||
_diagnosticListener.StopActivity(activity, new { HttpContext = httpContext });
|
||||
StopActivity(activity, httpContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
activity.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
// These are versions of DiagnosticSource.Start/StopActivity that don't allocate strings per call (see https://github.com/dotnet/corefx/issues/37055)
|
||||
private Activity StartActivity(Activity activity, HttpContext httpContext)
|
||||
{
|
||||
activity.Start();
|
||||
_diagnosticListener.Write(ActivityStartKey, httpContext);
|
||||
return activity;
|
||||
}
|
||||
|
||||
private void StopActivity(Activity activity, HttpContext httpContext)
|
||||
{
|
||||
// Stop sets the end time if it was unset, but we want it set before we issue the write
|
||||
// so we do it now.
|
||||
if (activity.Duration == TimeSpan.Zero)
|
||||
{
|
||||
activity.SetEndTime(DateTime.UtcNow);
|
||||
}
|
||||
_diagnosticListener.Write(ActivityStopKey, httpContext);
|
||||
activity.Stop(); // Resets Activity.Current (we want this after the Write)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ namespace Microsoft.AspNetCore.Http
|
|||
public override Microsoft.AspNetCore.Http.ConnectionInfo Connection { get { throw null; } }
|
||||
public override Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { get { throw null; } }
|
||||
public Microsoft.AspNetCore.Http.Features.FormOptions FormOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
|
||||
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
public Microsoft.AspNetCore.Http.HttpContext HttpContext { get { throw null; } }
|
||||
public override System.Collections.Generic.IDictionary<object, object> Items { get { throw null; } set { } }
|
||||
public override Microsoft.AspNetCore.Http.HttpRequest Request { get { throw null; } }
|
||||
public override System.Threading.CancellationToken RequestAborted { get { throw null; } set { } }
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Security.Claims;
|
||||
using System.Threading;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
|
|
@ -157,6 +158,12 @@ namespace Microsoft.AspNetCore.Http
|
|||
}
|
||||
}
|
||||
|
||||
// This property exists because of backwards compatibility.
|
||||
// We send an anonymous object with an HttpContext property
|
||||
// via DiagnosticSource in various events throughout the pipeline. Instead
|
||||
// we just send the HttpContext to avoid extra allocations
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public HttpContext HttpContext => this;
|
||||
|
||||
public override void Abort()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue