Skip to content

Commit 93c6634

Browse files
committed
HealthCheck configurable: logLevel, prefix, suffix, removeResponseWriter
1 parent bcd64dc commit 93c6634

File tree

5 files changed

+92
-19
lines changed

5 files changed

+92
-19
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,13 @@ Reference [ForwardedHeadersOptionsSetup.cs](https://github.com/dotnet/aspnetcore
4545
"HealthCheck": {
4646
"IsEnabled": true,
4747
"IsAzureAppServiceContainer": false, // will include /healthz and /robots933456.txt
48+
"LogLevel": "Debug",
4849
"Path": "/healthz",
4950
"Paths": [ "/healthz", "/robots933456.txt" ],
50-
"Port": null
51+
"Port": null,
52+
"Prefix": null,
53+
"Suffix": null,
54+
"RemoveResponseWriter": false
5155
},
5256
"HttpOverrides": {
5357
"ClearForwardLimit": false,
Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
1-
namespace NetLah.Extensions.HttpOverrides;
1+
using Microsoft.Extensions.Logging;
2+
3+
namespace NetLah.Extensions.HttpOverrides;
24

35
internal class HealthCheckAppOptions
46
{
57
public bool IsEnabled { get; set; } = true;
68

79
public bool IsAzureAppServiceContainer { get; set; }
810

9-
public string Path { get; set; } = DefaultConfiguration.HealthChecksPath;
11+
public LogLevel LogLevel { get; set; } = LogLevel.Debug;
12+
13+
public string? Path { get; set; } = DefaultConfiguration.HealthChecksPath;
1014

1115
public string[]? Paths { get; set; }
1216

1317
public int? Port { get; set; }
18+
19+
public string? Prefix { get; set; }
20+
21+
public string? Suffix { get; set; }
22+
23+
public bool RemoveResponseWriter { get; set; }
1424
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using Microsoft.AspNetCore.Http;
2+
using Microsoft.Extensions.Diagnostics.HealthChecks;
3+
using System.Text;
4+
5+
namespace NetLah.Extensions.HttpOverrides;
6+
7+
// https://github.com/dotnet/aspnetcore/blob/main/src/Middleware/HealthChecks/src/HealthCheckResponseWriters.cs
8+
internal class HealthCheckResponseWriters
9+
{
10+
public static HealthCheckResponseWriters Instance { get; set; } = new(default, default);
11+
12+
private readonly byte[] DegradedBytes;
13+
private readonly byte[] HealthyBytes;
14+
private readonly byte[] UnhealthyBytes;
15+
16+
public HealthCheckResponseWriters(string? prefix, string? suffix)
17+
{
18+
string Build(HealthStatus status) => $"{prefix}{status}{suffix}";
19+
20+
DegradedBytes = Encoding.UTF8.GetBytes(Build(HealthStatus.Degraded));
21+
HealthyBytes = Encoding.UTF8.GetBytes(Build(HealthStatus.Healthy));
22+
UnhealthyBytes = Encoding.UTF8.GetBytes(Build(HealthStatus.Unhealthy));
23+
}
24+
25+
public Task WriteMinimalPlaintext(HttpContext httpContext, HealthReport result)
26+
{
27+
httpContext.Response.ContentType = "text/plain";
28+
return result.Status switch
29+
{
30+
HealthStatus.Degraded => httpContext.Response.Body.WriteAsync(DegradedBytes.AsMemory()).AsTask(),
31+
HealthStatus.Healthy => httpContext.Response.Body.WriteAsync(HealthyBytes.AsMemory()).AsTask(),
32+
HealthStatus.Unhealthy => httpContext.Response.Body.WriteAsync(UnhealthyBytes.AsMemory()).AsTask(),
33+
_ => httpContext.Response.WriteAsync(result.Status.ToString())
34+
};
35+
}
36+
}

src/NetLah.Extensions.HttpOverrides/HttpOverridesExtensions.cs

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,30 +33,50 @@ public static IServiceCollection AddHttpOverrides(this IServiceCollection servic
3333
string httpLoggingSectionName = DefaultConfiguration.HttpLoggingKey,
3434
string healthCheckSectionName = DefaultConfiguration.HealthCheckKey)
3535
{
36-
ILogger? logger = null;
36+
ILogger? logger1 = null;
3737

38-
void EnsureLogger()
38+
ILogger EnsureLogger()
3939
{
40-
logger ??= _loggerLazy.Value;
41-
logger ??= NullLogger.Instance;
40+
logger1 ??= _loggerLazy.Value!;
41+
return logger1 ??= NullLogger.Instance;
4242
}
4343

4444
var healthCheckConfigurationSection = string.IsNullOrEmpty(healthCheckSectionName) ? configuration : configuration.GetSection(healthCheckSectionName);
4545
var healthCheckAppOptions = _healthCheckAppOptions = healthCheckConfigurationSection.Get<HealthCheckAppOptions>() ?? new HealthCheckAppOptions();
4646
if (healthCheckAppOptions.IsEnabled)
4747
{
48-
EnsureLogger();
48+
var logger = EnsureLogger();
49+
var logLevel = healthCheckAppOptions.LogLevel;
50+
4951
if (healthCheckConfigurationSection.GetChildren().Any())
5052
{
51-
logger?.LogDebug("Attempt to load HealthCheckOptions from configuration");
53+
logger.Log(logLevel, "Attempt to load HealthCheckOptions from configuration");
5254
services.Configure<HealthCheckOptions>(healthCheckConfigurationSection);
5355
}
5456
else
5557
{
56-
logger?.LogDebug("Add HealthChecks");
58+
logger.Log(logLevel, "Add HealthChecks");
5759
}
5860

59-
services.Configure<HealthCheckAppOptions>(healthCheckConfigurationSection);
61+
if (healthCheckAppOptions.RemoveResponseWriter)
62+
{
63+
logger.Log(logLevel, "HealthCheckOptions remove ResponseWriter");
64+
65+
services.Configure<HealthCheckOptions>(string.Empty, (HealthCheckOptions opt) =>
66+
{
67+
opt.ResponseWriter = null!;
68+
});
69+
}
70+
else if (!string.IsNullOrEmpty(healthCheckAppOptions.Prefix) || !string.IsNullOrEmpty(healthCheckAppOptions.Suffix))
71+
{
72+
logger.Log(logLevel, "HealthCheckOptions customize Prefix:{prefix} and Suffix:{suffix}", healthCheckAppOptions.Prefix, healthCheckAppOptions.Suffix);
73+
74+
var writer = HealthCheckResponseWriters.Instance = new HealthCheckResponseWriters(healthCheckAppOptions.Prefix, healthCheckAppOptions.Suffix);
75+
services.Configure<HealthCheckOptions>(string.Empty, (HealthCheckOptions opt) =>
76+
{
77+
opt.ResponseWriter = writer.WriteMinimalPlaintext;
78+
});
79+
}
6080

6181
services.AddHealthChecks(); // Registers health checks services
6282
}
@@ -65,8 +85,8 @@ void EnsureLogger()
6585

6686
if (!_isForwardedHeadersEnabled)
6787
{
68-
EnsureLogger();
69-
logger?.LogDebug("Attempt to load ForwardedHeadersOptions from configuration");
88+
var logger = EnsureLogger();
89+
logger.LogDebug("Attempt to load ForwardedHeadersOptions from configuration");
7090

7191
var httpOverridesConfigurationSection = string.IsNullOrEmpty(httpOverridesSectionName) ? configuration : configuration.GetSection(httpOverridesSectionName);
7292
services.Configure<ForwardedHeadersOptions>(httpOverridesConfigurationSection);
@@ -89,8 +109,8 @@ void EnsureLogger()
89109

90110
if (_isHttpLoggingEnabled)
91111
{
92-
EnsureLogger();
93-
logger?.LogDebug("Attempt to load HttpLoggingOptions from configuration");
112+
var logger = EnsureLogger();
113+
logger.LogDebug("Attempt to load HttpLoggingOptions from configuration");
94114

95115
var httpLoggingConfigurationSection = string.IsNullOrEmpty(httpLoggingSectionName) ? configuration : configuration.GetSection(httpLoggingSectionName);
96116
services.Configure<HttpLoggingOptions>(httpLoggingConfigurationSection);
@@ -133,6 +153,7 @@ public static WebApplication UseHttpOverrides(this WebApplication app, ILogger?
133153

134154
if (_healthCheckAppOptions.IsEnabled)
135155
{
156+
var logLevel = _healthCheckAppOptions.LogLevel;
136157
if (_healthCheckAppOptions.IsAzureAppServiceContainer)
137158
{
138159
var mainHealthChecksPath = string.IsNullOrEmpty(_healthCheckAppOptions.Path) ? DefaultConfiguration.HealthChecksPath : _healthCheckAppOptions.Path;
@@ -144,7 +165,7 @@ public static WebApplication UseHttpOverrides(this WebApplication app, ILogger?
144165
if (_healthCheckAppOptions.Paths is { } pathArrays && pathArrays.Length > 0)
145166
{
146167
var paths = pathArrays.Select(p => (PathString)p).ToArray();
147-
logger.LogDebug("Use HealthChecks Port:{port} {paths}", port, paths);
168+
logger.Log(logLevel, "Use HealthChecks Port:{port} Paths:{paths}", port, paths);
148169

149170
bool predicate(HttpContext c)
150171
{
@@ -167,8 +188,8 @@ bool predicate(HttpContext c)
167188
}
168189
else
169190
{
170-
var healthChecksPath = StringHelper.NormalizeNull(_healthCheckAppOptions.Path);
171-
logger.LogDebug("Use HealthChecks Port:{port} {path}", port, healthChecksPath);
191+
var healthChecksPath = _healthCheckAppOptions.Path;
192+
logger.LogDebug("Use HealthChecks Port:{port} Path:{path}", port, healthChecksPath);
172193
if (port.HasValue)
173194
{
174195
app.UseHealthChecks(healthChecksPath, port.Value);

src/NetLah.Extensions.HttpOverrides/StringHelper.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
namespace NetLah.Extensions.HttpOverrides;
1+
#if false
2+
namespace NetLah.Extensions.HttpOverrides;
23

34
internal static class StringHelper
45
{
@@ -16,3 +17,4 @@ public static string GetOrDefault(params string?[] values)
1617
public static string? NormalizeNull(string? value)
1718
=> string.IsNullOrWhiteSpace(value) ? default : value.Trim();
1819
}
20+
#endif

0 commit comments

Comments
 (0)