Loading…
Loading…
Technical reference for the Specaria Heartbeat Client, which sends periodic liveness and telemetry data to the Specaria platform for license validation.
The SpecariaHeartbeatClient is a system component responsible for sending periodic liveness and telemetry data to the Specaria platform API. This process, known as a "heartbeat," serves as a proof-of-liveness for an active installation and provides usage metrics that are compared against license entitlements.
The client is triggered on a daily schedule and also once upon application startup. It gathers a variety of metrics, including product version, component health, service counts, and optional diagnostic information. This data is assembled into a JSON payload, redacted for privacy, and sent via HTTP POST to the central Specaria licensing endpoint.
The client operates with fail-open semantics, meaning that any failure during the heartbeat process (e.g., network errors, database issues) will not crash the application. The heartbeat is simply dropped for that cycle and retried on the next scheduled run.
The client's primary inputs are the active license state, configuration properties, and data queried from the local database. Its main output is an HTTP request to the Specaria platform. It also records the status of each heartbeat attempt in the s2r_system_setting table for administrative visibility.
The heartbeat process follows a defined sequence to ensure data is collected, redacted, and transmitted reliably and securely.
flowchart TD
subgraph "Heartbeat Client Logic"
A[Daily Schedule or<br>Application Startup] --> B{Validate License};
B -- Invalid/Disabled --> Z1[End Cycle];
B -- Valid --> C[Publish Component Versions to DB];
C --> D{Check Sender Ownership};
D -- Not Owner --> Z2[End Cycle];
D -- Is Owner --> E[Assemble Heartbeat Payload];
subgraph "Payload Assembly"
direction LR
E1[Basic Telemetry<br>(Version, Uptime, Health)]
E2["Optional Telemetry<br>(Inventory, Diagnostics)"]
E --> E1 & E2;
end
E1 & E2 --> F[Redact Payload];
F --> G[POST to Specaria Platform];
G --> H{Handle Response};
H -- Success (2xx) --> I[Record Success in DB];
H -- Permanent Error (4xx) --> J[Record Failure in DB];
H -- Transient Error (5xx) --> K[Wait 60s & Retry POST];
K -- Success --> I;
K -- Failure --> J;
endTrigger: The process is initiated either by a daily cron schedule (configurable via s2r.specaria.heartbeat-cron) or once when the application starts (ApplicationStartedEvent).
License Validation: The client retrieves the current license state. If the license is absent or disabled, the cycle is aborted as there is no valid identity (jti) to authenticate the request.
Component Version Publishing: The client unconditionally gathers version information for all product components and writes it to the s2r_system_setting table. This ensures that whichever component is designated to send the heartbeat has access to accurate, up-to-date version data for the entire installation.
Sender Ownership: The client checks the specaria.heartbeat_sender setting in the database. To prevent duplicate reporting, only one component in an installation is designated as the heartbeat sender. If another component holds this role, the client stands down for the current cycle. It also stands down if the installation is running on the embedded "bootstrap" license, as its temporary identifier is not recognized by the platform.
Payload Assembly: If designated to send, the client constructs the JSON payload. The payload is separated into two tiers:
specaria.telemetry_optional_enabled setting is true. This tier contains richer, consent-gated data blocks, including inventory (enabled features, configuration keys) and diagnostics.Redaction: The assembled payload undergoes two redaction steps:
meta.heartbeat_redacted_fields are removed.SpecariaRedactor to remove any values that match disallowed patterns (e.g., hostnames, URLs). If the redactor rejects the payload, the heartbeat is dropped and an error is logged.Transmission: The final, redacted JSON payload is sent via HTTP POST to the endpoint specified in s2r.specaria.heartbeat-url-template. The request is authenticated using the raw license JWT as a Bearer token. The HTTP client automatically honors HTTPS_PROXY, NO_PROXY, and SSL_CERT_FILE environment variables.
Response Handling and Retry:
2xx status code indicates success.5xx status, timeout) triggers a single retry after a 60-second delay.401, 404, 410, 429) is not retried within the same cycle.Status Recording: The final outcome of the cycle (e.g., accepted-202, dropped-503, redactor-rejected) is written to the specaria.last_heartbeat_status key in the database. On success, specaria.last_heartbeat_at is updated with the current timestamp.
The client sends a JSON object with a structure compliant with the Specaria platform integration requirements. The payload includes top-level metadata and a nested telemetry object.
IMPORTANT
The telemetry object adheres to telemetry-schema-v1. The schema_version is fixed at 1 to ensure compatibility with the platform's validator. New data is added in optional blocks within this schema version.
Below is an example of a heartbeat payload. Values are for illustration only.
{
"product_version": "1.7.22",
"agent_version": "1.7.22",
"success": true,
"metrics": {
"max_discovered_services": 150,
"max_converted_services": 75
},
"environment": "production",
"host_fingerprint": "sha256-a1b2c3d4...",
"telemetry": {
"schema_version": 1,
"product_id": "s2r",
"release_version": "1.7.21",
"service_versions": {
"admin-api": "1.7.22",
"discovery-ingest": "1.5.1",
"s2r-release-controller": "1.6.21"
},
"uptime_seconds": 3600,
"deployment_type": "CUSTOMER_VPC",
"cloud_provider": "gcp",
"orchestrator": "cloud-run",
"instance_id": "f81d4fae-7dec-11d0-a765-00a0c91e6bf6",
"error_count_5m": 5,
"request_count_5m": 1000,
"controller_status": "ok",
"last_update_outcome": {
"release_version": "1.7.21",
"status": "success",
"at": "2023-10-27T10:00:00Z"
},
"inventory": {
"service_inventory": [
{
"name": "admin-api",
"image_tag": "1.7.22",
"replicas": 0
}
],
"capabilities": [
"feature-a",
"feature-b"
],
"config_keys_set": [
"CLOUD_PROVIDER",
"S2R_INSTANCE_ID"
],
"integrations": [
"f5"
],
"schema_versions": {
"admin-api": "V175"
},
"resource_profile": {
"cpu_class": "medium",
"mem_class": "medium",
"storage_class": "unknown"
}
},
"diagnostics": {
// Structure and content defined by the DiagnosticTelemetryCollector component.
}
}
}
The SpecariaHeartbeatClient is configured through Spring properties and environment variables.
| Name | Type | Default | Description |
|---|---|---|---|
s2r.specaria.heartbeat-cron | String | 0 5 0 * * * | Cron expression in UTC for the daily scheduled heartbeat. |
s2r.specaria.heartbeat-url-template | String | https://api.specaria.io/v1/licenses/{jti}/heartbeat | URL template for the heartbeat endpoint. The {jti} placeholder is replaced with the license JWT ID. |
S2R_SPECARIA_HTTP_TIMEOUT_SECONDS | Long | 60 | HTTP request timeout in seconds. |
s2r.specaria.optional-telemetry-default | Boolean | true | Default setting for enabling optional telemetry. true means the inventory and diagnostics blocks are sent unless explicitly disabled. |
s2r.cloud.provider | String | gcp | The cloud provider where the product is deployed. Maps to the cloud_provider telemetry field. Allowed values: gcp, aws, azure, on_prem. |
s2r.specaria.orchestrator | String | cloud-run | The container orchestrator. Maps to the orchestrator telemetry field. Allowed values: cloud-run, kubernetes, compose. |
S2R_DEPLOY_VERSION | String | — | The authoritative product version, stamped at deployment. This is the primary source for the product_version field. |
S2R_INSTANCE_ID | String | — | A stable, unique identifier (UUID v4) for the installation. If not set, a deterministic ID is generated from the license or host fingerprint. |
The client reads from and writes to the s2r_system_setting table to coordinate state and store results. All keys are stored with a platform-wide scope.
| Key | Access | Description |
|---|---|---|
specaria.last_heartbeat_at | Write | ISO-8601 timestamp of the last successful heartbeat. |
specaria.last_heartbeat_status | Write | Status of the last heartbeat attempt (e.g., accepted-202, dropped-404). |
specaria.telemetry_optional_enabled | Read/Write | Boolean flag ("true"/"false") to enable or disable the optional telemetry tier. |
specaria.heartbeat_sender | Read | The name of the component designated to send heartbeats for the installation. |
specaria.product_version | Write | The authoritative product version, published for the sender to use. |
specaria.service_versions | Write | A JSON object mapping component names to their versions, published for the sender. |
specaria.recent_runtime_ok | Read | A boolean flag indicating the health of the runtime component, refreshed by a separate health probe. |
The client makes an outbound call to the Specaria platform.
POST /v1/licenses/{jti}/heartbeats2r.specaria.heartbeat-url-template.Authorization: Bearer <license-jwt>Content-Type: application/jsonAccept: application/jsonUser-Agent: s2r-licensing/1The client's behavior can be controlled via an administrative API endpoint.
POST /admin/v1/specaria/telemetry/optionalinventory and diagnostics). This action sets the specaria.telemetry_optional_enabled system setting.The client is designed to be resilient and provide clear logging for its state.
| Condition | Trigger | Log Message / Status |
|---|---|---|
| Heartbeat Skipped | Another component is the designated sender. | S2R-LIC heartbeat not sent from admin-api — '<owner>' owns the heartbeat... Status: stood-down |
| Heartbeat Skipped | The active license is the embedded bootstrap license. | S2R-LIC heartbeat not sent — this install is on the embedded bootstrap licence... |
| Heartbeat Dropped | Payload contains a value forbidden by privacy rules. | S2R-LIC heartbeat DROPPED — privacy guard rejected payload: <reason> Status: redactor-rejected |
| Heartbeat Dropped | Failed to serialize the payload to JSON. | S2R-LIC heartbeat DROPPED — JSON serialization failed: <reason> Status: serialize-failed |
| Heartbeat Dropped | The raw license JWT is not available for authentication. | S2R-LIC heartbeat dropped — no raw license JWT available... Status: no-jwt |
| HTTP 401 Unauthorized | The license JWT in the Authorization header is invalid or expired. | S2R-LIC heartbeat HTTP 401 — license JWT rejected... Status: dropped-401 |
| HTTP 401 Unauthorized | The mTLS client certificate was rejected by the platform. | S2R-LIC heartbeat SPECARIA-MTLS-0001 - ... Status: mtls-cert-rejected-401 |
| HTTP 404 Not Found | The license jti in the URL is not known to the platform. This is a configuration error. | S2R-LIC heartbeat SPECARIA-HB-0404 — the platform has issued no licence for this jti... Status: no-such-license-404 |
| HTTP 410 Gone | The license has been revoked by the platform. | S2R-LIC heartbeat HB-0410 license revoked... |
| HTTP 429 Too Many Requests | The platform is rate-limiting requests. | S2R-LIC heartbeat HB-0429 rate limited... |
| Transport Error | Network error, DNS failure, or request timeout. | S2R-LIC heartbeat HTTP error: <class>: <message> (timeout=<N>s) Status: dropped-transport |
| Incorrect Metrics | A database query for metrics fails (e.g., due to a schema change). | S2R-LIC heartbeat 5m count query failed (fail-open, emitting 0/0): <reason> |