public async Task SendAsync(HealthCheckResults results) { if (ShouldSend(results) == false) { return; } if (string.IsNullOrEmpty(RecipientEmail)) { return; } var message = _textService.Localize("healthcheck/scheduledHealthCheckEmailBody", new[] { DateTime.Now.ToShortDateString(), DateTime.Now.ToShortTimeString(), results.ResultsAsHtml(Verbosity) }); var subject = _textService.Localize("healthcheck/scheduledHealthCheckEmailSubject"); var mailSender = new EmailSender(); using (var mailMessage = new MailMessage(UmbracoConfig.For.UmbracoSettings().Content.NotificationEmailAddress, RecipientEmail, string.IsNullOrEmpty(subject) ? "Umbraco Health Check Status" : subject, message) { IsBodyHtml = message.IsNullOrWhiteSpace() == false && message.Contains("<") && message.Contains("</") }) { await mailSender.SendAsync(mailMessage); } }
public override async Task SendAsync(HealthCheckResults results) { if (ShouldSend(results) == false) { return; } if (string.IsNullOrEmpty(RecipientEmail)) { return; } var message = _textService?.Localize("healthcheck", "scheduledHealthCheckEmailBody", new[] { DateTime.Now.ToShortDateString(), DateTime.Now.ToShortTimeString(), _markdownToHtmlConverter?.ToHtml(results, Verbosity) }); // Include the umbraco Application URL host in the message subject so that // you can identify the site that these results are for. var host = _hostingEnvironment?.ApplicationMainUrl?.ToString(); var subject = _textService?.Localize("healthcheck", "scheduledHealthCheckEmailSubject", new[] { host }); var mailMessage = CreateMailMessage(subject, message); Task?task = _emailSender?.SendAsync(mailMessage, Constants.Web.EmailTypes.HealthCheck); if (task is not null) { await task; } }
public override async Task SendAsync(HealthCheckResults results, CancellationToken token) { if (ShouldSend(results) == false) { return; } if (string.IsNullOrEmpty(RecipientEmail)) { return; } var message = _textService.Localize("healthcheck/scheduledHealthCheckEmailBody", new[] { DateTime.Now.ToShortDateString(), DateTime.Now.ToShortTimeString(), results.ResultsAsHtml(Verbosity) }); // Include the umbraco Application URL host in the message subject so that // you can identify the site that these results are for. var host = _runtimeState.ApplicationUrl; var subject = _textService.Localize("healthcheck/scheduledHealthCheckEmailSubject", new[] { host.ToString() }); var mailSender = new EmailSender(); using (var mailMessage = CreateMailMessage(subject, message)) { await mailSender.SendAsync(mailMessage); } }
public string ToHtml(HealthCheckResults results, HealthCheckNotificationVerbosity verbosity) { var mark = new Markdown(); var html = mark.Transform(results.ResultsAsMarkDown(verbosity)); html = ApplyHtmlHighlighting(html); return(html); }
protected void Page_Load(object sender, EventArgs e) { this.RegisterAsyncTask(new PageAsyncTask(async() => { var healthCheckManager = DependencyLocator.Current.GetInstance <IHealthCheckManager>(); this.HealthCheckResults = await healthCheckManager.CheckHealth(); })); }
public override async Task PerformExecuteAsync(object?state) { if (_healthChecksSettings.Notification.Enabled == false) { return; } if (_runtimeState.Level != RuntimeLevel.Run) { return; } switch (_serverRegistrar.CurrentServerRole) { case ServerRole.Subscriber: _logger.LogDebug("Does not run on subscriber servers."); return; case ServerRole.Unknown: _logger.LogDebug("Does not run on servers with unknown role."); return; } // 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; } // 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 (ICoreScope scope = _scopeProvider.CreateCoreScope()) using (_profilingLogger.DebugDuration <HealthCheckNotifier>("Health checks executing", "Health checks complete")) { // Don't notify for any checks that are disabled, nor for any disabled just for notifications. Guid[] disabledCheckIds = _healthChecksSettings.Notification.DisabledChecks .Select(x => x.Id) .Union(_healthChecksSettings.DisabledChecks .Select(x => x.Id)) .Distinct() .ToArray(); IEnumerable <HealthCheck> checks = _healthChecks .Where(x => disabledCheckIds.Contains(x.Id) == false); var results = await HealthCheckResults.Create(checks); results.LogResults(); // Send using registered notification methods that are enabled. foreach (IHealthCheckNotificationMethod notificationMethod in _notifications.Where(x => x.Enabled)) { await notificationMethod.SendAsync(results); } } }
public async Task <HealthCheckResults> GetHealthAsync( CancellationToken cancellationToken = default(CancellationToken)) { var healthCheckResults = new HealthCheckResults(); var tasks = _healthChecks.Select(c => new { name = c.Key, result = c.Value.CheckHealthAsync() }); var sw = new Stopwatch(); foreach (var task in tasks) { try { cancellationToken.ThrowIfCancellationRequested(); sw.Reset(); sw.Start(); var result = await task.result; sw.Stop(); healthCheckResults.Entries.Add(task.name, new HealthCheckResultExtended(result) { ResponseTime = sw.ElapsedMilliseconds }); } catch (OperationCanceledException) { throw; } catch { healthCheckResults.Entries.Add(task.name, new HealthCheckResultExtended(new HealthCheckResult(HealthStatus.Unhealthy))); } } var status = HealthStatus.Healthy; foreach (var healthCheckResultExtended in healthCheckResults.Entries.Values) { if (healthCheckResultExtended.Status == HealthStatus.Unhealthy) { status = HealthStatus.Unhealthy; break; } if (healthCheckResultExtended.Status == HealthStatus.Degraded) { status = HealthStatus.Degraded; } } healthCheckResults.Status = status; healthCheckResults.TotalResponseTime = healthCheckResults.Entries.Values.Sum(c => c.ResponseTime); return(healthCheckResults); }
public override async Task <bool> PerformRunAsync(CancellationToken token) { if (_runtimeState.Level != RuntimeLevel.Run) { return(true); // repeat... } switch (_runtimeState.ServerRole) { case ServerRole.Replica: _logger.Debug <HealthCheckNotifier>("Does not run on replica servers."); return(true); // DO repeat, server role can change case ServerRole.Unknown: _logger.Debug <HealthCheckNotifier>("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 (_runtimeState.IsMainDom == false) { _logger.Debug <HealthCheckNotifier>("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 (_logger.DebugDuration <HealthCheckNotifier>("Health checks executing", "Health checks complete")) { var healthCheckConfig = Current.Configs.HealthChecks(); // 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 }
/// <summary> /// Performas a health check of all depdendencies of the API service. /// </summary> /// <param name="app"></param> /// <returns></returns> public Task <HealthCheckResults> HealthCheckApi(string userId, string app) { var healthCheckResults = new HealthCheckResults() { Status = HealthCheckStatus.OK, Application = app }; return(Task.FromResult <HealthCheckResults>(healthCheckResults)); }
public static HealthCheckResults Run() { var results = new HealthCheckResults(); // Here's the list of checks to run results.Add(Ogr2OgrIExeIsCorrectVersion.Run()); results.Add(HeadlessGoogleChromeIsAvailable.Run()); results.Add(SqlServerSpatialDllSeemsToWork.Run()); return(results); }
protected void Page_Load(object sender, EventArgs e) { this.RegisterAsyncTask(new PageAsyncTask(async() => { var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(3)); var combined = CancellationTokenSource.CreateLinkedTokenSource(timeout.Token, this.Context.Request.TimedOutToken, this.Context.Response.ClientDisconnectedToken); var healthCheckManager = DependencyLocator.Current.GetInstance <IHealthCheckManager>(); this.HealthCheckResults = await healthCheckManager.CheckHealth(combined.Token); })); }
public override async Task <bool> PerformRunAsync(CancellationToken token) { if (_appContext == null) { return(true); // repeat... } switch (_appContext.GetCurrentServerRole()) { case ServerRole.Slave: LogHelper.Debug <HealthCheckNotifier>("Does not run on replica servers."); return(true); // DO repeat, server role can change case ServerRole.Unknown: LogHelper.Debug <HealthCheckNotifier>("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 (_appContext.MainDom.IsMainDom == false) { LogHelper.Debug <HealthCheckNotifier>("Does not run if not MainDom."); return(false); // do NOT repeat, going down } using (_appContext.ProfilingLogger.DebugDuration <KeepAlive>("Health checks executing", "Health checks complete")) { var healthCheckConfig = UmbracoConfig.For.HealthCheck(); // 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 = _healthCheckResolver.HealthChecks .Where(x => disabledCheckIds.Contains(x.Id) == false); var results = new HealthCheckResults(checks); results.LogResults(); // Send using registered notification methods that are enabled var registeredNotificationMethods = HealthCheckNotificationMethodResolver.Current.NotificationMethods.Where(x => x.Enabled); foreach (var notificationMethod in registeredNotificationMethods) { await notificationMethod.SendAsync(results); } } return(true); // repeat }
public override async Task <bool> PerformRunAsync(CancellationToken token) { if (_runtimeState.Level != RuntimeLevel.Run) { return(true); // repeat... } switch (_runtimeState.ServerRole) { case ServerRole.Replica: _logger.Debug <HealthCheckNotifier>("Does not run on replica servers."); return(true); // DO repeat, server role can change case ServerRole.Unknown: _logger.Debug <HealthCheckNotifier>("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 (_runtimeState.IsMainDom == false) { _logger.Debug <HealthCheckNotifier>("Does not run if not MainDom."); return(false); // do NOT repeat, going down } using (_logger.DebugDuration <HealthCheckNotifier>("Health checks executing", "Health checks complete")) { var healthCheckConfig = Current.Configs.HealthChecks(); // 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 void HealthCheckResults_WithSummaryVerbosity_ReturnsCorrectResultDescription() { var checks = new List <HealthCheck> { new StubHealthCheck1(StatusResultType.Success, "First check was successful"), new StubHealthCheck2(StatusResultType.Success, "Second check was successful"), }; var results = new HealthCheckResults(checks); var resultAsMarkdown = results.ResultsAsMarkDown(HealthCheckNotificationVerbosity.Summary); Assert.IsTrue(resultAsMarkdown.IndexOf("Result: 'Success'\r\n") > -1); }
public async Task HealthCheckResults_WithSummaryVerbosity_ReturnsCorrectResultDescription() { var checks = new List <HealthCheck> { new StubHealthCheck1(StatusResultType.Success, "First check was successful"), new StubHealthCheck2(StatusResultType.Success, "Second check was successful"), }; var results = await HealthCheckResults.Create(checks); var resultAsMarkdown = results.ResultsAsMarkDown(HealthCheckNotificationVerbosity.Summary); Assert.IsTrue(resultAsMarkdown.IndexOf("Result: 'Success'" + Environment.NewLine) > -1); }
protected bool ShouldSend(HealthCheckResults results) { if (Enabled == false) { return(false); } if (FailureOnly && results.AllChecksSuccessful) { return(false); } return(true); }
public async Task SendAsync(HealthCheckResults results) { if (ShouldSend(results) == false) { return; } if (string.IsNullOrEmpty(RecipientEmail)) { return; } var message = _textService.Localize("healthcheck/scheduledHealthCheckEmailBody", new[] { DateTime.Now.ToShortDateString(), DateTime.Now.ToShortTimeString(), results.ResultsAsHtml(Verbosity) }); // Include the umbraco Application URL host in the message subject so that // you can identify the site that these results are for. var umbracoApplicationUrl = ApplicationContext.Current.UmbracoApplicationUrl; var host = umbracoApplicationUrl; if (Uri.TryCreate(umbracoApplicationUrl, UriKind.Absolute, out var umbracoApplicationUri)) { host = umbracoApplicationUri.Host; } else { LogHelper.Debug <EmailNotificationMethod>($"umbracoApplicationUrl {umbracoApplicationUrl} appears to be invalid"); } var subject = _textService.Localize("healthcheck/scheduledHealthCheckEmailSubject", new[] { host }); var mailSender = new EmailSender(); using (var mailMessage = new MailMessage(UmbracoConfig.For.UmbracoSettings().Content.NotificationEmailAddress, RecipientEmail, string.IsNullOrEmpty(subject) ? "Umbraco Health Check Status" : subject, message) { IsBodyHtml = message.IsNullOrWhiteSpace() == false && message.Contains("<") && message.Contains("</") }) { await mailSender.SendAsync(mailMessage); } }
public async Task HealthCheckResults_WithSuccessfulChecks_ReturnsCorrectResultDescription() { var checks = new List <HealthCheck> { new StubHealthCheck1(StatusResultType.Success, "First check was successful"), new StubHealthCheck2(StatusResultType.Success, "Second check was successful"), }; var results = await HealthCheckResults.Create(checks); Assert.IsTrue(results.AllChecksSuccessful); var resultAsMarkdown = results.ResultsAsMarkDown(HealthCheckNotificationVerbosity.Summary); Assert.IsTrue(resultAsMarkdown.IndexOf("Checks for 'Stub check 1' all completed successfully.") > -1); Assert.IsTrue(resultAsMarkdown.IndexOf("Checks for 'Stub check 2' all completed successfully.") > -1); }
public void HealthCheckResults_WithFailingChecks_ReturnsCorrectResultDescription() { var checks = new List <HealthCheck> { new StubHealthCheck1(StatusResultType.Success, "First check was successful"), new StubHealthCheck2(StatusResultType.Error, "Second check was not successful"), }; var results = new HealthCheckResults(checks); Assert.IsFalse(results.AllChecksSuccessful); var resultAsMarkdown = results.ResultsAsMarkDown(HealthCheckNotificationVerbosity.Summary); Assert.IsTrue(resultAsMarkdown.IndexOf("Checks for 'Stub check 1' all completed succesfully.") > -1); Assert.IsTrue(resultAsMarkdown.IndexOf("Checks for 'Stub check 2' completed with errors.") > -1); }
public SiteMonitorNagiosViewData(FirmaSession currentFirmaSession, HealthCheckResults healthCheckResults) : base(currentFirmaSession) { HealthCheckResults = healthCheckResults; CompleteNagiosOutput = HealthCheckResults.GetHealthCheckResultsAsCompleteNagiosOutputText(); NagiosReturnCode = HealthCheckResults.GetNagiosReturnCode(); }
public abstract Task SendAsync(HealthCheckResults results);
protected bool ShouldSend(HealthCheckResults results) { return(Enabled && (!FailureOnly || !results.AllChecksSuccessful)); }
public abstract Task SendAsync(HealthCheckResults results, CancellationToken token);