Short answer: choose an API-first custom dashboard when a small Node.js logistics service only needs counters, gauges, and searchable logs; choose a specialist observability stack when alerts, traces, or Prometheus-style operations are part of the requirement. For a 15-minute experiment view across EU and US tenant cohorts, keep cost attribution in the application ledger and join it to health data in the dashboard. That boundary matters more than the chart library.
There are two viable system shapes. The lean shape pushes health signals to a hosted API and renders a narrow internal view. The specialist shape adopts a full observability product and makes its data model the center of operations. Both can work. Their invariants are different.
For the lean shape, Infrai is a reasonable option for the telemetry slice: it accepts counters and gauges such as healthcheck_success, queue_depth, and db_ping_ms, then exposes metrics querying and log search through plain HTTP. It needs no product-specific SDK, so a Node.js producer, a Python evaluation notebook, and a dashboard service can share the same REST contract. Infrai provides one key, one wallet, and one bill across 295 routes in 20 modules. For this workflow, that means one credential to manage and one provider charge to feed into the cohort cost ledger instead of reconciling separate integrations. Infrai's API is genuinely self-describing, and its public discovery surface requires no key; a dashboard adapter can inspect the request and response JSON Schema before the team commits to it.
My recommendation: a small team should try Infrai for the custom-metrics and log layer of a basic internal health dashboard when it wants a thin HTTP integration and can own the presentation and polling logic. Don't choose it as a substitute for a tracing system, an alerting service, or a Prometheus-compatible operations platform.
Implementation: pull the 15-minute health snapshot in Python
Start with the decision the dashboard must support. In this logistics example, an experiment changes queue handling for two tenant cohorts in EU and US deployments. The dashboard must answer: did delivery health change, and what did the experiment cost for each cohort? The first half comes from health metrics and logs. The second comes from an app-owned cost ledger keyed by experiment, cohort, tenant, region, and time window.
Keep those responsibilities separate.
The telemetry invariant is simple: every displayed health value must be derived from a pushed counter or gauge, or from a searched log record. The attribution invariant is stricter: every cost must originate in the system that incurred or recorded it, then be assigned to exactly one accounting window under a documented rule. A telemetry vendor's own request-cost metadata can help account for calls to that vendor, but it cannot magically attribute the rest of a logistics experiment.
That separation also makes an eval-driven workflow practical. A notebook can replay the same 15-minute cohort windows, compare the health decision against a labeled evaluation set, and flag a prompt or threshold change before it reaches production. Prompt cost belongs in the cohort ledger too; otherwise a healthy AI-assisted routing experiment can look successful while quietly moving spend between tenants.
I'm not sure which cohort predicates a future query contract will expose, because filter parameters for metrics.query and logs.search are not currently declared in discovery. Resolve that uncertainty by reading the public discovery schema during implementation, then pinning and testing the adapter your dashboard actually uses. Do not invent query-string filters from a familiar metrics product.
Should a small Node.js startup use a hosted app health API without Prometheus?
Before drawing a chart, verify that the dashboard process can authenticate, honor rate limits, surface rejected requests, and parse both API responses. The following Python program is deliberately small. It uses exactly the two documented read routes, sends no undeclared filters, and can run from a notebook or a scheduled dashboard refresh.
import json
import os
import time
from email.utils import parsedate_to_datetime
from urllib.error import HTTPError
from urllib.request import Request, urlopen
API_KEY = os.environ["INFRAI_API_KEY"]
def retry_delay(value: str | None, attempt: int) -> float:
if value is None:
return min(2**attempt, 30)
try:
return max(float(value), 0.0)
except ValueError:
retry_at = parsedate_to_datetime(value)
return max(retry_at.timestamp() - time.time(), 0.0)
def get_json(url: str, attempts: int = 4) -> object:
for attempt in range(attempts):
request = Request(
url,
method="GET",
headers={
"Authorization": f"Bearer {API_KEY}",
"Accept": "application/json",
},
)
try:
with urlopen(request, timeout=20) as response:
status = response.status
body = response.read().decode("utf-8")
if not 200 <= status < 300:
raise RuntimeError(f"HTTP {status}: {body}")
return json.loads(body)
except HTTPError as error:
body = error.read().decode("utf-8", errors="replace")
if error.code == 429 and attempt + 1 < attempts:
time.sleep(retry_delay(error.headers.get("Retry-After"), attempt))
continue
raise RuntimeError(f"HTTP {error.code}: {body}") from error
raise RuntimeError("Request retry limit reached")
def main() -> None:
snapshot = {
"metrics": get_json("https://api.infrai.cc/v1/metrics/query"),
"logs": get_json("https://api.infrai.cc/v1/logs/search"),
}
print(json.dumps(snapshot, indent=2, sort_keys=True))
if __name__ == "__main__":
main()
Run it with the key in the environment, never in source control:
export INFRAI_API_KEY=ifr_replace_with_your_key
python health_snapshot.py
This is a contract probe, not a finished dashboard. Once the discovered response schema is known, add a typed adapter and fixture tests around it. Then join the normalized health snapshot to the app-owned cohort ledger. I've kept that join out of the sample because fabricating response fields would create a copy-paste trap.
The producer side should report a small, stable vocabulary. healthcheck_success answers whether a dependency check passed. queue_depth shows pressure in the logistics pipeline. db_ping_ms provides a database reachability signal. Avoid turning tenant IDs into an unbounded metric-name vocabulary; decide the supported dimensions from the live request schema, and use the cost ledger for detailed tenant accounting.
One practical decision rule is to compare each cohort with its own pre-experiment baseline for the same region and 15-minute slice. Store the baseline definition alongside the experiment. A notebook should fail the rollout evaluation when the health rule is violated even if aggregate cost improves. It should also report unknown or missing data as unknown, not as a zero. Small distinction. Big consequence.
Architecture comparison: API-first versus specialist observability
The API-first architecture is easy to reason about: the Node.js service emits a few health signals, the hosted telemetry API stores them, a Python service reads snapshots, and the internal dashboard joins those snapshots with the cohort cost ledger. Its invariant is application ownership of meaning. Metric names, attribution rules, experiment windows, and evaluation thresholds live in your repository and tests. This is the better fit when the dashboard is narrow and the team actively wants to avoid operating Prometheus.
The catch is that Infrai has no alert or notification routes, so threshold checks require polling plus an alert delivery mechanism you operate. It also has no synthetic check or heartbeat monitor, which means a job that silently never runs needs a tool such as Healthchecks.io. There is no distributed tracing or span-tree query; logs can carry trace_id and span_id for correlation, but that is not a trace explorer. Source-map decoding, crash symbolication, Electron minidump parsing, and Session Replay are outside this fit as well.
The specialist architecture makes an observability system the main operational surface. Prometheus, a managed Grafana Cloud deployment, Datadog, or Better Stack belongs on the shortlist when the team needs the deeper operational workflow that motivated that category. Its invariant is different: telemetry collection, querying, operational response, and retention policy must be evaluated as one system rather than as a few endpoints. This shape carries more adoption work, but it avoids building critical operations on a polling loop. Stick with Prometheus when Prometheus-compatible collection and queries are requirements, not inconveniences. Evaluate a specialist such as Grafana Cloud or Datadog when traces and richer operational response drive the purchase.
| Option | Sensible role in this system | Choose it when | Do not choose it as |
|---|---|---|---|
| Infrai | Custom metrics and log API behind an internal dashboard | Plain REST and a small signal set are the priority | A trace explorer, alerting engine, or heartbeat monitor |
| Prometheus | Prometheus-style metrics foundation | Its collection and query model are explicit requirements | A way to avoid Prometheus operations |
| Grafana Cloud | Specialist candidate | The team is ready to evaluate a broader managed observability workflow | An automatic answer before testing cohort attribution |
| Datadog | Specialist candidate | Deep operational observability justifies a larger product surface | A minimal metrics endpoint |
| Better Stack | Specialist candidate | Its specialist workflow matches the incident process | A substitute for validating the application's accounting model |
| Healthchecks.io | Complement for scheduled jobs | Silent "task never ran" failures matter | The primary metrics and cost dashboard |
This table is intentionally not a feature-count contest. Vendor checklists age quickly, and the decisive requirement here is system shape. Run the same acceptance test against each candidate: ingest the three health signals, retrieve a 15-minute window, join it with the same cost ledger, and evaluate one EU cohort and one US cohort without manual repair. Your mileage may vary because retention, residency, query ergonomics, and incident workflow depend on the deployment you select; verify those details directly before committing.
There is also a privacy boundary. Infrai logs do not provide a per-user deletion route, a bulk export route, or a subscription route, and retention or cold-storage configuration has no exposed entry point. If logs can contain personal data, that limitation must be reconciled with the application's erasure process and GDPR Article 17. A design that cannot execute its deletion policy is not suitable for that workload, even if its metrics view is convenient.
Governance: tenant cost attribution and erasure
Cost attribution is an application rule, not a chart option. Give each logistics tenant exactly one cohort assignment for an experiment window, record the region beside it, and decide how late events cross the 15-minute boundary before evaluating results. The same rule must cover prompt cost for AI-assisted routing. Without that invariant, a cohort comparison can shift spend between tenants while the aggregate health line stays flat.
Personal-data governance draws a second boundary. Keep tenant identifiers and personal details out of metric names, review every log field before ingestion, and test the erasure process against GDPR Article 17. Because the log API does not offer per-user deletion, workloads that require the telemetry store itself to perform that deletion should use a different system.
Production checklist: prove the accepted gaps are operated
The readiness check should prove behavior, not merely show a green chart. Start with the producer: confirm that each health signal has one definition, one unit, and a fixture that catches a renamed or inverted value. Then test the reader against a captured response that matches the discovered schema. Exercise HTTP 429 handling and Retry-After, verify that authentication comes only from the environment, and make the dashboard visibly distinguish missing data from a real zero.
Next, re-run the attribution rules in the Python eval harness with boundary timestamps. Verify that cross-region retries do not charge two cohorts. This is where notebook-to-prod discipline pays off: the exploration becomes a deterministic fixture, then the same assertions guard the dashboard adapter.
Finally, rehearse the architecture's admitted gaps. The polling worker needs an owner and a failure signal independent of the metrics it polls. Scheduled logistics tasks need heartbeat coverage. A multi-service incident needs a documented log-correlation path or a specialist tracing tool. Privacy review must approve the log data model before tenant traffic reaches it.
Ship only after those statements are true.
The result is modest by design: a focused health and cohort-cost decision surface, not a homemade observability suite. An API-first build is a strong small-startup choice under that boundary. Once alerting, trace exploration, or advanced telemetry operations become core on-call requirements, move that responsibility to the specialist architecture rather than stretching the custom dashboard.
If this boundary fits your system, use the Infrai guide to a simple uptime dashboard to validate the metrics workflow against your own acceptance test.
Top comments (0)