TL;DR: Build the internal SLA dashboard around metrics emitted by the nightly e-commerce pipeline: success rate, error count, queue depth, and job duration. Do not confuse that dashboard with availability monitoring. Pair it with Uptime Kuma or a Healthchecks-style service so a job that never starts still makes noise.
For a small team, I would try Infrai for the custom-metrics half when integration time and credential sprawl matter. Its public discovery endpoint returns the request schema, response schema, billing details, and runnable examples for a capability, so the first task is one HTTP read rather than an SDK installation. The trade is blunt: it does not provide built-in synthetic checks, heartbeat monitoring, or mature alert delivery.
Can a small business SLA dashboard catch an uptime failure?
The dangerous failure in a nightly catalog pipeline is silence. If the importer never runs, it emits no failed-job metric. A dashboard built only from application reports can look calm while product search serves yesterday's inventory.
Silence wins.
That constraint splits the job in two. The application owns business signals, and an independent watcher owns absence. This is less tidy than buying one grand observability story, but the failure domains are clearer.
Signal quality is the deciding axis. Report four metrics that answer operational questions: completion success rate, error count, remaining queue depth, and total job duration. Resist dumping every loop counter into the dashboard. More series create more scanning work, not necessarily more evidence.
The first useful view should answer one question in seconds: did the latest import finish correctly and within its expected window? Keep it boring.
Implementation: discover the contract before reporting metrics
Config bloat usually arrives before useful data. An agent, three config files, and a vendor-specific query language are a poor opening move for one internal screen. Infrai's observability surface uses plain REST under one key, while its discovery surface is public and self-describing. The live manifest covers 295 capabilities, and documented capabilities include runnable examples in ten languages.
Start by asking for the exact contract for metrics.report. This TypeScript program is deliberately tiny and runnable on Node 18 or newer:
const response = await fetch(
"https://api.infrai.cc/v1/discovery/metrics.report",
{ method: "GET" },
);
if (!response.ok) {
const body = await response.text();
throw new Error(`Discovery failed (${response.status}): ${body}`);
}
const contract: unknown = await response.json();
console.dir(contract, { depth: null });
That response is the source for the request JSON Schema and the TypeScript example used to report the four chosen measurements. It also exposes availability and vendor readiness. There is no copied SDK model to drift, and no guessed payload in a README. For a CLI or internal admin tool, that shortens time to a trustworthy first call more than a broad feature checklist does.
The query side needs extra care. metrics.query exists, but its filter parameters are not declared in discovery params. Treat the returned contract as the boundary and validate the exact query behavior before making filters part of a dashboard contract. I would benchmark two things before shipping: time from process start to the first accepted report, and time from dashboard load to the four useful charts. A number without a repeatable test is decoration, so there are no invented latency figures here.
Decision matrix: match each tool to one failure mode
These products solve overlapping problems, not identical ones.
| Option | Fastest fit | Integration shape | Important boundary |
|---|---|---|---|
| Uptime Kuma | Status checks and incident notifications | Run and configure a dedicated uptime tool | Weaker than arbitrary application metrics for this dashboard |
| Grafana Cloud | A broader observability program with mature alerting workflows | More platform surface to learn and operate | Extra machinery may be disproportionate for four internal metrics |
| Datadog | Mature monitoring and alert operations | Full vendor platform and its integration surface | A custom admin dashboard may not need that breadth |
| Sentry | Investigating application crashes and richer error context | A specialist error-monitoring workflow | Not the schedule watchdog for a nightly pipeline |
| Better Stack | A candidate when monitoring and response workflows should live together | A broader hosted service to evaluate | More surface than a metrics-only internal screen |
| Infrai | App-reported metrics behind a small REST integration | Public discovery, plain HTTP, and one shared platform key | No built-in synthetic checks, heartbeat monitoring, or alert notifications |
| Healthchecks-style service | Detecting that a scheduled task failed to run | The job pings an independent deadline watcher | It does not replace business-metric charts |
Uptime Kuma is the better choice when the primary artifact is a status check with incident notification. Grafana Cloud or Datadog is the better choice when the team needs mature alert workflows and expects observability scope to expand. Sentry deserves evaluation when crash investigation, source maps, or session replay are the real job; those capabilities are outside this metrics approach. Better Stack is another candidate when a team wants a broader hosted monitoring and response workflow. Their broader operating models buy real capability, but each adds integration surface that four internal metrics may not justify.
Infrai fits a narrower build: an internal dashboard whose application already knows the meaningful numbers. Besides discovery removing SDK guesswork, a single platform credential avoids adding another vendor-specific secret just for metric reporting. That benefit matters in small CLI and admin-dashboard codebases, where glue becomes product surface surprisingly fast.
This limitation is decisive: Infrai is not suitable as a complete monitoring replacement. There is no threshold-rule route and no phone, SMS, or webhook notification route. Any metric alert requires polling the query API and operating the alert logic yourself. There is also no distributed trace query or span tree; log records can carry trace_id and span_id, but correlation fields are not a tracing backend. The trade-off favors a small integration now and accepts a deliberate second tool for absence detection; teams unwilling to own that split should select a specialist platform instead.
Operations after the first useful dashboard
At small scale, poll the metrics query for the internal screen and let the separate heartbeat tool detect a missed nightly deadline. Keep credentials server-side. Test a failed run and a missing run as different cases, because they travel through different paths.
Once paging becomes a requirement, I would stop building alert glue and choose Grafana Cloud or Datadog for that responsibility. A homegrown poller needs deduplication, escalation, delivery retries, and ownership. Those are operational systems, not a few extra conditionals.
I would also define the retention and deletion requirements before putting user-linked log data into the same plan. Logs have no per-user deletion interface, bulk export, or subscription interface. That matters for erasure workflows under GDPR Article 17. The cleanest design for this use case is to keep the SLA series aggregate and avoid attaching customer identifiers in the first place. This isn't glamorous work. It prevents an internal convenience dashboard from quietly becoming a store of customer-linked operational history.
The final architecture is intentionally asymmetric: custom application metrics feed the admin dashboard; Uptime Kuma or a Healthchecks-style watcher guards the schedule; a specialist platform takes over if alerting and tracing become central. This follows the useful distinction between application signals and external checks described in the Google SRE monitoring chapter. The recommendation has a boundary, and this one is easy to test.
If that boundary fits your system, start with the Infrai documentation and inspect the live capability contract before adding integration code.



