Integrations & packs
An integration onboards a source of data end to end: it detects software you run, configures the collector to ingest it, and installs a frame pack — a semantic layer and dashboards for that source. Reach for this page when you want to control which packs are installed; for the concepts behind them, see Integrations.
What an integration installs
When you enable one, it can do any of:
- Configure collection — add receivers to the collector so its telemetry gets ingested (e.g. tailing a log file, scraping DB stats).
- Edit the source’s own config — point the application at the collector. That file usually lives outside the project, so setup asks once before any of it is written and records the answer as
collect.integrations.external_edits. - Install a frame pack into
@frames/@<id>/— the views and dashboards you browse in the app. - Write editor skills into your coding agents (gated by
collect.integrations.skills— see Editor skills).
Integrations are reconciled on every noemata up, and on demand with noemata reconcile. By default their frame packs are managed — kept matching source and out of version control, so local edits don’t survive. You can instead take ownership of them; see Managed vs user-owned packs.
The always-installed packs
Two integrations are required: they install for every project, whether or not installed names them, and the wizard doesn’t offer to turn them off. Everything else Noemata ships references their frames, so a workspace without them has dangling references.
@noemata— Noemata’s own content: these docs (installed into the workspace at@frames/@noemata/docs/) plus a self-monitoring dashboard over Noemata’s own telemetry — the app server’s API, the query engine and its cache, the browser client’s web vitals, and the Node runtime.@opentelemetry— the OpenTelemetry semantic layer and app in one pack. Its page-less base views (@opentelemetry/views/traces,@opentelemetry/views/logs, the metrics views, and the five-signal@opentelemetry/views/combined) name the OTel semantic conventions once — pure, reusable bindings every dashboard builds on viaimports— and the same pack ships the dashboards (below).
Neither needs a collector, so both reconcile even into a project that has configured no telemetry stack at all. Listing one under installed stays valid — that is where per-integration settings would go — but it is never what switches it on.
The OpenTelemetry dashboards
The same @opentelemetry pack ships one tabbed dashboard — an Overview with a volume-adaptive service map, plus Services, Reliability, Traces, Logs, Database, Messaging, and Infrastructure sections — alongside per-entity routes (a service detail whose tab set adapts to what the service is: a backend, a browser app, or metrics only; plus entry operation, RUM session, trace waterfall, feature flag, host, and Kubernetes namespace / workload / pod pages). They read the otel_* tables the collector already populates and add no collector config of their own.
The otel_collector integration works the same way for the collector itself: the managed collector routes its internal metrics and logs back through its own OTLP receiver (see Monitoring the collector), and the @otel_collector pack turns that stream into a collector-health dashboard — pipeline throughput, refused and failed items, queue saturation, process resources, and the collector’s own logs.
Available integrations
Integrations are detected by the software you run. Broadly they cover: coding agents (coding), the common baseline, containers, databases, host metrics, images, llm serving, noemata itself, opentelemetry, and search engines. The setup wizard probes for each and offers the ones it finds; see Integrations for how detection works.
Enabling and disabling
The wizard (noemata config) is the usual way to change what’s installed. In noemata.json, integrations live under collect.integrations:
{ "collect": { "integrations": { "installed": { "opentelemetry": {} }, "managed": true, "skills": true, "external_edits": true } }}installed— the integrations enabled for this project, keyed by id. Two are enabled whether they appear here or not — see the always-installed packs — so leaving one out means “install it with the defaults”, never “leave it out”. Some integrations imply others: enablingmy_machine(the “monitor this machine” pick) also reconciles thehostmetricsdata integration — its collector config and frame pack install as if it were listed here, without appearing in the file.managed— whether Noemata owns the installed frame packs (see below).skills— whether integrations write editor skills (see Editor skills).external_edits— whether reconciliation may write outside the project (e.g.~/.claude/settings.json). The wizard asks once, when an integration you enable writes there, and records a decline here; every later reconcile reads it. When a reconcile does change a file outside the project it warns, naming each one.
To skip integrations for one run, use the up flags: --no-integrations (regenerate service configs only), --no-skills, or --no-external-edits.
Managed vs user-owned packs
collect.integrations.managed decides who owns the installed frame packs under @frames/@<id>/. --managed / --no-managed on the command line overrides it for a single run.
Reconcile compares each pack file against what it last installed, recorded under .data/packs/, so a local change can be told apart from an upstream one:
true(the default) — Noemata-managed. The packs are gitignored and reconcile keeps them matching source, overwriting local edits. Extend them by reference, never in place (below).false— user-owned. A local edit or deletion is preserved, and the packs are tracked by git like hand-authored frames. Ownership is per file: upstream changes still reach everything you haven’t touched.
A pack that is already installed but has no recorded base is adopted rather than overwritten — without a base there is no way to tell an untouched install from an edited one — and the base is recorded so the next run classifies normally.
Customizing a pack
With managed packs (the default), don’t edit an installed frame in place — the next reconcile overwrites it. Add a sibling frame that references the upstream one and layer your changes on top:
- add the installed frame to a view’s
importsto inherit its scalars and scope (see Views), or - pull a specific block in with
@block/use.
The frame schema reference has the full imports and reference surface. (With user-owned packs you can edit in place, but referencing still keeps your changes cleanly separated from upstream.)
.local overlays
To retune a shipped frame without forking it, drop a .local overlay next to it: index.frame.local.json beside index.frame.json (or index.page.local.json, overview.templates.local.json). The frame renders as base ⊕ local — the overlay replaces or adds the fields it names, and everything else is inherited from the managed base:
{ "$schema": "../../../.data/schemas/frame.overrides.json", "title": "My services", "view": { "tables": { "logs": { "table": "otel_logs", "with": { "Sev": "SeverityText" } } } }}Every field is optional, and an overlay only ever adds or replaces — it can retitle the frame, add or retune view tables and scalars, add named templates, or swap the page wholesale, but it never deletes a base field. .local files are yours: gitignored and never committed, so the tweak survives the next noemata up re-stamping the managed base. Editing an overlay hot-reloads the frame, and it is JSON-Schema validated and autocompleted in the editor. An overlay with no base file beside it is a validation error, not a silent no-op.