Skip to content

Health check api - #5952

Draft
hazel-bohon wants to merge 8 commits into
masterfrom
health-check-api
Draft

hazel-bohon wants to merge 8 commits into
masterfrom
health-check-api

Conversation

@hazel-bohon

@hazel-bohon hazel-bohon commented Oct 5, 2026 •

Copy link
Copy Markdown

hazel-bohon

This comment was marked as duplicate.

@hazel-bohon
hazel-bohon requested review from afprtclr and mchamberlin77 and a balanced review from Copilot October 5, 2026 16:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Five-second polling currently forces license discovery and persistence access for every open ServicePulse client.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Adds a dedicated Platform Health API for ServicePulse, separating internal health reporting from customer custom checks.

Changes:

  • Adds platform health inventory, alerts, licensing, and remote-instance metadata.
  • Extends configuration discovery and remote probing.
  • Adds unit, acceptance, authorization, and API approval coverage.

Reviewed against issue #5860, docs/platform-health.md, and the linked ServicePulse models/store. No private context was provided.

File Description
src/​ServiceControl/​ServiceControlApiHostBuilderExtensions.cs Registers license information provider.
src/​ServiceControl/​PlatformHealth/​PlatformHealthState.cs Tracks internal health-check state.
src/​ServiceControl/​PlatformHealth/​PlatformHealthController.cs Exposes the health endpoint.
src/​ServiceControl/​PlatformHealth/​PlatformHealthApi.cs Builds platform health responses.
src/​ServiceControl/​PlatformHealth.http Adds manual API requests.
src/​ServiceControl/​Licensing/​LicenseInfoProvider.cs Extracts shared license mapping.
src/​ServiceControl/​Licensing/​LicenseController.cs Uses the shared provider.
src/​ServiceControl/​Infrastructure/​WebApi/​RemoteInstanceServiceCollectionExtensions.cs Preserves remote URL prefixes.
src/​ServiceControl/​Infrastructure/​Api/​ConfigurationApi.cs Adds discovery metadata and robust remote probing.
src/​ServiceControl/​CustomChecks/​CustomChecksComponent.cs Registers platform health services.
src/​ServiceControl/​CustomChecks/​CustomCheckResultProcessor.cs Records internal health reports.
src/​ServiceControl.UnitTests/​ScatterGather/​RemoteInstanceHttpClientTests.cs Tests remote configuration requests.
src/​ServiceControl.UnitTests/​PlatformHealth/​PlatformHealthStateTests.cs Tests health-state behavior.
src/​ServiceControl.UnitTests/​PlatformHealth/​PlatformHealthApiTests.cs Tests response assembly and failures.
src/​ServiceControl.UnitTests/​Licensing/​ActiveLicenseTests.cs Tests extracted license mapping.
src/​ServiceControl.UnitTests/​ApprovalFiles/​APIApprovals.RootPathValue.approved.txt Approves discovery URL addition.
src/​ServiceControl.UnitTests/​ApprovalFiles/​APIApprovals.HttpApiRoutes.approved.txt Approves the new route.
src/​ServiceControl.UnitTests/​API/​APIApprovals.cs Tests primary configuration metadata.
src/​ServiceControl.MultiInstance.AcceptanceTests/​Infrastructure/​When_inspecting_platform_health.cs Exercises multi-instance health behavior.
src/​ServiceControl.Audit/​Infrastructure/​WebApi/​RootController.cs Publishes audit identity metadata.
src/​ServiceControl.Audit.UnitTests/​API/​APIApprovals.cs Tests audit configuration metadata.
src/​ServiceControl.Api/​IPlatformHealthApi.cs Defines the health API abstraction.
src/​ServiceControl.Api/​Contracts/​RootUrls.cs Advertises platform health discovery.
src/​ServiceControl.Api/​Contracts/​PlatformHealthView.cs Defines response contracts.
src/​ServiceControl.AcceptanceTests/​WebApi/​When_the_configuration_page_is_read.cs Verifies configuration metadata.
src/​ServiceControl.AcceptanceTests/​Security/​OpenIdConnect/​When_authentication_is_enabled.cs Verifies endpoint authorization.
src/​ServiceControl.AcceptanceTests/​Monitoring/​CustomChecks/​When_custom_checks_are_classified.cs Verifies health/custom-check separation.
docs/​README.md Indexes the design documentation.
docs/​platform-health.md Documents the API contract and rationale.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/ServiceControl/PlatformHealth/PlatformHealthApi.cs Outdated
Co-authored-by: hazel-bohon <2416062+hazel-bohon@users.noreply.github.com>
Comment thread docs/platform-health.md Outdated
Comment thread docs/platform-health.md
Comment on lines +29 to +30
| `transport_type`, `error_queue`, `error_log_queue`, `forward_error_messages` | Available transport configuration; a known `false` forwarding setting is preserved |
| `audit_queue`, `audit_log_queue`, `forward_audit_messages` | Available audit transport configuration |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these multiple fields listed in the same row? They read like the possible values for a field and not the field name themselves.

Comment thread docs/platform-health.md Outdated
Comment thread docs/README.md Outdated
Comment thread src/ServiceControl.Api/Contracts/PlatformHealthView.cs Outdated
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Application settings might contain remote URLs with /api. We strip that away to be a real base address.
client.BaseAddress = new Uri(remoteInstance.BaseAddress);
client.BaseAddress = new Uri(remoteInstance.BaseAddress.TrimEnd('/') + "/");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change does not make sense.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It ensures that there's a "/" but not a double slash at the end of the base url.

Comment thread src/ServiceControl/CustomChecks/CustomCheckResultProcessor.cs Outdated
{
using var response = await httpClient.GetAsync("/api/configuration", cancellationToken);
using var response = await httpClient.GetAsync("api/configuration", cancellationToken);
response.EnsureSuccessStatusCode();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this changes the behavior. Previously, a non-200 response was considered "online" but now it's "unavailable". That might affect consumers. I think both AuditThroughput/AuditQuery.cs and AuditThroughputCollectorHostedService.cs are good, but maybe I missed something else.

return new PlatformHealthInstance
{
Id = remote.InstanceId,
Name = new Uri(remote.BaseAddress).Host,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can fail if the address is invalid. Probably worth wrapping with try+catch or other validation.

static DateTimeOffset? ParseDate(string value) =>
DateTimeOffset.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out var date) ? date : null;

readonly ConcurrentDictionary<string, PlatformHealthInstance> lastKnownRemotes = new(StringComparer.Ordinal);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this dictionary is never cleared? I'm not sure if we ever get "way too many" of those, but wanted to mention that.

Co-authored-by: hazel-bohon <2416062+hazel-bohon@users.noreply.github.com>
var patch = new PatchByQueryOperation(query, new QueryOperationOptions
{
AllowStale = true,
AllowStale = false,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this need to be changed?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes to the license api should be in a sperate PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants