/// <summary>
        /// Processes a request.
        /// </summary>
        /// <param name="httpContext"></param>
        /// <returns></returns>
        public async Task InvokeAsync(HttpContext httpContext)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException(nameof(httpContext));
            }

            // Get results
            var result = await _healthCheckService.CheckHealthAsync(_checks, httpContext.RequestAborted);

            // Map status to response code - this is customizable via options.
            if (!_healthCheckOptions.ResultStatusCodes.TryGetValue(result.Status, out var statusCode))
            {
                var message =
                    $"No status code mapping found for {nameof(HealthCheckStatus)} value: {result.Status}." +
                    $"{nameof(HealthCheckOptions)}.{nameof(HealthCheckOptions.ResultStatusCodes)} must contain" +
                    $"an entry for {result.Status}.";

                throw new InvalidOperationException(message);
            }

            httpContext.Response.StatusCode = statusCode;

            if (_healthCheckOptions.ResponseWriter != null)
            {
                await _healthCheckOptions.ResponseWriter(httpContext, result);
            }
        }
예제 #2
0
        public async Task Invoke(HttpContext context)
        {
            var connInfo = context.Features.Get <IHttpConnectionFeature>();

            if (connInfo.LocalPort == _healthCheckPort)
            {
                var healthy = await _checkupService.CheckHealthAsync();

                if (healthy)
                {
                    await context.Response.WriteAsync("HealthCheck: OK");
                }
                else
                {
                    context.Response.StatusCode = 502;
                    context.Response.Headers.Add("content-type", "application/json");
                    await context.Response.WriteAsync(JsonConvert.SerializeObject(_checkupService.CheckResults));
                }
                return;
            }
            else
            {
                await _next.Invoke(context);
            }
        }
        public async Task Run([TimerTrigger("%HealthCheckTimerCron%")] TimerInfo myTimer, ILogger log)
        {
            log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");

            var healthCheckResult = await _healthCheckService.CheckHealthAsync(new HealthCheckContext());

            log.LogInformation($"HealthCheck Result: {healthCheckResult.Status}");
        }
        public HealthCheckResponse Execute()
        {
            var result = _healthCheckService.CheckHealthAsync().Result;

            bool success = result.CheckStatus == CheckStatus.Healthy;

            return(new HealthCheckResponse(success, result.Description));
        }
예제 #5
0
        public async Task <IActionResult> Index()
        {
            var timedTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(3));
            var stopwatch        = Stopwatch.StartNew();
            var checkResult      = await _healthCheck.CheckHealthAsync(timedTokenSource.Token);

            return(Ok(checkResult));
        }
예제 #6
0
        private static Func <IHealthCheckService> GetHealthCheckServiceFactoryFor(Func <Task> checkHealthAsync)
        {
            IHealthCheckService mockHealthCheckService = Substitute.For <IHealthCheckService>();

            mockHealthCheckService.CheckHealthAsync().Returns(checkHealthAsync());
            IHealthCheckService HealthCheckServiceFactory() => mockHealthCheckService;

            return(HealthCheckServiceFactory);
        }
예제 #7
0
        public async Task Invoke(HttpContext context)
        {
            if (context.Request.Path != _options.Path)
            {
                await _next(context);

                return;
            }

            if (_options.AuthorizationPolicy != null)
            {
                var principal = await SecurityHelper.GetUserPrincipal(context, _options.AuthorizationPolicy);

                if (!await _authorizationService.AuthorizeAsync(principal, context, _options.AuthorizationPolicy))
                {
                    _logger.AuthorizationFailed();
                    await _next(context);

                    return;
                }
            }

            var response = context.Response;

            // Canary response must not be cached
            response.Headers[HeaderNames.CacheControl] = "no-cache";
            response.Headers[HeaderNames.Pragma]       = "no-cache";
            response.Headers[HeaderNames.Expires]      = "-1";
            var serverSwitchContext = new ServerSwitchContext(context);
            await _serverSwitch?.CheckServerStateAsync(serverSwitchContext);

            if (serverSwitchContext.ServerDisabled)
            {
                _logger.ServerDisabled();
                response.StatusCode = StatusCodes.Status503ServiceUnavailable;
                response.WriteRetryAfterHeader(serverSwitchContext.RetryAfter);
            }
            else if (_options.EnableHealthCheck)
            {
                var healthCheckResponse = await _healthService.CheckHealthAsync(_defaultPolicy);

                if (healthCheckResponse.HasCriticalErrors)
                {
                    _logger.CanaryFailed(healthCheckResponse.Errors);
                    response.StatusCode = StatusCodes.Status503ServiceUnavailable;
                    response.WriteRetryAfterHeader(healthCheckResponse.RetryAfter);
                }
                else
                {
                    _logger.CanarySucceeded();
                    response.StatusCode = StatusCodes.Status200OK;
                }
            }
        }
