* Started moving to JSON instead of config. Mild refactoring but overall keeping it the same, except for injecting IConfiguration and JSON parsing instead of XML Tests currently unaffected, need to increase coverage * Moved to constants for appsettings keys Moved from IConfiguration to global settings - later to be replaced with IOptions Updated translation messages Installed IOptions ready for new PR Updated to new interface, IConfigurationService * Post-merge fix * Namespace move from Umbraco.Web to Umbraco.Core where appropriate * Renamed abstractsettings (from abstractconfig) Moving out of configservice into the POCO config check * Made the IIsCustomErrors healthcheck as obsolete, as no web.config setting). Investigate reintroducing this check in the .NET Core way (UseDevelopment). Reducing use of abstractsettings as not needed - we don't need a config service to read the config settings anymore as they're all explicit POCOs. Consolidated health-checks in project. * Removed test views that weren't meant to be added * Returned to use of abstractsettings with different use * Moved more health checks into correct folder/namespace, and enum into their own file * Correct namespace * Git history/compare lost due to file move, temporarily moving back to original folder. Will do another PR to move after this * Use existing GetStatus in abstract check for Debug mode * Updating to return to previous logic and putting files back into line * Macro errors returned to previous logic * Reuse abstractsettings class * Swapped order to assist with reviewing PR * Updated to include itempath * Not implemented comment to avoid confusion Implemented NotificationEmailCheck * Changed to IOptionsMonitor as per PR comments. Removed configurationservice as we need to rethink the fixing strategy. Updated logger. Needs to show fix message instead of fixing. Temporary fix for IIS version * Switched to IOptionsMonitor for all * No longer attempts to actually fix header in config. Still need to show suggestions. Co-authored-by: Elitsa Marinovska <elm@umbraco.dk>
111 lines
4.5 KiB
C#
111 lines
4.5 KiB
C#
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Umbraco.Core;
|
|
using Umbraco.Core.Configuration.Models;
|
|
using Umbraco.Core.HealthCheck;
|
|
using Umbraco.Core.Logging;
|
|
using Umbraco.Core.Scoping;
|
|
using Umbraco.Core.Sync;
|
|
using Umbraco.Web.HealthCheck;
|
|
using Microsoft.Extensions.Logging;
|
|
using Umbraco.Infrastructure.HealthCheck;
|
|
|
|
namespace Umbraco.Web.Scheduling
|
|
{
|
|
public class HealthCheckNotifier : RecurringTaskBase
|
|
{
|
|
private readonly IMainDom _mainDom;
|
|
private readonly HealthCheckCollection _healthChecks;
|
|
private readonly HealthCheckNotificationMethodCollection _notifications;
|
|
private readonly IScopeProvider _scopeProvider;
|
|
private readonly IProfilingLogger _profilingLogger;
|
|
private readonly ILogger<HealthCheckNotifier> _logger;
|
|
private readonly HealthChecksSettings _healthChecksSettings;
|
|
private readonly IServerRegistrar _serverRegistrar;
|
|
private readonly IRuntimeState _runtimeState;
|
|
|
|
public HealthCheckNotifier(
|
|
IBackgroundTaskRunner<RecurringTaskBase> runner,
|
|
int delayMilliseconds,
|
|
int periodMilliseconds,
|
|
HealthCheckCollection healthChecks,
|
|
HealthCheckNotificationMethodCollection notifications,
|
|
IMainDom mainDom,
|
|
IProfilingLogger profilingLogger ,
|
|
ILogger<HealthCheckNotifier> logger,
|
|
HealthChecksSettings healthChecksSettings,
|
|
IServerRegistrar serverRegistrar,
|
|
IRuntimeState runtimeState,
|
|
IScopeProvider scopeProvider)
|
|
: base(runner, delayMilliseconds, periodMilliseconds)
|
|
{
|
|
_healthChecks = healthChecks;
|
|
_notifications = notifications;
|
|
_mainDom = mainDom;
|
|
_scopeProvider = scopeProvider;
|
|
_runtimeState = runtimeState;
|
|
_profilingLogger = profilingLogger ;
|
|
_logger = logger;
|
|
_healthChecksSettings = healthChecksSettings;
|
|
_serverRegistrar = serverRegistrar;
|
|
_runtimeState = runtimeState;
|
|
}
|
|
|
|
public override async Task<bool> PerformRunAsync(CancellationToken token)
|
|
{
|
|
if (_runtimeState.Level != RuntimeLevel.Run)
|
|
return true; // repeat...
|
|
|
|
switch (_serverRegistrar.GetCurrentServerRole())
|
|
{
|
|
case ServerRole.Replica:
|
|
_logger.LogDebug("Does not run on replica servers.");
|
|
return true; // DO repeat, server role can change
|
|
case ServerRole.Unknown:
|
|
_logger.LogDebug("Does not run on servers with unknown role.");
|
|
return true; // DO repeat, server role can change
|
|
}
|
|
|
|
// ensure we do not run if not main domain, but do NOT lock it
|
|
if (_mainDom.IsMainDom == false)
|
|
{
|
|
_logger.LogDebug("Does not run if not MainDom.");
|
|
return false; // do NOT repeat, going down
|
|
}
|
|
|
|
// Ensure we use an explicit scope since we are running on a background thread and plugin health
|
|
// checks can be making service/database calls so we want to ensure the CallContext/Ambient scope
|
|
// isn't used since that can be problematic.
|
|
using (var scope = _scopeProvider.CreateScope())
|
|
using (_profilingLogger.DebugDuration<HealthCheckNotifier>("Health checks executing", "Health checks complete"))
|
|
{
|
|
var healthCheckConfig = _healthChecksSettings;
|
|
|
|
// Don't notify for any checks that are disabled, nor for any disabled
|
|
// just for notifications
|
|
var disabledCheckIds = healthCheckConfig.NotificationSettings.DisabledChecks
|
|
.Select(x => x.Id)
|
|
.Union(healthCheckConfig.DisabledChecks
|
|
.Select(x => x.Id))
|
|
.Distinct()
|
|
.ToArray();
|
|
|
|
var checks = _healthChecks
|
|
.Where(x => disabledCheckIds.Contains(x.Id) == false);
|
|
|
|
var results = new HealthCheckResults(checks);
|
|
results.LogResults();
|
|
|
|
// Send using registered notification methods that are enabled
|
|
foreach (var notificationMethod in _notifications.Where(x => x.Enabled))
|
|
await notificationMethod.SendAsync(results, token);
|
|
}
|
|
|
|
return true; // repeat
|
|
}
|
|
|
|
public override bool IsAsync => true;
|
|
}
|
|
}
|