Resvolution - Loggers & Booting

This commit is contained in:
Stephan
2016-08-25 10:23:41 +02:00
parent 3707db6c21
commit 9949f07a46
29 changed files with 260 additions and 390 deletions

View File

@@ -40,22 +40,16 @@ namespace Umbraco.Core
protected PluginManager PluginManager { get; private set; }
private IServiceContainer _appStartupEvtContainer;
private bool _isInitialized = false;
private bool _isStarted = false;
private bool _isComplete = false;
private bool _isInitialized;
private bool _isStarted;
private bool _isComplete;
private readonly UmbracoApplicationBase _umbracoApplication;
protected ApplicationContext ApplicationContext { get; private set; }
protected CacheHelper ApplicationCache { get; private set; }
protected UmbracoApplicationBase UmbracoApplication
{
get { return _umbracoApplication; }
}
protected UmbracoApplicationBase UmbracoApplication => _umbracoApplication;
protected ServiceContainer Container
{
get { return _umbracoApplication.Container; }
}
protected ServiceContainer Container => Current.Container; // fixme kill
protected IServiceProvider ServiceProvider { get; private set; }
@@ -78,13 +72,16 @@ namespace Umbraco.Core
if (_isInitialized)
throw new InvalidOperationException("The boot manager has already been initialized");
// the logger has been created by UmbracoApplicationBase
// fixme why not the profiling logger etc?! OR have them all created by the boot manager?
//Create logger/profiler, and their resolvers, these are special resolvers that can be resolved before frozen so we can start logging
LoggerResolver.Current = new LoggerResolver(_umbracoApplication.Logger) { CanResolveBeforeFrozen = true };
var profiler = CreateProfiler();
ProfilerResolver.Current = new ProfilerResolver(profiler) { CanResolveBeforeFrozen = true };
ProfilingLogger = new ProfilingLogger(_umbracoApplication.Logger, profiler);
var logger = Current.Logger;
ProfilingLogger = ProfilingLogger?? new ProfilingLogger(LoggerResolver.Current.Logger, ProfilerResolver.Current.Profiler);
var profiler = CreateProfiler();
Container.RegisterInstance(profiler); // fixme - re-registered?!
//ProfilerResolver.Current = new ProfilerResolver(profiler) { CanResolveBeforeFrozen = true };
ProfilingLogger = new ProfilingLogger(logger, profiler);
ApplicationCache = CreateApplicationCache();
@@ -154,7 +151,6 @@ namespace Umbraco.Core
internal virtual void ConfigureCoreServices(ServiceContainer container)
{
//Logging
container.RegisterInstance(_umbracoApplication.Logger);
container.RegisterInstance(ProfilingLogger.Profiler);
container.RegisterInstance(ProfilingLogger);

View File

@@ -2,8 +2,8 @@
using LightInject;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Dictionary;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Strings;
@@ -40,7 +40,11 @@ namespace Umbraco.Core.DependencyInjection
internal static void Reset()
{
_container = null;
_shortStringHelper = null;
_logger = null;
_profiler = null;
Resetted?.Invoke(null, EventArgs.Empty);
}
@@ -81,25 +85,28 @@ namespace Umbraco.Core.DependencyInjection
public static ICultureDictionaryFactory CultureDictionaryFactory
=> Container.GetInstance<ICultureDictionaryFactory>();
// fixme - refactor
// we don't want Umbraco to die because the container has not been properly initialized,
// for some too-important things such as IShortStringHelper or loggers, so if it's not
// registered we setup a default one. We should really refactor our tests so that it does
// not happen, but hey...
private static IShortStringHelper _shortStringHelper;
public static IShortStringHelper ShortStringHelper
{
get
{
// fixme - refactor
// we don't want Umbraco to die because the resolver hasn't been initialized
// as the ShortStringHelper is too important, so as long as it's not there
// already, we use a default one. That should never happen, but... in can, in
// some tests - we should really cleanup our tests and get rid of this!
=> _shortStringHelper ?? (_shortStringHelper = _container?.TryGetInstance<IShortStringHelper>()
?? new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(UmbracoConfig.For.UmbracoSettings())));
if (_shortStringHelper != null) return _shortStringHelper;
var reg = HasContainer ? Container.GetAvailableService<IShortStringHelper>() : null;
return _shortStringHelper = reg == null
? new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(UmbracoConfig.For.UmbracoSettings()))
: Container.GetInstance<IShortStringHelper>();
}
}
private static ILogger _logger;
private static IProfiler _profiler;
public static ILogger Logger
=> _logger ?? (_logger = _container?.TryGetInstance<ILogger>()
?? new DebugDiagnosticsLogger());
public static IProfiler Profiler
=> _profiler ?? (_profiler = _container?.TryGetInstance<IProfiler>()
?? new LogProfiler(Logger));
#endregion
}

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Web;
using Umbraco.Core.DependencyInjection;
using Umbraco.Core.Logging;
namespace Umbraco.Core
@@ -113,9 +114,9 @@ namespace Umbraco.Core
public static DisposableTimer TraceDuration(Type loggerType, Func<string> startMessage, Func<string> completeMessage)
{
return new DisposableTimer(
LoggerResolver.Current.Logger,
Current.Logger,
LogType.Info,
ProfilerResolver.HasCurrent ? ProfilerResolver.Current.Profiler : null,
Current.Profiler,
loggerType,
startMessage(),
completeMessage());
@@ -157,9 +158,9 @@ namespace Umbraco.Core
public static DisposableTimer TraceDuration(Type loggerType, string startMessage, string completeMessage)
{
return new DisposableTimer(
LoggerResolver.Current.Logger,
Current.Logger,
LogType.Info,
ProfilerResolver.HasCurrent ? ProfilerResolver.Current.Profiler : null,
Current.Profiler,
loggerType,
startMessage,
completeMessage);
@@ -212,9 +213,9 @@ namespace Umbraco.Core
public static DisposableTimer DebugDuration(Type loggerType, string startMessage, string completeMessage)
{
return new DisposableTimer(
LoggerResolver.Current.Logger,
Current.Logger,
LogType.Debug,
ProfilerResolver.HasCurrent ? ProfilerResolver.Current.Profiler : null,
Current.Profiler,
loggerType,
startMessage,
completeMessage);
@@ -225,9 +226,9 @@ namespace Umbraco.Core
public static DisposableTimer DebugDuration(Type loggerType, Func<string> startMessage, Func<string> completeMessage)
{
return new DisposableTimer(
LoggerResolver.Current.Logger,
Current.Logger,
LogType.Debug,
ProfilerResolver.HasCurrent ? ProfilerResolver.Current.Profiler : null,
Current.Profiler,
loggerType,
startMessage(),
completeMessage());

View File

@@ -3,6 +3,7 @@ using System.Linq;
using System.Threading;
using System.Web;
using log4net;
using Umbraco.Core.DependencyInjection;
namespace Umbraco.Core.Logging
{
@@ -23,14 +24,12 @@ namespace Umbraco.Core.Logging
/// <param name="exception"></param>
public static void Error<T>(string message, Exception exception)
{
if (LoggerResolver.HasCurrent == false || LoggerResolver.Current.HasValue == false) return;
LoggerResolver.Current.Logger.Error<T>(message, exception);
Current.Logger.Error<T>(message, exception);
}
public static void Error(Type callingType, string message, Exception exception)
{
if (LoggerResolver.HasCurrent == false || LoggerResolver.Current.HasValue == false) return;
LoggerResolver.Current.Logger.Error(callingType, message, exception);
Current.Logger.Error(callingType, message, exception);
}
#endregion
@@ -39,8 +38,7 @@ namespace Umbraco.Core.Logging
public static void Warn(Type callingType, string message, params Func<object>[] formatItems)
{
if (LoggerResolver.HasCurrent == false || LoggerResolver.Current.HasValue == false) return;
LoggerResolver.Current.Logger.Warn(callingType, message, formatItems);
Current.Logger.Warn(callingType, message, formatItems);
}
[Obsolete("Warnings with http trace should not be used. This method will be removed in future versions")]
@@ -54,8 +52,7 @@ namespace Umbraco.Core.Logging
HttpContext.Current.Trace.Warn(callingType.Name, string.Format(message, formatItems.Select(x => x.Invoke()).ToArray()));
}
if (LoggerResolver.HasCurrent == false || LoggerResolver.Current.HasValue == false) return;
LoggerResolver.Current.Logger.Warn(callingType, message, formatItems);
Current.Logger.Warn(callingType, message, formatItems);
}
@@ -79,8 +76,7 @@ namespace Umbraco.Core.Logging
e);
}
if (LoggerResolver.HasCurrent == false || LoggerResolver.Current.HasValue == false) return;
LoggerResolver.Current.Logger.WarnWithException(callingType, message, e, formatItems);
Current.Logger.WarnWithException(callingType, message, e, formatItems);
}
/// <summary>
@@ -132,8 +128,7 @@ namespace Umbraco.Core.Logging
/// <param name="generateMessage"></param>
public static void Info(Type callingType, Func<string> generateMessage)
{
if (LoggerResolver.HasCurrent == false || LoggerResolver.Current.HasValue == false) return;
LoggerResolver.Current.Logger.Info(callingType, generateMessage);
Current.Logger.Info(callingType, generateMessage);
}
/// <summary>
@@ -144,8 +139,7 @@ namespace Umbraco.Core.Logging
/// <param name="formatItems">The format items.</param>
public static void Info(Type type, string generateMessageFormat, params Func<object>[] formatItems)
{
if (LoggerResolver.HasCurrent == false || LoggerResolver.Current.HasValue == false) return;
LoggerResolver.Current.Logger.Info(type, generateMessageFormat, formatItems);
Current.Logger.Info(type, generateMessageFormat, formatItems);
}
/// <summary>
@@ -159,9 +153,11 @@ namespace Umbraco.Core.Logging
{
Info(typeof(T), generateMessageFormat, formatItems);
}
#endregion
#region Debug
/// <summary>
/// Debugs a message, only generating the message if tracing is actually enabled. Use this method to avoid calling any long-running methods such as "ToDebugString" if logging is disabled.
/// </summary>
@@ -180,8 +176,7 @@ namespace Umbraco.Core.Logging
/// <param name="generateMessage"></param>
public static void Debug(Type callingType, Func<string> generateMessage)
{
if (LoggerResolver.HasCurrent == false || LoggerResolver.Current.HasValue == false) return;
LoggerResolver.Current.Logger.Debug(callingType, generateMessage);
Current.Logger.Debug(callingType, generateMessage);
}
/// <summary>
@@ -192,8 +187,7 @@ namespace Umbraco.Core.Logging
/// <param name="formatItems">The format items.</param>
public static void Debug(Type type, string generateMessageFormat, params Func<object>[] formatItems)
{
if (LoggerResolver.HasCurrent == false || LoggerResolver.Current.HasValue == false) return;
LoggerResolver.Current.Logger.Debug(type, generateMessageFormat, formatItems);
Current.Logger.Debug(type, generateMessageFormat, formatItems);
}
/// <summary>
@@ -229,6 +223,5 @@ namespace Umbraco.Core.Logging
}
#endregion
}
}

