├── .github
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ ├── build-and-publish.yml
│ ├── build-and-test.yml
│ └── snyk-test.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Examples
├── Example.HealthChecks.AspNetCore.ResponseWriter
│ ├── Controllers
│ │ └── WeatherForecastController.cs
│ ├── Example.HealthChecks.AspNetCore.ResponseWriter.csproj
│ ├── Program.cs
│ ├── Startup.cs
│ ├── WeatherForecast.cs
│ ├── appsettings.Development.json
│ └── appsettings.json
├── Example.HealthChecks.AspNetCore
│ ├── Controllers
│ │ └── WeatherForecastController.cs
│ ├── Example.HealthChecks.AspNetCore.csproj
│ ├── Program.cs
│ ├── Startup.cs
│ ├── WeatherForecast.cs
│ ├── appsettings.Development.json
│ └── appsettings.json
└── Example.HealthChecks.Client
│ ├── Example.HealthChecks.Client.csproj
│ └── Program.cs
├── LICENSE.md
├── README.md
├── RockLib.HealthChecks.All.sln
├── RockLib.HealthChecks.AspNetCore.ResponseWriter
├── .editorconfig
├── CHANGELOG.md
├── Directory.Build.props
├── RockLib.HealthChecks.AspNetCore.ResponseWriter.csproj
├── RockLib.HealthChecks.AspNetCore.ResponseWriter.sln
└── RockLibHealthChecks.cs
├── RockLib.HealthChecks.AspNetCore
├── .editorconfig
├── CHANGELOG.md
├── Checks
│ └── HttpStatsHealthCheck.cs
├── Collector
│ ├── CollectorOptions.cs
│ ├── HealthMetricCollector.cs
│ ├── HealthMetricCollectorExtensions.cs
│ ├── HealthMetricCollectorFactory.cs
│ └── HttpResponseCollector.cs
├── Directory.Build.props
├── HealthCheckMiddleware.cs
├── HealthCheckMiddlewareExtensions.cs
├── IResponseFormatter.cs
├── NewtonsoftJsonResponseFormatter.cs
├── RockLib.HealthChecks.AspNetCore.csproj
└── RockLib.HealthChecks.AspNetCore.sln
├── RockLib.HealthChecks.Client
├── .editorconfig
├── CHANGELOG.md
├── Directory.Build.props
├── HealthCheckResult.cs
├── HealthCheckResultJsonConverter.cs
├── HealthResponse.cs
├── HealthStatus.cs
├── NullableAttributes.cs
├── RockLib.HealthChecks.Client.csproj
└── RockLib.HealthChecks.Client.sln
├── RockLib.HealthChecks.HttpModule
├── .editorconfig
├── CHANGELOG.md
├── Directory.Build.props
├── HealthCheckHttpModule.cs
├── RockLib.HealthChecks.HttpModule.csproj
└── RockLib.HealthChecks.HttpModule.sln
├── RockLib.HealthChecks.WebApi
├── .editorconfig
├── CHANGELOG.md
├── Directory.Build.props
├── HealthCheckHandler.cs
├── HealthCheckHandlerExtensions.cs
├── RockLib.HealthChecks.WebApi.csproj
└── RockLib.HealthChecks.WebApi.sln
├── RockLib.HealthChecks
├── .editorconfig
├── AssemblyAttributes.cs
├── CHANGELOG.md
├── DependencyInjection
│ ├── DependencyInjectionExtensions.cs
│ ├── HealthCheckRegistration.cs
│ ├── HealthCheckRunnerBuilder.cs
│ ├── HealthCheckRunnerOptions.cs
│ ├── IHealthCheckRunnerBuilder.cs
│ └── IHealthCheckRunnerOptions.cs
├── Directory.Build.props
├── HealthCheck.cs
├── HealthCheckExtensions.cs
├── HealthCheckResult.cs
├── HealthCheckRunner.cs
├── HealthResponse.cs
├── HealthStatus.cs
├── IHealthCheck.cs
├── IHealthCheckRunner.cs
├── IHealthResponseCustomizer.cs
├── NullableAttributes.cs
├── RockLib.HealthChecks.csproj
├── RockLib.HealthChecks.sln
├── SingleResultHealthCheck.cs
└── System
│ ├── DependencyInjectionExtensions.cs
│ ├── DiskDriveHealthCheck.cs
│ ├── ProcessUptimeHealthCheck.cs
│ └── SystemUptimeHealthCheck.cs
├── Tests
├── RockLib.HealthChecks.AspNetCore.ResponseWriter.Tests
│ ├── .editorconfig
│ ├── Directory.Build.props
│ ├── ResponseWriterTests.cs
│ └── RockLib.HealthChecks.AspNetCore.ResponseWriter.Tests.csproj
├── RockLib.HealthChecks.AspNetCore.Tests
│ ├── .editorconfig
│ ├── AssemblySettings.cs
│ ├── Checks
│ │ └── HttpStatsHealthCheckTests.cs
│ ├── Collector
│ │ ├── HealthMetricCollectorExtensionsTests.cs
│ │ ├── HealthMetricCollectorFactoryTests.cs
│ │ ├── HealthMetricCollectorTests.cs
│ │ └── HttpResponseCollectorTests.cs
│ ├── Directory.Build.props
│ ├── HealthCheckMiddlewareExtensionsTests.cs
│ ├── HealthCheckMiddlewareTests.cs
│ ├── NewtonsoftJsonResponseFormatterTests.cs
│ └── RockLib.HealthChecks.AspNetCore.Tests.csproj
├── RockLib.HealthChecks.Client.Tests
│ ├── .editorconfig
│ ├── AssemblySettings.cs
│ ├── DeserializeTests.cs
│ ├── Directory.Build.props
│ └── RockLib.HealthChecks.Client.Tests.csproj
├── RockLib.HealthChecks.HttpModule.Tests
│ ├── .editorconfig
│ ├── AssemblySettings.cs
│ ├── Directory.Build.props
│ ├── HealthCheckHttpModuleTests.cs
│ └── RockLib.HealthChecks.HttpModule.Tests.csproj
├── RockLib.HealthChecks.Tests
│ ├── .editorconfig
│ ├── AssemblySettings.cs
│ ├── Directory.Build.props
│ ├── HealthCheckExtensionsTests.cs
│ ├── HealthCheckResultTests.cs
│ ├── HealthCheckRunnerTests.cs
│ ├── HealthResponseTests.cs
│ ├── RockLib.HealthChecks.Tests.csproj
│ └── SingleResultHealthCheckTests.cs
└── RockLib.HealthChecks.WebApi.Tests
│ ├── .editorconfig
│ ├── AssemblySettings.cs
│ ├── Directory.Build.props
│ ├── HealthCheckHandlerExtensionsTests.cs
│ ├── HealthCheckHandlerTests.cs
│ └── RockLib.HealthChecks.WebApi.Tests.csproj
├── docs
├── AspNetCore.md
├── ConfigureAppSettings.md
├── ConfigureNet451AndAbove.md
├── ConfigureNet45AndBelow.md
├── CustomHealthCheck.md
├── DiskDriveHealthCheck.md
├── GettingStarted.md
├── HttpModule.md
├── HttpStatsHealthCheck.md
├── InstantiateRunner.md
├── ManualHealthChecks.md
├── ProcessUptimeHealthCheck.md
├── ResponseWriter.md
├── SystemUptimeHealthCheck.md
└── WebApi.md
└── icon.png
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Description
2 |
3 |
12 |
13 | ## Type of change:
14 |
15 | 1. Non-functional change (e.g. documentation changes, removing unused `using` directives, renaming local variables, etc)
16 | 2. Bug fix (non-breaking change that fixes an issue)
17 | 3. New feature (non-breaking change that adds functionality)
18 | 4. Breaking change (fix or feature that could cause existing functionality to not work as expected)
19 |
20 | ## Checklist:
21 |
22 | - Have you reviewed your own code? Do you understand every change?
23 | - Are you following the [contributing guidelines](../blob/main/CONTRIBUTING.md)?
24 | - Have you added tests that prove your fix is effective or that this feature works?
25 | - New and existing unit tests pass locally with these changes?
26 | - Have you made corresponding changes to the documentation?
27 | - Will this change require an update to an example project? (if so, create an issue and link to it)
28 |
29 | ---
30 |
31 | _[Reviewer guidelines](../blob/main/CONTRIBUTING.md#reviewing-changes)_
32 |
--------------------------------------------------------------------------------
/.github/workflows/build-and-publish.yml:
--------------------------------------------------------------------------------
1 | name: Build and Publish
2 |
3 | ####################################################################################################
4 | ## WORKFLOW TRIGGER
5 | ####################################################################################################
6 | on:
7 | # Workflow will run when a release is published.
8 | release:
9 | types: [ released, prereleased ]
10 |
11 | ####################################################################################################
12 | ## WORKFLOW JOBS
13 | ####################################################################################################
14 | jobs:
15 | # Calls the shared build-and-publish workflow.
16 | call_build_and_publish:
17 | name: Call build-and-publish workflow
18 | uses: RockLib/RockLib.Workflows/.github/workflows/build-and-publish.yml@main
19 | secrets: inherit
20 |
--------------------------------------------------------------------------------
/.github/workflows/build-and-test.yml:
--------------------------------------------------------------------------------
1 | name: Run Unit Test
2 |
3 | ####################################################################################################
4 | ## WORKFLOW TRIGGER
5 | ####################################################################################################
6 | on:
7 | # Workflow will run on pull requests to the main branch.
8 | pull_request:
9 | branches: [ main ]
10 |
11 | ####################################################################################################
12 | ## WORKFLOW JOBS
13 | ####################################################################################################
14 | jobs:
15 | # Calls the shared unit-test workflow.
16 | call_unit_test:
17 | name: Call unit-test workflow
18 | uses: RockLib/RockLib.Workflows/.github/workflows/unit-test.yml@main
19 | secrets: inherit
20 |
--------------------------------------------------------------------------------
/.github/workflows/snyk-test.yml:
--------------------------------------------------------------------------------
1 | name: Run Snyk Test
2 |
3 | ####################################################################################################
4 | ## WORKFLOW TRIGGER
5 | ####################################################################################################
6 | on:
7 | # Workflow will run after unit-test is completed.
8 | workflow_run:
9 | workflows: [ Run Unit Test ]
10 | types: [ completed ]
11 |
12 | ####################################################################################################
13 | ## WORKFLOW JOBS
14 | ####################################################################################################
15 | jobs:
16 | # Calls the shared snyk-test workflow.
17 | call_snyk_test:
18 | name: Call snyk-test workflow
19 | uses: RockLib/RockLib.Workflows/.github/workflows/snyk-test.yml@main
20 | secrets: inherit
21 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at RockLibSupport@quickenloans.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/Examples/Example.HealthChecks.AspNetCore.ResponseWriter/Controllers/WeatherForecastController.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Mvc;
2 | using Microsoft.Extensions.Logging;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 |
8 | namespace Example.HealthChecks.AspNetCore.ResponseWriter.Controllers
9 | {
10 | [ApiController]
11 | [Route("[controller]")]
12 | public class WeatherForecastController : ControllerBase
13 | {
14 | private static readonly string[] Summaries = new[]
15 | {
16 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
17 | };
18 |
19 | private readonly ILogger _logger;
20 |
21 | public WeatherForecastController(ILogger logger)
22 | {
23 | _logger = logger;
24 | }
25 |
26 | [HttpGet]
27 | public IEnumerable Get()
28 | {
29 | var rng = new Random();
30 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast
31 | {
32 | Date = DateTime.Now.AddDays(index),
33 | TemperatureC = rng.Next(-20, 55),
34 | Summary = Summaries[rng.Next(Summaries.Length)]
35 | })
36 | .ToArray();
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Examples/Example.HealthChecks.AspNetCore.ResponseWriter/Example.HealthChecks.AspNetCore.ResponseWriter.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net8.0
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Examples/Example.HealthChecks.AspNetCore.ResponseWriter/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Hosting;
2 | using Microsoft.Extensions.Configuration;
3 | using Microsoft.Extensions.Hosting;
4 | using Microsoft.Extensions.Logging;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Threading.Tasks;
9 |
10 | namespace Example.HealthChecks.AspNetCore.ResponseWriter
11 | {
12 | public class Program
13 | {
14 | public static void Main(string[] args)
15 | {
16 | CreateHostBuilder(args).Build().Run();
17 | }
18 |
19 | public static IHostBuilder CreateHostBuilder(string[] args) =>
20 | Host.CreateDefaultBuilder(args)
21 | .ConfigureWebHostDefaults(webBuilder =>
22 | {
23 | webBuilder.UseStartup();
24 | });
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Examples/Example.HealthChecks.AspNetCore.ResponseWriter/Startup.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Builder;
2 | using Microsoft.AspNetCore.Diagnostics.HealthChecks;
3 | using Microsoft.AspNetCore.Hosting;
4 | using Microsoft.Extensions.Configuration;
5 | using Microsoft.Extensions.DependencyInjection;
6 | using Microsoft.Extensions.Hosting;
7 | using RockLib.HealthChecks.AspNetCore.ResponseWriter;
8 |
9 | namespace Example.HealthChecks.AspNetCore.ResponseWriter
10 | {
11 | public class Startup
12 | {
13 | public Startup(IConfiguration configuration)
14 | {
15 | Configuration = configuration;
16 |
17 | // Set health checks options.
18 | RockLibHealthChecks.Indent = true;
19 | }
20 |
21 | public IConfiguration Configuration { get; }
22 |
23 | public void ConfigureServices(IServiceCollection services)
24 | {
25 | services.AddControllers();
26 |
27 | // Add health check service to the service collection.
28 | services.AddHealthChecks()
29 | .AddDiskStorageHealthCheck(options => options.AddDrive("C:\\", 309646), "disk:space");
30 | }
31 |
32 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
33 | {
34 | if (env.IsDevelopment())
35 | {
36 | app.UseDeveloperExceptionPage();
37 | }
38 |
39 | app.UseHttpsRedirection();
40 |
41 | app.UseRouting();
42 |
43 | app.UseAuthorization();
44 |
45 | // Add health checks endpoint to the pipeline before the call to UseEndpoints.
46 | app.UseHealthChecks("/health", new HealthCheckOptions
47 | {
48 | // To write health check responses in the rfc format, set the response writer of
49 | // the health check options.
50 | ResponseWriter = RockLibHealthChecks.ResponseWriter
51 | });
52 |
53 | app.UseEndpoints(endpoints =>
54 | {
55 | endpoints.MapControllers();
56 | });
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/Examples/Example.HealthChecks.AspNetCore.ResponseWriter/WeatherForecast.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Example.HealthChecks.AspNetCore.ResponseWriter
4 | {
5 | public class WeatherForecast
6 | {
7 | public DateTime Date { get; set; }
8 |
9 | public int TemperatureC { get; set; }
10 |
11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
12 |
13 | public string Summary { get; set; }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Examples/Example.HealthChecks.AspNetCore.ResponseWriter/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Examples/Example.HealthChecks.AspNetCore.ResponseWriter/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | },
9 | "AllowedHosts": "*"
10 | }
11 |
--------------------------------------------------------------------------------
/Examples/Example.HealthChecks.AspNetCore/Controllers/WeatherForecastController.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Mvc;
2 | using Microsoft.Extensions.Logging;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 |
8 | namespace Example.HealthChecks.AspNetCore.Controllers
9 | {
10 | [ApiController]
11 | [Route("[controller]")]
12 | public class WeatherForecastController : ControllerBase
13 | {
14 | private static readonly string[] Summaries = new[]
15 | {
16 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
17 | };
18 |
19 | private readonly ILogger _logger;
20 |
21 | public WeatherForecastController(ILogger logger)
22 | {
23 | _logger = logger;
24 | }
25 |
26 | [HttpGet]
27 | public IEnumerable Get()
28 | {
29 | var rng = new Random();
30 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast
31 | {
32 | Date = DateTime.Now.AddDays(index),
33 | TemperatureC = rng.Next(-20, 55),
34 | Summary = Summaries[rng.Next(Summaries.Length)]
35 | })
36 | .ToArray();
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Examples/Example.HealthChecks.AspNetCore/Example.HealthChecks.AspNetCore.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net8.0
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Examples/Example.HealthChecks.AspNetCore/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Hosting;
2 | using Microsoft.Extensions.Configuration;
3 | using Microsoft.Extensions.Hosting;
4 | using Microsoft.Extensions.Logging;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Threading.Tasks;
9 |
10 | namespace Example.HealthChecks.AspNetCore
11 | {
12 | public class Program
13 | {
14 | public static void Main(string[] args)
15 | {
16 | CreateHostBuilder(args).Build().Run();
17 | }
18 |
19 | public static IHostBuilder CreateHostBuilder(string[] args) =>
20 | Host.CreateDefaultBuilder(args)
21 | .ConfigureWebHostDefaults(webBuilder =>
22 | {
23 | webBuilder.UseStartup();
24 | });
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Examples/Example.HealthChecks.AspNetCore/Startup.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Builder;
2 | using Microsoft.AspNetCore.Hosting;
3 | using Microsoft.Extensions.Configuration;
4 | using Microsoft.Extensions.DependencyInjection;
5 | using Microsoft.Extensions.Hosting;
6 | using Newtonsoft.Json;
7 | using RockLib.HealthChecks.AspNetCore;
8 | using RockLib.HealthChecks.DependencyInjection;
9 | using RockLib.HealthChecks.System;
10 |
11 | namespace Example.HealthChecks.AspNetCore
12 | {
13 | public class Startup
14 | {
15 | public Startup(IConfiguration configuration)
16 | {
17 | Configuration = configuration;
18 | }
19 |
20 | public IConfiguration Configuration { get; }
21 |
22 | public void ConfigureServices(IServiceCollection services)
23 | {
24 | services.AddControllers();
25 |
26 | // This application defines its health check runner in its appsettings.json, so
27 | // a health check runner should *not* be added to the service collection. To define an
28 | // equivalent health check runner programmatically:
29 | /*
30 | services.AddHealthCheckRunner(options =>
31 | {
32 | options.Version = "1";
33 | options.ServiceId = "c0c4b71f-d540-4515-8a87-5a4ae5ca4c55";
34 | options.Description = "My Application";
35 | })
36 | .AddProcessUptimeHealthCheck()
37 | .AddDiskDriveHealthCheck(warnGigabytes: 10, failGigabytes: 1, driveName: "C:\\");
38 | */
39 | }
40 |
41 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
42 | {
43 | if (env.IsDevelopment())
44 | {
45 | app.UseDeveloperExceptionPage();
46 | }
47 |
48 | app.UseHttpsRedirection();
49 |
50 | app.UseRouting();
51 |
52 | app.UseAuthorization();
53 |
54 | // Add health checks endpoint to the pipeline before the call to UseEndpoints.
55 | app.UseRockLibHealthChecks(formatter: new NewtonsoftJsonResponseFormatter(Formatting.Indented));
56 |
57 | app.UseEndpoints(endpoints =>
58 | {
59 | endpoints.MapControllers();
60 | });
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/Examples/Example.HealthChecks.AspNetCore/WeatherForecast.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Example.HealthChecks.AspNetCore
4 | {
5 | public class WeatherForecast
6 | {
7 | public DateTime Date { get; set; }
8 |
9 | public int TemperatureC { get; set; }
10 |
11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
12 |
13 | public string Summary { get; set; }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Examples/Example.HealthChecks.AspNetCore/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Examples/Example.HealthChecks.AspNetCore/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | },
9 | "AllowedHosts": "*",
10 |
11 | "RockLib.HealthChecks": {
12 | "version": "1",
13 | "serviceId": "c0c4b71f-d540-4515-8a87-5a4ae5ca4c55",
14 | "description": "My Application",
15 | "healthChecks": [
16 | {
17 | "type": "RockLib.HealthChecks.System.ProcessUptimeHealthCheck, RockLib.HealthChecks"
18 | },
19 | {
20 | "type": "RockLib.HealthChecks.System.DiskDriveHealthCheck, RockLib.HealthChecks",
21 | "value": {
22 | "warnGigabytes": 10,
23 | "failGigabytes": 1,
24 | "driveName": "C:\\"
25 | }
26 | }
27 | ]
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Examples/Example.HealthChecks.Client/Example.HealthChecks.Client.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Exe
4 | net8.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Examples/Example.HealthChecks.Client/Program.cs:
--------------------------------------------------------------------------------
1 | using RockLib.HealthChecks.Client;
2 | using System;
3 | using System.Net.Http;
4 | using System.Net.Http.Json;
5 | using System.Threading.Tasks;
6 |
7 | namespace Example.HealthChecks.Client
8 | {
9 | class Program
10 | {
11 | static async Task Main(string[] args)
12 | {
13 | using var httpClient = new HttpClient();
14 |
15 | Console.Write("Press any key when ready to send health request . . .");
16 | Console.ReadKey(true);
17 | Console.WriteLine();
18 | Console.WriteLine();
19 |
20 | // Note: This example is designed to make a request to the
21 | // Example.HealthChecks.AspNetCore example.
22 | var httpResponse = await httpClient.GetAsync("https://localhost:5001/health");
23 |
24 | // Deserialize the request content into a HealthResponse object. Note that the
25 | // ReadFromJsonAsync extension method comes from the System.Net.Http.Json package.
26 | var healthResponse = await httpResponse.Content.ReadFromJsonAsync();
27 |
28 | // Use the HealthResponse object.
29 | Console.WriteLine($"Overall health check status: {healthResponse.Status}");
30 | Console.WriteLine($"Number of health checks performed: {healthResponse.Checks.Count}");
31 | foreach (var healthCheck in healthResponse.Checks)
32 | foreach (var healthCheckResult in healthCheck.Value)
33 | Console.WriteLine($"Health check '{healthCheck.Key}': {healthCheckResult.ObservedValue} {healthCheckResult.ObservedUnit}");
34 |
35 | Console.WriteLine();
36 | Console.Write("Press any key to exit . . .");
37 | Console.ReadKey(true);
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (C) 2019-2021 Rocket Mortgage
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # RockLib.HealthChecks
2 |
3 | *An implementation of the draft health check RFC located at https://inadarei.github.io/rfc-healthcheck/.*
4 |
5 | ---
6 |
7 | - [Getting started](docs/GettingStarted.md)
8 | - How to:
9 | - [Manually perform health checks](docs/ManualHealthChecks.md)
10 | - [Add RockLib.HealthChecks to an ASP.NET Core application](docs/AspNetCore.md)
11 | - [Add RockLib.HealthChecks to an ASP.NET WebApi application](docs/WebApi.md)
12 | - [Add RockLib.HealthChecks to an ASP.NET application via HttpModule](docs/HttpModule.md)
13 | - [Format the output of Microsoft.Extensions.Diagnostics.HealthChecks in the draft RFC format](docs/ResponseWriter.md)
14 | - [Instantiate health check runners](docs/InstantiateRunner.md)
15 | - [Configure an application with appsettings.json](docs/ConfigureAppSettings.md)
16 | - [Configure a .NET Framework application (4.5 or below) with app.config/web.config](docs/ConfigureNet45AndBelow.md)
17 | - [Configure a .NET Framework application (4.5.1 or above) with app.config/web.config](docs/ConfigureNet451AndAbove.md)
18 | - [Create custom health checks](docs/CustomHealthCheck.md)
19 | - Existing Health Checks:
20 | - System
21 | - [DiskDriveHealthCheck](docs/DiskDriveHealthCheck.md)
22 | - A health check that monitors the amount of available free space on disk.
23 | - [ProcessUptimeHealthCheck](docs/ProcessUptimeHealthCheck.md)
24 | - A health check that records the uptime of the current process. Always passes.
25 | - [SystemUptimeHealthCheck](docs/SystemUptimeHealthCheck.md)
26 | - A health check that records the uptime of the system. Always passes.
27 | - Downstream Services
28 | - [HttpStatsHealthCheck](docs/HttpStatsHealthCheck.md)
29 | - A health check that monitors HTTP calls to downstream systems and reports on outcomes.
30 |
--------------------------------------------------------------------------------
/RockLib.HealthChecks.AspNetCore.ResponseWriter/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 |
6 | [*.cs]
7 | # Styling
8 | indent_style = space
9 | indent_size = 4
10 | csharp_indent_case_contents = true
11 | csharp_indent_switch_labels = true
12 | csharp_new_line_before_catch = true
13 | csharp_new_line_before_else = true
14 | csharp_new_line_before_finally = true
15 | csharp_new_line_before_members_in_anonymous_types = false
16 | csharp_new_line_before_members_in_object_initializers = false
17 | csharp_new_line_before_open_brace = methods, control_blocks, types, properties, lambdas, accessors, object_collection_array_initializers
18 | csharp_new_line_between_query_expression_clauses = true
19 | csharp_prefer_braces = false:suggestion
20 | csharp_prefer_simple_default_expression = true:suggestion
21 | csharp_preferred_modifier_order = public,private,internal,protected,static,readonly,async,override,sealed:suggestion
22 | csharp_preserve_single_line_blocks = true
23 | csharp_preserve_single_line_statements = true
24 | csharp_space_after_cast = false
25 | csharp_space_after_colon_in_inheritance_clause = true
26 | csharp_space_after_keywords_in_control_flow_statements = true
27 | csharp_space_before_colon_in_inheritance_clause = true
28 | csharp_space_between_method_call_empty_parameter_list_parentheses = false
29 | csharp_space_between_method_call_name_and_opening_parenthesis = false
30 | csharp_space_between_method_call_parameter_list_parentheses = false
31 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
32 | csharp_space_between_method_declaration_parameter_list_parentheses = false
33 | csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
34 | csharp_style_expression_bodied_accessors = true:suggestion
35 | csharp_style_expression_bodied_constructors = false:suggestion
36 | csharp_style_expression_bodied_methods = false:suggestion
37 | csharp_style_expression_bodied_properties = true:suggestion
38 | csharp_style_inlined_variable_declaration = true:suggestion
39 | csharp_style_var_elsewhere = true:suggestion
40 | csharp_style_var_for_built_in_types = true:suggestion
41 | csharp_style_var_when_type_is_apparent = true:suggestion
42 | dotnet_sort_system_directives_first = false
43 | dotnet_style_explicit_tuple_names = true:suggestion
44 | dotnet_style_object_initializer = true:suggestion
45 | csharp_style_pattern_local_over_anonymous_function = false:suggestion
46 | dotnet_style_predefined_type_for_member_access = true:suggestion
47 | dotnet_style_prefer_inferred_anonymous_type_member_names = false:suggestion
48 | dotnet_style_prefer_inferred_tuple_names = true:suggestion
49 | dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
50 | dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
51 | dotnet_style_qualification_for_field = false:suggestion
52 | dotnet_style_qualification_for_method = false:suggestion
53 | dotnet_style_qualification_for_property = false:suggestion
54 |
55 |
56 | # Analyzer Configuration
57 | # These are rules we want to either ignore or have set as suggestion or info
58 |
59 | # CA1014: Mark assemblies with CLSCompliant
60 | # https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1014
61 | dotnet_diagnostic.CA1014.severity = none
62 |
63 | # CA1725: Parameter names should match base declaration
64 | # https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1725
65 | dotnet_diagnostic.CA1725.severity = suggestion
66 |
67 | # CA2227: Collection properties should be read only
68 | # https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2227
69 | dotnet_diagnostic.CA2227.severity = suggestion
70 |
--------------------------------------------------------------------------------
/RockLib.HealthChecks.AspNetCore.ResponseWriter/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # RockLib.HealthChecks.AspNetCore.ResponseWriter Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## 4.0.0 - 2025-02-05
9 |
10 | #### Changed
11 | - Finalized 4.0.0 release.
12 | - RockLib.HealthChecks.4.0.0-alpha.1 -> RockLib.HealthChecks.4.0.0
13 |
14 | ## 4.0.0-alpha.1 - 2025-02-05
15 |
16 | #### Changed
17 | - RockLib.HealthChecks.3.0.2 -> RockLib.HealthChecks.4.0.0-alpha.1
18 |
19 | ## 3.0.2 - 2024-11-05
20 |
21 | #### Changed
22 | - RockLib.HealthChecks.3.0.1 -> RockLib.HealthChecks.3.0.2 to fix vulnerability
23 |
24 | ## 3.0.1 - 2024-07-16
25 |
26 | #### Changed
27 | - RockLib.HealthChecks.3.0.0 -> RockLib.HealthChecks.3.0.1 to fix vulnerability
28 |
29 | ## 3.0.0 - 2024-03-04
30 |
31 | #### Changed
32 | - Removed netcoreapp3.1 from supported targets.
33 | - Added net8.0 to supported targets.
34 | - Updated package references.
35 |
36 | ## 3.0.0-alpha.1 - 2024-02-27
37 |
38 | #### Changed
39 | - Removed netcoreapp3.1 from supported targets from test project.
40 | - Added net8.0 to supported targets to test project.
41 | - Updated package references in test project.
42 |
43 | ## 2.0.0-alpha.2 - 2023-03-01
44 |
45 | #### Changed
46 | - Updated RockLib.HealthChecks dependency to 2.0.1.
47 |
48 | ## 2.0.0-alpha.1 - 2022-12-15
49 |
50 | #### Added
51 | - Added `.editorconfig` and `Directory.Build.props` files to ensure consistency.
52 |
53 | #### Changed
54 | - Supported targets: net6.0, netcoreapp3.1, and net48.
55 | - As the package now uses nullable reference types, some method parameters now specify if they can accept nullable values.
56 |
57 | ## 1.1.2 - 2021-08-13
58 |
59 | #### Changed
60 |
61 | - Changes "Quicken Loans" to "Rocket Mortgage".
62 | - Updates RockLib.HealthChecks to latest version, [1.3.9](https://github.com/RockLib/RockLib.HealthChecks/blob/main/RockLib.HealthChecks/CHANGELOG.md#139---2021-08-13).
63 |
64 | ## 1.1.1 - 2021-05-10
65 |
66 | #### Added
67 |
68 | - Adds SourceLink to nuget package.
69 |
70 | #### Changed
71 |
72 | - Updates RockLib.HealthChecks package to latest version, which includes SourceLink.
73 |
74 | ----
75 |
76 | **Note:** Release notes in the above format are not available for earlier versions of
77 | RockLib.HealthChecks.AspNetCore.ResponseWriter. What follows below are the original release notes.
78 |
79 | ----
80 |
81 | ## 1.1.0
82 |
83 | Adds the ability to hide the exception or description/output when mapping a Microsoft HealthReportEntry to a RockLib HealthCheckResult.
84 |
85 | ## 1.0.4
86 |
87 | Updates RockLib.HealthChecks dependency, adding missing functionality for the net5.0 target.
88 |
89 | ## 1.0.3
90 |
91 | Adds net5.0 target and updates dependencies.
92 |
93 | ## 1.0.2
94 |
95 | Adds icon to project and nuget package.
96 |
97 | ## 1.0.1
98 |
99 | Updates to align with nuget conventions.
100 |
101 | ## 1.0.0
102 |
103 | Initial release.
104 |
105 | ## 1.0.0-rc1
106 |
107 | Initial release candidate.
108 |
--------------------------------------------------------------------------------
/RockLib.HealthChecks.AspNetCore.ResponseWriter/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | true
4 |
5 |
6 | all
7 | Rocket Mortgage
8 | Copyright 2025 (c) Rocket Mortgage. All rights reserved.
9 | latest
10 | enable
11 | net8.0;net48
12 | NU1603,NU1701
13 | true
14 |
15 |
16 |
17 | all
18 | runtime; build; native; contentfiles; analyzers; buildtransitive
19 |
20 |
21 |
--------------------------------------------------------------------------------
/RockLib.HealthChecks.AspNetCore.ResponseWriter/RockLib.HealthChecks.AspNetCore.ResponseWriter.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Embedded
4 | A ResponseWriter for Microsoft.Extensions.Diagnostics.HealthChecks that writes in the format described by https://inadarei.github.io/rfc-healthcheck/.
5 | True
6 | True
7 | icon.png
8 | RockLib.HealthChecks.AspNetCore.ResponseWriter
9 | LICENSE.md
10 | https://github.com/RockLib/RockLib.HealthChecks
11 | A changelog is available at https://github.com/RockLib/RockLib.HealthChecks/blob/main/RockLib.HealthChecks.AspNetCore.ResponseWriter/CHANGELOG.md.
12 | false
13 | rocklib health checks aspnetcore responsewriter
14 | 4.0.0
15 | True
16 | 4.0.0
17 |
18 |
19 | bin\$(Configuration)\$(TargetFramework)\$(PackageId).xml
20 |
21 |
22 | true
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/RockLib.HealthChecks.AspNetCore.ResponseWriter/RockLib.HealthChecks.AspNetCore.ResponseWriter.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.4.33110.190
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RockLib.HealthChecks.AspNetCore.ResponseWriter", "RockLib.HealthChecks.AspNetCore.ResponseWriter.csproj", "{482209AA-CA19-40B1-9D32-083CC50C2B88}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RockLib.HealthChecks.AspNetCore.ResponseWriter.Tests", "..\Tests\RockLib.HealthChecks.AspNetCore.ResponseWriter.Tests\RockLib.HealthChecks.AspNetCore.ResponseWriter.Tests.csproj", "{04532804-CCFE-40BA-B93D-5634222F4F50}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {482209AA-CA19-40B1-9D32-083CC50C2B88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {482209AA-CA19-40B1-9D32-083CC50C2B88}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {482209AA-CA19-40B1-9D32-083CC50C2B88}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {482209AA-CA19-40B1-9D32-083CC50C2B88}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {04532804-CCFE-40BA-B93D-5634222F4F50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {04532804-CCFE-40BA-B93D-5634222F4F50}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {04532804-CCFE-40BA-B93D-5634222F4F50}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {04532804-CCFE-40BA-B93D-5634222F4F50}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {9BD2137B-45A2-4572-9151-93471F4F7CC9}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/RockLib.HealthChecks.AspNetCore/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 |
6 | [*.cs]
7 | # Styling
8 | indent_style = space
9 | indent_size = 4
10 | csharp_indent_case_contents = true
11 | csharp_indent_switch_labels = true
12 | csharp_new_line_before_catch = true
13 | csharp_new_line_before_else = true
14 | csharp_new_line_before_finally = true
15 | csharp_new_line_before_members_in_anonymous_types = false
16 | csharp_new_line_before_members_in_object_initializers = false
17 | csharp_new_line_before_open_brace = methods, control_blocks, types, properties, lambdas, accessors, object_collection_array_initializers
18 | csharp_new_line_between_query_expression_clauses = true
19 | csharp_prefer_braces = false:suggestion
20 | csharp_prefer_simple_default_expression = true:suggestion
21 | csharp_preferred_modifier_order = public,private,internal,protected,static,readonly,async,override,sealed:suggestion
22 | csharp_preserve_single_line_blocks = true
23 | csharp_preserve_single_line_statements = true
24 | csharp_space_after_cast = false
25 | csharp_space_after_colon_in_inheritance_clause = true
26 | csharp_space_after_keywords_in_control_flow_statements = true
27 | csharp_space_before_colon_in_inheritance_clause = true
28 | csharp_space_between_method_call_empty_parameter_list_parentheses = false
29 | csharp_space_between_method_call_name_and_opening_parenthesis = false
30 | csharp_space_between_method_call_parameter_list_parentheses = false
31 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
32 | csharp_space_between_method_declaration_parameter_list_parentheses = false
33 | csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
34 | csharp_style_expression_bodied_accessors = true:suggestion
35 | csharp_style_expression_bodied_constructors = false:suggestion
36 | csharp_style_expression_bodied_methods = false:suggestion
37 | csharp_style_expression_bodied_properties = true:suggestion
38 | csharp_style_inlined_variable_declaration = true:suggestion
39 | csharp_style_var_elsewhere = true:suggestion
40 | csharp_style_var_for_built_in_types = true:suggestion
41 | csharp_style_var_when_type_is_apparent = true:suggestion
42 | dotnet_sort_system_directives_first = false
43 | dotnet_style_explicit_tuple_names = true:suggestion
44 | dotnet_style_object_initializer = true:suggestion
45 | csharp_style_pattern_local_over_anonymous_function = false:suggestion
46 | dotnet_style_predefined_type_for_member_access = true:suggestion
47 | dotnet_style_prefer_inferred_anonymous_type_member_names = false:suggestion
48 | dotnet_style_prefer_inferred_tuple_names = true:suggestion
49 | dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
50 | dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
51 | dotnet_style_qualification_for_field = false:suggestion
52 | dotnet_style_qualification_for_method = false:suggestion
53 | dotnet_style_qualification_for_property = false:suggestion
54 |
55 |
56 | # Analyzer Configuration
57 | # These are rules we want to either ignore or have set as suggestion or info
58 |
59 | # CA1014: Mark assemblies with CLSCompliant
60 | # https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1014
61 | dotnet_diagnostic.CA1014.severity = none
62 |
63 | # CA1725: Parameter names should match base declaration
64 | # https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1725
65 | dotnet_diagnostic.CA1725.severity = suggestion
66 |
67 | # CA2227: Collection properties should be read only
68 | # https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2227
69 | dotnet_diagnostic.CA2227.severity = suggestion
70 |
--------------------------------------------------------------------------------
/RockLib.HealthChecks.AspNetCore/Collector/CollectorOptions.cs:
--------------------------------------------------------------------------------
1 | namespace RockLib.HealthChecks.AspNetCore.Collector;
2 |
3 | ///
4 | /// Options for configuring a .
5 | ///
6 | /// Intended to be reused in other IMetricCollector implementations.
7 | public record CollectorOptions
8 | {
9 | ///
10 | /// The name of the collector. Defaults to .
11 | ///
12 | /// Use http host name (e.g. "myapp.foc.zone") if collecting http client response codes.
13 | public string Name { get; set; } = string.Empty;
14 |
15 | ///
16 | /// number of samples to keep in the collector. Defaults to 100.
17 | ///
18 | public int? Samples { get; set; }
19 |
20 | ///
21 | /// warning threshold for the collector. Defaults to 0.9.
22 | ///
23 | public double? WarningThreshold { get; set; }
24 |
25 | ///
26 | /// error threshold for the collector. Defaults to 0.75.
27 | ///
28 | public double? ErrorThreshold { get; set; }
29 | }
--------------------------------------------------------------------------------
/RockLib.HealthChecks.AspNetCore/Collector/HealthMetricCollector.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Threading;
4 |
5 | namespace RockLib.HealthChecks.AspNetCore.Collector;
6 |
7 | ///
8 | /// Interface definition for a health metric collectors. "health metrics" not to be confused with "application metrics" (e.g. OTEL/Dynatrace).
9 | ///
10 | ///
11 | public interface IHealthMetricCollector
12 | {
13 | ///
14 | /// Add a new metric to the collector.
15 | ///
16 | ///
17 | void Collect(int outcome);
18 |
19 | ///
20 | /// Retrieve the metrics from the collector.
21 | ///
22 | ///
23 | ///
24 | int[] GetMetrics(Func? predicate = null);
25 |
26 | ///
27 | /// Retrieve the number of impressions from the collector.
28 | ///
29 | long GetImpressionCount();
30 | }
31 |
32 | ///
33 | /// A simple implementation of that stores metrics in a fixed-size array.
34 | /// The fixed-size array is used as a circular buffer - "only store the N most-recent metrics".
35 | ///
36 | public class HealthMetricCollector : IHealthMetricCollector
37 | {
38 | private long _impressionCount;
39 | private readonly int[] _metrics;
40 | private readonly int _size;
41 |
42 | ///
43 | /// Implementation of that stores integer metrics in a fixed-size array.
44 | ///
45 | /// how large to make the array
46 | public HealthMetricCollector(int size)
47 | {
48 | _metrics = new int[size];
49 | _size = size;
50 | }
51 |
52 | ///
53 | /// see
54 | ///
55 | /// the integer outcome to put into the array.
56 | public void Collect(int outcome)
57 | {
58 | var idx = Interlocked.Increment(ref _impressionCount) % _size;
59 | _metrics[idx] = outcome;
60 | }
61 |
62 | ///
63 | /// see
64 | ///
65 | /// Func used to collate matching entries
66 | /// an int[] of entries matching the predicate
67 | public int[] GetMetrics(Func? predicate = null)
68 | {
69 | return _metrics.Where(predicate ?? (x => x != 0)).ToArray();
70 | }
71 |
72 | ///
73 | /// see
74 | ///
75 | ///
76 | public long GetImpressionCount()
77 | {
78 | return _impressionCount;
79 | }
80 | }
--------------------------------------------------------------------------------
/RockLib.HealthChecks.AspNetCore/Collector/HealthMetricCollectorExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace RockLib.HealthChecks.AspNetCore.Collector;
4 |
5 | ///
6 | /// IHealthMetricCollector extensions.
7 | ///
8 | public static class HealthMetricCollectorExtensions
9 | {
10 | ///
11 | /// Return a count of the metrics that match the predicate.
12 | ///
13 | ///
14 | ///
15 | ///
16 | public static int GetCount(this IHealthMetricCollector collector, Func predicate)
17 | {
18 | return collector?.GetMetrics(predicate).Length ?? 0;
19 | }
20 | }
--------------------------------------------------------------------------------
/RockLib.HealthChecks.AspNetCore/Collector/HealthMetricCollectorFactory.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace RockLib.HealthChecks.AspNetCore.Collector;
4 |
5 | ///
6 | /// Interface definition for the container of collectors. We use this to manage the lifecycle of collectors.
7 | ///
8 | /// factory is Singleton at runtime
9 | ///
10 | public interface IHealthMetricCollectorFactory
11 | {
12 | ///
13 | /// used by the health check middleware to right-size collectors (by name)
14 | ///
15 | ///
16 | ///
17 | internal void ConfigureCollector(string name, int? samples = null);
18 |
19 | ///
20 | /// Returns a handle to a collector by name
21 | ///
22 | ///
23 | ///
24 | public IHealthMetricCollector LeaseCollector(string? name);
25 |
26 | ///
27 | /// Returns all collectors held by the factory
28 | ///
29 | ///
30 | public Dictionary GetCollectors();
31 |
32 | ///
33 | /// Override the default sample size for new collectors
34 | ///
35 | ///
36 | public void SetDefaultSampleSize(int? samples);
37 | }
38 |
39 | ///
40 | /// A factory for accessing instances. The factory holds the collectors and manages their lifecycle.
41 | ///
42 | public class HealthMetricCollectorFactory : IHealthMetricCollectorFactory
43 | {
44 | private readonly Dictionary _collectors;
45 | private int _defaultSamples = 100;
46 |
47 | ///
48 | /// Default constructor - typically used by the DI container
49 | ///
50 | public HealthMetricCollectorFactory()
51 | {
52 | _collectors = new Dictionary();
53 | }
54 |
55 | ///
56 | /// Obtain a collector by name.
57 | /// If the collector does not exist it's created (w/size=100).
58 | ///
59 | ///
60 | ///
61 | public IHealthMetricCollector LeaseCollector(string? name)
62 | {
63 | name ??= string.Empty;
64 | if (_collectors.TryGetValue(name, out var value)) return value;
65 |
66 | value = new HealthMetricCollector(_defaultSamples);
67 | _collectors[name] = value;
68 | return value;
69 | }
70 |
71 | ///
72 | /// Exposes all collectors held by the factory
73 | ///
74 | ///
75 | public Dictionary GetCollectors()
76 | {
77 | return _collectors;
78 | }
79 |
80 | ///
81 | /// Set the default sample size for all collectors (w/o explicit size).
82 | ///
83 | ///
84 | public void SetDefaultSampleSize(int? samples)
85 | {
86 | _defaultSamples = samples ?? _defaultSamples;
87 | }
88 |
89 | ///
90 | /// Configure a collector by name with the given sample size.
91 | ///
92 | ///
93 | ///
94 | public void ConfigureCollector(string name, int? samples = null)
95 | {
96 | _collectors[name] = new HealthMetricCollector(samples ?? _defaultSamples);
97 | }
98 | }
--------------------------------------------------------------------------------
/RockLib.HealthChecks.AspNetCore/Collector/HttpResponseCollector.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net.Http;
3 | using System.Threading;
4 | using System.Threading.Tasks;
5 |
6 | namespace RockLib.HealthChecks.AspNetCore.Collector;
7 |
8 | ///
9 | /// A delegating handler that collects the status code of the response from an HTTP request.
10 | ///
11 | /// Added to the HttpClient pipeline to collect response status codes.
12 | public class HttpResponseCollector : DelegatingHandler
13 | {
14 | private readonly IHealthMetricCollectorFactory _factory;
15 |
16 | ///
17 | /// Initializes a new instance of the class.
18 | ///
19 | ///
20 | public HttpResponseCollector(IHealthMetricCollectorFactory factory)
21 | {
22 | _factory = factory;
23 | }
24 |
25 | ///
26 | /// Sends an HTTP request to the inner handler to send to the server as an asynchronous operation.
27 | /// Records the status code of the response in the for the host of the request.
28 | ///
29 | ///
30 | ///
31 | ///
32 | protected async override Task SendAsync(HttpRequestMessage request,
33 | CancellationToken cancellationToken)
34 | {
35 | #if NET6_0_OR_GREATER
36 | ArgumentNullException.ThrowIfNull(request);
37 | #else
38 | if (request is null) { throw new ArgumentNullException(nameof(request)); }
39 | #endif
40 | var response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
41 | _factory.LeaseCollector(request.RequestUri?.Host).Collect((int)response.StatusCode);
42 | return response;
43 | }
44 | }
--------------------------------------------------------------------------------
/RockLib.HealthChecks.AspNetCore/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | true
4 |
5 |
6 | all
7 | Rocket Mortgage
8 | Copyright 2025 (c) Rocket Mortgage. All rights reserved.
9 | latest
10 | enable
11 | net8.0;net48
12 | NU1603,NU1701
13 | true
14 |
15 |
16 |
17 | all
18 | runtime; build; native; contentfiles; analyzers; buildtransitive
19 |
20 |
21 |
--------------------------------------------------------------------------------
/RockLib.HealthChecks.AspNetCore/HealthCheckMiddlewareExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Builder;
2 | using Microsoft.AspNetCore.Http;
3 | using Microsoft.Extensions.Hosting;
4 | using System;
5 | using System.Linq;
6 |
7 | namespace RockLib.HealthChecks.AspNetCore;
8 |
9 | ///
10 | /// Extensions for using RockLib.HealthChecks with ASP.NET Core middleware.
11 | ///
12 | public static class HealthCheckMiddlewareExtensions
13 | {
14 | ///
15 | /// Adds a terminal to the application.
16 | ///
17 | /// The application builder.
18 | ///
19 | /// The name of the health runner that will perform health checks for the health endpoint.
20 | ///
21 | /// The route of the health endpoint.
22 | ///
23 | /// The responsible for formatting health responses for the middleware's HTTP response body.
24 | ///
25 | /// The application builder.
26 | public static IApplicationBuilder UseRockLibHealthChecks(this IApplicationBuilder builder,
27 | string healthCheckRunnerName = "", string route = "/health", IResponseFormatter? formatter = null)
28 | {
29 | #if NET6_0_OR_GREATER
30 | ArgumentNullException.ThrowIfNull(builder);
31 | ArgumentNullException.ThrowIfNull(healthCheckRunnerName);
32 | ArgumentNullException.ThrowIfNull(route);
33 | #else
34 | if (builder is null) { throw new ArgumentNullException(nameof(builder)); }
35 | if (healthCheckRunnerName is null) { throw new ArgumentNullException(nameof(healthCheckRunnerName)); }
36 | if (route is null) { throw new ArgumentNullException(nameof(route)); }
37 | #endif
38 |
39 | var path = new PathString($"/{route.Trim('/')}");
40 |
41 | return builder.Map(path, appBuilder =>
42 | appBuilder.UseMiddleware(healthCheckRunnerName, formatter ?? NewtonsoftJsonResponseFormatter.DefaultInstance));
43 | }
44 |
45 | ///
46 | /// Exposes a means for health check dependencies to be integrated into the application.
47 | ///
48 | /// the application builder
49 | /// The application builder.
50 | public static IHostApplicationBuilder ConfigureRockLibHealthChecks(this IHostApplicationBuilder builder)
51 | {
52 | #if NET6_0_OR_GREATER
53 | ArgumentNullException.ThrowIfNull(builder);
54 | #else
55 | if (builder is null) { throw new ArgumentNullException(nameof(builder)); }
56 | #endif
57 |
58 | var config = builder.Configuration.GetSection("RockLib.HealthChecks");
59 | var checks = config.GetSection("healthChecks").GetChildren().ToArray();
60 | foreach (var checkCfg in checks)
61 | {
62 | var typeStr = checkCfg["type"];
63 | if (string.IsNullOrWhiteSpace(typeStr)) continue;
64 |
65 | Type.GetType(typeStr)?.GetMethod("Configure")?.Invoke(null, [builder]);
66 | Console.WriteLine($"Configured health check: {typeStr}");
67 | }
68 |
69 | return builder;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/RockLib.HealthChecks.AspNetCore/IResponseFormatter.cs:
--------------------------------------------------------------------------------
1 | namespace RockLib.HealthChecks.AspNetCore;
2 |
3 | ///
4 | /// Defines an object that formats objects.
5 | ///
6 | public interface IResponseFormatter
7 | {
8 | ///
9 | /// Formats the specified .
10 | ///
11 | /// The to format.
12 | /// The formatted .
13 | string Format(HealthResponse healthResponse);
14 | }
15 |
--------------------------------------------------------------------------------
/RockLib.HealthChecks.AspNetCore/NewtonsoftJsonResponseFormatter.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System;
3 |
4 | namespace RockLib.HealthChecks.AspNetCore;
5 |
6 | ///
7 | /// An implementation of that formats health responses as draft
8 | /// RFC compliant JSON using Newtonsoft.Json.
9 | ///
10 | public class NewtonsoftJsonResponseFormatter : IResponseFormatter
11 | {
12 | internal static readonly NewtonsoftJsonResponseFormatter DefaultInstance = new NewtonsoftJsonResponseFormatter();
13 |
14 | ///
15 | /// Initializes a new instance of the class.
16 | ///
17 | /// The formatting options.
18 | /// The JSON serializer settings.
19 | public NewtonsoftJsonResponseFormatter(Formatting formatting = Formatting.None, JsonSerializerSettings? settings = null)
20 | {
21 | if (!Enum.IsDefined(typeof(Formatting), formatting))
22 | {
23 | throw new ArgumentOutOfRangeException(nameof(formatting));
24 | }
25 |
26 | Formatting = formatting;
27 | Settings = settings;
28 | }
29 |
30 | ///
31 | /// Gets the formatting options.
32 | ///
33 | public Formatting Formatting { get; }
34 |
35 | ///
36 | /// Gets the JSON serializer settings.
37 | ///
38 | public JsonSerializerSettings? Settings { get; }
39 |
40 | ///
41 | /// Formats the specified as draft RFC compliant JSON.
42 | ///
43 | /// The to format.
44 | /// The formatted .
45 | public string Format(HealthResponse healthResponse)
46 | {
47 | #if NET6_0_OR_GREATER
48 | ArgumentNullException.ThrowIfNull(healthResponse);
49 | #else
50 | if (healthResponse is null) { throw new ArgumentNullException(nameof(healthResponse)); }
51 | #endif
52 |
53 | return JsonConvert.SerializeObject(healthResponse, typeof(HealthResponse), Formatting, Settings);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/RockLib.HealthChecks.AspNetCore/RockLib.HealthChecks.AspNetCore.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Embedded
4 | A simple set of .NET Core Middleware extensions for adding Health Checks to your web application.
5 | True
6 | True
7 | icon.png
8 | RockLib.HealthChecks.AspNetCore
9 | LICENSE.md
10 | https://github.com/RockLib/RockLib.HealthChecks
11 | A changelog is available at https://github.com/RockLib/RockLib.HealthChecks/blob/main/RockLib.HealthChecks.AspNetCore/CHANGELOG.md.
12 | false
13 | rocklib health checks aspnetcore middleware
14 | 5.0.0
15 | True
16 | 5.0.0
17 |
18 |
19 | bin\$(Configuration)\$(TargetFramework)\$(PackageId).xml
20 |
21 |
22 | true
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/RockLib.HealthChecks.AspNetCore/RockLib.HealthChecks.AspNetCore.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.4.33110.190
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RockLib.HealthChecks.AspNetCore", "RockLib.HealthChecks.AspNetCore.csproj", "{2374AEAA-E75B-4C25-9CC0-54E214D1F772}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B551CDB9-DDCF-45A8-85EF-51EEB96E92DD}"
9 | EndProject
10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RockLib.HealthChecks.AspNetCore.Tests", "..\Tests\RockLib.HealthChecks.AspNetCore.Tests\RockLib.HealthChecks.AspNetCore.Tests.csproj", "{3B860C82-1B81-4E13-A1A7-1C690A19E138}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|Any CPU = Debug|Any CPU
15 | Release|Any CPU = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {2374AEAA-E75B-4C25-9CC0-54E214D1F772}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {2374AEAA-E75B-4C25-9CC0-54E214D1F772}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {2374AEAA-E75B-4C25-9CC0-54E214D1F772}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {2374AEAA-E75B-4C25-9CC0-54E214D1F772}.Release|Any CPU.Build.0 = Release|Any CPU
22 | {3B860C82-1B81-4E13-A1A7-1C690A19E138}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {3B860C82-1B81-4E13-A1A7-1C690A19E138}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {3B860C82-1B81-4E13-A1A7-1C690A19E138}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {3B860C82-1B81-4E13-A1A7-1C690A19E138}.Release|Any CPU.Build.0 = Release|Any CPU
26 | EndGlobalSection
27 | GlobalSection(SolutionProperties) = preSolution
28 | HideSolutionNode = FALSE
29 | EndGlobalSection
30 | GlobalSection(ExtensibilityGlobals) = postSolution
31 | SolutionGuid = {9BD2137B-45A2-4572-9151-93471F4F7CC9}
32 | EndGlobalSection
33 | EndGlobal
34 |
--------------------------------------------------------------------------------
/RockLib.HealthChecks.Client/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 |
6 | [*.cs]
7 | # Styling
8 | indent_style = space
9 | indent_size = 4
10 | csharp_indent_case_contents = true
11 | csharp_indent_switch_labels = true
12 | csharp_new_line_before_catch = true
13 | csharp_new_line_before_else = true
14 | csharp_new_line_before_finally = true
15 | csharp_new_line_before_members_in_anonymous_types = false
16 | csharp_new_line_before_members_in_object_initializers = false
17 | csharp_new_line_before_open_brace = methods, control_blocks, types, properties, lambdas, accessors, object_collection_array_initializers
18 | csharp_new_line_between_query_expression_clauses = true
19 | csharp_prefer_braces = false:suggestion
20 | csharp_prefer_simple_default_expression = true:suggestion
21 | csharp_preferred_modifier_order = public,private,internal,protected,static,readonly,async,override,sealed:suggestion
22 | csharp_preserve_single_line_blocks = true
23 | csharp_preserve_single_line_statements = true
24 | csharp_space_after_cast = false
25 | csharp_space_after_colon_in_inheritance_clause = true
26 | csharp_space_after_keywords_in_control_flow_statements = true
27 | csharp_space_before_colon_in_inheritance_clause = true
28 | csharp_space_between_method_call_empty_parameter_list_parentheses = false
29 | csharp_space_between_method_call_name_and_opening_parenthesis = false
30 | csharp_space_between_method_call_parameter_list_parentheses = false
31 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
32 | csharp_space_between_method_declaration_parameter_list_parentheses = false
33 | csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
34 | csharp_style_expression_bodied_accessors = true:suggestion
35 | csharp_style_expression_bodied_constructors = false:suggestion
36 | csharp_style_expression_bodied_methods = false:suggestion
37 | csharp_style_expression_bodied_properties = true:suggestion
38 | csharp_style_inlined_variable_declaration = true:suggestion
39 | csharp_style_var_elsewhere = true:suggestion
40 | csharp_style_var_for_built_in_types = true:suggestion
41 | csharp_style_var_when_type_is_apparent = true:suggestion
42 | dotnet_sort_system_directives_first = false
43 | dotnet_style_explicit_tuple_names = true:suggestion
44 | dotnet_style_object_initializer = true:suggestion
45 | csharp_style_pattern_local_over_anonymous_function = false:suggestion
46 | dotnet_style_predefined_type_for_member_access = true:suggestion
47 | dotnet_style_prefer_inferred_anonymous_type_member_names = false:suggestion
48 | dotnet_style_prefer_inferred_tuple_names = true:suggestion
49 | dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
50 | dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
51 | dotnet_style_qualification_for_field = false:suggestion
52 | dotnet_style_qualification_for_method = false:suggestion
53 | dotnet_style_qualification_for_property = false:suggestion
54 |
55 |
56 | # Analyzer Configuration
57 | # These are rules we want to either ignore or have set as suggestion or info
58 |
59 | # CA1014: Mark assemblies with CLSCompliant
60 | # https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1014
61 | dotnet_diagnostic.CA1014.severity = none
62 |
63 | # CA1725: Parameter names should match base declaration
64 | # https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1725
65 | dotnet_diagnostic.CA1725.severity = suggestion
66 |
67 | # CA2227: Collection properties should be read only
68 | # https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2227
69 | dotnet_diagnostic.CA2227.severity = suggestion
70 |
--------------------------------------------------------------------------------
/RockLib.HealthChecks.Client/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # RockLib.HealthChecks.Client Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## 3.0.0 - 2025-02-05
9 |
10 | #### Changed
11 | - Finalized 3.0.0 version
12 |
13 | ## 3.0.0-alpha.1 - 2025-02-05
14 |
15 | #### Changed
16 | - Removed .NET 6 as a target framework
17 |
18 | ## 2.0.2 - 2024-10-10
19 |
20 | #### Changed
21 | System.Text.Json.8.0.4 -> System.Text.Json.8.0.5 to fix vulnerability
22 |
23 | ## 2.0.1 - 2024-07-16
24 |
25 | #### Changed
26 | System.Text.Json.8.0.2 -> System.Text.Json.8.0.4 to fix vulnerability
27 |
28 | ## 2.0.0 - 2024-03-04
29 |
30 | #### Changed
31 | - Removed netcoreapp3.1 from supported targets.
32 | - Added net8.0 to supported targets.
33 | - Updated package references.
34 |
35 | ## 2.0.0-alpha.1 - 2024-02-29
36 |
37 | #### Changed
38 | - Removed netcoreapp3.1 from supported targets from test project.
39 | - Added net8.0 to supported targets to test project.
40 | - Updated package references in test project.
41 |
42 | ## 1.0.0 - 2022-03-03
43 |
44 | #### Added
45 | - Added `.editorconfig` and `Directory.Build.props` files to ensure consistency.
46 |
47 | #### Changed
48 | - Supported targets: net6.0, netcoreapp3.1, and net48.
49 | - As the package now uses nullable reference types, some method parameters now specify if they can accept nullable values.
50 |
51 | ## 1.0.0-alpha03 - 2021-08-13
52 |
53 | #### Changed
54 |
55 | - Changes "Quicken Loans" to "Rocket Mortgage".
56 |
57 | ## 1.0.0-alpha02 - 2021-05-10
58 |
59 | #### Added
60 |
61 | - Adds SourceLink to nuget package.
62 |
63 | #### Changed
64 |
65 | - Updates System.Text.Json package to latest version.
66 |
67 | ----
68 |
69 | **Note:** Release notes in the above format are not available for earlier versions of
70 | RockLib.HealthChecks.Client. What follows below are the original release notes.
71 |
72 | ----
73 |
74 | ## 1.0.0-alpha01
75 |
76 | Initial prerelease.
77 |
--------------------------------------------------------------------------------
/RockLib.HealthChecks.Client/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | true
4 |
5 |
6 | all
7 | Rocket Mortgage
8 | Copyright 2025 (c) Rocket Mortgage. All rights reserved.
9 | latest
10 | enable
11 | net8.0;net48
12 | NU1603,NU1701
13 | true
14 |
15 |
16 |
17 | all
18 | runtime; build; native; contentfiles; analyzers; buildtransitive
19 |
20 |
21 |
--------------------------------------------------------------------------------
/RockLib.HealthChecks.Client/HealthCheckResultJsonConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text.Json;
4 | using System.Text.Json.Serialization;
5 |
6 | namespace RockLib.HealthChecks.Client
7 | {
8 | ///
9 | /// A implementation for deserializing types from json.
10 | ///
11 | public class HealthCheckResultJsonConverter : JsonConverter
12 | {
13 | ///
14 | public override HealthCheckResult Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
15 | {
16 | if (reader.TokenType != JsonTokenType.StartObject)
17 | {
18 | throw new JsonException($"JsonTokenType was of type {reader.TokenType}, only objects are supported");
19 | }
20 |
21 | var result = new HealthCheckResult();
22 | while (reader.Read())
23 | {
24 | if (reader.TokenType == JsonTokenType.EndObject)
25 | {
26 | return result;
27 | }
28 |
29 | if (reader.TokenType != JsonTokenType.PropertyName)
30 | {
31 | throw new JsonException("JsonTokenType was not PropertyName");
32 | }
33 |
34 | var propertyName = reader.GetString()!;
35 |
36 | if (string.IsNullOrWhiteSpace(propertyName))
37 | {
38 | throw new JsonException("Failed to get property name");
39 | }
40 |
41 | reader.Read();
42 |
43 | result.Add(propertyName, ExtractValue(ref reader, options));
44 | }
45 |
46 | return result;
47 | }
48 |
49 | ///
50 | public override void Write(Utf8JsonWriter writer, HealthCheckResult value, JsonSerializerOptions options)
51 | {
52 | JsonSerializer.Serialize(writer, value, options);
53 | }
54 |
55 | private object? ExtractValue(ref Utf8JsonReader reader, JsonSerializerOptions options)
56 | {
57 | switch (reader.TokenType)
58 | {
59 | case JsonTokenType.String:
60 | if (reader.TryGetDateTime(out var date))
61 | {
62 | return date;
63 | }
64 | return reader.GetString();
65 | case JsonTokenType.False:
66 | return false;
67 | case JsonTokenType.True:
68 | return true;
69 | case JsonTokenType.Null:
70 | return null;
71 | case JsonTokenType.Number:
72 | if (reader.TryGetInt64(out var result))
73 | {
74 | return result;
75 | }
76 | return reader.GetDecimal();
77 | case JsonTokenType.StartObject:
78 | return Read(ref reader, null!, options);
79 | case JsonTokenType.StartArray:
80 | var list = new List