Skip to content

javaChip56/EndpointHealthCheck

Repository files navigation

ApiHealthDashboard

Portable ASP.NET Core Razor Pages dashboard for monitoring API health check endpoints.

This project is being built to:

  • poll configured health endpoints directly over HTTP
  • parse JSON health responses without Xabaril UI libraries
  • render a local-only AdminLTE dashboard
  • load endpoint definitions from YAML
  • keep active runtime state in memory with optional per-endpoint file persistence for current state
  • stay portable for internal and restricted environments

Current Status

Implemented so far:

  • Phase 1: solution bootstrap
  • Phase 2: local AdminLTE layout and placeholder pages
  • Phase 3: YAML configuration models, loader, validation, and tests
  • Phase 4: in-memory runtime state store and tests
  • Phase 5: HTTP endpoint poller and tests
  • Phase 6: health response parser and tests
  • Phase 7: background polling scheduler and tests
  • Phase 8: manual refresh actions and page-model tests
  • Phase 9: dashboard summary view and tests
  • Phase 10: endpoint details diagnostics view and tests
  • Phase 11: error handling and structured logging improvements
  • Phase 12: automated test expansion for invalid and edge-case coverage
  • Phase 13: publish and deployment validation
  • Phase 14: GitHub Actions CI/CD and Dependabot automation
  • Post-v1: endpoint import flow with live probe, YAML preview, and diff comparison
  • Post-v1: CLI execution mode with JSON/XML reporting
  • Post-v1: YAML hot-reload for dashboard and endpoint files
  • Post-v1: per-endpoint current-state persistence with compact JSON files
  • Post-v1: runtime-state cleanup and retention settings for orphaned persisted state files
  • Post-v1: recent poll sample retention with derived dashboard and details metrics
  • Post-v1: mini trend visuals and short status history from retained runtime samples
  • Post-v1: SMTP email notifications with dashboard defaults and per-endpoint recipients
  • Post-v1: persisted notification dispatch history in runtime state

Not implemented yet:

  • Backlog items tracked for post-v1 work

Solution Layout

.
|-- ApiHealthDashboard.sln
|-- README.md
|-- src/
|   `-- ApiHealthDashboard/
|       |-- Configuration/
|       |-- Domain/
|       |-- Parsing/
|       |-- Scheduling/
|       |-- Services/
|       |-- State/
|       |-- Pages/
|       |-- wwwroot/
|       |-- dashboard.yaml
|       `-- endpoints/
`-- tests/
    `-- ApiHealthDashboard.Tests/

Tech Stack

  • .NET 8
  • ASP.NET Core Razor Pages
  • AdminLTE v3.2.0 bundled locally
  • YamlDotNet
  • xUnit

Current Features

Local AdminLTE Shell

The app uses locally bundled AdminLTE assets under src/ApiHealthDashboard/wwwroot/adminlte.

Current UI pages:

YAML Configuration

Dashboard configuration is loaded at startup from src/ApiHealthDashboard/dashboard.yaml.

Current configuration support:

  • dashboard.refreshUiSeconds
  • dashboard.requestTimeoutSecondsDefault
  • dashboard.showRawPayload
  • dashboard.endpointFiles for loading endpoints from one or more separate YAML files
  • dashboard.notifications.enabled, notifyOnRecovery, cooldownMinutes, minimumPriority, subjectPrefix, to, and cc
  • endpoint id, name, url, enabled, frequencySeconds, timeoutSeconds
  • endpoint priority with Critical, High, Normal, or Low
  • endpoint headers, includeChecks, excludeChecks
  • endpoint notificationEmails and notificationCc
  • ${ENV_VAR} substitution in YAML values
  • endpoint definitions can be kept inline in dashboard.yaml or split into multiple files under src/ApiHealthDashboard/endpoints
  • project YAML files are copied to both build and publish output by default
  • runtime changes to dashboard.yaml and referenced endpoint YAML files are watched and hot-reloaded without restarting the app

Validation currently checks:

  • required endpoint id, name, and url
  • unique endpoint ids
  • absolute HTTP/HTTPS URLs only
  • positive refresh, frequency, and timeout values
  • non-empty header names

Runtime State Store

The app now includes a runtime endpoint state store with an in-memory cache and optional per-endpoint current-state persistence.

Current runtime models:

State store components:

Current behavior:

  • initializes one runtime state entry per configured endpoint at startup
  • keeps active runtime state in memory for fast reads by pages and the scheduler
  • can persist the latest current state for each endpoint to a compact JSON file under a configurable runtime-state directory
  • restores persisted current state on startup for configured endpoints and resets any stale IsPolling flag to false
  • persists successful email notification dispatch history alongside endpoint runtime state so cooldown survives restarts
  • can clean up orphaned persisted state files on a configurable interval after a configurable retention window
  • retains a configurable rolling window of recent poll samples per endpoint for derived runtime metrics
  • retains a configurable rolling window of recent notification dispatch records per endpoint
  • supports get-all, get-one, upsert, and reinitialize operations
  • returns deep copies so callers cannot mutate internal store state accidentally
  • uses thread-safe locking for concurrent access

HTTP Poller

The app now includes an HttpClientFactory-based endpoint poller for individual health endpoint requests.

Poller components:

Current behavior:

  • performs async HTTP GET requests for configured endpoints
  • uses per-endpoint timeout with fallback to the dashboard default timeout
  • applies configured request headers
  • captures check time, duration, HTTP status, response body, and error message
  • distinguishes success, timeout, network failure, HTTP failure, empty response, and unknown failure
  • avoids logging secret header values

Health Response Parser

The app now includes a JSON health response parser that normalizes flexible payload shapes into recursive runtime models.

Parser components:

Current behavior:

  • parses simple top-level health payloads with an overall status
  • parses entries dictionaries common in ASP.NET Core health endpoint output
  • parses nested child structures recursively
  • preserves useful extra fields in snapshot metadata and node data
  • applies per-endpoint includeChecks and excludeChecks filtering
  • returns a parser-error snapshot instead of crashing on malformed JSON

Polling Scheduler

The app now includes a hosted background scheduler for per-endpoint polling loops.

Scheduler components:

Current behavior:

  • starts one polling loop per enabled endpoint
  • respects each endpoint's own polling frequency
  • prevents overlapping polls for the same endpoint with endpoint-level locking
  • updates runtime state before and after each poll
  • records last checked time, last successful time, duration, status, and current error
  • triggers email notifications when an endpoint enters a problem state, changes alert state, or recovers
  • keeps slow endpoints from blocking other endpoint loops
  • already exposes a scheduler interface that Phase 8 can reuse for manual refresh actions
  • restarts enabled polling loops automatically when YAML hot-reload changes the configured endpoint set

YAML Hot-Reload

The web app now watches the dashboard YAML and referenced endpoint YAML files for runtime changes.

Current hot-reload behavior:

  • detects create, update, delete, and rename events for dashboard.yaml and referenced endpoint YAML files
  • reloads configuration with a short debounce to avoid duplicate reload storms while saving
  • applies the new config without restarting the app when YAML stays valid
  • keeps the last successfully loaded config active if a reload fails
  • updates the visible configuration warning banner when reload warnings or failures occur
  • preserves runtime status for endpoints that still exist after a reload and initializes new endpoints as Unknown

Manual Refresh Actions

The dashboard and endpoint details pages now expose working manual refresh actions through Razor Pages handlers.

Current manual refresh behavior:

  • dashboard supports refresh-all and refresh-single-endpoint actions
  • endpoint details page supports refresh for the current endpoint
  • refresh actions reuse the scheduler interface instead of duplicating poll logic
  • user feedback is shown through page status messages after each action
  • dashboard and details pages now read live configured endpoints and current runtime state instead of hard-coded placeholder rows

Dashboard Summary

The dashboard home page now acts as an operational summary instead of a transitional placeholder.

Current dashboard behavior:

  • shows configured, enabled, disabled, and actively polling endpoint counts
  • highlights healthy, degraded, unhealthy, and unknown totals in summary cards
  • includes a client-side search field for filtering endpoint rows by name, id, status, or error text
  • refreshes the live dashboard section with same-origin timed GET requests instead of reloading the whole page
  • briefly flashes endpoint rows when they are manually refreshed or when background polling updates change the rendered row state
  • uses different row flash cues for routine updates, improving health transitions, and worsening health transitions
  • shows a compact recent-status indicator strip plus a short trend label for each endpoint
  • sorts endpoint summaries and active issues by endpoint priority before name
  • renders a live endpoint table with last check, duration, recent signal metrics, error summary, and manual refresh actions
  • surfaces degraded and unhealthy endpoints in an active issues panel for faster triage
  • shows a clearer empty state when no endpoints are configured

