public void Constructor_BindsConfigurationCorrectly() { var appsettings = new Dictionary <string, string>() { ["management:endpoints:enabled"] = "false", ["management:endpoints:sensitive"] = "false", ["management:endpoints:path"] = "/cloudfoundryapplication", ["management:endpoints:health:enabled"] = "true", ["management:endpoints:health:requiredPermissions"] = "NONE", ["management:endpoints:cloudfoundry:validatecertificates"] = "true", ["management:endpoints:cloudfoundry:enabled"] = "true" }; ConfigurationBuilder configurationBuilder = new ConfigurationBuilder(); configurationBuilder.AddInMemoryCollection(appsettings); var config = configurationBuilder.Build(); var opts = new HealthOptions(config); CloudFoundryOptions cloudOpts = new CloudFoundryOptions(config); Assert.True(cloudOpts.Enabled); Assert.False(cloudOpts.Sensitive); Assert.Equal(string.Empty, cloudOpts.Id); Assert.Equal("/cloudfoundryapplication", cloudOpts.Path); Assert.True(cloudOpts.ValidateCertificates); Assert.True(opts.Enabled); Assert.False(opts.Sensitive); Assert.Equal("health", opts.Id); Assert.Equal("/cloudfoundryapplication/health", opts.Path); Assert.Equal(Permissions.NONE, opts.RequiredPermissions); }
public void Invoke_HandlesExceptions_ReturnsExpectedHealth() { var opts = new HealthOptions(); var contributors = new List <IHealthContributor>() { new TestContrib("h1"), new TestContrib("h2", true), new TestContrib("h3") }; var ep = new HealthEndpoint(opts, new DefaultHealthAggregator(), contributors); var info = ep.Invoke(); foreach (var contrib in contributors) { TestContrib tc = (TestContrib)contrib; if (tc.Throws) { Assert.False(tc.Called); } else { Assert.True(tc.Called); } } Assert.Equal(HealthStatus.UP, info.Status); }
public IHealthRoot Build() { if (_options == null) { _options = new HealthOptions(); } if (_healthFormatterCollection.Count == 0) { _healthFormatterCollection.Add(new HealthStatusTextOutputFormatter()); } IRunHealthChecks healthCheckRunner; var health = new DefaultHealth(_checks.Values); var defaultMetricsOutputFormatter = _defaultMetricsHealthFormatter ?? _healthFormatterCollection.FirstOrDefault(); if (_options.Enabled && health.Checks.Any()) { healthCheckRunner = new DefaultHealthCheckRunner(health.Checks); } else { healthCheckRunner = new NoOpHealthCheckRunner(); } return(new HealthRoot( health, _options, _healthFormatterCollection, defaultMetricsOutputFormatter, healthCheckRunner)); }
public void UseHealthActuator_ThrowsIfContributorsNull() { var builder = new AppBuilder(); var config = new ConfigurationBuilder().Build(); var options = new HealthOptions(config); var exception = Assert.Throws <ArgumentNullException>(() => builder.UseHealthActuator(options, new DefaultHealthAggregator(), contributors: null)); Assert.Equal("contributors", exception.ParamName); }
public static IEnumerable <KeyValuePair <string, string> > ToKeyValue(this HealthOptions options) { var result = new Dictionary <string, string> { [KeyValuePairHealthOptions.EnabledDirective] = options.Enabled.ToString() }; return(result); }
/// <inheritdoc /> public Task ReportAsync(HealthOptions options, HealthStatus status, CancellationToken cancellationToken = default) { if (_throwEx != null) { throw _throwEx; } return(Task.FromResult(_pass)); }
public void Constructor_InitializesWithDefaults() { var opts = new HealthOptions(); Assert.True(opts.Enabled); Assert.False(opts.Sensitive); Assert.Equal("health", opts.Id); Assert.Equal(Permissions.RESTRICTED, opts.RequiredPermissions); }
public static IServiceCollection AddKumuluzHealth(this IServiceCollection services, Action <HealthOptions> options = null) { HealthOptions opt = new HealthOptions(); options?.Invoke(opt); IHealth healthRegistry = new Health(opt); services.AddSingleton(healthRegistry); return(services); }
public KeyValuePairHealthOptions(HealthOptions options, IEnumerable <KeyValuePair <string, string> > optionValues) { if (optionValues == null) { throw new ArgumentNullException(nameof(optionValues)); } _options = options; _optionValues = optionValues.ToDictionary(o => o.Key, o => o.Value); }
/// <inheritdoc /> public Task ReportAsync(HealthOptions options, HealthStatus status, CancellationToken cancellationToken = default) { if (!_healthAsMetricsOptions.Enabled || !options.Enabled) { Logger.Trace($"Health Status Reporter `{this}` disabled, not reporting."); #if NETSTANDARD1_6 return(Task.CompletedTask); #else return(AppMetricsHealthTaskHelper.CompletedTask()); #endif } Logger.Trace($"Health Status Reporter `{this}` reporting health status."); foreach (var healthResult in status.Results) { var tags = new MetricTags(HealthReportingConstants.TagKeys.HealthCheckName, healthResult.Name); if (healthResult.Check.Status == HealthCheckStatus.Degraded) { _metrics.Measure.Gauge.SetValue(ApplicationHealthMetricRegistry.Checks, tags, HealthConstants.HealthScore.degraded); } else if (healthResult.Check.Status == HealthCheckStatus.Unhealthy) { _metrics.Measure.Gauge.SetValue(ApplicationHealthMetricRegistry.Checks, tags, HealthConstants.HealthScore.unhealthy); } else if (healthResult.Check.Status == HealthCheckStatus.Healthy) { _metrics.Measure.Gauge.SetValue(ApplicationHealthMetricRegistry.Checks, tags, HealthConstants.HealthScore.healthy); } } var overallHealthStatus = HealthConstants.HealthScore.healthy; if (status.Status == HealthCheckStatus.Unhealthy) { overallHealthStatus = HealthConstants.HealthScore.unhealthy; } else if (status.Status == HealthCheckStatus.Degraded) { overallHealthStatus = HealthConstants.HealthScore.degraded; } _metrics.Measure.Gauge.SetValue(ApplicationHealthMetricRegistry.HealthGauge, overallHealthStatus); Logger.Trace($"Health Status Reporter `{this}` successfully reported health status."); #if NETSTANDARD1_6 return(Task.CompletedTask); #else return(AppMetricsHealthTaskHelper.CompletedTask()); #endif }
public void Invoke_NoContributors_ReturnsExpectedHealth() { var opts = new HealthOptions(); var contributors = new List <IHealthContributor>(); var agg = new DefaultHealthAggregator(); var ep = new HealthEndpoint(opts, agg, contributors, GetLogger <HealthEndpoint>()); var health = ep.Invoke(); Assert.NotNull(health); Assert.Equal(HealthStatus.UNKNOWN, health.Status); }
public void Can_set_options_with_instance() { // Arrange var options = new HealthOptions { Enabled = true }; // Act var health = new HealthBuilder().Configuration.Configure(options).Build(); // Assert health.Options.Enabled.Should().BeTrue(); }
public Health(HealthOptions healthOptions) { if (healthOptions == null) { _healthChecks = new Dictionary <string, HealthCheck>(); } else { _healthChecks = healthOptions.HealthChecks; } _logger = healthOptions.Logger ?? new NullLogger <Health>(); }
public void HealthEndpointMiddleware_PathAndVerbMatching_ReturnsExpected() { var opts = new HealthOptions(); var contribs = new List <IHealthContributor>() { new DiskSpaceContributor() }; var ep = new HealthEndpoint(opts, new DefaultHealthAggregator(), contribs); var middle = new HealthEndpointOwinMiddleware(null, ep); Assert.True(middle.RequestVerbAndPathMatch("GET", "/health")); Assert.False(middle.RequestVerbAndPathMatch("PUT", "/health")); Assert.False(middle.RequestVerbAndPathMatch("GET", "/badpath")); }
public static void UseHealthActuator(IConfiguration configuration, IHealthAggregator healthAggregator = null, IEnumerable <IHealthContributor> contributors = null, ILoggerFactory loggerFactory = null) { var options = new HealthOptions(configuration); healthAggregator = healthAggregator ?? new DefaultHealthAggregator(); contributors = contributors ?? new List <IHealthContributor>() { new DiskSpaceContributor(new DiskSpaceContributorOptions(configuration)) }; var ep = new HealthEndpoint(options, healthAggregator, contributors, CreateLogger <HealthEndpoint>(loggerFactory)); var handler = new HealthHandler(ep, SecurityService, CreateLogger <HealthHandler>(loggerFactory)); ConfiguredHandlers.Add(handler); }
public Task ReportAsync(HealthOptions options, HealthStatus status, CancellationToken cancellationToken = default(CancellationToken)) { foreach (var item in status.Results) { _metrics.Measure.Counter.Increment(new CounterOptions { Name = "health", MeasurementUnit = Unit.Calls, Tags = new MetricTags( new[] { "name", "status" }, new[] { item.Name, item.Check.Status.ToString() }) }); } return(Task.CompletedTask); }
private static void UseHealthMiddleware( IApplicationBuilder app, IOptions <HealthEndpointsHostingOptions> endpointsHostingOptionsAccessor, IOptions <HealthEndpointsOptions> endpointsOptionsAccessor, HealthOptions metricsOptions, IHealthOutputFormatter formatter = null) { formatter = formatter ?? endpointsOptionsAccessor.Value.HealthEndpointOutputFormatter; app.UseWhen( context => ShouldUseHealthEndpoint(endpointsHostingOptionsAccessor, endpointsOptionsAccessor, metricsOptions, context), appBuilder => { var responseWriter = HealthAspNetCoreHealthEndpointsServiceCollectionExtensions.ResolveHealthResponseWriter(app.ApplicationServices, formatter); appBuilder.UseMiddleware <HealthCheckEndpointMiddleware>(responseWriter, endpointsOptionsAccessor.Value.Timeout); }); }
public void Invoke_CallsAllContributors() { var opts = new HealthOptions(); var contributors = new List <IHealthContributor>() { new TestContrib("h1"), new TestContrib("h2"), new TestContrib("h3") }; var ep = new HealthEndpoint(opts, new DefaultHealthAggregator(), contributors); var info = ep.Invoke(); foreach (var contrib in contributors) { TestContrib tc = (TestContrib)contrib; Assert.True(tc.Called); } }
public void Constructor_BindsConfigurationCorrectly() { var appsettings = @" { 'management': { 'endpoints': { 'enabled': false, 'sensitive': false, 'path': '/cloudfoundryapplication', 'health' : { 'enabled': true, 'requiredPermissions' : 'NONE' }, 'cloudfoundry': { 'validatecertificates' : true, 'enabled': true } } } }"; var path = TestHelpers.CreateTempFile(appsettings); string directory = Path.GetDirectoryName(path); string fileName = Path.GetFileName(path); ConfigurationBuilder configurationBuilder = new ConfigurationBuilder(); configurationBuilder.SetBasePath(directory); configurationBuilder.AddJsonFile(fileName); var config = configurationBuilder.Build(); var opts = new HealthOptions(config); CloudFoundryOptions cloudOpts = new CloudFoundryOptions(config); Assert.True(cloudOpts.Enabled); Assert.False(cloudOpts.Sensitive); Assert.Equal(string.Empty, cloudOpts.Id); Assert.Equal("/cloudfoundryapplication", cloudOpts.Path); Assert.True(cloudOpts.ValidateCertificates); Assert.True(opts.Enabled); Assert.False(opts.Sensitive); Assert.Equal("health", opts.Id); Assert.Equal("/cloudfoundryapplication/health", opts.Path); Assert.Equal(Permissions.NONE, opts.RequiredPermissions); }
public async void HandleHealthRequestAsync_ReturnsExpected() { var opts = new HealthOptions(); var contribs = new List <IHealthContributor>() { new DiskSpaceContributor() }; var ep = new TestHealthEndpoint(opts, new DefaultHealthAggregator(), contribs); var middle = new HealthEndpointMiddleware(null, ep); var context = CreateRequest("GET", "/health"); await middle.HandleHealthRequestAsync(context); context.Response.Body.Seek(0, SeekOrigin.Begin); StreamReader rdr = new StreamReader(context.Response.Body); string json = await rdr.ReadToEndAsync(); Assert.Equal("{\"status\":\"UNKNOWN\"}", json); }
public async void HealthInvoke_ReturnsExpected() { // arrange var opts = new HealthOptions(); var contribs = new List <IHealthContributor>() { new DiskSpaceContributor() }; var ep = new TestHealthEndpoint(opts, new DefaultHealthAggregator(), contribs); var middle = new HealthEndpointOwinMiddleware(null, ep); var context = OwinTestHelpers.CreateRequest("GET", "/health"); // act var json = await middle.InvokeAndReadResponse(context); // assert Assert.Equal("{\"status\":\"UNKNOWN\"}", json); }
private static bool ShouldUseHealthEndpoint( IOptions <HealthEndpointsHostingOptions> endpointsHostingOptionsAccessor, IOptions <HealthEndpointsOptions> endpointsOptionsAccessor, HealthOptions metricsOptions, HttpContext context) { int?port = null; if (endpointsHostingOptionsAccessor.Value.HealthEndpointPort.HasValue) { port = endpointsHostingOptionsAccessor.Value.HealthEndpointPort.Value; } return(context.Request.Path == endpointsHostingOptionsAccessor.Value.HealthEndpoint && endpointsOptionsAccessor.Value.HealthEndpointEnabled && metricsOptions.Enabled && endpointsHostingOptionsAccessor.Value.HealthEndpoint.IsPresent() && (!port.HasValue || context.Features.Get <IHttpConnectionFeature>()?.LocalPort == port.Value)); }
public void Can_override_option_instance_values_with_key_value_pair_options() { // Arrange var options = new HealthOptions { Enabled = true, }; var keyValuePairs = new Dictionary <string, string> { { "HealthOptions:Enabled", "false" } }; // Act var health = new HealthBuilder().Configuration.Configure(options, keyValuePairs).Build(); // Assert health.Options.Enabled.Should().BeFalse(); }
public IHealthRoot Build() { if (_options == null) { _options = new HealthOptions(); } if (_healthFormatterCollection.Count == 0) { _healthFormatterCollection.Add(new HealthStatusTextOutputFormatter()); } IRunHealthChecks healthCheckRunner; var health = new DefaultHealth(_checks.Values); var defaultMetricsOutputFormatter = _defaultMetricsHealthFormatter ?? _healthFormatterCollection.FirstOrDefault(); if (_options.Enabled && health.Checks.Any()) { healthCheckRunner = new DefaultHealthCheckRunner(health.Checks); } else { healthCheckRunner = new NoOpHealthCheckRunner(); } if (string.IsNullOrWhiteSpace(_options.ApplicationName)) { var entryAssembly = Assembly.GetEntryAssembly(); _options.ApplicationName = entryAssembly?.GetName()?.Name?.Trim(); } return(new HealthRoot( health, _options, _healthFormatterCollection, defaultMetricsOutputFormatter, healthCheckRunner, _healthStatusReporters)); }
public void Application_Start(object sender, EventArgs e) { //Initialize NEP Application NepServiceApplication.Init(); WebApiConfig.Register(GlobalConfiguration.Configuration); // Code that runs on application startup CMS.AMS.ResolverBuilder resolver = new ResolverBuilder(); CurrentRequest.Resolver = resolver.GetResolver(); CurrentRequest.Resolver.AppName = "Global.asax"; IDBAccess m_dbaccess = CurrentRequest.Resolver.Resolve <DBAccess>(); SQLParametersList paramlist = new SQLParametersList(); String QueryStr = "Update Folders set MassOperationStatus = '~FNIU~'"; m_dbaccess.ExecuteNonQuery(DataBases.LogixRT, CommandType.Text, QueryStr, paramlist); //Adding health monitors InitializeHealthMonitors(); HealthOptions.AddHealthMonitors(componentHealthMonitors.ToArray()); }
public void IsHealthRequest_ReturnsExpected() { var opts = new HealthOptions(); var contribs = new List <IHealthContributor>() { new DiskSpaceContributor() }; var ep = new HealthEndpoint(opts, new DefaultHealthAggregator(), contribs); var middle = new HealthEndpointMiddleware(null, ep); var context = CreateRequest("GET", "/health"); Assert.True(middle.IsHealthRequest(context)); var context2 = CreateRequest("PUT", "/health"); Assert.False(middle.IsHealthRequest(context2)); var context3 = CreateRequest("GET", "/badpath"); Assert.False(middle.IsHealthRequest(context3)); }
public void GetStatusCode_ReturnsExpected() { var opts = new HealthOptions(); var contribs = new List <IHealthContributor>() { new DiskSpaceContributor() }; var ep = new HealthEndpoint(opts, new DefaultHealthAggregator(), contribs); Assert.Equal(503, ep.GetStatusCode(new HealthCheckResult { Status = HealthStatus.DOWN })); Assert.Equal(503, ep.GetStatusCode(new HealthCheckResult { Status = HealthStatus.OUT_OF_SERVICE })); Assert.Equal(200, ep.GetStatusCode(new HealthCheckResult { Status = HealthStatus.UP })); Assert.Equal(200, ep.GetStatusCode(new HealthCheckResult { Status = HealthStatus.UNKNOWN })); }
/// <inheritdoc /> public async Task ReportAsync(HealthOptions options, HealthStatus status, CancellationToken cancellationToken = default) { var resetRuns = false; _runs++; if (!_slackOptions.Enabled || !options.Enabled) { Logger.Trace($"Health Status Reporter `{this}` disabled, not reporting."); return; } Logger.Trace($"Health Status Reporter `{this}` reporting health status."); var applicationName = options.ApplicationName; if (Uri.TryCreate(applicationName, UriKind.Absolute, out var appUri)) { applicationName = $"<{appUri}|{appUri}>"; } var slackMessage = new SlackPayload { Text = $"*{applicationName} Unhealthy*", Channel = _slackOptions.Channel, UserName = _slackOptions.Username, IconEmoji = string.IsNullOrWhiteSpace(_slackOptions.EmojiIcon) ? DefaultEmojiIcon : _slackOptions.EmojiIcon }; var newUnhealthyChecks = status.Results.Where(r => r.Check.Status == HealthCheckStatus.Unhealthy && !LastUnhealthyCheckCache.Contains(r.Name)).ToList(); if (newUnhealthyChecks.Any()) { AddHealthAttachments(HealthCheckStatus.Unhealthy, newUnhealthyChecks, slackMessage); } if (_runs > _slackOptions.RunsBeforeReportExistingFailures) { resetRuns = true; var existingUnHealthyChecks = status.Results .Where(r => r.Check.Status == HealthCheckStatus.Unhealthy && LastUnhealthyCheckCache.Contains(r.Name) && newUnhealthyChecks.All(c => c.Name != r.Name)) .ToList(); if (existingUnHealthyChecks.Any()) { AddHealthAttachments(HealthCheckStatus.Unhealthy, existingUnHealthyChecks, slackMessage, reFailure: true); } } if (_slackOptions.AlertOnDegradedChecks) { var degradedChecks = status.Results.Where(r => r.Check.Status == HealthCheckStatus.Degraded && !LastDegradedCheckCache.Contains(r.Name)).ToList(); if (degradedChecks.Any()) { AddHealthAttachments(HealthCheckStatus.Degraded, degradedChecks, slackMessage); } if (_runs > _slackOptions.RunsBeforeReportExistingFailures) { resetRuns = true; var existingDegradedChecks = status.Results .Where(r => r.Check.Status == HealthCheckStatus.Degraded && LastDegradedCheckCache.Contains(r.Name) && degradedChecks.All(c => c.Name != r.Name)) .ToList(); if (existingDegradedChecks.Any()) { AddHealthAttachments(HealthCheckStatus.Degraded, existingDegradedChecks, slackMessage, reFailure: true); } } } if (resetRuns) { _runs = 0; } if (slackMessage.Attachments.Any()) { try { var response = await _httpClient.PostAsync(_slackOptions.WebhookUrl, new JsonContent(slackMessage), cancellationToken); if (response.IsSuccessStatusCode) { Logger.Trace($"Health Status Reporter `{this}` successfully reported health status."); } else { Logger.Error($"Health Status Reporter `{this}` failed to reported health status with status code: `{response.StatusCode}` and reason phrase: `{response.ReasonPhrase}`"); } } catch (Exception ex) { Logger.Error(ex, $"Health Status Reporter `{this}` failed to reported health status"); } } await AlertStatusChangeChecks(status, applicationName, cancellationToken); }
private static void HealthConfiger(HealthOptions options) { options.Enabled = true; }
/// <inheritdoc /> public Task ReportAsync(HealthOptions options, HealthStatus status, CancellationToken cancellationToken = default) { Console.WriteLine($"{options.ApplicationName} - Overall status: {status.Status}"); return(Task.CompletedTask); }