Metrics Ingestion

Push time-series metrics via `/ingestion/metrics` and surface them on each entity's Metrics tab — covers payload shape, two storage backends (PostgreSQL + Prometheus), and operator caveats.

The Metrics Ingestion surface accepts time-series metrics pushed into the platform by collectors or custom integrations and surfaces them on each affected data entity's Metrics tab. The platform supports the OpenMetrics metric model — five metric types (COUNTER, GAUGE, HISTOGRAM, SUMMARY, GAUGE_HISTOGRAM) carrying labels and observation values — and stores them either in its own PostgreSQL database or in an external Prometheus instance, depending on the deployment's metrics.storage configuration.

Operators turning on metrics ingestion typically have one of two workflows in mind:

  • Catalog-side cardinality metrics — row counts, on-disk size, freshness gauges emitted by a collector that scrapes a source system and pushes the result to ODD. These appear as cards on the entity's Metrics tab so an operator opening the entity sees the current row count alongside its schema, ownership, and lineage.

  • Custom-framework metrics — an in-house pipeline (a daily ETL job, an external profiling tool, a side-process emitting per-entity health signals) pushes structured metrics into the catalog so the platform becomes the single source of truth for "what numbers describe this entity right now."

This page covers the inbound push surface (POST /ingestion/metrics), the entity-side read surface (the Metrics tab), and the three operator caveats that the configuration reference does not surface in full.

Where to find it

Two surfaces consume the same data:

  • POST /ingestion/metrics — the inbound push endpoint. Collectors and custom integrations call this with a MetricSetList payload (one or more MetricSets, each anchored to a data entity's ODDRN and carrying a list of MetricFamily time series).

  • Per-entity Metrics tab — on a data entity's detail page, the Metrics tab renders the ingested time series as charts. The platform reads from GET /api/dataentities/{id}/metrics, which fans out to either the internal PostgreSQL store or the configured Prometheus instance depending on metrics.storage.

For the platform-side configuration of the two storage backends (metrics.storage, metrics.prometheus-host, the Prometheus remote-write requirement), see Configure ODD Platform → Enable Metrics. The configuration reference is the canonical home for the storage knobs; this page is the surface description and the operator-caveat list.

The endpoint

POST /ingestion/metrics
Content-Type: application/json

{
  "items": [
    {
      "oddrn": "<data-entity-oddrn>",
      "metric_families": [
        {
          "name": "<metric-family-name>",
          "type": "COUNTER",                /* or GAUGE / HISTOGRAM / SUMMARY / GAUGE_HISTOGRAM */
          "metrics": [
            { "labels": {"<key>": "<value>", ...}, "metric_points": [ { "value": 123, ... } ] }
          ]
        }
      ]
    }
  ]
}
Property
Notes

Method

POST

Path

/ingestion/metrics

Request body

MetricSetList — one or more MetricSets; each MetricSet carries an oddrn (the target data entity) and a list of MetricFamily entries.

Body size cap

20 MB. The Spring WebFlux codec max-in-memory-size is set to 20MB in application.yml. A request larger than that does not get a clean rejection — the platform raises an internal buffer-limit error during body decoding and returns HTTP 500 (not a 413 "Payload Too Large"), with no body identifying the cap as the cause. Chunk large pushes into multiple MetricSetList calls to stay under the limit; a 500 from this endpoint on a large push is the symptom to look for.

Response

201 Created (no body). The platform does not return a per-metric acceptance result. See the empty-payload caveat below — an empty MetricSetList also returns 201, so a 201 is not by itself proof that any metric was written.

Failure on misconfigured storage

If metrics.storage is set to an invalid value (anything other than INTERNAL_POSTGRES or PROMETHEUS), the platform fails to start with NoSuchBeanDefinitionException because the storage-backed IngestionMetricsService bean cannot be wired. Misconfiguration is caught at boot, not at first request.

The exact OpenAPI shape (per-field schemas, the five metric-type discriminators) lives in the platform's ingestion contract; consult the ODD Specification for the field-level reference.

Known operator caveats

Several behaviours of the metrics ingestion surface are non-obvious from the configuration reference alone. Each item below states what an operator might assume, what the platform actually does, and what to do today.

Where to next

  • Configure ODD Platform → Enable Metricsmetrics.storage, metrics.prometheus-host, the OTLP export channel, the Prometheus tenant label.

  • Enable Security → Ingestion — the per-auth.type reachability matrix for every /ingestion/* path (including /ingestion/metrics).

  • Notifications — the sibling subsystem that moves alerts out of the platform; the same WAL-driven pipeline reads ingested events.

  • API Reference — the per-feature HTTP-endpoint index. The metrics push side lives in the ODD Specification ingestion contract; the read side is covered by the per-entity API.

Last updated