Endpoint Import Flow

The app now includes an endpoint import preview flow for deriving YAML from a live API probe without writing files automatically.

Current import behavior:

  • sends a live request using the entered URL, headers, timeout, and enabled/frequency settings
  • auto-suggests endpoint id and name when those fields are left blank
  • shows a soft warning when the chosen poll frequency is below the configured appsettings recommendation
  • emits generated YAML with a normalized endpoint priority value
  • allows notification recipients and per-endpoint CC recipients to be entered and included in generated YAML
  • parses discovered checks from the response and can optionally populate includeChecks
  • generates a normalized YAML snippet for manual copy into dashboard.yaml or a separate endpoint file
  • compares the generated YAML against the currently loaded config when an existing endpoint matches by id or URL
  • shows a diff preview plus a raw response preview for review before any manual save

Email Notifications

The app now supports SMTP email notifications with dashboard-level defaults and per-endpoint recipient overrides.

Current email notification behavior:

  • uses SMTP settings from appsettings under Email:Smtp
  • uses file-based email templates from Email:Templates with defaults under src/ApiHealthDashboard/Templates/Email
  • uses dashboard YAML settings to enable notifications, set recovery behavior, cooldown, minimum priority, subject prefix, and default recipients
  • merges global dashboard recipients with endpoint-specific notificationEmails and notificationCc
  • sends alert emails when an endpoint enters or changes problem state
  • can send recovery emails when an endpoint returns to a non-problem state
  • can send a one-time Stabilized email when an endpoint settles into a Stable ... trend after recovering
  • sends multipart email with HTML content plus a plain-text fallback body
  • treats repeated transport failures as a Failing condition for alerting purposes
  • records successful dispatches in endpoint runtime state so notification cooldown and history survive restarts

CLI Execution

The app now includes a one-shot CLI mode for scripted health execution without starting the web UI.

Current CLI behavior:

  • executes the full configured suite with --cli --all
  • executes one or more specific endpoint YAML files with repeated --endpoint-file arguments
  • reuses dashboard settings from dashboard.yaml, including default request timeout values
  • writes a machine-readable JSON report to standard output
  • includes endpoint priority in JSON and XML execution reports
  • can optionally write the same execution report to a JSON or XML file
  • keeps missing dashboard or endpoint YAML files as warnings in the output instead of failing hard

Endpoint Details

The endpoint details page now acts as a diagnostic view for a single configured endpoint.

Current details-page behavior:

  • shows endpoint metadata including enabled state, priority, frequency, timeout, and masked request headers
  • shows request filter configuration for included and excluded checks
  • summarizes the latest poll with status, timings, retrieved timestamp, and current error
  • shows retained recent sample metrics including success rate, failure count, average duration, last status change, and a short trend summary
  • shows a short recent status history with the latest observed status transitions
  • shows recent successful notification dispatch history with event type, condition, timestamp, and recipients
  • renders top-level and nested health checks recursively with native expand and collapse support
  • surfaces snapshot metadata captured from the parsed response
  • shows the raw payload section only when enabled in configuration

Error Handling And Logging

The app now emits clearer structured logs around startup, configuration loading, polling, parsing failures, and manual refresh actions.

Current logging behavior:

  • logs startup initialization begin, completion, app-started, and app-stopping events
  • logs configuration load attempts, success, and startup-failure cases with the resolved YAML path
  • logs manual refresh requests from both the dashboard and endpoint details pages
  • logs poll start and completion with trigger source, duration, result kind, and HTTP status code when available
  • logs timeout, network, HTTP, parser, and scheduler-loop failure conditions without exposing secret header values

Automated Test Coverage

The test suite now covers both core happy paths and a wider set of invalid and operational edge cases.

Recent test expansion includes:

  • isolated dashboard configuration validator tests
  • YAML loader missing-file and malformed-YAML cases
  • parser coverage for unknown-field preservation and recursive exclusion filtering
  • poller coverage for unexpected failures and caller-driven cancellation
  • scheduler coverage for parser-error snapshots and refresh-all enabled-endpoint counting
  • page-model coverage for default details routing and missing endpoint-id refresh actions

Publish And Deployment Validation

The app has now been validated as a portable publishable deployment, not just a local source checkout.

