Skip to content

Concepts

A frame models a thing you care about — a service, a host, a Kubernetes namespace, an API endpoint — and how to observe it. It pairs a view (what data is relevant and how to read it) with a page (how to display it). This page explains how those fit together; Views and Blocks cover each half in depth.

A frame = view + page

frame
├── view — semantic layer: tables, filters, derived columns, metrics
└── page — block tree: layout + queries + visualizations over the view

The view names and shapes your data once; the page refers to those names. A metric like DurationP95 is defined in the view and then used by name in any number of blocks on the page. Change the definition in one place and every block follows.

The view is a semantic layer, not a query

A view does not run a query by itself. It declares:

  • which tables the frame draws from (a database table, or another frame’s view — see extending frames);
  • a where filter that scopes every query in the frame;
  • a with map of named scalar expressions — derived columns like DurationMs and metrics like ErrorRate.

Blocks on the page then issue queries against this view, referring to its columns and metrics by name. Noemata compiles each block’s query together with the view into one SQL statement.

Metrics are just aggregating scalars

There is no separate “metric” type. A scalar in the view’s with map becomes a metric when its expression calls an aggregate function:

"with": {
"DurationMs": "Duration / 1e6", // derived column (row-level)
"DurationP95": "quantile(0.95)(DurationMs)", // metric (aggregate)
"ErrorCount": "countIf(IsError)", // metric
"ErrorRate": "ErrorCount / count()" // metric, built from another
}

Scalars can reference earlier scalars by name (ErrorRate uses ErrorCount), so you build a small vocabulary of derived columns and compose metrics from it. See Views.

Parameters make a frame addressable

A frame can declare params — typed slots, bound to a column, that scope it to one entity:

"params": [{ "type": "string", "column": "ServiceName", "required": true }]

A parameterized frame is reached by URL (?ServiceName=checkout), and the param auto-scopes every table in the view — Noemata adds ServiceName = <value> to each query automatically. One service frame definition then renders a dashboard for any service. See Views.

How data flows

DB table ──▶ view (filters + derived columns + metrics) ──▶ block query ──▶ visualization
▲ params auto-scope here

When the page renders, each data-bearing block (a plot, table, or stat) builds a query over the view, Noemata compiles and runs it, and the result feeds the block’s marks or columns. Cookbook walks this end to end.