예제 #8
0
        public async Task <IActionResult> Index()
        {
            var result = await healthCheckService.CheckHealthAsync();

            var data = new HealthStatusViewModel(result.CheckStatus);

            foreach (var item in result.Results)
            {
                data.AddResult(item.Key, item.Value);
            }

            return(View(data));
        }
예제 #9
0
        public async Task <IActionResult> Index()
        {
            var result = await _healthCheckSvc.CheckHealthAsync();

            var data = new HealthStatusViewModel(result.CheckStatus);

            foreach (var checkResult in result.Results)
            {
                data.AddResult(checkResult.Key, checkResult.Value);
            }

            return(View(data));
        }
예제 #10
0
        public async Task <IActionResult> Index()
        {
            var healthCheckResult = await _healthCheckService.CheckHealthAsync();

            var checkStatusdata = new HealthStatusViewModel(healthCheckResult.CheckStatus);

            foreach (var result in healthCheckResult.Results)
            {
                checkStatusdata.AddResult(result.Key, result.Value);
            }

            ViewBag.RefreshSeconds = 60;
            return(View(checkStatusdata));
        }
        public async Task <HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = new CancellationToken())
        {
            var healthStatus = await _healthCheckStorage.GetCurrentStatusAsync(ServiceName);

            if (healthStatus == null || healthStatus.DateTime + CheckPeriod < DateTime.UtcNow)
            {
                healthStatus = await _healthCheckService.CheckHealthAsync();

                await _healthCheckStorage.CheckedAsync(ServiceName, healthStatus);
            }
            return(healthStatus.Status switch
            {
                HealthStatus.Healthy => HealthCheckResult.Healthy(),
                _ => HealthCheckResult.Unhealthy(healthStatus.ErrorMessage)
            });
예제 #12
0
        /// <summary>
        /// Process an individual request.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task InvokeAsync(HttpContext context)
        {
            if (context.Request.Path == _healthCheckOptions.Path)
            {
                // Get results
                var result = await _healthCheckService.CheckHealthAsync(context.RequestAborted);

                // Map status to response code
                switch (result.Status)
                {
                case HealthCheckStatus.Failed:
                    context.Response.StatusCode = StatusCodes.Status500InternalServerError;
                    break;

                case HealthCheckStatus.Unhealthy:
                    context.Response.StatusCode = StatusCodes.Status503ServiceUnavailable;
                    break;

                case HealthCheckStatus.Degraded:
                    // Degraded doesn't mean unhealthy so we return 200, but the content will contain more details
                    context.Response.StatusCode = StatusCodes.Status200OK;
                    break;

                case HealthCheckStatus.Healthy:
                    context.Response.StatusCode = StatusCodes.Status200OK;
                    break;

                default:
                    // This will only happen when we change HealthCheckStatus and we don't update this.
                    Debug.Fail($"Unrecognized HealthCheckStatus value: {result.Status}");
                    throw new InvalidOperationException($"Unrecognized HealthCheckStatus value: {result.Status}");
                }

                // Render results to JSON
                var json = new JObject(
                    new JProperty("status", result.Status.ToString()),
                    new JProperty("results", new JObject(result.Results.Select(pair =>
                                                                               new JProperty(pair.Key, new JObject(
                                                                                                 new JProperty("status", pair.Value.Status.ToString()),
                                                                                                 new JProperty("description", pair.Value.Description),
                                                                                                 new JProperty("data", new JObject(pair.Value.Data.Select(p => new JProperty(p.Key, p.Value))))))))));
                await context.Response.WriteAsync(json.ToString(Formatting.None));
            }
            else
            {
                await _next(context);
            }
        }
예제 #13
0
        public async Task <IActionResult> Index()
        {
            string result;

            if (await _healthCheck.CheckHealthAsync())
            {
                result = "healthy";
            }
            else
            {
                result = "unhealthy!";
            }

            ViewData["AppStatus"] = result;

            return(View());
        }
예제 #14
0
        public async Task <IActionResult> Index()
        {
            string result;

            if (await _healthCheck.CheckHealthAsync())
            {
                result = "healthy";
            }
            else
            {
                result = "unhealthy!";
            }

            ViewData["Results"]   = JsonConvert.SerializeObject(_healthCheck.CheckResults);
            ViewData["AppStatus"] = result;

            return(View());
        }
예제 #15
0
        public async Task Invoke(HttpContext context)
        {
            if (IsHealthCheckRequest(context))
            {
                var timeoutTokenSource = new CancellationTokenSource(_timeout);
                var result             = await _service.CheckHealthAsync(timeoutTokenSource.Token);

                var status = result.CheckStatus;

                if (status != CheckStatus.Healthy)
                {
                    context.Response.StatusCode = 503;
                }

                context.Response.Headers.Add("content-type", "application/json");
                await context.Response.WriteAsync(JsonConvert.SerializeObject(new { status = status.ToString() }));
            }
            else
            {
                await _next.Invoke(context);
            }
        }
예제 #16
0
        public async Task <IActionResult> Get()
        {
            //run a single Health Check it makes a call to the drone to check if everything is fine
            //await means it is an async action.

            /*
             * We get back a CompositeHealthCheckResult which is a summary of the health check
             * that we registered in theAddHealthChecks method in our Startup class.
             * That class has a CheckStatus property that has 4 options (Healthy, Unhealthy, Warning, and Unknown).
             * We have chosen to check if the Drone is Healthy
             *
             *
             */
            var healthCheckResult = await _healthCheckService.CheckHealthAsync();

            if (healthCheckResult.CheckStatus == CheckStatus.Healthy)
            {
                return(new JsonResult(new { Drone = "I am a healthy drone 1" }));
            }


            var droneDown = healthCheckResult.CheckStatus != CheckStatus.Healthy;

            //if the drone does not return 200 OK.
            if (droneDown)
            {
                /*
                 * Ring the alarm here.
                 */

                return(new JsonResult(new { Error = "Drone 1 is not responding" })
                {
                    StatusCode = StatusCodes.Status500InternalServerError
                });
            }

            //returns 200 OK
            return(Ok());
        }
예제 #17
0
        public async Task <IActionResult> GetStatus()
        {
            CompositeHealthCheckResult healthCheckResult = await _healthCheckService.CheckHealthAsync();

            bool somethingIsWrong = healthCheckResult.CheckStatus != CheckStatus.Healthy;

            if (somethingIsWrong)
            {
                // healthCheckResult has a .Description property, but that shows the description of all health checks.
                // Including the successful ones, so let's filter those out
                var failedHealthCheckDescriptions = healthCheckResult.Results.Where(r => r.Value.CheckStatus != CheckStatus.Healthy)
                                                    .Select(r => r.Value.Description)
                                                    .ToList();

                // return a 500 with JSON containing the Results of the Health Check
                return(new JsonResult(new { Status = healthCheckResult.CheckStatus, Errors = failedHealthCheckDescriptions })
                {
                    StatusCode = StatusCodes.Status503ServiceUnavailable
                });
            }

            return(Ok(new { Status = healthCheckResult.CheckStatus }));
        }
        public async Task <IActionResult> Get()
        {
            var healthCheckResult = await _healthCheckService.CheckHealthAsync();

            if (healthCheckResult.CheckStatus == CheckStatus.Healthy)
            {
                return(new JsonResult(new { Drone = "I am a healthy drone" }));
            }

            var droneDown = healthCheckResult.CheckStatus != CheckStatus.Healthy;

            if (droneDown)
            {
                var failedHealthCheckDescriptions = healthCheckResult.Results.Where(r => r.Value.CheckStatus != CheckStatus.Healthy)
                                                    .Select(r => r.Value.Data.Values.First())
                                                    .ToList();
                return(new JsonResult(new { Error = "Drone 1 is not responding" })
                {
                    StatusCode = StatusCodes.Status500InternalServerError
                });
            }

            return(Ok());
        }
예제 #19
0
        public async Task Invoke(HttpContext context)
        {
            var connInfo = context.Features.Get <IHttpConnectionFeature>();

            if (connInfo.LocalPort == _healthCheckPort)
            {
                var healthy = await _checkupService.CheckHealthAsync();

                if (healthy)
                {
                    await context.Response.WriteAsync("HealthCheck: OK");
                }
                else
                {
                    context.Response.StatusCode = 502;
                    await context.Response.WriteAsync("HealthStatus: Unhealthy");
                }
                return;
            }
            else
            {
                await _next.Invoke(context);
            }
        }
예제 #20
0
        private Task <CompositeHealthCheckResult> GetHealthCheckResult()
        {
            var timeoutTokenSource = new CancellationTokenSource(5000);

            return(_service.CheckHealthAsync(timeoutTokenSource.Token));
        }
예제 #21
0
        private void Heartbeat(List <AgentServiceRegistration> registrations)
        {
            if (_serviceConfig.SERVICE_CHECK_TTL.HasValue && !string.IsNullOrEmpty(_serviceConfig.SERVICE_CHECK_INTERVAL))
            {
                try
                {
                    var timer = new System.Timers.Timer((double)(int.Parse(_serviceConfig.SERVICE_CHECK_INTERVAL) * 1000));
                    timer.Elapsed += async delegate
                    {
                        try
                        {
                            var result = await _healthCheckService.CheckHealthAsync();

                            var status = result.CheckStatus;

                            if (status == CheckStatus.Healthy)
                            {
                                foreach (var registration in registrations)
                                {
                                    try
                                    {
                                        await _client.Agent.PassTTL("service:" + registration.ID, result.Description, default(CancellationToken));

                                        LogDebug("service " + registration.ID + " ttl passing", Array.Empty <object>());
                                    }
                                    catch (Exception ex)
                                    {
                                        LogWarning(ex, ex.Message);
                                    }
                                }
                            }
                            else if (status == CheckStatus.Warning)
                            {
                                foreach (var registration in registrations)
                                {
                                    try
                                    {
                                        await _client.Agent.WarnTTL("service:" + registration.ID, result.Description, default(CancellationToken));

                                        LogDebug("service " + registration.ID + " ttl warn", Array.Empty <object>());
                                    }
                                    catch (Exception ex)
                                    {
                                        LogWarning(ex, ex.Message);
                                    }
                                }
                            }
                            else
                            {
                                foreach (var registration in registrations)
                                {
                                    try
                                    {
                                        await _client.Agent.FailTTL("service:" + registration.ID, result.Description, default(CancellationToken));

                                        LogDebug("service " + registration.ID + " ttl failed", Array.Empty <object>());
                                    }
                                    catch (Exception ex)
                                    {
                                        LogWarning(ex, ex.Message);
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            LogError(ex, ex.Message);
                        }
                    };
                    timer.Start();
                }
                catch (Exception ex)
                {
                    LogError(ex, ex.Message);
                }
            }
        }
        public static Task <CompositeHealthCheckResult> CheckHealthAsync(this IHealthCheckService service)
        {
            Guard.ArgumentNotNull(nameof(service), service);

            return(service.CheckHealthAsync(CheckStatus.Unhealthy, CancellationToken.None));
        }
예제 #23
0
        public async Task <IHttpActionResult> HealthCheckDiagnostics()
        {
            var result = await healthCheckService.CheckHealthAsync(default(CancellationToken));

            return(EnforceStatusPolicyResult(result));
        }
        public async void Heartbeat()
        {
            if (registerCompleted)
            {
                var result = await _healthCheckService.CheckHealthAsync();

                var status = result.CheckStatus;


                try
                {
                    foreach (var registration in _registrations)
                    {
                        if (registration.Checks.Length > 1)
                        {
                            for (int i = 0; i < registration.Checks.Length; i++)
                            {
                                if (registration.Checks[i].TTL.HasValue)
                                {
                                    try
                                    {
                                        if (status == CheckStatus.Healthy)
                                        {
                                            await _client.Agent.PassTTL($"service:{registration.ID}:{i + 1}", "passing", default(CancellationToken));


                                            LogDebug("service " + registration.ID + " ttl passing", Array.Empty <object>());
                                        }
                                        else if (status == CheckStatus.Warning)
                                        {
                                            await _client.Agent.WarnTTL($"service:{registration.ID}:{i + 1}", "passing", default(CancellationToken));


                                            LogDebug("service " + registration.ID + " ttl warn", Array.Empty <object>());
                                        }
                                        else
                                        {
                                            await _client.Agent.FailTTL($"service:{registration.ID}:{i + 1}", "passing", default(CancellationToken));


                                            LogDebug("service " + registration.ID + " ttl warn", Array.Empty <object>());
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        LogWarning(ex, ex.Message);
                                    }
                                }
                            }
                        }
                        else if (registration.Checks.Length == 1)
                        {
                            if (registration.Checks[0].TTL.HasValue)
                            {
                                try
                                {
                                    if (status == CheckStatus.Healthy)
                                    {
                                        await _client.Agent.PassTTL($"service:{registration.ID}", "passing", default(CancellationToken));


                                        LogDebug("service " + registration.ID + " ttl passing", Array.Empty <object>());
                                    }
                                    else if (status == CheckStatus.Warning)
                                    {
                                        await _client.Agent.WarnTTL($"service:{registration.ID}", "passing", default(CancellationToken));


                                        LogDebug("service " + registration.ID + " ttl warn", Array.Empty <object>());
                                    }
                                    else
                                    {
                                        await _client.Agent.FailTTL($"service:{registration.ID}", "passing", default(CancellationToken));


                                        LogDebug("service " + registration.ID + " ttl warn", Array.Empty <object>());
                                    }
                                }
                                catch (Exception ex)
                                {
                                    LogWarning(ex, ex.Message);
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogError(ex, ex.Message);
                }
            }
        }
        public static Task <CompositeHealthCheckResult> CheckHealthAsync(this IHealthCheckService service, CheckStatus partiallyHealthyStatus, CancellationToken cancellationToken)
        {
            Guard.ArgumentNotNull(nameof(service), service);

            return(service.CheckHealthAsync(partiallyHealthyStatus, cancellationToken));
        }
        public async Task Invoke(HttpContext context)
        {
            PathString subpath;

            if (!context.Request.Path.StartsWithSegments(_options.Path, out subpath))
            {
                await _next(context);

                return;
            }

            var policyName = subpath.ToUriComponent().Trim('/');

            if (policyName.Length == 0)
            {
                policyName = Constants.DefaultPolicy;
            }

            if (_options.AuthorizationPolicy != null)
            {
                var principal = await SecurityHelper.GetUserPrincipal(context, _options.AuthorizationPolicy);

                if (!await _authorizationService.AuthorizeAsync(principal, context, _options.AuthorizationPolicy))
                {
                    _logger.AuthorizationFailed();
                    await _next(context);

                    return;
                }
            }

            HealthCheckPolicy policy = _policyProvider.GetPolicy(policyName);

            if (policy == null)
            {
                _logger.InvalidPolicy(policyName);
                await _next(context);

                return;
            }

            var response            = context.Response;
            var healthCheckResponse = await _healthService.CheckHealthAsync(policy);

            if (healthCheckResponse.HasErrors)
            {
                _logger.HealthCheckFailed(healthCheckResponse.Errors);
                if (healthCheckResponse.HasCriticalErrors)
                {
                    response.StatusCode = StatusCodes.Status503ServiceUnavailable;
                    response.WriteRetryAfterHeader(healthCheckResponse.RetryAfter);
                }
            }
            else
            {
                _logger.HealthCheckSucceeded();
                response.StatusCode = StatusCodes.Status200OK;
            }

            if (_options.SendResults && !HttpMethods.IsHead(context.Request.Method))
            {
                response.ContentType = ApplicationJson;
                using (var writer = new HttpResponseStreamWriter(response.Body, Encoding.UTF8, 1024, _bytePool, _charPool))
                {
                    using (var jsonWriter = new JsonTextWriter(writer))
                    {
                        jsonWriter.ArrayPool   = _jsonCharPool;
                        jsonWriter.CloseOutput = false;

                        _jsonSerializer.Serialize(jsonWriter, healthCheckResponse.Results);
                    }
                }
            }
        }
예제 #27
0
 public async Task <CompositeHealthCheckResult> Get() => await _healthCheck.CheckHealthAsync();
예제 #28
0
 public async Task <IActionResult> GetStats([FromServices] IHealthCheckService service)
 {
     return(Json(await service.CheckHealthAsync()));
 }
예제 #29
0
 public ActionResult Result()
 {
     return(Ok(_healthCheck.CheckHealthAsync().Result));
 }
예제 #30
0
        public async Task <IActionResult> StatusHealthCheck()
        {
            var healthCheckResult = await _healthCheckService.CheckHealthAsync(Request.GetCancellationToken()).ConfigureAwait(false);

            return(Ok(healthCheckResult));
        }