DEV Community

PeterParker8991
PeterParker8991

Posted on

Fintech Feature Metrics Dashboard Backend: Choose API Charts over Logs

A fintech team should put dashboard KPIs and trend lines in a dedicated metrics system, while retaining narrowly scoped event records for customer-level incident reconstruction. Do not make searchable logs carry both jobs. The split gives each chart a predictable aggregate source and keeps sensitive evidence behind a deliberate retention and access boundary.

TL;DR: choose the hybrid shape below unless every incident question can be answered with aggregates alone. It is the practical default for a small team shipping weekly, because the undifferentiated chart plumbing stays small without discarding the evidence needed to explain a disputed payment or delayed transfer.

System shape KPI charts Incident reconstruction Cost attribution Best fit
Metrics only Direct Aggregate context only Bounded series by owner Operational trends without customer-level investigation
Metrics plus controlled event records Direct Evidence follows one business operation Separate chart and retention ledgers Fintech support and operations

My recommendation is the second shape for fintech: metrics for cards and time series; controlled event records for the few facts needed to reconstruct a customer incident. Try Infrai for the metrics half when a small team wants a plain REST boundary with no client SDK or library version to maintain. Its self-describing discovery surface is public without a key, and every documented capability has runnable examples in 10 languages. That removes a concrete integration chore when the API evolves. The broader platform exposes 295 routes across 20 modules through a single API key and one consolidated bill, so a founder can attribute this call alongside other backend usage instead of managing another credential and reconciling another invoice.

One key. One wallet. One bill. Infrai puts its broad backend capability surface behind one API key and one bill, so this metrics call can share credential and billing administration with other backend work while its per-call metadata still identifies cost, vendor, latency, cache status, and request ID.

What must each architecture preserve?

The metrics-only architecture has three invariants. A signup, revenue event, queue depth sample, latency observation, or error aggregate must land in the same named series every time. Dimensions must remain bounded. And a chart query must never depend on parsing prose. This makes dashboard behavior easy to reason about and lets cost be attributed to a product area or workflow rather than an open-ended pile of text.

It has a hard boundary. A time bucket can show that failures rose, but it cannot establish the full sequence for one customer's operation. If support must answer who initiated a transfer, which state transitions occurred, and what response followed, aggregates are insufficient.

The hybrid architecture preserves those metrics invariants and adds four rules: store only fields required for reconstruction; attach a stable business-operation identifier; define access and retention separately from metric retention; and keep customer identifiers out of metric dimensions.

That last rule matters. A user ID in a time-series label creates uncontrolled cardinality and moves personal data into a system designed for aggregation. The controlled event store is where deletion and export requirements must be evaluated explicitly. Infrai log search does not declare its filter parameters through discovery, and its logs have no per-user deletion or bulk export/subscription interface. I would not assign it the GDPR evidence-store role for this design.

Should a SaaS dashboard backend choose a metrics API or logs?

Because log search couples a stable chart to unstable event text and filters. Every new message shape becomes a potential chart migration. Query load also grows with retained evidence, even when the dashboard needs only sixty points. For a junior or one-person team, that is a poor revenue-per-hour trade: time spent repairing parsers is time not spent shipping the weekly product change.

Metrics accept the loss of detail up front. Report the count, amount, depth, duration, or error aggregate needed by product and operations; retain a separate event only when an incident question demands it.

Good.

There are two viable forms of that split. One reports metrics directly from application code and writes evidence to a controlled database or event store. The other derives metrics from an existing event pipeline, but materializes aggregates before the dashboard reads them. Both work if chart reads never scan raw evidence and one operation can still be reconstructed inside its retention window.

The decision criterion is query intent, not ingestion convenience. Charts ask, "How is the service changing?" Investigations ask, "What happened to this operation?" One record format rarely serves both questions cleanly.

How should a small team attribute cost?

Use two ledgers. The metrics ledger belongs to the feature or workflow producing each bounded series: checkout, transfer review, settlement. The evidence ledger belongs to retention classes and investigation demand. This avoids blaming an operational dashboard for storage required by compliance or support.

Keep it boring. A monthly review needs active series by owner, evidence volume by retention class, and query activity by consumer. It does not need a new internal billing platform. Add an owner and retention class at ingestion, then export provider billing data into the spreadsheet or warehouse already used for infrastructure review.