View File

@@ -1,28 +0,0 @@
using Umbraco.Core.ObjectResolution;
namespace Umbraco.Core.Logging
{
/// <summary>
/// The logger resolver
/// </summary>
/// <remarks>
/// NOTE: This is a 'special' resolver in that it gets initialized before most other things, it cannot use IoC so it cannot implement ContainerObjectResolverBase
/// </remarks>
public sealed class LoggerResolver : SingleObjectResolverBase<LoggerResolver, ILogger>
{
public LoggerResolver(ILogger logger)
: base(logger)
{
}
/// <summary>
/// Gets the current logger
/// </summary>
public ILogger Logger
{
get { return Value; }
}
}
}

View File

@@ -1,9 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Owin.Logging;
using Umbraco.Core.DependencyInjection;
namespace Umbraco.Core.Logging
{
@@ -16,9 +13,7 @@ namespace Umbraco.Core.Logging
/// <returns/>
public Microsoft.Owin.Logging.ILogger Create(string name)
{
return new OwinLogger(
LoggerResolver.HasCurrent ? LoggerResolver.Current.Logger : new DebugDiagnosticsLogger(),
new Lazy<Type>(() => Type.GetType(name) ?? typeof (OwinLogger)));
return new OwinLogger(Current.Logger, new Lazy<Type>(() => Type.GetType(name) ?? typeof (OwinLogger)));
}
}
}

