Monitoring
Metrics, the doctor checks, the Doctor page and the Capabilities page.
Harthelm tells you how it is doing three ways: the doctor (a list of checks you run, in a terminal or on the console's Doctor page), the Capabilities page (what the cluster offers), and Prometheus metrics.
The doctor
As a cluster admin:
hart admin doctorIt runs every check core can make from its own state and prints one line per check: ok, warn, fail or skip (a feature
that is switched off). The exit status is 1 when a check failed, so it fits a cron job or a CI step. -o json gives
the report as one document.
| Check | What it looks at |
|---|---|
database | The database answers and every migration of this release is applied. |
capabilities | The Kubernetes version and which optional components the hourly probe found. |
volume-uid | Every workspace volume belongs to security.defaultUid. |
custom-domains | Edge objects and a certificate source exist for custom domains. |
network-policy | The newest NetworkPolicy self-check, and every egress rule that opens its ports to every address. |
internal-tls | The in-cluster certificate is present, valid for core's Services, and not expiring within 14 days. |
mail | The mail relay answers. |
oidc | The issuer's discovery document answers. Since 1.5.0 a failure names a hint that fits its cause. |
backups | The last platform dump (late after 26 hours), workspace archive runs and the monthly restore check. |
jobs | Background jobs that used all attempts and gave up in the last 24 hours. |
routers | Routers connected to core and holding the current route table. |
license | The licence's state, its limits against what they count, the console host and the clock; since 1.5.0, without a licence in force, the installation id. See Licence. |
pull-secrets | The Secrets of global.imagePullSecrets and their copies in the team namespaces. Since 1.2.0. |
managed-images | The managed services' images are pinned by a digest that resolves. Since 1.3.0. |
managed-storage | The managed services' storage classes exist and allow volume expansion. Since 1.3.0. |
managed-backups | The backup pods reach every enabled managed service, and every instance with backups on has a dump of the last 26 hours. Since 1.3.0. |
managed-tls | With in-cluster TLS, cert-manager is installed and the managed services' certificates are issued and renewed. Since 1.3.0. |
managed-storage-write | A pod with the managed services' security context wrote and read a fresh volume of each class they use. Since 1.4.0. |
managed-s3-backup-space | The backup volume keeps 1.2 × what the S3 snapshots reference free; fails below a tenth. Since 1.4.0. |
managed-s3-blob-gc | The cleanup of unreferenced S3 backup data went through every snapshot directory within 48 hours. Since 1.4.0. |
What each result means and what to do: Troubleshooting. The same report is
GET /admin/doctor; see hart admin doctor.
The Doctor page
Since 1.5.0 the console runs the same checks under Platform → Doctor, between Capabilities and
Licence. Only cluster admins see the page; anyone else who opens its address is told that only cluster admins
can run the checks. It shows a table of the checks in the order of hart admin doctor, with the check's name, its
status (ok, warn, fail, or skip, greyed out) and its detail; above it, the count per status, when the checks
ran and how long that took, and the command that runs the same checks from a terminal.
Core runs every check each time the report is asked for, as with the command, so opening the page runs them, and Run again runs them once more (the last results stay visible, dimmed, until the new ones are in). The page never runs them on a timer or when you come back to the browser tab. Each check gets at most 10 seconds. There is no switch for the capability probe: what the cluster offers is on the Capabilities page, which the Doctor page links to.
Capabilities
hart admin doctor --capabilitiesadds what the cluster offers: the Kubernetes version and every optional feature with its state and, when it is not available, the reason. The console shows the same under Platform → Capabilities.
| Feature | Available when |
|---|---|
oidc | oidc.issuer is set |
mail | mail.smtp.host is set |
shared-volumes | workspace volumes are rwx |
agent-image-volume | image volumes work; otherwise the agent is copied by an init container |
managed-postgres | the CloudNativePG operator is installed and the provider is on |
managed-valkey, managed-mariadb, managed-rabbitmq, managed-s3 | the provider is on and has an image (since 1.3.0) |
custom-domains | customDomains.enabled and an edge |
automated-certificates | cert-manager and customDomains.issuer |
gateway-api | the HTTPRoute CRD and routing.gatewayAPI.parentRefs |
network-policies | the self-check passed, endPort included |
cilium-policies | Cilium, for the per-team backstop |
admission-guard | ValidatingAdmissionPolicy is served and security.admissionGuard.enabled |
internal-tls | internal.tls is on and the certificate is mounted |
platform-backups | backup.enabled |
workspace-archives | backup.workspaces.enabled |
service-monitors | the Prometheus Operator is installed |
Features that need a missing component are greyed out in the console instead of failing. The probe runs at core's start and hourly.
Metrics
Core and the routers serve Prometheus metrics on port 9090 at /metrics. Let your scraper in with
networkPolicy.metricsNamespaceSelector:
networkPolicy:
metricsNamespaceSelector: {kubernetes.io/metadata.name: monitoring}The families:
| Prefix | From | Examples |
|---|---|---|
harthelm_backup_ | core | harthelm_backup_last_success_timestamp_seconds, harthelm_backup_last_run_failed, harthelm_backup_last_size_bytes per kind and target |
harthelm_core_ | core | harthelm_core_agent_channels, harthelm_core_route_streams, harthelm_core_sleeps_total, harthelm_core_internal_plain_requests_total |
harthelm_jobs_ | core | harthelm_jobs_queue, harthelm_jobs_running, harthelm_jobs_finished_total, harthelm_jobs_leader |
harthelm_reconcile_ | core | harthelm_reconcile_writes_total, harthelm_reconcile_orphans |
harthelm_scheduling_ | core | harthelm_scheduling_sleeps_total, harthelm_scheduling_always_on_wakes_total |
harthelm_gitproxy_ | core | harthelm_gitproxy_requests_total, harthelm_gitproxy_upstream_failures_total |
harthelm_mail_ | core | harthelm_mail_messages_total |
harthelm_license_ | core | harthelm_license_state, harthelm_license_expiry_timestamp_seconds, harthelm_license_usage, harthelm_license_limit |
harthelm_router_ | router | harthelm_router_requests_total, harthelm_router_wake_seconds, harthelm_router_workspaces, harthelm_router_managed_hosts, harthelm_router_stream_reconnects_total |
The bundled database's exporter (CloudNativePG) listens on 9187; extra queries go in
database.bundled.monitoring.customQueries.
Alerts to start with
groups:
- name: harthelm
rules:
- alert: HarthelmBackupFailed
expr: harthelm_backup_last_run_failed == 1
- alert: HarthelmBackupMissed
expr: time() - harthelm_backup_last_success_timestamp_seconds{kind="platform"} > 26 * 3600Run hart admin doctor on a schedule as well, and alert on its exit status: it covers what metrics do not (certificate
expiry, the identity provider, the mail relay).