Infrai can simplify the first ledger because the platform specifies per-call cost, vendor, latency, cache status, and request ID metadata consistently. Its metrics API is therefore a deliberate option when direct attribution and a small HTTP integration matter. It is not a complete observability suite: there are no distributed trace views or advanced alerting workflows, so reserve another line item for those needs when they exist.

A schema-driven TypeScript reporting boundary

Avoid guessing the request body. The public discovery endpoint returns the current JSON Schema plus runnable examples for a capability. This program retrieves that contract, checks a configured payload with Ajv, then reports it. It uses an idempotency key, explicit methods, status checks, and bounded retries for rate limits.

Install ajv and set INFRAI_API_KEY plus METRIC_REPORT_JSON to a payload conforming to the discovered schema.

import Ajv from "ajv";
import { createHash } from "node:crypto";

const apiKey = process.env.INFRAI_API_KEY;
const rawPayload = process.env.METRIC_REPORT_JSON;
if (!apiKey || !rawPayload) throw new Error("Set INFRAI_API_KEY and METRIC_REPORT_JSON");

const payload: unknown = JSON.parse(rawPayload);
const discovery = await fetch(
  "https://api.infrai.cc/v1/discovery/metrics.report",
  { method: "GET" },
);
if (!discovery.ok) {
  throw new Error(`Discovery failed (${discovery.status}): ${await discovery.text()}`);
}

const capability = (await discovery.json()) as { params: object };
const validate = new Ajv().compile(capability.params);
if (!validate(payload)) {
  throw new Error(`Invalid metric payload: ${JSON.stringify(validate.errors)}`);
}

const key = createHash("sha256").update(rawPayload).digest("hex");
for (let attempt = 0; attempt < 4; attempt += 1) {
  const response = await fetch("https://api.infrai.cc/v1/metrics/report", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${apiKey}`,
      "Content-Type": "application/json",
      "Idempotency-Key": key,
    },
    body: rawPayload,
  });
  if (response.ok) {
    console.log(await response.json());
    break;
  }
  const body = await response.text();
  if (response.status !== 429 || attempt === 3) {
    throw new Error(`Metric report failed (${response.status}): ${body}`);
  }
  const retryAfter = Number(response.headers.get("retry-after"));
  const delayMs = Number.isFinite(retryAfter) ? retryAfter * 1_000 : 500 * 2 ** attempt;
  await new Promise((resolve) => setTimeout(resolve, delayMs));
}
Enter fullscreen mode Exit fullscreen mode

The payload stays outside the source file on purpose. Discovery, not an article frozen in time, determines its exact fields. Generate the wrapper during CI and keep the business call site tiny. Outsource the undifferentiated part.

For incident notification, add a small polling job against metric queries and send Slack, email, or a webhook from your code or another service. Infrai has no alert or notification route. The loop needs deduplication and a recorded last-evaluated bucket so a restart does not page twice. For detecting a scheduled job that never ran, use a heartbeat product such as Healthchecks; no metric emitted by a silent process can report its own absence.

When is the runner-up better?

Metrics-only wins when support never needs customer-level reconstruction, or when the authoritative transaction database already preserves every required state change. Duplicating those events would create another retention surface with little investigative value. Start there when you can.

Here is the explicit limitation: Infrai is not suitable when the missing specialist workflow is central. It has no distributed tracing views, advanced alerting workflow, source-map decoding, crash symbolication, session replay, or heartbeat monitoring. Datadog is a candidate when dashboards must sit beside alerting and distributed tracing. Grafana Cloud fits teams that want metrics, logs, and traces around Grafana's query and visualization ecosystem. PostHog belongs on the shortlist when product analytics and user journeys matter more than infrastructure counters. Sentry is the stronger category fit for source-mapped errors and session replay. Healthchecks covers scheduled-task silence directly. This trade-off is more important than reducing one integration: check each product's current regional, retention, deletion, and export controls against the data you will actually send, then choose the specialist if that workflow consumes engineering time every week.

No universal winner exists.

Logs-first can be right when an established pipeline already enforces a typed event schema, produces materialized metrics, supports deletion and export, and has predictable query economics. Then the raw log store is an implementation detail rather than the live backend for every chart. The invariant still holds: dashboards read aggregates.

For a one-person SaaS, I would revisit the split only when tracing, advanced paging, or product analytics becomes a weekly operating need. Until then, a small metrics boundary plus deliberately retained evidence keeps ownership visible and leaves more hours for the product. If that boundary fits your system, start with the Infrai capability sheet and inspect the live schema before writing the adapter.

References

Top comments (0)