Validated deployment behavior:

  • framework-dependent publish completes successfully
  • self-contained Windows win-x64 publish completes successfully
  • published output includes dashboard.yaml, endpoint YAML files, appsettings.json, and bundled local AdminLTE assets
  • both published variants run directly from their publish folders and return HTTP 200 for /
  • bundled CSS assets load from the published folders without relying on external CDNs
  • no database package or runtime dependency is required
  • no Node.js, npm, yarn, or frontend build tool dependency is required

GitHub Actions And Dependabot

The repository now includes automation for CI, CodeQL scanning, release packaging, and dependency updates.

Current automation files:

Current automation behavior:

  • CI runs on pushes to master, develop, and enhancements, and on pull requests targeting those branches
  • CI restores, builds in Release mode, runs tests, and uploads TRX test results
  • CodeQL runs for C# on pushes to master, develop, and enhancements, pull requests targeting those branches, and manual dispatches
  • Release automation verifies the solution, publishes self-contained artifacts for win-x64 and linux-x64, packages them, generates checksums, and uploads them to the GitHub release
  • Dependabot monitors both NuGet dependencies and GitHub Actions workflow dependencies on a weekly schedule

Running The App

From the repository root:

dotnet run --project .\src\ApiHealthDashboard\ApiHealthDashboard.csproj

The app reads the dashboard YAML path from the Bootstrap:DashboardConfigPath setting in:

The current primary setting is Bootstrap:DashboardConfigPath. Bootstrap:EndpointsConfigPath is still accepted as a legacy fallback.

Runtime state persistence is configured through RuntimeState:Enabled and RuntimeState:DirectoryPath in the same appsettings files. By default, the app writes compact per-endpoint current-state files under runtime-state/endpoints relative to the app content root.

SMTP email delivery is configured through Email:Smtp in the same appsettings files. Keep secrets such as SMTP usernames and passwords in environment variables or deployment-time configuration rather than committing them to source control.

Email template rendering is configured through Email:Templates in the same appsettings files. By default, the app loads notification.txt and notification.html from Templates/Email under the app content root.

Current cleanup settings:

  • RuntimeState:CleanupEnabled to enable periodic runtime-state cleanup
  • RuntimeState:CleanupIntervalMinutes to control how often orphan cleanup runs
  • RuntimeState:DeleteOrphanedStateFiles to enable deletion of persisted state files that no longer belong to configured endpoints
  • RuntimeState:OrphanedStateFileRetentionHours to keep orphaned state files for a configurable grace period before deletion
  • RuntimeState:RecentSampleLimit to cap how many recent poll samples are retained per endpoint
  • RuntimeState:NotificationHistoryLimit to cap how many notification dispatch records are retained per endpoint

You can also override it with an environment variable:

$env:APIHEALTHDASHBOARD_BOOTSTRAP__DASHBOARDCONFIGPATH="D:\path\to\dashboard.yaml"
dotnet run --project .\src\ApiHealthDashboard\ApiHealthDashboard.csproj

Running The CLI

Run the full suite and print JSON to stdout:

dotnet run --project .\src\ApiHealthDashboard\ApiHealthDashboard.csproj --no-build --no-launch-profile -- --cli --all

Run only selected endpoint YAML files:

dotnet run --project .\src\ApiHealthDashboard\ApiHealthDashboard.csproj --no-build --no-launch-profile -- --cli --endpoint-file .\src\ApiHealthDashboard\endpoints\orders-api.yaml --endpoint-file .\src\ApiHealthDashboard\endpoints\billing-api.yaml

Write a JSON or XML file in addition to the JSON stdout output:

dotnet run --project .\src\ApiHealthDashboard\ApiHealthDashboard.csproj --no-build --no-launch-profile -- --cli --all --output-file .\artifacts\health-report.json
dotnet run --project .\src\ApiHealthDashboard\ApiHealthDashboard.csproj --no-build --no-launch-profile -- --cli --all --output-file .\artifacts\health-report.xml --output-format xml

For the cleanest machine-readable stdout, prefer a published build or dotnet run with both --no-build and --no-launch-profile.

Optional CLI arguments:

  • --dashboard-config <path> to override the dashboard YAML path
  • --all to execute the whole configured suite
  • --endpoint-file <path> to execute only selected endpoint YAML files
  • --output-file <path> to persist the report to disk
  • --output-format json|xml to choose file output format

Running Tests

dotnet test .\ApiHealthDashboard.sln -c Release

Publishing

Framework-dependent publish:

dotnet publish .\src\ApiHealthDashboard\ApiHealthDashboard.csproj -c Release --self-contained false

Self-contained Windows publish:

dotnet publish .\src\ApiHealthDashboard\ApiHealthDashboard.csproj -c Release -r win-x64 --self-contained true

Deployment notes:

  • the published folder is runnable on its own with the included dashboard.yaml and endpoint YAML files
  • local UI assets under wwwroot/adminlte remain bundled after publish
  • no additional database or Node.js setup is required for the published app

CI/CD Automation

Repository automation now includes:

  • CI build and test workflow for master, develop, and enhancements
  • CodeQL SAST workflow for C#
  • release packaging workflow for self-contained GitHub release artifacts
  • Dependabot configuration for NuGet and GitHub Actions dependencies

Release flow:

  1. Create and push a version tag such as v1.0.1
  2. GitHub Actions runs the release workflow automatically
  3. The workflow verifies build and tests, publishes win-x64 and linux-x64 self-contained outputs, packages them, and generates .sha256 checksum files
  4. The packaged artifacts are attached to the GitHub release

Manual release flow:

  • Run the Release workflow from GitHub Actions with a release_version
  • Optionally enable GitHub release upload from the workflow-dispatch input

Local note:

  • the workflow files were added and reviewed locally, and the application build still passes, but this shell environment does not include a YAML workflow linter for direct execution-free validation

Current automated coverage includes:

  • CLI option parsing and validation
  • CLI report JSON and XML serialization
  • CLI execution summary generation for full-suite and selected-endpoint runs
  • valid YAML load
  • normalization of null optional collections
  • missing configuration file handling
  • malformed YAML handling
  • duplicate endpoint id validation
  • invalid value aggregation
  • isolated validator success and invalid-case checks
  • environment variable substitution
  • runtime state initialization
  • runtime state upsert and deep-copy safety
  • runtime state reinitialization
  • runtime state concurrent update behavior
  • poller success handling
  • poller timeout handling
  • poller network failure handling
  • poller non-success HTTP status handling
  • poller empty-response handling
  • poller request header application
  • parser flat payload handling
  • parser entries payload handling
  • parser nested payload handling
  • parser recursive filtering behavior
  • parser malformed JSON handling
  • parser malformed JSON warning logging
  • parser extra metadata preservation
  • parser recursive exclusion filtering
  • scheduler state update handling
  • scheduler overlap prevention
  • scheduler independent polling for enabled endpoints only
  • scheduler refresh-all enabled-count behavior
  • scheduler parser-error snapshot persistence
  • dashboard page-model mixed counter and problem-endpoint calculation
  • dashboard page-model empty dashboard state handling
  • dashboard page-model missing endpoint-id refresh handling
  • dashboard page-model refresh-all behavior
  • dashboard page-model refresh-single behavior
  • endpoint details page-model default endpoint resolution
  • endpoint details page-model no-endpoint refresh handling
  • endpoint details page-model diagnostic summary loading
  • endpoint details raw-payload visibility rules
  • endpoint details page-model refresh behavior
  • endpoint details not-found behavior

Test file:

Important Constraints

  • Do not use Xabaril health check UI packages
  • Do not rely on CDN-hosted frontend assets
  • Do not require a database
  • Keep active runtime state in memory and persisted runtime files lightweight
  • Prefer small, focused services

Development Progress

  • Phase 1 - Solution bootstrap
  • Phase 2 - Local AdminLTE integration
  • Phase 3 - YAML configuration loader
  • Phase 4 - Runtime state store
  • Phase 5 - HTTP poller
  • Phase 6 - Health response parser
  • Phase 7 - Polling scheduler
  • Phase 8 - Manual refresh actions
  • Phase 9 - Dashboard summary page
  • Phase 10 - Endpoint details page
  • Phase 11 - Error handling and logging
  • Phase 12 - Automated tests expansion
  • Phase 13 - Publish and deployment validation
  • Phase 14 - GitHub Actions CI/CD

Future Plans

These are planned enhancements after the current v1 path:

  • add configurable retention controls for future persisted history files once trend capture is introduced
  • optionally add per-endpoint history files once the embedded recent-sample window is no longer sufficient
  • optionally add external email API delivery in addition to the current SMTP implementation

Notes For Ongoing Updates

This README is intended to evolve with the project. As new phases land, we should keep these sections current:

  • implemented features
  • run and configuration instructions
  • test coverage
  • development progress checklist
  • deployment and CI/CD notes

About

Ligh-weight API Endpoint Health Check Dashboard.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors