Skip to content

Health check api - #5952

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

hazel-bohon wants to merge 3 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.

var hasConnector = connectorHeartbeatStatus.LastHeartbeat != null;
try
{
var license = await licenseInfoProvider.GetLicense(true, "servicepulse", cancellationToken);
Co-authored-by: hazel-bohon <2416062+hazel-bohon@users.noreply.github.com>
Comment thread docs/platform-health.md

Association uses case-insensitive instance name plus reporting host ID. A legacy remote without a host ID can use a name match only when there is one matching inventory row and one reporting host with that name. Ambiguous or unmatched reports remain in root `alerts` without `instance_id`; they are never assigned to several rows. Consumers should retain a place to display those unassigned alerts.

The legacy summary describes captured checks, not the whole browser-visible platform: `status` is `unknown` before any internal report, `healthy` when none are failing, and `unhealthy` when at least one is failing. Its corresponding `severity` values are `unknown`, `none`, and `error`. ServicePulse should use per-instance health for page severity and combine it with its independently observed monitoring state. The legacy summary does not account for monitoring, browser connectivity, license expiry, or available upgrades.

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 seems to conflict with the health field above that gives degraded for instances with failures.

How is severity determined? I do not see anything in the table above that gives an indication of issue serverity.

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

### License

`license.availability` is `available` after a successful refresh and `unavailable` when license details cannot be refreshed. An unavailable license never claims to be valid and does not suppress instance health.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Is the license something currently checked by the Custom Checks health checks? From what I see in the task adding a license api is out of scope.

If we want to expand scope and add this it could be in a separate PR to keep the work for each new API clear.

Comment thread docs/README.md
- [Retries over Azure Storage Queues transport](retries-asq-transport.md) — transport-specific retry handling
- [Data versioning design](data-versioning-design.md) — the cache-versioning invariant for API responses
- [Event log design](eventlog-design.md) — what the event log is and what it records
- [Platform health API](platform-health.md) — how ServicePulse reads internal health independently from customer custom checks

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
- [Platform health API](platform-health.md) — how ServicePulse reads internal health independently from customer custom checks
- [Platform health API](platform-health.md) — how ServicePulse can read internal health independently from customer custom checks

public Guid HostId { get; set; }
}

#nullable enable

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 is this not applied for the entire file?

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.

4 participants