diff --git a/samples/HealthChecksSample/CustomWriterStartup.cs b/samples/HealthChecksSample/CustomWriterStartup.cs
index 87e58b7b7d..97003068fc 100644
--- a/samples/HealthChecksSample/CustomWriterStartup.cs
+++ b/samples/HealthChecksSample/CustomWriterStartup.cs
@@ -6,6 +6,8 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
namespace HealthChecksSample
{
@@ -45,23 +47,16 @@ namespace HealthChecksSample
private static Task WriteResponse(HttpContext httpContext, CompositeHealthCheckResult result)
{
- httpContext.Response.ContentType = "text/html";
- return httpContext.Response.WriteAsync($@"
-
-
-
- Everything is {result.Status}
-
-
-
- | Name | Status |
-
-
- {string.Join("", result.Results.Select(kvp => $"| {kvp.Key} | {kvp.Value.Status} |
"))}
-
-
-
-");
+ httpContext.Response.ContentType = "application/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))))))))));
+ return httpContext.Response.WriteAsync(json.ToString(Formatting.Indented));
}
}
}
diff --git a/samples/HealthChecksSample/DetailedStatusStartup.cs b/samples/HealthChecksSample/DetailedStatusStartup.cs
deleted file mode 100644
index 76475c5db5..0000000000
--- a/samples/HealthChecksSample/DetailedStatusStartup.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Diagnostics.HealthChecks;
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Diagnostics.HealthChecks;
-
-namespace HealthChecksSample
-{
- // Pass in `--scenario detailed` at the command line to run this sample.
- public class DetailedStatusStartup
- {
- public void ConfigureServices(IServiceCollection services)
- {
- // Registers required services for health checks
- services
- .AddHealthChecks()
-
- // Registers a custom health check, in this case it will execute an
- // inline delegate.
- .AddCheck("GC Info", () =>
- {
- // This example will report degraded status if the application is using
- // more than 1gb of memory.
- //
- // Additionally we include some GC info in the reported diagnostics.
- var allocated = GC.GetTotalMemory(forceFullCollection: false);
- var data = new Dictionary()
- {
- { "Allocated", allocated },
- { "Gen0Collections", GC.CollectionCount(0) },
- { "Gen1Collections", GC.CollectionCount(1) },
- { "Gen2Collections", GC.CollectionCount(2) },
- };
-
- // Report degraded status if the allocated memory is >= 1gb (in bytes)
- var status = allocated >= 1024 * 1024 * 1024 ? HealthCheckStatus.Degraded : HealthCheckStatus.Healthy;
-
- return Task.FromResult(new HealthCheckResult(
- status,
- exception: null,
- description: "reports degraded status if allocated bytes >= 1gb",
- data: data));
- });
- }
-
- public void Configure(IApplicationBuilder app, IHostingEnvironment env)
- {
- // This will register the health checks middleware at the URL /health
- //
- // This example overrides the ResponseWriter to include a detailed
- // status as JSON. Use this response writer (or create your own) to include
- // detailed diagnostic information for use by a monitoring system.
- app.UseHealthChecks("/health", new HealthCheckOptions()
- {
- ResponseWriter = HealthCheckResponseWriters.WriteDetailedJson,
- });
-
- app.Run(async (context) =>
- {
- await context.Response.WriteAsync("Go to /health to see the health status");
- });
- }
- }
-}
diff --git a/samples/HealthChecksSample/GCInfoHealthCheck.cs b/samples/HealthChecksSample/GCInfoHealthCheck.cs
index 644fdb0a32..f37ade8980 100644
--- a/samples/HealthChecksSample/GCInfoHealthCheck.cs
+++ b/samples/HealthChecksSample/GCInfoHealthCheck.cs
@@ -7,7 +7,7 @@ using Microsoft.Extensions.Diagnostics.HealthChecks;
namespace HealthChecksSample
{
// This is an example of a custom health check that implements IHealthCheck.
- // This is the same core logic as the DetailedStatusStartup example.
+ //
// See CustomWriterStartup to see how this is registered.
public class GCInfoHealthCheck : IHealthCheck
{
diff --git a/samples/HealthChecksSample/HealthChecksSample.csproj b/samples/HealthChecksSample/HealthChecksSample.csproj
index 2f3c0e6aaa..c8a2fded73 100644
--- a/samples/HealthChecksSample/HealthChecksSample.csproj
+++ b/samples/HealthChecksSample/HealthChecksSample.csproj
@@ -11,6 +11,7 @@
+
diff --git a/samples/HealthChecksSample/LivenessProbeStartup.cs b/samples/HealthChecksSample/LivenessProbeStartup.cs
index d7645b5f0e..3a4078759f 100644
--- a/samples/HealthChecksSample/LivenessProbeStartup.cs
+++ b/samples/HealthChecksSample/LivenessProbeStartup.cs
@@ -48,12 +48,7 @@ namespace HealthChecksSample
// The readiness check uses all of the registered health checks (default)
- app.UseHealthChecks("/health/ready", new HealthCheckOptions()
- {
- // This sample is using detailed status to make more apparent which checks are being run - any
- // output format will work with liveness and readiness checks.
- ResponseWriter = HealthCheckResponseWriters.WriteDetailedJson,
- });
+ app.UseHealthChecks("/health/ready");
// The liveness check uses an 'identity' health check that always returns healty
app.UseHealthChecks("/health/live", new HealthCheckOptions()
@@ -63,10 +58,6 @@ namespace HealthChecksSample
{
"identity",
},
-
- // This sample is using detailed status to make more apparent which checks are being run - any
- // output format will work with liveness and readiness checks.
- ResponseWriter = HealthCheckResponseWriters.WriteDetailedJson,
});
app.Run(async (context) =>
diff --git a/samples/HealthChecksSample/Program.cs b/samples/HealthChecksSample/Program.cs
index 4d9455ed2d..b4e8874f22 100644
--- a/samples/HealthChecksSample/Program.cs
+++ b/samples/HealthChecksSample/Program.cs
@@ -16,7 +16,6 @@ namespace HealthChecksSample
{
{ "", typeof(BasicStartup) },
{ "basic", typeof(BasicStartup) },
- { "detailed", typeof(DetailedStatusStartup) },
{ "writer", typeof(CustomWriterStartup) },
{ "liveness", typeof(LivenessProbeStartup) },
};
diff --git a/src/Microsoft.AspNetCore.Diagnostics.HealthChecks/Builder/HealthCheckApplicationBuilderExtensions.cs b/src/Microsoft.AspNetCore.Diagnostics.HealthChecks/Builder/HealthCheckApplicationBuilderExtensions.cs
index f1f47b3ba5..e6239a3488 100644
--- a/src/Microsoft.AspNetCore.Diagnostics.HealthChecks/Builder/HealthCheckApplicationBuilderExtensions.cs
+++ b/src/Microsoft.AspNetCore.Diagnostics.HealthChecks/Builder/HealthCheckApplicationBuilderExtensions.cs
@@ -20,7 +20,13 @@ namespace Microsoft.AspNetCore.Builder
/// The path on which to provide health check status.
/// A reference to the after the operation has completed.
///
- /// The health check middleware will use default settings other than the provided .
+ ///
+ /// This method will use to
+ /// listen to health checks requests on the specified URL path.
+ ///
+ ///
+ /// The health check middleware will use default settings from .
+ ///
///
public static IApplicationBuilder UseHealthChecks(this IApplicationBuilder app, PathString path)
{
@@ -44,6 +50,12 @@ namespace Microsoft.AspNetCore.Builder
/// The path on which to provide health check status.
/// A used to configure the middleware.
/// A reference to the after the operation has completed.
+ ///
+ ///
+ /// This method will use to
+ /// listen to health checks requests on the specified URL path.
+ ///
+ ///
public static IApplicationBuilder UseHealthChecks(this IApplicationBuilder app, PathString path, HealthCheckOptions options)
{
if (app == null)
diff --git a/src/Microsoft.AspNetCore.Diagnostics.HealthChecks/HealthCheckResponseWriters.cs b/src/Microsoft.AspNetCore.Diagnostics.HealthChecks/HealthCheckResponseWriters.cs
index 95ddf00ac8..a74072f63f 100644
--- a/src/Microsoft.AspNetCore.Diagnostics.HealthChecks/HealthCheckResponseWriters.cs
+++ b/src/Microsoft.AspNetCore.Diagnostics.HealthChecks/HealthCheckResponseWriters.cs
@@ -1,56 +1,18 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-using System;
-using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Diagnostics.HealthChecks;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
namespace Microsoft.AspNetCore.Diagnostics.HealthChecks
{
- public static class HealthCheckResponseWriters
+ internal static class HealthCheckResponseWriters
{
public static Task WriteMinimalPlaintext(HttpContext httpContext, CompositeHealthCheckResult result)
{
- if (httpContext == null)
- {
- throw new ArgumentNullException(nameof(httpContext));
- }
-
- if (result == null)
- {
- throw new ArgumentNullException(nameof(result));
- }
-
httpContext.Response.ContentType = "text/plain";
return httpContext.Response.WriteAsync(result.Status.ToString());
}
-
- public static Task WriteDetailedJson(HttpContext httpContext, CompositeHealthCheckResult result)
- {
- if (httpContext == null)
- {
- throw new ArgumentNullException(nameof(httpContext));
- }
-
- if (result == null)
- {
- throw new ArgumentNullException(nameof(result));
- }
-
- httpContext.Response.ContentType = "application/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))))))))));
- return httpContext.Response.WriteAsync(json.ToString(Formatting.Indented));
- }
}
}
diff --git a/src/Microsoft.AspNetCore.Diagnostics.HealthChecks/Microsoft.AspNetCore.Diagnostics.HealthChecks.csproj b/src/Microsoft.AspNetCore.Diagnostics.HealthChecks/Microsoft.AspNetCore.Diagnostics.HealthChecks.csproj
index 76a24a4c47..b7dd85d4a6 100644
--- a/src/Microsoft.AspNetCore.Diagnostics.HealthChecks/Microsoft.AspNetCore.Diagnostics.HealthChecks.csproj
+++ b/src/Microsoft.AspNetCore.Diagnostics.HealthChecks/Microsoft.AspNetCore.Diagnostics.HealthChecks.csproj
@@ -1,4 +1,4 @@
-
+
ASP.NET Core middleware for returning the results of Health Checks in the application
@@ -16,7 +16,6 @@
-
diff --git a/test/Microsoft.AspNetCore.Diagnostics.HealthChecks.Tests/HealthCheckMiddlewareSampleTest.cs b/test/Microsoft.AspNetCore.Diagnostics.HealthChecks.Tests/HealthCheckMiddlewareSampleTest.cs
index 4e716ed3b9..bffed9ed66 100644
--- a/test/Microsoft.AspNetCore.Diagnostics.HealthChecks.Tests/HealthCheckMiddlewareSampleTest.cs
+++ b/test/Microsoft.AspNetCore.Diagnostics.HealthChecks.Tests/HealthCheckMiddlewareSampleTest.cs
@@ -1,12 +1,10 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
-using Newtonsoft.Json;
using Xunit;
namespace Microsoft.AspNetCore.Diagnostics.HealthChecks
@@ -37,22 +35,6 @@ namespace Microsoft.AspNetCore.Diagnostics.HealthChecks
var server = new TestServer(builder);
var client = server.CreateClient();
- var response = await client.GetAsync("/health");
- Assert.Equal(HttpStatusCode.OK, response.StatusCode);
- Assert.Equal("text/html", response.Content.Headers.ContentType.ToString());
-
- // Ignoring the body since it contains a bunch of statistics
- }
-
- [Fact]
- public async Task DetailedStatusStartup()
- {
- var builder = new WebHostBuilder()
- .UseStartup();
-
- var server = new TestServer(builder);
- var client = server.CreateClient();
-
var response = await client.GetAsync("/health");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal("application/json", response.Content.Headers.ContentType.ToString());
@@ -63,20 +45,6 @@ namespace Microsoft.AspNetCore.Diagnostics.HealthChecks
[Fact]
public async Task LivenessProbeStartup_Liveness()
{
- var expectedJson = JsonConvert.SerializeObject(new
- {
- status = "Healthy",
- results = new
- {
- identity = new
- {
- status = "Healthy",
- description = "",
- data = new { }
- },
- },
- }, Formatting.Indented);
-
var builder = new WebHostBuilder()
.UseStartup();
@@ -85,33 +53,13 @@ namespace Microsoft.AspNetCore.Diagnostics.HealthChecks
var response = await client.GetAsync("/health/live");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
- Assert.Equal("application/json", response.Content.Headers.ContentType.ToString());
- Assert.Equal(expectedJson, await response.Content.ReadAsStringAsync());
+ Assert.Equal("text/plain", response.Content.Headers.ContentType.ToString());
+ Assert.Equal("Healthy", await response.Content.ReadAsStringAsync());
}
[Fact]
public async Task LivenessProbeStartup_Readiness()
{
- var expectedJson = JsonConvert.SerializeObject(new
- {
- status = "Unhealthy",
- results = new
- {
- identity = new
- {
- status = "Healthy",
- description = "",
- data = new { }
- },
- slow_dependency = new
- {
- status = "Unhealthy",
- description = "Dependency is still initializing",
- data = new { }
- },
- },
- }, Formatting.Indented);
-
var builder = new WebHostBuilder()
.UseStartup();
@@ -120,8 +68,8 @@ namespace Microsoft.AspNetCore.Diagnostics.HealthChecks
var response = await client.GetAsync("/health/ready");
Assert.Equal(HttpStatusCode.ServiceUnavailable, response.StatusCode);
- Assert.Equal("application/json", response.Content.Headers.ContentType.ToString());
- Assert.Equal(expectedJson, await response.Content.ReadAsStringAsync());
+ Assert.Equal("text/plain", response.Content.Headers.ContentType.ToString());
+ Assert.Equal("Unhealthy", await response.Content.ReadAsStringAsync());
}
}
}
diff --git a/test/Microsoft.AspNetCore.Diagnostics.HealthChecks.Tests/HealthCheckMiddlewareTests.cs b/test/Microsoft.AspNetCore.Diagnostics.HealthChecks.Tests/HealthCheckMiddlewareTests.cs
index 74d23c81bf..0555ab6f7a 100644
--- a/test/Microsoft.AspNetCore.Diagnostics.HealthChecks.Tests/HealthCheckMiddlewareTests.cs
+++ b/test/Microsoft.AspNetCore.Diagnostics.HealthChecks.Tests/HealthCheckMiddlewareTests.cs
@@ -7,6 +7,7 @@ using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
@@ -201,94 +202,40 @@ namespace Microsoft.AspNetCore.Diagnostics.HealthChecks
}
[Fact]
- public async Task DetailedJsonReturnsEmptyHealthyResponseIfNoHealthChecksRegistered()
- {
- var expectedJson = JsonConvert.SerializeObject(new
- {
- status = "Healthy",
- results = new { }
- }, Formatting.Indented);
-
- var builder = new WebHostBuilder()
- .Configure(app =>
- {
- app.UseHealthChecks("/health", new HealthCheckOptions()
- {
- ResponseWriter = HealthCheckResponseWriters.WriteDetailedJson,
- });
- })
- .ConfigureServices(services =>
- {
- services.AddHealthChecks();
- });
- var server = new TestServer(builder);
- var client = server.CreateClient();
-
- var response = await client.GetAsync("/health");
-
- var result = await response.Content.ReadAsStringAsync();
- Assert.Equal(expectedJson, result);
- }
-
- [Fact]
- public async Task DetailedJsonReturnsResultsFromHealthChecks()
+ public async Task CanUseCustomWriter()
{
var expectedJson = JsonConvert.SerializeObject(new
{
status = "Unhealthy",
- results = new
- {
- Foo = new
- {
- status = "Healthy",
- description = "Good to go!",
- data = new { }
- },
- Bar = new
- {
- status = "Degraded",
- description = "Feeling a bit off.",
- data = new { someUsefulAttribute = 42 }
- },
- Baz = new
- {
- status = "Unhealthy",
- description = "Not feeling good at all",
- data = new { }
- },
- Boz = new
- {
- status = "Unhealthy",
- description = string.Empty,
- data = new { }
- },
- },
- }, Formatting.Indented);
+ });
var builder = new WebHostBuilder()
.Configure(app =>
{
app.UseHealthChecks("/health", new HealthCheckOptions()
{
- ResponseWriter = HealthCheckResponseWriters.WriteDetailedJson,
+ ResponseWriter = (c, r) =>
+ {
+ var json = JsonConvert.SerializeObject(new { status = r.Status.ToString(), });
+ c.Response.ContentType = "application/json";
+ return c.Response.WriteAsync(json);
+ },
});
})
.ConfigureServices(services =>
{
services.AddHealthChecks()
- .AddCheck("Foo", () => Task.FromResult(HealthCheckResult.Healthy("Good to go!")))
- .AddCheck("Bar", () => Task.FromResult(HealthCheckResult.Degraded("Feeling a bit off.", new Dictionary()
- {
- { "someUsefulAttribute", 42 }
- })))
- .AddCheck("Baz", () => Task.FromResult(HealthCheckResult.Unhealthy("Not feeling good at all", new Exception("Bad times"))))
- .AddCheck("Boz", () => Task.FromResult(HealthCheckResult.Unhealthy(new Exception("Very bad times"))));
+ .AddCheck("Foo", () => Task.FromResult(HealthCheckResult.Healthy("A-ok!")))
+ .AddCheck("Bar", () => Task.FromResult(HealthCheckResult.Unhealthy("Pretty bad.")))
+ .AddCheck("Baz", () => Task.FromResult(HealthCheckResult.Healthy("A-ok!")));
});
var server = new TestServer(builder);
var client = server.CreateClient();
var response = await client.GetAsync("/health");
+ Assert.Equal("application/json", response.Content.Headers.ContentType.ToString());
+
var result = await response.Content.ReadAsStringAsync();
Assert.Equal(expectedJson, result);
}