Merge branch 'temp8' into temp8-ui-cleanup
This commit is contained in:
@@ -33,8 +33,6 @@
|
||||
<dependency id="LightInject.Annotation" version="[1.1.0,1.999999)" />
|
||||
<dependency id="LightInject.Mvc" version="[2.0.0,2.999999)" />
|
||||
<dependency id="LightInject.WebApi" version="[2.0.0,2.999999)" />
|
||||
<dependency id="log4net" version="[2.0.8,2.999999)" />
|
||||
<dependency id="Log4Net.Async" version="[2.0.4,2.999999)" />
|
||||
<dependency id="Lucene.Net.Contrib" version="[3.0.3,3.999999)" />
|
||||
<dependency id="Markdown" version="[2.2.1,2.999999)" />
|
||||
<dependency id="Microsoft.AspNet.Identity.Owin" version="[2.2.1,2.999999)" />
|
||||
@@ -53,6 +51,13 @@
|
||||
<dependency id="Newtonsoft.Json" version="[11.0.2,11.999999)" />
|
||||
<dependency id="NPoco" version="[3.9.3,3.999999)" />
|
||||
<dependency id="Semver" version="[2.0.4,2.999999)" />
|
||||
<dependency id="Serilog" version="[2.7.1,2.999999)" />
|
||||
<dependency id="Serilog.Enrichers.Process" version="[2.0.1,2.999999)" />
|
||||
<dependency id="Serilog.Enrichers.Thread" version="[3.0.0,3.999999)" />
|
||||
<dependency id="Serilog.Filters.Expressions" version="[2.0.0,2.999999)" />
|
||||
<dependency id="Serilog.Formatting.Compact" version="[1.0.0,1.999999)" />
|
||||
<dependency id="Serilog.Settings.AppSettings" version="[2.1.2,2.999999)" />
|
||||
<dependency id="Serilog.Sinks.File" version="[4.0.0,4.999999)" />
|
||||
<dependency id="System.Reflection.Primitives" version="[4.3.0,4.999999)" />
|
||||
<dependency id="System.Runtime.Handles" version="[4.3.0,4.999999)" />
|
||||
<dependency id="System.Security.Cryptography.X509Certificates" version="[4.3.2,4.999999)" />
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
not want this to happen as the alpha of the next major is, really, the next major already.
|
||||
-->
|
||||
<dependency id="Microsoft.AspNet.SignalR.Core" version="[2.2.3, 2.999999)" />
|
||||
<dependency id="Umbraco.ModelsBuilder.Ui" version="[8.0.0-alpha.20]" />
|
||||
<dependency id="Umbraco.ModelsBuilder.Ui" version="[8.0.0-alpha.22]" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
@@ -35,7 +35,6 @@
|
||||
<file src="$BuildTmp$\WebApp\config\splashes\**" target="UmbracoFiles\Config\splashes" />
|
||||
<file src="$BuildTmp$\WebApp\config\BackOfficeTours\**" target="Content\Config\BackOfficeTours" />
|
||||
<file src="$BuildTmp$\WebApp\umbraco\**" target="UmbracoFiles\umbraco" />
|
||||
<file src="$BuildTmp$\WebApp\umbraco_client\**" target="UmbracoFiles\umbraco_client" />
|
||||
<file src="$BuildTmp$\WebApp\Media\Web.config" target="Content\Media\Web.config" />
|
||||
|
||||
<file src="$BuildTmp$\WebApp\App_Plugins\ModelsBuilder\modelsbuilder.htm" target="Content\App_Plugins\ModelsBuilder\modelsbuilder.htm" />
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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")]
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// This is used to do an assembly binding redirect via code - normally required due to signature changes in assemblies
|
||||
/// </summary>
|
||||
@@ -30,12 +27,6 @@ namespace Umbraco.Core
|
||||
/// <returns></returns>
|
||||
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
|
||||
|
||||
@@ -111,15 +111,15 @@ namespace Umbraco.Core.Components
|
||||
catch (Exception e)
|
||||
{
|
||||
// in case of an error, force-dump everything to log
|
||||
_logger.Info<BootLoader>(() => GetComponentsReport(requirements));
|
||||
_logger.Error<BootLoader>("Failed to sort components.", e);
|
||||
_logger.Info<BootLoader>("Component Report:\r\n{ComponentReport}", GetComponentsReport(requirements));
|
||||
_logger.Error<BootLoader>(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<BootLoader>(text);
|
||||
_logger.Debug<BootLoader>("Ordered Components: {SortedComponentTypes}", sortedComponentTypes);
|
||||
|
||||
return sortedComponentTypes;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -494,7 +494,7 @@ namespace Umbraco.Core.Composing
|
||||
if (--attempts == 0)
|
||||
throw;
|
||||
|
||||
_logger.Logger.Debug<TypeLoader>(() => $"Attempted to get filestream for file {path} failed, {attempts} attempts left, pausing for {pauseMilliseconds} milliseconds");
|
||||
_logger.Logger.Debug<TypeLoader>("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<TypeLoader>(() => $"Getting {GetName(baseType, attributeType)}: found a cached type list.");
|
||||
_logger.Logger.Debug<TypeLoader>("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<TypeLoader>(() => $"Getting {GetName(baseType, attributeType)}: failed to load from cache file, must scan assemblies.");
|
||||
_logger.Logger.Debug<TypeLoader>("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<TypeLoader>("Getting " + GetName(baseType, attributeType) + ": failed to load cache file type " + type + ", reverting to scanning assemblies.", ex);
|
||||
_logger.Logger.Error<TypeLoader>(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<TypeLoader>(() => $"Getting {GetName(baseType, attributeType)}: loaded types from cache file.");
|
||||
_logger.Logger.Debug<TypeLoader>("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<TypeLoader>(() => $"Getting {GetName(baseType, attributeType)}: scanning assemblies.");
|
||||
_logger.Logger.Debug<TypeLoader>("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<TypeLoader>(() => $"Got {GetName(baseType, attributeType)}, caching ({added.ToString().ToLowerInvariant()}).");
|
||||
_logger.Logger.Debug<TypeLoader>("Got {TypeName}, caching ({CacheType}).", GetName(baseType, attributeType), added.ToString().ToLowerInvariant());
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Logger.Debug<TypeLoader>(() => $"Got {GetName(baseType, attributeType)}.");
|
||||
_logger.Logger.Debug<TypeLoader>("Got {TypeName}.", GetName(baseType, attributeType));
|
||||
}
|
||||
|
||||
return typeList.Types;
|
||||
|
||||
@@ -79,13 +79,13 @@ namespace Umbraco.Core.Configuration
|
||||
versionAttribute.SetValue(newVersion);
|
||||
clientDependencyConfigXml.Save(_fileName, SaveOptions.DisableFormatting);
|
||||
|
||||
_logger.Info<ClientDependencyConfiguration>(() => $"Updated version number from {oldVersion} to {newVersion}");
|
||||
_logger.Info<ClientDependencyConfiguration>("Updated version number from {OldVersion} to {NewVersion}", oldVersion, newVersion);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error<ClientDependencyConfiguration>("Couldn't update ClientDependency version number", ex);
|
||||
_logger.Error<ClientDependencyConfiguration>(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<ClientDependencyConfiguration>(() => $"Updated version number from {oldVersion} to {newVersion}");
|
||||
_logger.Info<ClientDependencyConfiguration>("Updated version number from {OldVersion} to {NewVersion}", oldVersion, newVersion);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error<ClientDependencyConfiguration>("Couldn't update ClientDependency version number", ex);
|
||||
_logger.Error<ClientDependencyConfiguration>(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<ClientDependencyConfiguration>("Could not get path from ClientDependency.config", ex);
|
||||
_logger.Error<ClientDependencyConfiguration>(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<ClientDependencyConfiguration>("Could not clear temp files", ex);
|
||||
_logger.Error<ClientDependencyConfiguration>(ex, "Could not clear temp files");
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<GridEditorsConfig>("Could not parse the contents of grid.editors.config.js into a JSON array", ex);
|
||||
_logger.Error<GridEditorsConfig>(ex, "Could not parse the contents of grid.editors.config.js into a JSON array '{Json}", sourceString);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<UmbracoConfig>("Config error", ex);
|
||||
Current.Logger.Error<UmbracoConfig>(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<UmbracoConfig>("Config error", ex);
|
||||
Current.Logger.Error<UmbracoConfig>(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<UmbracoConfig>("Config error", ex);
|
||||
Current.Logger.Error<UmbracoConfig>(ex, "Config error");
|
||||
throw ex;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Gets the version comment of the executing code (eg "beta").
|
||||
/// </summary>
|
||||
public static string CurrentComment => "alpha.44";
|
||||
public static string CurrentComment => "alpha.49";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the assembly version of Umbraco.Code.dll.
|
||||
|
||||
@@ -111,7 +111,7 @@ namespace Umbraco.Core.IO
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error<MediaFileSystem>("Failed to delete attached file \"" + file + "\".", e);
|
||||
Logger.Error<MediaFileSystem>(e, "Failed to delete attached file '{File}'", file);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -73,11 +73,11 @@ namespace Umbraco.Core.IO
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
{
|
||||
Current.Logger.Error<PhysicalFileSystem>("Not authorized to get directories", ex);
|
||||
Current.Logger.Error<PhysicalFileSystem>(ex, "Not authorized to get directories for '{Path}'", fullPath);
|
||||
}
|
||||
catch (DirectoryNotFoundException ex)
|
||||
{
|
||||
Current.Logger.Error<PhysicalFileSystem>("Directory not found", ex);
|
||||
Current.Logger.Error<PhysicalFileSystem>(ex, "Directory not found for '{Path}'", fullPath);
|
||||
}
|
||||
|
||||
return Enumerable.Empty<string>();
|
||||
@@ -109,7 +109,7 @@ namespace Umbraco.Core.IO
|
||||
}
|
||||
catch (DirectoryNotFoundException ex)
|
||||
{
|
||||
Current.Logger.Error<PhysicalFileSystem>("Directory not found", ex);
|
||||
Current.Logger.Error<PhysicalFileSystem>(ex, "Directory not found for '{Path}'", fullPath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,11 +189,11 @@ namespace Umbraco.Core.IO
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
{
|
||||
Current.Logger.Error<PhysicalFileSystem>("Not authorized to get directories", ex);
|
||||
Current.Logger.Error<PhysicalFileSystem>(ex, "Not authorized to get directories for '{Path}'", fullPath);
|
||||
}
|
||||
catch (DirectoryNotFoundException ex)
|
||||
{
|
||||
Current.Logger.Error<PhysicalFileSystem>("Directory not found", ex);
|
||||
Current.Logger.Error<PhysicalFileSystem>(ex, "Directory not found for '{FullPath}'", fullPath);
|
||||
}
|
||||
|
||||
return Enumerable.Empty<string>();
|
||||
@@ -226,7 +226,7 @@ namespace Umbraco.Core.IO
|
||||
}
|
||||
catch (FileNotFoundException ex)
|
||||
{
|
||||
Current.Logger.Info<PhysicalFileSystem>(() => $"DeleteFile failed with FileNotFoundException: {ex.InnerException}");
|
||||
Current.Logger.Error<PhysicalFileSystem>(ex.InnerException, "DeleteFile failed with FileNotFoundException for '{Path}'", fullPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace Umbraco.Core.IO
|
||||
}
|
||||
|
||||
_logger = logger;
|
||||
_logger.Debug<ShadowFileSystems>(() => "Shadow " + id + ".");
|
||||
_logger.Debug<ShadowFileSystems>("Shadow '{ShadowId}'", id);
|
||||
_id = id;
|
||||
|
||||
_wrappers = wrappers;
|
||||
@@ -112,7 +112,7 @@ namespace Umbraco.Core.IO
|
||||
{
|
||||
lock (Locker)
|
||||
{
|
||||
_logger.Debug<ShadowFileSystems>(() => "UnShadow " + _id + " (" + (_completed ? "complete" : "abort") + ").");
|
||||
_logger.Debug<ShadowFileSystems>("UnShadow '{ShadowId}' {Status}", _id, _completed ? "complete" : "abort");
|
||||
|
||||
var exceptions = new List<Exception>();
|
||||
foreach (var wrapper in _wrappers)
|
||||
|
||||
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Allows for outputting a normalized appdomainappid token in a log format
|
||||
/// </summary>
|
||||
public sealed class AppDomainTokenConverter : log4net.Util.PatternConverter
|
||||
{
|
||||
protected override void Convert(TextWriter writer, object state)
|
||||
{
|
||||
writer.Write(HttpRuntime.AppDomainAppId.ReplaceNonAlphanumericChars(string.Empty));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
using log4net.Appender;
|
||||
using log4net.Core;
|
||||
using log4net.Util;
|
||||
using System;
|
||||
using System.Runtime.Remoting.Messaging;
|
||||
|
||||
namespace Umbraco.Core.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Borrowed from https://github.com/cjbhaines/Log4Net.Async - will reference Nuget packages directly in v8
|
||||
/// </summary>
|
||||
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); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns HttpContext.Current
|
||||
/// </summary>
|
||||
protected internal object HttpContext
|
||||
{
|
||||
get
|
||||
{
|
||||
return CallContext.HostContext;
|
||||
}
|
||||
set
|
||||
{
|
||||
CallContext.HostContext = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The logger name that will be used for logging internal errors.
|
||||
/// </summary>
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Fatal(Type reporting, Exception exception)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(Environment.NewLine + exception, reporting.FullName);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Fatal(Type reporting, string message)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(message);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Fatal(Type reporting, string messageTemplate, params object[] args)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(messageTemplate, args);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Error(Type reporting, Exception exception, string message)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(message + Environment.NewLine + exception, reporting.FullName);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Error(Type reporting, Exception exception)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(Environment.NewLine + exception, reporting.FullName);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Error(Type reporting, string message)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(message);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Error(Type reporting, string messageTemplate, params object[] args)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(messageTemplate, args);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Warn(Type reporting, string format)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(format, reporting.FullName);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Warn(Type reporting, Func<string> messageBuilder)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(messageBuilder(), reporting.FullName);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Warn(Type reporting, string format, params object[] args)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(string.Format(format, args), reporting.FullName);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Warn(Type reporting, string format, params Func<object>[] args)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(string.Format(format, args.Select(x => x()).ToArray()), reporting.FullName);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Warn(Type reporting, Exception exception, string message)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(message + Environment.NewLine + exception, reporting.FullName);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Warn(Type reporting, Exception exception, Func<string> messageBuilder)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(messageBuilder() + Environment.NewLine + exception, reporting.FullName);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Warn(Type reporting, Exception exception, string format, params Func<object>[] args)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(string.Format(format + Environment.NewLine + exception, args.Select(x => x()).ToArray()), reporting.FullName);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Info(Type reporting, string message)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(message, reporting.FullName);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Info(Type reporting, Func<string> messageBuilder)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(messageBuilder(), reporting.FullName);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Info(Type reporting, string format, params object[] args)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(string.Format(format, args), reporting.FullName);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Info(Type reporting, string format, params Func<object>[] args)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(string.Format(format, args.Select(x => x()).ToArray()), reporting.FullName);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Debug(Type reporting, string message)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(message, reporting.FullName);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Debug(Type reporting, Func<string> messageBuilder)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(messageBuilder(), reporting.FullName);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Debug(Type reporting, string format, params object[] args)
|
||||
{
|
||||
@@ -105,9 +116,16 @@ namespace Umbraco.Core.Logging
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Debug(Type reporting, string format, params Func<object>[] 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);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Verbose(Type reporting, string format, params object[] args)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(string.Format(format, args), reporting.FullName);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core
|
||||
namespace Umbraco.Core.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Starts the timer and invokes a callback upon disposal. Provides a simple way of timing an operation by wrapping it in a <code>using</code> (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:
|
||||
@@ -1,22 +1,98 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Umbraco.Core.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the logging service.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Message templates in logging methods follow the Message Templates specification
|
||||
/// available at https://messagetemplates.org/ in order to support structured logging.</para>
|
||||
/// <para>Implementations must ensure that they support these templates. Note that the
|
||||
/// specification includes support for traditional C# numeric placeholders.</para>
|
||||
/// <para>For instance, "Processed {Input} in {Time}ms."</para>
|
||||
/// </remarks>
|
||||
public interface ILogger
|
||||
{
|
||||
/// <summary>
|
||||
/// Logs a fatal message with an exception.
|
||||
/// </summary>
|
||||
/// <param name="reporting">The reporting type.</param>
|
||||
/// <param name="exception">An exception.</param>
|
||||
/// <param name="message">A message.</param>
|
||||
void Fatal(Type reporting, Exception exception, string message);
|
||||
|
||||
/// <summary>
|
||||
/// Logs a fatal exception.
|
||||
/// </summary>
|
||||
/// <param name="reporting">The reporting type.</param>
|
||||
/// <param name="exception">An exception.</param>
|
||||
/// <remarks>The message string is unspecified and is implementation-specific.</remarks>
|
||||
void Fatal(Type reporting, Exception exception);
|
||||
|
||||
/// <summary>
|
||||
/// Logs a fatal message.
|
||||
/// </summary>
|
||||
/// <param name="reporting">The reporting type.</param>
|
||||
/// <param name="message">A message.</param>
|
||||
void Fatal(Type reporting, string message);
|
||||
|
||||
/// <summary>
|
||||
/// Logs a fatal message with an exception.
|
||||
/// </summary>
|
||||
/// <param name="reporting">The reporting type.</param>
|
||||
/// <param name="exception">An exception.</param>
|
||||
/// <param name="messageTemplate">A message template.</param>
|
||||
/// <param name="propertyValues">Property values.</param>
|
||||
void Fatal(Type reporting, Exception exception, string messageTemplate, params object[] propertyValues);
|
||||
|
||||
/// <summary>
|
||||
/// Logs a fatal message.
|
||||
/// </summary>
|
||||
/// <param name="reporting">The reporting type.</param>
|
||||
/// <param name="messageTemplate">A message template.</param>
|
||||
/// <param name="propertyValues">Property values.</param>
|
||||
void Fatal(Type reporting, string messageTemplate, params object[] propertyValues);
|
||||
|
||||
/// <summary>
|
||||
/// Logs an error message with an exception.
|
||||
/// </summary>
|
||||
/// <param name="reporting">The reporting type.</param>
|
||||
/// <param name="exception">An exception.</param>
|
||||
/// <param name="message">A message.</param>
|
||||
void Error(Type reporting, Exception exception, string message);
|
||||
|
||||
/// <summary>
|
||||
/// Logs an error exception.
|
||||
/// </summary>
|
||||
/// <param name="reporting">The reporting type.</param>
|
||||
/// <param name="exception">An exception.</param>
|
||||
/// <remarks>The message string is unspecified and is implementation-specific.</remarks>
|
||||
void Error(Type reporting, Exception exception);
|
||||
|
||||
/// <summary>
|
||||
/// Logs an error message.
|
||||
/// </summary>
|
||||
/// <param name="reporting">The reporting type.</param>
|
||||
/// <param name="message">A message.</param>
|
||||
/// <param name="exception">An exception.</param>
|
||||
void Error(Type reporting, string message, Exception exception = null);
|
||||
void Error(Type reporting, string message);
|
||||
|
||||
// note: should we have more overloads for Error too?
|
||||
/// <summary>
|
||||
/// Logs an error message with an exception.
|
||||
/// </summary>
|
||||
/// <param name="reporting">The reporting type.</param>
|
||||
/// <param name="exception">An exception.</param>
|
||||
/// <param name="messageTemplate">A message template.</param>
|
||||
/// <param name="propertyValues">Property values.</param>
|
||||
void Error(Type reporting, Exception exception, string messageTemplate, params object[] propertyValues);
|
||||
|
||||
/// <summary>
|
||||
/// Logs an error message.
|
||||
/// </summary>
|
||||
/// <param name="reporting">The reporting type.</param>
|
||||
/// <param name="messageTemplate">A message template.</param>
|
||||
/// <param name="propertyValues">Property values.</param>
|
||||
void Error(Type reporting, string messageTemplate, params object[] propertyValues);
|
||||
|
||||
/// <summary>
|
||||
/// Logs a warning message.
|
||||
@@ -29,8 +105,9 @@ namespace Umbraco.Core.Logging
|
||||
/// Logs a warning message.
|
||||
/// </summary>
|
||||
/// <param name="reporting">The reporting type.</param>
|
||||
/// <param name="messageBuilder">A message builder.</param>
|
||||
void Warn(Type reporting, Func<string> messageBuilder);
|
||||
/// <param name="messageTemplate">A message template.</param>
|
||||
/// <param name="propertyValues">Property values.</param>
|
||||
void Warn(Type reporting, string messageTemplate, params object[] propertyValues);
|
||||
|
||||
/// <summary>
|
||||
/// Logs a warning message with an exception.
|
||||
@@ -45,8 +122,9 @@ namespace Umbraco.Core.Logging
|
||||
/// </summary>
|
||||
/// <param name="reporting">The reporting type.</param>
|
||||
/// <param name="exception">An exception.</param>
|
||||
/// <param name="messageBuilder">A message builder.</param>
|
||||
void Warn(Type reporting, Exception exception, Func<string> messageBuilder);
|
||||
/// <param name="messageTemplate">A message template.</param>
|
||||
/// <param name="propertyValues">Property values.</param>
|
||||
void Warn(Type reporting, Exception exception, string messageTemplate, params object[] propertyValues);
|
||||
|
||||
/// <summary>
|
||||
/// Logs an information message.
|
||||
@@ -56,11 +134,12 @@ namespace Umbraco.Core.Logging
|
||||
void Info(Type reporting, string message);
|
||||
|
||||
/// <summary>
|
||||
/// Logs an information message.
|
||||
/// Logs a info message.
|
||||
/// </summary>
|
||||
/// <param name="reporting">The reporting type.</param>
|
||||
/// <param name="messageBuilder">A message builder.</param>
|
||||
void Info(Type reporting, Func<string> messageBuilder);
|
||||
/// <param name="messageTemplate">A message template.</param>
|
||||
/// <param name="propertyValues">Property values.</param>
|
||||
void Info(Type reporting, string messageTemplate, params object[] propertyValues);
|
||||
|
||||
/// <summary>
|
||||
/// Logs a debugging message.
|
||||
@@ -70,10 +149,26 @@ namespace Umbraco.Core.Logging
|
||||
void Debug(Type reporting, string message);
|
||||
|
||||
/// <summary>
|
||||
/// Logs a debugging message.
|
||||
/// Logs a debug message.
|
||||
/// </summary>
|
||||
/// <param name="reporting">The reporting type.</param>
|
||||
/// <param name="messageBuilder">A message builder.</param>
|
||||
void Debug(Type reporting, Func<string> messageBuilder);
|
||||
/// <param name="messageTemplate">A message template.</param>
|
||||
/// <param name="propertyValues">Property values.</param>
|
||||
void Debug(Type reporting, string messageTemplate, params object[] propertyValues);
|
||||
|
||||
/// <summary>
|
||||
/// Logs a verbose message.
|
||||
/// </summary>
|
||||
/// <param name="reporting">The reporting type.</param>
|
||||
/// <param name="message">A message.</param>
|
||||
void Verbose(Type reporting, string message);
|
||||
|
||||
/// <summary>
|
||||
/// Logs a verbose message.
|
||||
/// </summary>
|
||||
/// <param name="reporting">The reporting type.</param>
|
||||
/// <param name="messageTemplate">A message template.</param>
|
||||
/// <param name="propertyValues">Property values.</param>
|
||||
void Verbose(Type reporting, string messageTemplate, params object[] propertyValues);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
namespace Umbraco.Core.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Borrowed from https://github.com/cjbhaines/Log4Net.Async - will reference Nuget packages directly in v8
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
internal interface IQueue<T>
|
||||
{
|
||||
void Enqueue(T item);
|
||||
bool TryDequeue(out T ret);
|
||||
}
|
||||
}
|
||||
@@ -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<T>(string.Empty, new ImageProcessingException(message));
|
||||
Current.Logger.Error<T>(new ImageProcessingException(message));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@ namespace Umbraco.Core.Logging
|
||||
/// <inheritdoc/>
|
||||
public IDisposable Step(string name)
|
||||
{
|
||||
_logger.Debug<LogProfiler>(() => $"Begin: {name}.");
|
||||
return new LightDisposableTimer(duration => _logger.Info<LogProfiler>(() => $"End {name}. ({duration}ms)"));
|
||||
_logger.Debug<LogProfiler>("Begin: {ProfileName}", name);
|
||||
return new LightDisposableTimer(duration => _logger.Info<LogProfiler>("End {ProfileName} ({ProfileDuration}ms)", name, duration));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
||||
@@ -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
|
||||
{
|
||||
///<summary>
|
||||
/// Implements <see cref="ILogger"/> on top of log4net.
|
||||
/// Implements <see cref="ILogger"/> on top of Serilog.
|
||||
///</summary>
|
||||
public class Logger : ILogger
|
||||
{
|
||||
/// <summary>
|
||||
/// Initialize a new instance of the <see cref="Logger"/> class with a log4net configuration file.
|
||||
/// Initialize a new instance of the <see cref="Logger"/> class with a configuration file.
|
||||
/// </summary>
|
||||
/// <param name="log4NetConfigFile"></param>
|
||||
public Logger(FileInfo log4NetConfigFile)
|
||||
: this()
|
||||
/// <param name="logConfigFile"></param>
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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
|
||||
/// </summary>
|
||||
/// <remarks>Used by UmbracoApplicationBase to get its logger.</remarks>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Fatal(Type reporting, Exception exception)
|
||||
{
|
||||
Fatal(reporting, exception, string.Empty);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Fatal(Type reporting, string message)
|
||||
{
|
||||
//Sometimes we need to throw an error without an ex
|
||||
Fatal(reporting, null, message);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Fatal(Type reporting, string messageTemplate, params object[] propertyValues)
|
||||
{
|
||||
//Log a structured message WITHOUT an ex
|
||||
Fatal(reporting, null, messageTemplate, propertyValues);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Error(Type reporting, Exception exception, string message)
|
||||
{
|
||||
Error(reporting, exception, message, null);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Error(Type reporting, Exception exception)
|
||||
{
|
||||
Error(reporting, exception, string.Empty);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Error(Type reporting, string message)
|
||||
{
|
||||
//Sometimes we need to throw an error without an ex
|
||||
Error(reporting, null, message);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Error(Type reporting, string messageTemplate, params object[] propertyValues)
|
||||
{
|
||||
//Log a structured message WITHOUT an ex
|
||||
Error(reporting, null, messageTemplate, propertyValues);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
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<Type, Exception, string, object[]> 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
|
||||
/// <inheritdoc/>
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Warn(Type reporting, Func<string> 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());
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Warn(Type reporting, string format, params Func<object>[] 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);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
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<object>());
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Warn(Type reporting, Exception exception, Func<string> 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);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Warn(Type reporting, Exception exception, string format, params Func<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.Select(x => x.Invoke()).ToArray());
|
||||
logger.Warn(message, exception);
|
||||
var logger = Log.Logger;
|
||||
logger?.ForContext(reporting).Warning(exception, messageTemplate, propertyValues);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
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<object>());
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Info(Type reporting, Func<string> 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());
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Info(Type reporting, string format, params Func<object>[] 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);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
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<object>());
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Debug(Type reporting, string messageTemplate, params object[] propertyValues)
|
||||
{
|
||||
var logger = Log.Logger;
|
||||
logger?.ForContext(reporting).Debug(messageTemplate, propertyValues);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Debug(Type reporting, Func<string> 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<object>());
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Debug(Type reporting, string format, params Func<object>[] args)
|
||||
{
|
||||
var logger = LogManager.GetLogger(reporting);
|
||||
if (logger == null || logger.IsDebugEnabled == false) return;
|
||||
logger.DebugFormat(format, args.Select(x => x.Invoke()).ToArray());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Logs an error message.
|
||||
/// Logs an error message
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The reporting type.</typeparam>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="message">A message.</param>
|
||||
/// <param name="exception">An exception.</param>
|
||||
public static void Error<T>(this ILogger logger, string message, Exception exception = null)
|
||||
public static void Error<T>(this ILogger logger, Exception exception, string message)
|
||||
{
|
||||
logger.Error(typeof(T), message, exception);
|
||||
logger.Error(typeof(T), exception, message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs an error message with a structured message template
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The reporting type</typeparam>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="messageTemplate">A structured message template</param>
|
||||
/// <param name="exception">An exception</param>
|
||||
/// <param name="propertyValues">Message property values</param>
|
||||
public static void Error<T>(this ILogger logger, Exception exception, string messageTemplate, params object[] propertyValues)
|
||||
{
|
||||
logger.Error(typeof(T), exception, messageTemplate, propertyValues);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs an error message NOTE: This will log an empty message string
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The reporting type</typeparam>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="exception">An exception</param>
|
||||
public static void Error<T>(this ILogger logger, Exception exception)
|
||||
{
|
||||
logger.Error(typeof(T), exception);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs an error message WITHOUT EX
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="message"></param>
|
||||
public static void Error<T>(this ILogger logger, string message)
|
||||
{
|
||||
logger.Error(typeof(T), message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs an error message - using a structured log message
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The reporting type</typeparam>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="messageTemplate">A structured message template</param>
|
||||
/// <param name="propertyValues">Message property values</param>
|
||||
public static void Error<T>(this ILogger logger, string messageTemplate, params object[] propertyValues)
|
||||
{
|
||||
logger.Error(typeof(T), messageTemplate, propertyValues);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -32,26 +78,15 @@ namespace Umbraco.Core.Logging
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs a warning message.
|
||||
/// Logs a warning message with a structured message template
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The reporting type.</typeparam>
|
||||
/// <typeparam name="T">The reporting type</typeparam>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="messageBuilder">A message builder.</param>
|
||||
public static void Warn<T>(this ILogger logger, Func<string> messageBuilder)
|
||||
/// <param name="messageTemplate">A structured message template</param>
|
||||
/// <param name="propertyValues">Message property values</param>
|
||||
public static void Warn<T>(this ILogger logger, string messageTemplate, params object[] propertyValues)
|
||||
{
|
||||
logger.Warn(typeof(T), messageBuilder);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs a formatted warning message with an exception.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The reporting type.</typeparam>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="exception">An exception.</param>
|
||||
/// <param name="messageBuilder">A message builder.</param>
|
||||
public static void Warn<T>(this ILogger logger, Exception exception, Func<string> messageBuilder)
|
||||
{
|
||||
logger.Warn(typeof(T), exception, messageBuilder);
|
||||
logger.Warn(typeof(T), messageTemplate, propertyValues);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -66,6 +101,19 @@ namespace Umbraco.Core.Logging
|
||||
logger.Warn(typeof(T), exception, message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs a warning message with an exception with a structured message template
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The reporting type</typeparam>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="exception">An exception</param>
|
||||
/// <param name="messageTemplate">A structured message template</param>
|
||||
/// <param name="propertyValues">Message property values</param>
|
||||
public static void Warn<T>(this ILogger logger, Exception exception, string messageTemplate, params object[] propertyValues)
|
||||
{
|
||||
logger.Warn(typeof(T), exception, messageTemplate, propertyValues);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs an information message.
|
||||
/// </summary>
|
||||
@@ -78,14 +126,15 @@ namespace Umbraco.Core.Logging
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs an information message.
|
||||
/// Logs a information message with a structured message template
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The reporting type.</typeparam>
|
||||
/// <typeparam name="T">The reporting type</typeparam>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="messageBuilder">A message builder.</param>
|
||||
public static void Info<T>(this ILogger logger, Func<string> messageBuilder)
|
||||
/// <param name="messageTemplate">A structured message template</param>
|
||||
/// <param name="propertyValues">Message property values</param>
|
||||
public static void Info<T>(this ILogger logger, string messageTemplate, params object[] propertyValues)
|
||||
{
|
||||
logger.Info(typeof(T), messageBuilder);
|
||||
logger.Info(typeof(T), messageTemplate, propertyValues);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -100,14 +149,66 @@ namespace Umbraco.Core.Logging
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs a debugging message.
|
||||
/// Logs a debugging message with a structured message template
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The reporting type</typeparam>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="messageTemplate">A structured message template</param>
|
||||
/// <param name="propertyValues">Message property values</param>
|
||||
public static void Debug<T>(this ILogger logger, string messageTemplate, params object[] propertyValues)
|
||||
{
|
||||
logger.Debug(typeof(T), messageTemplate, propertyValues);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs a verbose message.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The reporting type.</typeparam>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="messageBuilder">A message builder.</param>
|
||||
public static void Debug<T>(this ILogger logger, Func<string> messageBuilder)
|
||||
/// <param name="message">A message.</param>
|
||||
public static void Verbose<T>(this ILogger logger, string message)
|
||||
{
|
||||
logger.Debug(typeof(T), messageBuilder);
|
||||
logger.Verbose(typeof(T), message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs a Verbose message with a structured message template
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The reporting type</typeparam>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="messageTemplate">A structured message template</param>
|
||||
/// <param name="propertyValues">Message property values</param>
|
||||
public static void Verbose<T>(this ILogger logger, string messageTemplate, params object[] propertyValues)
|
||||
{
|
||||
logger.Verbose(typeof(T), messageTemplate, propertyValues);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Logs a fatal message.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The reporting type.</typeparam>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="exception">An exception.</param>
|
||||
/// <param name="message">A message.</param>
|
||||
public static void Fatal<T>(this ILogger logger, Exception exception, string message)
|
||||
{
|
||||
logger.Fatal(typeof(T), exception, message);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Logs a fatal message with a structured message template
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The reporting type.</typeparam>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="exception">An exception.</param>
|
||||
/// <param name="messageTemplate">A structured message template</param>
|
||||
/// <param name="propertyValues">Message property values</param>
|
||||
public static void Fatal<T>(this ILogger logger, Exception exception, string messageTemplate, params object[] propertyValues)
|
||||
{
|
||||
logger.Fatal(typeof(T), exception, messageTemplate, propertyValues);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
using log4net.Core;
|
||||
|
||||
namespace Umbraco.Core.Logging
|
||||
{
|
||||
/// <remarks>
|
||||
/// Borrowed from https://github.com/cjbhaines/Log4Net.Async - will reference Nuget packages directly in v8
|
||||
/// </remarks>
|
||||
internal sealed class LoggingEventContext
|
||||
{
|
||||
public LoggingEventContext(LoggingEvent loggingEvent, object httpContext)
|
||||
{
|
||||
LoggingEvent = loggingEvent;
|
||||
HttpContext = httpContext;
|
||||
}
|
||||
|
||||
public LoggingEvent LoggingEvent { get; set; }
|
||||
|
||||
public object HttpContext { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
using System;
|
||||
using log4net.Core;
|
||||
|
||||
namespace Umbraco.Core.Logging
|
||||
{
|
||||
/// <remarks>
|
||||
/// Borrowed from https://github.com/cjbhaines/Log4Net.Async - will reference Nuget packages directly in v8
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Borrowed from https://github.com/cjbhaines/Log4Net.Async - will reference Nuget packages directly in v8
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
internal sealed class RingBuffer<T> : IQueue<T>
|
||||
{
|
||||
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<object, EventArgs> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using log4net.Appender;
|
||||
using log4net.Util;
|
||||
|
||||
namespace Umbraco.Core.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// 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.:
|
||||
///
|
||||
/// <example>
|
||||
/// <appender name="rollingFile" type="Log4netAwesomeness.CustomRollingFileAppender, Log4netAwesomeness">
|
||||
/// <file type="log4net.Util.PatternString" value="App_Data\Logs\UmbracoTraceLog.%property{log4net:HostName}.txt" />
|
||||
/// <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
|
||||
/// <appendToFile value="true" />
|
||||
/// <rollingStyle value="Date" />
|
||||
/// <maximumFileSize value="5MB" />
|
||||
/// <maxLogFileDays value="5"/>
|
||||
/// <basefilePattern value="UmbracoTraceLog.*.txt.*"/>
|
||||
/// <layout type="log4net.Layout.PatternLayout">
|
||||
/// <conversionPattern value=" %date [P%property{processId}/D%property{appDomainId}/T%thread] %-5level %logger - %message%newline" />
|
||||
/// </layout>
|
||||
/// <layout type="log4net.Layout.PatternLayout">
|
||||
/// <conversionPattern value=" %date [P%property{processId}/D%property{appDomainId}/T%thread] %-5level %logger - %message%newline" />
|
||||
/// </layout>
|
||||
/// <encoding value="utf-8" />
|
||||
/// </appender>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
public class RollingFileCleanupAppender : RollingFileAppender
|
||||
{
|
||||
public int MaxLogFileDays { get; set; }
|
||||
public string BaseFilePattern { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This override will delete logs older than the specified amount of days
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <param name="append"></param>
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using Serilog.Core;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace Umbraco.Core.Logging.SerilogExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 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
|
||||
/// </summary>
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// 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
|
||||
/// </summary>
|
||||
/// <param name="logConfig">A Serilog LoggerConfiguration</param>
|
||||
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<Log4NetLevelMapperEnricher>();
|
||||
|
||||
return logConfig;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Outputs a .txt format log at /App_Data/Logs/
|
||||
/// </summary>
|
||||
/// <param name="logConfig">A Serilog LoggerConfiguration</param>
|
||||
/// <param name="minimumLevel">The log level you wish the JSON file to collect - default is Verbose (highest)</param>
|
||||
/// <param name="retainedFileCount">The number of days to keep log files. Default is set to null which means all logs are kept</param>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Outputs a CLEF format JSON log at /App_Data/Logs/
|
||||
/// </summary>
|
||||
/// <param name="logConfig">A Serilog LoggerConfiguration</param>
|
||||
/// <param name="minimumLevel">The log level you wish the JSON file to collect - default is Verbose (highest)</param>
|
||||
/// <param name="retainedFileCount">The number of days to keep log files. Default is set to null which means all logs are kept</param>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads settings from /config/serilog.config
|
||||
/// That allows the main logging pipeline to be configured
|
||||
/// </summary>
|
||||
/// <param name="logConfig">A Serilog LoggerConfiguration</param>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads settings from /config/serilog.user.config
|
||||
/// That allows a seperate logging pipeline to be configured that wil not affect the main Umbraco log
|
||||
/// </summary>
|
||||
/// <param name="logConfig">A Serilog LoggerConfiguration</param>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -117,7 +117,7 @@ namespace Umbraco.Core
|
||||
|
||||
lock (_locko)
|
||||
{
|
||||
_logger.Debug<MainDom>(() => "Signaled" + (_signaled ? " (again)" : "") + " (" + source + ").");
|
||||
_logger.Debug<MainDom>("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<MainDom>("Stopping.");
|
||||
_logger.Info<MainDom>("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<MainDom>("Error while running callback, remaining callbacks will not run.", e);
|
||||
_logger.Error<MainDom>(e, "Error while running callback, remaining callbacks will not run.");
|
||||
throw;
|
||||
}
|
||||
|
||||
}
|
||||
_logger.Debug<MainDom>("Stopped.");
|
||||
_logger.Debug<MainDom>("Stopped ({SignalSource})", source);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// in any case...
|
||||
_isMainDom = false;
|
||||
_asyncLocker.Dispose();
|
||||
_logger.Info<MainDom>("Released.");
|
||||
_logger.Info<MainDom>("Released ({SignalSource})", source);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace Umbraco.Core.Manifest
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Error<ManifestParser>($"Failed to parse manifest at \"{path}\", ignoring.", e);
|
||||
_logger.Error<ManifestParser>(e, "Failed to parse manifest at '{Path}', ignoring.", path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace Umbraco.Core.Manifest
|
||||
if (_isRestarting) return;
|
||||
|
||||
_isRestarting = true;
|
||||
_logger.Info<ManifestWatcher>("manifest has changed, app pool is restarting (" + e.FullPath + ")");
|
||||
_logger.Info<ManifestWatcher>("Manifest has changed, app pool is restarting ({Path})", e.FullPath);
|
||||
HttpRuntime.UnloadAppDomain();
|
||||
Dispose(); // uh? if the app restarts then this should be disposed anyways?
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,7 +309,7 @@ namespace Umbraco.Core.Migrations.Install
|
||||
{
|
||||
var source = connectionStrings.Attribute("configSource").Value;
|
||||
var configFile = IOHelper.MapPath($"{SystemDirectories.Root}/{source}");
|
||||
logger.Info<DatabaseBuilder>(() => $"Storing ConnectionString in {configFile}");
|
||||
logger.Info<DatabaseBuilder>("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<DatabaseBuilder>(() => $"Configured a new ConnectionString using the '{providerName}' provider.");
|
||||
logger.Info<DatabaseBuilder>("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 + "<p>Installation completed!</p>";
|
||||
|
||||
//now that everything is done, we need to determine the version of SQL server that is executing
|
||||
_logger.Info<DatabaseBuilder>(() => $"Database configuration status: {message}");
|
||||
_logger.Info<DatabaseBuilder>("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<DatabaseBuilder>(() => $"Database configuration status: {message}");
|
||||
_logger.Info<DatabaseBuilder>("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<DatabaseBuilder>("Database configuration failed", ex);
|
||||
_logger.Error<DatabaseBuilder>(ex, "Database configuration failed");
|
||||
|
||||
if (_databaseSchemaValidationResult != null)
|
||||
{
|
||||
_logger.Info<DatabaseBuilder>(() => $"The database schema validation produced the following summary: {Environment.NewLine}{_databaseSchemaValidationResult.GetSummary()}");
|
||||
_logger.Info<DatabaseBuilder>("The database schema validation produced the following summary: {DbSchemaSummary}", _databaseSchemaValidationResult.GetSummary());
|
||||
}
|
||||
|
||||
return new Result
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Umbraco.Core.Migrations.Install
|
||||
/// <param name="tableName">Name of the table to create base data for</param>
|
||||
public void InitializeBaseData(string tableName)
|
||||
{
|
||||
_logger.Info<DatabaseDataCreator>(() => $"Creating data in table {tableName}");
|
||||
_logger.Info<DatabaseDataCreator>("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<DatabaseDataCreator>(() => $"Done creating table {tableName} data.");
|
||||
_logger.Info<DatabaseDataCreator>("Done creating table {TableName} data.", tableName);
|
||||
}
|
||||
|
||||
private void CreateNodeData()
|
||||
|
||||
@@ -98,7 +98,7 @@ namespace Umbraco.Core.Migrations.Install
|
||||
var tableNameAttribute = table.FirstAttribute<TableNameAttribute>();
|
||||
var tableName = tableNameAttribute == null ? table.Name : tableNameAttribute.Value;
|
||||
|
||||
_logger.Info<DatabaseSchemaCreator>(() => $"Uninstall {tableName}");
|
||||
_logger.Info<DatabaseSchemaCreator>("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<DatabaseSchemaCreator>("Could not drop table " + tableName, ex);
|
||||
_logger.Error<DatabaseSchemaCreator>(ex, "Could not drop table {TableName}", tableName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -141,13 +141,7 @@ namespace Umbraco.Core.Migrations.Install
|
||||
|
||||
//get the db index defs
|
||||
result.DbIndexDefinitions = SqlSyntax.GetDefinedIndexes(_database)
|
||||
.Select(x => new DbIndexDefinition
|
||||
{
|
||||
TableName = x.Item1,
|
||||
IndexName = x.Item2,
|
||||
ColumnName = x.Item3,
|
||||
IsUnique = x.Item4
|
||||
}).ToArray();
|
||||
.Select(x => new DbIndexDefinition(x)).ToArray();
|
||||
|
||||
result.TableDefinitions.AddRange(OrderedTables
|
||||
.Select(x => DefinitionFactory.GetTableDefinition(x, SqlSyntax)));
|
||||
@@ -160,6 +154,14 @@ namespace Umbraco.Core.Migrations.Install
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This validates the Primary/Foreign keys in the database
|
||||
/// </summary>
|
||||
/// <param name="result"></param>
|
||||
/// <remarks>
|
||||
/// This does not validate any database constraints that are not PKs or FKs because Umbraco does not create a database with non PK/FK contraints.
|
||||
/// Any unique "constraints" in the database are done with unique indexes.
|
||||
/// </remarks>
|
||||
private void ValidateDbConstraints(DatabaseSchemaResult result)
|
||||
{
|
||||
//MySql doesn't conform to the "normal" naming of constraints, so there is currently no point in doing these checks.
|
||||
@@ -172,8 +174,7 @@ namespace Umbraco.Core.Migrations.Install
|
||||
var constraintsInDatabase = SqlSyntax.GetConstraintsPerColumn(_database).DistinctBy(x => x.Item3).ToList();
|
||||
var foreignKeysInDatabase = constraintsInDatabase.Where(x => x.Item3.InvariantStartsWith("FK_")).Select(x => x.Item3).ToList();
|
||||
var primaryKeysInDatabase = constraintsInDatabase.Where(x => x.Item3.InvariantStartsWith("PK_")).Select(x => x.Item3).ToList();
|
||||
var indexesInDatabase = constraintsInDatabase.Where(x => x.Item3.InvariantStartsWith("IX_")).Select(x => x.Item3).ToList();
|
||||
var indexesInSchema = result.TableDefinitions.SelectMany(x => x.Indexes.Select(y => y.Name)).ToList();
|
||||
|
||||
var unknownConstraintsInDatabase =
|
||||
constraintsInDatabase.Where(
|
||||
x =>
|
||||
@@ -188,7 +189,7 @@ namespace Umbraco.Core.Migrations.Install
|
||||
// In theory you could have: FK_ or fk_ ...or really any standard that your development department (or developer) chooses to use.
|
||||
foreach (var unknown in unknownConstraintsInDatabase)
|
||||
{
|
||||
if (foreignKeysInSchema.InvariantContains(unknown) || primaryKeysInSchema.InvariantContains(unknown) || indexesInSchema.InvariantContains(unknown))
|
||||
if (foreignKeysInSchema.InvariantContains(unknown) || primaryKeysInSchema.InvariantContains(unknown))
|
||||
{
|
||||
result.ValidConstraints.Add(unknown);
|
||||
}
|
||||
@@ -230,23 +231,6 @@ namespace Umbraco.Core.Migrations.Install
|
||||
result.Errors.Add(new Tuple<string, string>("Constraint", primaryKey));
|
||||
}
|
||||
|
||||
//Constaints:
|
||||
|
||||
//NOTE: SD: The colIndex checks above should really take care of this but I need to keep this here because it was here before
|
||||
// and some schema validation checks might rely on this data remaining here!
|
||||
//Add valid and invalid index differences to the result object
|
||||
var validIndexDifferences = indexesInDatabase.Intersect(indexesInSchema, StringComparer.InvariantCultureIgnoreCase);
|
||||
foreach (var index in validIndexDifferences)
|
||||
{
|
||||
result.ValidConstraints.Add(index);
|
||||
}
|
||||
var invalidIndexDifferences =
|
||||
indexesInDatabase.Except(indexesInSchema, StringComparer.InvariantCultureIgnoreCase)
|
||||
.Union(indexesInSchema.Except(indexesInDatabase, StringComparer.InvariantCultureIgnoreCase));
|
||||
foreach (var index in invalidIndexDifferences)
|
||||
{
|
||||
result.Errors.Add(new Tuple<string, string>("Constraint", index));
|
||||
}
|
||||
}
|
||||
|
||||
private void ValidateDbColumns(DatabaseSchemaResult result)
|
||||
@@ -392,13 +376,13 @@ namespace Umbraco.Core.Migrations.Install
|
||||
{
|
||||
//Execute the Create Table sql
|
||||
var created = _database.Execute(new Sql(createSql));
|
||||
_logger.Info<DatabaseSchemaCreator>(() => $"Create Table '{tableName}' ({created}):\n {createSql}");
|
||||
_logger.Info<DatabaseSchemaCreator>("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<DatabaseSchemaCreator>(() => $"Create Primary Key ({createdPk}):\n {createPrimaryKeySql}");
|
||||
_logger.Info<DatabaseSchemaCreator>("Create Primary Key ({CreatedPk}):\n {Sql}", createdPk, createPrimaryKeySql);
|
||||
}
|
||||
|
||||
//Turn on identity insert if db provider is not mysql
|
||||
@@ -424,21 +408,21 @@ namespace Umbraco.Core.Migrations.Install
|
||||
foreach (var sql in indexSql)
|
||||
{
|
||||
var createdIndex = _database.Execute(new Sql(sql));
|
||||
_logger.Info<DatabaseSchemaCreator>(() => $"Create Index ({createdIndex}):\n {sql}");
|
||||
_logger.Info<DatabaseSchemaCreator>("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<DatabaseSchemaCreator>(() => $"Create Foreign Key ({createdFk}):\n {sql}");
|
||||
_logger.Info<DatabaseSchemaCreator>("Create Foreign Key ({CreatedFk}):\n {Sql}", createdFk, sql);
|
||||
}
|
||||
|
||||
transaction.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
_logger.Info<DatabaseSchemaCreator>(() => $"Created table '{tableName}'");
|
||||
_logger.Info<DatabaseSchemaCreator>("Created table '{TableName}'", tableName);
|
||||
}
|
||||
|
||||
public void DropTable(string tableName)
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace Umbraco.Core.Migrations
|
||||
|
||||
if (string.IsNullOrWhiteSpace(sql))
|
||||
{
|
||||
Logger.Info(GetType(), $"SQL [{Context.Index}]: <empty>");
|
||||
Logger.Info(GetType(), "SQL [{ContextIndex}: <empty>", 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();
|
||||
}
|
||||
|
||||
@@ -269,14 +269,11 @@ namespace Umbraco.Core.Migrations
|
||||
if (_migrationBuilder == null || _logger == null)
|
||||
throw new InvalidOperationException("Cannot execute a non-executing plan.");
|
||||
|
||||
_logger.Info<MigrationPlan>(() => $"Starting \"{Name}\"...");
|
||||
_logger.Info<MigrationPlan>("Starting '{MigrationName}'...", Name);
|
||||
|
||||
var origState = fromState ?? string.Empty;
|
||||
|
||||
_logger.Info<MigrationPlan>(() =>
|
||||
{
|
||||
var info = "At " + (string.IsNullOrWhiteSpace(origState) ? "origin" : ("\"" + origState + "\"")) + ".";
|
||||
return info.Replace("{", "{{").Replace("}", "}}"); // stupid log4net
|
||||
});
|
||||
_logger.Info<MigrationPlan>("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<MigrationPlan>(() => $"At \"{origState}\".");
|
||||
_logger.Info<MigrationPlan>("At {OrigState}", origState);
|
||||
|
||||
if (!_transitions.TryGetValue(origState, out transition))
|
||||
throw new Exception($"Unknown state \"{origState}\".");
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_12_0
|
||||
{
|
||||
@@ -12,20 +11,22 @@ namespace Umbraco.Core.Migrations.Upgrade.V_7_12_0
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var exists = Context.Database.FirstOrDefault<RelationTypeDto>("WHERE alias=@alias", new { alias = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias });
|
||||
if (exists == null)
|
||||
var relationTypeCount = Context.Database.ExecuteScalar<int>("SELECT COUNT(*) FROM umbracoRelationType WHERE alias=@alias",
|
||||
new { alias = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias });
|
||||
|
||||
if (relationTypeCount > 0)
|
||||
return;
|
||||
|
||||
var uniqueId = (Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias + "____" + Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteName).ToGuid();
|
||||
Insert.IntoTable("umbracoRelationType").Row(new
|
||||
{
|
||||
var uniqueId = (Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias + "____" + Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteName).ToGuid();
|
||||
Insert.IntoTable("umbracoRelationType").Row(new
|
||||
{
|
||||
typeUniqueId = uniqueId,
|
||||
alias = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias,
|
||||
name = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteName,
|
||||
childObjectType = Constants.ObjectTypes.MediaType,
|
||||
parentObjectType = Constants.ObjectTypes.MediaType,
|
||||
dual = false
|
||||
typeUniqueId = uniqueId,
|
||||
alias = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias,
|
||||
name = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteName,
|
||||
childObjectType = Constants.ObjectTypes.MediaType,
|
||||
parentObjectType = Constants.ObjectTypes.MediaType,
|
||||
dual = false
|
||||
}).Do();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_12_0
|
||||
{
|
||||
@@ -11,16 +12,16 @@ namespace Umbraco.Core.Migrations.Upgrade.V_7_12_0
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexes(Context.Database)
|
||||
.Select(x => new DbIndexDefinition
|
||||
{
|
||||
TableName = x.Item1,
|
||||
IndexName = x.Item2,
|
||||
ColumnName = x.Item3,
|
||||
IsUnique = x.Item4
|
||||
}).ToArray();
|
||||
// Some people seem to have a constraint in their DB instead of an index, we'd need to drop that one
|
||||
// See: https://our.umbraco.com/forum/using-umbraco-and-getting-started/93282-upgrade-from-711-to-712-fails
|
||||
var constraints = SqlSyntax.GetConstraintsPerTable(Context.Database).Distinct().ToArray();
|
||||
if (constraints.Any(x => x.Item2.InvariantEquals("IX_umbracoLanguage_languageISOCode")))
|
||||
{
|
||||
Delete.UniqueConstraint("IX_umbracoLanguage_languageISOCode").FromTable("umbracoLanguage").Do();
|
||||
}
|
||||
|
||||
//Ensure the index exists before dropping it
|
||||
//Now check for indexes of that name and drop that if it exists
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(Context.Database);
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoLanguage_languageISOCode")))
|
||||
{
|
||||
Delete.Index("IX_umbracoLanguage_languageISOCode").OnTable("umbracoLanguage").Do();
|
||||
@@ -35,8 +36,11 @@ namespace Umbraco.Core.Migrations.Upgrade.V_7_12_0
|
||||
Create.Index("IX_umbracoLanguage_languageISOCode")
|
||||
.OnTable("umbracoLanguage")
|
||||
.OnColumn("languageISOCode")
|
||||
.Ascending()
|
||||
.WithOptions()
|
||||
.Unique()
|
||||
.Do();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
var keyName = c.Item3.ToLowerInvariant();
|
||||
if (dups.Contains(keyName))
|
||||
{
|
||||
Logger.Warn<RefactorXmlColumns>(() => $"Duplicate constraint {c.Item3}");
|
||||
Logger.Warn<RefactorXmlColumns>("Duplicate constraint '{Constraint}'", c.Item3);
|
||||
continue;
|
||||
}
|
||||
dups.Add(keyName);
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace Umbraco.Core.Models
|
||||
/// <param name="name">Name of the content</param>
|
||||
/// <param name="parent">Parent <see cref="IContent"/> object</param>
|
||||
/// <param name="contentType">ContentType for the current Content object</param>
|
||||
/// <param name="culture">An optional culture.</param>
|
||||
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
|
||||
/// <param name="parent">Parent <see cref="IContent"/> object</param>
|
||||
/// <param name="contentType">ContentType for the current Content object</param>
|
||||
/// <param name="properties">Collection of properties</param>
|
||||
/// <param name="culture">An optional culture.</param>
|
||||
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
|
||||
/// <param name="name">Name of the content</param>
|
||||
/// <param name="parentId">Id of the Parent content</param>
|
||||
/// <param name="contentType">ContentType for the current Content object</param>
|
||||
/// <param name="culture">An optional culture.</param>
|
||||
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
|
||||
/// <param name="parentId">Id of the Parent content</param>
|
||||
/// <param name="contentType">ContentType for the current Content object</param>
|
||||
/// <param name="properties">Collection of properties</param>
|
||||
/// <param name="culture">An optional culture.</param>
|
||||
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<string> PublishedCultures => _publishInfos?.Keys ?? Enumerable.Empty<string>();
|
||||
|
||||
//fixme should this return false if ID == 0?
|
||||
//fixme should this return false if IsCultureAvailable(culture) is false?
|
||||
/// <inheritdoc />
|
||||
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?
|
||||
/// <inheritdoc />
|
||||
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?
|
||||
/// <inheritdoc />
|
||||
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
|
||||
|
||||
/// <inheritdoc/>
|
||||
[IgnoreDataMember]
|
||||
|
||||
@@ -87,6 +87,8 @@ namespace Umbraco.Core.Models
|
||||
/// <para>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.</para>
|
||||
/// <para>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).</para>
|
||||
/// </remarks>
|
||||
bool IsCulturePublished(string culture);
|
||||
|
||||
@@ -107,8 +109,9 @@ namespace Umbraco.Core.Models
|
||||
/// Gets a value indicated whether a given culture is edited.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>A culture is edited when it is not published, or when it is published but
|
||||
/// it has changes.</para>
|
||||
/// <para>A culture is edited when it is available, and not published or published but
|
||||
/// with changes.</para>
|
||||
/// <para>A culture can be edited even though the document might now have been saved yet (and can have no identity).</para>
|
||||
/// </remarks>
|
||||
bool IsCultureEdited(string culture);
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error<ImageCropperValueConverter>("Could not parse the string " + jsonString + " to a json object", ex);
|
||||
logger.Error<ImageCropperValueConverter>(ex, "Could not parse the string '{JsonString}' to a json object", jsonString);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -552,9 +552,14 @@ namespace Umbraco.Core.Models
|
||||
private Attempt<T> WarnIfPropertyTypeNotFoundOnGet<T>(string propertyAlias, string propertyName, T defaultVal)
|
||||
{
|
||||
void DoLog(string logPropertyAlias, string logPropertyName)
|
||||
=> Current.Logger.Warn<Member>($"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<Member>("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<Member>($"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<Member>("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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -192,7 +192,7 @@ namespace Umbraco.Core.Packaging
|
||||
assemblyName.Name,
|
||||
"' see error log for full details."));
|
||||
assembliesWithErrors.Add(a);
|
||||
Current.Logger.Error<PackageBinaryInspector>("An error occurred scanning package assemblies", ex);
|
||||
Current.Logger.Error<PackageBinaryInspector>(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<PackageBinaryInspector>("An error occurred scanning package assemblies", ex);
|
||||
Current.Logger.Error<PackageBinaryInspector>(ex, "An error occurred scanning package assembly '{AssemblyName}'", a.GetName().FullName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,13 +6,13 @@ namespace Umbraco.Core.Persistence.DatabaseModelDefinitions
|
||||
{
|
||||
public ConstraintDefinition(ConstraintType type)
|
||||
{
|
||||
constraintType = type;
|
||||
_constraintType = type;
|
||||
}
|
||||
|
||||
private ConstraintType constraintType;
|
||||
public bool IsPrimaryKeyConstraint { get { return ConstraintType.PrimaryKey == constraintType; } }
|
||||
public bool IsUniqueConstraint { get { return ConstraintType.Unique == constraintType; } }
|
||||
public bool IsNonUniqueConstraint { get { return ConstraintType.NonUnique == constraintType; } }
|
||||
private readonly ConstraintType _constraintType;
|
||||
public bool IsPrimaryKeyConstraint => ConstraintType.PrimaryKey == _constraintType;
|
||||
public bool IsUniqueConstraint => ConstraintType.Unique == _constraintType;
|
||||
public bool IsNonUniqueConstraint => ConstraintType.NonUnique == _constraintType;
|
||||
|
||||
public string SchemaName { get; set; }
|
||||
public string ConstraintName { get; set; }
|
||||
|
||||
@@ -1,13 +1,23 @@
|
||||
namespace Umbraco.Core.Persistence.DatabaseModelDefinitions
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Persistence.DatabaseModelDefinitions
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a database index definition retreived by querying the database
|
||||
/// </summary>
|
||||
internal class DbIndexDefinition
|
||||
{
|
||||
public virtual string IndexName { get; set; }
|
||||
public virtual string TableName { get; set; }
|
||||
public virtual string ColumnName { get; set; }
|
||||
public virtual bool IsUnique { get; set; }
|
||||
public DbIndexDefinition(Tuple<string, string, string, bool> data)
|
||||
{
|
||||
TableName = data.Item1;
|
||||
IndexName = data.Item2;
|
||||
ColumnName = data.Item3;
|
||||
IsUnique = data.Item4;
|
||||
}
|
||||
|
||||
public string IndexName { get; }
|
||||
public string TableName { get; }
|
||||
public string ColumnName { get; }
|
||||
public bool IsUnique { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<ContentRepositoryBase<TId, TEntity, TRepository>>(msg);
|
||||
throw new InvalidOperationException($"The query returned multiple property sets for content {temp.Id}, {temp.ContentType.Name}");
|
||||
Logger.Warn<ContentRepositoryBase<TId, TEntity, TRepository>>("The query returned multiple property sets for content {ContentId}, {ContentTypeName}", temp.Id, temp.ContentType.Name);
|
||||
}
|
||||
|
||||
result[temp.VersionId] = new PropertyCollection(properties);
|
||||
|
||||
@@ -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<ContentTypeRepository>(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<ContentTypeRepository>("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();
|
||||
|
||||
@@ -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<ContentTypeRepositoryBase<TEntity>>(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<ContentTypeRepositoryBase<TEntity>>("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<ContentTypeRepositoryBase<TEntity>>(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<ContentTypeRepositoryBase<TEntity>>("{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<ContentTypeRepositoryBase<TEntity>>(() => $"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<ContentTypeRepositoryBase<TEntity>>("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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,8 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
string TruncateTable { get; }
|
||||
string CreateConstraint { get; }
|
||||
string DeleteConstraint { get; }
|
||||
|
||||
[Obsolete("This is never used, use the Format(ForeignKeyDefinition) instead")]
|
||||
string CreateForeignKeyConstraint { get; }
|
||||
string DeleteDefaultConstraint { get; }
|
||||
string FormatDateTime(DateTime date, bool includeTime = true);
|
||||
@@ -80,8 +82,32 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
|
||||
IEnumerable<string> GetTablesInSchema(IDatabase db);
|
||||
IEnumerable<ColumnInfo> GetColumnsInSchema(IDatabase db);
|
||||
|
||||
/// <summary>
|
||||
/// Returns all constraints defined in the database (Primary keys, foreign keys, unique constraints...) (does not include indexes)
|
||||
/// </summary>
|
||||
/// <param name="db"></param>
|
||||
/// <returns>
|
||||
/// A Tuple containing: TableName, ConstraintName
|
||||
/// </returns>
|
||||
IEnumerable<Tuple<string, string>> GetConstraintsPerTable(IDatabase db);
|
||||
|
||||
/// <summary>
|
||||
/// Returns all constraints defined in the database (Primary keys, foreign keys, unique constraints...) (does not include indexes)
|
||||
/// </summary>
|
||||
/// <param name="db"></param>
|
||||
/// <returns>
|
||||
/// A Tuple containing: TableName, ColumnName, ConstraintName
|
||||
/// </returns>
|
||||
IEnumerable<Tuple<string, string, string>> GetConstraintsPerColumn(IDatabase db);
|
||||
|
||||
/// <summary>
|
||||
/// Returns all defined Indexes in the database excluding primary keys
|
||||
/// </summary>
|
||||
/// <param name="db"></param>
|
||||
/// <returns>
|
||||
/// A Tuple containing: TableName, IndexName, ColumnName, IsUnique
|
||||
/// </returns>
|
||||
IEnumerable<Tuple<string, string, string, bool>> GetDefinedIndexes(IDatabase db);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,6 +79,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<Tuple<string, string>> GetConstraintsPerTable(IDatabase db)
|
||||
{
|
||||
List<Tuple<string, string>> list;
|
||||
@@ -101,6 +102,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<Tuple<string, string, string>> GetConstraintsPerColumn(IDatabase db)
|
||||
{
|
||||
List<Tuple<string, string, string>> list;
|
||||
@@ -127,6 +129,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<Tuple<string, string, string, bool>> GetDefinedIndexes(IDatabase db)
|
||||
{
|
||||
List<Tuple<string, string, string, bool>> list;
|
||||
@@ -385,7 +388,7 @@ ORDER BY TABLE_NAME, INDEX_NAME",
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error<MySqlSyntaxProvider>("Error querying for lower_case support", ex);
|
||||
_logger.Error<MySqlSyntaxProvider>(ex, "Error querying for lower_case support");
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -107,40 +107,27 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
item.IS_NULLABLE, item.DATA_TYPE)).ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<Tuple<string, string>> GetConstraintsPerTable(IDatabase db)
|
||||
{
|
||||
var items = db.Fetch<dynamic>("SELECT TABLE_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS");
|
||||
var indexItems = db.Fetch<dynamic>("SELECT TABLE_NAME, INDEX_NAME FROM INFORMATION_SCHEMA.INDEXES");
|
||||
return
|
||||
items.Select(item => new Tuple<string, string>(item.TABLE_NAME, item.CONSTRAINT_NAME))
|
||||
.Union(
|
||||
indexItems.Select(
|
||||
indexItem => new Tuple<string, string>(indexItem.TABLE_NAME, indexItem.INDEX_NAME)))
|
||||
.ToList();
|
||||
return items.Select(item => new Tuple<string, string>(item.TABLE_NAME, item.CONSTRAINT_NAME)).ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<Tuple<string, string, string>> GetConstraintsPerColumn(IDatabase db)
|
||||
{
|
||||
var items =
|
||||
db.Fetch<dynamic>(
|
||||
"SELECT CONSTRAINT_NAME, TABLE_NAME, COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE");
|
||||
var indexItems = db.Fetch<dynamic>("SELECT INDEX_NAME, TABLE_NAME, COLUMN_NAME FROM INFORMATION_SCHEMA.INDEXES");
|
||||
return
|
||||
items.Select(
|
||||
item => new Tuple<string, string, string>(item.TABLE_NAME, item.COLUMN_NAME, item.CONSTRAINT_NAME))
|
||||
.Union(
|
||||
indexItems.Select(
|
||||
indexItem =>
|
||||
new Tuple<string, string, string>(indexItem.TABLE_NAME, indexItem.COLUMN_NAME,
|
||||
indexItem.INDEX_NAME))).ToList();
|
||||
var items = db.Fetch<dynamic>("SELECT TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE");
|
||||
return items.Select(item => new Tuple<string, string, string>(item.TABLE_NAME, item.COLUMN_NAME, item.CONSTRAINT_NAME)).ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<Tuple<string, string, string, bool>> GetDefinedIndexes(IDatabase db)
|
||||
{
|
||||
var items =
|
||||
db.Fetch<dynamic>(
|
||||
@"SELECT TABLE_NAME, INDEX_NAME, COLUMN_NAME, [UNIQUE] FROM INFORMATION_SCHEMA.INDEXES
|
||||
WHERE INDEX_NAME NOT LIKE 'PK_%'
|
||||
WHERE PRIMARY_KEY=0
|
||||
ORDER BY TABLE_NAME, INDEX_NAME");
|
||||
return
|
||||
items.Select(
|
||||
|
||||
@@ -163,6 +163,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
item.IS_NULLABLE, item.DATA_TYPE)).ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<Tuple<string, string>> GetConstraintsPerTable(IDatabase db)
|
||||
{
|
||||
var items =
|
||||
@@ -171,6 +172,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
return items.Select(item => new Tuple<string, string>(item.TABLE_NAME, item.CONSTRAINT_NAME)).ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<Tuple<string, string, string>> GetConstraintsPerColumn(IDatabase db)
|
||||
{
|
||||
var items =
|
||||
@@ -179,6 +181,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
return items.Select(item => new Tuple<string, string, string>(item.TABLE_NAME, item.COLUMN_NAME, item.CONSTRAINT_NAME)).ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<Tuple<string, string, string, bool>> GetDefinedIndexes(IDatabase db)
|
||||
{
|
||||
var items =
|
||||
@@ -188,7 +191,7 @@ CASE WHEN I.is_unique_constraint = 1 OR I.is_unique = 1 THEN 1 ELSE 0 END AS [U
|
||||
from sys.tables as T inner join sys.indexes as I on T.[object_id] = I.[object_id]
|
||||
inner join sys.index_columns as IC on IC.[object_id] = I.[object_id] and IC.[index_id] = I.[index_id]
|
||||
inner join sys.all_columns as AC on IC.[object_id] = AC.[object_id] and IC.[column_id] = AC.[column_id]
|
||||
WHERE I.name NOT LIKE 'PK_%'
|
||||
WHERE I.is_primary_key = 0
|
||||
order by T.name, I.name");
|
||||
return items.Select(item => new Tuple<string, string, string, bool>(item.TABLE_NAME, item.INDEX_NAME, item.COLUMN_NAME,
|
||||
item.UNIQUE == 1)).ToList();
|
||||
|
||||
@@ -10,13 +10,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
public static IEnumerable<DbIndexDefinition> GetDefinedIndexesDefinitions(this ISqlSyntaxProvider sql, IDatabase db)
|
||||
{
|
||||
return sql.GetDefinedIndexes(db)
|
||||
.Select(x => new DbIndexDefinition
|
||||
{
|
||||
TableName = x.Item1,
|
||||
IndexName = x.Item2,
|
||||
ColumnName = x.Item3,
|
||||
IsUnique = x.Item4
|
||||
}).ToArray();
|
||||
.Select(x => new DbIndexDefinition(x)).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -190,13 +190,13 @@ namespace Umbraco.Core.Persistence
|
||||
}
|
||||
#endif
|
||||
|
||||
protected override void OnException(Exception x)
|
||||
protected override void OnException(Exception ex)
|
||||
{
|
||||
_logger.Error<UmbracoDatabase>("Exception (" + InstanceId + ").", x);
|
||||
_logger.Debug<UmbracoDatabase>(() => "At:\r\n" + Environment.StackTrace);
|
||||
_logger.Error<UmbracoDatabase>(ex, "Exception ({InstanceId}).", InstanceId);
|
||||
_logger.Debug<UmbracoDatabase>("At:\r\n{StackTrace}", Environment.StackTrace);
|
||||
if (EnableSqlTrace == false)
|
||||
_logger.Debug<UmbracoDatabase>(() => "Sql:\r\n" + CommandToString(LastSQL, LastArgs));
|
||||
base.OnException(x);
|
||||
_logger.Debug<UmbracoDatabase>("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<UmbracoDatabase>(() => CommandToString(cmd).Replace("{", "{{").Replace("}", "}}")); // fixme these escapes should be builtin
|
||||
_logger.Debug<UmbracoDatabase>("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...)
|
||||
|
||||
@@ -261,7 +261,7 @@ namespace Umbraco.Core.PropertyEditors
|
||||
var result = TryConvertValueToCrlType(editorValue.Value);
|
||||
if (result.Success == false)
|
||||
{
|
||||
Current.Logger.Warn<DataValueEditor>(() => $"The value {editorValue.Value} cannot be converted to the type {ValueTypes.ToStorageType(ValueType)}");
|
||||
Current.Logger.Warn<DataValueEditor>("The value {EditorValue} cannot be converted to the type {StorageTypeValue}", editorValue.Value, ValueTypes.ToStorageType(ValueType));
|
||||
return null;
|
||||
}
|
||||
return result.Result;
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
namespace Umbraco.Core.PropertyEditors
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the configuration for the slider value editor.
|
||||
@@ -8,7 +6,7 @@ namespace Umbraco.Web.PropertyEditors
|
||||
public class SliderConfiguration
|
||||
{
|
||||
[ConfigurationField("enableRange", "Enable range", "boolean")]
|
||||
public string Range { get; set; }
|
||||
public bool EnableRange { get; set; }
|
||||
|
||||
[ConfigurationField("orientation", "Orientation", "views/propertyeditors/slider/orientation.prevalues.html")]
|
||||
public string Orientation { get; set; }
|
||||
@@ -38,7 +36,7 @@ namespace Umbraco.Web.PropertyEditors
|
||||
public string Tooltip { get; set; }
|
||||
|
||||
[ConfigurationField("tooltipSplit", "Tooltip split", "boolean", Description = "If false show one tootip if true show two tooltips one for each handler")]
|
||||
public string TooltipSplit { get; set; } // fixme bool?
|
||||
public bool TooltipSplit { get; set; } // fixme bool?
|
||||
|
||||
[ConfigurationField("tooltipFormat", "Tooltip format", "textstring", Description = "The value wanted to be displayed in the tooltip. Use {0} and {1} for current values - {1} is only for range slider and if not using tooltip split.")]
|
||||
public string TooltipFormat { get; set; }
|
||||
@@ -47,7 +45,7 @@ namespace Umbraco.Web.PropertyEditors
|
||||
public string TooltipPosition { get; set; }
|
||||
|
||||
[ConfigurationField("reversed", "Reversed", "boolean", Description = "Whether or not the slider should be reversed")]
|
||||
public string Reversed { get; set; } // fixme bool?
|
||||
public bool Reversed { get; set; } // fixme bool?
|
||||
|
||||
[ConfigurationField("ticks", "Ticks", "textstring", Description = "Comma-separated values. Used to define the values of ticks. Tick marks are indicators to denote special values in the range. This option overwrites min and max options.")]
|
||||
public string Ticks { get; set; }
|
||||
@@ -61,4 +59,4 @@ namespace Umbraco.Web.PropertyEditors
|
||||
[ConfigurationField("ticksSnapBounds", "Ticks snap bounds", "number", Description = "Used to define the snap bounds of a tick. Snaps to the tick if value is within these bounds.")]
|
||||
public int TicksSnapBounds { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Umbraco.Core.PropertyEditors
|
||||
{
|
||||
public class SliderPropertyEditorConfiguration
|
||||
{
|
||||
[JsonProperty("enableRange")]
|
||||
public bool EnableRange { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -100,7 +100,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Current.Logger.Error<GridValueConverter>("Could not parse the string " + sourceString + " to a json object", ex);
|
||||
Current.Logger.Error<GridValueConverter>(ex, "Could not parse the string '{JsonString}' to a json object", sourceString);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<ImageCropperValueConverter>($"Could not deserialize string \"{sourceString}\" into an image cropper value.", ex);
|
||||
Current.Logger.Error<ImageCropperValueConverter>(ex, "Could not deserialize string '{JsonString}' into an image cropper value.", sourceString);
|
||||
value = new ImageCropperValue { Src = sourceString };
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Current.Logger.Error<JsonValueConverter>("Could not parse the string " + sourceString + " to a json object", ex);
|
||||
Current.Logger.Error<JsonValueConverter>(ex, "Could not parse the string '{JsonString}' to a json object", sourceString);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
|
||||
return Storages.GetOrAdd(dataTypeId, id =>
|
||||
{
|
||||
var dataType = _dataTypeService.GetDataType(id);
|
||||
var configuration = dataType.ConfigurationAs<SliderPropertyEditorConfiguration>();
|
||||
var configuration = dataType.ConfigurationAs<SliderConfiguration>();
|
||||
return configuration.EnableRange;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace Umbraco.Core.Publishing
|
||||
var counter = 0;
|
||||
var contentForRelease = _contentService.GetContentForRelease().ToArray();
|
||||
if (contentForRelease.Length > 0)
|
||||
_logger.Debug<ScheduledPublisher>(() => $"There's {contentForRelease.Length} item(s) of content to be published");
|
||||
_logger.Debug<ScheduledPublisher>("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<ContentService>(() => $"Result of publish attempt: {result.Result}");
|
||||
_logger.Debug<ContentService>("Result of publish attempt: {PublishResult}", result.Result);
|
||||
if (result.Success == false)
|
||||
{
|
||||
_logger.Error<ScheduledPublisher>($"Error publishing node {d.Id}");
|
||||
_logger.Error<ScheduledPublisher>(null, "Error publishing node {NodeId}", d.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
catch (Exception ee)
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error<ScheduledPublisher>($"Error publishing node {d.Id}", ee);
|
||||
_logger.Error<ScheduledPublisher>(ex, "Error publishing node {NodeId}", d.Id);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
var contentForExpiration = _contentService.GetContentForExpiration().ToArray();
|
||||
if (contentForExpiration.Length > 0)
|
||||
_logger.Debug<ScheduledPublisher>(() => $"There's {contentForExpiration.Length} item(s) of content to be unpublished");
|
||||
_logger.Debug<ScheduledPublisher>("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<ScheduledPublisher>($"Error unpublishing node {d.Id}", ee);
|
||||
_logger.Error<ScheduledPublisher>(ex, "Error unpublishing node {NodeId}", d.Id);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace Umbraco.Core.Runtime
|
||||
|
||||
try
|
||||
{
|
||||
Logger.Debug<CoreRuntime>(() => $"Runtime: {GetType().FullName}");
|
||||
Logger.Debug<CoreRuntime>("Runtime: {Runtime}", GetType().FullName);
|
||||
|
||||
AquireMainDom(container);
|
||||
DetermineRuntimeLevel(container);
|
||||
@@ -141,11 +141,11 @@ namespace Umbraco.Core.Runtime
|
||||
var dbfactory = container.GetInstance<IUmbracoDatabaseFactory>();
|
||||
SetRuntimeStateLevel(dbfactory, Logger);
|
||||
|
||||
Logger.Debug<CoreRuntime>(() => $"Runtime level: {_state.Level}");
|
||||
Logger.Debug<CoreRuntime>("Runtime level: {RuntimeLevel}", _state.Level);
|
||||
|
||||
if (_state.Level == RuntimeLevel.Upgrade)
|
||||
{
|
||||
Logger.Debug<CoreRuntime>(() => $"Configure database factory for upgrades.");
|
||||
Logger.Debug<CoreRuntime>("Configure database factory for upgrades.");
|
||||
dbfactory.ConfigureForUpgrade();
|
||||
}
|
||||
}
|
||||
@@ -262,12 +262,12 @@ namespace Umbraco.Core.Runtime
|
||||
{
|
||||
// there *is* a local version, but it does not match the code version
|
||||
// need to upgrade
|
||||
logger.Debug<CoreRuntime>(() => $"Local version \"{localVersion}\" < code version \"{codeVersion}\", need to upgrade Umbraco.");
|
||||
logger.Debug<CoreRuntime>("Local version '{LocalVersion}' < code version '{CodeVersion}', need to upgrade Umbraco.", localVersion, codeVersion);
|
||||
_state.Level = RuntimeLevel.Upgrade;
|
||||
}
|
||||
else if (localVersion > codeVersion)
|
||||
{
|
||||
logger.Warn<CoreRuntime>(() => $"Local version \"{localVersion}\" > code version \"{codeVersion}\", downgrading is not supported.");
|
||||
logger.Warn<CoreRuntime>("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
|
||||
@@ -292,16 +292,14 @@ namespace Umbraco.Core.Runtime
|
||||
{
|
||||
connect = databaseFactory.CanConnect;
|
||||
if (connect) break;
|
||||
logger.Debug<CoreRuntime>(() => i == 0
|
||||
? "Could not immediately connect to database, trying again."
|
||||
: "Could not connect to database.");
|
||||
logger.Debug<CoreRuntime>("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<CoreRuntime>(() => "Could not connect to database.");
|
||||
logger.Debug<CoreRuntime>("Could not connect to database.");
|
||||
_state.Level = RuntimeLevel.BootFailed;
|
||||
|
||||
// in fact, this is bad enough that we want to throw
|
||||
@@ -365,7 +363,7 @@ namespace Umbraco.Core.Runtime
|
||||
_state.CurrentMigrationState = state;
|
||||
_state.FinalMigrationState = umbracoPlan.FinalState;
|
||||
|
||||
logger.Debug<CoreRuntime>(() => $"Final upgrade state is \"{_state.FinalMigrationState}\", database contains \"{state ?? "<null>"}\".");
|
||||
logger.Debug<CoreRuntime>("Final upgrade state is '{FinalMigrationState}', database contains {DatabaseState}", _state.FinalMigrationState, state ?? "<null>");
|
||||
|
||||
return state == _state.FinalMigrationState;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -318,7 +318,8 @@ namespace Umbraco.Core.Scoping
|
||||
if (completed.HasValue == false || completed.Value == false)
|
||||
{
|
||||
if (LogUncompletedScopes)
|
||||
_logger.Debug<Scope>(() => "Uncompleted Child Scope at\r\n" + Environment.StackTrace);
|
||||
_logger.Debug<Scope>("Uncompleted Child Scope at\r\n {StackTrace}", Environment.StackTrace);
|
||||
|
||||
_completed = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ namespace Umbraco.Core.Scoping
|
||||
}
|
||||
|
||||
// hard to inject into a static method :(
|
||||
Current.Logger.Warn<ScopeProvider>(() => $"Missed {typeof(T).Name} Object {objectKey.ToString("N").Substring(0, 8)}");
|
||||
Current.Logger.Warn<ScopeProvider>("Missed {TypeName} Object {ObjectKey}", typeof(T).Name, objectKey.ToString("N").Substring(0, 8));
|
||||
#if DEBUG_SCOPES
|
||||
//Current.Logger.Debug<ScopeProvider>("At:\r\n" + Head(Environment.StackTrace, 24));
|
||||
#endif
|
||||
|
||||
@@ -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<MembershipProviderBase>("Cannot specify a Hashed password format with the enabledPasswordRetrieval option set to true", ex);
|
||||
Current.Logger.Error<MembershipProviderBase>(ex, "Cannot specify a Hashed password format with the enabledPasswordRetrieval option set to true");
|
||||
throw ex;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<ContentService>($"Failed to publish document id={d.Id}, reason={result.Result}.");
|
||||
Logger.Error<ContentService>(null, "Failed to publish document id={DocumentId}, reason={Reason}.", d.Id, result.Result);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error<ContentService>($"Failed to publish document id={d.Id}, an exception was thrown.", e);
|
||||
Logger.Error<ContentService>(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<ContentService>($"Failed to unpublish document id={d.Id}, reason={result.Result}.");
|
||||
Logger.Error<ContentService>(null, "Failed to unpublish document id={DocumentId}, reason={Reason}.", d.Id, result.Result);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error<ContentService>($"Failed to unpublish document id={d.Id}, an exception was thrown.", e);
|
||||
Logger.Error<ContentService>(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<ContentService>("An error occurred while deleting file attached to nodes: " + file, e));
|
||||
(file, e) => Logger.Error<ContentService>(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<IContent>(content, evtMsgs)))
|
||||
{
|
||||
Logger.Info<ContentService>(() => $"Document \"'{content.Name}\" (id={content.Id}) cannot be published: publishing was cancelled.");
|
||||
Logger.Info<ContentService>("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<ContentService>(() => $"Document \"{content.Name}\" (id={content.Id}) cannot be published: document does not have published values.");
|
||||
Logger.Info<ContentService>("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<ContentService>(() => $"Document \"{content.Name}\" (id={content.Id}) cannot be published: document has expired.");
|
||||
Logger.Info<ContentService>("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<ContentService>(() => $"Document \"{content.Name}\" (id={content.Id}) cannot be published: document is awaiting release.");
|
||||
Logger.Info<ContentService>("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<ContentService>(() => $"Document \"{content.Name}\" (id={content.Id}) cannot be published: document is trashed.");
|
||||
Logger.Info<ContentService>("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<ContentService>(() => $"Document \"{content.Name}\" (id={content.Id}) cannot be published: parent is not published.");
|
||||
Logger.Info<ContentService>("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<ContentService>(() => $"Content \"{content.Name}\" (id={content.Id}) has been published.");
|
||||
Logger.Info<ContentService>("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<IContent>(content, evtMsgs)))
|
||||
{
|
||||
Logger.Info<ContentService>(() => $"Document \"{content.Name}\" (id={content.Id}) cannot be unpublished: unpublishing was cancelled.");
|
||||
Logger.Info<ContentService>("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<ContentService>(() => $"Document \"{content.Name}\" (id={content.Id}) had its release date removed, because it was unpublished.");
|
||||
Logger.Info<ContentService>("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<ContentService>(() => $"Document \"{content.Name}\" (id={content.Id}) has been unpublished.");
|
||||
Logger.Info<ContentService>("Document '{ContentName}' (id={ContentId}) has been unpublished.", content.Name, content.Id);
|
||||
return attempt;
|
||||
}
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
{
|
||||
if (xmlSource.ContainsKey(culture) == false)
|
||||
{
|
||||
_logger.Warn<LocalizedTextService>(() => $"The culture specified {culture} was not found in any configured sources for this service");
|
||||
_logger.Warn<LocalizedTextService>("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<LocalizedTextService>(() => $"The culture specified {culture} was not found in any configured sources for this service");
|
||||
_logger.Warn<LocalizedTextService>("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<LocalizedTextService>(() => $"The culture specified {culture} was not found in any configured sources for this service");
|
||||
_logger.Warn<LocalizedTextService>("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<LocalizedTextService>(() => $"The culture specified {culture} was not found in any configured sources for this service");
|
||||
_logger.Warn<LocalizedTextService>("The culture specified {Culture} was not found in any configured sources for this service", culture);
|
||||
return "[" + key + "]";
|
||||
}
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
}
|
||||
catch (CultureNotFoundException)
|
||||
{
|
||||
Current.Logger.Warn<LocalizedTextServiceFileSources>(() => $"The culture {cultureVal} found in the file {fileInfo.FullName} is not a valid culture");
|
||||
Current.Logger.Warn<LocalizedTextServiceFileSources>("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<LocalizedTextServiceFileSources>(() => $"The folder does not exist: {fileSourceFolder.FullName}, therefore no sources will be discovered");
|
||||
Current.Logger.Warn<LocalizedTextServiceFileSources>("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<LocalizedTextServiceFileSources>("Could not load file into XML " + supplementaryFile.File.FullName, ex);
|
||||
_logger.Error<LocalizedTextServiceFileSources>(ex, "Could not load file into XML {File}", supplementaryFile.File.FullName);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<MediaService>("An error occurred while deleting file attached to nodes: " + file, e));
|
||||
(file, e) => Logger.Error<MediaService>(e, "An error occurred while deleting file attached to nodes: {File}", file));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<MemberService>("An error occurred while deleting file attached to nodes: " + file, e));
|
||||
(file, e) => Logger.Error<MemberService>(e, "An error occurred while deleting file attached to nodes: {File}", file));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -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<NotificationService>(() => string.Format("Notification \"{0}\" sent to {1} ({2})", request.Action, request.UserName, request.Email));
|
||||
_logger.Debug<NotificationService>("Notification '{Action}' sent to {Username} ({Email})", request.Action, request.UserName, request.Email);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error<NotificationService>("An error occurred sending notification", ex);
|
||||
_logger.Error<NotificationService>(ex, "An error occurred sending notification");
|
||||
s.Dispose();
|
||||
s = new SmtpClient();
|
||||
}
|
||||
|
||||
@@ -491,7 +491,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
var tryCreateFolder = _contentTypeService.CreateContainer(-1, rootFolder);
|
||||
if (tryCreateFolder == false)
|
||||
{
|
||||
_logger.Error<PackagingService>("Could not create folder: " + rootFolder, tryCreateFolder.Exception);
|
||||
_logger.Error<PackagingService>(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<PackagingService>("Could not create folder: " + folderName, tryCreateFolder.Exception);
|
||||
_logger.Error<PackagingService>(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<PackagingService>(() => $"Packager: Error handling allowed templates. Template with alias '{alias}' could not be found.");
|
||||
_logger.Warn<PackagingService>("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<PackagingService>(() => $"Packager: Error handling default template. Default template with alias '{defaultTemplateElement.Value}' could not be found.");
|
||||
_logger.Warn<PackagingService>("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<PackagingService>(() => $"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<PackagingService>("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<PackagingService>(() => $"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<PackagingService>(
|
||||
"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<PackagingService>("Could not create folder: " + rootFolder, tryCreateFolder.Exception);
|
||||
_logger.Error<PackagingService>(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<PackagingService>("Could not create folder: " + folderName, tryCreateFolder.Exception);
|
||||
_logger.Error<PackagingService>(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<PackagingService>(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<PackagingService>(
|
||||
"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));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -192,9 +192,11 @@ namespace Umbraco.Core.Sync
|
||||
if (count > Options.MaxProcessingInstructionCount)
|
||||
{
|
||||
//too many instructions, proceed to cold boot
|
||||
Logger.Warn<DatabaseServerMessenger>(() => $"The instruction count ({count}) exceeds the specified MaxProcessingInstructionCount ({Options.MaxProcessingInstructionCount})."
|
||||
Logger.Warn<DatabaseServerMessenger>(
|
||||
"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<DatabaseServerMessenger>($"Failed to deserialize instructions ({dto.Id}: \"{dto.Instructions}\").", ex);
|
||||
Logger.Error<DatabaseServerMessenger>(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<DatabaseServerMessenger>(
|
||||
$"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.
|
||||
|
||||
@@ -157,7 +157,7 @@ namespace Umbraco.Core.Sync
|
||||
{
|
||||
if (refresher == null) throw new ArgumentNullException(nameof(refresher));
|
||||
|
||||
Current.Logger.Debug<ServerMessengerBase>(() => $"Invoking refresher {refresher.GetType()} on local server for message type RefreshByPayload");
|
||||
Current.Logger.Debug<ServerMessengerBase>("Invoking refresher {RefresherType} on local server for message type RefreshByPayload", refresher.GetType());
|
||||
|
||||
var payloadRefresher = refresher as IPayloadCacheRefresher<TPayload>;
|
||||
if (payloadRefresher == null)
|
||||
@@ -179,7 +179,7 @@ namespace Umbraco.Core.Sync
|
||||
{
|
||||
if (refresher == null) throw new ArgumentNullException(nameof(refresher));
|
||||
|
||||
Current.Logger.Debug<ServerMessengerBase>(() => $"Invoking refresher {refresher.GetType()} on local server for message type {messageType}");
|
||||
Current.Logger.Debug<ServerMessengerBase>("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<ServerMessengerBase>(() => $"Invoking refresher {refresher.GetType()} on local server for message type {messageType}");
|
||||
Current.Logger.Debug<ServerMessengerBase>("Invoking refresher {RefresherType} on local server for message type {MessageType}", refresher.GetType(), messageType);
|
||||
|
||||
var typedRefresher = refresher as ICacheRefresher<T>;
|
||||
|
||||
|
||||
@@ -64,8 +64,6 @@
|
||||
<PackageReference Include="LightInject" Version="5.1.2" />
|
||||
<PackageReference Include="LightInject.Annotation" Version="1.1.0" />
|
||||
<PackageReference Include="LightInject.Web" Version="2.0.0" />
|
||||
<PackageReference Include="log4net" Version="2.0.8" />
|
||||
<PackageReference Include="Log4Net.Async" Version="2.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNet.Identity.Owin" Version="2.2.1" />
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.6" />
|
||||
<PackageReference Include="Microsoft.Owin.Security.Cookies" Version="4.0.0" />
|
||||
@@ -76,6 +74,27 @@
|
||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||
<PackageReference Include="NPoco" Version="3.9.3" />
|
||||
<PackageReference Include="Semver" Version="2.0.4" />
|
||||
<PackageReference Include="Serilog">
|
||||
<Version>2.7.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Serilog.Enrichers.Process">
|
||||
<Version>2.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Serilog.Enrichers.Thread">
|
||||
<Version>3.0.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Serilog.Filters.Expressions">
|
||||
<Version>2.0.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Serilog.Formatting.Compact">
|
||||
<Version>1.0.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Serilog.Settings.AppSettings">
|
||||
<Version>2.1.2</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Serilog.Sinks.File">
|
||||
<Version>4.0.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Umbraco.SqlServerCE" Version="4.0.0.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -310,7 +329,8 @@
|
||||
<Compile Include="IO\MediaPathSchemes\OriginalMediaPathScheme.cs" />
|
||||
<Compile Include="IO\MediaPathSchemes\TwoGuidsMediaPathScheme.cs" />
|
||||
<Compile Include="KeyValuePairExtensions.cs" />
|
||||
<Compile Include="Logging\RollingFileCleanupAppender.cs" />
|
||||
<Compile Include="Logging\SerilogExtensions\LoggerConfigExtensions.cs" />
|
||||
<Compile Include="Logging\SerilogExtensions\Log4NetLevelMapperEnricher.cs" />
|
||||
<Compile Include="Migrations\MigrationBase_Extra.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_7_10_0\RenamePreviewFolder.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_7_12_0\AddRelationTypeForMediaFolderOnDelete.cs" />
|
||||
@@ -404,7 +424,7 @@
|
||||
<Compile Include="PropertyEditors\PropertyEditorCollection.cs" />
|
||||
<Compile Include="PropertyEditors\PropertyEditorTagsExtensions.cs" />
|
||||
<Compile Include="PropertyEditors\PropertyValueLevel.cs" />
|
||||
<Compile Include="PropertyEditors\SliderPropertyEditorConfiguration.cs" />
|
||||
<Compile Include="PropertyEditors\SliderConfiguration.cs" />
|
||||
<Compile Include="PropertyEditors\TagConfiguration.cs" />
|
||||
<Compile Include="PropertyEditors\ValueConverters\ImageCropperValue.cs" />
|
||||
<Compile Include="PropertyEditors\ValueConverters\ImageCropperValueTypeConverter.cs" />
|
||||
@@ -455,7 +475,7 @@
|
||||
<Compile Include="Dictionary\ICultureDictionary.cs" />
|
||||
<Compile Include="Dictionary\ICultureDictionaryFactory.cs" />
|
||||
<Compile Include="DisposableObject.cs" />
|
||||
<Compile Include="DisposableTimer.cs" />
|
||||
<Compile Include="Logging\DisposableTimer.cs" />
|
||||
<Compile Include="EmailSender.cs" />
|
||||
<Compile Include="Enum.cs" />
|
||||
<Compile Include="EnumerableExtensions.cs" />
|
||||
@@ -545,24 +565,18 @@
|
||||
<Compile Include="IRuntimeState.cs" />
|
||||
<Compile Include="LambdaExpressionCacheKey.cs" />
|
||||
<Compile Include="ListExtensions.cs" />
|
||||
<Compile Include="Logging\AppDomainTokenConverter.cs" />
|
||||
<Compile Include="Logging\AsyncForwardingAppenderBase.cs" />
|
||||
<Compile Include="Logging\DebugDiagnosticsLogger.cs" />
|
||||
<Compile Include="Logging\ILogger.cs" />
|
||||
<Compile Include="Logging\ImageProcessorLogger.cs" />
|
||||
<Compile Include="Logging\IProfiler.cs" />
|
||||
<Compile Include="Logging\IQueue.cs" />
|
||||
<Compile Include="Logging\Logger.cs" />
|
||||
<Compile Include="Logging\LoggerExtensions.cs" />
|
||||
<Compile Include="Logging\LoggingEventContext.cs" />
|
||||
<Compile Include="Logging\LoggingEventHelper.cs" />
|
||||
<Compile Include="Logging\LoggingTaskExtension.cs" />
|
||||
<Compile Include="Logging\LogProfiler.cs" />
|
||||
<Compile Include="Logging\OwinLogger.cs" />
|
||||
<Compile Include="Logging\OwinLoggerFactory.cs" />
|
||||
<Compile Include="Logging\ProfilerExtensions.cs" />
|
||||
<Compile Include="Logging\ProfilingLogger.cs" />
|
||||
<Compile Include="Logging\RingBuffer.cs" />
|
||||
<Compile Include="Logging\VoidProfiler.cs" />
|
||||
<Compile Include="Logging\WebProfiler.cs" />
|
||||
<Compile Include="Logging\WebProfilerComponent.cs" />
|
||||
|
||||
@@ -3,10 +3,11 @@ using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
using log4net;
|
||||
using LightInject;
|
||||
using Serilog;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Logging;
|
||||
using ILogger = Umbraco.Core.Logging.ILogger;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
@@ -27,7 +28,7 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
protected virtual ILogger GetLogger()
|
||||
{
|
||||
return Logger.CreateWithDefaultLog4NetConfiguration();
|
||||
return Logger.CreateWithDefaultConfiguration();
|
||||
}
|
||||
|
||||
// events - in the order they trigger
|
||||
@@ -91,7 +92,7 @@ namespace Umbraco.Core
|
||||
var msg = "Unhandled exception in AppDomain";
|
||||
if (isTerminating) msg += " (terminating)";
|
||||
msg += ".";
|
||||
logger.Error<UmbracoApplicationBase>(msg, exception);
|
||||
logger.Error<UmbracoApplicationBase>(exception, msg);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -184,14 +185,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<UmbracoApplicationBase>(shutdownMsg);
|
||||
logger.Info<UmbracoApplicationBase>("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<UmbracoApplicationBase>("Application shutdown. Reason: " + HostingEnvironment.ShutdownReason);
|
||||
logger.Info<UmbracoApplicationBase>("Application shutdown. Reason: {ShutdownReason}", HostingEnvironment.ShutdownReason);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,7 +203,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
|
||||
@@ -220,7 +225,7 @@ namespace Umbraco.Core
|
||||
// ignore HTTP errors
|
||||
if (exception.GetType() == typeof(HttpException)) return;
|
||||
|
||||
Current.Logger.Error<UmbracoApplicationBase>("An unhandled exception occurred.", exception);
|
||||
Current.Logger.Error<UmbracoApplicationBase>(exception, "An unhandled exception occurred");
|
||||
}
|
||||
|
||||
// called by ASP.NET (auto event wireup) at any phase in the application life cycle
|
||||
@@ -243,7 +248,7 @@ namespace Umbraco.Core
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Current.Logger.Error<UmbracoApplicationBase>($"Error in {name} handler.", ex);
|
||||
Current.Logger.Error<UmbracoApplicationBase>(ex, "Error in {Name} handler.", name);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<MacroNavigator>(msg); // beware! this can quicky overflow log4net
|
||||
//Console.WriteLine(msg);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -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<NavigableNavigator>(msg); // beware! this can quicky overflow log4net
|
||||
//Console.WriteLine(msg);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -162,7 +162,7 @@ namespace Umbraco.Examine
|
||||
/// </remarks>
|
||||
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
|
||||
/// <summary>
|
||||
/// overridden for logging
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected override void OnIndexingError(IndexingErrorEventArgs e)
|
||||
/// <param name="ex"></param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
<PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" Version="0.10.13" />
|
||||
<PackageReference Include="BenchmarkDotNet.Toolchains.Roslyn" Version="0.10.13" />
|
||||
<PackageReference Include="Castle.Core" Version="4.2.1" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="2.8.0" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="2.9.0" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="2.8.0" />
|
||||
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="2.0.11" />
|
||||
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.0" />
|
||||
|
||||
@@ -5,10 +5,6 @@
|
||||
</startup>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0"/>
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.CodeAnalysis" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.8.0.0" newVersion="2.8.0.0"/>
|
||||
|
||||
@@ -107,10 +107,6 @@
|
||||
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0"/>
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.CodeAnalysis" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.8.0.0" newVersion="2.8.0.0"/>
|
||||
|
||||
@@ -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<Type> FindClassesOfTypeWithAttribute<T, TAttribute>()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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<string> 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<object>[] 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<string> 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<object>[] 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<object>[] 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<string> 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<object>[] 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<string> 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<object>[] 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,7 +344,7 @@ namespace Umbraco.Tests.TestHelpers
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error<TestWithDatabaseBase>("Could not remove the old database file", ex);
|
||||
Logger.Error<TestWithDatabaseBase>(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);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user