View File

@@ -1,42 +0,0 @@
using Umbraco.Core.ObjectResolution;
namespace Umbraco.Core.Logging
{
/// <summary>
/// A resolver exposing the current profiler
/// </summary>
/// <remarks>
/// NOTE: This is a 'special' resolver in that it gets initialized before most other things, it cannot use IoC so it cannot implement ContainerObjectResolverBase
/// </remarks>
internal class ProfilerResolver : SingleObjectResolverBase<ProfilerResolver, IProfiler>
{
/// <summary>
/// Constructor
/// </summary>
/// <param name="profiler"></param>
public ProfilerResolver(IProfiler profiler)
: base(profiler)
{
}
/// <summary>
/// Method allowing to change the profiler during startup
/// </summary>
/// <param name="profiler"></param>
internal void SetProfiler(IProfiler profiler)
{
Value = profiler;
}
/// <summary>
/// Gets the current profiler
/// </summary>
public IProfiler Profiler
{
get { return Value; }
}
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using Umbraco.Core.Logging;
@@ -8,64 +9,62 @@ namespace Umbraco.Core.Manifest
{
internal class ManifestWatcher : DisposableObject
{
private static readonly object Locker = new object();
private static volatile bool _isRestarting;
private readonly ILogger _logger;
private readonly List<FileSystemWatcher> _fws = new List<FileSystemWatcher>();
private static volatile bool _isRestarting = false;
private static readonly object Locker = new object();
public ManifestWatcher(ILogger logger)
{
if (logger == null) throw new ArgumentNullException("logger");
if (logger == null) throw new ArgumentNullException(nameof(logger));
_logger = logger;
}
public void Start(params string[] packageFolders)
{
foreach (var packageFolder in packageFolders)
foreach (var packageFolder in packageFolders.Where(IsWatchable))
{
if (Directory.Exists(packageFolder) && File.Exists(Path.Combine(packageFolder, "package.manifest")))
{
//NOTE: for some reason *.manifest doesn't work!
// for some reason *.manifest doesn't work
var fsw = new FileSystemWatcher(packageFolder, "*package.*")
{
IncludeSubdirectories = false,
NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
};
_fws.Add(fsw);
fsw.Changed += FswChanged;
fsw.EnableRaisingEvents = true;
}
}
private static bool IsWatchable(string folder)
{
return Directory.Exists(folder) && File.Exists(Path.Combine(folder, "package.manifest"));
}
void FswChanged(object sender, FileSystemEventArgs e)
{
if (e.Name.InvariantContains("package.manifest"))
{
//Ensure the app is not restarted multiple times for multiple saving during the same app domain execution
if (_isRestarting == false)
private void FswChanged(object sender, FileSystemEventArgs e)
{
if (e.Name.InvariantContains("package.manifest") == false) return;
// ensure the app is not restarted multiple times for multiple
// savings during the same app domain execution - restart once
lock (Locker)
{
if (_isRestarting == false)
{
_isRestarting = true;
if (_isRestarting) return;
_isRestarting = true;
_logger.Info<ManifestWatcher>("manifest has changed, app pool is restarting (" + e.FullPath + ")");
HttpRuntime.UnloadAppDomain();
Dispose();
}
}
}
Dispose(); // uh? if the app restarts then this should be disposed anyways?
}
}
protected override void DisposeResources()
{
foreach (var fw in _fws)
{
fw.Dispose();
}
}
}
}

View File

@@ -110,15 +110,14 @@ namespace Umbraco.Core.Plugins
return LazyInitializer.EnsureInitialized(ref _instance, ref _hasInstance, ref _instanceLocker, () =>
{
var appctx = ApplicationContext.Current;
var cacheProvider = appctx == null
var cacheProvider = appctx == null // fixme - should Current have an ApplicationCache?
? new NullCacheProvider()
: appctx.ApplicationCache.RuntimeCache;
ProfilingLogger profilingLogger;
if (appctx == null)
{
var logger = LoggerResolver.HasCurrent ? LoggerResolver.Current.Logger : new DebugDiagnosticsLogger();
var profiler = ProfilerResolver.HasCurrent ? ProfilerResolver.Current.Profiler : new LogProfiler(logger);
profilingLogger = new ProfilingLogger(logger, profiler);
// fixme - should Current have a ProfilingLogger?
profilingLogger = new ProfilingLogger(DependencyInjection.Current.Logger, DependencyInjection.Current.Profiler);
}
else
{

View File

@@ -489,7 +489,6 @@
<Compile Include="Logging\DebugDiagnosticsLogger.cs" />
<Compile Include="Logging\AppDomainTokenConverter.cs" />
<Compile Include="Logging\LoggerExtensions.cs" />
<Compile Include="Logging\LoggerResolver.cs" />
<Compile Include="Logging\ProfilingLogger.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenThreeZero\CreateCacheInstructionTable.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenThreeZero\MigrateStylesheetDataToFile.cs" />
@@ -1032,7 +1031,6 @@
<Compile Include="Logging\IProfiler.cs" />
<Compile Include="Logging\LogProfiler.cs" />
<Compile Include="Logging\ProfilerExtensions.cs" />
<Compile Include="Logging\ProfilerResolver.cs" />
<Compile Include="Logging\WebProfiler.cs" />
<Compile Include="PropertyEditors\DelimitedManifestValueValidator.cs" />
<Compile Include="PropertyEditors\IntegerValidator.cs" />

View File

@@ -20,28 +20,57 @@ namespace Umbraco.Core
/// </remarks>
public abstract class UmbracoApplicationBase : HttpApplication
{
/// <summary>
/// Gets a boot manager.
/// </summary>
protected abstract IBootManager GetBootManager();
/// <summary>
/// Umbraco application's IoC container
/// Gets a logger.
/// </summary>
internal ServiceContainer Container { get; private set; }
private ILogger _logger;
/// <summary>
/// Constructor
/// </summary>
protected UmbracoApplicationBase()
protected virtual ILogger GetLogger()
{
// beware! this code can run more that once
// so it is NOT the right place to initialize global stuff such as the container
//
// however, it is OK to initialize app-local stuff
if (Current.HasContainer)
Container = Current.Container;
return Logger.CreateWithDefaultLog4NetConfiguration();
}
/// <summary>
/// Boots up the Umbraco application.
/// </summary>
internal void StartApplication(object sender, EventArgs e)
{
// create the container for the application, and configure.
// the boot manager is responsible for registrations
var container = new ServiceContainer();
container.ConfigureUmbracoCore(); // also sets Current.Container
// register the essential stuff,
// ie the global application logger
// (profiler etc depend on boot manager)
var logger = GetLogger();
container.RegisterInstance(logger);
// take care of unhandled exceptions - there is nothing we can do to
// prevent the entire w3wp process to go down but at least we can try
// and log the exception
AppDomain.CurrentDomain.UnhandledException += (_, args) =>
{
var exception = (Exception)args.ExceptionObject;
var isTerminating = args.IsTerminating; // always true?
var msg = "Unhandled exception in AppDomain";
if (isTerminating) msg += " (terminating)";
logger.Error<UmbracoApplicationBase>(msg, exception);
};
// boot
GetBootManager()
.Initialize()
.Startup(appContext => OnApplicationStarting(sender, e))
.Complete(appContext => OnApplicationStarted(sender, e));
}
#region Events
public event EventHandler ApplicationStarting;
public event EventHandler ApplicationStarted;
@@ -49,43 +78,13 @@ namespace Umbraco.Core
/// Called when the HttpApplication.Init() is fired, allows developers to subscribe to the HttpApplication events
/// </summary>
/// <remarks>
/// Needs to be static otherwise null refs occur - though I don't know why
/// Needs to be static otherwise null refs occur - though I don't know why FIXME wtf?
/// </remarks>
public static event EventHandler ApplicationInit;
public static event EventHandler ApplicationError;
public static event EventHandler ApplicationEnd;
/// <summary>
/// Boots up the Umbraco application
/// </summary>
internal void StartApplication(object sender, EventArgs e)
{
// create the container for the application, and configure.
// the boot managers are responsible for registrations
Container = new ServiceContainer();
Container.ConfigureUmbracoCore();
//take care of unhandled exceptions - there is nothing we can do to
// prevent the entire w3wp process to go down but at least we can try
// and log the exception
AppDomain.CurrentDomain.UnhandledException += (_, args) =>
{
var exception = (Exception) args.ExceptionObject;
var isTerminating = args.IsTerminating; // always true?
var msg = "Unhandled exception in AppDomain";
if (isTerminating) msg += " (terminating)";
LogHelper.Error<UmbracoApplicationBase>(msg, exception);
};
//boot up the application
GetBootManager()
.Initialize()
.Startup(appContext => OnApplicationStarting(sender, e))
.Complete(appContext => OnApplicationStarted(sender, e));
}
/// <summary>
/// Initializes the Umbraco application
/// </summary>
@@ -117,12 +116,10 @@ namespace Umbraco.Core
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void OnApplicationStarting(object sender, EventArgs e)
{
if (ApplicationStarting != null)
{
try
{
ApplicationStarting(sender, e);
ApplicationStarting?.Invoke(sender, e);
}
catch (Exception ex)
{
@@ -131,20 +128,16 @@ namespace Umbraco.Core
}
}
}
/// <summary>
/// Developers can override this method to do anything they need to do once the application startup routine is completed.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void OnApplicationStarted(object sender, EventArgs e)
{
if (ApplicationStarted != null)
{
try
{
ApplicationStarted(sender, e);
ApplicationStarted?.Invoke(sender, e);
}
catch (Exception ex)
{
@@ -152,7 +145,6 @@ namespace Umbraco.Core
throw;
}
}
}
/// <summary>
/// Called to raise the ApplicationInit event
@@ -160,12 +152,10 @@ namespace Umbraco.Core
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnApplicationInit(object sender, EventArgs e)
{
if (ApplicationInit != null)
{
try
{
ApplicationInit(sender, e);
ApplicationInit?.Invoke(sender, e);
}
catch (Exception ex)
{
@@ -173,7 +163,6 @@ namespace Umbraco.Core
throw;
}
}
}
/// <summary>
/// A method that can be overridden to invoke code when the application has an error.
@@ -182,8 +171,7 @@ namespace Umbraco.Core
/// <param name="e"></param>
protected virtual void OnApplicationError(object sender, EventArgs e)
{
var handler = ApplicationError;
if (handler != null) handler(this, EventArgs.Empty);
ApplicationError?.Invoke(this, EventArgs.Empty);
}
protected void Application_Error(object sender, EventArgs e)
@@ -199,7 +187,7 @@ namespace Umbraco.Core
return;
}
Logger.Error<UmbracoApplicationBase>("An unhandled exception occurred", exc);
Current.Logger.Error<UmbracoApplicationBase>("An unhandled exception occurred", exc);
OnApplicationError(sender, e);
}
@@ -211,8 +199,7 @@ namespace Umbraco.Core
/// <param name="e"></param>
protected virtual void OnApplicationEnd(object sender, EventArgs e)
{
var handler = ApplicationEnd;
if (handler != null) handler(this, EventArgs.Empty);
ApplicationEnd?.Invoke(this, EventArgs.Empty);
}
protected void Application_End(object sender, EventArgs e)
@@ -248,34 +235,22 @@ namespace Umbraco.Core
runtime,
null);
var shutdownMsg = string.Format("{0}\r\n\r\n_shutDownMessage={1}\r\n\r\n_shutDownStack={2}",
HostingEnvironment.ShutdownReason,
shutDownMessage,
shutDownStack);
var shutdownMsg = $"{HostingEnvironment.ShutdownReason}\r\n\r\n_shutDownMessage={shutDownMessage}\r\n\r\n_shutDownStack={shutDownStack}";
Logger.Info<UmbracoApplicationBase>("Application shutdown. Details: " + shutdownMsg);
Current.Logger.Info<UmbracoApplicationBase>("Application shutdown. Details: " + shutdownMsg);
}
catch (Exception)
{
//if for some reason that fails, then log the normal output
Logger.Info<UmbracoApplicationBase>("Application shutdown. Reason: " + HostingEnvironment.ShutdownReason);
Current.Logger.Info<UmbracoApplicationBase>("Application shutdown. Reason: " + HostingEnvironment.ShutdownReason);
}
}
OnApplicationEnd(sender, e);
//Last thing to do is shutdown log4net
// last thing to do is shutdown log4net
LogManager.Shutdown();
}
protected abstract IBootManager GetBootManager();
/// <summary>
/// Returns the logger instance for the application - this will be used throughout the entire app
/// </summary>
public virtual ILogger Logger
{
get { return _logger ?? (_logger = Logging.Logger.CreateWithDefaultLog4NetConfiguration()); }
}
#endregion
}
}

