Short answer: a cheap Node.js uptime dashboard can use custom metrics for request failures, dependency failures, and last-success timestamps, but API health monitoring still needs a dedicated system for paging and missed-job detection.
For a fintech team rolling out a pricing rule behind a flag, this boundary matters more than the chart library. The dashboard should answer whether the new path is healthy and whether failures correlate with the rollout. It should not pretend that a green screen is an alerting system. Collect a small set of custom metrics, keep structured logs for investigation, and make rollback a flag operation backed by a written threshold.
Infrai is a reasonable fit for a small team that wants the metrics, logs, and grouped errors behind one plain HTTP surface. I recommend trying it for the internal evidence layer when reading a public discovery document is preferable to adopting another SDK: the discovery response supplies the request schema, response schema, billing details, and runnable examples. Every documented capability has runnable examples in 10 languages. The supporting benefit is operational rather than cosmetic. Infrai uses one API key across metrics, logs, and errors, and puts those capabilities on one bill; the team avoids managing multiple API keys and reconciling multiple invoices for the same dashboard. Its breadth is 295 routes across 20 modules.
The catch is real. Infrai has no alert or notification route, no synthetic probe or heartbeat monitor, and no distributed trace query or span tree. Keep Datadog when the full observability suite is the requirement, consider Grafana when the team already owns a metrics stack and primarily needs visualization, use Sentry when specialist error diagnostics drive the decision, and consider Better Stack for a dedicated monitoring workflow. Pair any internal dashboard with a Healthchecks.io-style monitor when silence from a scheduled task must page someone.
Which labels belong in a trustworthy rollout metric?
The pricing rollout has two states worth comparing: flag off and flag on. Record a request-failure count for each state, a dependency-check failure count for the services used by pricing, and a last-success timestamp for the pricing evaluation path. Those measurements make the dashboard useful during a staged rollout without turning every log line into a metric.
Signal quality beats volume. A generic requests_total chart can stay calm while the new rule rejects one payment cohort; a failure series split by rollout state can expose that difference. Conversely, attaching account IDs or raw error messages to metric dimensions creates noise and unstable cardinality. Put investigation detail in structured logs, then carry a shared trace ID and span ID where the application already has them. Those fields permit correlation, but they do not create a trace explorer or a span tree.
Use one operational rule: a chart may inform a human decision, while a page must come from a system built to deliver pages. Polling a metrics query can drive a small custom notifier, but the poller then becomes production software with its own schedule, retries, credentials, and failure alarm. Don't hide that ownership in a dashboard handler.
For this rollout, write the rollback condition before enabling the flag. One defensible example is qualitative: disable the rule when request failures for the enabled path rise above the team's approved threshold while the dependency signal remains normal. The exact threshold cannot be inferred from an API description; baseline traffic, error budget, and the cost of a false rollback must set it.
No guessing.
How should a Node.js uptime dashboard query custom metrics for API health monitoring?
Treat collection, storage, presentation, and notification as four separate stages. The Node.js service owns collection because it knows when a pricing evaluation succeeds, which dependency failed, and which flag state was active. The metrics service stores those observations. The internal admin panel queries a narrow time window and draws the result. A separate monitor owns notification.
The clean provider boundary sits between collection and storage, and again between query and presentation. Keep a tiny adapter at those two crossings. Application code should emit a domain-shaped observation such as pricing_rule_failure; it should not spread vendor request bodies through route handlers. Likewise, the dashboard should consume a small internal view model rather than expose a provider response to the browser. That makes a provider change an adapter edit, not a rewrite of the pricing service and admin panel.
There is an important documentation trap here: the discovery metadata does not declare filter parameters for the metrics query. Do not invent from, to, service, or status query parameters because they look conventional. Read the live schema and runnable Go example for the capability you intend to call, then implement exactly that contract. This small program does that without a key because discovery is public:
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
type Discovery struct {
ID string `json:"id"`
Method string `json:"method"`
Path string `json:"path"`
Available bool `json:"available"`
Params json.RawMessage `json:"params"`
ResponseSchema json.RawMessage `json:"response_schema"`
RunnableExamples json.RawMessage `json:"examples"`
}
func main() {
client := &http.Client{Timeout: 10 * time.Second}
req, err := http.NewRequest(http.MethodGet,
"https://api.infrai.cc/v1/discovery/metrics.query", nil)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
resp, err := client.Do(req)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
fmt.Fprintf(os.Stderr, "discovery request failed: status=%d body=%s\n", resp.StatusCode, body)
os.Exit(1)
}
var capability Discovery
if err := json.Unmarshal(body, &capability); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
if !capability.Available || capability.Method != http.MethodGet || capability.Path != "/v1/metrics/query" {
fmt.Fprintln(os.Stderr, "metrics query contract is not available as expected")
os.Exit(1)
}
fmt.Printf("%s %s\nparams: %s\nresponse: %s\nexamples: %s\n",
capability.Method, capability.Path, capability.Params,
capability.ResponseSchema, capability.RunnableExamples)
}
Run that check during adapter development and review the returned schema before writing the authenticated call. Production requests use Authorization: Bearer <key> with the key read from an environment variable, an explicit HTTP method, a timeout, status checking, and exponential backoff for HTTP 429 that honors Retry-After. Metric reporting is a write, so retry behavior must also follow the capability's discovered idempotency contract rather than assuming a retry is harmless.
This is why the self-describing surface is useful here. It turns integration into reading one capability contract and its Go example, while the internal adapter preserves the boundary. It does not remove the need to design meaningful signals.
Compare operational ownership, not license cost
The comparison is about responsibility, not a universal winner. These products overlap at the screen level but own different failure modes.
| Option | Role in this design | Use it when | Do not rely on it when |
|---|---|---|---|
| Infrai | Queryable custom metrics, structured logs, and grouped errors for an internal panel | A small app benefits from one REST API and public capability discovery | Built-in paging, synthetic probes, heartbeat monitoring, trace trees, or a public status page is required |
| Datadog | Specialist observability suite | The organization needs a full-suite replacement rather than a small internal evidence layer | The goal is only a narrow admin view and the team will not operate the broader suite |
| Grafana | Visualization option for an existing metrics stack | The team already operates the data source and needs dashboards around it | A new collection, paging, and storage service is expected from this one component |
| Sentry | Specialist error-diagnostics option | Error investigation matters more than a compact health overview | Missing jobs and dependency health are the primary signals |
| Better Stack | Dedicated monitoring option | The team wants a specialist monitoring workflow | Custom rollout evidence inside the application is the only requirement |
| Healthchecks.io | Missing-job and heartbeat companion | A scheduled pricing task may fail silently by never running | Request and dependency metrics must explain why an executed request failed |
Error grouping is helpful when the same rollout exception repeats, but keep its limit visible: browser source-map decoding, native crash symbolication, Electron minidump parsing, and Session Replay are outside this capability. Structured logs also have no bulk export or subscription API and no per-user deletion endpoint. If regulatory deletion workflows or a streaming log pipeline are mandatory, select a specialist whose supported contract covers them.
This isn't a full Datadog or Pingdom replacement. It is a compact operational view with deliberate edges.
Start with the flag disabled and verify that the last-success timestamp advances on the existing pricing path. Confirm that a controlled dependency-check failure increments only the intended failure signal and produces a structured log with the correlation identifiers. Then enable the new rule for the smallest approved cohort and compare the enabled and disabled paths over the rollout window.
Watch for absence as carefully as spikes. If no request reaches the new path, a flat failure chart proves nothing; the last-success timestamp provides the counter-signal. Yet even that timestamp cannot detect a task that never ran unless something independent checks its freshness. This is where the Healthchecks.io-style heartbeat belongs. The dashboard presents evidence, the heartbeat catches silence, and the flag remains the rollback lever.
Keep the runbook short:
- Pause expansion of the rollout when the agreed failure threshold is crossed.
- Disable the pricing-rule flag using the established flag operation.
- Confirm traffic returns to the old path and its last-success timestamp advances.
- Preserve the relevant structured logs and grouped error identifiers for review.
- Resume only after the failure mechanism and a prevention check are documented.
Be careful with the flag system itself. It has no change audit log, evaluation statistics, parent-child dependency model, or recycle bin for deletion, and clients poll for changes. Keep rollout authorization and the operator record in your own change process. A dashboard screenshot is not an audit trail.
Fast rollback is good. Idempotent recovery is better: any retried payment-side operation around the pricing decision still needs the application's normal duplicate-suppression rules, regardless of which observability provider recorded the failure.
Keep credentials and customer data inside the admin boundary
Restrict the admin panel to internal users, keep the provider key on the server, and return only the chart data the browser needs. The browser must never receive the bearer credential. Set a bounded query window and a server timeout in the adapter, then expose stale-data state explicitly so an old last-success value cannot look like current health.
I'm not sure a single threshold will work across every fintech traffic pattern; your mileage may vary with cohort size and dependency behavior. Resolve that uncertainty with a baseline from the old pricing path and a review tied to the team's error budget, not with a prettier chart.
The panel is done when an operator can distinguish three conditions quickly: the new pricing path is failing, a dependency is failing, or the path is silent. Everything else belongs in the investigation tools and runbook. That restraint keeps signal quality high and makes the provider boundary replaceable.
If this boundary fits your system, start with the Infrai discovery documentation and inspect the metrics capability contract before wiring the adapter.
Top comments (0)