public async Task <IActionResult> RunHealthzAsync() { // get list of genres as list of string _logger.LogInformation(nameof(RunHealthzAsync)); HealthCheckResult res = await RunCosmosHealthCheck().ConfigureAwait(false); HttpContext.Items.Add(typeof(HealthCheckResult).ToString(), res); return(new ObjectResult(IetfCheck.ToIetfStatus(res.Status)) { StatusCode = res.Status == HealthStatus.Unhealthy ? (int)System.Net.HttpStatusCode.ServiceUnavailable : (int)System.Net.HttpStatusCode.OK }); }
/// <summary> /// Write the health check results as json /// </summary> /// <param name="httpContext">HttpContext</param> /// <param name="healthReport">HealthReport</param> /// <returns>Task</returns> public static Task IetfResponseWriter(HttpContext httpContext, HealthReport healthReport) { if (httpContext == null) { throw new ArgumentNullException(nameof(httpContext)); } if (healthReport == null) { throw new ArgumentNullException(nameof(healthReport)); } // create the dictionaries Dictionary <string, object> result = new Dictionary <string, object>(); Dictionary <string, object> checks = new Dictionary <string, object>(); // add header values result.Add("status", IetfCheck.ToIetfStatus(healthReport.Status)); result.Add("serviceId", CosmosHealthCheck.ServiceId); result.Add("description", CosmosHealthCheck.Description); // add all the entries foreach (HealthReportEntry e in healthReport.Entries.Values) { // add all the data elements foreach (KeyValuePair <string, object> d in e.Data) { // transform HealthzCheck into IetfCheck if (d.Value is HealthzCheck r) { // add to checks dictionary checks.Add(d.Key, new IetfCheck(r)); } else { // add to the main dictionary result.Add(d.Key, d.Value); } } } // add the checks to the dictionary result.Add("checks", checks); // write the json httpContext.Response.ContentType = "application/health+json"; httpContext.Response.StatusCode = healthReport.Status == HealthStatus.Unhealthy ? (int)System.Net.HttpStatusCode.ServiceUnavailable : (int)System.Net.HttpStatusCode.OK; return(httpContext.Response.WriteAsync(JsonSerializer.Serialize(result, jsonOptions))); }
/// <summary> /// Log the healthz results for degraded and unhealthy /// </summary> /// <param name="context">HttpContext</param> /// <param name="duration">double</param> /// <returns></returns> private static bool LogHealthzHandled(HttpContext context, double duration) { if (context == null) { throw new ArgumentNullException(nameof(context)); } // check if there is a HealthCheckResult item if (context.Items.Count > 0 && context.Items.ContainsKey(typeof(HealthCheckResult).ToString())) { var hcr = (HealthCheckResult)context.Items[typeof(HealthCheckResult).ToString()]; // log not healthy requests if (hcr.Status != HealthStatus.Healthy) { string log = string.Empty; // build the log message log += string.Format(CultureInfo.InvariantCulture, $"{IetfCheck.ToIetfStatus(hcr.Status)}\t{duration,6:0}\t{context.Request.Headers[_ipHeader]}\t{GetPathAndQuerystring(context.Request)}\n"); // add each not healthy check to the log message foreach (var d in hcr.Data.Values) { if (d is HealthzCheck h && h.Status != HealthStatus.Healthy) { log += string.Format(CultureInfo.InvariantCulture, $"{IetfCheck.ToIetfStatus(h.Status)}\t{(long)h.Duration.TotalMilliseconds,6}\t{context.Request.Headers[_ipHeader]}\t{h.Endpoint}\t({h.TargetDuration.TotalMilliseconds,1:0})\n"); } } if (hcr.Exception != null) { log += "HealthCheckException\n"; log += hcr.Exception.ToString() + "\n"; } // write the log message Console.Write(log); // done logging this request return(true); } } // keep processing return(false); }