View File

@@ -29,8 +29,10 @@ namespace Umbraco.Tests.BootManagers
public override void TearDown()
{
base.TearDown();
ResolverCollection.ResetAll();
TestApplicationEventHandler.Reset();
Resolution.Reset();
Current.Reset();
}
@@ -41,19 +43,16 @@ namespace Umbraco.Tests.BootManagers
/// </summary>
public class TestApp : UmbracoApplicationBase
{
private readonly ILogger _logger = Mock.Of<ILogger>();
protected override IBootManager GetBootManager()
{
return new TestBootManager(this, new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>()));
return new TestBootManager(this, new ProfilingLogger(_logger, Mock.Of<IProfiler>()));
}
private ILogger _logger;
/// <summary>
/// Returns the logger instance for the application - this will be used throughout the entire app
/// </summary>
public override ILogger Logger
protected override ILogger GetLogger()
{
get { return _logger ?? (_logger = Mock.Of<ILogger>()); }
return _logger;
}
}
@@ -64,12 +63,12 @@ namespace Umbraco.Tests.BootManagers
{
public TestBootManager(UmbracoApplicationBase umbracoApplication, ProfilingLogger logger)
: base(umbracoApplication, logger)
{
}
{ }
internal override void ConfigureCoreServices(ServiceContainer container)
{
base.ConfigureCoreServices(container);
container.Register<IUmbracoSettingsSection>(factory => SettingsForTests.GetDefault());
container.Register<DatabaseContext>(factory => new DatabaseContext(
factory.GetInstance<IDatabaseFactory>(),

View File

@@ -23,6 +23,7 @@ using Umbraco.Web;
using Umbraco.Web.PublishedCache;
using Umbraco.Web.Routing;
using Umbraco.Web.Security;
using Current = Umbraco.Web.Current;
namespace Umbraco.Tests
{
@@ -32,13 +33,13 @@ namespace Umbraco.Tests
[SetUp]
public void Setup()
{
Umbraco.Web.Current.UmbracoContextAccessor = new TestUmbracoContextAccessor();
Current.UmbracoContextAccessor = new TestUmbracoContextAccessor();
}
[TearDown]
public void TearDown()
{
Umbraco.Web.Current.UmbracoContextAccessor = null;
Current.Reset();
}
[Test]

View File

@@ -10,12 +10,10 @@ using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.UnitOfWork;
using Umbraco.Core.Profiling;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
using Current = Umbraco.Web.Current;
namespace Umbraco.Tests.Services
{
@@ -32,11 +30,16 @@ namespace Umbraco.Tests.Services
protected override void FreezeResolution()
{
ProfilerResolver.Current = new ProfilerResolver(new TestProfiler());
Container.Register<IProfiler, TestProfiler>();
base.FreezeResolution();
}
[Test]
public void Profiler()
{
Assert.IsInstanceOf<TestProfiler>(Current.Profiler);
}
[Test]
public void Retrieving_All_Content_In_Site()
{

View File

@@ -272,18 +272,6 @@ namespace Umbraco.Tests.TestHelpers
var cache = new NullCacheProvider();
var enableRepositoryEvents = behavior != null && behavior.EnableRepositoryEvents;
if (enableRepositoryEvents && LoggerResolver.HasCurrent == false)
{
// XmlStore wants one if handling events
LoggerResolver.Current = new LoggerResolver(Mock.Of<ILogger>())
{
CanResolveBeforeFrozen = true
};
ProfilerResolver.Current = new ProfilerResolver(new LogProfiler(Mock.Of<ILogger>()))
{
CanResolveBeforeFrozen = true
};
}
ContentTypesCache = new PublishedContentTypeCache(
ApplicationContext.Services.ContentTypeService,

View File

@@ -1,4 +1,6 @@
using NUnit.Framework;
using Umbraco.Core.DependencyInjection;
using Current = Umbraco.Web.Current;
namespace Umbraco.Tests.TestHelpers
{
@@ -14,14 +16,14 @@ namespace Umbraco.Tests.TestHelpers
public virtual void Initialize()
{
SettingsForTests.Reset();
Umbraco.Web.Current.UmbracoContextAccessor = new TestUmbracoContextAccessor();
Current.UmbracoContextAccessor = new TestUmbracoContextAccessor();
}
[TearDown]
public virtual void TearDown()
{
SettingsForTests.Reset();
Umbraco.Web.Current.UmbracoContextAccessor = null;
Current.Reset();
}
}
}

View File

@@ -27,13 +27,13 @@ namespace Umbraco.Tests.Web.Mvc
[SetUp]
public void SetUp()
{
Umbraco.Web.Current.UmbracoContextAccessor = new TestUmbracoContextAccessor();
Current.UmbracoContextAccessor = new TestUmbracoContextAccessor();
}
[TearDown]
public void TearDown()
{
Umbraco.Web.Current.UmbracoContextAccessor = null;
Current.Reset();
}
private MethodInfo GetRenderMvcControllerIndexMethodFromCurrentType(Type currType)

View File

@@ -9,6 +9,7 @@ using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Web.Models;
using Umbraco.Web.Mvc;
using Current = Umbraco.Web.Current;
namespace Umbraco.Tests.Web.Mvc
{
@@ -18,13 +19,13 @@ namespace Umbraco.Tests.Web.Mvc
[SetUp]
public void SetUp()
{
Umbraco.Web.Current.UmbracoContextAccessor = new TestUmbracoContextAccessor();
Current.UmbracoContextAccessor = new TestUmbracoContextAccessor();
}
[TearDown]
public void TearDown()
{
Umbraco.Web.Current.UmbracoContextAccessor = null;
Current.Reset();
}
[Test]

View File

@@ -23,6 +23,7 @@ using Umbraco.Web.Mvc;
using Umbraco.Web.PublishedCache;
using Umbraco.Web.Routing;
using Umbraco.Web.Security;
using Current = Umbraco.Web.Current;
namespace Umbraco.Tests.Web.Mvc
{
@@ -32,13 +33,13 @@ namespace Umbraco.Tests.Web.Mvc
[SetUp]
public void SetUp()
{
Umbraco.Web.Current.UmbracoContextAccessor = new TestUmbracoContextAccessor();
Current.UmbracoContextAccessor = new TestUmbracoContextAccessor();
}
[TearDown]
public void TearDown()
{
Umbraco.Web.Current.UmbracoContextAccessor = null;
Current.Reset();
}
[Test]

View File

@@ -19,6 +19,7 @@ using Umbraco.Web.Mvc;
using Umbraco.Web.PublishedCache;
using Umbraco.Web.Routing;
using Umbraco.Web.Security;
using Current = Umbraco.Web.Current;
namespace Umbraco.Tests.Web
{
@@ -28,7 +29,7 @@ namespace Umbraco.Tests.Web
[TearDown]
public void TearDown()
{
Umbraco.Web.Current.UmbracoContextAccessor = null;
Current.Reset();
}
[Test]

View File

@@ -4,6 +4,7 @@ using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Dictionary;
using Umbraco.Core.Events;
using Umbraco.Core.Logging;
using Umbraco.Core.Macros;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Persistence.Migrations;
@@ -65,7 +66,7 @@ namespace Umbraco.Web
get
{
if (_facadeAccessor != null) return _facadeAccessor;
return (_facadeAccessor = Container.GetInstance<IFacadeAccessor>());
return _facadeAccessor = Container.GetInstance<IFacadeAccessor>();
}
set { _facadeAccessor = value; } // for tests
}
@@ -89,7 +90,7 @@ namespace Umbraco.Web
get
{
if (_umbracoContextAccessor != null) return _umbracoContextAccessor;
return (_umbracoContextAccessor = Container.GetInstance<IUmbracoContextAccessor>());
return _umbracoContextAccessor = Container.GetInstance<IUmbracoContextAccessor>();
}
set { _umbracoContextAccessor = value; } // for tests
}
@@ -199,41 +200,33 @@ namespace Umbraco.Web
// proxy Core for convenience
public static UrlSegmentProviderCollection UrlSegmentProviders
=> Container.GetInstance<UrlSegmentProviderCollection>();
public static UrlSegmentProviderCollection UrlSegmentProviders => CoreCurrent.UrlSegmentProviders;
public static CacheRefresherCollection CacheRefreshers
=> Container.GetInstance<CacheRefresherCollection>();
public static CacheRefresherCollection CacheRefreshers => CoreCurrent.CacheRefreshers;
public static PropertyEditorCollection PropertyEditors
=> Container.GetInstance<PropertyEditorCollection>();
public static PropertyEditorCollection PropertyEditors => CoreCurrent.PropertyEditors;
public static ParameterEditorCollection ParameterEditors
=> Container.GetInstance<ParameterEditorCollection>();
public static ParameterEditorCollection ParameterEditors => CoreCurrent.ParameterEditors;
internal static ValidatorCollection Validators
=> Container.GetInstance<ValidatorCollection>();
internal static ValidatorCollection Validators => CoreCurrent.Validators;
internal static PackageActionCollection PackageActions
=> Container.GetInstance<PackageActionCollection>();
internal static PackageActionCollection PackageActions => CoreCurrent.PackageActions;
internal static PropertyValueConverterCollection PropertyValueConverters
=> Container.GetInstance<PropertyValueConverterCollection>();
internal static PropertyValueConverterCollection PropertyValueConverters => CoreCurrent.PropertyValueConverters;
internal static IPublishedContentModelFactory PublishedContentModelFactory
=> Container.GetInstance<IPublishedContentModelFactory>();
internal static IPublishedContentModelFactory PublishedContentModelFactory => CoreCurrent.PublishedContentModelFactory;
public static IServerMessenger ServerMessenger
=> Container.GetInstance<IServerMessenger>();
public static IServerMessenger ServerMessenger => CoreCurrent.ServerMessenger;
public static IServerRegistrar ServerRegistrar
=> Container.GetInstance<IServerRegistrar>();
public static IServerRegistrar ServerRegistrar => CoreCurrent.ServerRegistrar;
public static ICultureDictionaryFactory CultureDictionaryFactory
=> Container.GetInstance<ICultureDictionaryFactory>();
public static ICultureDictionaryFactory CultureDictionaryFactory => CoreCurrent.CultureDictionaryFactory;
public static IShortStringHelper ShortStringHelper
=> Container.GetInstance<IShortStringHelper>();
public static IShortStringHelper ShortStringHelper => CoreCurrent.ShortStringHelper;
public static ILogger Logger => CoreCurrent.Logger;
public static IProfiler Profiler => CoreCurrent.Profiler;
#endregion
}

View File

@@ -33,7 +33,7 @@ namespace Umbraco.Web
/// <returns></returns>
public static IHtmlString RenderProfiler(this HtmlHelper helper)
{
return new HtmlString(ProfilerResolver.Current.Profiler.Render());
return new HtmlString(Current.Profiler.Render());
}
/// <summary>

View File

@@ -1,6 +1,7 @@
using System.IO;
using System.Web.Mvc;
using Umbraco.Core.Logging;
using Umbraco.Web;
namespace Umbraco.Core.Profiling
{
@@ -20,7 +21,7 @@ namespace Umbraco.Core.Profiling
public void Render(ViewContext viewContext, TextWriter writer)
{
using (ProfilerResolver.Current.Profiler.Step(string.Format("{0}.Render: {1}", _name, _viewPath)))
using (Current.Profiler.Step(string.Format("{0}.Render: {1}", _name, _viewPath)))
{
_inner.Render(viewContext, writer);
}

View File

@@ -1,5 +1,6 @@
using System.Web.Mvc;
using Umbraco.Core.Logging;
using Umbraco.Web;
namespace Umbraco.Core.Profiling
{
@@ -16,7 +17,7 @@ namespace Umbraco.Core.Profiling
public ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
{
using (ProfilerResolver.Current.Profiler.Step(string.Format("{0}.FindPartialView, {1}, {2}", _name, partialViewName, useCache)))
using (Current.Profiler.Step(string.Format("{0}.FindPartialView, {1}, {2}", _name, partialViewName, useCache)))
{
return WrapResult(Inner.FindPartialView(controllerContext, partialViewName, useCache));
}
@@ -24,7 +25,7 @@ namespace Umbraco.Core.Profiling
public ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
using (ProfilerResolver.Current.Profiler.Step(string.Format("{0}.FindView, {1}, {2}, {3}", _name, viewName, masterName, useCache)))
using (Current.Profiler.Step(string.Format("{0}.FindView, {1}, {2}, {3}", _name, viewName, masterName, useCache)))
{
return WrapResult(Inner.FindView(controllerContext, viewName, masterName, useCache));
}
@@ -40,7 +41,7 @@ namespace Umbraco.Core.Profiling
public void ReleaseView(ControllerContext controllerContext, IView view)
{
using (ProfilerResolver.Current.Profiler.Step(string.Format("{0}.ReleaseView, {1}", _name, view.GetType().Name)))
using (Current.Profiler.Step(string.Format("{0}.ReleaseView, {1}", _name, view.GetType().Name)))
{
Inner.ReleaseView(controllerContext, view);
}

View File

@@ -23,7 +23,7 @@ namespace Umbraco.Web.Mvc
[Obsolete("Use the ctor specifying all depenendencies instead")]
public UmbracoPageResult()
: this(new ProfilingLogger(LoggerResolver.Current.Logger, ProfilerResolver.Current.Profiler))
: this(new ProfilingLogger(Current.Logger, Current.Profiler))
{
}

View File

@@ -135,7 +135,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
{
if (SyncToXmlFile == false) return;
var logger = LoggerResolver.Current.Logger;
var logger = Current.Logger;
// there's always be one task keeping a ref to the runner
// so it's safe to just create it as a local var here

View File

@@ -54,7 +54,7 @@ namespace Umbraco.Web.UI.Pages
/// </summary>
public ProfilingLogger ProfilingLogger
{
get { return _logger ?? (_logger = new ProfilingLogger(LoggerResolver.Current.Logger, ProfilerResolver.Current.Profiler)); }
get { return _logger ?? (_logger = new ProfilingLogger(Current.Logger, Current.Profiler)); }
}
private ProfilingLogger _logger;

View File

@@ -1,53 +1,39 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Web;
using System.Web.Hosting;
using System.Web.Mvc;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Manifest;
using Umbraco.Web.Routing;
namespace Umbraco.Web
{
/// <summary>
/// The Umbraco global.asax class
/// Represents the Umbraco global.asax class.
/// </summary>
public class UmbracoApplication : UmbracoApplicationBase
{
// if configured and in debug mode, a ManifestWatcher watches App_Plugins folders for
// package.manifest chances and restarts the application on any change
private ManifestWatcher _mw;
protected override void OnApplicationStarted(object sender, EventArgs e)
{
base.OnApplicationStarted(sender, e);
if (ApplicationContext.Current.IsConfigured && GlobalSettings.DebugMode)
{
var appPluginFolder = IOHelper.MapPath("~/App_Plugins/");
if (Directory.Exists(appPluginFolder))
{
_mw = new ManifestWatcher(LoggerResolver.Current.Logger);
_mw.Start(Directory.GetDirectories(IOHelper.MapPath("~/App_Plugins/")));
}
}
if (ApplicationContext.Current.IsConfigured == false || GlobalSettings.DebugMode == false)
return;
var appPlugins = IOHelper.MapPath("~/App_Plugins/");
if (Directory.Exists(appPlugins) == false) return;
_mw = new ManifestWatcher(Current.Logger);
_mw.Start(Directory.GetDirectories(appPlugins));
}
protected override void OnApplicationEnd(object sender, EventArgs e)
{
base.OnApplicationEnd(sender, e);
if (_mw != null)
{
_mw.Dispose();
}
_mw?.Dispose();
}
protected override IBootManager GetBootManager()

View File

@@ -347,7 +347,7 @@ namespace umbraco.presentation.developer.packages
_installer.InstallCleanUp(packageId, dir);
// Update ClientDependency version
var clientDependencyConfig = new Umbraco.Core.Configuration.ClientDependencyConfiguration(LoggerResolver.Current.Logger);
var clientDependencyConfig = new Umbraco.Core.Configuration.ClientDependencyConfiguration(Current.Logger);
var clientDependencyUpdated = clientDependencyConfig.IncreaseVersionNumber();
//clear the tree cache - we'll do this here even though the browser will reload, but just in case it doesn't can't hurt.