diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index 62872c283c..b142e08c5f 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -33,8 +33,6 @@ - - @@ -53,6 +51,13 @@ + + + + + + + diff --git a/build/NuSpecs/UmbracoCms.nuspec b/build/NuSpecs/UmbracoCms.nuspec index 9811743746..1deec235f8 100644 --- a/build/NuSpecs/UmbracoCms.nuspec +++ b/build/NuSpecs/UmbracoCms.nuspec @@ -22,7 +22,7 @@ not want this to happen as the alpha of the next major is, really, the next major already. --> - + @@ -35,7 +35,6 @@ - diff --git a/build/NuSpecs/tools/install.core.ps1 b/build/NuSpecs/tools/install.core.ps1 index ad3a00651b..0a658266a1 100644 --- a/build/NuSpecs/tools/install.core.ps1 +++ b/build/NuSpecs/tools/install.core.ps1 @@ -33,7 +33,6 @@ if ($project) { robocopy $umbracoBinFolder $umbracoBinBackupPath /e /LOG:$copyLogsPath\UmbracoBinBackup.log # Delete files Umbraco ships with - if(Test-Path $umbracoBinFolder\log4net.dll) { Remove-Item $umbracoBinFolder\log4net.dll -Force -Confirm:$false } if(Test-Path $umbracoBinFolder\Microsoft.ApplicationBlocks.Data.dll) { Remove-Item $umbracoBinFolder\Microsoft.ApplicationBlocks.Data.dll -Force -Confirm:$false } if(Test-Path $umbracoBinFolder\System.Data.SqlServerCe.dll) { Remove-Item $umbracoBinFolder\System.Data.SqlServerCe.dll -Force -Confirm:$false } if(Test-Path $umbracoBinFolder\System.Data.SqlServerCe.Entity.dll) { Remove-Item $umbracoBinFolder\System.Data.SqlServerCe.Entity.dll -Force -Confirm:$false } diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs index 77bd21b673..e6118de937 100644 --- a/src/SolutionInfo.cs +++ b/src/SolutionInfo.cs @@ -19,4 +19,4 @@ using System.Resources; // these are FYI and changed automatically [assembly: AssemblyFileVersion("8.0.0")] -[assembly: AssemblyInformationalVersion("8.0.0-alpha.44")] +[assembly: AssemblyInformationalVersion("8.0.0-alpha.49")] diff --git a/src/Umbraco.Core/BindingRedirects.cs b/src/Umbraco.Core/BindingRedirects.cs index a93485085e..17e187b7ae 100644 --- a/src/Umbraco.Core/BindingRedirects.cs +++ b/src/Umbraco.Core/BindingRedirects.cs @@ -18,10 +18,7 @@ namespace Umbraco.Core // this only gets called when an assembly can't be resolved AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; } - - private static readonly Regex Log4NetAssemblyPattern = new Regex("log4net, Version=([\\d\\.]+?), Culture=neutral, PublicKeyToken=\\w+$", RegexOptions.Compiled); - private const string Log4NetReplacement = "log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a"; - + /// /// This is used to do an assembly binding redirect via code - normally required due to signature changes in assemblies /// @@ -30,12 +27,6 @@ namespace Umbraco.Core /// private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { - //log4net: - if (Log4NetAssemblyPattern.IsMatch(args.Name) && args.Name != Log4NetReplacement) - { - return Assembly.Load(Log4NetAssemblyPattern.Replace(args.Name, Log4NetReplacement)); - } - //AutoMapper: // ensure the assembly is indeed AutoMapper and that the PublicKeyToken is null before trying to Load again // do NOT just replace this with 'return Assembly', as it will cause an infinite loop -> stackoverflow diff --git a/src/Umbraco.Core/Components/BootLoader.cs b/src/Umbraco.Core/Components/BootLoader.cs index fd09ce839d..87d4cdac75 100644 --- a/src/Umbraco.Core/Components/BootLoader.cs +++ b/src/Umbraco.Core/Components/BootLoader.cs @@ -111,15 +111,15 @@ namespace Umbraco.Core.Components catch (Exception e) { // in case of an error, force-dump everything to log - _logger.Info(() => GetComponentsReport(requirements)); - _logger.Error("Failed to sort components.", e); + _logger.Info("Component Report:\r\n{ComponentReport}", GetComponentsReport(requirements)); + _logger.Error(e, "Failed to sort compontents."); throw; } // bit verbose but should help for troubleshooting var text = "Ordered Components: " + Environment.NewLine + string.Join(Environment.NewLine, sortedComponentTypes) + Environment.NewLine; Console.WriteLine(text); - _logger.Debug(text); + _logger.Debug("Ordered Components: {SortedComponentTypes}", sortedComponentTypes); return sortedComponentTypes; } diff --git a/src/Umbraco.Core/Composing/TypeFinder.cs b/src/Umbraco.Core/Composing/TypeFinder.cs index f244d1d1ce..a42b84e0c5 100644 --- a/src/Umbraco.Core/Composing/TypeFinder.cs +++ b/src/Umbraco.Core/Composing/TypeFinder.cs @@ -148,7 +148,7 @@ namespace Umbraco.Core.Composing catch (FileNotFoundException ex) { //this will occur if it cannot load the assembly - Current.Logger.Error(typeof(TypeFinder), "Could not load assembly App_Code", ex); + Current.Logger.Error(typeof(TypeFinder), ex, "Could not load assembly App_Code"); } } } @@ -224,7 +224,6 @@ namespace Umbraco.Core.Composing "Dynamic,", "HtmlDiff,", "Iesi.Collections,", - "log4net,", "Microsoft.", "Newtonsoft.", "NHibernate.", @@ -440,7 +439,7 @@ namespace Umbraco.Core.Composing } catch (TypeLoadException ex) { - Current.Logger.Error(typeof(TypeFinder), $"Could not query types on {assembly} assembly, this is most likely due to this assembly not being compatible with the current Umbraco version", ex); + Current.Logger.Error(typeof(TypeFinder), ex, "Could not query types on {Assembly} assembly, this is most likely due to this assembly not being compatible with the current Umbraco version", assembly); continue; } @@ -506,7 +505,7 @@ namespace Umbraco.Core.Composing } catch (TypeLoadException ex) { - Current.Logger.Error(typeof(TypeFinder), $"Could not query types on {assembly} assembly, this is most likely due to this assembly not being compatible with the current Umbraco version", ex); + Current.Logger.Error(typeof(TypeFinder), ex, "Could not query types on {Assembly} assembly, this is most likely due to this assembly not being compatible with the current Umbraco version", assembly); continue; } @@ -573,7 +572,7 @@ namespace Umbraco.Core.Composing if (NotifiedLoadExceptionAssemblies.Contains(a.FullName) == false) { NotifiedLoadExceptionAssemblies.Add(a.FullName); - Current.Logger.Warn(typeof (TypeFinder), ex, $"Could not load all types from {a.GetName().Name}."); + Current.Logger.Warn(typeof (TypeFinder), ex, "Could not load all types from {TypeName}.", a.GetName().Name); } } return rex.Types.WhereNotNull().ToArray(); diff --git a/src/Umbraco.Core/Composing/TypeLoader.cs b/src/Umbraco.Core/Composing/TypeLoader.cs index d87fdfe3de..304638e017 100644 --- a/src/Umbraco.Core/Composing/TypeLoader.cs +++ b/src/Umbraco.Core/Composing/TypeLoader.cs @@ -494,7 +494,7 @@ namespace Umbraco.Core.Composing if (--attempts == 0) throw; - _logger.Logger.Debug(() => $"Attempted to get filestream for file {path} failed, {attempts} attempts left, pausing for {pauseMilliseconds} milliseconds"); + _logger.Logger.Debug("Attempted to get filestream for file {Path} failed, {NumberOfAttempts} attempts left, pausing for {PauseMilliseconds} milliseconds", path, attempts, pauseMilliseconds); Thread.Sleep(pauseMilliseconds); } } @@ -645,7 +645,7 @@ namespace Umbraco.Core.Composing if (typeList != null) { // need to put some logging here to try to figure out why this is happening: http://issues.umbraco.org/issue/U4-3505 - _logger.Logger.Debug(() => $"Getting {GetName(baseType, attributeType)}: found a cached type list."); + _logger.Logger.Debug("Getting {TypeName}: found a cached type list.", GetName(baseType, attributeType)); return typeList.Types; } @@ -676,7 +676,7 @@ namespace Umbraco.Core.Composing // so in this instance there will never be a result. if (cacheResult.Exception is CachedTypeNotFoundInFileException || cacheResult.Success == false) { - _logger.Logger.Debug(() => $"Getting {GetName(baseType, attributeType)}: failed to load from cache file, must scan assemblies."); + _logger.Logger.Debug("Getting {TypeName}: failed to load from cache file, must scan assemblies.", GetName(baseType, attributeType)); scan = true; } else @@ -695,7 +695,7 @@ namespace Umbraco.Core.Composing catch (Exception ex) { // in case of any exception, we have to exit, and revert to scanning - _logger.Logger.Error("Getting " + GetName(baseType, attributeType) + ": failed to load cache file type " + type + ", reverting to scanning assemblies.", ex); + _logger.Logger.Error(ex, "Getting {TypeName}: failed to load cache file type {CacheType}, reverting to scanning assemblies.", GetName(baseType, attributeType), type); scan = true; break; } @@ -703,7 +703,7 @@ namespace Umbraco.Core.Composing if (scan == false) { - _logger.Logger.Debug(() => $"Getting {GetName(baseType, attributeType)}: loaded types from cache file."); + _logger.Logger.Debug("Getting {TypeName}: loaded types from cache file.", GetName(baseType, attributeType)); } } } @@ -711,7 +711,7 @@ namespace Umbraco.Core.Composing if (scan) { // either we had to scan, or we could not get the types from the cache file - scan now - _logger.Logger.Debug(() => $"Getting {GetName(baseType, attributeType)}: scanning assemblies."); + _logger.Logger.Debug("Getting {TypeName}: scanning assemblies.", GetName(baseType, attributeType)); foreach (var t in finder()) typeList.Add(t); @@ -729,11 +729,11 @@ namespace Umbraco.Core.Composing UpdateCache(); } - _logger.Logger.Debug(() => $"Got {GetName(baseType, attributeType)}, caching ({added.ToString().ToLowerInvariant()})."); + _logger.Logger.Debug("Got {TypeName}, caching ({CacheType}).", GetName(baseType, attributeType), added.ToString().ToLowerInvariant()); } else { - _logger.Logger.Debug(() => $"Got {GetName(baseType, attributeType)}."); + _logger.Logger.Debug("Got {TypeName}.", GetName(baseType, attributeType)); } return typeList.Types; diff --git a/src/Umbraco.Core/Configuration/ClientDependencyConfiguration.cs b/src/Umbraco.Core/Configuration/ClientDependencyConfiguration.cs index 41076e5d91..61f9023167 100644 --- a/src/Umbraco.Core/Configuration/ClientDependencyConfiguration.cs +++ b/src/Umbraco.Core/Configuration/ClientDependencyConfiguration.cs @@ -79,13 +79,13 @@ namespace Umbraco.Core.Configuration versionAttribute.SetValue(newVersion); clientDependencyConfigXml.Save(_fileName, SaveOptions.DisableFormatting); - _logger.Info(() => $"Updated version number from {oldVersion} to {newVersion}"); + _logger.Info("Updated version number from {OldVersion} to {NewVersion}", oldVersion, newVersion); return true; } } catch (Exception ex) { - _logger.Error("Couldn't update ClientDependency version number", ex); + _logger.Error(ex, "Couldn't update ClientDependency version number"); } return false; @@ -113,13 +113,13 @@ namespace Umbraco.Core.Configuration versionAttribute.SetValue(newVersion); clientDependencyConfigXml.Save(_fileName, SaveOptions.DisableFormatting); - _logger.Info(() => $"Updated version number from {oldVersion} to {newVersion}"); + _logger.Info("Updated version number from {OldVersion} to {NewVersion}", oldVersion, newVersion); return true; } } catch (Exception ex) { - _logger.Error("Couldn't update ClientDependency version number", ex); + _logger.Error(ex, "Couldn't update ClientDependency version number"); } return false; @@ -150,7 +150,7 @@ namespace Umbraco.Core.Configuration catch (Exception ex) { //invalid path format or something... try/catch to be safe - _logger.Error("Could not get path from ClientDependency.config", ex); + _logger.Error(ex, "Could not get path from ClientDependency.config"); } var success = true; @@ -167,7 +167,7 @@ namespace Umbraco.Core.Configuration catch (Exception ex) { // Something could be locking the directory or the was another error, making sure we don't break the upgrade installer - _logger.Error("Could not clear temp files", ex); + _logger.Error(ex, "Could not clear temp files"); success = false; } } diff --git a/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs b/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs index a0ca2da4ff..708c563d9d 100644 --- a/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs +++ b/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs @@ -40,13 +40,15 @@ namespace Umbraco.Core.Configuration.Grid var gridConfig = Path.Combine(_configFolder.FullName, "grid.editors.config.js"); if (File.Exists(gridConfig)) { + var sourceString = File.ReadAllText(gridConfig); + try { - editors.AddRange(parser.ParseGridEditors(File.ReadAllText(gridConfig))); + editors.AddRange(parser.ParseGridEditors(sourceString)); } catch (Exception ex) { - _logger.Error("Could not parse the contents of grid.editors.config.js into a JSON array", ex); + _logger.Error(ex, "Could not parse the contents of grid.editors.config.js into a JSON array '{Json}", sourceString); } } diff --git a/src/Umbraco.Core/Configuration/UmbracoConfig.cs b/src/Umbraco.Core/Configuration/UmbracoConfig.cs index 248736d0fe..6dd5617992 100644 --- a/src/Umbraco.Core/Configuration/UmbracoConfig.cs +++ b/src/Umbraco.Core/Configuration/UmbracoConfig.cs @@ -88,7 +88,7 @@ namespace Umbraco.Core.Configuration if (_healthChecks == null) { var ex = new ConfigurationErrorsException("Could not load the " + typeof(IHealthChecks) + " from config file, ensure the web.config and healthchecks.config files are formatted correctly"); - Current.Logger.Error("Config error", ex); + Current.Logger.Error(ex, "Config error"); throw ex; } @@ -103,7 +103,7 @@ namespace Umbraco.Core.Configuration if (_dashboardSection == null) { var ex = new ConfigurationErrorsException("Could not load the " + typeof(IDashboardSection) + " from config file, ensure the web.config and Dashboard.config files are formatted correctly"); - Current.Logger.Error("Config error", ex); + Current.Logger.Error(ex, "Config error"); throw ex; } @@ -162,7 +162,7 @@ namespace Umbraco.Core.Configuration if (_umbracoSettings == null) { var ex = new ConfigurationErrorsException("Could not load the " + typeof (IUmbracoSettingsSection) + " from config file, ensure the web.config and umbracoSettings.config files are formatted correctly"); - Current.Logger.Error("Config error", ex); + Current.Logger.Error(ex, "Config error"); throw ex; } diff --git a/src/Umbraco.Core/Configuration/UmbracoVersion.cs b/src/Umbraco.Core/Configuration/UmbracoVersion.cs index 9c0ad4c7c4..8fb650510b 100644 --- a/src/Umbraco.Core/Configuration/UmbracoVersion.cs +++ b/src/Umbraco.Core/Configuration/UmbracoVersion.cs @@ -22,7 +22,7 @@ namespace Umbraco.Core.Configuration /// /// Gets the version comment of the executing code (eg "beta"). /// - public static string CurrentComment => "alpha.44"; + public static string CurrentComment => "alpha.49"; /// /// Gets the assembly version of Umbraco.Code.dll. diff --git a/src/Umbraco.Core/IO/MediaFileSystem.cs b/src/Umbraco.Core/IO/MediaFileSystem.cs index 47f9f14423..4ecb44cfb9 100644 --- a/src/Umbraco.Core/IO/MediaFileSystem.cs +++ b/src/Umbraco.Core/IO/MediaFileSystem.cs @@ -102,7 +102,7 @@ namespace Umbraco.Core.IO } catch (Exception e) { - Logger.Error("Failed to delete attached file \"" + file + "\".", e); + Logger.Error(e, "Failed to delete attached file '{File}'", file); } }); } diff --git a/src/Umbraco.Core/IO/PhysicalFileSystem.cs b/src/Umbraco.Core/IO/PhysicalFileSystem.cs index bc9968153f..217ecb51b4 100644 --- a/src/Umbraco.Core/IO/PhysicalFileSystem.cs +++ b/src/Umbraco.Core/IO/PhysicalFileSystem.cs @@ -73,11 +73,11 @@ namespace Umbraco.Core.IO } catch (UnauthorizedAccessException ex) { - Current.Logger.Error("Not authorized to get directories", ex); + Current.Logger.Error(ex, "Not authorized to get directories for '{Path}'", fullPath); } catch (DirectoryNotFoundException ex) { - Current.Logger.Error("Directory not found", ex); + Current.Logger.Error(ex, "Directory not found for '{Path}'", fullPath); } return Enumerable.Empty(); @@ -109,7 +109,7 @@ namespace Umbraco.Core.IO } catch (DirectoryNotFoundException ex) { - Current.Logger.Error("Directory not found", ex); + Current.Logger.Error(ex, "Directory not found for '{Path}'", fullPath); } } @@ -189,11 +189,11 @@ namespace Umbraco.Core.IO } catch (UnauthorizedAccessException ex) { - Current.Logger.Error("Not authorized to get directories", ex); + Current.Logger.Error(ex, "Not authorized to get directories for '{Path}'", fullPath); } catch (DirectoryNotFoundException ex) { - Current.Logger.Error("Directory not found", ex); + Current.Logger.Error(ex, "Directory not found for '{FullPath}'", fullPath); } return Enumerable.Empty(); @@ -226,7 +226,7 @@ namespace Umbraco.Core.IO } catch (FileNotFoundException ex) { - Current.Logger.Info(() => $"DeleteFile failed with FileNotFoundException: {ex.InnerException}"); + Current.Logger.Error(ex.InnerException, "DeleteFile failed with FileNotFoundException for '{Path}'", fullPath); } } diff --git a/src/Umbraco.Core/IO/ShadowFileSystems.cs b/src/Umbraco.Core/IO/ShadowFileSystems.cs index c101b9a7c2..289667b0db 100644 --- a/src/Umbraco.Core/IO/ShadowFileSystems.cs +++ b/src/Umbraco.Core/IO/ShadowFileSystems.cs @@ -54,7 +54,7 @@ namespace Umbraco.Core.IO } _logger = logger; - _logger.Debug(() => "Shadow " + id + "."); + _logger.Debug("Shadow '{ShadowId}'", id); _id = id; _wrappers = wrappers; @@ -112,7 +112,7 @@ namespace Umbraco.Core.IO { lock (Locker) { - _logger.Debug(() => "UnShadow " + _id + " (" + (_completed ? "complete" : "abort") + ")."); + _logger.Debug("UnShadow '{ShadowId}' {Status}", _id, _completed ? "complete" : "abort"); var exceptions = new List(); foreach (var wrapper in _wrappers) diff --git a/src/Umbraco.Core/Logging/AppDomainTokenConverter.cs b/src/Umbraco.Core/Logging/AppDomainTokenConverter.cs deleted file mode 100644 index 0abddc63e3..0000000000 --- a/src/Umbraco.Core/Logging/AppDomainTokenConverter.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Web; - -namespace Umbraco.Core.Logging -{ - /// - /// Allows for outputting a normalized appdomainappid token in a log format - /// - public sealed class AppDomainTokenConverter : log4net.Util.PatternConverter - { - protected override void Convert(TextWriter writer, object state) - { - writer.Write(HttpRuntime.AppDomainAppId.ReplaceNonAlphanumericChars(string.Empty)); - } - } -} diff --git a/src/Umbraco.Core/Logging/AsyncForwardingAppenderBase.cs b/src/Umbraco.Core/Logging/AsyncForwardingAppenderBase.cs deleted file mode 100644 index 3ebcfe458f..0000000000 --- a/src/Umbraco.Core/Logging/AsyncForwardingAppenderBase.cs +++ /dev/null @@ -1,121 +0,0 @@ -using log4net.Appender; -using log4net.Core; -using log4net.Util; -using System; -using System.Runtime.Remoting.Messaging; - -namespace Umbraco.Core.Logging -{ - /// - /// Borrowed from https://github.com/cjbhaines/Log4Net.Async - will reference Nuget packages directly in v8 - /// - public abstract class AsyncForwardingAppenderBase : ForwardingAppender - { - #region Private Members - - private const FixFlags DefaultFixFlags = FixFlags.Partial; - private FixFlags fixFlags = DefaultFixFlags; - private LoggingEventHelper loggingEventHelper; - - #endregion Private Members - - #region Properties - - public FixFlags Fix - { - get { return fixFlags; } - set { SetFixFlags(value); } - } - - /// - /// Returns HttpContext.Current - /// - protected internal object HttpContext - { - get - { - return CallContext.HostContext; - } - set - { - CallContext.HostContext = value; - } - } - - /// - /// The logger name that will be used for logging internal errors. - /// - protected abstract string InternalLoggerName { get; } - - public abstract int? BufferSize { get; set; } - - #endregion Properties - - public override void ActivateOptions() - { - base.ActivateOptions(); - loggingEventHelper = new LoggingEventHelper(InternalLoggerName, DefaultFixFlags); - InitializeAppenders(); - } - - #region Appender Management - - public override void AddAppender(IAppender newAppender) - { - base.AddAppender(newAppender); - SetAppenderFixFlags(newAppender); - } - - private void SetFixFlags(FixFlags newFixFlags) - { - if (newFixFlags != fixFlags) - { - loggingEventHelper.Fix = newFixFlags; - fixFlags = newFixFlags; - InitializeAppenders(); - } - } - - private void InitializeAppenders() - { - foreach (var appender in Appenders) - { - SetAppenderFixFlags(appender); - } - } - - private void SetAppenderFixFlags(IAppender appender) - { - var bufferingAppender = appender as BufferingAppenderSkeleton; - if (bufferingAppender != null) - { - bufferingAppender.Fix = Fix; - } - } - - #endregion Appender Management - - #region Forwarding - - protected void ForwardInternalError(string message, Exception exception, Type thisType) - { - LogLog.Error(thisType, message, exception); - var loggingEvent = loggingEventHelper.CreateLoggingEvent(Level.Error, message, exception); - ForwardLoggingEvent(loggingEvent, thisType); - } - - protected void ForwardLoggingEvent(LoggingEvent loggingEvent, Type thisType) - { - try - { - base.Append(loggingEvent); - } - catch (Exception exception) - { - LogLog.Error(thisType, "Unable to forward logging event", exception); - } - } - - #endregion Forwarding - } -} diff --git a/src/Umbraco.Core/Logging/DebugDiagnosticsLogger.cs b/src/Umbraco.Core/Logging/DebugDiagnosticsLogger.cs index 4bb7aeb464..a8ca9b6c31 100644 --- a/src/Umbraco.Core/Logging/DebugDiagnosticsLogger.cs +++ b/src/Umbraco.Core/Logging/DebugDiagnosticsLogger.cs @@ -1,5 +1,4 @@ using System; -using System.Linq; namespace Umbraco.Core.Logging { @@ -9,95 +8,107 @@ namespace Umbraco.Core.Logging public class DebugDiagnosticsLogger : ILogger { /// - public void Error(Type reporting, string message, Exception exception = null) + public void Fatal(Type reporting, Exception exception, string message) { System.Diagnostics.Debug.WriteLine(message + Environment.NewLine + exception, reporting.FullName); } + /// + public void Fatal(Type reporting, Exception exception) + { + System.Diagnostics.Debug.WriteLine(Environment.NewLine + exception, reporting.FullName); + } + + /// + public void Fatal(Type reporting, string message) + { + System.Diagnostics.Debug.WriteLine(message); + } + + /// + public void Fatal(Type reporting, Exception exception, string messageTemplate, params object[] args) + { + System.Diagnostics.Debug.WriteLine(string.Format(messageTemplate, args) + Environment.NewLine + exception, reporting.FullName); + } + + /// + public void Fatal(Type reporting, string messageTemplate, params object[] args) + { + System.Diagnostics.Debug.WriteLine(messageTemplate, args); + } + + /// + public void Error(Type reporting, Exception exception, string message) + { + System.Diagnostics.Debug.WriteLine(message + Environment.NewLine + exception, reporting.FullName); + } + + /// + public void Error(Type reporting, Exception exception) + { + System.Diagnostics.Debug.WriteLine(Environment.NewLine + exception, reporting.FullName); + } + + /// + public void Error(Type reporting, string message) + { + System.Diagnostics.Debug.WriteLine(message); + } + + /// + public void Error(Type reporting, Exception exception, string messageTemplate, params object[] args) + { + System.Diagnostics.Debug.WriteLine(string.Format(messageTemplate, args) + Environment.NewLine + exception, reporting.FullName); + } + + /// + public void Error(Type reporting, string messageTemplate, params object[] args) + { + System.Diagnostics.Debug.WriteLine(messageTemplate, args); + } + /// public void Warn(Type reporting, string format) { System.Diagnostics.Debug.WriteLine(format, reporting.FullName); } - - /// - public void Warn(Type reporting, Func messageBuilder) - { - System.Diagnostics.Debug.WriteLine(messageBuilder(), reporting.FullName); - } - + /// public void Warn(Type reporting, string format, params object[] args) { System.Diagnostics.Debug.WriteLine(string.Format(format, args), reporting.FullName); } - /// - public void Warn(Type reporting, string format, params Func[] args) - { - System.Diagnostics.Debug.WriteLine(string.Format(format, args.Select(x => x()).ToArray()), reporting.FullName); - } - /// public void Warn(Type reporting, Exception exception, string message) { System.Diagnostics.Debug.WriteLine(message + Environment.NewLine + exception, reporting.FullName); } - /// - public void Warn(Type reporting, Exception exception, Func messageBuilder) - { - System.Diagnostics.Debug.WriteLine(messageBuilder() + Environment.NewLine + exception, reporting.FullName); - } - /// public void Warn(Type reporting, Exception exception, string format, params object[] args) { System.Diagnostics.Debug.WriteLine(string.Format(format + Environment.NewLine + exception, args), reporting.FullName); } - /// - public void Warn(Type reporting, Exception exception, string format, params Func[] args) - { - System.Diagnostics.Debug.WriteLine(string.Format(format + Environment.NewLine + exception, args.Select(x => x()).ToArray()), reporting.FullName); - } - /// public void Info(Type reporting, string message) { System.Diagnostics.Debug.WriteLine(message, reporting.FullName); } - /// - public void Info(Type reporting, Func messageBuilder) - { - System.Diagnostics.Debug.WriteLine(messageBuilder(), reporting.FullName); - } - /// public void Info(Type reporting, string format, params object[] args) { System.Diagnostics.Debug.WriteLine(string.Format(format, args), reporting.FullName); } - /// - public void Info(Type reporting, string format, params Func[] args) - { - System.Diagnostics.Debug.WriteLine(string.Format(format, args.Select(x => x()).ToArray()), reporting.FullName); - } - /// public void Debug(Type reporting, string message) { System.Diagnostics.Debug.WriteLine(message, reporting.FullName); } - /// - public void Debug(Type reporting, Func messageBuilder) - { - System.Diagnostics.Debug.WriteLine(messageBuilder(), reporting.FullName); - } - /// public void Debug(Type reporting, string format, params object[] args) { @@ -105,9 +116,16 @@ namespace Umbraco.Core.Logging } /// - public void Debug(Type reporting, string format, params Func[] args) + public void Verbose(Type reporting, string message) { - System.Diagnostics.Debug.WriteLine(string.Format(format, args.Select(x => x()).ToArray()), reporting.FullName); + System.Diagnostics.Debug.WriteLine(message, reporting.FullName); } + + /// + public void Verbose(Type reporting, string format, params object[] args) + { + System.Diagnostics.Debug.WriteLine(string.Format(format, args), reporting.FullName); + } + } } diff --git a/src/Umbraco.Core/DisposableTimer.cs b/src/Umbraco.Core/Logging/DisposableTimer.cs similarity index 81% rename from src/Umbraco.Core/DisposableTimer.cs rename to src/Umbraco.Core/Logging/DisposableTimer.cs index 58382a50e9..869ca2cd44 100644 --- a/src/Umbraco.Core/DisposableTimer.cs +++ b/src/Umbraco.Core/Logging/DisposableTimer.cs @@ -1,8 +1,7 @@ using System; using System.Diagnostics; -using Umbraco.Core.Logging; -namespace Umbraco.Core +namespace Umbraco.Core.Logging { /// /// Starts the timer and invokes a callback upon disposal. Provides a simple way of timing an operation by wrapping it in a using (C#) statement. @@ -18,6 +17,7 @@ namespace Umbraco.Core private string _failMessage; private Exception _failException; private bool _failed; + private readonly string _timingId; internal enum LogType { @@ -38,16 +38,17 @@ namespace Umbraco.Core _endMessage = endMessage; _failMessage = failMessage; _thresholdMilliseconds = thresholdMilliseconds < 0 ? 0 : thresholdMilliseconds; + _timingId = Guid.NewGuid().ToString("N"); if (thresholdMilliseconds == 0) { switch (logType) { case LogType.Debug: - logger.Debug(loggerType, startMessage); + logger.Debug(loggerType, "[Timing {TimingId}] {StartMessage}", _timingId, startMessage); break; case LogType.Info: - logger.Info(loggerType, startMessage); + logger.Info(loggerType, "[Timing {TimingId}] {StartMessage}", _timingId, startMessage); break; default: throw new ArgumentOutOfRangeException(nameof(logType)); @@ -91,15 +92,15 @@ namespace Umbraco.Core { if (_failed) { - _logger.Error(_loggerType, $"{_failMessage} ({Stopwatch.ElapsedMilliseconds}ms)", _failException); + _logger.Error(_loggerType, _failException, "[Timing {TimingId}] {FailMessage} ({TimingDuration}ms)", _timingId, _failMessage, Stopwatch.ElapsedMilliseconds); } else switch (_logType) { case LogType.Debug: - _logger.Debug(_loggerType, () => $"{_endMessage} ({Stopwatch.ElapsedMilliseconds}ms)"); + _logger.Debug(_loggerType, "[Timing {TimingId}] {EndMessage} ({TimingDuration}ms)", _timingId, _endMessage, Stopwatch.ElapsedMilliseconds); break; case LogType.Info: - _logger.Info(_loggerType, () => $"{_endMessage} ({Stopwatch.ElapsedMilliseconds}ms)"); + _logger.Info(_loggerType, "[Timing {TimingId}] {EndMessage} ({TimingDuration}ms)", _timingId, _endMessage, Stopwatch.ElapsedMilliseconds); break; // filtered in the ctor //default: diff --git a/src/Umbraco.Core/Logging/ILogger.cs b/src/Umbraco.Core/Logging/ILogger.cs index 905ba9f7fa..2162b10bfe 100644 --- a/src/Umbraco.Core/Logging/ILogger.cs +++ b/src/Umbraco.Core/Logging/ILogger.cs @@ -1,22 +1,98 @@ using System; -using System.ComponentModel; namespace Umbraco.Core.Logging { /// /// Defines the logging service. /// + /// + /// Message templates in logging methods follow the Message Templates specification + /// available at https://messagetemplates.org/ in order to support structured logging. + /// Implementations must ensure that they support these templates. Note that the + /// specification includes support for traditional C# numeric placeholders. + /// For instance, "Processed {Input} in {Time}ms." + /// public interface ILogger { + /// + /// Logs a fatal message with an exception. + /// + /// The reporting type. + /// An exception. + /// A message. + void Fatal(Type reporting, Exception exception, string message); + + /// + /// Logs a fatal exception. + /// + /// The reporting type. + /// An exception. + /// The message string is unspecified and is implementation-specific. + void Fatal(Type reporting, Exception exception); + + /// + /// Logs a fatal message. + /// + /// The reporting type. + /// A message. + void Fatal(Type reporting, string message); + + /// + /// Logs a fatal message with an exception. + /// + /// The reporting type. + /// An exception. + /// A message template. + /// Property values. + void Fatal(Type reporting, Exception exception, string messageTemplate, params object[] propertyValues); + + /// + /// Logs a fatal message. + /// + /// The reporting type. + /// A message template. + /// Property values. + void Fatal(Type reporting, string messageTemplate, params object[] propertyValues); + + /// + /// Logs an error message with an exception. + /// + /// The reporting type. + /// An exception. + /// A message. + void Error(Type reporting, Exception exception, string message); + + /// + /// Logs an error exception. + /// + /// The reporting type. + /// An exception. + /// The message string is unspecified and is implementation-specific. + void Error(Type reporting, Exception exception); + /// /// Logs an error message. /// /// The reporting type. /// A message. - /// An exception. - void Error(Type reporting, string message, Exception exception = null); + void Error(Type reporting, string message); - // note: should we have more overloads for Error too? + /// + /// Logs an error message with an exception. + /// + /// The reporting type. + /// An exception. + /// A message template. + /// Property values. + void Error(Type reporting, Exception exception, string messageTemplate, params object[] propertyValues); + + /// + /// Logs an error message. + /// + /// The reporting type. + /// A message template. + /// Property values. + void Error(Type reporting, string messageTemplate, params object[] propertyValues); /// /// Logs a warning message. @@ -29,8 +105,9 @@ namespace Umbraco.Core.Logging /// Logs a warning message. /// /// The reporting type. - /// A message builder. - void Warn(Type reporting, Func messageBuilder); + /// A message template. + /// Property values. + void Warn(Type reporting, string messageTemplate, params object[] propertyValues); /// /// Logs a warning message with an exception. @@ -45,8 +122,9 @@ namespace Umbraco.Core.Logging /// /// The reporting type. /// An exception. - /// A message builder. - void Warn(Type reporting, Exception exception, Func messageBuilder); + /// A message template. + /// Property values. + void Warn(Type reporting, Exception exception, string messageTemplate, params object[] propertyValues); /// /// Logs an information message. @@ -56,11 +134,12 @@ namespace Umbraco.Core.Logging void Info(Type reporting, string message); /// - /// Logs an information message. + /// Logs a info message. /// /// The reporting type. - /// A message builder. - void Info(Type reporting, Func messageBuilder); + /// A message template. + /// Property values. + void Info(Type reporting, string messageTemplate, params object[] propertyValues); /// /// Logs a debugging message. @@ -70,10 +149,26 @@ namespace Umbraco.Core.Logging void Debug(Type reporting, string message); /// - /// Logs a debugging message. + /// Logs a debug message. /// /// The reporting type. - /// A message builder. - void Debug(Type reporting, Func messageBuilder); + /// A message template. + /// Property values. + void Debug(Type reporting, string messageTemplate, params object[] propertyValues); + + /// + /// Logs a verbose message. + /// + /// The reporting type. + /// A message. + void Verbose(Type reporting, string message); + + /// + /// Logs a verbose message. + /// + /// The reporting type. + /// A message template. + /// Property values. + void Verbose(Type reporting, string messageTemplate, params object[] propertyValues); } } diff --git a/src/Umbraco.Core/Logging/IQueue.cs b/src/Umbraco.Core/Logging/IQueue.cs deleted file mode 100644 index db87cb7705..0000000000 --- a/src/Umbraco.Core/Logging/IQueue.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Umbraco.Core.Logging -{ - /// - /// Borrowed from https://github.com/cjbhaines/Log4Net.Async - will reference Nuget packages directly in v8 - /// - /// - internal interface IQueue - { - void Enqueue(T item); - bool TryDequeue(out T ret); - } -} diff --git a/src/Umbraco.Core/Logging/ImageProcessorLogger.cs b/src/Umbraco.Core/Logging/ImageProcessorLogger.cs index 02faac39aa..fa1f117e06 100644 --- a/src/Umbraco.Core/Logging/ImageProcessorLogger.cs +++ b/src/Umbraco.Core/Logging/ImageProcessorLogger.cs @@ -27,7 +27,7 @@ namespace Umbraco.Core.Logging { // Using LogHelper since the ImageProcessor logger expects a parameterless constructor. var message = $"{callerName} {lineNumber} : {text}"; - Current.Logger.Error(string.Empty, new ImageProcessingException(message)); + Current.Logger.Error(new ImageProcessingException(message)); } /// @@ -41,7 +41,7 @@ namespace Umbraco.Core.Logging { // Using LogHelper since the ImageProcessor logger expects a parameterless constructor. var message = $"{callerName} {lineNumber} : {text}"; - Current.Logger.Error(type, string.Empty, new ImageProcessingException(message)); + Current.Logger.Error(type, new ImageProcessingException(message)); } } } diff --git a/src/Umbraco.Core/Logging/LogProfiler.cs b/src/Umbraco.Core/Logging/LogProfiler.cs index 6fbb1b2e26..b80e40942a 100644 --- a/src/Umbraco.Core/Logging/LogProfiler.cs +++ b/src/Umbraco.Core/Logging/LogProfiler.cs @@ -24,8 +24,8 @@ namespace Umbraco.Core.Logging /// public IDisposable Step(string name) { - _logger.Debug(() => $"Begin: {name}."); - return new LightDisposableTimer(duration => _logger.Info(() => $"End {name}. ({duration}ms)")); + _logger.Debug("Begin: {ProfileName}", name); + return new LightDisposableTimer(duration => _logger.Info("End {ProfileName} ({ProfileDuration}ms)", name, duration)); } /// diff --git a/src/Umbraco.Core/Logging/Logger.cs b/src/Umbraco.Core/Logging/Logger.cs index 188cf01ac9..0a20022e93 100644 --- a/src/Umbraco.Core/Logging/Logger.cs +++ b/src/Umbraco.Core/Logging/Logger.cs @@ -1,61 +1,129 @@ using System; -using System.Diagnostics; -using System.Globalization; using System.IO; -using System.Linq; using System.Reflection; using System.Threading; -using log4net; -using log4net.Config; using Umbraco.Core.Configuration; using Umbraco.Core.Diagnostics; -using log4net.Util; +using Serilog; +using Serilog.Events; +using Umbraco.Core.Logging.SerilogExtensions; namespace Umbraco.Core.Logging { /// - /// Implements on top of log4net. + /// Implements on top of Serilog. /// public class Logger : ILogger { /// - /// Initialize a new instance of the class with a log4net configuration file. + /// Initialize a new instance of the class with a configuration file. /// - /// - public Logger(FileInfo log4NetConfigFile) - : this() + /// + public Logger(FileInfo logConfigFile) { - XmlConfigurator.Configure(log4NetConfigFile); + Log.Logger = new LoggerConfiguration() + .ReadFrom.AppSettings(filePath: AppDomain.CurrentDomain.BaseDirectory + logConfigFile) + .CreateLogger(); } - // private for CreateWithDefaultLog4NetConfiguration - private Logger() + public Logger(LoggerConfiguration logConfig) { - // add custom global properties to the log4net context that we can use in our logging output - GlobalContext.Properties["processId"] = Process.GetCurrentProcess().Id; - GlobalContext.Properties["appDomainId"] = AppDomain.CurrentDomain.Id; + //Configure Serilog static global logger with config passed in + Log.Logger = logConfig.CreateLogger(); } /// - /// Creates a logger with the default log4net configuration discovered (i.e. from the web.config). + /// Creates a logger with some pre-definied configuration and remainder from config file /// /// Used by UmbracoApplicationBase to get its logger. - public static Logger CreateWithDefaultLog4NetConfiguration() + public static Logger CreateWithDefaultConfiguration() { - return new Logger(); + var loggerConfig = new LoggerConfiguration(); + loggerConfig + .MinimalConfiguration() + .OutputDefaultTextFile(LogEventLevel.Debug) + .OutputDefaultJsonFile() + .ReadFromConfigFile() + .ReadFromUserConfigFile(); + + return new Logger(loggerConfig); } /// - public void Error(Type reporting, string message, Exception exception = null) + public void Fatal(Type reporting, Exception exception, string message) { - var logger = LogManager.GetLogger(reporting); - if (logger == null) return; + Fatal(reporting, exception, message, null); + } + /// + public void Fatal(Type reporting, Exception exception) + { + Fatal(reporting, exception, string.Empty); + } + + /// + public void Fatal(Type reporting, string message) + { + //Sometimes we need to throw an error without an ex + Fatal(reporting, null, message); + } + + /// + public void Fatal(Type reporting, string messageTemplate, params object[] propertyValues) + { + //Log a structured message WITHOUT an ex + Fatal(reporting, null, messageTemplate, propertyValues); + } + + /// + public void Fatal(Type reporting, Exception exception, string messageTemplate, params object[] propertyValues) + { + ErrorOrFatal(Fatal, exception, ref messageTemplate); + var logger = Log.Logger; + logger?.ForContext(reporting).Fatal(exception, messageTemplate, propertyValues); + } + + /// + public void Error(Type reporting, Exception exception, string message) + { + Error(reporting, exception, message, null); + } + + /// + public void Error(Type reporting, Exception exception) + { + Error(reporting, exception, string.Empty); + } + + /// + public void Error(Type reporting, string message) + { + //Sometimes we need to throw an error without an ex + Error(reporting, null, message); + } + + /// + public void Error(Type reporting, string messageTemplate, params object[] propertyValues) + { + //Log a structured message WITHOUT an ex + Error(reporting, null, messageTemplate, propertyValues); + } + + /// + public void Error(Type reporting, Exception exception, string messageTemplate, params object[] propertyValues) + { + ErrorOrFatal(Error, exception, ref messageTemplate); + var logger = Log.Logger; + logger?.ForContext(reporting).Error(exception, messageTemplate, propertyValues); + } + + private static void ErrorOrFatal(Action logAction, Exception exception, ref string messageTemplate) + { var dump = false; if (IsTimeoutThreadAbortException(exception)) { - message += "\r\nThe thread has been aborted, because the request has timed out."; + messageTemplate += "\r\nThe thread has been aborted, because the request has timed out."; // dump if configured, or if stacktrace contains Monitor.ReliableEnter dump = UmbracoConfig.For.CoreDebug().DumpOnTimeoutThreadAbort || IsMonitorEnterThreadAbortException(exception); @@ -69,23 +137,22 @@ namespace Umbraco.Core.Logging try { var dumped = MiniDump.Dump(withException: true); - message += dumped + messageTemplate += dumped ? "\r\nA minidump was created in App_Data/MiniDump" : "\r\nFailed to create a minidump"; } - catch (Exception e) + catch (Exception ex) { - message += string.Format("\r\nFailed to create a minidump ({0}: {1})", e.GetType().FullName, e.Message); + //Log a new entry (as opposed to appending to same log entry) + logAction(ex.GetType(), ex, "Failed to create a minidump at App_Data/MiniDump ({ExType}: {ExMessage}", + new object[]{ ex.GetType().FullName, ex.Message }); } } - - logger.Error(message, exception); } private static bool IsMonitorEnterThreadAbortException(Exception exception) { - var abort = exception as ThreadAbortException; - if (abort == null) return false; + if (!(exception is ThreadAbortException abort)) return false; var stacktrace = abort.StackTrace; return stacktrace.Contains("System.Threading.Monitor.ReliableEnter"); @@ -93,8 +160,7 @@ namespace Umbraco.Core.Logging private static bool IsTimeoutThreadAbortException(Exception exception) { - var abort = exception as ThreadAbortException; - if (abort == null) return false; + if (!(exception is ThreadAbortException abort)) return false; if (abort.ExceptionState == null) return false; @@ -110,135 +176,67 @@ namespace Umbraco.Core.Logging /// public void Warn(Type reporting, string format) { - var logger = LogManager.GetLogger(reporting); - if (logger == null || logger.IsWarnEnabled == false) return; - logger.Warn(format); + Warn(reporting, null, format); } - + /// - public void Warn(Type reporting, Func messageBuilder) + public void Warn(Type reporting, string messageTemplate, params object[] propertyValues) { - var logger = LogManager.GetLogger(reporting); - if (logger == null || logger.IsWarnEnabled == false) return; - logger.Warn(messageBuilder()); - } - - /// - public void Warn(Type reporting, string format, params object[] args) - { - var logger = LogManager.GetLogger(reporting); - if (logger == null || logger.IsWarnEnabled == false) return; - logger.WarnFormat(format, args); - } - - /// - public void Warn(Type reporting, string format, params Func[] args) - { - var logger = LogManager.GetLogger(reporting); - if (logger == null || logger.IsWarnEnabled == false) return; - logger.WarnFormat(format, args.Select(x => x.Invoke()).ToArray()); + Warn(reporting, null, messageTemplate, propertyValues); } /// public void Warn(Type reporting, Exception exception, string message) { - var logger = LogManager.GetLogger(reporting); - if (logger == null || logger.IsWarnEnabled == false) return; - logger.Warn(message, exception); + Warn(reporting, exception, message, Array.Empty()); } - + /// - public void Warn(Type reporting, Exception exception, Func messageBuilder) + public void Warn(Type reporting, Exception exception, string messageTemplate, params object[] propertyValues) { - var logger = LogManager.GetLogger(reporting); - if (logger == null || logger.IsWarnEnabled == false) return; - logger.Warn(messageBuilder(), exception); - } - - /// - public void Warn(Type reporting, Exception exception, string format, params object[] args) - { - var logger = LogManager.GetLogger(reporting); - if (logger == null || logger.IsWarnEnabled == false) return; - // there is no WarnFormat overload that accepts an exception - // format the message the way log4net would do it (see source code LogImpl.cs) - var message = new SystemStringFormat(CultureInfo.InvariantCulture, format, args); - logger.Warn(message, exception); - } - - /// - public void Warn(Type reporting, Exception exception, string format, params Func[] args) - { - var logger = LogManager.GetLogger(reporting); - if (logger == null || logger.IsWarnEnabled == false) return; - // there is no WarnFormat overload that accepts an exception - // format the message the way log4net would do it (see source code LogImpl.cs) - var message = new SystemStringFormat(CultureInfo.InvariantCulture, format, args.Select(x => x.Invoke()).ToArray()); - logger.Warn(message, exception); + var logger = Log.Logger; + logger?.ForContext(reporting).Warning(exception, messageTemplate, propertyValues); } /// public void Info(Type reporting, string message) { - var logger = LogManager.GetLogger(reporting); - if (logger == null || logger.IsInfoEnabled == false) return; - logger.Info(message); + Info(reporting, message, Array.Empty()); } /// - public void Info(Type reporting, Func generateMessage) + public void Info(Type reporting, string messageTemplate, params object[] propertyValues) { - var logger = LogManager.GetLogger(reporting); - if (logger == null || logger.IsInfoEnabled == false) return; - logger.Info(generateMessage()); - } - - /// - public void Info(Type reporting, string format, params object[] args) - { - var logger = LogManager.GetLogger(reporting); - if (logger == null || logger.IsInfoEnabled == false) return; - logger.InfoFormat(format, args); - } - - /// - public void Info(Type reporting, string format, params Func[] args) - { - var logger = LogManager.GetLogger(reporting); - if (logger == null || logger.IsInfoEnabled == false) return; - logger.InfoFormat(format, args.Select(x => x.Invoke()).ToArray()); + var logger = Log.Logger; + logger?.ForContext(reporting).Information(messageTemplate, propertyValues); } /// public void Debug(Type reporting, string message) { - var logger = LogManager.GetLogger(reporting); - if (logger == null || logger.IsDebugEnabled == false) return; - logger.Debug(message); + Debug(reporting, message, Array.Empty()); + } + + /// + public void Debug(Type reporting, string messageTemplate, params object[] propertyValues) + { + var logger = Log.Logger; + logger?.ForContext(reporting).Debug(messageTemplate, propertyValues); } /// - public void Debug(Type reporting, Func messageBuilder) + public void Verbose(Type reporting, string message) { - var logger = LogManager.GetLogger(reporting); - if (logger == null || logger.IsDebugEnabled == false) return; - logger.Debug(messageBuilder()); + Verbose(reporting, message, Array.Empty()); } /// - public void Debug(Type reporting, string format, params object[] args) + public void Verbose(Type reporting, string messageTemplate, params object[] propertyValues) { - var logger = LogManager.GetLogger(reporting); - if (logger == null || logger.IsDebugEnabled == false) return; - logger.DebugFormat(format, args); + var logger = Log.Logger; + logger?.ForContext(reporting).Verbose(messageTemplate, propertyValues); } - /// - public void Debug(Type reporting, string format, params Func[] args) - { - var logger = LogManager.GetLogger(reporting); - if (logger == null || logger.IsDebugEnabled == false) return; - logger.DebugFormat(format, args.Select(x => x.Invoke()).ToArray()); - } + } } diff --git a/src/Umbraco.Core/Logging/LoggerExtensions.cs b/src/Umbraco.Core/Logging/LoggerExtensions.cs index 4c0a6b026a..c29bcef4f7 100644 --- a/src/Umbraco.Core/Logging/LoggerExtensions.cs +++ b/src/Umbraco.Core/Logging/LoggerExtensions.cs @@ -1,5 +1,4 @@ using System; -using System.Linq; namespace Umbraco.Core.Logging { @@ -9,15 +8,62 @@ namespace Umbraco.Core.Logging public static class LoggerExtensions { /// - /// Logs an error message. + /// Logs an error message /// /// The reporting type. /// The logger. /// A message. /// An exception. - public static void Error(this ILogger logger, string message, Exception exception = null) + public static void Error(this ILogger logger, Exception exception, string message) { - logger.Error(typeof(T), message, exception); + logger.Error(typeof(T), exception, message); + } + + /// + /// Logs an error message with a structured message template + /// + /// The reporting type + /// The logger. + /// A structured message template + /// An exception + /// Message property values + public static void Error(this ILogger logger, Exception exception, string messageTemplate, params object[] propertyValues) + { + logger.Error(typeof(T), exception, messageTemplate, propertyValues); + } + + /// + /// Logs an error message NOTE: This will log an empty message string + /// + /// The reporting type + /// The logger. + /// An exception + public static void Error(this ILogger logger, Exception exception) + { + logger.Error(typeof(T), exception); + } + + /// + /// Logs an error message WITHOUT EX + /// + /// + /// + /// + public static void Error(this ILogger logger, string message) + { + logger.Error(typeof(T), message); + } + + /// + /// Logs an error message - using a structured log message + /// + /// The reporting type + /// The logger. + /// A structured message template + /// Message property values + public static void Error(this ILogger logger, string messageTemplate, params object[] propertyValues) + { + logger.Error(typeof(T), messageTemplate, propertyValues); } /// @@ -32,26 +78,15 @@ namespace Umbraco.Core.Logging } /// - /// Logs a warning message. + /// Logs a warning message with a structured message template /// - /// The reporting type. + /// The reporting type /// The logger. - /// A message builder. - public static void Warn(this ILogger logger, Func messageBuilder) + /// A structured message template + /// Message property values + public static void Warn(this ILogger logger, string messageTemplate, params object[] propertyValues) { - logger.Warn(typeof(T), messageBuilder); - } - - /// - /// Logs a formatted warning message with an exception. - /// - /// The reporting type. - /// The logger. - /// An exception. - /// A message builder. - public static void Warn(this ILogger logger, Exception exception, Func messageBuilder) - { - logger.Warn(typeof(T), exception, messageBuilder); + logger.Warn(typeof(T), messageTemplate, propertyValues); } /// @@ -66,6 +101,19 @@ namespace Umbraco.Core.Logging logger.Warn(typeof(T), exception, message); } + /// + /// Logs a warning message with an exception with a structured message template + /// + /// The reporting type + /// The logger. + /// An exception + /// A structured message template + /// Message property values + public static void Warn(this ILogger logger, Exception exception, string messageTemplate, params object[] propertyValues) + { + logger.Warn(typeof(T), exception, messageTemplate, propertyValues); + } + /// /// Logs an information message. /// @@ -78,14 +126,15 @@ namespace Umbraco.Core.Logging } /// - /// Logs an information message. + /// Logs a information message with a structured message template /// - /// The reporting type. + /// The reporting type /// The logger. - /// A message builder. - public static void Info(this ILogger logger, Func messageBuilder) + /// A structured message template + /// Message property values + public static void Info(this ILogger logger, string messageTemplate, params object[] propertyValues) { - logger.Info(typeof(T), messageBuilder); + logger.Info(typeof(T), messageTemplate, propertyValues); } /// @@ -100,14 +149,66 @@ namespace Umbraco.Core.Logging } /// - /// Logs a debugging message. + /// Logs a debugging message with a structured message template + /// + /// The reporting type + /// The logger. + /// A structured message template + /// Message property values + public static void Debug(this ILogger logger, string messageTemplate, params object[] propertyValues) + { + logger.Debug(typeof(T), messageTemplate, propertyValues); + } + + /// + /// Logs a verbose message. /// /// The reporting type. /// The logger. - /// A message builder. - public static void Debug(this ILogger logger, Func messageBuilder) + /// A message. + public static void Verbose(this ILogger logger, string message) { - logger.Debug(typeof(T), messageBuilder); + logger.Verbose(typeof(T), message); } + + /// + /// Logs a Verbose message with a structured message template + /// + /// The reporting type + /// The logger. + /// A structured message template + /// Message property values + public static void Verbose(this ILogger logger, string messageTemplate, params object[] propertyValues) + { + logger.Verbose(typeof(T), messageTemplate, propertyValues); + } + + + /// + /// Logs a fatal message. + /// + /// The reporting type. + /// The logger. + /// An exception. + /// A message. + public static void Fatal(this ILogger logger, Exception exception, string message) + { + logger.Fatal(typeof(T), exception, message); + } + + + /// + /// Logs a fatal message with a structured message template + /// + /// The reporting type. + /// The logger. + /// An exception. + /// A structured message template + /// Message property values + public static void Fatal(this ILogger logger, Exception exception, string messageTemplate, params object[] propertyValues) + { + logger.Fatal(typeof(T), exception, messageTemplate, propertyValues); + } + } } diff --git a/src/Umbraco.Core/Logging/LoggingEventContext.cs b/src/Umbraco.Core/Logging/LoggingEventContext.cs deleted file mode 100644 index 2dac3c4676..0000000000 --- a/src/Umbraco.Core/Logging/LoggingEventContext.cs +++ /dev/null @@ -1,20 +0,0 @@ -using log4net.Core; - -namespace Umbraco.Core.Logging -{ - /// - /// Borrowed from https://github.com/cjbhaines/Log4Net.Async - will reference Nuget packages directly in v8 - /// - internal sealed class LoggingEventContext - { - public LoggingEventContext(LoggingEvent loggingEvent, object httpContext) - { - LoggingEvent = loggingEvent; - HttpContext = httpContext; - } - - public LoggingEvent LoggingEvent { get; set; } - - public object HttpContext { get; set; } - } -} diff --git a/src/Umbraco.Core/Logging/LoggingEventHelper.cs b/src/Umbraco.Core/Logging/LoggingEventHelper.cs deleted file mode 100644 index a92e557f34..0000000000 --- a/src/Umbraco.Core/Logging/LoggingEventHelper.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using log4net.Core; - -namespace Umbraco.Core.Logging -{ - /// - /// Borrowed from https://github.com/cjbhaines/Log4Net.Async - will reference Nuget packages directly in v8 - /// - internal sealed class LoggingEventHelper - { - // needs to be a seperate class so that location is determined correctly by log4net when required - - private static readonly Type HelperType = typeof(LoggingEventHelper); - private readonly string loggerName; - - public FixFlags Fix { get; set; } - - public LoggingEventHelper(string loggerName, FixFlags fix) - { - this.loggerName = loggerName; - Fix = fix; - } - - public LoggingEvent CreateLoggingEvent(Level level, string message, Exception exception) - { - var loggingEvent = new LoggingEvent(HelperType, null, loggerName, level, message, exception) - { - Fix = Fix - }; - return loggingEvent; - } - } -} diff --git a/src/Umbraco.Core/Logging/OwinLogger.cs b/src/Umbraco.Core/Logging/OwinLogger.cs index a6ae0c332a..5601cb53f2 100644 --- a/src/Umbraco.Core/Logging/OwinLogger.cs +++ b/src/Umbraco.Core/Logging/OwinLogger.cs @@ -26,34 +26,34 @@ namespace Umbraco.Core.Logging switch (eventType) { case TraceEventType.Critical: - _logger.Error(_type.Value, string.Format("Event Id: {0}, state: {1}", eventId, state), exception ?? new Exception("Critical error")); + _logger.Fatal(_type.Value, exception, "[{EventType}] Event Id: {EventId}, State: {State}", eventType, eventId, state); return true; case TraceEventType.Error: - _logger.Error(_type.Value, string.Format("Event Id: {0}, state: {1}", eventId, state), exception ?? new Exception("Error")); + _logger.Error(_type.Value, exception, "[{EventType}] Event Id: {EventId}, State: {State}", eventType, eventId, state); return true; case TraceEventType.Warning: - _logger.Warn(_type.Value, string.Format("Event Id: {0}, state: {1}", eventId, state)); + _logger.Warn(_type.Value, "[{EventType}] Event Id: {EventId}, State: {State}", eventType, eventId, state); return true; case TraceEventType.Information: - _logger.Info(_type.Value, string.Format("Event Id: {0}, state: {1}", eventId, state)); + _logger.Info(_type.Value, "[{EventType}] Event Id: {EventId}, State: {State}", eventType, eventId, state); return true; case TraceEventType.Verbose: - _logger.Debug(_type.Value, string.Format("Event Id: {0}, state: {1}", eventId, state)); + _logger.Debug(_type.Value, "[{EventType}] Event Id: {EventId}, State: {State}", eventType, eventId, state); return true; case TraceEventType.Start: - _logger.Debug(_type.Value, string.Format("Event Id: {0}, state: {1}", eventId, state)); + _logger.Debug(_type.Value, "[{EventType}] Event Id: {EventId}, State: {State}", eventType, eventId, state); return true; case TraceEventType.Stop: - _logger.Debug(_type.Value, string.Format("Event Id: {0}, state: {1}", eventId, state)); + _logger.Debug(_type.Value, "[{EventType}] Event Id: {EventId}, State: {State}", eventType, eventId, state); return true; case TraceEventType.Suspend: - _logger.Debug(_type.Value, string.Format("Event Id: {0}, state: {1}", eventId, state)); + _logger.Debug(_type.Value, "[{EventType}] Event Id: {EventId}, State: {State}", eventType, eventId, state); return true; case TraceEventType.Resume: - _logger.Debug(_type.Value, string.Format("Event Id: {0}, state: {1}", eventId, state)); + _logger.Debug(_type.Value, "[{EventType}] Event Id: {EventId}, State: {State}", eventType, eventId, state); return true; case TraceEventType.Transfer: - _logger.Debug(_type.Value, string.Format("Event Id: {0}, state: {1}", eventId, state)); + _logger.Debug(_type.Value, "[{EventType}] Event Id: {EventId}, State: {State}", eventType, eventId, state); return true; default: throw new ArgumentOutOfRangeException("eventType"); diff --git a/src/Umbraco.Core/Logging/RingBuffer.cs b/src/Umbraco.Core/Logging/RingBuffer.cs deleted file mode 100644 index 18f28faf6b..0000000000 --- a/src/Umbraco.Core/Logging/RingBuffer.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System; - -namespace Umbraco.Core.Logging -{ - /// - /// Borrowed from https://github.com/cjbhaines/Log4Net.Async - will reference Nuget packages directly in v8 - /// - /// - internal sealed class RingBuffer : IQueue - { - private readonly object lockObject = new object(); - private readonly T[] buffer; - private readonly int size; - private int readIndex = 0; - private int writeIndex = 0; - private bool bufferFull = false; - - public int Size { get { return size; } } - - public event Action BufferOverflow; - - public RingBuffer(int size) - { - this.size = size; - buffer = new T[size]; - } - - public void Enqueue(T item) - { - var bufferWasFull = false; - lock (lockObject) - { - buffer[writeIndex] = item; - writeIndex = (++writeIndex) % size; - if (bufferFull) - { - bufferWasFull = true; - readIndex = writeIndex; - } - else if (writeIndex == readIndex) - { - bufferFull = true; - } - } - - if (bufferWasFull) - { - if (BufferOverflow != null) - { - BufferOverflow(this, EventArgs.Empty); - } - } - } - - public bool TryDequeue(out T ret) - { - if (readIndex == writeIndex && !bufferFull) - { - ret = default(T); - return false; - } - lock (lockObject) - { - if (readIndex == writeIndex && !bufferFull) - { - ret = default(T); - return false; - } - - ret = buffer[readIndex]; - buffer[readIndex] = default(T); - readIndex = (++readIndex) % size; - bufferFull = false; - return true; - } - } - } -} diff --git a/src/Umbraco.Core/Logging/RollingFileCleanupAppender.cs b/src/Umbraco.Core/Logging/RollingFileCleanupAppender.cs deleted file mode 100644 index 6be2552296..0000000000 --- a/src/Umbraco.Core/Logging/RollingFileCleanupAppender.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -using System.IO; -using log4net.Appender; -using log4net.Util; - -namespace Umbraco.Core.Logging -{ - /// - /// This class will do the exact same thing as the RollingFileAppender that comes from log4net - /// With the extension, that it is able to do automatic cleanup of the logfiles in the directory where logging happens - /// - /// By specifying the properties MaxLogFileDays and BaseFilePattern, the files will automaticly get deleted when - /// the logger is configured(typically when the app starts). To utilize this appender swap out the type of the rollingFile appender - /// that ships with Umbraco, to be Umbraco.Core.Logging.RollingFileCleanupAppender, and add the maxLogFileDays and baseFilePattern elements - /// to the configuration i.e.: - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public class RollingFileCleanupAppender : RollingFileAppender - { - public int MaxLogFileDays { get; set; } - public string BaseFilePattern { get; set; } - - /// - /// This override will delete logs older than the specified amount of days - /// - /// - /// - protected override void OpenFile(string fileName, bool append) - { - bool cleanup = true; - // Validate settings and input - if (MaxLogFileDays <= 0) - { - LogLog.Warn(typeof(RollingFileCleanupAppender), "Parameter 'MaxLogFileDays' needs to be a positive integer, aborting cleanup"); - cleanup = false; - } - - if (string.IsNullOrWhiteSpace(BaseFilePattern)) - { - LogLog.Warn(typeof(RollingFileCleanupAppender), "Parameter 'BaseFilePattern' is empty, aborting cleanup"); - cleanup = false; - } - // grab the directory we are logging to, as this is were we will search for older logfiles - var logFolder = Path.GetDirectoryName(fileName); - if (Directory.Exists(logFolder) == false) - { - LogLog.Warn(typeof(RollingFileCleanupAppender), string.Format("Directory '{0}' for logfiles does not exist, aborting cleanup", logFolder)); - cleanup = false; - } - // If everything is validated, we can do the actual cleanup - if (cleanup) - { - Cleanup(logFolder); - } - - base.OpenFile(fileName, append); - } - - private void Cleanup(string directoryPath) - { - // only take files that matches the pattern we are using i.e. UmbracoTraceLog.*.txt.* - string[] logFiles = Directory.GetFiles(directoryPath, BaseFilePattern); - LogLog.Debug(typeof(RollingFileCleanupAppender), string.Format("Found {0} files that matches the baseFilePattern: '{1}'", logFiles.Length, BaseFilePattern)); - - foreach (var logFile in logFiles) - { - DateTime lastAccessTime = System.IO.File.GetLastWriteTimeUtc(logFile); - // take the value from the config file - if (lastAccessTime < DateTime.Now.AddDays(-MaxLogFileDays)) - { - LogLog.Debug(typeof(RollingFileCleanupAppender), string.Format("Deleting file {0} as its lastAccessTime is older than {1} days speficied by MaxLogFileDays", logFile, MaxLogFileDays)); - base.DeleteFile(logFile); - } - } - } - } -} diff --git a/src/Umbraco.Core/Logging/SerilogExtensions/Log4NetLevelMapperEnricher.cs b/src/Umbraco.Core/Logging/SerilogExtensions/Log4NetLevelMapperEnricher.cs new file mode 100644 index 0000000000..681f7b4936 --- /dev/null +++ b/src/Umbraco.Core/Logging/SerilogExtensions/Log4NetLevelMapperEnricher.cs @@ -0,0 +1,49 @@ +using Serilog.Core; +using Serilog.Events; + +namespace Umbraco.Core.Logging.SerilogExtensions +{ + /// + /// This is used to create a new property in Logs called 'Log4NetLevel' + /// So that we can map Serilog levels to Log4Net levels - so log files stay consistent + /// + internal class Log4NetLevelMapperEnricher : ILogEventEnricher + { + public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) + { + var log4NetLevel = string.Empty; + + switch (logEvent.Level) + { + case LogEventLevel.Debug: + log4NetLevel = "DEBUG"; + break; + + case LogEventLevel.Error: + log4NetLevel = "ERROR"; + break; + + case LogEventLevel.Fatal: + log4NetLevel = "FATAL"; + break; + + case LogEventLevel.Information: + log4NetLevel = "INFO"; + break; + + case LogEventLevel.Verbose: + log4NetLevel = "ALL"; + break; + + case LogEventLevel.Warning: + log4NetLevel = "WARN"; + break; + } + + //Pad string so that all log levels are 5 chars long (needed to keep the txt log file lined up nicely) + log4NetLevel = log4NetLevel.PadRight(5); + + logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("Log4NetLevel", log4NetLevel)); + } + } +} diff --git a/src/Umbraco.Core/Logging/SerilogExtensions/LoggerConfigExtensions.cs b/src/Umbraco.Core/Logging/SerilogExtensions/LoggerConfigExtensions.cs new file mode 100644 index 0000000000..150fb0395c --- /dev/null +++ b/src/Umbraco.Core/Logging/SerilogExtensions/LoggerConfigExtensions.cs @@ -0,0 +1,103 @@ +using System; +using System.Web; +using Serilog; +using Serilog.Events; +using Serilog.Formatting.Compact; + +namespace Umbraco.Core.Logging.SerilogExtensions +{ + public static class LoggerConfigExtensions + { + /// + /// This configures Serilog with some defaults + /// Such as adding ProcessID, Thread, AppDomain etc + /// It is highly recommended that you keep/use this default in your own logging config customizations + /// + /// A Serilog LoggerConfiguration + public static LoggerConfiguration MinimalConfiguration(this LoggerConfiguration logConfig) + { + Serilog.Debugging.SelfLog.Enable(msg => System.Diagnostics.Debug.WriteLine(msg)); + + //Set this environment variable - so that it can be used in external config file + //add key="serilog:write-to:RollingFile.pathFormat" value="%BASEDIR%\logs\log.txt" /> + Environment.SetEnvironmentVariable("BASEDIR", AppDomain.CurrentDomain.BaseDirectory, EnvironmentVariableTarget.Process); + + logConfig.MinimumLevel.Verbose() //Set to highest level of logging (as any sinks may want to restrict it to Errors only) + .Enrich.WithProcessId() + .Enrich.WithProcessName() + .Enrich.WithThreadId() + .Enrich.WithProperty("AppDomainId", AppDomain.CurrentDomain.Id) + .Enrich.WithProperty("AppDomainAppId", HttpRuntime.AppDomainAppId.ReplaceNonAlphanumericChars(string.Empty)) + .Enrich.WithProperty("MachineName", Environment.MachineName) + .Enrich.With(); + + return logConfig; + } + + /// + /// Outputs a .txt format log at /App_Data/Logs/ + /// + /// A Serilog LoggerConfiguration + /// The log level you wish the JSON file to collect - default is Verbose (highest) + /// The number of days to keep log files. Default is set to null which means all logs are kept + public static LoggerConfiguration OutputDefaultTextFile(this LoggerConfiguration logConfig, LogEventLevel minimumLevel = LogEventLevel.Verbose, int? retainedFileCount = null) + { + //Main .txt logfile - in similar format to older Log4Net output + //Ends with ..txt as Date is inserted before file extension substring + logConfig.WriteTo.File($@"{AppDomain.CurrentDomain.BaseDirectory}\App_Data\Logs\UmbracoTraceLog.{Environment.MachineName}..txt", + shared: true, + rollingInterval: RollingInterval.Day, + restrictedToMinimumLevel: minimumLevel, + retainedFileCountLimit: null, //Setting to null means we keep all files - default is 31 days + outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss,fff} [P{ProcessId}/D{AppDomainId}/T{ThreadId}] {Log4NetLevel} {SourceContext} - {Message:lj}{NewLine}{Exception}"); + + return logConfig; + } + + /// + /// Outputs a CLEF format JSON log at /App_Data/Logs/ + /// + /// A Serilog LoggerConfiguration + /// The log level you wish the JSON file to collect - default is Verbose (highest) + /// The number of days to keep log files. Default is set to null which means all logs are kept + public static LoggerConfiguration OutputDefaultJsonFile(this LoggerConfiguration logConfig, LogEventLevel minimumLevel = LogEventLevel.Verbose, int? retainedFileCount = null) + { + //.clef format (Compact log event format, that can be imported into local SEQ & will make searching/filtering logs easier) + //Ends with ..txt as Date is inserted before file extension substring + logConfig.WriteTo.File(new CompactJsonFormatter(), $@"{AppDomain.CurrentDomain.BaseDirectory}\App_Data\Logs\UmbracoTraceLog.{Environment.MachineName}..json", + shared: true, + rollingInterval: RollingInterval.Day, //Create a new JSON file every day + retainedFileCountLimit: retainedFileCount, //Setting to null means we keep all files - default is 31 days + restrictedToMinimumLevel: minimumLevel); + + return logConfig; + } + + /// + /// Reads settings from /config/serilog.config + /// That allows the main logging pipeline to be configured + /// + /// A Serilog LoggerConfiguration + public static LoggerConfiguration ReadFromConfigFile(this LoggerConfiguration logConfig) + { + //Read from main serilog.config file + logConfig.ReadFrom.AppSettings(filePath: AppDomain.CurrentDomain.BaseDirectory + @"\config\serilog.config"); + + return logConfig; + } + + /// + /// Reads settings from /config/serilog.user.config + /// That allows a seperate logging pipeline to be configured that wil not affect the main Umbraco log + /// + /// A Serilog LoggerConfiguration + public static LoggerConfiguration ReadFromUserConfigFile(this LoggerConfiguration logConfig) + { + //A nested logger - where any user configured sinks via config can not effect the main 'umbraco' logger above + logConfig.WriteTo.Logger(cfg => + cfg.ReadFrom.AppSettings(filePath: AppDomain.CurrentDomain.BaseDirectory + @"\config\serilog.user.config")); + + return logConfig; + } + } +} diff --git a/src/Umbraco.Core/MainDom.cs b/src/Umbraco.Core/MainDom.cs index 5fcd9ee072..eb036fd441 100644 --- a/src/Umbraco.Core/MainDom.cs +++ b/src/Umbraco.Core/MainDom.cs @@ -117,7 +117,7 @@ namespace Umbraco.Core lock (_locko) { - _logger.Debug(() => "Signaled" + (_signaled ? " (again)" : "") + " (" + source + ")."); + _logger.Debug("Signaled {Signaled} ({SignalSource})", _signaled ? "(again)" : string.Empty, source); if (_signaled) return; if (_isMainDom == false) return; // probably not needed _signaled = true; @@ -125,7 +125,7 @@ namespace Umbraco.Core try { - _logger.Info("Stopping."); + _logger.Info("Stopping ({SignalSource})", source); foreach (var callback in _callbacks.OrderBy(x => x.Key).Select(x => x.Value)) { try @@ -134,19 +134,19 @@ namespace Umbraco.Core } catch (Exception e) { - _logger.Error("Error while running callback, remaining callbacks will not run.", e); + _logger.Error(e, "Error while running callback, remaining callbacks will not run."); throw; } } - _logger.Debug("Stopped."); + _logger.Debug("Stopped ({SignalSource})", source); } finally { // in any case... _isMainDom = false; _asyncLocker.Dispose(); - _logger.Info("Released."); + _logger.Info("Released ({SignalSource})", source); } } diff --git a/src/Umbraco.Core/Manifest/ManifestParser.cs b/src/Umbraco.Core/Manifest/ManifestParser.cs index adf3418fb0..e2363e314f 100644 --- a/src/Umbraco.Core/Manifest/ManifestParser.cs +++ b/src/Umbraco.Core/Manifest/ManifestParser.cs @@ -81,7 +81,7 @@ namespace Umbraco.Core.Manifest } catch (Exception e) { - _logger.Error($"Failed to parse manifest at \"{path}\", ignoring.", e); + _logger.Error(e, "Failed to parse manifest at '{Path}', ignoring.", path); } } diff --git a/src/Umbraco.Core/Manifest/ManifestWatcher.cs b/src/Umbraco.Core/Manifest/ManifestWatcher.cs index 3bc70e2d78..4c0ddbf822 100644 --- a/src/Umbraco.Core/Manifest/ManifestWatcher.cs +++ b/src/Umbraco.Core/Manifest/ManifestWatcher.cs @@ -54,7 +54,7 @@ namespace Umbraco.Core.Manifest if (_isRestarting) return; _isRestarting = true; - _logger.Info("manifest has changed, app pool is restarting (" + e.FullPath + ")"); + _logger.Info("Manifest has changed, app pool is restarting ({Path})", e.FullPath); HttpRuntime.UnloadAppDomain(); Dispose(); // uh? if the app restarts then this should be disposed anyways? } diff --git a/src/Umbraco.Core/Media/UploadAutoFillProperties.cs b/src/Umbraco.Core/Media/UploadAutoFillProperties.cs index 4ab2bf7a7c..2045e947ac 100644 --- a/src/Umbraco.Core/Media/UploadAutoFillProperties.cs +++ b/src/Umbraco.Core/Media/UploadAutoFillProperties.cs @@ -153,7 +153,7 @@ namespace Umbraco.Core.Media } catch (Exception ex) { - _logger.Error(typeof(UploadAutoFillProperties), $"Could not populate upload auto-fill properties for file \"{filepath}\".", ex); + _logger.Error(typeof(UploadAutoFillProperties), ex, "Could not populate upload auto-fill properties for file '{File}'.", filepath); ResetProperties(content, autoFillConfig, culture, segment); } } diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseBuilder.cs b/src/Umbraco.Core/Migrations/Install/DatabaseBuilder.cs index 9e2af56b7b..4986eeab02 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseBuilder.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseBuilder.cs @@ -309,7 +309,7 @@ namespace Umbraco.Core.Migrations.Install { var source = connectionStrings.Attribute("configSource").Value; var configFile = IOHelper.MapPath($"{SystemDirectories.Root}/{source}"); - logger.Info(() => $"Storing ConnectionString in {configFile}"); + logger.Info("Storing ConnectionString in {ConfigFile}", configFile); if (File.Exists(configFile)) { xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace); @@ -335,7 +335,7 @@ namespace Umbraco.Core.Migrations.Install } xml.Save(fileName, SaveOptions.DisableFormatting); - logger.Info(() => $"Configured a new ConnectionString using the '{providerName}' provider."); + logger.Info("Configured a new ConnectionString using the '{ProviderName}' provider.", providerName); } internal bool IsConnectionStringConfigured(ConnectionStringSettings databaseSettings) @@ -500,7 +500,7 @@ namespace Umbraco.Core.Migrations.Install message = message + "

Installation completed!

"; //now that everything is done, we need to determine the version of SQL server that is executing - _logger.Info(() => $"Database configuration status: {message}"); + _logger.Info("Database configuration status: {DbConfigStatus}", message); return new Result { Message = message, Success = true, Percentage = "100" }; } @@ -589,7 +589,7 @@ namespace Umbraco.Core.Migrations.Install //now that everything is done, we need to determine the version of SQL server that is executing - _logger.Info(() => $"Database configuration status: {message}"); + _logger.Info("Database configuration status: {DbConfigStatus}", message); return new Result { Message = message, Success = true, Percentage = "100" }; } @@ -658,11 +658,11 @@ namespace Umbraco.Core.Migrations.Install private Result HandleInstallException(Exception ex) { - _logger.Error("Database configuration failed", ex); + _logger.Error(ex, "Database configuration failed"); if (_databaseSchemaValidationResult != null) { - _logger.Info(() => $"The database schema validation produced the following summary: {Environment.NewLine}{_databaseSchemaValidationResult.GetSummary()}"); + _logger.Info("The database schema validation produced the following summary: {DbSchemaSummary}", _databaseSchemaValidationResult.GetSummary()); } return new Result diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs index be9a1b9b74..ac74e6ee66 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs @@ -29,7 +29,7 @@ namespace Umbraco.Core.Migrations.Install /// Name of the table to create base data for public void InitializeBaseData(string tableName) { - _logger.Info(() => $"Creating data in table {tableName}"); + _logger.Info("Creating data in {TableName}", tableName); if (tableName.Equals(Constants.DatabaseSchema.Tables.Node)) CreateNodeData(); @@ -76,7 +76,7 @@ namespace Umbraco.Core.Migrations.Install if (tableName.Equals(Constants.DatabaseSchema.Tables.KeyValue)) CreateKeyValueData(); - _logger.Info(() => $"Done creating table {tableName} data."); + _logger.Info("Done creating table {TableName} data.", tableName); } private void CreateNodeData() diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseSchemaCreator.cs b/src/Umbraco.Core/Migrations/Install/DatabaseSchemaCreator.cs index 14ffcda2ec..ae3f95ec4d 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseSchemaCreator.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseSchemaCreator.cs @@ -98,7 +98,7 @@ namespace Umbraco.Core.Migrations.Install var tableNameAttribute = table.FirstAttribute(); var tableName = tableNameAttribute == null ? table.Name : tableNameAttribute.Value; - _logger.Info(() => $"Uninstall {tableName}"); + _logger.Info("Uninstall {TableName}", tableName); try { @@ -109,7 +109,7 @@ namespace Umbraco.Core.Migrations.Install { //swallow this for now, not sure how best to handle this with diff databases... though this is internal // and only used for unit tests. If this fails its because the table doesn't exist... generally! - _logger.Error("Could not drop table " + tableName, ex); + _logger.Error(ex, "Could not drop table {TableName}", tableName); } } } @@ -376,13 +376,13 @@ namespace Umbraco.Core.Migrations.Install { //Execute the Create Table sql var created = _database.Execute(new Sql(createSql)); - _logger.Info(() => $"Create Table '{tableName}' ({created}):\n {createSql}"); + _logger.Info("Create Table '{TableName}' ({Created}): \n {Sql}", tableName, created, createSql); //If any statements exists for the primary key execute them here if (string.IsNullOrEmpty(createPrimaryKeySql) == false) { var createdPk = _database.Execute(new Sql(createPrimaryKeySql)); - _logger.Info(() => $"Create Primary Key ({createdPk}):\n {createPrimaryKeySql}"); + _logger.Info("Create Primary Key ({CreatedPk}):\n {Sql}", createdPk, createPrimaryKeySql); } //Turn on identity insert if db provider is not mysql @@ -408,21 +408,21 @@ namespace Umbraco.Core.Migrations.Install foreach (var sql in indexSql) { var createdIndex = _database.Execute(new Sql(sql)); - _logger.Info(() => $"Create Index ({createdIndex}):\n {sql}"); + _logger.Info("Create Index ({CreatedIndex}):\n {Sql}", createdIndex, sql); } //Loop through foreignkey statements and execute sql foreach (var sql in foreignSql) { var createdFk = _database.Execute(new Sql(sql)); - _logger.Info(() => $"Create Foreign Key ({createdFk}):\n {sql}"); + _logger.Info("Create Foreign Key ({CreatedFk}):\n {Sql}", createdFk, sql); } transaction.Complete(); } } - _logger.Info(() => $"Created table '{tableName}'"); + _logger.Info("Created table '{TableName}'", tableName); } public void DropTable(string tableName) diff --git a/src/Umbraco.Core/Migrations/MigrationExpressionBase.cs b/src/Umbraco.Core/Migrations/MigrationExpressionBase.cs index 351d9e9f8a..f1c535b466 100644 --- a/src/Umbraco.Core/Migrations/MigrationExpressionBase.cs +++ b/src/Umbraco.Core/Migrations/MigrationExpressionBase.cs @@ -55,7 +55,7 @@ namespace Umbraco.Core.Migrations if (string.IsNullOrWhiteSpace(sql)) { - Logger.Info(GetType(), $"SQL [{Context.Index}]: "); + Logger.Info(GetType(), "SQL [{ContextIndex}: ", Context.Index); } else { @@ -90,7 +90,7 @@ namespace Umbraco.Core.Migrations private void ExecuteStatement(StringBuilder stmtBuilder) { var stmt = stmtBuilder.ToString(); - Logger.Info(GetType(), $"SQL [{Context.Index}]: {stmt}"); + Logger.Info(GetType(), "SQL [{ContextIndex}]: {Sql}", Context.Index, stmt); Database.Execute(stmt); stmtBuilder.Clear(); } diff --git a/src/Umbraco.Core/Migrations/MigrationPlan.cs b/src/Umbraco.Core/Migrations/MigrationPlan.cs index bea98feac3..5c999ad6ef 100644 --- a/src/Umbraco.Core/Migrations/MigrationPlan.cs +++ b/src/Umbraco.Core/Migrations/MigrationPlan.cs @@ -269,14 +269,11 @@ namespace Umbraco.Core.Migrations if (_migrationBuilder == null || _logger == null) throw new InvalidOperationException("Cannot execute a non-executing plan."); - _logger.Info(() => $"Starting \"{Name}\"..."); + _logger.Info("Starting '{MigrationName}'...", Name); + var origState = fromState ?? string.Empty; - _logger.Info(() => - { - var info = "At " + (string.IsNullOrWhiteSpace(origState) ? "origin" : ("\"" + origState + "\"")) + "."; - return info.Replace("{", "{{").Replace("}", "}}"); // stupid log4net - }); + _logger.Info("At {OrigState}", string.IsNullOrWhiteSpace(origState) ? "origin": origState); if (!_transitions.TryGetValue(origState, out var transition)) throw new Exception($"Unknown state \"{origState}\"."); @@ -291,7 +288,7 @@ namespace Umbraco.Core.Migrations var nextState = transition.TargetState; origState = nextState; - _logger.Info(() => $"At \"{origState}\"."); + _logger.Info("At {OrigState}", origState); if (!_transitions.TryGetValue(origState, out transition)) throw new Exception($"Unknown state \"{origState}\"."); diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/RefactorXmlColumns.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/RefactorXmlColumns.cs index 0becdc5a8c..db8f95bf71 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/RefactorXmlColumns.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/RefactorXmlColumns.cs @@ -37,7 +37,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 var keyName = c.Item3.ToLowerInvariant(); if (dups.Contains(keyName)) { - Logger.Warn(() => $"Duplicate constraint {c.Item3}"); + Logger.Warn("Duplicate constraint '{Constraint}'", c.Item3); continue; } dups.Add(keyName); diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs index caa7a2a3e4..dd379e02f8 100644 --- a/src/Umbraco.Core/Models/Content.cs +++ b/src/Umbraco.Core/Models/Content.cs @@ -32,6 +32,7 @@ namespace Umbraco.Core.Models /// Name of the content /// Parent object /// ContentType for the current Content object + /// An optional culture. public Content(string name, IContent parent, IContentType contentType, string culture = null) : this(name, parent, contentType, new PropertyCollection(), culture) { } @@ -43,6 +44,7 @@ namespace Umbraco.Core.Models /// Parent object /// ContentType for the current Content object /// Collection of properties + /// An optional culture. public Content(string name, IContent parent, IContentType contentType, PropertyCollection properties, string culture = null) : base(name, parent, contentType, properties, culture) { @@ -57,6 +59,7 @@ namespace Umbraco.Core.Models /// Name of the content /// Id of the Parent content /// ContentType for the current Content object + /// An optional culture. public Content(string name, int parentId, IContentType contentType, string culture = null) : this(name, parentId, contentType, new PropertyCollection(), culture) { } @@ -68,6 +71,7 @@ namespace Umbraco.Core.Models /// Id of the Parent content /// ContentType for the current Content object /// Collection of properties + /// An optional culture. public Content(string name, int parentId, IContentType contentType, PropertyCollection properties, string culture = null) : base(name, parentId, contentType, properties, culture) { @@ -213,23 +217,23 @@ namespace Umbraco.Core.Models [IgnoreDataMember] public IEnumerable PublishedCultures => _publishInfos?.Keys ?? Enumerable.Empty(); - //fixme should this return false if ID == 0? - //fixme should this return false if IsCultureAvailable(culture) is false? /// public bool IsCulturePublished(string culture) + // just check _publishInfos + // a non-available culture could not become published anyways => _publishInfos != null && _publishInfos.ContainsKey(culture); - //fixme should this return false if ID == 0? - //fixme should this return false if IsCultureAvailable(culture) is false? /// public bool WasCulturePublished(string culture) + // just check _publishInfosOrig - a copy of _publishInfos + // a non-available culture could not become published anyways => _publishInfosOrig != null && _publishInfosOrig.ContainsKey(culture); - //fixme should this return false if ID == 0? - //fixme should this return false if IsCultureAvailable(culture) is false? /// public bool IsCultureEdited(string culture) - => !IsCulturePublished(culture) || (_editedCultures != null && _editedCultures.Contains(culture)); + => IsCultureAvailable(culture) && // is available, and + (!IsCulturePublished(culture) || // is not published, or + (_editedCultures != null && _editedCultures.Contains(culture))); // is edited /// [IgnoreDataMember] diff --git a/src/Umbraco.Core/Models/IContent.cs b/src/Umbraco.Core/Models/IContent.cs index 9e79a75e25..5910d01d34 100644 --- a/src/Umbraco.Core/Models/IContent.cs +++ b/src/Umbraco.Core/Models/IContent.cs @@ -87,6 +87,8 @@ namespace Umbraco.Core.Models /// A culture becomes published whenever values for this culture are published, /// and the content published name for this culture is non-null. It becomes non-published /// whenever values for this culture are unpublished. + /// A culture becomes published as soon as PublishCulture has been invoked, + /// even though the document might now have been saved yet (and can have no identity). /// bool IsCulturePublished(string culture); @@ -107,8 +109,9 @@ namespace Umbraco.Core.Models /// Gets a value indicated whether a given culture is edited. ///
/// - /// A culture is edited when it is not published, or when it is published but - /// it has changes. + /// A culture is edited when it is available, and not published or published but + /// with changes. + /// A culture can be edited even though the document might now have been saved yet (and can have no identity). /// bool IsCultureEdited(string culture); diff --git a/src/Umbraco.Core/Models/MediaExtensions.cs b/src/Umbraco.Core/Models/MediaExtensions.cs index 1f219d5e10..f510377c09 100644 --- a/src/Umbraco.Core/Models/MediaExtensions.cs +++ b/src/Umbraco.Core/Models/MediaExtensions.cs @@ -41,7 +41,7 @@ namespace Umbraco.Core.Models } catch (Exception ex) { - logger.Error("Could not parse the string " + jsonString + " to a json object", ex); + logger.Error(ex, "Could not parse the string '{JsonString}' to a json object", jsonString); return string.Empty; } } diff --git a/src/Umbraco.Core/Models/Member.cs b/src/Umbraco.Core/Models/Member.cs index e0d52f7077..7576f01ce0 100644 --- a/src/Umbraco.Core/Models/Member.cs +++ b/src/Umbraco.Core/Models/Member.cs @@ -552,9 +552,14 @@ namespace Umbraco.Core.Models private Attempt WarnIfPropertyTypeNotFoundOnGet(string propertyAlias, string propertyName, T defaultVal) { void DoLog(string logPropertyAlias, string logPropertyName) - => Current.Logger.Warn($"Trying to access the '{logPropertyName}' property on " + typeof(Member) - + $" but the {logPropertyAlias} property does not exist on the member type so a default value is returned. Ensure that you have a property type with alias: " - + logPropertyAlias + $" configured on your member type in order to use the '{logPropertyName}' property on the model correctly."); + { + Current.Logger.Warn("Trying to access the '{PropertyName}' property on '{MemberType}' " + + "but the {PropertyAlias} property does not exist on the member type so a default value is returned. " + + "Ensure that you have a property type with alias: {PropertyAlias} configured on your member type in order to use the '{PropertyName}' property on the model correctly.", + logPropertyName, + typeof(Member), + logPropertyAlias); + } // if the property doesn't exist, if (Properties.Contains(propertyAlias) == false) @@ -572,8 +577,13 @@ namespace Umbraco.Core.Models private bool WarnIfPropertyTypeNotFoundOnSet(string propertyAlias, string propertyName) { void DoLog(string logPropertyAlias, string logPropertyName) - => Current.Logger.Warn($"An attempt was made to set a value on the property '{logPropertyName}' on type " + typeof(Member) - + $" but the property type {logPropertyAlias} does not exist on the member type, ensure that this property type exists so that setting this property works correctly."); + { + Current.Logger.Warn("An attempt was made to set a value on the property '{PropertyName}' on type '{MemberType}' but the " + + "property type {PropertyAlias} does not exist on the member type, ensure that this property type exists so that setting this property works correctly.", + logPropertyName, + typeof(Member), + logPropertyAlias); + } // if the property doesn't exist, if (Properties.Contains(propertyAlias) == false) diff --git a/src/Umbraco.Core/Models/PathValidationExtensions.cs b/src/Umbraco.Core/Models/PathValidationExtensions.cs index 74c2c9faa5..2db954b316 100644 --- a/src/Umbraco.Core/Models/PathValidationExtensions.cs +++ b/src/Umbraco.Core/Models/PathValidationExtensions.cs @@ -88,7 +88,7 @@ namespace Umbraco.Core.Models if (entity.ValidatePath() == false) { - logger.Warn(typeof(PathValidationExtensions), $"The content item {entity.Id} has an invalid path: {entity.Path} with parentID: {entity.ParentId}"); + logger.Warn(typeof(PathValidationExtensions), "The content item {EntityId} has an invalid path: {EntityPath} with parentID: {EntityParentId}", entity.Id, entity.Path, entity.ParentId); if (entity.ParentId == -1) { entity.Path = string.Concat("-1,", entity.Id); @@ -112,4 +112,4 @@ namespace Umbraco.Core.Models } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Core/Models/PropertyTagsExtensions.cs b/src/Umbraco.Core/Models/PropertyTagsExtensions.cs index b0e0d0bd9c..26779161a1 100644 --- a/src/Umbraco.Core/Models/PropertyTagsExtensions.cs +++ b/src/Umbraco.Core/Models/PropertyTagsExtensions.cs @@ -225,7 +225,7 @@ namespace Umbraco.Core.Models } catch (Exception ex) { - Current.Logger.Warn(typeof(PropertyTagsExtensions), ex, "Could not automatically convert stored json value to an enumerable string"); + Current.Logger.Warn(typeof(PropertyTagsExtensions), ex, "Could not automatically convert stored json value to an enumerable string '{Json}'", value.ToString()); } break; diff --git a/src/Umbraco.Core/Packaging/PackageBinaryInspector.cs b/src/Umbraco.Core/Packaging/PackageBinaryInspector.cs index b392aca289..7cacb30bd3 100644 --- a/src/Umbraco.Core/Packaging/PackageBinaryInspector.cs +++ b/src/Umbraco.Core/Packaging/PackageBinaryInspector.cs @@ -192,7 +192,7 @@ namespace Umbraco.Core.Packaging assemblyName.Name, "' see error log for full details.")); assembliesWithErrors.Add(a); - Current.Logger.Error("An error occurred scanning package assemblies", ex); + Current.Logger.Error(ex, "An error occurred scanning package assembly '{AssemblyName}'", assemblyName.FullName); } } } @@ -236,7 +236,7 @@ namespace Umbraco.Core.Packaging a.GetName().Name, "' see error log for full details.")); assembliesWithErrors.Add(a); - Current.Logger.Error("An error occurred scanning package assemblies", ex); + Current.Logger.Error(ex, "An error occurred scanning package assembly '{AssemblyName}'", a.GetName().FullName); } } diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs index 13812662bd..2e0139aa30 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs @@ -487,10 +487,9 @@ namespace Umbraco.Core.Persistence.Repositories.Implement if (result.ContainsKey(temp.VersionId)) { - var msg = $"The query returned multiple property sets for content {temp.Id}, {temp.ContentType.Name}"; if (ContentRepositoryBase.ThrowOnWarning) - throw new InvalidOperationException(msg); - Logger.Warn>(msg); + throw new InvalidOperationException($"The query returned multiple property sets for content {temp.Id}, {temp.ContentType.Name}"); + Logger.Warn>("The query returned multiple property sets for content {ContentId}, {ContentTypeName}", temp.Id, temp.ContentType.Name); } result[temp.VersionId] = new PropertyCollection(properties); diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepository.cs index 8ba25b2a50..aa61383f85 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepository.cs @@ -227,10 +227,9 @@ namespace Umbraco.Core.Persistence.Repositories.Implement { if (string.IsNullOrWhiteSpace(entity.Alias)) { - var m = $"ContentType '{entity.Name}' cannot have an empty Alias. This is most likely due to invalid characters stripped from the Alias."; - var e = new Exception(m); - Logger.Error(m, e); - throw e; + var ex = new Exception($"ContentType '{entity.Name}' cannot have an empty Alias. This is most likely due to invalid characters stripped from the Alias."); + Logger.Error("ContentType '{EntityName}' cannot have an empty Alias. This is most likely due to invalid characters stripped from the Alias.", entity.Name); + throw ex; } ((ContentType)entity).AddingEntity(); diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs index 9a077a320e..555fc56157 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs @@ -521,10 +521,12 @@ AND umbracoNode.id <> @id", { if (string.IsNullOrWhiteSpace(pt.Alias)) { - var m = $"Property Type '{pt.Name}' cannot have an empty Alias. This is most likely due to invalid characters stripped from the Alias."; - var e = new InvalidOperationException(m); - Logger.Error>(m, e); - throw e; + var ex = new InvalidOperationException($"Property Type '{pt.Name}' cannot have an empty Alias. This is most likely due to invalid characters stripped from the Alias."); + + Logger.Error>("Property Type '{PropertyTypeName}' cannot have an empty Alias. This is most likely due to invalid characters stripped from the Alias.", + pt.Name); + + throw ex; } } @@ -532,10 +534,13 @@ AND umbracoNode.id <> @id", { if (string.IsNullOrWhiteSpace(entity.Alias)) { - var m = $"{typeof(TEntity).Name} '{entity.Name}' cannot have an empty Alias. This is most likely due to invalid characters stripped from the Alias."; - var e = new InvalidOperationException(m); - Logger.Error>(m, e); - throw e; + var ex = new InvalidOperationException($"{typeof(TEntity).Name} '{entity.Name}' cannot have an empty Alias. This is most likely due to invalid characters stripped from the Alias."); + + Logger.Error>("{EntityTypeName} '{EntityName}' cannot have an empty Alias. This is most likely due to invalid characters stripped from the Alias.", + typeof(TEntity).Name, + entity.Name); + + throw ex; } } @@ -561,7 +566,7 @@ AND umbracoNode.id <> @id", } else { - Logger.Warn>(() => $"Could not assign a data type for the property type {propertyType.Alias} since no data type was found with a property editor {propertyType.PropertyEditorAlias}"); + Logger.Warn>("Could not assign a data type for the property type {PropertyTypeAlias} since no data type was found with a property editor {PropertyEditorAlias}", propertyType.Alias, propertyType.PropertyEditorAlias); } } } diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs index 093723cea5..28c0b0dec6 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs @@ -1073,7 +1073,10 @@ namespace Umbraco.Core.Persistence.Repositories.Implement NodeId = content.Id, LanguageId = LanguageRepository.GetIdByIsoCode(culture) ?? throw new InvalidOperationException("Not a valid culture."), Culture = culture, - Edited = !content.IsCulturePublished(culture) || (editedCultures != null && editedCultures.Contains(culture)) // if not published, always edited + + // if not published, always edited + // no need to check for availability: it *is* available since it is in content.CultureNames + Edited = !content.IsCulturePublished(culture) || (editedCultures != null && editedCultures.Contains(culture)) }; } diff --git a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs index fc967da9bf..4ff0545281 100644 --- a/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs +++ b/src/Umbraco.Core/Persistence/SqlSyntax/MySqlSyntaxProvider.cs @@ -388,7 +388,7 @@ ORDER BY TABLE_NAME, INDEX_NAME", } catch (Exception ex) { - _logger.Error("Error querying for lower_case support", ex); + _logger.Error(ex, "Error querying for lower_case support"); } finally { diff --git a/src/Umbraco.Core/Persistence/UmbracoDatabase.cs b/src/Umbraco.Core/Persistence/UmbracoDatabase.cs index 0f337595fe..64e4c0adca 100644 --- a/src/Umbraco.Core/Persistence/UmbracoDatabase.cs +++ b/src/Umbraco.Core/Persistence/UmbracoDatabase.cs @@ -190,13 +190,13 @@ namespace Umbraco.Core.Persistence } #endif - protected override void OnException(Exception x) + protected override void OnException(Exception ex) { - _logger.Error("Exception (" + InstanceId + ").", x); - _logger.Debug(() => "At:\r\n" + Environment.StackTrace); + _logger.Error(ex, "Exception ({InstanceId}).", InstanceId); + _logger.Debug("At:\r\n{StackTrace}", Environment.StackTrace); if (EnableSqlTrace == false) - _logger.Debug(() => "Sql:\r\n" + CommandToString(LastSQL, LastArgs)); - base.OnException(x); + _logger.Debug("Sql:\r\n{Sql}", CommandToString(LastSQL, LastArgs)); + base.OnException(ex); } private DbCommand _cmd; @@ -208,7 +208,7 @@ namespace Umbraco.Core.Persistence cmd.CommandTimeout = cmd.Connection.ConnectionTimeout; if (EnableSqlTrace) - _logger.Debug(() => CommandToString(cmd).Replace("{", "{{").Replace("}", "}}")); // fixme these escapes should be builtin + _logger.Debug("SQL Trace:\r\n{Sql}", CommandToString(cmd).Replace("{", "{{").Replace("}", "}}")); // fixme these escapes should be builtin #if DEBUG_DATABASES // detects whether the command is already in use (eg still has an open reader...) diff --git a/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs b/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs index e8d16fcd62..912bf1c367 100644 --- a/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs @@ -261,7 +261,7 @@ namespace Umbraco.Core.PropertyEditors var result = TryConvertValueToCrlType(editorValue.Value); if (result.Success == false) { - Current.Logger.Warn(() => $"The value {editorValue.Value} cannot be converted to the type {ValueTypes.ToStorageType(ValueType)}"); + Current.Logger.Warn("The value {EditorValue} cannot be converted to the type {StorageTypeValue}", editorValue.Value, ValueTypes.ToStorageType(ValueType)); return null; } return result.Result; diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/GridValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/GridValueConverter.cs index 5a642bedc7..2131764ad6 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/GridValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/GridValueConverter.cs @@ -100,7 +100,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters } catch (Exception ex) { - Current.Logger.Error("Could not parse the string " + sourceString + " to a json object", ex); + Current.Logger.Error(ex, "Could not parse the string '{JsonString}' to a json object", sourceString); } } diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/ImageCropperValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/ImageCropperValueConverter.cs index 413e66afb7..79cb748960 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/ImageCropperValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/ImageCropperValueConverter.cs @@ -43,7 +43,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters catch (Exception ex) { // cannot deserialize, assume it may be a raw image url - Current.Logger.Error($"Could not deserialize string \"{sourceString}\" into an image cropper value.", ex); + Current.Logger.Error(ex, "Could not deserialize string '{JsonString}' into an image cropper value.", sourceString); value = new ImageCropperValue { Src = sourceString }; } diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/JsonValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/JsonValueConverter.cs index aeeb1a795f..d4cee4762f 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/JsonValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/JsonValueConverter.cs @@ -57,7 +57,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters } catch (Exception ex) { - Current.Logger.Error("Could not parse the string " + sourceString + " to a json object", ex); + Current.Logger.Error(ex, "Could not parse the string '{JsonString}' to a json object", sourceString); } } diff --git a/src/Umbraco.Core/Publishing/ScheduledPublisher.cs b/src/Umbraco.Core/Publishing/ScheduledPublisher.cs index 1d2d62b929..73cc752508 100644 --- a/src/Umbraco.Core/Publishing/ScheduledPublisher.cs +++ b/src/Umbraco.Core/Publishing/ScheduledPublisher.cs @@ -35,7 +35,7 @@ namespace Umbraco.Core.Publishing var counter = 0; var contentForRelease = _contentService.GetContentForRelease().ToArray(); if (contentForRelease.Length > 0) - _logger.Debug(() => $"There's {contentForRelease.Length} item(s) of content to be published"); + _logger.Debug("There's {ContentItemsForRelease} item(s) of content to be published", contentForRelease.Length); foreach (var d in contentForRelease) { try @@ -43,26 +43,26 @@ namespace Umbraco.Core.Publishing d.ReleaseDate = null; d.PublishCulture(); // fixme variants? var result = _contentService.SaveAndPublish(d, userId: _userService.GetProfileById(d.WriterId).Id); - _logger.Debug(() => $"Result of publish attempt: {result.Result}"); + _logger.Debug("Result of publish attempt: {PublishResult}", result.Result); if (result.Success == false) { - _logger.Error($"Error publishing node {d.Id}"); + _logger.Error(null, "Error publishing node {NodeId}", d.Id); } else { counter++; } } - catch (Exception ee) + catch (Exception ex) { - _logger.Error($"Error publishing node {d.Id}", ee); + _logger.Error(ex, "Error publishing node {NodeId}", d.Id); throw; } } var contentForExpiration = _contentService.GetContentForExpiration().ToArray(); if (contentForExpiration.Length > 0) - _logger.Debug(() => $"There's {contentForExpiration.Length} item(s) of content to be unpublished"); + _logger.Debug("There's {ContentItemsForExpiration} item(s) of content to be unpublished", contentForExpiration.Length); foreach (var d in contentForExpiration) { try @@ -74,9 +74,9 @@ namespace Umbraco.Core.Publishing counter++; } } - catch (Exception ee) + catch (Exception ex) { - _logger.Error($"Error unpublishing node {d.Id}", ee); + _logger.Error(ex, "Error unpublishing node {NodeId}", d.Id); throw; } } diff --git a/src/Umbraco.Core/Runtime/CoreRuntime.cs b/src/Umbraco.Core/Runtime/CoreRuntime.cs index 7ab87029a5..3e86003b9d 100644 --- a/src/Umbraco.Core/Runtime/CoreRuntime.cs +++ b/src/Umbraco.Core/Runtime/CoreRuntime.cs @@ -81,7 +81,7 @@ namespace Umbraco.Core.Runtime try { - Logger.Debug(() => $"Runtime: {GetType().FullName}"); + Logger.Debug("Runtime: {Runtime}", GetType().FullName); AquireMainDom(container); DetermineRuntimeLevel(container); @@ -139,11 +139,11 @@ namespace Umbraco.Core.Runtime var dbfactory = container.GetInstance(); SetRuntimeStateLevel(dbfactory, Logger); - Logger.Debug(() => $"Runtime level: {_state.Level}"); + Logger.Debug("Runtime level: {RuntimeLevel}", _state.Level); if (_state.Level == RuntimeLevel.Upgrade) { - Logger.Debug(() => $"Configure database factory for upgrades."); + Logger.Debug("Configure database factory for upgrades."); dbfactory.ConfigureForUpgrade(); } } @@ -260,12 +260,12 @@ namespace Umbraco.Core.Runtime { // there *is* a local version, but it does not match the code version // need to upgrade - logger.Debug(() => $"Local version \"{localVersion}\" < code version \"{codeVersion}\", need to upgrade Umbraco."); + logger.Debug("Local version '{LocalVersion}' < code version '{CodeVersion}', need to upgrade Umbraco.", localVersion, codeVersion); _state.Level = RuntimeLevel.Upgrade; } else if (localVersion > codeVersion) { - logger.Warn(() => $"Local version \"{localVersion}\" > code version \"{codeVersion}\", downgrading is not supported."); + logger.Warn("Local version '{LocalVersion}' > code version '{CodeVersion}', downgrading is not supported.", localVersion, codeVersion); _state.Level = RuntimeLevel.BootFailed; // in fact, this is bad enough that we want to throw @@ -290,16 +290,14 @@ namespace Umbraco.Core.Runtime { connect = databaseFactory.CanConnect; if (connect) break; - logger.Debug(() => i == 0 - ? "Could not immediately connect to database, trying again." - : "Could not connect to database."); + logger.Debug("Could not immediately connect to database, trying again."); Thread.Sleep(1000); } if (connect == false) { // cannot connect to configured database, this is bad, fail - logger.Debug(() => "Could not connect to database."); + logger.Debug("Could not connect to database."); _state.Level = RuntimeLevel.BootFailed; // in fact, this is bad enough that we want to throw @@ -363,7 +361,7 @@ namespace Umbraco.Core.Runtime _state.CurrentMigrationState = state; _state.FinalMigrationState = umbracoPlan.FinalState; - logger.Debug(() => $"Final upgrade state is \"{_state.FinalMigrationState}\", database contains \"{state ?? ""}\"."); + logger.Debug("Final upgrade state is '{FinalMigrationState}', database contains {DatabaseState}", _state.FinalMigrationState, state ?? ""); return state == _state.FinalMigrationState; } diff --git a/src/Umbraco.Core/RuntimeState.cs b/src/Umbraco.Core/RuntimeState.cs index 53a474cef7..d09bd95081 100644 --- a/src/Umbraco.Core/RuntimeState.cs +++ b/src/Umbraco.Core/RuntimeState.cs @@ -117,7 +117,7 @@ namespace Umbraco.Core var change = url != null && !_applicationUrls.Contains(url); if (change) { - _logger.Info(typeof(ApplicationUrlHelper), $"New url \"{url}\" detected, re-discovering application url."); + _logger.Info(typeof(ApplicationUrlHelper), "New url '{Url}' detected, re-discovering application url.", url); _applicationUrls.Add(url); } diff --git a/src/Umbraco.Core/Scoping/Scope.cs b/src/Umbraco.Core/Scoping/Scope.cs index d3e31c0d81..adc5482e68 100644 --- a/src/Umbraco.Core/Scoping/Scope.cs +++ b/src/Umbraco.Core/Scoping/Scope.cs @@ -318,7 +318,8 @@ namespace Umbraco.Core.Scoping if (completed.HasValue == false || completed.Value == false) { if (LogUncompletedScopes) - _logger.Debug(() => "Uncompleted Child Scope at\r\n" + Environment.StackTrace); + _logger.Debug("Uncompleted Child Scope at\r\n {StackTrace}", Environment.StackTrace); + _completed = false; } } diff --git a/src/Umbraco.Core/Scoping/ScopeProvider.cs b/src/Umbraco.Core/Scoping/ScopeProvider.cs index beb1ee5374..ea68a05f15 100644 --- a/src/Umbraco.Core/Scoping/ScopeProvider.cs +++ b/src/Umbraco.Core/Scoping/ScopeProvider.cs @@ -117,7 +117,7 @@ namespace Umbraco.Core.Scoping } // hard to inject into a static method :( - Current.Logger.Warn(() => $"Missed {typeof(T).Name} Object {objectKey.ToString("N").Substring(0, 8)}"); + Current.Logger.Warn("Missed {TypeName} Object {ObjectKey}", typeof(T).Name, objectKey.ToString("N").Substring(0, 8)); #if DEBUG_SCOPES //Current.Logger.Debug("At:\r\n" + Head(Environment.StackTrace, 24)); #endif diff --git a/src/Umbraco.Core/Security/MembershipProviderBase.cs b/src/Umbraco.Core/Security/MembershipProviderBase.cs index ea9ce4458a..0c8461c2f2 100644 --- a/src/Umbraco.Core/Security/MembershipProviderBase.cs +++ b/src/Umbraco.Core/Security/MembershipProviderBase.cs @@ -281,7 +281,7 @@ namespace Umbraco.Core.Security if ((PasswordFormat == MembershipPasswordFormat.Hashed) && EnablePasswordRetrieval) { var ex = new ProviderException("Provider can not retrieve a hashed password"); - Current.Logger.Error("Cannot specify a Hashed password format with the enabledPasswordRetrieval option set to true", ex); + Current.Logger.Error(ex, "Cannot specify a Hashed password format with the enabledPasswordRetrieval option set to true"); throw ex; } diff --git a/src/Umbraco.Core/Services/Implement/ContentService.cs b/src/Umbraco.Core/Services/Implement/ContentService.cs index 30e76468a6..0bb00ef5a4 100644 --- a/src/Umbraco.Core/Services/Implement/ContentService.cs +++ b/src/Umbraco.Core/Services/Implement/ContentService.cs @@ -1240,11 +1240,11 @@ namespace Umbraco.Core.Services.Implement d.PublishCulture(); // fixme variants? result = SaveAndPublish(d, userId: d.WriterId); if (result.Success == false) - Logger.Error($"Failed to publish document id={d.Id}, reason={result.Result}."); + Logger.Error(null, "Failed to publish document id={DocumentId}, reason={Reason}.", d.Id, result.Result); } catch (Exception e) { - Logger.Error($"Failed to publish document id={d.Id}, an exception was thrown.", e); + Logger.Error(e, "Failed to publish document id={DocumentId}, an exception was thrown.", d.Id); throw; } yield return result; @@ -1256,11 +1256,11 @@ namespace Umbraco.Core.Services.Implement d.ExpireDate = null; var result = Unpublish(d, userId: d.WriterId); if (result.Success == false) - Logger.Error($"Failed to unpublish document id={d.Id}, reason={result.Result}."); + Logger.Error(null, "Failed to unpublish document id={DocumentId}, reason={Reason}.", d.Id, result.Result); } catch (Exception e) { - Logger.Error($"Failed to unpublish document id={d.Id}, an exception was thrown.", e); + Logger.Error(e, "Failed to unpublish document id={DocumentId}, an exception was thrown.", d.Id); throw; } } @@ -1439,7 +1439,7 @@ namespace Umbraco.Core.Services.Implement // fixme not going to work, do it differently _mediaFileSystem.DeleteFiles(args.MediaFilesToDelete, // remove flagged files - (file, e) => Logger.Error("An error occurred while deleting file attached to nodes: " + file, e)); + (file, e) => Logger.Error(e, "An error occurred while deleting file attached to nodes: {File}", file)); } } @@ -2178,7 +2178,7 @@ namespace Umbraco.Core.Services.Implement // raise Publishing event if (scope.Events.DispatchCancelable(Publishing, this, new PublishEventArgs(content, evtMsgs))) { - Logger.Info(() => $"Document \"'{content.Name}\" (id={content.Id}) cannot be published: publishing was cancelled."); + Logger.Info("Document '{ContentName}' (id={ContentId}) cannot be published: {Reason}", content.Name, content.Id, "publishing was cancelled"); return new PublishResult(PublishResultType.FailedCancelledByEvent, evtMsgs, content); } @@ -2186,7 +2186,7 @@ namespace Umbraco.Core.Services.Implement // either because it is 'publishing' or because it already has a published version if (((Content) content).PublishedState != PublishedState.Publishing && content.PublishedVersionId == 0) { - Logger.Info(() => $"Document \"{content.Name}\" (id={content.Id}) cannot be published: document does not have published values."); + Logger.Info("Document '{ContentName}' (id={ContentId}) cannot be published: {Reason}", content.Name, content.Id, "document does not have published values"); return new PublishResult(PublishResultType.FailedNoPublishedValues, evtMsgs, content); } @@ -2194,15 +2194,15 @@ namespace Umbraco.Core.Services.Implement switch (content.Status) { case ContentStatus.Expired: - Logger.Info(() => $"Document \"{content.Name}\" (id={content.Id}) cannot be published: document has expired."); + Logger.Info("Document '{ContentName}' (id={ContentId}) cannot be published: {Reason}", content.Name, content.Id, "document has expired"); return new PublishResult(PublishResultType.FailedHasExpired, evtMsgs, content); case ContentStatus.AwaitingRelease: - Logger.Info(() => $"Document \"{content.Name}\" (id={content.Id}) cannot be published: document is awaiting release."); + Logger.Info("Document '{ContentName}' (id={ContentId}) cannot be published: {Reason}", content.Name, content.Id, "document is awaiting release"); return new PublishResult(PublishResultType.FailedAwaitingRelease, evtMsgs, content); case ContentStatus.Trashed: - Logger.Info(() => $"Document \"{content.Name}\" (id={content.Id}) cannot be published: document is trashed."); + Logger.Info("Document '{ContentName}' (id={ContentId}) cannot be published: {Reason}", content.Name, content.Id, "document is trashed"); return new PublishResult(PublishResultType.FailedIsTrashed, evtMsgs, content); } @@ -2214,7 +2214,7 @@ namespace Umbraco.Core.Services.Implement var pathIsOk = content.ParentId == Constants.System.Root || IsPathPublished(GetParent(content)); if (pathIsOk == false) { - Logger.Info(() => $"Document \"{content.Name}\" (id={content.Id}) cannot be published: parent is not published."); + Logger.Info("Document '{ContentName}' (id={ContentId}) cannot be published: {Reason}", content.Name, content.Id, "parent is not published"); return new PublishResult(PublishResultType.FailedPathNotPublished, evtMsgs, content); } @@ -2238,7 +2238,7 @@ namespace Umbraco.Core.Services.Implement // change state to publishing ((Content) content).PublishedState = PublishedState.Publishing; - Logger.Info(() => $"Content \"{content.Name}\" (id={content.Id}) has been published."); + Logger.Info("Document '{ContentName}' (id={ContentId}) has been published.", content.Name, content.Id); return result; } @@ -2248,7 +2248,7 @@ namespace Umbraco.Core.Services.Implement // raise UnPublishing event if (scope.Events.DispatchCancelable(UnPublishing, this, new PublishEventArgs(content, evtMsgs))) { - Logger.Info(() => $"Document \"{content.Name}\" (id={content.Id}) cannot be unpublished: unpublishing was cancelled."); + Logger.Info("Document '{ContentName}' (id={ContentId}) cannot be unpublished: unpublishing was cancelled.", content.Name, content.Id); return new UnpublishResult(UnpublishResultType.FailedCancelledByEvent, evtMsgs, content); } @@ -2271,13 +2271,13 @@ namespace Umbraco.Core.Services.Implement if (content.ReleaseDate.HasValue && content.ReleaseDate.Value <= DateTime.Now) { content.ReleaseDate = null; - Logger.Info(() => $"Document \"{content.Name}\" (id={content.Id}) had its release date removed, because it was unpublished."); + Logger.Info("Document '{ContentName}' (id={ContentId}) had its release date removed, because it was unpublished.", content.Name, content.Id); } // change state to unpublishing ((Content) content).PublishedState = PublishedState.Unpublishing; - Logger.Info(() => $"Document \"{content.Name}\" (id={content.Id}) has been unpublished."); + Logger.Info("Document '{ContentName}' (id={ContentId}) has been unpublished.", content.Name, content.Id); return attempt; } diff --git a/src/Umbraco.Core/Services/Implement/LocalizedTextService.cs b/src/Umbraco.Core/Services/Implement/LocalizedTextService.cs index 953e80594f..923b9994d1 100644 --- a/src/Umbraco.Core/Services/Implement/LocalizedTextService.cs +++ b/src/Umbraco.Core/Services/Implement/LocalizedTextService.cs @@ -104,7 +104,7 @@ namespace Umbraco.Core.Services.Implement { if (xmlSource.ContainsKey(culture) == false) { - _logger.Warn(() => $"The culture specified {culture} was not found in any configured sources for this service"); + _logger.Warn("The culture specified {Culture} was not found in any configured sources for this service", culture); return result; } @@ -124,7 +124,7 @@ namespace Umbraco.Core.Services.Implement { if (_dictionarySource.ContainsKey(culture) == false) { - _logger.Warn(() => $"The culture specified {culture} was not found in any configured sources for this service"); + _logger.Warn("The culture specified {Culture} was not found in any configured sources for this service", culture); return result; } @@ -207,7 +207,7 @@ namespace Umbraco.Core.Services.Implement { if (_dictionarySource.ContainsKey(culture) == false) { - _logger.Warn(() => $"The culture specified {culture} was not found in any configured sources for this service"); + _logger.Warn("The culture specified {Culture} was not found in any configured sources for this service", culture); return "[" + key + "]"; } @@ -245,7 +245,7 @@ namespace Umbraco.Core.Services.Implement { if (xmlSource.ContainsKey(culture) == false) { - _logger.Warn(() => $"The culture specified {culture} was not found in any configured sources for this service"); + _logger.Warn("The culture specified {Culture} was not found in any configured sources for this service", culture); return "[" + key + "]"; } diff --git a/src/Umbraco.Core/Services/Implement/LocalizedTextServiceFileSources.cs b/src/Umbraco.Core/Services/Implement/LocalizedTextServiceFileSources.cs index 44587b616b..3b3f90a412 100644 --- a/src/Umbraco.Core/Services/Implement/LocalizedTextServiceFileSources.cs +++ b/src/Umbraco.Core/Services/Implement/LocalizedTextServiceFileSources.cs @@ -88,7 +88,7 @@ namespace Umbraco.Core.Services.Implement } catch (CultureNotFoundException) { - Current.Logger.Warn(() => $"The culture {cultureVal} found in the file {fileInfo.FullName} is not a valid culture"); + Current.Logger.Warn("The culture {CultureValue} found in the file {CultureFile} is not a valid culture", cultureVal, fileInfo.FullName); //If the culture in the file is invalid, we'll just hope the file name is a valid culture below, otherwise // an exception will be thrown. } @@ -125,7 +125,7 @@ namespace Umbraco.Core.Services.Implement if (fileSourceFolder.Exists == false) { - Current.Logger.Warn(() => $"The folder does not exist: {fileSourceFolder.FullName}, therefore no sources will be discovered"); + Current.Logger.Warn("The folder does not exist: {FileSourceFolder}, therefore no sources will be discovered", fileSourceFolder.FullName); } else { @@ -204,7 +204,7 @@ namespace Umbraco.Core.Services.Implement } catch (Exception ex) { - _logger.Error("Could not load file into XML " + supplementaryFile.File.FullName, ex); + _logger.Error(ex, "Could not load file into XML {File}", supplementaryFile.File.FullName); continue; } diff --git a/src/Umbraco.Core/Services/Implement/MediaService.cs b/src/Umbraco.Core/Services/Implement/MediaService.cs index d29875d68b..8f6a1c6000 100644 --- a/src/Umbraco.Core/Services/Implement/MediaService.cs +++ b/src/Umbraco.Core/Services/Implement/MediaService.cs @@ -892,7 +892,7 @@ namespace Umbraco.Core.Services.Implement scope.Events.Dispatch(Deleted, this, args); _mediaFileSystem.DeleteFiles(args.MediaFilesToDelete, // remove flagged files - (file, e) => Logger.Error("An error occurred while deleting file attached to nodes: " + file, e)); + (file, e) => Logger.Error(e, "An error occurred while deleting file attached to nodes: {File}", file)); } } diff --git a/src/Umbraco.Core/Services/Implement/MemberService.cs b/src/Umbraco.Core/Services/Implement/MemberService.cs index ca2b39dee2..288809bf33 100644 --- a/src/Umbraco.Core/Services/Implement/MemberService.cs +++ b/src/Umbraco.Core/Services/Implement/MemberService.cs @@ -930,7 +930,7 @@ namespace Umbraco.Core.Services.Implement // fixme - this is MOOT because the event will not trigger immediately // it's been refactored already (think it's the dispatcher that deals with it?) _mediaFileSystem.DeleteFiles(args.MediaFilesToDelete, // remove flagged files - (file, e) => Logger.Error("An error occurred while deleting file attached to nodes: " + file, e)); + (file, e) => Logger.Error(e, "An error occurred while deleting file attached to nodes: {File}", file)); } #endregion diff --git a/src/Umbraco.Core/Services/Implement/NotificationService.cs b/src/Umbraco.Core/Services/Implement/NotificationService.cs index 9f76e087c1..3afb7c3777 100644 --- a/src/Umbraco.Core/Services/Implement/NotificationService.cs +++ b/src/Umbraco.Core/Services/Implement/NotificationService.cs @@ -629,11 +629,11 @@ namespace Umbraco.Core.Services.Implement try { if (Sendmail != null) Sendmail(s, request.Mail, _logger); else s.Send(request.Mail); - _logger.Debug(() => string.Format("Notification \"{0}\" sent to {1} ({2})", request.Action, request.UserName, request.Email)); + _logger.Debug("Notification '{Action}' sent to {Username} ({Email})", request.Action, request.UserName, request.Email); } catch (Exception ex) { - _logger.Error("An error occurred sending notification", ex); + _logger.Error(ex, "An error occurred sending notification"); s.Dispose(); s = new SmtpClient(); } diff --git a/src/Umbraco.Core/Services/Implement/PackagingService.cs b/src/Umbraco.Core/Services/Implement/PackagingService.cs index 54e549dd08..ef22861947 100644 --- a/src/Umbraco.Core/Services/Implement/PackagingService.cs +++ b/src/Umbraco.Core/Services/Implement/PackagingService.cs @@ -491,7 +491,7 @@ namespace Umbraco.Core.Services.Implement var tryCreateFolder = _contentTypeService.CreateContainer(-1, rootFolder); if (tryCreateFolder == false) { - _logger.Error("Could not create folder: " + rootFolder, tryCreateFolder.Exception); + _logger.Error(tryCreateFolder.Exception, "Could not create folder: {FolderName}", rootFolder); throw tryCreateFolder.Exception; } var rootFolderId = tryCreateFolder.Result.Entity.Id; @@ -525,7 +525,7 @@ namespace Umbraco.Core.Services.Implement var tryCreateFolder = _contentTypeService.CreateContainer(current.Id, folderName); if (tryCreateFolder == false) { - _logger.Error("Could not create folder: " + folderName, tryCreateFolder.Exception); + _logger.Error(tryCreateFolder.Exception, "Could not create folder: {FolderName}", folderName); throw tryCreateFolder.Exception; } return _contentTypeService.GetContainer(tryCreateFolder.Result.Entity.Id); @@ -631,7 +631,7 @@ namespace Umbraco.Core.Services.Implement } else { - _logger.Warn(() => $"Packager: Error handling allowed templates. Template with alias '{alias}' could not be found."); + _logger.Warn("Packager: Error handling allowed templates. Template with alias '{TemplateAlias}' could not be found.", alias); } } @@ -647,7 +647,7 @@ namespace Umbraco.Core.Services.Implement } else { - _logger.Warn(() => $"Packager: Error handling default template. Default template with alias '{defaultTemplateElement.Value}' could not be found."); + _logger.Warn("Packager: Error handling default template. Default template with alias '{DefaultTemplateAlias}' could not be found.", defaultTemplateElement.Value); } } } @@ -718,7 +718,8 @@ namespace Umbraco.Core.Services.Implement // This means that the property will not be created. if (dataTypeDefinition == null) { - _logger.Warn(() => $"Packager: Error handling creation of PropertyType '{property.Element("Name").Value}'. Could not find DataTypeDefintion with unique id '{dataTypeDefinitionId}' nor one referencing the DataType with a property editor alias (or legacy control id) '{property.Element("Type").Value.Trim()}'. Did the package creator forget to package up custom datatypes? This property will be converted to a label/readonly editor if one exists."); + _logger.Warn("Packager: Error handling creation of PropertyType '{PropertyType}'. Could not find DataTypeDefintion with unique id '{DataTypeDefinitionId}' nor one referencing the DataType with a property editor alias (or legacy control id) '{PropertyEditorAlias}'. Did the package creator forget to package up custom datatypes? This property will be converted to a label/readonly editor if one exists.", + property.Element("Name").Value, dataTypeDefinitionId, property.Element("Type").Value.Trim()); //convert to a label! dataTypeDefinition = _dataTypeService.GetByEditorAlias(Constants.PropertyEditors.Aliases.NoEdit).FirstOrDefault(); @@ -762,7 +763,9 @@ namespace Umbraco.Core.Services.Implement var allowedChild = _importedContentTypes.ContainsKey(alias) ? _importedContentTypes[alias] : _contentTypeService.Get(alias); if (allowedChild == null) { - _logger.Warn(() => $"Packager: Error handling DocumentType structure. DocumentType with alias '{alias}' could not be found and was not added to the structure for '{contentType.Alias}'."); + _logger.Warn( + "Packager: Error handling DocumentType structure. DocumentType with alias '{DoctypeAlias}' could not be found and was not added to the structure for '{DoctypeStructureAlias}'.", + alias, contentType.Alias); continue; } @@ -946,7 +949,7 @@ namespace Umbraco.Core.Services.Implement var tryCreateFolder = _dataTypeService.CreateContainer(-1, rootFolder); if (tryCreateFolder == false) { - _logger.Error("Could not create folder: " + rootFolder, tryCreateFolder.Exception); + _logger.Error(tryCreateFolder.Exception, "Could not create folder: {FolderName}", rootFolder); throw tryCreateFolder.Exception; } current = _dataTypeService.GetContainer(tryCreateFolder.Result.Entity.Id); @@ -979,7 +982,7 @@ namespace Umbraco.Core.Services.Implement var tryCreateFolder = _dataTypeService.CreateContainer(current.Id, folderName); if (tryCreateFolder == false) { - _logger.Error("Could not create folder: " + folderName, tryCreateFolder.Exception); + _logger.Error(tryCreateFolder.Exception, "Could not create folder: {FolderName}", folderName); throw tryCreateFolder.Exception; } return _dataTypeService.GetContainer(tryCreateFolder.Result.Entity.Id); @@ -1526,7 +1529,10 @@ namespace Umbraco.Core.Services.Implement else if (string.IsNullOrEmpty((string)elementCopy.Element("Master")) == false && templateElements.Any(x => (string)x.Element("Alias") == (string)elementCopy.Element("Master")) == false) { - _logger.Info(string.Format("Template '{0}' has an invalid Master '{1}', so the reference has been ignored.", (string)elementCopy.Element("Alias"), (string)elementCopy.Element("Master"))); + _logger.Info( + "Template '{TemplateAlias}' has an invalid Master '{TemplateMaster}', so the reference has been ignored.", + (string) elementCopy.Element("Alias"), + (string) elementCopy.Element("Master")); } graph.AddItem(TopoGraph.CreateNode((string) elementCopy.Element("Alias"), elementCopy, dependencies)); diff --git a/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs b/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs index 7abb8b6f9d..0a8d60e209 100644 --- a/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs +++ b/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs @@ -39,14 +39,14 @@ namespace Umbraco.Core.Sync if (string.IsNullOrWhiteSpace(umbracoApplicationUrl) == false) { umbracoApplicationUrl = umbracoApplicationUrl.TrimEnd('/'); - logger.Info(TypeOfApplicationUrlHelper, "ApplicationUrl: " + umbracoApplicationUrl + " (provider)"); + logger.Info(TypeOfApplicationUrlHelper, "ApplicationUrl: {UmbracoAppUrl} (provider)", umbracoApplicationUrl); return umbracoApplicationUrl; } if (request == null) return null; umbracoApplicationUrl = GetApplicationUrlFromCurrentRequest(request, globalSettings); - logger.Info(TypeOfApplicationUrlHelper, "ApplicationUrl: " + umbracoApplicationUrl + " (UmbracoModule request)"); + logger.Info(TypeOfApplicationUrlHelper, "ApplicationUrl: {UmbracoAppUrl} (UmbracoModule request)", umbracoApplicationUrl); return umbracoApplicationUrl; } @@ -62,7 +62,7 @@ namespace Umbraco.Core.Sync if (url.IsNullOrWhiteSpace() == false) { var umbracoApplicationUrl = url.TrimEnd('/'); - logger.Info(TypeOfApplicationUrlHelper, "ApplicationUrl: " + umbracoApplicationUrl + " (using web.routing/@umbracoApplicationUrl)"); + logger.Info(TypeOfApplicationUrlHelper, "ApplicationUrl: {UmbracoAppUrl} (using web.routing/@umbracoApplicationUrl)", umbracoApplicationUrl); return umbracoApplicationUrl; } @@ -78,7 +78,7 @@ namespace Umbraco.Core.Sync var ssl = globalSettings.UseHttps ? "s" : ""; url = "http" + ssl + "://" + url; var umbracoApplicationUrl = url.TrimEnd('/'); - logger.Info(TypeOfApplicationUrlHelper, "ApplicationUrl: " + umbracoApplicationUrl + " (using scheduledTasks/@baseUrl)"); + logger.Info(TypeOfApplicationUrlHelper, "ApplicationUrl: {UmbracoAppUrl} (using scheduledTasks/@baseUrl)", umbracoApplicationUrl); return umbracoApplicationUrl; } @@ -92,7 +92,7 @@ namespace Umbraco.Core.Sync if (url.IsNullOrWhiteSpace() == false) { var umbracoApplicationUrl = url.TrimEnd('/'); - logger.Info(TypeOfApplicationUrlHelper, "ApplicationUrl: " + umbracoApplicationUrl + " (IServerRegistrar)"); + logger.Info(TypeOfApplicationUrlHelper, "ApplicationUrl: {UmbracoAppUrl} (IServerRegistrar)", umbracoApplicationUrl); return umbracoApplicationUrl; } diff --git a/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs b/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs index a1b89e58bc..20f9276ba1 100644 --- a/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs +++ b/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs @@ -192,9 +192,11 @@ namespace Umbraco.Core.Sync if (count > Options.MaxProcessingInstructionCount) { //too many instructions, proceed to cold boot - Logger.Warn(() => $"The instruction count ({count}) exceeds the specified MaxProcessingInstructionCount ({Options.MaxProcessingInstructionCount})." + Logger.Warn( + "The instruction count ({InstructionCount}) exceeds the specified MaxProcessingInstructionCount ({MaxProcessingInstructionCount})." + " The server will skip existing instructions, rebuild its caches and indexes entirely, adjust its last synced Id" - + " to the latest found in the database and maintain cache updates based on that Id."); + + " to the latest found in the database and maintain cache updates based on that Id.", + count, Options.MaxProcessingInstructionCount); coldboot = true; } @@ -350,7 +352,10 @@ namespace Umbraco.Core.Sync } catch (JsonException ex) { - Logger.Error($"Failed to deserialize instructions ({dto.Id}: \"{dto.Instructions}\").", ex); + Logger.Error(ex, "Failed to deserialize instructions ({DtoId}: '{DtoInstructions}').", + dto.Id, + dto.Instructions); + lastId = dto.Id; // skip continue; } @@ -406,7 +411,10 @@ namespace Umbraco.Core.Sync catch (Exception ex) { Logger.Error( - $"DISTRIBUTED CACHE IS NOT UPDATED. Failed to execute instructions ({dto.Id}: \"{dto.Instructions}\"). Instruction is being skipped/ignored", ex); + ex, + "DISTRIBUTED CACHE IS NOT UPDATED. Failed to execute instructions ({DtoId}: '{DtoInstructions}'). Instruction is being skipped/ignored", + dto.Id, + dto.Instructions); //we cannot throw here because this invalid instruction will just keep getting processed over and over and errors // will be thrown over and over. The only thing we can do is ignore and move on. diff --git a/src/Umbraco.Core/Sync/ServerMessengerBase.cs b/src/Umbraco.Core/Sync/ServerMessengerBase.cs index 68223a40e6..bbf00c3a6b 100644 --- a/src/Umbraco.Core/Sync/ServerMessengerBase.cs +++ b/src/Umbraco.Core/Sync/ServerMessengerBase.cs @@ -157,7 +157,7 @@ namespace Umbraco.Core.Sync { if (refresher == null) throw new ArgumentNullException(nameof(refresher)); - Current.Logger.Debug(() => $"Invoking refresher {refresher.GetType()} on local server for message type RefreshByPayload"); + Current.Logger.Debug("Invoking refresher {RefresherType} on local server for message type RefreshByPayload", refresher.GetType()); var payloadRefresher = refresher as IPayloadCacheRefresher; if (payloadRefresher == null) @@ -179,7 +179,7 @@ namespace Umbraco.Core.Sync { if (refresher == null) throw new ArgumentNullException(nameof(refresher)); - Current.Logger.Debug(() => $"Invoking refresher {refresher.GetType()} on local server for message type {messageType}"); + Current.Logger.Debug("Invoking refresher {RefresherType} on local server for message type {MessageType}", refresher.GetType(), messageType); switch (messageType) { @@ -240,7 +240,7 @@ namespace Umbraco.Core.Sync { if (refresher == null) throw new ArgumentNullException(nameof(refresher)); - Current.Logger.Debug(() => $"Invoking refresher {refresher.GetType()} on local server for message type {messageType}"); + Current.Logger.Debug("Invoking refresher {RefresherType} on local server for message type {MessageType}", refresher.GetType(), messageType); var typedRefresher = refresher as ICacheRefresher; diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 1ddf5f0857..01432b7e31 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -64,8 +64,6 @@ - - @@ -76,6 +74,27 @@ + + 2.7.1 + + + 2.0.1 + + + 3.0.0 + + + 2.0.0 + + + 1.0.0 + + + 2.1.2 + + + 4.0.0 + @@ -317,7 +336,8 @@ - + + @@ -462,7 +482,7 @@ - + @@ -552,24 +572,18 @@ - - - - - - diff --git a/src/Umbraco.Core/UmbracoApplicationBase.cs b/src/Umbraco.Core/UmbracoApplicationBase.cs index 2e08814e1f..14b94fe65c 100644 --- a/src/Umbraco.Core/UmbracoApplicationBase.cs +++ b/src/Umbraco.Core/UmbracoApplicationBase.cs @@ -3,9 +3,10 @@ using System.Reflection; using System.Threading; using System.Web; using System.Web.Hosting; -using log4net; +using Serilog; using Umbraco.Core.Composing; using Umbraco.Core.Logging; +using ILogger = Umbraco.Core.Logging.ILogger; namespace Umbraco.Core { @@ -26,7 +27,7 @@ namespace Umbraco.Core ///
protected virtual ILogger GetLogger() { - return Logger.CreateWithDefaultLog4NetConfiguration(); + return Logger.CreateWithDefaultConfiguration(); } /// @@ -100,7 +101,7 @@ namespace Umbraco.Core var msg = "Unhandled exception in AppDomain"; if (isTerminating) msg += " (terminating)"; msg += "."; - logger.Error(msg, exception); + logger.Error(exception, msg); }; } @@ -193,14 +194,15 @@ namespace Umbraco.Core BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField, null, runtime, null); - var shutdownMsg = $"Application shutdown. Details: {HostingEnvironment.ShutdownReason}\r\n\r\n_shutDownMessage={shutDownMessage}\r\n\r\n_shutDownStack={shutDownStack}"; - - logger.Info(shutdownMsg); + logger.Info("Application shutdown. Details: {ShutdownReason}\r\n\r\n_shutDownMessage={ShutdownMessage}\r\n\r\n_shutDownStack={ShutdownStack}", + HostingEnvironment.ShutdownReason, + shutDownMessage, + shutDownStack); } catch (Exception) { //if for some reason that fails, then log the normal output - logger.Info("Application shutdown. Reason: " + HostingEnvironment.ShutdownReason); + logger.Info("Application shutdown. Reason: {ShutdownReason}", HostingEnvironment.ShutdownReason); } } @@ -210,7 +212,10 @@ namespace Umbraco.Core { HandleApplicationEnd(); OnApplicationEnd(sender, evargs); - LogManager.Shutdown(); + + //Not sure if we need to do this - as my POC approach I never had to deal with this + //As the LightInject container when tearing down will dispose of Serilog AFAIK + Log.CloseAndFlush(); } #endregion @@ -229,7 +234,7 @@ namespace Umbraco.Core // ignore HTTP errors if (exception.GetType() == typeof(HttpException)) return; - Current.Logger.Error("An unhandled exception occurred.", exception); + Current.Logger.Error(exception, "An unhandled exception occurred"); } // called by ASP.NET (auto event wireup) at any phase in the application life cycle @@ -252,7 +257,7 @@ namespace Umbraco.Core } catch (Exception ex) { - Current.Logger.Error($"Error in {name} handler.", ex); + Current.Logger.Error(ex, "Error in {Name} handler.", name); throw; } } diff --git a/src/Umbraco.Core/UriExtensions.cs b/src/Umbraco.Core/UriExtensions.cs index e579a5158f..d018dddfbf 100644 --- a/src/Umbraco.Core/UriExtensions.cs +++ b/src/Umbraco.Core/UriExtensions.cs @@ -155,7 +155,7 @@ namespace Umbraco.Core } catch (ArgumentException ex) { - Current.Logger.Error(typeof(UriExtensions), "Failed to determine if request was client side", ex); + Current.Logger.Error(typeof(UriExtensions), ex, "Failed to determine if request was client side"); return false; } } diff --git a/src/Umbraco.Core/Xml/XPath/MacroNavigator.cs b/src/Umbraco.Core/Xml/XPath/MacroNavigator.cs index d9c3e4b0f3..8b4755107a 100644 --- a/src/Umbraco.Core/Xml/XPath/MacroNavigator.cs +++ b/src/Umbraco.Core/Xml/XPath/MacroNavigator.cs @@ -164,8 +164,6 @@ namespace Umbraco.Core.Xml.XPath #pragma warning disable 168 var msg = string.Format(format, args); // unused if not writing, hence #pragma #pragma warning restore 168 - //LogHelper.Debug(msg); // beware! this can quicky overflow log4net - //Console.WriteLine(msg); } #endif diff --git a/src/Umbraco.Core/Xml/XPath/NavigableNavigator.cs b/src/Umbraco.Core/Xml/XPath/NavigableNavigator.cs index d4acfe137d..4c15f1b9b0 100644 --- a/src/Umbraco.Core/Xml/XPath/NavigableNavigator.cs +++ b/src/Umbraco.Core/Xml/XPath/NavigableNavigator.cs @@ -4,7 +4,7 @@ // In Debug configuration, diagnostics code can be enabled by defining DEBUGNAVIGATOR below, // but by default nothing is writted, unless some lines are un-commented in Debug(...) below. // -// Beware! Diagnostics are extremely verbose and can overflow log4net pretty easily. +// Beware! Diagnostics are extremely verbose and can overflow logging pretty easily. #if DEBUG // define to enable diagnostics code @@ -254,8 +254,6 @@ namespace Umbraco.Core.Xml.XPath //format = "[" + _uid.ToString("00000") + "] " + Tabs.Substring(0, _tabs) + format; //var msg = string.Format(format, args); - //LogHelper.Debug(msg); // beware! this can quicky overflow log4net - //Console.WriteLine(msg); } #endif diff --git a/src/Umbraco.Examine/UmbracoContentIndexer.cs b/src/Umbraco.Examine/UmbracoContentIndexer.cs index bdbaf04a32..94982c8591 100644 --- a/src/Umbraco.Examine/UmbracoContentIndexer.cs +++ b/src/Umbraco.Examine/UmbracoContentIndexer.cs @@ -212,7 +212,7 @@ namespace Umbraco.Examine var filtered = c.RawQuery(rawQuery); var results = searcher.Search(filtered); - ProfilingLogger.Logger.Debug(GetType(), $"DeleteFromIndex with query: {rawQuery} (found {results.TotalItemCount} results)"); + ProfilingLogger.Logger.Debug(GetType(), "DeleteFromIndex with query: {Query} (found {TotalItems} results)", rawQuery, results.TotalItemCount); //need to queue a delete item for each one found foreach (var r in results) diff --git a/src/Umbraco.Examine/UmbracoExamineIndexer.cs b/src/Umbraco.Examine/UmbracoExamineIndexer.cs index 0219ace270..64fd7b5c71 100644 --- a/src/Umbraco.Examine/UmbracoExamineIndexer.cs +++ b/src/Umbraco.Examine/UmbracoExamineIndexer.cs @@ -162,7 +162,7 @@ namespace Umbraco.Examine /// public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config) { - ProfilingLogger.Logger.Debug(GetType(), () => $"{name} indexer initializing"); + ProfilingLogger.Logger.Debug(GetType(), "{IndexerName} indexer initializing", name); if (config["enableDefaultEventHandler"] != null && bool.TryParse(config["enableDefaultEventHandler"], out var enabled)) { @@ -331,11 +331,11 @@ namespace Umbraco.Examine /// /// overridden for logging /// - /// - protected override void OnIndexingError(IndexingErrorEventArgs e) + /// + protected override void OnIndexingError(IndexingErrorEventArgs ex) { - ProfilingLogger.Logger.Error(GetType(), e.Message, e.InnerException); - base.OnIndexingError(e); + ProfilingLogger.Logger.Error(GetType(), ex.InnerException, ex.Message); + base.OnIndexingError(ex); } /// @@ -359,7 +359,12 @@ namespace Umbraco.Examine } } - ProfilingLogger.Logger.Debug(GetType(), () => $"Write lucene doc id:{docArgs.ValueSet.Id}, category:{docArgs.ValueSet.Category}, type:{docArgs.ValueSet.ItemType}"); + ProfilingLogger.Logger.Debug(GetType(), + "Write lucene doc id:{DocumentId}, category:{DocumentCategory}, type:{DocumentItemType}", + docArgs.ValueSet.Id, + docArgs.ValueSet.Category, + docArgs.ValueSet.ItemType); + base.OnDocumentWriting(docArgs); } @@ -369,7 +374,10 @@ namespace Umbraco.Examine /// protected override void AddDocument(Document doc, IndexItem item, IndexWriter writer) { - ProfilingLogger.Logger.Debug(GetType(), () => $"AddDocument {item.ValueSet.Id} with type {item.ValueSet.ItemType}"); + ProfilingLogger.Logger.Debug(GetType(), + "AddDocument {DocumentId} with type {DocumentItemType}", + item.ValueSet.Id, + item.ValueSet.ItemType); base.AddDocument(doc, item, writer); } diff --git a/src/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj b/src/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj index 19236e0163..7c8968d93b 100644 --- a/src/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj +++ b/src/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj @@ -61,7 +61,7 @@ - + diff --git a/src/Umbraco.Tests.Benchmarks/app.config b/src/Umbraco.Tests.Benchmarks/app.config index d71468cbdb..227af0f591 100644 --- a/src/Umbraco.Tests.Benchmarks/app.config +++ b/src/Umbraco.Tests.Benchmarks/app.config @@ -5,10 +5,6 @@ - - - - diff --git a/src/Umbraco.Tests/App.config b/src/Umbraco.Tests/App.config index 24c1445f01..f76f6b73b6 100644 --- a/src/Umbraco.Tests/App.config +++ b/src/Umbraco.Tests/App.config @@ -107,10 +107,6 @@ - - - - diff --git a/src/Umbraco.Tests/Composing/TypeFinderTests.cs b/src/Umbraco.Tests/Composing/TypeFinderTests.cs index 8c7c1f2d07..955f6f94c8 100644 --- a/src/Umbraco.Tests/Composing/TypeFinderTests.cs +++ b/src/Umbraco.Tests/Composing/TypeFinderTests.cs @@ -356,7 +356,6 @@ namespace Umbraco.Tests.Composing "Dynamic,", "HtmlDiff,", "Iesi.Collections,", - "log4net,", "Microsoft.", "Newtonsoft.", "NHibernate.", @@ -379,7 +378,8 @@ namespace Umbraco.Tests.Composing "ICSharpCode.", "CookComputing.", /* Mono */ - "MonoDevelop.NUnit" + "MonoDevelop.NUnit", + "Serilog." }; public static IEnumerable FindClassesOfTypeWithAttribute() diff --git a/src/Umbraco.Tests/Persistence/LocksTests.cs b/src/Umbraco.Tests/Persistence/LocksTests.cs index 18113955cf..4dfb90c8fd 100644 --- a/src/Umbraco.Tests/Persistence/LocksTests.cs +++ b/src/Umbraco.Tests/Persistence/LocksTests.cs @@ -14,7 +14,7 @@ namespace Umbraco.Tests.Persistence { [TestFixture] [Timeout(60000)] - [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, Logger = UmbracoTestOptions.Logger.Log4Net)] + [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, Logger = UmbracoTestOptions.Logger.Serilog)] public class LocksTests : TestWithDatabaseBase { protected override void Initialize() diff --git a/src/Umbraco.Tests/TestHelpers/ConsoleLogger.cs b/src/Umbraco.Tests/TestHelpers/ConsoleLogger.cs index d6dfb2d48a..9caa4b2aa1 100644 --- a/src/Umbraco.Tests/TestHelpers/ConsoleLogger.cs +++ b/src/Umbraco.Tests/TestHelpers/ConsoleLogger.cs @@ -1,82 +1,93 @@ using System; -using System.Linq; using Umbraco.Core.Logging; namespace Umbraco.Tests.TestHelpers { public class ConsoleLogger : ILogger { - public void Error(Type reporting, string message, Exception exception) + public void Fatal(Type reporting, Exception exception, string message) { - Console.WriteLine("INFO {0} - {1}", reporting.Name, message); + Console.WriteLine("FATAL {0} - {1}", reporting.Name, message); Console.WriteLine(exception); } + public void Fatal(Type reporting, Exception exception) + { + Console.WriteLine("FATAL {0}", reporting.Name); + Console.WriteLine(exception); + } + + public void Fatal(Type reporting, string message) + { + Console.WriteLine("FATAL {0} - {1}", reporting.Name, message); + } + + public void Fatal(Type reporting, Exception exception, string format, params object[] args) + { + Console.WriteLine("FATAL {0} - {1}", reporting.Name, string.Format(format, args)); + Console.WriteLine(exception); + } + + public void Fatal(Type reporting, string format, params object[] args) + { + Console.WriteLine("FATAL {0} - {1}", reporting.Name, string.Format(format, args)); + } + + public void Error(Type reporting, Exception exception, string message) + { + Console.WriteLine("ERROR {0} - {1}", reporting.Name, message); + Console.WriteLine(exception); + } + + public void Error(Type reporting, Exception exception) + { + Console.WriteLine("ERROR {0}", reporting.Name); + Console.WriteLine(exception); + } + + public void Error(Type reporting, string message) + { + Console.WriteLine("ERROR {0} - {1}", reporting.Name, message); + } + + public void Error(Type reporting, Exception exception, string format, params object[] args) + { + Console.WriteLine("ERROR {0} - {1}", reporting.Name, string.Format(format, args)); + Console.WriteLine(exception); + } + + public void Error(Type reporting, string format, params object[] args) + { + Console.WriteLine("ERROR {0} - {1}", reporting.Name, string.Format(format, args)); + } + public void Warn(Type reporting, string message) { Console.WriteLine("WARN {0} - {1}", reporting.Name, message); } - public void Warn(Type reporting, Func messageBuilder) - { - Console.WriteLine("WARN {0} - {1}", reporting.Name, messageBuilder()); - } - public void Warn(Type reporting, string format, params object[] args) { Console.WriteLine("WARN {0} - {1}", reporting.Name, string.Format(format, args)); } - public void Warn(Type reporting, string format, params Func[] args) - { - Console.WriteLine("WARN {0} - {1}", reporting.Name, string.Format(format, args.Select(x => x()).ToArray())); - } - public void Warn(Type reporting, Exception exception, string message) { Console.WriteLine("WARN {0} - {1}", reporting.Name, message); Console.WriteLine(exception); } - - public void Warn(Type reporting, Exception exception, Func messageBuilder) - { - Console.WriteLine("WARN {0} - {1}", reporting.Name, messageBuilder()); - Console.WriteLine(exception); - } - + public void Warn(Type reporting, Exception exception, string format, params object[] args) { Console.WriteLine("WARN {0} - {1}", reporting.Name, string.Format(format, args)); Console.WriteLine(exception); } - public void Warn(Type reporting, Exception exception, string format, params Func[] args) - { - Console.WriteLine("WARN {0} - {1}", reporting.Name, string.Format(format, args.Select(x => x()).ToArray())); - Console.WriteLine(exception); - } - - public void WarnWithException(Type reporting, string format, Exception e, params Func[] args) - { - Console.WriteLine("WARN {0} - {1}", reporting.Name, string.Format(format, args.Select(x => x()).ToArray())); - Console.WriteLine(e); - } - - public void Info(Type reporting, Func generateMessage) - { - Console.WriteLine("INFO {0} - {1}", reporting.Name, generateMessage()); - } - public void Info(Type reporting, string format, params object[] args) { Console.WriteLine("INFO {0} - {1}", reporting.Name, string.Format(format, args)); } - public void Info(Type reporting, string format, params Func[] args) - { - Console.WriteLine("INFO {0} - {1}", reporting.Name, string.Format(format, args.Select(x => x()).ToArray())); - } - public void Info(Type reporting, string message) { Console.WriteLine("INFO {0} - {1}", reporting.Name, message); @@ -87,19 +98,19 @@ namespace Umbraco.Tests.TestHelpers Console.WriteLine("DEBUG {0} - {1}", reporting.Name, message); } - public void Debug(Type reporting, Func messageBuilder) - { - Console.WriteLine("DEBUG {0} - {1}", reporting.Name, messageBuilder()); - } - public void Debug(Type reporting, string format, params object[] args) { Console.WriteLine("DEBUG {0} - {1}", reporting.Name, string.Format(format, args)); } - public void Debug(Type reporting, string format, params Func[] args) + public void Verbose(Type reporting, string message) { - Console.WriteLine("DEBUG {0} - {1}", reporting.Name, string.Format(format, args.Select(x => x()).ToArray())); + Console.WriteLine("VERBOSE {0} - {1}", reporting.Name, message); + } + + public void Verbose(Type reporting, string format, params object[] args) + { + Console.WriteLine("VERBOSE {0} - {1}", reporting.Name, string.Format(format, args)); } } } diff --git a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs index 00457d510d..8ad318faa5 100644 --- a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs +++ b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs @@ -338,7 +338,7 @@ namespace Umbraco.Tests.TestHelpers } catch (Exception ex) { - Logger.Error("Could not remove the old database file", ex); + Logger.Error(ex, "Could not remove the old database file"); // swallow this exception - that's because a sub class might require further teardown logic onFail?.Invoke(ex); diff --git a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs index 7d9dd34491..7d0f53d404 100644 --- a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs +++ b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs @@ -162,9 +162,9 @@ namespace Umbraco.Tests.Testing Container.RegisterSingleton(f => Mock.Of()); Container.RegisterSingleton(f => Mock.Of()); } - else if (option == UmbracoTestOptions.Logger.Log4Net) + else if (option == UmbracoTestOptions.Logger.Serilog) { - Container.RegisterSingleton(f => new Logger(new FileInfo(TestHelper.MapPathForTest("~/unit-test-log4net.config")))); + Container.RegisterSingleton(f => new Logger(new FileInfo(TestHelper.MapPathForTest("~/unit-test.config")))); Container.RegisterSingleton(f => new LogProfiler(f.GetInstance())); } diff --git a/src/Umbraco.Tests/Testing/UmbracoTestOptions.cs b/src/Umbraco.Tests/Testing/UmbracoTestOptions.cs index 3f57ac14d8..deefd33946 100644 --- a/src/Umbraco.Tests/Testing/UmbracoTestOptions.cs +++ b/src/Umbraco.Tests/Testing/UmbracoTestOptions.cs @@ -6,8 +6,8 @@ { // pure mocks Mock, - // log4net for tests - Log4Net + // Serilog for tests + Serilog } public enum Database diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 4f6ad05e1b..19e894cd56 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -80,7 +80,6 @@ - @@ -107,7 +106,6 @@ - @@ -520,7 +518,7 @@ Designer - + Always diff --git a/src/Umbraco.Tests/UmbracoExamine/ExamineBaseTest.cs b/src/Umbraco.Tests/UmbracoExamine/ExamineBaseTest.cs index b56ad43ff5..d512e53b9c 100644 --- a/src/Umbraco.Tests/UmbracoExamine/ExamineBaseTest.cs +++ b/src/Umbraco.Tests/UmbracoExamine/ExamineBaseTest.cs @@ -14,7 +14,7 @@ namespace Umbraco.Tests.UmbracoExamine [OneTimeSetUp] public void InitializeFixture() { - var logger = new Logger(new FileInfo(TestHelper.MapPathForTest("~/unit-test-log4net.config"))); + var logger = new Logger(new FileInfo(TestHelper.MapPathForTest("~/unit-test.config"))); _profilingLogger = new ProfilingLogger(logger, new LogProfiler(logger)); } diff --git a/src/Umbraco.Tests/unit-test-log4net.config b/src/Umbraco.Tests/unit-test-log4net.config deleted file mode 100644 index 34890fd583..0000000000 --- a/src/Umbraco.Tests/unit-test-log4net.config +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Umbraco.Tests/unit-test-logger.config b/src/Umbraco.Tests/unit-test-logger.config new file mode 100644 index 0000000000..62fa1353b2 --- /dev/null +++ b/src/Umbraco.Tests/unit-test-logger.config @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditors.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditors.directive.js index edb08f1066..c852228205 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditors.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditors.directive.js @@ -206,6 +206,10 @@ removeEditor(args.editor); })); + evts.push(eventsService.on("appState.editors.closeAll", function (name, args) { + scope.editors = []; + })); + //ensure to unregister from all events! scope.$on('$destroy', function () { for (var e in evts) { diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valformmanager.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valformmanager.directive.js index 726103caf9..948702a4e3 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valformmanager.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valformmanager.directive.js @@ -12,7 +12,7 @@ * Another thing this directive does is to ensure that any .control-group that contains form elements that are invalid will * be marked with the 'error' css class. This ensures that labels included in that control group are styled correctly. **/ -function valFormManager(serverValidationManager, $rootScope, $log, $timeout, notificationsService, eventsService, $routeParams, navigationService) { +function valFormManager(serverValidationManager, $rootScope, $timeout, $location, overlayService, eventsService, $routeParams, navigationService, editorService, localizationService) { var SHOW_VALIDATION_CLASS_NAME = "show-validation"; var SAVING_EVENT_NAME = "formSubmitting"; @@ -44,6 +44,22 @@ function valFormManager(serverValidationManager, $rootScope, $log, $timeout, not }, link: function (scope, element, attr, formCtrl) { + var labels = {}; + + var labelKeys = [ + "prompt_unsavedChanges", + "prompt_unsavedChangesWarning", + "prompt_discardChanges", + "prompt_stay" + ]; + + localizationService.localizeMany(labelKeys).then(function (values) { + labels.unsavedChangesTitle = values[0]; + labels.unsavedChangesContent = values[1]; + labels.discardChangesButton = values[2]; + labels.stayButton = values[3]; + }); + //watch the list of validation errors to notify the application of any validation changes scope.$watch(function () { //the validators are in the $error collection: https://docs.angularjs.org/api/ng/type/form.FormController#$error @@ -104,28 +120,62 @@ function valFormManager(serverValidationManager, $rootScope, $log, $timeout, not formCtrl.$setPristine(); })); + var confirmed = false; + //This handles the 'unsaved changes' dialog which is triggered when a route is attempting to be changed but // the form has pending changes var locationEvent = $rootScope.$on('$locationChangeStart', function(event, nextLocation, currentLocation) { - if (!formCtrl.$dirty || isSavingNewItem) { + + var infiniteEditors = editorService.getEditors(); + + if (!formCtrl.$dirty && infiniteEditors.length === 0 || isSavingNewItem && infiniteEditors.length === 0) { + confirmed = true; return; } var nextPath = nextLocation.split("#")[1]; - if (nextPath) { + if (nextPath && !confirmed) { if (navigationService.isRouteChangingNavigation(currentLocation, nextLocation)) { - if (!notificationsService.hasView()) { - if (nextPath.indexOf("%253") || nextPath.indexOf("%252")) { - nextPath = decodeURIComponent(nextPath); - } - - var msg = { view: "confirmroutechange", args: { path: nextPath, listener: locationEvent } }; - notificationsService.add(msg); + if (nextPath.indexOf("%253") || nextPath.indexOf("%252")) { + nextPath = decodeURIComponent(nextPath); } + // Open discard changes overlay + var overlay = { + "view": "default", + "title": labels.unsavedChangesTitle, + "content": labels.unsavedChangesContent, + "disableBackdropClick": true, + "submitButtonLabel": labels.stayButton, + "closeButtonLabel": labels.discardChangesButton, + submit: function() { + overlayService.close(); + }, + close: function() { + // close all editors + editorService.closeAll(); + // allow redirection + navigationService.clearSearch(); + //we need to break the path up into path and query + var parts = nextPath.split("?"); + var query = {}; + if (parts.length > 1) { + _.each(parts[1].split("&"), function(q) { + var keyVal = q.split("="); + query[keyVal[0]] = keyVal[1]; + }); + } + $location.path(parts[0]).search(query); + overlayService.close(); + confirmed = true; + } + }; + + overlayService.open(overlay); + //prevent the route! event.preventDefault(); diff --git a/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js index 16d6cc20c9..7b80694e3b 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js @@ -682,7 +682,7 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, notifica // /belle/#/content/edit/9876 (where 9876 is the new id) //clear the query strings - navigationService.clearSearch(); + navigationService.clearSearch(["cculture"]); //change to new path $location.path("/" + $routeParams.section + "/" + $routeParams.tree + "/" + $routeParams.method + "/" + id); diff --git a/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js b/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js index 453785f537..eab167c2ec 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js @@ -53,7 +53,7 @@ * @methodOf umbraco.services.editorService * * @description - * Opens a media editor in infinite editing, the submit callback returns the updated content item + * Method to close the latest opened editor */ function close() { var length = editors.length; @@ -69,6 +69,26 @@ eventsService.emit("appState.editors.close", args); } + /** + * @ngdoc method + * @name umbraco.services.editorService#closeAll + * @methodOf umbraco.services.editorService + * + * @description + * Method to close all open editors + */ + function closeAll() { + + editors = []; + + var args = { + editors: editors, + editor: null + }; + + eventsService.emit("appState.editors.closeAll", args); + } + /** * @ngdoc method * @name umbraco.services.editorService#contentEditor @@ -454,6 +474,7 @@ getEditors: getEditors, open: open, close: close, + closeAll: closeAll, mediaEditor: mediaEditor, contentEditor: contentEditor, contentPicker: contentPicker, diff --git a/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js b/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js index 13940b5124..3ad2864fa8 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js @@ -30,6 +30,7 @@ function navigationService($rootScope, $route, $routeParams, $log, $location, $q //A list of query strings defined that when changed will not cause a reload of the route var nonRoutingQueryStrings = ["mculture", "cculture"]; + var retainedQueryStrings = ['mculture']; //used to track the current dialog object var currentDialog = null; @@ -192,8 +193,8 @@ function navigationService($rootScope, $route, $routeParams, $log, $location, $q * @description * utility to clear the querystring/search params while maintaining a known list of parameters that should be maintained throughout the app */ - clearSearch: function () { - var toRetain = ["mculture"]; + clearSearch: function (toRetain) { + var toRetain = _.union(retainedQueryStrings, toRetain); var currentSearch = $location.search(); $location.search(''); _.each(toRetain, function (k) { diff --git a/src/Umbraco.Web.UI.Client/src/common/services/overlay.service.js b/src/Umbraco.Web.UI.Client/src/common/services/overlay.service.js index a202c6ca6b..16d51add92 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/overlay.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/overlay.service.js @@ -10,17 +10,37 @@ function overlayService(eventsService, backdropService) { - function open(overlay) { + var currentOverlay = null; + + function open(newOverlay) { + + // prevent two open overlays at the same time + if(currentOverlay) { + return; + } + + var backdropOptions = {}; + var overlay = newOverlay; + + // set the default overlay position to center if(!overlay.position) { overlay.position = "center"; } + + // option to disable backdrop clicks + if(overlay.disableBackdropClick) { + backdropOptions.disableEventsOnClick = true; + } + overlay.show = true; - backdropService.open(); + backdropService.open(backdropOptions); + currentOverlay = overlay; eventsService.emit("appState.overlay", overlay); } function close() { backdropService.close(); + currentOverlay = null; eventsService.emit("appState.overlay", null); } diff --git a/src/Umbraco.Web.UI.Client/src/controllers/main.controller.js b/src/Umbraco.Web.UI.Client/src/controllers/main.controller.js index a47f552c9d..24318cce02 100644 --- a/src/Umbraco.Web.UI.Client/src/controllers/main.controller.js +++ b/src/Umbraco.Web.UI.Client/src/controllers/main.controller.js @@ -8,7 +8,7 @@ * The main application controller * */ -function MainController($scope, $rootScope, $location, $routeParams, $timeout, $http, $log, appState, treeService, notificationsService, userService, navigationService, historyService, updateChecker, assetsService, eventsService, umbRequestHelper, tmhDynamicLocale, localStorageService, tourService, editorService) { +function MainController($scope, $location, appState, treeService, notificationsService, userService, historyService, updateChecker, assetsService, eventsService, tmhDynamicLocale, localStorageService, editorService, overlayService) { //the null is important because we do an explicit bool check on this in the view $scope.authenticated = null; @@ -87,6 +87,8 @@ function MainController($scope, $rootScope, $location, $routeParams, $timeout, $ $location.path("/").search(""); historyService.removeAll(); treeService.clearCache(); + editorService.closeAll(); + overlayService.close(); //if the user changed, clearout local storage too - could contain sensitive data localStorageService.clearAll(); diff --git a/src/Umbraco.Web.UI.Client/src/less/components/editor.less b/src/Umbraco.Web.UI.Client/src/less/components/editor.less index 72c1ea5209..3a39ec9e1c 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/editor.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/editor.less @@ -66,7 +66,7 @@ background: @white; position: absolute; padding: 0 20px; - z-index: @zindexFixedNavbar; + z-index: @zIndexEditor; border-bottom: 1px solid @gray-9; width: 100%; box-sizing: border-box; diff --git a/src/Umbraco.Web.UI.Client/src/less/components/editor/umb-editor.less b/src/Umbraco.Web.UI.Client/src/less/components/editor/umb-editor.less index 79d941bbac..640a276443 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/editor/umb-editor.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/editor/umb-editor.less @@ -13,7 +13,7 @@ bottom: 0; left: 0; background: @gray-10; - z-index: 100; + z-index: @zIndexEditor; } .umb-editor--animating { @@ -43,5 +43,5 @@ right: 0; left: 0; background: rgba(0,0,0,0.2); - z-index: 100; + z-index: @zIndexEditor; } \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/less/components/overlays.less b/src/Umbraco.Web.UI.Client/src/less/components/overlays.less index ee865f1321..3fbe32134b 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/overlays.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/overlays.less @@ -4,7 +4,7 @@ background: @white; z-index: @zindexUmbOverlay; animation: fadeIn 0.2s; - box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23); + box-shadow: 0 10px 50px rgba(0,0,0,0.1), 0 6px 20px rgba(0,0,0,0.16); } .umb-overlay__form { diff --git a/src/Umbraco.Web.UI.Client/src/less/variables.less b/src/Umbraco.Web.UI.Client/src/less/variables.less index c7d2e8d6ed..c6e87a74fe 100644 --- a/src/Umbraco.Web.UI.Client/src/less/variables.less +++ b/src/Umbraco.Web.UI.Client/src/less/variables.less @@ -319,6 +319,7 @@ // ------------------------- // Used for a bird's eye view of components dependent on the z-axis // Try to avoid customizing these :) +@zIndexEditor: 100; @zIndexTree: 100; @zindexDropdown: 1000; @zindexPopover: 1010; diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/default/default.html b/src/Umbraco.Web.UI.Client/src/views/common/overlays/default/default.html new file mode 100644 index 0000000000..04201dde70 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/default/default.html @@ -0,0 +1 @@ +
{{model.content}}
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-variant-state.html b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-variant-state.html index 3a41f0623d..6b1d5af89e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-variant-state.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-variant-state.html @@ -1,6 +1,6 @@ -
-
-
-
-
-
+ + + + + + diff --git a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-header.html b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-header.html index 0914346189..d4a540892e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-header.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-header.html @@ -60,16 +60,9 @@ {{variant.language.name}} - - - - - - + -
Open in split view
-
diff --git a/src/Umbraco.Web.UI.Client/src/views/content/overlays/publish.html b/src/Umbraco.Web.UI.Client/src/views/content/overlays/publish.html index 46ad4e7299..b49046feac 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/overlays/publish.html +++ b/src/Umbraco.Web.UI.Client/src/views/content/overlays/publish.html @@ -28,7 +28,7 @@
- +
diff --git a/src/Umbraco.Web.UI.Client/src/views/content/overlays/save.html b/src/Umbraco.Web.UI.Client/src/views/content/overlays/save.html index 0515bd878e..dbe4c8fe24 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/overlays/save.html +++ b/src/Umbraco.Web.UI.Client/src/views/content/overlays/save.html @@ -28,7 +28,7 @@
- +
diff --git a/src/Umbraco.Web.UI/Properties/AssemblyInfo.cs b/src/Umbraco.Web.UI/Properties/AssemblyInfo.cs index ccedc337cd..53f2769d0e 100644 --- a/src/Umbraco.Web.UI/Properties/AssemblyInfo.cs +++ b/src/Umbraco.Web.UI/Properties/AssemblyInfo.cs @@ -8,6 +8,3 @@ using System.Runtime.InteropServices; [assembly: ComVisible(false)] [assembly: Guid("A87ADD48-9DB5-4068-BCC6-377CC54E7AE4")] - -// log4net -[assembly: log4net.Config.XmlConfigurator(Watch = false)] diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 499a98554a..08bee948ee 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -90,16 +90,14 @@ - - - + - - All + + all @@ -109,7 +107,7 @@ - 8.0.0-alpha.20 + 8.0.0-alpha.22 @@ -260,9 +258,6 @@ Designer - - log4net.config - FileSystemProviders.config @@ -276,6 +271,12 @@ HealthChecks.config Designer + + Designer + + + Designer + umbracoSettings.config Designer @@ -489,7 +490,6 @@ Designer - diff --git a/src/Umbraco.Web.UI/config/log4net.Release.config b/src/Umbraco.Web.UI/config/log4net.Release.config deleted file mode 100644 index 9993f88371..0000000000 --- a/src/Umbraco.Web.UI/config/log4net.Release.config +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Umbraco.Web.UI/config/log4net.config b/src/Umbraco.Web.UI/config/log4net.config deleted file mode 100644 index d9d107cd8d..0000000000 --- a/src/Umbraco.Web.UI/config/log4net.config +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Umbraco.Web.UI/config/serilog.config b/src/Umbraco.Web.UI/config/serilog.config new file mode 100644 index 0000000000..a0a8f8658a --- /dev/null +++ b/src/Umbraco.Web.UI/config/serilog.config @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/src/Umbraco.Web.UI/config/serilog.user.config b/src/Umbraco.Web.UI/config/serilog.user.config new file mode 100644 index 0000000000..c308c25104 --- /dev/null +++ b/src/Umbraco.Web.UI/config/serilog.user.config @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Umbraco.Web.UI/config/umbracoSettings.config b/src/Umbraco.Web.UI/config/umbracoSettings.config index f14d43e5d2..fb400faf85 100644 --- a/src/Umbraco.Web.UI/config/umbracoSettings.config +++ b/src/Umbraco.Web.UI/config/umbracoSettings.config @@ -167,7 +167,7 @@ diff --git a/src/Umbraco.Web.UI/web.Template.config b/src/Umbraco.Web.UI/web.Template.config index 57720033ab..f0da7ebe62 100644 --- a/src/Umbraco.Web.UI/web.Template.config +++ b/src/Umbraco.Web.UI/web.Template.config @@ -12,8 +12,7 @@
-
- +
@@ -39,7 +38,6 @@ - @@ -58,7 +56,6 @@ - @@ -242,10 +239,6 @@ - - - - diff --git a/src/Umbraco.Web/Cache/MediaCacheRefresher.cs b/src/Umbraco.Web/Cache/MediaCacheRefresher.cs index 7c64f3378b..4abf7d8787 100644 --- a/src/Umbraco.Web/Cache/MediaCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/MediaCacheRefresher.cs @@ -47,15 +47,17 @@ namespace Umbraco.Web.Cache if (anythingChanged) { - var mediaCache = CacheHelper.IsolatedRuntimeCache.GetCache(); - Current.ApplicationCache.ClearPartialViewCache(); + var mediaCache = CacheHelper.IsolatedRuntimeCache.GetCache(); + foreach (var payload in payloads) { if (payload.ChangeTypes == TreeChangeTypes.Remove) _idkMap.ClearCache(payload.Id); + if (!mediaCache) continue; + // repository cache // it *was* done for each pathId but really that does not make sense // only need to do it for the current media diff --git a/src/Umbraco.Web/Components/DatabaseServerRegistrarAndMessengerComponent.cs b/src/Umbraco.Web/Components/DatabaseServerRegistrarAndMessengerComponent.cs index 0577c6cdd9..123941d6a2 100644 --- a/src/Umbraco.Web/Components/DatabaseServerRegistrarAndMessengerComponent.cs +++ b/src/Umbraco.Web/Components/DatabaseServerRegistrarAndMessengerComponent.cs @@ -237,7 +237,7 @@ namespace Umbraco.Web.Components } catch (Exception ex) { - _logger.Error("Failed to update server record in database.", ex); + _logger.Error(ex, "Failed to update server record in database."); return false; // probably stop if we have an error } } diff --git a/src/Umbraco.Web/Editors/AuthenticationController.cs b/src/Umbraco.Web/Editors/AuthenticationController.cs index cdce23532d..c60716ad39 100644 --- a/src/Umbraco.Web/Editors/AuthenticationController.cs +++ b/src/Umbraco.Web/Editors/AuthenticationController.cs @@ -416,20 +416,19 @@ namespace Umbraco.Web.Editors var lockedOut = await UserManager.IsLockedOutAsync(model.UserId); if (lockedOut) { - Logger.Info(() => - $"User {model.UserId} is currently locked out, unlocking and resetting AccessFailedCount"); + Logger.Info("User {UserId} is currently locked out, unlocking and resetting AccessFailedCount", model.UserId); //var user = await UserManager.FindByIdAsync(model.UserId); var unlockResult = await UserManager.SetLockoutEndDateAsync(model.UserId, DateTimeOffset.Now); if (unlockResult.Succeeded == false) { - Logger.Warn(() => $"Could not unlock for user {model.UserId} - error {unlockResult.Errors.First()}"); + Logger.Warn("Could not unlock for user {UserId} - error {UnlockError}", model.UserId, unlockResult.Errors.First()); } var resetAccessFailedCountResult = await UserManager.ResetAccessFailedCountAsync(model.UserId); if (resetAccessFailedCountResult.Succeeded == false) { - Logger.Warn(() => $"Could not reset access failed count {model.UserId} - error {unlockResult.Errors.First()}"); + Logger.Warn("Could not reset access failed count {UserId} - error {UnlockError}", model.UserId, unlockResult.Errors.First()); } } @@ -455,7 +454,7 @@ namespace Umbraco.Web.Editors Core.Constants.Security.BackOfficeAuthenticationType, Core.Constants.Security.BackOfficeExternalAuthenticationType); - Logger.Info(() => $"User {(User.Identity == null ? "UNKNOWN" : User.Identity.Name)} from IP address {owinContext.Request.RemoteIpAddress} has logged out"); + Logger.Info("User {UserName} from IP address {RemoteIpAddress} has logged out", User.Identity == null ? "UNKNOWN" : User.Identity.Name, owinContext.Request.RemoteIpAddress); if (UserManager != null) { diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index b96926af4f..8c3cc5f557 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -745,7 +745,7 @@ namespace Umbraco.Web.Editors //Check if a mandatory language is missing from being published var variant = cultureVariants.First(x => x.Culture == lang.IsoCode); - var isPublished = contentItem.PersistedContent.IsCultureAvailable(lang.IsoCode) && contentItem.PersistedContent.IsCulturePublished(lang.IsoCode); + var isPublished = contentItem.PersistedContent.IsCulturePublished(lang.IsoCode); var isPublishing = variant.Publish; if (!isPublished && !isPublishing) @@ -966,7 +966,7 @@ namespace Umbraco.Web.Editors } catch (Exception ex) { - Logger.Error("Could not update content sort order", ex); + Logger.Error(ex, "Could not update content sort order"); throw; } } diff --git a/src/Umbraco.Web/Editors/ContentTypeController.cs b/src/Umbraco.Web/Editors/ContentTypeController.cs index 79079265af..ea385ceba6 100644 --- a/src/Umbraco.Web/Editors/ContentTypeController.cs +++ b/src/Umbraco.Web/Editors/ContentTypeController.cs @@ -278,7 +278,7 @@ namespace Umbraco.Web.Editors var tryCreateTemplate = Services.FileService.CreateTemplateForContentType(ctSave.Alias, ctSave.Name); if (tryCreateTemplate == false) { - Logger.Warn(() => $"Could not create a template for the Content Type: {ctSave.Alias}, status: {tryCreateTemplate.Result.Result}"); + Logger.Warn("Could not create a template for the Content Type: {ContentTypeAlias}, status: {CreateTemplateResult}", ctSave.Alias, tryCreateTemplate.Result.Result); } template = tryCreateTemplate.Result.Entity; } @@ -487,7 +487,7 @@ namespace Umbraco.Web.Editors } catch (Exception ex) { - Current.Logger.Error(typeof(ContentTypeController), "Error cleaning up temporary udt file in App_Data: " + ex.Message, ex); + Current.Logger.Error(ex, "Error cleaning up temporary udt file in App_Data: {File}", filePath); } return Request.CreateResponse(HttpStatusCode.OK); diff --git a/src/Umbraco.Web/Editors/DashboardController.cs b/src/Umbraco.Web/Editors/DashboardController.cs index 8e40e40213..230fbbea36 100644 --- a/src/Umbraco.Web/Editors/DashboardController.cs +++ b/src/Umbraco.Web/Editors/DashboardController.cs @@ -75,7 +75,7 @@ namespace Umbraco.Web.Editors } catch (HttpRequestException ex) { - Logger.Debug(() => $"Error getting dashboard content from '{url}': {ex.Message}\n{ex.InnerException}"); + Logger.Error(ex.InnerException ?? ex, "Error getting dashboard content from '{Url}'", url); //it's still new JObject() - we return it like this to avoid error codes which triggers UI warnings ApplicationCache.RuntimeCache.InsertCacheItem(key, () => result, new TimeSpan(0, 5, 0)); @@ -116,7 +116,7 @@ namespace Umbraco.Web.Editors } catch (HttpRequestException ex) { - Logger.Debug(() => string.Format("Error getting dashboard CSS from '{0}': {1}\n{2}", url, ex.Message, ex.InnerException)); + Logger.Error(ex.InnerException ?? ex, "Error getting dashboard CSS from '{Url}'", url); //it's still string.Empty - we return it like this to avoid error codes which triggers UI warnings ApplicationCache.RuntimeCache.InsertCacheItem(key, () => result, new TimeSpan(0, 5, 0)); diff --git a/src/Umbraco.Web/Editors/DictionaryController.cs b/src/Umbraco.Web/Editors/DictionaryController.cs index faaad9407c..7d846e68ec 100644 --- a/src/Umbraco.Web/Editors/DictionaryController.cs +++ b/src/Umbraco.Web/Editors/DictionaryController.cs @@ -90,9 +90,9 @@ namespace Umbraco.Web.Editors return Request.CreateResponse(HttpStatusCode.OK, item.Id); } - catch (Exception exception) + catch (Exception ex) { - Logger.Error(GetType(), "Error creating dictionary", exception); + Logger.Error(GetType(), ex, "Error creating dictionary with {Name} under {ParentId}", key, parentId); return Request.CreateNotificationValidationErrorResponse("Error creating dictionary item"); } } @@ -175,9 +175,9 @@ namespace Umbraco.Web.Editors return model; } - catch (Exception e) + catch (Exception ex) { - Logger.Error(GetType(), "Error saving dictionary", e); + Logger.Error(GetType(), ex, "Error saving dictionary with {Name} under {ParentId}", dictionary.Name, dictionary.ParentId); throw new HttpResponseException(Request.CreateNotificationValidationErrorResponse("Something went wrong saving dictionary")); } } diff --git a/src/Umbraco.Web/Editors/ExamineManagementController.cs b/src/Umbraco.Web/Editors/ExamineManagementController.cs index c4ef00eff8..cfc25454a4 100644 --- a/src/Umbraco.Web/Editors/ExamineManagementController.cs +++ b/src/Umbraco.Web/Editors/ExamineManagementController.cs @@ -171,7 +171,7 @@ namespace Umbraco.Web.Editors { //ensure it's not listening indexer.IndexOperationComplete -= Indexer_IndexOperationComplete; - Logger.Error("An error occurred rebuilding index", ex); + Logger.Error(ex, "An error occurred rebuilding index"); var response = Request.CreateResponse(HttpStatusCode.Conflict); response.Content = new diff --git a/src/Umbraco.Web/Editors/MediaController.cs b/src/Umbraco.Web/Editors/MediaController.cs index 7b4054deec..70aa7e4da8 100644 --- a/src/Umbraco.Web/Editors/MediaController.cs +++ b/src/Umbraco.Web/Editors/MediaController.cs @@ -562,7 +562,7 @@ namespace Umbraco.Web.Editors } catch (Exception ex) { - Logger.Error("Could not update media sort order", ex); + Logger.Error(ex, "Could not update media sort order"); throw; } } diff --git a/src/Umbraco.Web/Editors/PackageInstallController.cs b/src/Umbraco.Web/Editors/PackageInstallController.cs index fec358f113..d2a0df68ba 100644 --- a/src/Umbraco.Web/Editors/PackageInstallController.cs +++ b/src/Umbraco.Web/Editors/PackageInstallController.cs @@ -72,9 +72,9 @@ namespace Umbraco.Web.Editors installed.Delete(Security.GetUserId().ResultOr(0)); } } - catch (Exception e) + catch (Exception ex) { - Logger.Error("Failed to uninstall.", e); + Logger.Error(ex, "Failed to uninstall."); throw; } @@ -188,7 +188,7 @@ namespace Umbraco.Web.Editors var actionsXml = new XmlDocument(); actionsXml.LoadXml("" + pack.Data.Actions + ""); - Logger.Debug(() => $"executing undo actions: {actionsXml.OuterXml}"); + Logger.Debug("Executing undo actions: {UndoActionsXml}", actionsXml.OuterXml); foreach (XmlNode n in actionsXml.DocumentElement.SelectNodes("//Action")) { @@ -199,13 +199,13 @@ namespace Umbraco.Web.Editors } catch (Exception ex) { - Logger.Error("An error occurred running undo actions", ex); + Logger.Error(ex, "An error occurred running undo actions"); } } } catch (Exception ex) { - Logger.Error("An error occurred running undo actions", ex); + Logger.Error(ex, "An error occurred running undo actions"); } } diff --git a/src/Umbraco.Web/Editors/PasswordChanger.cs b/src/Umbraco.Web/Editors/PasswordChanger.cs index 44042352bb..5034ce1950 100644 --- a/src/Umbraco.Web/Editors/PasswordChanger.cs +++ b/src/Umbraco.Web/Editors/PasswordChanger.cs @@ -93,7 +93,7 @@ namespace Umbraco.Web.Editors if (resetResult.Succeeded == false) { var errors = string.Join(". ", resetResult.Errors); - _logger.Warn(() => $"Could not reset user password {errors}"); + _logger.Warn("Could not reset user password {PasswordErrors}", errors); return Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Could not reset password, errors: " + errors, new[] { "resetPassword" }) }); } @@ -122,7 +122,7 @@ namespace Umbraco.Web.Editors if (changeResult.Succeeded == false) { var errors = string.Join(". ", changeResult.Errors); - _logger.Warn(() => $"Could not change user password {errors}"); + _logger.Warn("Could not change user password {PasswordErrors}", errors); return Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("Could not change password, errors: " + errors, new[] { "oldPassword" }) }); } return Attempt.Succeed(new PasswordChangedModel()); diff --git a/src/Umbraco.Web/HealthCheck/Checks/Config/ConfigurationService.cs b/src/Umbraco.Web/HealthCheck/Checks/Config/ConfigurationService.cs index c1d71d4180..8b080af88c 100644 --- a/src/Umbraco.Web/HealthCheck/Checks/Config/ConfigurationService.cs +++ b/src/Umbraco.Web/HealthCheck/Checks/Config/ConfigurationService.cs @@ -56,13 +56,13 @@ namespace Umbraco.Web.HealthCheck.Checks.Config Result = string.Format(xmlNode.Value ?? xmlNode.InnerText) }; } - catch (Exception exception) + catch (Exception ex) { - Current.Logger.Error("Error trying to get configuration value", exception); + Current.Logger.Error(ex, "Error trying to get configuration value"); return new ConfigurationServiceResult { Success = false, - Result = _textService.Localize("healthcheck/configurationServiceError", new[] { exception.Message }) + Result = _textService.Localize("healthcheck/configurationServiceError", new[] { ex.Message }) }; } } @@ -102,13 +102,13 @@ namespace Umbraco.Web.HealthCheck.Checks.Config xmlDocument.Save(_configFilePath); return new ConfigurationServiceResult { Success = true }; } - catch (Exception exception) + catch (Exception ex) { - Current.Logger.Error("Error trying to update configuration", exception); + Current.Logger.Error(ex, "Error trying to update configuration"); return new ConfigurationServiceResult { Success = false, - Result = _textService.Localize("healthcheck/configurationServiceError", new[] { exception.Message }) + Result = _textService.Localize("healthcheck/configurationServiceError", new[] { ex.Message }) }; } } diff --git a/src/Umbraco.Web/HealthCheck/Checks/DataIntegrity/DatabaseSchemaValidationHealthCheck.cs b/src/Umbraco.Web/HealthCheck/Checks/DataIntegrity/DatabaseSchemaValidationHealthCheck.cs index 569373f0bb..d3c60d4b59 100644 --- a/src/Umbraco.Web/HealthCheck/Checks/DataIntegrity/DatabaseSchemaValidationHealthCheck.cs +++ b/src/Umbraco.Web/HealthCheck/Checks/DataIntegrity/DatabaseSchemaValidationHealthCheck.cs @@ -42,11 +42,11 @@ namespace Umbraco.Web.HealthCheck.Checks.DataIntegrity { var results = _databaseBuilder.ValidateDatabaseSchema(); - _logger.Warn(typeof(DatabaseSchemaValidationHealthCheck), _textService.Localize("databaseSchemaValidationCheckDatabaseLogMessage")); + _logger.Warn(_textService.Localize("databaseSchemaValidationCheckDatabaseLogMessage")); foreach(var error in results.Errors) { - _logger.Warn(typeof(DatabaseSchemaValidationHealthCheck), error.Item1 + ": " + error.Item2); + _logger.Warn("{Error} : {ErrorDetail}", error.Item1, error.Item2); } if(results.Errors.Count > 0) diff --git a/src/Umbraco.Web/HealthCheck/HealthCheckController.cs b/src/Umbraco.Web/HealthCheck/HealthCheckController.cs index 14642ac843..6412409488 100644 --- a/src/Umbraco.Web/HealthCheck/HealthCheckController.cs +++ b/src/Umbraco.Web/HealthCheck/HealthCheckController.cs @@ -69,9 +69,9 @@ namespace Umbraco.Web.HealthCheck //Core.Logging.LogHelper.Debug("Running health check: " + check.Name); return check.GetStatus(); } - catch (Exception e) + catch (Exception ex) { - _logger.Error("Exception in health check: " + check.Name, e); + _logger.Error(ex, "Exception in health check: {HealthCheckName}" + check.Name); throw; } } diff --git a/src/Umbraco.Web/HealthCheck/HealthCheckResults.cs b/src/Umbraco.Web/HealthCheck/HealthCheckResults.cs index 74b44ea7b8..5962f2cabc 100644 --- a/src/Umbraco.Web/HealthCheck/HealthCheckResults.cs +++ b/src/Umbraco.Web/HealthCheck/HealthCheckResults.cs @@ -27,7 +27,7 @@ namespace Umbraco.Web.HealthCheck } catch (Exception ex) { - Logger.Error($"Error running scheduled health check: {t.Name}", ex); + Logger.Error(ex, "Error running scheduled health check: {HealthCheckName}", t.Name); var message = $"Health check failed with exception: {ex.Message}. See logs for details."; return new List { @@ -62,16 +62,16 @@ namespace Umbraco.Web.HealthCheck var checkIsSuccess = result.Value.All(x => x.ResultType == StatusResultType.Success); if (checkIsSuccess) { - Logger.Info(() => $" Checks for '{checkName}' all completed succesfully."); + Logger.Info("Checks for '{HealthCheckName}' all completed succesfully.", checkName); } else { - Logger.Warn(() => $" Checks for '{checkName}' completed with errors."); + Logger.Warn("Checks for '{HealthCheckName}' completed with errors.", checkName); } foreach (var checkResult in checkResults) { - Logger.Info(() => $" Result: {checkResult.ResultType}, Message: '{checkResult.Message}'"); + Logger.Info("Result for {HealthCheckName}: {HealthCheckResult}, Message: '{HealthCheckMessage}'", checkName, checkResult.ResultType, checkResult.Message); } } } diff --git a/src/Umbraco.Web/ImageCropperTemplateExtensions.cs b/src/Umbraco.Web/ImageCropperTemplateExtensions.cs index ed134d2e58..83e4b727b2 100644 --- a/src/Umbraco.Web/ImageCropperTemplateExtensions.cs +++ b/src/Umbraco.Web/ImageCropperTemplateExtensions.cs @@ -447,7 +447,7 @@ namespace Umbraco.Web } catch (Exception ex) { - Current.Logger.Error(typeof(ImageCropperTemplateExtensions), "Could not parse the json string: " + json, ex); + Current.Logger.Error(typeof(ImageCropperTemplateExtensions), ex, "Could not parse the json string: {Json}", json); } } diff --git a/src/Umbraco.Web/Install/Controllers/InstallApiController.cs b/src/Umbraco.Web/Install/Controllers/InstallApiController.cs index 96377e7cb7..387360163a 100644 --- a/src/Umbraco.Web/Install/Controllers/InstallApiController.cs +++ b/src/Umbraco.Web/Install/Controllers/InstallApiController.cs @@ -127,7 +127,7 @@ namespace Umbraco.Web.Install.Controllers catch (Exception ex) { - _logger.Error("An error occurred during installation step " + step.Name, ex); + _logger.Error(ex, "An error occurred during installation step {Step}", step.Name); if (ex is TargetInvocationException && ex.InnerException != null) { @@ -217,7 +217,7 @@ namespace Umbraco.Web.Install.Controllers } catch (Exception ex) { - _logger.Error("Checking if step requires execution (" + step.Name + ") failed.", ex); + _logger.Error(ex, "Checking if step requires execution ({Step}) failed.", step.Name); throw; } } @@ -225,7 +225,7 @@ namespace Umbraco.Web.Install.Controllers // executes the step internal InstallSetupResult ExecuteStep(InstallSetupStep step, JToken instruction) { - using (_proflog.TraceDuration("Executing installation step: " + step.Name, "Step completed")) + using (_proflog.TraceDuration($"Executing installation step: '{step.Name}'.", "Step completed")) { var model = instruction?.ToObject(step.StepType); var genericStepType = typeof(InstallSetupStep<>); @@ -238,7 +238,7 @@ namespace Umbraco.Web.Install.Controllers } catch (Exception ex) { - _logger.Error("Installation step " + step.Name + " failed.", ex); + _logger.Error(ex, "Installation step {Step} failed.", step.Name); throw; } } diff --git a/src/Umbraco.Web/Install/HttpInstallAuthorizeAttribute.cs b/src/Umbraco.Web/Install/HttpInstallAuthorizeAttribute.cs index 68acdd6cc8..83aa037097 100644 --- a/src/Umbraco.Web/Install/HttpInstallAuthorizeAttribute.cs +++ b/src/Umbraco.Web/Install/HttpInstallAuthorizeAttribute.cs @@ -57,7 +57,7 @@ namespace Umbraco.Web.Install } catch (Exception ex) { - Current.Logger.Error("An error occurred determining authorization", ex); + Current.Logger.Error(ex, "An error occurred determining authorization"); return false; } } diff --git a/src/Umbraco.Web/Install/InstallHelper.cs b/src/Umbraco.Web/Install/InstallHelper.cs index c31f1f08e1..194fe2aac7 100644 --- a/src/Umbraco.Web/Install/InstallHelper.cs +++ b/src/Umbraco.Web/Install/InstallHelper.cs @@ -109,7 +109,7 @@ namespace Umbraco.Web.Install } catch (Exception ex) { - _logger.Error("An error occurred in InstallStatus trying to check upgrades", ex); + _logger.Error(ex, "An error occurred in InstallStatus trying to check upgrades"); } } @@ -176,7 +176,7 @@ namespace Umbraco.Web.Install } catch (AggregateException ex) { - _logger.Error("Could not download list of available starter kits", ex); + _logger.Error(ex, "Could not download list of available starter kits"); } return packages; diff --git a/src/Umbraco.Web/Install/InstallSteps/DatabaseConfigureStep.cs b/src/Umbraco.Web/Install/InstallSteps/DatabaseConfigureStep.cs index aab42dca9e..a54b64733f 100644 --- a/src/Umbraco.Web/Install/InstallSteps/DatabaseConfigureStep.cs +++ b/src/Umbraco.Web/Install/InstallSteps/DatabaseConfigureStep.cs @@ -85,7 +85,7 @@ namespace Umbraco.Web.Install.InstallSteps } catch (Exception ex) { - _logger.Error("An error occurred, reconfiguring...", ex); + _logger.Error(ex, "An error occurred, reconfiguring..."); //something went wrong, could not connect so probably need to reconfigure return true; } diff --git a/src/Umbraco.Web/Install/InstallSteps/DatabaseInstallStep.cs b/src/Umbraco.Web/Install/InstallSteps/DatabaseInstallStep.cs index 068f3069bd..c4cad38072 100644 --- a/src/Umbraco.Web/Install/InstallSteps/DatabaseInstallStep.cs +++ b/src/Umbraco.Web/Install/InstallSteps/DatabaseInstallStep.cs @@ -59,7 +59,7 @@ namespace Umbraco.Web.Install.InstallSteps else { var ex = new ArgumentNullException(string.Format("ConfigurationManager.ConnectionStrings[{0}]", Constants.System.UmbracoConnectionName), "Install / upgrade did not complete successfully, umbracoDbDSN was not set in the connectionStrings section"); - logger.Error("", ex); + logger.Error(ex, "Install / upgrade did not complete successfully, umbracoDbDSN was not set in the connectionStrings section"); throw ex; } } diff --git a/src/Umbraco.Web/Macros/MacroRenderer.cs b/src/Umbraco.Web/Macros/MacroRenderer.cs index cf8dcb76d5..c6972a0067 100644 --- a/src/Umbraco.Web/Macros/MacroRenderer.cs +++ b/src/Umbraco.Web/Macros/MacroRenderer.cs @@ -99,7 +99,7 @@ namespace Umbraco.Web.Macros if (macroContent == null) return null; - Current.Logger.Debug(() => $"Macro content loaded from cache \"{model.CacheIdentifier}\"."); + Current.Logger.Debug("Macro content loaded from cache '{MacroCacheId}'", model.CacheIdentifier); // ensure that the source has not changed // note: does not handle dependencies, and never has @@ -159,7 +159,7 @@ namespace Umbraco.Web.Macros priority: CacheItemPriority.NotRemovable ); - Current.Logger.Debug(() => $"Macro content saved to cache \"{model.CacheIdentifier}\"."); + Current.Logger.Debug("Macro content saved to cache '{MacroCacheId}'", model.CacheIdentifier); } // gets the macro source file name @@ -304,7 +304,7 @@ namespace Umbraco.Web.Macros { Exceptions.Add(e); - _plogger.Logger.Warn(e, () => $"Failed {msgIn}"); + _plogger.Logger.Warn(e, "Failed {MsgIn}", msgIn); var macroErrorEventArgs = new MacroErrorEventArgs { diff --git a/src/Umbraco.Web/Macros/UserControlMacroEngine.cs b/src/Umbraco.Web/Macros/UserControlMacroEngine.cs index e6cf497b3d..12730c1d1d 100644 --- a/src/Umbraco.Web/Macros/UserControlMacroEngine.cs +++ b/src/Umbraco.Web/Macros/UserControlMacroEngine.cs @@ -31,7 +31,7 @@ namespace Umbraco.Web.Macros // note: we are not setting the 'CurrentNode' property on the control anymore, // as that was an INode which is gone in v8. Use UmbracoContext to access the // current content. - Current.Logger.Info(() => $"Loaded control \"{filename}\" with ID \"{control.ID}\"."); + Current.Logger.Info("Loaded control '{UserControlFile}' with ID '{UserControlId}'", filename, control.ID); UpdateControlProperties(control, model); return new MacroContent { Control = control }; @@ -64,7 +64,7 @@ namespace Umbraco.Web.Macros var controlProperty = type.GetProperty(modelProperty.Key); if (controlProperty == null) { - Current.Logger.Warn(() => $"Control property \"{modelProperty.Key}\" doesn't exist or isn't accessible, skip."); + Current.Logger.Warn("Control property '{UserControlProperty}' doesn't exist or isn't accessible, skip.", modelProperty.Key); continue; } @@ -74,16 +74,16 @@ namespace Umbraco.Web.Macros try { controlProperty.SetValue(control, tryConvert.Result, null); - Current.Logger.Debug(() => $"Set property \"{modelProperty.Key}\" value \"{modelProperty.Value}\"."); + Current.Logger.Debug("Set property '{UserControlProperty}' value '{UserControlPropertyValue}'", modelProperty.Key, modelProperty.Value); } catch (Exception e) { - Current.Logger.Warn(e, () => $"Failed to set property \"{modelProperty.Key}\" value \"{modelProperty.Value}\"."); + Current.Logger.Warn(e, "Failed to set property '{UserControlProperty}' value '{UserControlPropertyValue}'", modelProperty.Key, modelProperty.Value); } } else { - Current.Logger.Warn(() => $"Failed to set property \"{modelProperty.Key}\" value \"{modelProperty.Value}\"."); + Current.Logger.Warn("Failed to set property '{UserControlProperty}' value '{UserControlPropertyValue}'", modelProperty.Key, modelProperty.Value); } } } diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs index 03c4e4a95b..d9506897c8 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs @@ -40,8 +40,9 @@ namespace Umbraco.Web.Models.Mapping if (editor == null) { _logger.Error>( - "No property editor found, converting to a Label", - new NullReferenceException("The property editor with alias " + property.PropertyType.PropertyEditorAlias + " does not exist")); + new NullReferenceException("The property editor with alias " + property.PropertyType.PropertyEditorAlias + " does not exist"), + "No property editor '{PropertyEditorAlias}' found, converting to a Label", + property.PropertyType.PropertyEditorAlias); editor = _propertyEditors[Constants.PropertyEditors.Aliases.NoEdit]; } diff --git a/src/Umbraco.Web/Models/Mapping/ContentSavedStateResolver.cs b/src/Umbraco.Web/Models/Mapping/ContentSavedStateResolver.cs index 1c9af34388..4fb4d3370a 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentSavedStateResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentSavedStateResolver.cs @@ -28,8 +28,7 @@ namespace Umbraco.Web.Models.Mapping ? PublishedState.Published : PublishedState.Unpublished; - //it can only be 'edited' if the content item is persisted and if the variant has a name and it's flagged as edited - isEdited = source.Id > 0 && source.IsCultureAvailable(culture) && source.IsCultureEdited(culture); + isEdited = source.IsCultureEdited(culture); } else { @@ -37,17 +36,16 @@ namespace Umbraco.Web.Models.Mapping ? PublishedState.Unpublished : PublishedState.Published; - isEdited = source.Id > 0 && source.Edited; + isEdited = source.Edited; } - //now we can calculate the content state - if (!isEdited && publishedState == PublishedState.Unpublished) - return ContentSavedState.NotCreated; - if (isEdited && publishedState == PublishedState.Unpublished) - return ContentSavedState.Draft; - if (!isEdited && publishedState == PublishedState.Published) - return ContentSavedState.Published; - return ContentSavedState.PublishedPendingChanges; + if (publishedState == PublishedState.Unpublished) + return isEdited && source.Id > 0 ? ContentSavedState.Draft : ContentSavedState.NotCreated; + + if (publishedState == PublishedState.Published) + return isEdited ? ContentSavedState.PublishedPendingChanges : ContentSavedState.Published; + + throw new NotSupportedException($"PublishedState {publishedState} is not supported."); } } } diff --git a/src/Umbraco.Web/Models/Mapping/DataTypeConfigurationFieldDisplayResolver.cs b/src/Umbraco.Web/Models/Mapping/DataTypeConfigurationFieldDisplayResolver.cs index d1838fc0f8..e262753b83 100644 --- a/src/Umbraco.Web/Models/Mapping/DataTypeConfigurationFieldDisplayResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/DataTypeConfigurationFieldDisplayResolver.cs @@ -25,7 +25,7 @@ namespace Umbraco.Web.Models.Mapping if (configuration.TryGetValue(field.Key, out var value)) field.Value = value; else // weird - just leave the field without a value - but warn - Current.Logger.Warn(() => $"Could not find a value for configuration field \"{field.Key}\"."); + Current.Logger.Warn("Could not find a value for configuration field '{ConfigField}'", field.Key); } } diff --git a/src/Umbraco.Web/Models/Mapping/MacroMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/MacroMapperProfile.cs index e888d78c07..9977b1cfb1 100644 --- a/src/Umbraco.Web/Models/Mapping/MacroMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/MacroMapperProfile.cs @@ -41,7 +41,7 @@ namespace Umbraco.Web.Models.Mapping { //we'll just map this to a text box paramEditor = Current.ParameterEditors[Constants.PropertyEditors.Aliases.TextBox]; - Current.Logger.Warn(() => $"Could not resolve a parameter editor with alias {property.EditorAlias}, a textbox will be rendered in it's place"); + Current.Logger.Warn("Could not resolve a parameter editor with alias {PropertyEditorAlias}, a textbox will be rendered in it's place", property.EditorAlias); } parameter.View = paramEditor.GetValueEditor().View; diff --git a/src/Umbraco.Web/Mvc/AdminTokenAuthorizeAttribute.cs b/src/Umbraco.Web/Mvc/AdminTokenAuthorizeAttribute.cs index adb9bf69d8..882cb5624c 100644 --- a/src/Umbraco.Web/Mvc/AdminTokenAuthorizeAttribute.cs +++ b/src/Umbraco.Web/Mvc/AdminTokenAuthorizeAttribute.cs @@ -119,7 +119,7 @@ namespace Umbraco.Web.Mvc } catch (Exception ex) { - Logger.Error("Failed to format passed in token value", ex); + Logger.Error(ex, "Failed to format passed in token value"); return false; } } diff --git a/src/Umbraco.Web/Mvc/RenderRouteHandler.cs b/src/Umbraco.Web/Mvc/RenderRouteHandler.cs index e3c797bead..fa52b102d4 100644 --- a/src/Umbraco.Web/Mvc/RenderRouteHandler.cs +++ b/src/Umbraco.Web/Mvc/RenderRouteHandler.cs @@ -318,8 +318,11 @@ namespace Umbraco.Web.Mvc } else { - Current.Logger.Warn(() => - $"The current Document Type {request.PublishedContent.ContentType.Alias} matches a locally declared controller of type {controllerType.FullName}. Custom Controllers for Umbraco routing must implement '{typeof(IRenderController).FullName}' and inherit from '{typeof(ControllerBase).FullName}'."); + Current.Logger.Warn("The current Document Type {ContentTypeAlias} matches a locally declared controller of type {ControllerName}. Custom Controllers for Umbraco routing must implement '{UmbracoRenderController}' and inherit from '{UmbracoControllerBase}'.", + request.PublishedContent.ContentType.Alias, + controllerType.FullName, + typeof(IRenderController).FullName, + typeof(ControllerBase).FullName); //we cannot route to this custom controller since it is not of the correct type so we'll continue with the defaults // that have already been set above. diff --git a/src/Umbraco.Web/NotificationServiceExtensions.cs b/src/Umbraco.Web/NotificationServiceExtensions.cs index 2cf3b026de..1fb229a66e 100644 --- a/src/Umbraco.Web/NotificationServiceExtensions.cs +++ b/src/Umbraco.Web/NotificationServiceExtensions.cs @@ -76,7 +76,7 @@ namespace Umbraco.Web user = userService.GetUserById(Constants.Security.SuperUserId); if (user == null) { - Current.Logger.Warn(typeof(NotificationServiceExtensions), $"Noticiations can not be sent, no admin user with id {Constants.Security.SuperUserId} could be resolved"); + Current.Logger.Warn(typeof(NotificationServiceExtensions), "Noticiations can not be sent, no admin user with id {SuperUserId} could be resolved", Constants.Security.SuperUserId); return; } } @@ -101,7 +101,7 @@ namespace Umbraco.Web user = userService.GetUserById(Constants.Security.SuperUserId); if (user == null) { - Current.Logger.Warn(typeof(NotificationServiceExtensions), $"Noticiations can not be sent, no admin user with id {Constants.Security.SuperUserId} could be resolved"); + Current.Logger.Warn(typeof(NotificationServiceExtensions), "Noticiations can not be sent, no admin user with id {SuperUserId} could be resolved", Constants.Security.SuperUserId); return; } } diff --git a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs index 6183641aaf..2a74b4f05c 100644 --- a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs @@ -76,7 +76,7 @@ namespace Umbraco.Web.PropertyEditors catch (Exception ex) { if (writeLog) - Logger.Error($"Could not parse image cropper value \"{value}\"", ex); + Logger.Error(ex, "Could not parse image cropper value '{Json}'", value); return null; } } diff --git a/src/Umbraco.Web/PropertyEditors/RteEmbedController.cs b/src/Umbraco.Web/PropertyEditors/RteEmbedController.cs index ff9c9d49e7..9199707d10 100644 --- a/src/Umbraco.Web/PropertyEditors/RteEmbedController.cs +++ b/src/Umbraco.Web/PropertyEditors/RteEmbedController.cs @@ -63,7 +63,7 @@ namespace Umbraco.Web.PropertyEditors } catch(Exception ex) { - Logger.Error(string.Format("Error embedding url {0} - width: {1} height: {2}", url, width, height), ex); + Logger.Error(ex, "Error embedding url {Url} - width: {Width} height: {Height}", url, width, height); result.Status = Status.Error; } diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/RelatedLinksLegacyValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/RelatedLinksLegacyValueConverter.cs index 1e8197ec7a..407ea481c4 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueConverters/RelatedLinksLegacyValueConverter.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/RelatedLinksLegacyValueConverter.cs @@ -85,7 +85,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters } catch (Exception ex) { - _logger.Error("Could not parse the string " + sourceString + " to a json object", ex); + _logger.Error(ex, "Could not parse the string '{Json}' to a json object", sourceString); } } @@ -123,7 +123,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters } catch (Exception ex) { - _logger.Error("Could not parse the string " + sourceString + " to a json object", ex); + _logger.Error(ex, "Could not parse the string '{Json}' to a json object", sourceString); } } diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/RelatedLinksValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/RelatedLinksValueConverter.cs index 632052d3e7..b3b3919278 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueConverters/RelatedLinksValueConverter.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/RelatedLinksValueConverter.cs @@ -95,7 +95,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters } else { - _logger.Warn(() => $"Related Links value converter skipped a link as the node has been unpublished/deleted (Internal Link NodeId: {relatedLink.Link}, Link Caption: \"{relatedLink.Caption}\")"); + _logger.Warn("Related Links value converter skipped a link as the node has been unpublished/deleted (Internal Link NodeId: {RelatedLinkNodeId}, Link Caption: '{RelatedLinkCaption}')", relatedLink.Link, relatedLink.Caption); } } @@ -158,7 +158,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters } catch (Exception ex) { - _logger.Error("Could not parse the string " + sourceString + " to a json object", ex); + _logger.Error(ex, "Could not parse the string {Json} to a json object", sourceString); } } diff --git a/src/Umbraco.Web/PublishedCache/NuCache/ContentStore.cs b/src/Umbraco.Web/PublishedCache/NuCache/ContentStore.cs index 834594af9e..ca5a5db88c 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/ContentStore.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/ContentStore.cs @@ -446,7 +446,7 @@ namespace Umbraco.Web.PublishedCache.NuCache throw new ArgumentException("Kit content cannot have children.", nameof(kit)); // ReSharper restore LocalizableElement - _logger.Debug(() => "Set content ID:" + kit.Node.Id); + _logger.Debug("Set content ID: {KitNodeId}", kit.Node.Id); var lockInfo = new WriteLockInfo(); try @@ -571,7 +571,7 @@ namespace Umbraco.Web.PublishedCache.NuCache if (link?.Value == null) return false; var content = link.Value; - _logger.Debug(() => "Clear content ID:" + content.Id); + _logger.Debug("Clear content ID: {ContentId}", content.Id); // clear the entire branch ClearBranchLocked(content); @@ -921,7 +921,7 @@ namespace Umbraco.Web.PublishedCache.NuCache { // see notes in CreateSnapshot #if DEBUG - _logger.Debug(() => "Collect."); + _logger.Debug("Collect."); #endif while (_genRefRefs.TryPeek(out GenRefRef genRefRef) && (genRefRef.Count == 0 || genRefRef.WGenRef.IsAlive == false)) { @@ -1098,7 +1098,7 @@ namespace Umbraco.Web.PublishedCache.NuCache #if DEBUG _logger = logger; - _logger.Debug(() => "Creating snapshot."); + _logger.Debug("Creating snapshot."); #endif } @@ -1113,7 +1113,7 @@ namespace Umbraco.Web.PublishedCache.NuCache #if DEBUG _logger = logger; - _logger.Debug(() => "Creating live."); + _logger.Debug("Creating live."); #endif } @@ -1194,7 +1194,7 @@ namespace Umbraco.Web.PublishedCache.NuCache { if (_gen < 0) return; #if DEBUG - _logger.Debug(() => "Dispose snapshot (" + (_genRef?.GenRefRef.Count.ToString() ?? "live") + ")."); + _logger.Debug("Dispose snapshot ({Snapshot})", _genRef?.GenRefRef.Count.ToString() ?? "live"); #endif _gen = -1; if (_genRef != null) diff --git a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/DatabaseDataSource.cs b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/DatabaseDataSource.cs index 0a0c398cd6..a143997fab 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/DatabaseDataSource.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/DatabaseDataSource.cs @@ -186,7 +186,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource { if (Debugger.IsAttached) throw new Exception("Missing cmsContentNu edited content for node " + dto.Id + ", consider rebuilding."); - Current.Logger.Warn(() => $"Missing cmsContentNu edited content for node {dto.Id}, consider rebuilding."); + Current.Logger.Warn("Missing cmsContentNu edited content for node {NodeId}, consider rebuilding.", dto.Id); } else { @@ -211,7 +211,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource { if (Debugger.IsAttached) throw new Exception("Missing cmsContentNu published content for node " + dto.Id + ", consider rebuilding."); - Current.Logger.Warn(() => $"Missing cmsContentNu published content for node {dto.Id}, consider rebuilding."); + Current.Logger.Warn("Missing cmsContentNu published content for node {NodeId}, consider rebuilding.", dto.Id); } else { diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs index 34efa7136a..5bcb2f70d4 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs @@ -186,9 +186,9 @@ namespace Umbraco.Web.PublishedCache.NuCache LockAndLoadDomains(); } - catch (Exception e) + catch (Exception ex) { - _logger.Error("Panic, exception while loading cache data.", e); + _logger.Fatal(ex, "Panic, exception while loading cache data."); } // finaly, cache is ready! @@ -298,12 +298,12 @@ namespace Umbraco.Web.PublishedCache.NuCache _localContentDb?.Clear(); - _logger.Debug(() => "Loading content from database..."); + _logger.Debug("Loading content from database..."); var sw = Stopwatch.StartNew(); var kits = _dataSource.GetAllContentSources(scope); _contentStore.SetAll(kits); sw.Stop(); - _logger.Debug(() => "Loaded content from database (" + sw.ElapsedMilliseconds + "ms)."); + _logger.Debug("Loaded content from database ({ElapsedMilliseconds}ms)", sw.ElapsedMilliseconds); } private void LoadContentFromLocalDbLocked(IScope scope) @@ -312,12 +312,12 @@ namespace Umbraco.Web.PublishedCache.NuCache .Select(x => _publishedContentTypeFactory.CreateContentType(x)); _contentStore.UpdateContentTypes(null, contentTypes, null); - _logger.Debug(() => "Loading content from local db..."); + _logger.Debug("Loading content from local db..."); var sw = Stopwatch.StartNew(); var kits = _localContentDb.Select(x => x.Value).OrderBy(x => x.Node.Level); _contentStore.SetAll(kits); sw.Stop(); - _logger.Debug(() => "Loaded content from local db (" + sw.ElapsedMilliseconds + "ms)."); + _logger.Debug("Loaded content from local db ({ElapsedMilliseconds}ms)", sw.ElapsedMilliseconds); } // keep these around - might be useful @@ -365,12 +365,12 @@ namespace Umbraco.Web.PublishedCache.NuCache _localMediaDb?.Clear(); - _logger.Debug(() => "Loading media from database..."); + _logger.Debug("Loading media from database..."); var sw = Stopwatch.StartNew(); var kits = _dataSource.GetAllMediaSources(scope); _mediaStore.SetAll(kits); sw.Stop(); - _logger.Debug(() => "Loaded media from database (" + sw.ElapsedMilliseconds + "ms)."); + _logger.Debug("Loaded media from database ({ElapsedMilliseconds}ms)", sw.ElapsedMilliseconds); } private void LoadMediaFromLocalDbLocked(IScope scope) @@ -379,12 +379,12 @@ namespace Umbraco.Web.PublishedCache.NuCache .Select(x => _publishedContentTypeFactory.CreateContentType(x)); _mediaStore.UpdateContentTypes(null, mediaTypes, null); - _logger.Debug(() => "Loading media from local db..."); + _logger.Debug("Loading media from local db..."); var sw = Stopwatch.StartNew(); var kits = _localMediaDb.Select(x => x.Value); _mediaStore.SetAll(kits); sw.Stop(); - _logger.Debug(() => "Loaded media from local db (" + sw.ElapsedMilliseconds + "ms)."); + _logger.Debug("Loaded media from local db ({ElapsedMilliseconds}ms)", sw.ElapsedMilliseconds); } // keep these around - might be useful @@ -551,7 +551,7 @@ namespace Umbraco.Web.PublishedCache.NuCache foreach (var payload in payloads) { - _logger.Debug(() => $"Notified {payload.ChangeTypes} for content {payload.Id}"); + _logger.Debug("Notified {ChangeTypes} for content {ContentId}", payload.ChangeTypes, payload.Id); if (payload.ChangeTypes.HasType(TreeChangeTypes.RefreshAll)) { @@ -641,7 +641,7 @@ namespace Umbraco.Web.PublishedCache.NuCache foreach (var payload in payloads) { - _logger.Debug(() => $"Notified {payload.ChangeTypes} for media {payload.Id}"); + _logger.Debug("Notified {ChangeTypes} for media {MediaId}", payload.ChangeTypes, payload.Id); if (payload.ChangeTypes.HasType(TreeChangeTypes.RefreshAll)) { @@ -710,7 +710,7 @@ namespace Umbraco.Web.PublishedCache.NuCache return; foreach (var payload in payloads) - _logger.Debug(() => $"Notified {payload.ChangeTypes} for {payload.ItemType} {payload.Id}"); + _logger.Debug("Notified {ChangeTypes} for {ItemType} {ItemId}", payload.ChangeTypes, payload.ItemType, payload.Id); Notify(_contentStore, payloads, RefreshContentTypesLocked); Notify(_mediaStore, payloads, RefreshMediaTypesLocked); @@ -760,7 +760,9 @@ namespace Umbraco.Web.PublishedCache.NuCache var idsA = payloads.Select(x => x.Id).ToArray(); foreach (var payload in payloads) - _logger.Debug(() => $"Notified {(payload.Removed ? "Removed" : "Refreshed")} for data type {payload.Id}"); + _logger.Debug("Notified {RemovedStatus} for data type {DataTypeId}", + payload.Removed ? "Removed" : "Refreshed", + payload.Id); using (_contentStore.GetWriter(_scopeProvider)) using (_mediaStore.GetWriter(_scopeProvider)) diff --git a/src/Umbraco.Web/PublishedCache/PublishedContentTypeCache.cs b/src/Umbraco.Web/PublishedCache/PublishedContentTypeCache.cs index a41a270c52..ca30370598 100644 --- a/src/Umbraco.Web/PublishedCache/PublishedContentTypeCache.cs +++ b/src/Umbraco.Web/PublishedCache/PublishedContentTypeCache.cs @@ -48,7 +48,7 @@ namespace Umbraco.Web.PublishedCache /// public void ClearAll() { - _logger.Debug(() => "Clear all."); + _logger.Debug("Clear all."); try { @@ -70,7 +70,7 @@ namespace Umbraco.Web.PublishedCache /// An identifier. public void ClearContentType(int id) { - _logger.Debug(() => $"Clear content type w/id {id}."); + _logger.Debug("Clear content type w/id {ContentTypeId}", id); try { @@ -105,7 +105,7 @@ namespace Umbraco.Web.PublishedCache /// A data type identifier. public void ClearDataType(int id) { - _logger.Debug(() => $"Clear data type w/id {id}."); + _logger.Debug("Clear data type w/id {DataTypeId}.", id); // there is no recursion to handle here because a PublishedContentType contains *all* its // properties ie both its own properties and those that were inherited (it's based upon an diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/DictionaryPublishedContent.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/DictionaryPublishedContent.cs index 9d4dfda461..49e0d1e9d2 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/DictionaryPublishedContent.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/DictionaryPublishedContent.cs @@ -108,7 +108,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache else { // this is a property that does not correspond to anything, ignore and log - Current.Logger.Warn(() => "Dropping property \"" + i.Key + "\" because it does not belong to the content type."); + Current.Logger.Warn("Dropping property '{PropertyKey}' because it does not belong to the content type.", i.Key); } } } diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PreviewContent.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PreviewContent.cs index 36b38b11ac..515fb96679 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PreviewContent.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PreviewContent.cs @@ -40,7 +40,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache } catch (Exception ex) { - Current.Logger.Error($"Could not load preview set {_previewSet} for user {_userId}.", ex); + Current.Logger.Error(ex, "Could not load preview set {PreviewSet} for user {UserId}.", _previewSet, _userId); ClearPreviewSet(); @@ -146,7 +146,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache } catch (Exception ex) { - Current.Logger.Error($"Couldn't delete preview set {file.Name} for user {userId}", ex); + Current.Logger.Error(ex, "Couldn't delete preview set {FileName} for user {UserId}", file.Name, userId); } } diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs index 6cf8b85ed1..79ff0c33a8 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs @@ -122,13 +122,13 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache //See this thread: http://examine.cdodeplex.com/discussions/264341 //Catch the exception here for the time being, and just fallback to GetMedia //TODO: Need to fix examine in LB scenarios! - Current.Logger.Error("Could not load data from Examine index for media", ex); + Current.Logger.Error(ex, "Could not load data from Examine index for media"); } else if (ex is AlreadyClosedException) { //If the app domain is shutting down and the site is under heavy load the index reader will be closed and it really cannot //be re-opened since the app domain is shutting down. In this case we have no option but to try to load the data from the db. - Current.Logger.Error("Could not load data from Examine index for media, the app domain is most likely in a shutdown state", ex); + Current.Logger.Error(ex, "Could not load data from Examine index for media, the app domain is most likely in a shutdown state"); } else throw; } @@ -306,13 +306,13 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache //See this thread: http://examine.cdodeplex.com/discussions/264341 //Catch the exception here for the time being, and just fallback to GetMedia //TODO: Need to fix examine in LB scenarios! - Current.Logger.Error("Could not load data from Examine index for media", ex); + Current.Logger.Error(ex, "Could not load data from Examine index for media"); } else if (ex is AlreadyClosedException) { //If the app domain is shutting down and the site is under heavy load the index reader will be closed and it really cannot //be re-opened since the app domain is shutting down. In this case we have no option but to try to load the data from the db. - Current.Logger.Error("Could not load data from Examine index for media, the app domain is most likely in a shutdown state", ex); + Current.Logger.Error(ex, "Could not load data from Examine index for media, the app domain is most likely in a shutdown state"); } else throw; } @@ -330,8 +330,8 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache var miss = Interlocked.CompareExchange(ref _examineIndexMiss, 0, 0); // volatile read if (miss < ExamineIndexMissMax && Interlocked.Increment(ref _examineIndexMiss) == ExamineIndexMissMax) - Current.Logger.Warn(() => $"Failed ({ExamineIndexMissMax} times) to retrieve medias from Examine index and had to load" - + " them from DB. This may indicate that the Examine index is corrupted."); + Current.Logger.Warn("Failed ({ExamineIndexMissMax} times) to retrieve medias from Examine index and had to load" + + " them from DB. This may indicate that the Examine index is corrupted.", ExamineIndexMissMax); return ConvertFromIMedia(media); } @@ -348,8 +348,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache : ConvertFromXPathNavigator(media.Current); } - Current.Logger.Warn(() => - $"Could not retrieve media {id} from Examine index or from legacy library.GetMedia method"); + Current.Logger.Warn("Could not retrieve media {MediaId} from Examine index or from legacy library.GetMedia method", id); return null; } diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlStore.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlStore.cs index caf937315e..5b640f13e5 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlStore.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlStore.cs @@ -409,9 +409,9 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache } dtd.Append(dtdInner); } - catch (Exception exception) + catch (Exception ex) { - Current.Logger.Error("Failed to build a DTD for the Xml cache.", exception); + Current.Logger.Error(ex, "Failed to build a DTD for the Xml cache."); } dtd.AppendLine("]>"); @@ -696,12 +696,12 @@ AND (umbracoNode.id=@id)"; Current.Logger.Info("Saved Xml to file."); } - catch (Exception e) + catch (Exception ex) { // if something goes wrong remove the file DeleteXmlFile(); - Current.Logger.Error("Failed to save Xml to file.", e); + Current.Logger.Error(ex, "Failed to save Xml to file '{FileName}'.", _xmlFileName); } } @@ -736,12 +736,12 @@ AND (umbracoNode.id=@id)"; Current.Logger.Info("Saved Xml to file."); } - catch (Exception e) + catch (Exception ex) { // if something goes wrong remove the file DeleteXmlFile(); - Current.Logger.Error("Failed to save Xml to file.", e); + Current.Logger.Error(ex, "Failed to save Xml to file '{FileName}'.", _xmlFileName); } } @@ -796,9 +796,9 @@ AND (umbracoNode.id=@id)"; Current.Logger.Warn("Failed to load Xml, file does not exist."); return null; } - catch (Exception e) + catch (Exception ex) { - Current.Logger.Error("Failed to load Xml from file.", e); + Current.Logger.Error(ex, "Failed to load Xml from file '{FileName}'.", _xmlFileName); try { DeleteXmlFile(); @@ -1038,7 +1038,7 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder"; { foreach (var payload in payloads) { - Current.Logger.Debug(() => $"Notified {payload.ChangeTypes} for content {payload.Id}."); + Current.Logger.Debug("Notified {ChangeTypes} for content {ContentId}", payload.ChangeTypes, payload.Id); if (payload.ChangeTypes.HasType(TreeChangeTypes.RefreshAll)) { @@ -1071,7 +1071,8 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder"; if (content == null || content.Published == false || content.Trashed) { // no published version - Current.Logger.Debug(() => $"Notified, content {payload.Id} has no published version."); + Current.Logger.Debug("Notified, content {ContentId} has no published version.", payload.Id); + if (current != null) { // remove from xml if exists @@ -1109,7 +1110,8 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder"; if (dtos.MoveNext() == false) { // gone fishing, remove (possible race condition) - Current.Logger.Debug(() => $"Notifified, content {payload.Id} gone fishing."); + Current.Logger.Debug("Notified, content {ContentId} gone fishing.", payload.Id); + if (current != null) { // remove from xml if exists @@ -1222,7 +1224,7 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder"; .ToArray(); foreach (var payload in payloads) - Current.Logger.Debug(() => $"Notified {payload.ChangeTypes} for content type {payload.Id}."); + Current.Logger.Debug("Notified {ChangeTypes} for content type {ContentTypeId}", payload.ChangeTypes, payload.Id); if (ids.Length > 0) // must have refreshes, not only removes RefreshContentTypes(ids); @@ -1239,9 +1241,11 @@ ORDER BY umbracoNode.level, umbracoNode.sortOrder"; // the types will be reloaded if/when needed foreach (var payload in payloads) _contentTypeCache.ClearDataType(payload.Id); - + foreach (var payload in payloads) - Current.Logger.Debug(() => $"Notified {(payload.Removed ? "Removed" : "Refreshed")} for data type {payload.Id}."); + Current.Logger.Debug("Notified {RemovedStatus} for data type {payload.Id}", + payload.Removed ? "Removed" : "Refreshed", + payload.Id); // that's all we need to do as the changes have NO impact whatsoever on the Xml content diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlStoreFilePersister.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlStoreFilePersister.cs index 6b247bdf0d..c656562236 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlStoreFilePersister.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlStoreFilePersister.cs @@ -62,7 +62,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache if (touched == false) return; - _logger.Debug(() => $"Created, save in {WaitMilliseconds}ms."); + _logger.Debug("Created, save in {WaitMilliseconds}ms.", WaitMilliseconds); _initialTouch = DateTime.Now; _timer = new Timer(_ => TimerRelease()); _timer.Change(WaitMilliseconds, 0); @@ -107,7 +107,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache else if (_timer == null) // we don't have a timer yet { - _logger.Debug(() => $"Touched, was idle, start and save in {WaitMilliseconds}ms."); + _logger.Debug("Touched, was idle, start and save in {WaitMilliseconds}ms.", WaitMilliseconds); _initialTouch = DateTime.Now; _timer = new Timer(_ => TimerRelease()); _timer.Change(WaitMilliseconds, 0); @@ -120,7 +120,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache if (DateTime.Now - _initialTouch < TimeSpan.FromMilliseconds(MaxWaitMilliseconds)) { - _logger.Debug(() => $"Touched, was waiting, can delay, save in {WaitMilliseconds}ms."); + _logger.Debug("Touched, was waiting, can delay, save in {WaitMilliseconds}ms.", WaitMilliseconds); _timer.Change(WaitMilliseconds, 0); } else diff --git a/src/Umbraco.Web/Routing/ContentFinderByIdPath.cs b/src/Umbraco.Web/Routing/ContentFinderByIdPath.cs index fa2ca519d9..447d4e34af 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByIdPath.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByIdPath.cs @@ -48,13 +48,13 @@ namespace Umbraco.Web.Routing if (nodeId > 0) { - _logger.Debug(() => $"Id={nodeId}"); + _logger.Debug("Id={NodeId}", nodeId); node = frequest.UmbracoContext.ContentCache.GetById(nodeId); if (node != null) { frequest.PublishedContent = node; - _logger.Debug(() => $"Found node with id={frequest.PublishedContent.Id}"); + _logger.Debug("Found node with id={PublishedContentId}", frequest.PublishedContent.Id); } else { diff --git a/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs b/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs index cac9244dbf..99b4e22b5a 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs @@ -70,7 +70,7 @@ namespace Umbraco.Web.Routing if (error404.HasValue) { - _logger.Debug(() => $"Got id={error404.Value}."); + _logger.Debug("Got id={ErrorNodeId}.", error404.Value); content = frequest.UmbracoContext.ContentCache.GetById(error404.Value); diff --git a/src/Umbraco.Web/Routing/ContentFinderByRedirectUrl.cs b/src/Umbraco.Web/Routing/ContentFinderByRedirectUrl.cs index b8bc5f19fb..d50951161c 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByRedirectUrl.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByRedirectUrl.cs @@ -48,7 +48,7 @@ namespace Umbraco.Web.Routing if (redirectUrl == null) { - _logger.Debug(() => $"No match for route: \"{route}\"."); + _logger.Debug("No match for route: '{Route}'", route); return false; } @@ -56,11 +56,11 @@ namespace Umbraco.Web.Routing var url = content == null ? "#" : content.Url; if (url.StartsWith("#")) { - _logger.Debug(() => $"Route \"{route}\" matches content {redirectUrl.ContentId} which has no url."); + _logger.Debug("Route '{Route}' matches content {ContentId} which has no url.", route, redirectUrl.ContentId); return false; } - _logger.Debug(() => $"Route \"{route}\" matches content {content.Id} with url \"{url}\", redirecting."); + _logger.Debug("Route '{Route}' matches content {ContentId} with url '{Url}', redirecting.", route, content.Id, url); frequest.SetRedirectPermanent(url); return true; } diff --git a/src/Umbraco.Web/Routing/ContentFinderByUrl.cs b/src/Umbraco.Web/Routing/ContentFinderByUrl.cs index 042ca5882f..a3c54406a8 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByUrl.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByUrl.cs @@ -46,13 +46,13 @@ namespace Umbraco.Web.Routing { if (docreq == null) throw new System.ArgumentNullException(nameof(docreq)); - Logger.Debug(() => $"Test route \"{route}\""); + Logger.Debug("Test route '{Route}'", route); var node = docreq.UmbracoContext.ContentCache.GetByRoute(route, culture: docreq.Culture?.Name); if (node != null) { docreq.PublishedContent = node; - Logger.Debug(() => $"Got content, id={node.Id}"); + Logger.Debug("Got content, id={NodeId}", node.Id); } else { diff --git a/src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs b/src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs index 59e30cc8b0..bbf3ee1283 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByUrlAlias.cs @@ -44,7 +44,7 @@ namespace Umbraco.Web.Routing if (node != null) { frequest.PublishedContent = node; - Logger.Debug(() => $"Path \"{frequest.Uri.AbsolutePath}\" is an alias for id={frequest.PublishedContent.Id}"); + Logger.Debug("Path '{UriAbsolutePath}' is an alias for id={PublishedContentId}", frequest.Uri.AbsolutePath, frequest.PublishedContent.Id); } } diff --git a/src/Umbraco.Web/Routing/ContentFinderByUrlAndTemplate.cs b/src/Umbraco.Web/Routing/ContentFinderByUrlAndTemplate.cs index 0b4c02aa8e..1d1661966f 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByUrlAndTemplate.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByUrlAndTemplate.cs @@ -49,7 +49,7 @@ namespace Umbraco.Web.Routing var template = _fileService.GetTemplate(templateAlias); if (template != null) { - Logger.Debug(() => $"Valid template: \"{templateAlias}\""); + Logger.Debug("Valid template: '{TemplateAlias}'", templateAlias); var route = frequest.HasDomain ? (frequest.Domain.ContentId.ToString() + path) : path; node = FindContent(frequest, route); @@ -59,12 +59,12 @@ namespace Umbraco.Web.Routing } else { - Logger.Debug(() => $"Not a valid template: \"{templateAlias}\""); + Logger.Debug("Not a valid template: '{TemplateAlias}'", templateAlias); } } else { - Logger.Debug("No template in path \"/\""); + Logger.Debug("No template in path '/'"); } return node != null; diff --git a/src/Umbraco.Web/Routing/DefaultUrlProvider.cs b/src/Umbraco.Web/Routing/DefaultUrlProvider.cs index fb9cdfa9bd..61437b6640 100644 --- a/src/Umbraco.Web/Routing/DefaultUrlProvider.cs +++ b/src/Umbraco.Web/Routing/DefaultUrlProvider.cs @@ -43,8 +43,7 @@ namespace Umbraco.Web.Routing { if (string.IsNullOrWhiteSpace(route)) { - _logger.Debug(() => - $"Couldn't find any page with nodeId={id}. This is most likely caused by the page not being published."); + _logger.Debug("Couldn't find any page with nodeId={NodeId}. This is most likely caused by the page not being published.", id); return null; } diff --git a/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs b/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs index bcf89349ef..1a0e5ef873 100644 --- a/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs +++ b/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs @@ -107,7 +107,7 @@ namespace Umbraco.Web.Routing } catch (Exception ex) { - Current.Logger.Error("Could not parse xpath expression: " + errorPage.ContentXPath, ex); + Current.Logger.Error(ex, "Could not parse xpath expression: {ContentXPath}", errorPage.ContentXPath); return null; } } diff --git a/src/Umbraco.Web/Routing/PublishedRouter.cs b/src/Umbraco.Web/Routing/PublishedRouter.cs index 8b222a3079..52ec98c665 100644 --- a/src/Umbraco.Web/Routing/PublishedRouter.cs +++ b/src/Umbraco.Web/Routing/PublishedRouter.cs @@ -277,7 +277,7 @@ namespace Umbraco.Web.Routing // note - we are not handling schemes nor ports here. - _logger.Debug(() => $"{tracePrefix}Uri=\"{request.Uri}\""); + _logger.Debug("{TracePrefix}Uri='{RequestUri}'", tracePrefix, request.Uri); var domainsCache = request.UmbracoContext.PublishedSnapshot.Domains; var domains = domainsCache.GetAll(includeWildcards: false).ToList(); @@ -314,7 +314,7 @@ namespace Umbraco.Web.Routing if (domainAndUri != null) { // matching an existing domain - _logger.Debug(() => $"{tracePrefix}Matches domain=\"{domainAndUri.Name}\", rootId={domainAndUri.ContentId}, culture=\"{domainAndUri.Culture}\""); + _logger.Debug("{TracePrefix}Matches domain='{Domain}', rootId={RootContentId}, culture='{Culture}'", tracePrefix, domainAndUri.Name, domainAndUri.ContentId, domainAndUri.Culture); request.Domain = domainAndUri; request.Culture = domainAndUri.Culture; @@ -329,12 +329,12 @@ namespace Umbraco.Web.Routing else { // not matching any existing domain - _logger.Debug(() => $"{tracePrefix}Matches no domain"); + _logger.Debug("{TracePrefix}Matches no domain", tracePrefix); request.Culture = defaultCulture == null ? CultureInfo.CurrentUICulture : new CultureInfo(defaultCulture); } - _logger.Debug(() => $"{tracePrefix}Culture=\"{request.Culture.Name}\""); + _logger.Debug("{TracePrefix}Culture='{CultureName}'", tracePrefix, request.Culture.Name); return request.Domain != null; } @@ -350,7 +350,7 @@ namespace Umbraco.Web.Routing return; var nodePath = request.PublishedContent.Path; - _logger.Debug(() => $"{tracePrefix}Path=\"{nodePath}\""); + _logger.Debug("{TracePrefix}Path='{NodePath}'", tracePrefix, nodePath); var rootNodeId = request.HasDomain ? request.Domain.ContentId : (int?)null; var domain = DomainHelper.FindWildcardDomainInPath(request.UmbracoContext.PublishedSnapshot.Domains.GetAll(true), nodePath, rootNodeId); @@ -358,11 +358,11 @@ namespace Umbraco.Web.Routing if (domain != null) { request.Culture = domain.Culture; - _logger.Debug(() => $"{tracePrefix}Got domain on node {domain.ContentId}, set culture to \"{request.Culture.Name}\"."); + _logger.Debug("{TracePrefix}Got domain on node {DomainContentId}, set culture to '{CultureName}'", tracePrefix, domain.ContentId, request.Culture.Name); } else { - _logger.Debug(() => $"{tracePrefix}No match."); + _logger.Debug("{TracePrefix}No match.", tracePrefix); } } @@ -435,8 +435,7 @@ namespace Umbraco.Web.Routing /// A value indicating whether a document and template were found. private void FindPublishedContentAndTemplate(PublishedRequest request) { - const string tracePrefix = "FindPublishedContentAndTemplate: "; - _logger.Debug(() => $"{tracePrefix}Path=\"{request.Uri.AbsolutePath}\""); + _logger.Debug("FindPublishedContentAndTemplate: Path='{UriAbsolutePath}'", request.Uri.AbsolutePath); // run the document finders FindPublishedContent(request); @@ -479,7 +478,7 @@ namespace Umbraco.Web.Routing //iterate but return on first one that finds it var found = _contentFinders.Any(finder => { - _logger.Debug(() => "Finder " + finder.GetType().FullName); + _logger.Debug("Finder {ContentFinderType}", finder.GetType().FullName); return finder.TryFindContent(request); }); } @@ -505,22 +504,22 @@ namespace Umbraco.Web.Routing const int maxLoop = 8; do { - _logger.Debug(() => $"{tracePrefix}{(i == 0 ? "Begin" : "Loop")}"); + _logger.Debug("HandlePublishedContent: Loop {LoopCounter}", i); // handle not found if (request.HasPublishedContent == false) { request.Is404 = true; - _logger.Debug(() => $"{tracePrefix}No document, try last chance lookup"); + _logger.Debug("HandlePublishedContent: No document, try last chance lookup"); // if it fails then give up, there isn't much more that we can do if (_contentLastChanceFinder.TryFindContent(request) == false) { - _logger.Debug(() => $"{tracePrefix}Failed to find a document, give up"); + _logger.Debug("HandlePublishedContent: Failed to find a document, give up"); break; } - _logger.Debug(() => $"{tracePrefix}Found a document"); + _logger.Debug("HandlePublishedContent: Found a document"); } // follow internal redirects as long as it's not running out of control ie infinite loop of some sort @@ -542,11 +541,11 @@ namespace Umbraco.Web.Routing if (i == maxLoop || j == maxLoop) { - _logger.Debug(() => $"{tracePrefix}Looks like we're running into an infinite loop, abort"); + _logger.Debug("HandlePublishedContent: Looks like we're running into an infinite loop, abort"); request.PublishedContent = null; } - _logger.Debug(() => $"{tracePrefix}End"); + _logger.Debug("HandlePublishedContent: End"); } /// @@ -559,8 +558,6 @@ namespace Umbraco.Web.Routing /// private bool FollowInternalRedirects(PublishedRequest request) { - const string tracePrefix = "FollowInternalRedirects: "; - if (request.PublishedContent == null) throw new InvalidOperationException("There is no PublishedContent."); @@ -593,23 +590,25 @@ namespace Umbraco.Web.Routing if (valid == false) { // bad redirect - log and display the current page (legacy behavior) - _logger.Debug(() => $"{tracePrefix}Failed to redirect to id={request.PublishedContent.GetProperty(Constants.Conventions.Content.InternalRedirectId).GetSourceValue()}: value is not an int nor a GuidUdi."); + _logger.Debug("FollowInternalRedirects: Failed to redirect to id={InternalRedirectId}: value is not an int nor a GuidUdi.", + request.PublishedContent.GetProperty(Constants.Conventions.Content.InternalRedirectId).GetSourceValue()); } if (internalRedirectNode == null) { - _logger.Debug(() => $"{tracePrefix}Failed to redirect to id={request.PublishedContent.GetProperty(Constants.Conventions.Content.InternalRedirectId).GetSourceValue()}: no such published document."); + _logger.Debug("FollowInternalRedirects: Failed to redirect to id={InternalRedirectId}: no such published document.", + request.PublishedContent.GetProperty(Constants.Conventions.Content.InternalRedirectId).GetSourceValue()); } else if (internalRedirectId == request.PublishedContent.Id) { // redirect to self - _logger.Debug(() => $"{tracePrefix}Redirecting to self, ignore"); + _logger.Debug("FollowInternalRedirects: Redirecting to self, ignore"); } else { request.SetInternalRedirectPublishedContent(internalRedirectNode); // don't use .PublishedContent here redirect = true; - _logger.Debug(() => $"{tracePrefix}Redirecting to id={internalRedirectId}"); + _logger.Debug("FollowInternalRedirects: Redirecting to id={InternalRedirectId}", internalRedirectId); } return redirect; @@ -621,8 +620,6 @@ namespace Umbraco.Web.Routing /// Redirecting to a different site root and/or culture will not pick the new site root nor the new culture. private void EnsurePublishedContentAccess(PublishedRequest request) { - const string tracePrefix = "EnsurePublishedContentAccess: "; - if (request.PublishedContent == null) throw new InvalidOperationException("There is no PublishedContent."); @@ -632,13 +629,13 @@ namespace Umbraco.Web.Routing if (publicAccessAttempt) { - _logger.Debug(() => $"{tracePrefix}Page is protected, check for access"); + _logger.Debug("EnsurePublishedContentAccess: Page is protected, check for access"); var membershipHelper = Current.Container.GetInstance(); if (membershipHelper.IsLoggedIn() == false) { - _logger.Debug(() => $"{tracePrefix}Not logged in, redirect to login page"); + _logger.Debug("EnsurePublishedContentAccess: Not logged in, redirect to login page"); var loginPageId = publicAccessAttempt.Result.LoginNodeId; @@ -647,19 +644,19 @@ namespace Umbraco.Web.Routing } else if (_services.PublicAccessService.HasAccess(request.PublishedContent.Id, _services.ContentService, GetRolesForLogin(membershipHelper.CurrentUserName)) == false) { - _logger.Debug(() => $"{tracePrefix}Current member has not access, redirect to error page"); + _logger.Debug("EnsurePublishedContentAccess: Current member has not access, redirect to error page"); var errorPageId = publicAccessAttempt.Result.NoAccessNodeId; if (errorPageId != request.PublishedContent.Id) request.PublishedContent = request.UmbracoContext.PublishedSnapshot.Content.GetById(errorPageId); } else { - _logger.Debug(() => $"{tracePrefix}Current member has access"); + _logger.Debug("EnsurePublishedContentAccess: Current member has access"); } } else { - _logger.Debug(() => $"{tracePrefix}Page is not protected"); + _logger.Debug("EnsurePublishedContentAccess: Page is not protected"); } } @@ -672,8 +669,6 @@ namespace Umbraco.Web.Routing // use the Prepared event to change the template if they wish. Should we also // implement an ITemplateFinder logic? - const string tracePrefix = "FindTemplate: "; - if (request.PublishedContent == null) { request.TemplateModel = null; @@ -710,16 +705,16 @@ namespace Umbraco.Web.Routing if (templateId > 0) { - _logger.Debug(() => $"{tracePrefix}Look for template id={templateId}"); + _logger.Debug("FindTemplate: Look for template id={TemplateId}", templateId); var template = _services.FileService.GetTemplate(templateId); if (template == null) throw new InvalidOperationException("The template with Id " + templateId + " does not exist, the page cannot render"); request.TemplateModel = template; - _logger.Debug(() => $"{tracePrefix}Got template id={template.Id} alias=\"{template.Alias}\""); + _logger.Debug("FindTemplate: Got template id={TemplateId} alias='{TemplateAlias}'", template.Id, template.Alias); } else { - _logger.Debug(() => $"{tracePrefix}No specified template."); + _logger.Debug("FindTemplate: No specified template."); } } else @@ -731,24 +726,24 @@ namespace Umbraco.Web.Routing // ignore if the alias does not match - just trace if (request.HasTemplate) - _logger.Debug(() => $"{tracePrefix}Has a template already, but also an alternate template."); - _logger.Debug(() => $"{tracePrefix}Look for alternate template alias=\"{altTemplate}\""); + _logger.Debug("FindTemplate: Has a template already, but also an alternate template."); + _logger.Debug("FindTemplate: Look for alternate template alias='{AltTemplate}'", altTemplate); var template = _services.FileService.GetTemplate(altTemplate); if (template != null) { request.TemplateModel = template; - _logger.Debug(() => $"{tracePrefix}Got template id={template.Id} alias=\"{template.Alias}\""); + _logger.Debug("FindTemplate: Got template id={TemplateId} alias='{TemplateAlias}'", template.Id, template.Alias); } else { - _logger.Debug(() => $"{tracePrefix}The template with alias=\"{altTemplate}\" does not exist, ignoring."); + _logger.Debug("FindTemplate: The template with alias='{AltTemplate}' does not exist, ignoring.", altTemplate); } } if (request.HasTemplate == false) { - _logger.Debug(() => $"{tracePrefix}No template was found."); + _logger.Debug("FindTemplate: No template was found."); // initial idea was: if we're not already 404 and UmbracoSettings.HandleMissingTemplateAs404 is true // then reset _pcr.Document to null to force a 404. @@ -761,7 +756,7 @@ namespace Umbraco.Web.Routing } else { - _logger.Debug(() => $"{tracePrefix}Running with template id={request.TemplateModel.Id} alias=\"{request.TemplateModel.Alias}\""); + _logger.Debug("FindTemplate: Running with template id={TemplateId} alias='{TemplateAlias}'", request.TemplateModel.Id, request.TemplateModel.Alias); } } diff --git a/src/Umbraco.Web/Routing/UrlProviderExtensions.cs b/src/Umbraco.Web/Routing/UrlProviderExtensions.cs index aa34c9e555..c390c03ac7 100644 --- a/src/Umbraco.Web/Routing/UrlProviderExtensions.cs +++ b/src/Umbraco.Web/Routing/UrlProviderExtensions.cs @@ -65,9 +65,9 @@ namespace Umbraco.Web.Routing { url = umbracoContext.UrlProvider.GetUrl(content.Id, culture); } - catch (Exception e) + catch (Exception ex) { - logger.Error("GetUrl exception.", e); + logger.Error(ex, "GetUrl exception."); url = "#ex"; } diff --git a/src/Umbraco.Web/Scheduling/BackgroundTaskRunner.cs b/src/Umbraco.Web/Scheduling/BackgroundTaskRunner.cs index b464e4fb31..858692edc0 100644 --- a/src/Umbraco.Web/Scheduling/BackgroundTaskRunner.cs +++ b/src/Umbraco.Web/Scheduling/BackgroundTaskRunner.cs @@ -233,7 +233,7 @@ namespace Umbraco.Web.Scheduling throw new InvalidOperationException("The task runner has completed."); // add task - _logger.Debug(() => _logPrefix + "Task added " + task.GetType().FullName); + _logger.Debug("{LogPrefix} Task Added {TaskType}", _logPrefix , task.GetType().FullName); _tasks.Post(task); // start @@ -253,12 +253,12 @@ namespace Umbraco.Web.Scheduling { if (_completed) { - _logger.Debug(() => _logPrefix + $"Task cannot be added {task.GetType().FullName}, the task runner has already shutdown"); + _logger.Debug("{LogPrefix} Task cannot be added {TaskType}, the task runner has already shutdown", _logPrefix, task.GetType().FullName); return false; } // add task - _logger.Debug(() => _logPrefix + "Task added " + task.GetType().FullName); + _logger.Debug("{LogPrefix} Task added {TaskType}", _logPrefix, task.GetType().FullName); _tasks.Post(task); // start @@ -315,7 +315,7 @@ namespace Umbraco.Web.Scheduling _shutdownToken = _shutdownTokenSource.Token; _runningTask = Task.Run(async () => await Pump().ConfigureAwait(false), _shutdownToken); - _logger.Debug(() => _logPrefix + "Starting"); + _logger.Debug("{LogPrefix} Starting", _logPrefix); } /// @@ -387,9 +387,9 @@ namespace Umbraco.Web.Scheduling { await RunAsync(bgTask, _cancelTokenSource.Token).ConfigureAwait(false); } - catch (Exception e) + catch (Exception ex) { - _logger.Error(_logPrefix + "Task runner exception.", e); + _logger.Error(ex, "{LogPrefix} Task runner exception", _logPrefix); } // done @@ -414,7 +414,7 @@ namespace Umbraco.Web.Scheduling if (_shutdownToken.IsCancellationRequested == false && _tasks.Count > 0) continue; // if we really have nothing to do, stop - _logger.Debug(() => _logPrefix + "Stopping"); + _logger.Debug("{LogPrefix} Stopping", _logPrefix); if (_options.PreserveRunningTask == false) _runningTask = null; @@ -536,7 +536,8 @@ namespace Umbraco.Web.Scheduling } catch (Exception ex) { - _logger.Error(_logPrefix + "Task has failed", ex); + + _logger.Error(ex, "{LogPrefix} Task has failed", _logPrefix); } } @@ -579,7 +580,7 @@ namespace Umbraco.Web.Scheduling } catch (Exception ex) { - _logger.Error(_logPrefix + name + " exception occurred", ex); + _logger.Error(ex, "{LogPrefix} {Name} exception occurred", _logPrefix, name); } } @@ -667,7 +668,7 @@ namespace Umbraco.Web.Scheduling if (_terminating == false) { _terminating = true; - _logger.Info(() => $"{_logPrefix}Terminating{(immediate ? immediate.ToString() : "")}"); + _logger.Info("{LogPrefix} Terminating {Immediate}", _logPrefix, immediate ? immediate.ToString() : string.Empty); onTerminating = true; } } @@ -681,7 +682,7 @@ namespace Umbraco.Web.Scheduling // processing, call the UnregisterObject method, and then return or it can return immediately and complete // processing asynchronously before calling the UnregisterObject method. - _logger.Info(() => _logPrefix + "Waiting for tasks to complete"); + _logger.Info("{LogPrefix} Waiting for tasks to complete", _logPrefix); Shutdown(false, false); // do not accept any more tasks, flush the queue, do not wait // raise the completed event only after the running threading task has completed @@ -700,7 +701,7 @@ namespace Umbraco.Web.Scheduling // immediate parameter is true, the registered object must call the UnregisterObject method before returning; // otherwise, its registration will be removed by the application manager. - _logger.Info(() => _logPrefix + "Cancelling tasks"); + _logger.Info("{LogPrefix} Cancelling tasks", _logPrefix); Shutdown(true, true); // cancel all tasks, wait for the current one to end Terminate(true); } @@ -723,7 +724,9 @@ namespace Umbraco.Web.Scheduling terminatedSource = _terminatedSource; } - _logger.Info(() => _logPrefix + "Tasks " + (immediate ? "cancelled" : "completed") + ", terminated"); + _logger.Info("{LogPrefix} Tasks {TaskStatus}, terminated", + _logPrefix, + immediate ? "cancelled" : "completed"); OnEvent(Terminated, "Terminated"); diff --git a/src/Umbraco.Web/Scheduling/KeepAlive.cs b/src/Umbraco.Web/Scheduling/KeepAlive.cs index af3b1f1cb9..cdc011c52d 100644 --- a/src/Umbraco.Web/Scheduling/KeepAlive.cs +++ b/src/Umbraco.Web/Scheduling/KeepAlive.cs @@ -64,9 +64,9 @@ namespace Umbraco.Web.Scheduling var request = new HttpRequestMessage(HttpMethod.Get, url); var result = await _httpClient.SendAsync(request, token); } - catch (Exception e) + catch (Exception ex) { - _logger.Error(string.Format("Failed (at \"{0}\").", umbracoAppUrl), e); + _logger.Error(ex, "Failed (at '{UmbracoAppUrl}').", umbracoAppUrl); } } diff --git a/src/Umbraco.Web/Scheduling/LogScrubber.cs b/src/Umbraco.Web/Scheduling/LogScrubber.cs index 9edd203856..5fcdd4d6dc 100644 --- a/src/Umbraco.Web/Scheduling/LogScrubber.cs +++ b/src/Umbraco.Web/Scheduling/LogScrubber.cs @@ -41,9 +41,9 @@ namespace Umbraco.Web.Scheduling if (settings.Logging.MaxLogAge > -1) maximumAge = settings.Logging.MaxLogAge; } - catch (Exception e) + catch (Exception ex) { - _logger.Error("Unable to locate a log scrubbing maximum age. Defaulting to 24 hours.", e); + _logger.Error(ex, "Unable to locate a log scrubbing maximum age. Defaulting to 24 hours."); } return maximumAge; @@ -57,9 +57,9 @@ namespace Umbraco.Web.Scheduling if (settings.Logging.CleaningMiliseconds > -1) interval = settings.Logging.CleaningMiliseconds; } - catch (Exception e) + catch (Exception ex) { - logger.Error("Unable to locate a log scrubbing interval. Defaulting to 4 hours.", e); + logger.Error(ex, "Unable to locate a log scrubbing interval. Defaulting to 4 hours."); } return interval; } diff --git a/src/Umbraco.Web/Scheduling/ScheduledPublishing.cs b/src/Umbraco.Web/Scheduling/ScheduledPublishing.cs index fa5fc452db..ae2031dac6 100644 --- a/src/Umbraco.Web/Scheduling/ScheduledPublishing.cs +++ b/src/Umbraco.Web/Scheduling/ScheduledPublishing.cs @@ -62,9 +62,9 @@ namespace Umbraco.Web.Scheduling var publisher = new ScheduledPublisher(_contentService, _logger, _userService); var count = publisher.CheckPendingAndProcess(); } - catch (Exception e) + catch (Exception ex) { - _logger.Error("Failed.", e); + _logger.Error(ex, "Failed."); } return true; // repeat diff --git a/src/Umbraco.Web/Scheduling/ScheduledTasks.cs b/src/Umbraco.Web/Scheduling/ScheduledTasks.cs index dc0f77e0fc..9644ad864c 100644 --- a/src/Umbraco.Web/Scheduling/ScheduledTasks.cs +++ b/src/Umbraco.Web/Scheduling/ScheduledTasks.cs @@ -82,7 +82,7 @@ namespace Umbraco.Web.Scheduling } catch (Exception ex) { - _logger.Error("An error occurred calling web task for url: " + url, ex); + _logger.Error(ex, "An error occurred calling web task for url: {Url}", url); } return false; } @@ -113,9 +113,9 @@ namespace Umbraco.Web.Scheduling { await ProcessTasksAsync(token); } - catch (Exception ee) + catch (Exception ex) { - _logger.Error("Error executing scheduled task", ee); + _logger.Error(ex, "Error executing scheduled task"); } } diff --git a/src/Umbraco.Web/Scheduling/SchedulerComponent.cs b/src/Umbraco.Web/Scheduling/SchedulerComponent.cs index 68f6d008e2..12f85c49ba 100644 --- a/src/Umbraco.Web/Scheduling/SchedulerComponent.cs +++ b/src/Umbraco.Web/Scheduling/SchedulerComponent.cs @@ -87,7 +87,7 @@ namespace Umbraco.Web.Scheduling { LazyInitializer.EnsureInitialized(ref _tasks, ref _started, ref _locker, () => { - _logger.Debug(() => "Initializing the scheduler"); + _logger.Debug("Initializing the scheduler"); var settings = UmbracoConfig.For.UmbracoSettings(); var tasks = new List(); diff --git a/src/Umbraco.Web/Search/ExamineComponent.cs b/src/Umbraco.Web/Search/ExamineComponent.cs index 44cc6d60f1..ff7d0c8dc4 100644 --- a/src/Umbraco.Web/Search/ExamineComponent.cs +++ b/src/Umbraco.Web/Search/ExamineComponent.cs @@ -91,7 +91,7 @@ namespace Umbraco.Web.Search var registeredIndexers = examineManager.IndexProviders.Values.OfType().Count(x => x.EnableDefaultEventHandler); - profilingLogger.Logger.Info(() => $"Adding examine event handlers for {registeredIndexers} index providers."); + profilingLogger.Logger.Info("Adding examine event handlers for {RegisteredIndexers} index providers.", registeredIndexers); // don't bind event handlers if we're not suppose to listen if (registeredIndexers == 0) @@ -133,9 +133,9 @@ namespace Umbraco.Web.Search // rebuilds any empty indexes RebuildIndexes(true, _examineManager, logger); } - catch (Exception e) + catch (Exception ex) { - logger.Error("Failed to rebuild empty indexes.", e); + logger.Error(ex, "Failed to rebuild empty indexes."); } }); bg.Start(); @@ -200,7 +200,7 @@ namespace Umbraco.Web.Search var dir = luceneIndexer.GetLuceneDirectory(); if (IndexWriter.IsLocked(dir)) { - logger.Info(() => $"Forcing index {luceneIndexer.Name} to be unlocked since it was left in a locked state"); + logger.Info("Forcing index {IndexerName} to be unlocked since it was left in a locked state", luceneIndexer.Name); IndexWriter.Unlock(dir); } } @@ -219,9 +219,9 @@ namespace Umbraco.Web.Search i.DocumentWriting += grid.DocumentWriting; } } - catch (Exception e) + catch (Exception ex) { - logger.Error("Failed to bind grid property editor.", e); + logger.Error(ex, "Failed to bind grid property editor."); } } diff --git a/src/Umbraco.Web/Security/Identity/AuthenticationOptionsExtensions.cs b/src/Umbraco.Web/Security/Identity/AuthenticationOptionsExtensions.cs index 08e367eeeb..20f93f44a6 100644 --- a/src/Umbraco.Web/Security/Identity/AuthenticationOptionsExtensions.cs +++ b/src/Umbraco.Web/Security/Identity/AuthenticationOptionsExtensions.cs @@ -108,7 +108,7 @@ namespace Umbraco.Web.Security.Identity } catch (System.Exception ex) { - Current.Logger.Error(typeof (AuthenticationOptionsExtensions), "Could not read AuthenticationOptions properties", ex); + Current.Logger.Error(typeof (AuthenticationOptionsExtensions), ex, "Could not read AuthenticationOptions properties"); } } else diff --git a/src/Umbraco.Web/Security/MembershipHelper.cs b/src/Umbraco.Web/Security/MembershipHelper.cs index bed6099964..b632173669 100644 --- a/src/Umbraco.Web/Security/MembershipHelper.cs +++ b/src/Umbraco.Web/Security/MembershipHelper.cs @@ -277,7 +277,7 @@ namespace Umbraco.Web.Security if (member == null) { //this should not happen - Current.Logger.Warn(() => $"The member validated but then no member was returned with the username {username}"); + Current.Logger.Warn("The member validated but then no member was returned with the username {Username}", username); return false; } //Log them in diff --git a/src/Umbraco.Web/Security/Providers/UmbracoMembershipProvider.cs b/src/Umbraco.Web/Security/Providers/UmbracoMembershipProvider.cs index 51feed6746..1b528c2ba9 100644 --- a/src/Umbraco.Web/Security/Providers/UmbracoMembershipProvider.cs +++ b/src/Umbraco.Web/Security/Providers/UmbracoMembershipProvider.cs @@ -149,7 +149,7 @@ namespace Umbraco.Web.Security.Providers if (MemberService.Exists(username)) { status = MembershipCreateStatus.DuplicateUserName; - Current.Logger.Warn>(() => $"Cannot create member as username already exists: {username}"); + Current.Logger.Warn>("Cannot create member as username already exists: {Username}", username); return null; } @@ -157,7 +157,7 @@ namespace Umbraco.Web.Security.Providers if (MemberService.GetByEmail(email) != null && RequiresUniqueEmail) { status = MembershipCreateStatus.DuplicateEmail; - Current.Logger.Warn>(() => $"Cannot create member as a member with the same email address exists: {email}"); + Current.Logger.Warn>("Cannot create member as a member with the same email address exists: {Email}", email); return null; } @@ -524,8 +524,7 @@ namespace Umbraco.Web.Security.Providers if (member == null) { - Current.Logger.Info(() => - $"Login attempt failed for username {username} from IP address {GetCurrentRequestIpAddress()}, the user does not exist" ); + Current.Logger.Info("Login attempt failed for username {Username} from IP address {IpAddress}, the user does not exist", username, GetCurrentRequestIpAddress()); return new ValidateUserResult { @@ -535,8 +534,7 @@ namespace Umbraco.Web.Security.Providers if (member.IsApproved == false) { - Current.Logger.Info(() => - $"Login attempt failed for username {username} from IP address {GetCurrentRequestIpAddress()}, the user is not approved"); + Current.Logger.Info("Login attempt failed for username {Username} from IP address {IpAddress}, the user is not approved", username, GetCurrentRequestIpAddress()); return new ValidateUserResult { @@ -546,8 +544,7 @@ namespace Umbraco.Web.Security.Providers } if (member.IsLockedOut) { - Current.Logger.Info(() => - $"Login attempt failed for username {username} from IP address {GetCurrentRequestIpAddress()}, the user is locked"); + Current.Logger.Info("Login attempt failed for username {Username} from IP address {IpAddress}, the user is locked", username, GetCurrentRequestIpAddress()); return new ValidateUserResult { @@ -571,13 +568,11 @@ namespace Umbraco.Web.Security.Providers member.IsLockedOut = true; member.LastLockoutDate = DateTime.Now; - Current.Logger.Info(() => - $"Login attempt failed for username {username} from IP address {GetCurrentRequestIpAddress()}, the user is now locked out, max invalid password attempts exceeded"); + Current.Logger.Info("Login attempt failed for username {Username} from IP address {IpAddress}, the user is now locked out, max invalid password attempts exceeded", username, GetCurrentRequestIpAddress()); } else { - Current.Logger.Info(() => - $"Login attempt failed for username {username} from IP address {GetCurrentRequestIpAddress()}"); + Current.Logger.Info("Login attempt failed for username {Username} from IP address {IpAddress}", username, GetCurrentRequestIpAddress()); } } else @@ -590,8 +585,7 @@ namespace Umbraco.Web.Security.Providers member.LastLoginDate = DateTime.Now; - Current.Logger.Info(() => - $"Login attempt succeeded for username {username} from IP address {GetCurrentRequestIpAddress()}"); + Current.Logger.Info("Login attempt succeeded for username {Username} from IP address {IpAddress}", username, GetCurrentRequestIpAddress()); } //don't raise events for this! It just sets the member dates, if we do raise events this will diff --git a/src/Umbraco.Web/Services/ApplicationTreeService.cs b/src/Umbraco.Web/Services/ApplicationTreeService.cs index 006c0fb07d..abd9f08a53 100644 --- a/src/Umbraco.Web/Services/ApplicationTreeService.cs +++ b/src/Umbraco.Web/Services/ApplicationTreeService.cs @@ -339,7 +339,7 @@ namespace Umbraco.Web.Services var clrType = Type.GetType(type); if (clrType == null) { - _logger.Warn(() => $"The tree definition: {addElement} could not be resolved to a .Net object type"); + _logger.Warn("The tree definition: {AddElement} could not be resolved to a .Net object type", addElement); continue; } diff --git a/src/Umbraco.Web/Suspendable.cs b/src/Umbraco.Web/Suspendable.cs index 9e15b2419e..beb0029f4f 100644 --- a/src/Umbraco.Web/Suspendable.cs +++ b/src/Umbraco.Web/Suspendable.cs @@ -39,7 +39,7 @@ namespace Umbraco.Web { _suspended = false; - Current.ProfilingLogger.Logger.Info(typeof (PageCacheRefresher), $"Resume document cache (reload:{(_tried ? "true" : "false")})."); + Current.ProfilingLogger.Logger.Info(typeof (PageCacheRefresher), "Resume document cache (reload:{Tried}).", _tried); if (_tried == false) return; _tried = false; @@ -73,7 +73,7 @@ namespace Umbraco.Web { _suspended = false; - Current.ProfilingLogger.Logger.Info(typeof (ExamineEvents), $"Resume indexers (rebuild:{(_tried ? "true" : "false")})."); + Current.ProfilingLogger.Logger.Info(typeof (ExamineEvents), "Resume indexers (rebuild:{Tried}).", _tried); if (_tried == false) return; _tried = false; diff --git a/src/Umbraco.Web/Templates/TemplateUtilities.cs b/src/Umbraco.Web/Templates/TemplateUtilities.cs index e22a39bfeb..782878b5c0 100644 --- a/src/Umbraco.Web/Templates/TemplateUtilities.cs +++ b/src/Umbraco.Web/Templates/TemplateUtilities.cs @@ -100,7 +100,7 @@ namespace Umbraco.Web.Templates { // find all relative urls (ie. urls that contain ~) var tags = ResolveUrlPattern.Matches(text); - Current.Logger.Debug(typeof(IOHelper), "After regex: " + timer.Stopwatch.ElapsedMilliseconds + " matched: " + tags.Count); + Current.Logger.Debug(typeof(IOHelper), "After regex: {ElapsedMilliseconds} matched: {TagsCount}", timer.Stopwatch.ElapsedMilliseconds, tags.Count); foreach (Match tag in tags) { var url = ""; diff --git a/src/Umbraco.Web/Trees/LegacyTreeController.cs b/src/Umbraco.Web/Trees/LegacyTreeController.cs index 155e7db3e7..87035e0632 100644 --- a/src/Umbraco.Web/Trees/LegacyTreeController.cs +++ b/src/Umbraco.Web/Trees/LegacyTreeController.cs @@ -38,9 +38,8 @@ namespace Umbraco.Web.Trees var attempt = tree.TryLoadFromLegacyTree(id, queryStrings, Url, tree.ApplicationAlias); if (attempt.Success == false) { - var msg = "Could not render tree " + queryStrings.GetRequiredString("treeType") + " for node id " + id; - Logger.Error(msg, attempt.Exception); - throw new ApplicationException(msg); + Logger.Error(attempt.Exception, "Could not render tree {TreeType} for node id {NodeId}", queryStrings.GetRequiredString("treeType"), id); + throw new ApplicationException("Could not render tree " + queryStrings.GetRequiredString("treeType") + " for node id " + id); } return attempt.Result; @@ -65,9 +64,8 @@ namespace Umbraco.Web.Trees var attempt = tree.TryGetMenuFromLegacyTreeRootNode(queryStrings, Url); if (attempt.Success == false) { - var msg = "Could not render menu for root node for treeType " + queryStrings.GetRequiredString("treeType"); - Logger.Error(msg, attempt.Exception); - throw new ApplicationException(msg); + Logger.Error(attempt.Exception, "Could not render menu for root node for treeType {TreeType}", queryStrings.GetRequiredString("treeType")); + throw new ApplicationException("Could not render menu for root node for treeType " + queryStrings.GetRequiredString("treeType")); } foreach (var menuItem in attempt.Result.Items) @@ -81,9 +79,8 @@ namespace Umbraco.Web.Trees var attempt = tree.TryGetMenuFromLegacyTreeNode(parentId, id, queryStrings, Url); if (attempt.Success == false) { - var msg = "Could not render menu for treeType " + queryStrings.GetRequiredString("treeType") + " for node id " + parentId; - Logger.Error(msg, attempt.Exception); - throw new ApplicationException(msg); + Logger.Error(attempt.Exception, "Could not render menu for treeType {TreeType} for node id {ParentNodeId}", queryStrings.GetRequiredString("treeType"), parentId); + throw new ApplicationException("Could not render menu for treeType " + queryStrings.GetRequiredString("treeType") + " for node id " + parentId); } foreach (var menuItem in attempt.Result.Items) { diff --git a/src/Umbraco.Web/Trees/LegacyTreeJavascript.cs b/src/Umbraco.Web/Trees/LegacyTreeJavascript.cs index 1190e60699..0ae9916d4b 100644 --- a/src/Umbraco.Web/Trees/LegacyTreeJavascript.cs +++ b/src/Umbraco.Web/Trees/LegacyTreeJavascript.cs @@ -34,7 +34,7 @@ namespace Umbraco.Web.Trees } catch (Exception ex) { - Current.Logger.Error(typeof(LegacyTreeJavascript), "Could not load the JS from the legacy tree " + bTree.TreeAlias, ex); + Current.Logger.Error(typeof(LegacyTreeJavascript), ex, "Could not load the JS from the legacy tree {TreeAlias}", bTree.TreeAlias); } } @@ -64,9 +64,9 @@ namespace Umbraco.Web.Trees } } } - catch (Exception ee) + catch (Exception ex) { - Current.Logger.Error(typeof(LegacyTreeJavascript), "Error initializing tree action", ee); + Current.Logger.Error(typeof(LegacyTreeJavascript), ex, "Error initializing tree action"); } } diff --git a/src/Umbraco.Web/UI/CdfLogger.cs b/src/Umbraco.Web/UI/CdfLogger.cs index ab2ec18197..2a36a52376 100644 --- a/src/Umbraco.Web/UI/CdfLogger.cs +++ b/src/Umbraco.Web/UI/CdfLogger.cs @@ -36,12 +36,12 @@ namespace Umbraco.Web.UI public void Error(string msg, Exception ex) { - _logger.Error(msg, ex); + _logger.Error(ex, msg); } public void Fatal(string msg, Exception ex) { - _logger.Error(msg, ex); + _logger.Error(ex, msg); } } } diff --git a/src/Umbraco.Web/UI/Pages/UmbracoEnsuredPage.cs b/src/Umbraco.Web/UI/Pages/UmbracoEnsuredPage.cs index 48bb3e6881..a8cb93c704 100644 --- a/src/Umbraco.Web/UI/Pages/UmbracoEnsuredPage.cs +++ b/src/Umbraco.Web/UI/Pages/UmbracoEnsuredPage.cs @@ -102,7 +102,7 @@ namespace Umbraco.Web.UI.Pages if (!Security.ValidateUserApp(CurrentApp)) { var ex = new SecurityException(String.Format("The current user doesn't have access to the section/app '{0}'", CurrentApp)); - Current.Logger.Error(String.Format("Tried to access '{0}'", CurrentApp), ex); + Current.Logger.Error(ex, "Tried to access '{CurrentApp}'", CurrentApp); throw ex; } diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 28779c0486..cc477c3224 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -67,8 +67,6 @@ - - diff --git a/src/Umbraco.Web/UmbracoModule.cs b/src/Umbraco.Web/UmbracoModule.cs index 819c144f26..7d08822791 100644 --- a/src/Umbraco.Web/UmbracoModule.cs +++ b/src/Umbraco.Web/UmbracoModule.cs @@ -51,7 +51,10 @@ namespace Umbraco.Web var end = false; var response = context.Response; - logger.Debug(() => $"Response status: Redirect={(pcr.IsRedirect ? (pcr.IsRedirectPermanent ? "permanent" : "redirect") : "none")}, Is404={(pcr.Is404 ? "true" : "false")}, StatusCode={pcr.ResponseStatusCode}"); + logger.Debug("Response status: Redirect={Redirect}, Is404={Is404}, StatusCode={ResponseStatusCode}", + pcr.IsRedirect ? (pcr.IsRedirectPermanent ? "permanent" : "redirect") : "none", + pcr.Is404 ? "true" : "false", + pcr.ResponseStatusCode); if(pcr.Cacheability != default) response.Cache.SetCacheability(pcr.Cacheability); diff --git a/src/Umbraco.Web/WebApi/Filters/AngularAntiForgeryHelper.cs b/src/Umbraco.Web/WebApi/Filters/AngularAntiForgeryHelper.cs index 92589fc370..a0bbeac851 100644 --- a/src/Umbraco.Web/WebApi/Filters/AngularAntiForgeryHelper.cs +++ b/src/Umbraco.Web/WebApi/Filters/AngularAntiForgeryHelper.cs @@ -59,7 +59,7 @@ namespace Umbraco.Web.WebApi.Filters } catch (Exception ex) { - Current.Logger.Error(typeof(AngularAntiForgeryHelper), "Could not validate XSRF token", ex); + Current.Logger.Error(typeof(AngularAntiForgeryHelper), ex, "Could not validate XSRF token"); return false; } return true; diff --git a/src/Umbraco.Web/WebApi/Filters/FileUploadCleanupFilterAttribute.cs b/src/Umbraco.Web/WebApi/Filters/FileUploadCleanupFilterAttribute.cs index 9b2a533273..b60545e3cb 100644 --- a/src/Umbraco.Web/WebApi/Filters/FileUploadCleanupFilterAttribute.cs +++ b/src/Umbraco.Web/WebApi/Filters/FileUploadCleanupFilterAttribute.cs @@ -66,7 +66,7 @@ namespace Umbraco.Web.WebApi.Filters } catch (System.Exception ex) { - Current.Logger.Error("Could not delete temp file " + f.TempFilePath, ex); + Current.Logger.Error(ex, "Could not delete temp file {FileName}", f.TempFilePath); } } } @@ -98,7 +98,7 @@ namespace Umbraco.Web.WebApi.Filters } catch (System.Exception ex) { - Current.Logger.Error("Could not acquire actionExecutedContext.Response.Content", ex); + Current.Logger.Error(ex, "Could not acquire actionExecutedContext.Response.Content"); return; } @@ -121,7 +121,7 @@ namespace Umbraco.Web.WebApi.Filters tempFolders.Add(dir); } - Current.Logger.Debug("Removing temp file " + f.TempFilePath); + Current.Logger.Debug("Removing temp file {FileName}", f.TempFilePath); try { @@ -129,7 +129,7 @@ namespace Umbraco.Web.WebApi.Filters } catch (System.Exception ex) { - Current.Logger.Error("Could not delete temp file " + f.TempFilePath, ex); + Current.Logger.Error(ex, "Could not delete temp file {FileName}", f.TempFilePath); } //clear out the temp path so it's not returned in the response @@ -148,12 +148,12 @@ namespace Umbraco.Web.WebApi.Filters } else { - Current.Logger.Warn("The actionExecutedContext.Request.Content.Value is not IHaveUploadedFiles, it is " + objectContent.Value.GetType()); + Current.Logger.Warn("The actionExecutedContext.Request.Content.Value is not IHaveUploadedFiles, it is {ObjectType}", objectContent.Value.GetType()); } } else { - Current.Logger.Warn("The actionExecutedContext.Request.Content is not ObjectContent, it is " + actionExecutedContext.Request.Content.GetType()); + Current.Logger.Warn("The actionExecutedContext.Request.Content is not ObjectContent, it is {RequestObjectType}", actionExecutedContext.Request.Content.GetType()); } } @@ -171,7 +171,7 @@ namespace Umbraco.Web.WebApi.Filters } catch (System.Exception ex) { - Current.Logger.Error("Could not delete temp file " + file, ex); + Current.Logger.Error(ex, "Could not delete temp file {FileName}", file); } } } diff --git a/src/Umbraco.Web/WebApi/UnhandledExceptionLogger.cs b/src/Umbraco.Web/WebApi/UnhandledExceptionLogger.cs index 7c289889c2..1dd43f5b2a 100644 --- a/src/Umbraco.Web/WebApi/UnhandledExceptionLogger.cs +++ b/src/Umbraco.Web/WebApi/UnhandledExceptionLogger.cs @@ -24,12 +24,12 @@ namespace Umbraco.Web.WebApi public override void Log(ExceptionLoggerContext context) { - if (context != null && context.ExceptionContext != null - && context.ExceptionContext.ActionContext != null && context.ExceptionContext.ActionContext.ControllerContext != null - && context.ExceptionContext.ActionContext.ControllerContext.Controller != null - && context.Exception != null) + if (context != null && context.Exception != null) { - _logger.Error(context.ExceptionContext.ActionContext.ControllerContext.Controller.GetType(), "Unhandled controller exception occurred", context.Exception); + var requestUrl = context.ExceptionContext?.ControllerContext?.Request?.RequestUri?.AbsoluteUri; + var controllerType = context.ExceptionContext?.ActionContext?.ControllerContext?.Controller?.GetType(); + + _logger.Error(controllerType, context.Exception, "Unhandled controller exception occurred for request '{RequestUrl}'", requestUrl); } } diff --git a/src/Umbraco.Web/_Legacy/Actions/Action.cs b/src/Umbraco.Web/_Legacy/Actions/Action.cs index 99022eb16d..388a5735fd 100644 --- a/src/Umbraco.Web/_Legacy/Actions/Action.cs +++ b/src/Umbraco.Web/_Legacy/Actions/Action.cs @@ -81,9 +81,9 @@ namespace Umbraco.Web._Legacy.Actions _actionJsList += string.Format(",\n\tmenuItem(\"{0}\", \"{1}\", \"{2}\", \"{3}\")", action.Letter, icon, Current.Services.TextService.Localize("actions/"+ action.Alias, new[] { language }), action.JsFunctionName); } - catch (Exception ee) + catch (Exception ex) { - Current.Logger.Error("Error registrering action to javascript", ee); + Current.Logger.Error(ex, "Error registrering action to javascript"); } } diff --git a/src/Umbraco.Web/_Legacy/PackageActions/addStringToHtmlElement.cs b/src/Umbraco.Web/_Legacy/PackageActions/addStringToHtmlElement.cs index 8eedd13e06..56ebb76980 100644 --- a/src/Umbraco.Web/_Legacy/PackageActions/addStringToHtmlElement.cs +++ b/src/Umbraco.Web/_Legacy/PackageActions/addStringToHtmlElement.cs @@ -123,7 +123,7 @@ namespace Umbraco.Web._Legacy.PackageActions } catch (Exception ex) { - Current.Logger.Error("An error occurred", ex); + Current.Logger.Error(ex, "An error occurred"); } } else @@ -171,7 +171,7 @@ namespace Umbraco.Web._Legacy.PackageActions } catch (Exception ex) { - Current.Logger.Error("An error occurred", ex); + Current.Logger.Error(ex, "An error occurred"); } } else diff --git a/src/Umbraco.Web/_Legacy/Packager/Installer.cs b/src/Umbraco.Web/_Legacy/Packager/Installer.cs index 87ffa2d665..952f1987a4 100644 --- a/src/Umbraco.Web/_Legacy/Packager/Installer.cs +++ b/src/Umbraco.Web/_Legacy/Packager/Installer.cs @@ -187,9 +187,9 @@ namespace umbraco.cms.businesslogic.packager tempDir = UnPack(fi.FullName, deleteFile); LoadConfig(tempDir); } - catch (Exception exception) + catch (Exception ex) { - Current.Logger.Error(string.Format("Error importing file {0}", fi.FullName), exception); + Current.Logger.Error(ex, "Error importing file {FileName}", fi.FullName); throw; } } @@ -317,9 +317,9 @@ namespace umbraco.cms.businesslogic.packager File.Delete(sourceFile); } } - catch (Exception exception) + catch (Exception ex) { - Current.Logger.Error("Package install error", exception); + Current.Logger.Error(ex, "Package install error"); throw; } @@ -522,9 +522,9 @@ namespace umbraco.cms.businesslogic.packager insPack.Save(); } - catch (Exception exception) + catch (Exception ex) { - Current.Logger.Error("Error installing businesslogic", exception); + Current.Logger.Error(ex, "Error installing businesslogic"); throw; } diff --git a/src/Umbraco.Web/_Legacy/Packager/PackageInstance/InstalledPackage.cs b/src/Umbraco.Web/_Legacy/Packager/PackageInstance/InstalledPackage.cs index a358c69389..c16afa0b84 100644 --- a/src/Umbraco.Web/_Legacy/Packager/PackageInstance/InstalledPackage.cs +++ b/src/Umbraco.Web/_Legacy/Packager/PackageInstance/InstalledPackage.cs @@ -87,7 +87,7 @@ namespace umbraco.cms.businesslogic.packager { } catch (Exception ex) { - Current.Logger.Error("An error occured in isPackagedInstalled", ex); + Current.Logger.Error(ex, "An error occured in isPackagedInstalled"); return false; } } diff --git a/src/Umbraco.Web/_Legacy/Packager/PackageInstance/PackageActions.cs b/src/Umbraco.Web/_Legacy/Packager/PackageInstance/PackageActions.cs index 90645fa121..d1df47cd44 100644 --- a/src/Umbraco.Web/_Legacy/Packager/PackageInstance/PackageActions.cs +++ b/src/Umbraco.Web/_Legacy/Packager/PackageInstance/PackageActions.cs @@ -34,9 +34,9 @@ namespace umbraco.cms.businesslogic.packager ipa.Execute(packageName, actionXml); } } - catch (Exception ipaExp) + catch (Exception ex) { - Current.Logger.Error(string.Format("Error loading package action '{0}' for package {1}", ipa.Alias(), packageName), ipaExp); + Current.Logger.Error(ex, "Error loading package action '{PackageActionAlias}' for package {PackageName}", ipa.Alias(), packageName); } } } @@ -60,9 +60,9 @@ namespace umbraco.cms.businesslogic.packager ipa.Undo(packageName, actionXml); } } - catch (Exception ipaExp) + catch (Exception ex) { - Current.Logger.Error(string.Format("Error undoing package action '{0}' for package {1}", ipa.Alias(), packageName), ipaExp); + Current.Logger.Error(ex, "Error undoing package action '{PackageActionAlias}' for package {PackageName}", ipa.Alias(), packageName); } } } diff --git a/src/Umbraco.Web/_Legacy/Packager/data.cs b/src/Umbraco.Web/_Legacy/Packager/data.cs index 9353d52461..88cc7a4b54 100644 --- a/src/Umbraco.Web/_Legacy/Packager/data.cs +++ b/src/Umbraco.Web/_Legacy/Packager/data.cs @@ -180,7 +180,7 @@ namespace umbraco.cms.businesslogic.packager } catch (Exception ex) { - Current.Logger.Error("An error occurred in GetAllPackages", ex); + Current.Logger.Error(ex, "An error occurred in GetAllPackages"); } } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/Tree/JTreeContextMenu.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/Tree/JTreeContextMenu.cs index 267eb7323e..726936f570 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/Tree/JTreeContextMenu.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/Tree/JTreeContextMenu.cs @@ -45,9 +45,9 @@ namespace umbraco.controls.Tree } } } - catch (Exception ee) + catch (Exception ex) { - Current.Logger.Error("Error initializing tree action", ee); + Current.Logger.Error(ex, "Error initializing tree action"); } } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dashboard/FeedProxy.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dashboard/FeedProxy.aspx.cs index dd4988f65a..0e21605fbb 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dashboard/FeedProxy.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dashboard/FeedProxy.aspx.cs @@ -47,7 +47,7 @@ namespace dashboardUtilities } else { - Current.Logger.Debug(string.Format("Access to unallowed feedproxy attempted: {0}", requestUri)); + Current.Logger.Debug("Access to unallowed feedproxy attempted: {RequestUrl}", requestUri); } } } @@ -55,7 +55,7 @@ namespace dashboardUtilities } catch (Exception ex) { - Current.Logger.Error("Exception occurred", ex); + Current.Logger.Error(ex, "Exception occurred"); } } } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/protectPage.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/protectPage.aspx.cs index 518138d761..d1a542fac8 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/protectPage.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/protectPage.aspx.cs @@ -244,7 +244,7 @@ namespace umbraco.presentation.umbraco.dialogs } catch (Exception ex) { - Current.Logger.Error("An error occurred initializing the protect page editor", ex); + Current.Logger.Error(ex, "An error occurred initializing the protect page editor"); } if (GetProtectionType(documentId) == ProtectionType.Simple) diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/sendToTranslation.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/sendToTranslation.aspx.cs index cfefdda52c..62063863bd 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/sendToTranslation.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/sendToTranslation.aspx.cs @@ -182,7 +182,7 @@ namespace umbraco.presentation.dialogs } catch (Exception ex) { - Current.Logger.Error("Error sending translation e-mail", ex); + Current.Logger.Error(ex, "Error sending translation e-mail"); } } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx.cs index ca26c5c08d..f82587a413 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx.cs @@ -137,7 +137,7 @@ namespace umbraco.presentation.webservices } catch (Exception ex) { - Current.Logger.Error("Could not update media sort order", ex); + Current.Logger.Error(ex, "Could not update media sort order"); } } @@ -192,7 +192,7 @@ namespace umbraco.presentation.webservices } catch (Exception ex) { - Current.Logger.Error("Could not update content sort order", ex); + Current.Logger.Error(ex, "Could not update content sort order"); } }