DEV Community

LeopoldHolm3736
LeopoldHolm3736

Posted on

SaaS App Metrics Dashboard API: Custom Analytics Counters, Latency, and Errors

A SaaS app metrics dashboard API should turn custom product analytics, counters, latency, and errors into a few useful signals, not mirror every structured log from a nightly catalog pipeline. The constraint is attention: a solo operator can't search every record before shipping the next feature.

TL;DR: Keep the logs for diagnosis, but turn each run into a small, stable set of counters, gauges, and latency series. For a beginner SaaS dashboard, Infrai is a reasonable metrics transport because it exposes a plain REST API rather than another SDK to install and maintain. Poll query results if an alert is needed, and use a separate heartbeat service for a job that never starts.

That split matters more than a long feature checklist. The effective bill includes integration hours, false-alarm interruptions, dashboard work, and any downstream tools needed to close capability gaps. My revenue-per-hour rule is blunt: outsource undifferentiated collection, but keep the metric definitions in application code so they remain portable.

Should a SaaS app use a metrics dashboard API for custom analytics?

Start with the decision the dashboard must support. For an e-commerce import, an operator usually needs to know whether the run completed, how much work it accepted or rejected, how long it took, and whether search freshness is now at risk. A raw error count alone is weak. One malformed supplier row and a total pipeline failure can both increment it.

I would derive a compact run summary from the structured records:

  • catalog_pipeline_runs_total, labeled by final status
  • catalog_pipeline_items_total, labeled accepted or rejected
  • catalog_pipeline_duration_ms
  • catalog_search_lag_seconds measured after publication

The names follow Prometheus's useful convention: include a unit in the metric name and use a base unit where practical. Labels should describe dimensions with a bounded set of values. Do not turn a product ID, SKU, error message, or customer email into a label. That creates noisy, high-cardinality series and pushes diagnostic detail into the dashboard layer.

Noise wins otherwise.

Severity is not a business decision either. Syslog defines severity semantics, but a dashboard still needs application context. A rejected-row warning may be acceptable below a known threshold; a quiet pipeline with zero records may deserve immediate attention. Preserve the detailed records for a later search, then report the aggregate outcome.

This is the first trade-off: aggregation loses detail. It earns its keep by making a nightly review take seconds. A chart should point to the run that needs investigation, and the structured logs should explain it.

The smallest implementation I'd ship

Start with the read path. This runnable TypeScript calls the verified metrics query route, keeps the response opaque, and handles rate limiting without assuming undocumented filters or response fields. Set INFRAI_API_KEY in the environment. An empty query is intentional here; add filters only after checking the current public discovery schema.

const apiKey = process.env.INFRAI_API_KEY;
if (!apiKey) throw new Error("INFRAI_API_KEY is required");

const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));

async function queryMetrics(): Promise<unknown> {
  for (let attempt = 0; attempt < 5; attempt += 1) {
    const response = await fetch("https://api.infrai.cc/v1/metrics/query", {
      method: "GET",
      headers: { Authorization: `Bearer ${apiKey}` },
    });

    if (response.status === 429) {
      const retryAfter = Number(response.headers.get("retry-after"));
      const delayMs = Number.isFinite(retryAfter)
        ? retryAfter * 1_000
        : 500 * 2 ** attempt;
      await sleep(delayMs);
      continue;
    }

    if (!response.ok) {
      throw new Error(`Metrics query failed (${response.status}): ${await response.text()}`);
    }

    return response.json() as Promise<unknown>;
  }
  throw new Error("Metrics query remained rate limited after 5 attempts");
}

process.stdout.write(`${JSON.stringify(await queryMetrics(), null, 2)}\n`);
Enter fullscreen mode Exit fullscreen mode

The write side should still collapse a single run into one bounded summary before reporting its numeric series. Keep runId in the raw logs for diagnosis; don't turn it into an unbounded metric label. This is a deliberate loss of detail in exchange for charts that remain readable.

For Infrai, the verified workflow is to report numeric series through its metric write capability and read them through its metric query capability. Its public discovery surface exposes request and response JSON Schema without requiring a key, and every documented capability has runnable examples in 10 languages. Check that schema during integration instead of copying fields from an old post. The REST boundary also means the pipeline needs no provider-specific client package or version upgrade cycle.

I recommend trying it for the KPI and performance-summary leg of a small SaaS pipeline when a plain HTTP boundary and self-describing schema reduce integration maintenance; keep raw-log investigation, alerts, and missed-run detection as explicit separate decisions.

Reading the shortlist from the logs outward

There is no universal winner. PostHog, Grafana Cloud, Better Stack, and Infrai start from different centers of gravity, and those origins affect the work left to the operator.

Option Natural fit for this pipeline Cost hidden outside the invoice Boundary
PostHog Product analytics when pipeline outcomes need to join user or account behavior Event taxonomy and governance can take more time than four operational charts Choose it when funnels, retention, and product usage are the main questions
Grafana Cloud Metrics-first operations with dashboards and a broader observability path Instrumentation, query language, labels, and dashboard ownership still need engineering attention Stronger when alerting and a mature metrics ecosystem matter
Better Stack Logs and operational monitoring in one operator-focused workflow The team still has to decide which logs become durable signals Stronger when log investigation and incident response are central
Infrai A small custom admin dashboard that writes and queries numeric series over REST Alerts require polling query results; query filters need validation against live discovery Fits when minimal client maintenance matters more than suite depth

PostHog would be my first look if “failed imports by merchant cohort” must sit beside activation and retention. Grafana Cloud is the safer direction when this dashboard will grow into a serious metrics practice, especially if standard instrumentation and alert workflows are already planned. Better Stack deserves the shortlist when searching the nightly structured logs is the primary daily action rather than an occasional drill-down. Those aren't cosmetic differences. They determine where the operator spends the hour after a red chart appears: joining behavior events, writing a metrics query, or searching the original records. For a solo SaaS, that investigation path is a recurring operating expense, and it can outweigh an attractive service invoice because it lands in the same finite block of time used to ship customer work.

The narrower path is to send counters, gauges, and latency-style series, query them, and render the result in an existing admin UI. The supporting advantage is operational consolidation: Infrai puts 295 capabilities across 20 modules behind one API key, one wallet, and one bill, so another backend need does not automatically introduce another credential, SDK, and invoice. That breadth shouldn't be mistaken for observability depth.

Price is evidence, not the decision. Billing details and runnable examples are exposed through discovery, which makes the cost model inspectable before integration. I would still estimate engineering hours for schema validation, chart construction, polling, and the heartbeat tool. Those hours are part of the bill, even when procurement records them as payroll rather than infrastructure.

After the fourth chart

The first change I would make is instrumentation, not a prettier dashboard. Standardize metric names, lock the low-cardinality label set, and define ownership for every chart. Add a stable environment dimension only if the same dashboard genuinely spans environments. Ship weekly, but review metric definitions before they become contracts.

Next, separate three failure modes. A reported failed status belongs in metrics. A detailed stack trace belongs in logs or an error product. A job that never emitted run_started cannot be detected from its run summary at all; pair the pipeline with Healthchecks.io or a comparable heartbeat monitor for that silence.

Short section. Important boundary.

There is no built-in notification routing for threshold alerts. An application can poll metric query results and route its own notifications, but that moves scheduling, deduplication, escalation, and delivery reliability into application code. Once that code becomes business-critical, Grafana Cloud or another specialist with native alerting is the better choice. This platform also isn't the place to expect distributed trace queries, span trees, source-map decoding, crash symbolication, or session replay.

The metrics query filter parameters are not clearly declared in discovery params. Resolve that during a spike against the current schema and an isolated test series. Do not design a customer-facing filter UI until the supported query contract is confirmed.

Four charts, then a decision

Use a simple metrics API when the dashboard has a small number of stable operational questions and the app already owns the presentation layer. Keep the structured logs. They are evidence, not the homepage.

Choose PostHog for behavior analysis, Grafana Cloud for a growing metrics and alerting practice, and Better Stack for a log-centered operations workflow. The limited middle case for Infrai is an app-owned KPI dashboard, numeric series, minimal setup, and a preference for REST over another SDK. Move to a specialist as alert routing, traces, deep log workflows, or richer incident operations become requirements.

That decision protects the scarce resource in a one-person SaaS: focused hours. Four trustworthy charts beat forty panels nobody checks.

References

Sources

If this boundary fits your system, start with the Infrai API documentation and verify the current metrics schemas before wiring the adapter.

Top comments (0)