U4-7813 Enable MiniProfiler to profiler during startup

Conflicts:
	src/Umbraco.Core/Umbraco.Core.csproj
This commit is contained in:
Shannon
2016-01-26 17:56:25 +01:00
parent e461cb92da
commit 72900ef3b3
4 changed files with 155 additions and 9 deletions

View File

@@ -0,0 +1,126 @@
using System.Threading;
using System.Web;
using StackExchange.Profiling;
namespace Umbraco.Core.Profiling
{
/// <summary>
/// Allows us to profile items during app startup - before an HttpRequest is created
/// </summary>
internal class StartupWebProfilerProvider : WebRequestProfilerProvider
{
public StartupWebProfilerProvider()
{
_startupPhase = StartupPhase.Boot;
//create the startup profiler
_startupProfiler = new MiniProfiler("http://localhost/umbraco-startup", ProfileLevel.Verbose)
{
Name = "StartupProfiler"
};
}
private MiniProfiler _startupProfiler;
private readonly ReaderWriterLockSlim _locker = new ReaderWriterLockSlim();
private enum StartupPhase
{
None = 0,
Boot = 1,
Request = 2
}
private volatile StartupPhase _startupPhase;
public void BootComplete()
{
using (new ReadLock(_locker))
{
if (_startupPhase != StartupPhase.Boot) return;
}
using (var l = new UpgradeableReadLock(_locker))
{
if (_startupPhase == StartupPhase.Boot)
{
l.UpgradeToWriteLock();
////Now we need to transfer some information from our startup phase to the normal
////web request phase to output the startup profiled information.
////Stop our internal startup profiler, this will write out it's results to storage.
//StopProfiler(_startupProfiler);
//SaveProfiler(_startupProfiler);
_startupPhase = StartupPhase.Request;
}
}
}
public override void Stop(bool discardResults)
{
using (new ReadLock(_locker))
{
if (_startupPhase == StartupPhase.None)
{
base.Stop(discardResults);
return;
}
}
using (var l = new UpgradeableReadLock(_locker))
{
if (_startupPhase > 0 && base.GetCurrentProfiler() == null)
{
l.UpgradeToWriteLock();
_startupPhase = StartupPhase.None;
if (HttpContext.Current != null)
{
HttpContext.Current.Items[":mini-profiler:"] = _startupProfiler;
base.Stop(discardResults);
_startupProfiler = null;
}
}
else
{
base.Stop(discardResults);
}
}
}
public override MiniProfiler Start(ProfileLevel level)
{
using (new ReadLock(_locker))
{
if (_startupPhase > 0 && base.GetCurrentProfiler() == null)
{
SetProfilerActive(_startupProfiler);
return _startupProfiler;
}
return base.Start(level);
}
}
public override MiniProfiler GetCurrentProfiler()
{
using (new ReadLock(_locker))
{
if (_startupPhase > 0)
{
try
{
var current = base.GetCurrentProfiler();
if (current == null) return _startupProfiler;
}
catch
{
return _startupProfiler;
}
}
return base.GetCurrentProfiler();
}
}
}
}

View File

@@ -12,15 +12,24 @@ namespace Umbraco.Core.Profiling
/// </summary>
internal class WebProfiler : IProfiler
{
private StartupWebProfilerProvider _startupWebProfilerProvider;
/// <summary>
/// Constructor
/// </summary>
/// <remarks>
/// Binds to application events to enable the MiniProfiler
/// </remarks>
/// </summary>
internal WebProfiler()
{
//setup some defaults
MiniProfiler.Settings.SqlFormatter = new SqlServerFormatter();
MiniProfiler.Settings.StackMaxLength = 5000;
//At this point we know that we've been constructed during app startup, there won't be an HttpRequest in the HttpContext
// since it hasn't started yet. So we need to do some hacking to enable profiling during startup.
_startupWebProfilerProvider = new StartupWebProfilerProvider();
//this should always be the case during startup, we'll need to set a custom profiler provider
MiniProfiler.Settings.ProfilerProvider = _startupWebProfilerProvider;
//Binds to application events to enable the MiniProfiler with a real HttpRequest
UmbracoApplicationBase.ApplicationInit += UmbracoApplicationApplicationInit;
}
@@ -53,7 +62,12 @@ namespace Umbraco.Core.Profiling
/// <param name="e"></param>
void UmbracoApplicationEndRequest(object sender, EventArgs e)
{
if (CanPerformProfilingAction(sender))
if (_startupWebProfilerProvider != null)
{
Stop();
_startupWebProfilerProvider = null;
}
else if (CanPerformProfilingAction(sender))
{
Stop();
}
@@ -66,6 +80,11 @@ namespace Umbraco.Core.Profiling
/// <param name="e"></param>
void UmbracoApplicationBeginRequest(object sender, EventArgs e)
{
if (_startupWebProfilerProvider != null)
{
_startupWebProfilerProvider.BootComplete();
}
if (CanPerformProfilingAction(sender))
{
Start();
@@ -124,9 +143,7 @@ namespace Umbraco.Core.Profiling
/// Start the profiler
/// </summary>
public void Start()
{
MiniProfiler.Settings.SqlFormatter = new SqlServerFormatter();
MiniProfiler.Settings.StackMaxLength = 5000;
{
MiniProfiler.Start();
}