Record conventions
Detections emit OTel log records named noemata.detection.<kind>. Supported kinds are extract, threshold, burn_rate, appears, disappears, changes, and value_change. Alerting and recommendation enrichment retain the detector’s event name. emit.log.event_name can override it; noemata.detection.kind remains available for selection.
Severity defaults to info, except changes, which normalizes the detected change point’s info, warning, or critical label to info, warn, or error (OTel INFO/9, WARN/13, or ERROR/17). Extraction classification and alerting override the default; explicit emit severity has final precedence. SQL severity uses the normalized default or classified value before an emit override.
Detection identity
| Attribute | Value |
|---|---|
noemata.detection.kind | Detector kind. |
noemata.detection.name | Workflow reference, or authored change.name. |
noemata.detection.instance | Stable hash of grouping values, scoped by workflow reference and step. |
noemata.detection.group.<column> | Each grouping dimension’s value. |
Identify a detector instance by the scope attributes noemata.workflow.ref and noemata.workflow.step together with noemata.detection.instance. The hash alone is not globally unique. Instance hashing distinguishes NULL, empty strings, and values containing separators. An ungrouped detector has one instance. Change-point boundaries distinguish findings internally but are excluded from the public instance hash and group attributes. Extraction event identity still distinguishes source rows. Deduplicate log delivery by noemata.event.id, which reproduces across retries independently of the run ID.
Detector measurements
All fields below have the prefix noemata.. Missing readings are omitted.
| Namespace | Fields |
|---|---|
extract | source.event_name, when present on the source. Selected source attributes are also retained. |
threshold | value, and values when alert history is captured. |
burn_rate | value, budget_remaining, exhausts_at, burn_long_1 through burn_long_4, burn_short_1 through burn_short_4, and captured values. |
appears | first_seen, last_seen. |
disappears | last_seen, and captured values of the absence count. |
changes | type, direction, magnitude, severity_text (info, warning, or critical), from, to, boundary, and captured values. |
value_change | from, to. |
Timestamp attributes use ISO strings. Numeric readings retain their numeric types. Authored change.of, change.from, and change.to use the corresponding detector namespace. Missing-data recovery omits unavailable current measurements.
Alert state
Persistent alerts emit events only on transitions. Quiet evaluations and unchanged firing evaluations do not emit default logs. Resolution is a transition, including when the instance is absent and no_data: resolve applies.
| Attribute | Value |
|---|---|
noemata.alert.transition | fired, escalated, de-escalated, or resolved. |
noemata.alert.state | Resulting persistent state: firing or quiet. |
noemata.alert.level | Held info, warning, or critical level; absent on resolution. |
noemata.alert.previous_level | Prior level on escalation, de-escalation, or resolution. |
noemata.alert.fired_at | Episode start, including on its resolution. |
noemata.alert.evaluated_level | Instantaneous matching level, when present. |
noemata.alert.evaluated_levels | Captured evaluation history. |
noemata.alert.condition / condition.<op> | Entered level’s predicate or comparator operand. |
Levels map to OTel severities info, warn, and error. Resolution defaults to info. appears, changes, and value_change use one-shot classification: a qualifying finding has transition: fired and a level, with no persistent state, recovery event, or default alert gauge. Unmatched one-shot findings still emit with no alert attributes, using detector severity for changes and info for appears and value_change. Matched findings emit once at the classified severity. Extraction adds noemata.alert.level and noemata.alert.condition on matched rows, without a lifecycle transition, state, recovery event, or gauge. Unmatched extraction rows have no alert attributes.
alert.limit caps tracked instances and retains their slots until recovery. alert.order_by ranks admissions. Emit filters and limits run after state updates and cannot remove tracked instances from evaluation.
One-shot event timestamps use finding time: the change-point boundary, appearance first-seen time, or exact-value change source time. Persistent alert events use transition time. Extraction preserves source time. Explicit emit time overrides these defaults.
Evaluation history noemata.alert.evaluated_levels is chronological: "" means a present evaluation matched no level; null means no input data. Array positions are preserved and align with the detector measurement history.
Recommendations
Every detector accepts recommend: { body, name?, where?, attributes? }. A matching predicate adds noemata.recommendation.name and noemata.recommendation.body; the name defaults to the workflow reference. A false or SQL NULL predicate preserves the event without advice. Recommendations preserve the event body, name, severity, and alert lifecycle.
body accepts literal, SQL, or Handlebars values. attributes accepts ordinary emit values; represent estimates and units with custom attributes when useful. Custom attribute precedence is detector attributes, matching recommendation attributes, then emit attributes. Authored maps cannot override reserved noemata.* attributes.
SQL enrichment reads detector output and alert results. Threshold expressions that need source columns or aggregates, in recommend or in detector attributes, project those values at the source grain before enrichment. Missing source values on recovery remain missing. Use where to restrict advice to the appropriate transition.
Default emission
| Detector | Without alerting | With alerting |
|---|---|---|
threshold, burn_rate | Evaluation events and measurement gauges. | Transition events, measurement gauges, and alert-level gauge. |
appears, changes, value_change | Finding events. | All findings; matched findings are classified. |
disappears | One event per absence episode. | Transition events and alert-level gauge. |
extract | Selected source-row events. | Classified source-row events. |
Detector emit owns detector events and measurements. alert.emit owns transition events and the alert-level gauge. Omitted or true selects defaults; false disables that location’s output; custom emission replaces that location’s defaults. Disabling output preserves evaluation and state updates. Under persistent alerting, custom detector logs receive transitions. For one-shot detectors, custom detector logs also receive unmatched findings. Custom detector metrics receive present evaluation rows. Custom alert metrics receive settled state, including resolution rows.
Measurement gauges include healthy evaluations independently of alert admission. Missing or non-finite measurements produce no point.
| Metric | Reading | Additional attributes |
|---|---|---|
noemata.threshold.value | Threshold evaluation value. | None. |
noemata.burn_rate | Burn multiple over one distinct trailing window. | noemata.burn_rate.window_seconds, numeric duration in seconds. |
noemata.burn_rate.max | Maximum burn across the long windows. | None. |
noemata.burn_rate.budget_remaining | Unspent fraction of the SLO window’s error budget. | None. |
Burn-rate gauges use unit 1. Equal window durations emit one point per instance and evaluation, even when used by multiple window pairs. Filter or group by window duration; do not sum overlapping windows. All windows and aggregate readings share the detection instance. Metric name, resource, scope, and data-point attributes distinguish metric series; timestamps, severity, and alert episodes do not enter the instance hash.
noemata.alert.level emits held ranks 1, 2, or 3 while firing and one final 0 on resolution. Quiet instances produce no further points. A no-data hold emits the held rank. Default metric dimensions contain stable detection identity and grouping; level, transitions, advice, run IDs, and event IDs do not split the series.
The runtime layer
Records produced by Noemata workflows use the noemata.workflows instrumentation scope. Scope attributes include noemata.workflow.ref, noemata.workflow.step, and noemata.workflow.hash. The hash fingerprints the authored execute definition, referenced block and expression helpers, literal template parameters, and evaluation schedule. Unused templates, the configured workflow reference, state version, and values resolved later from runtime context do not affect the hash. Bump version to reset carried state after changing the definition. Views select a record’s stream by its top-level EventName; the instrumentation scope identifies its producer.
Record attributes the runtime stamps:
| Attribute | Value |
|---|---|
noemata.event.id | Deterministic dedup identity. Delivery is at-least-once; a re-send carries the same id. |
noemata.workflow.run_id | The producing run. |
noemata.workflow.occurrence | ISO occurrence time of the evaluation that produced the record. |
noemata.frame.id / noemata.frame.instance | Only when the run is frame-hosted. |
noemata.component | workflow on a run’s own records; every log record the server emits carries the component it ran for (api, scheduler, workflow, bootstrap). |
Log records include noemata.event.id, noemata.workflow.run_id, and noemata.workflow.occurrence. Metric data points omit those per-record attributes. Metric attributes include authored attributes; frame-hosted metric data points also include noemata.frame.id and noemata.frame.instance as series attributes.
Authored attributes may not use the noemata.* namespace or event.name; validation rejects them.
The subject
A detection declares an entity — the OTel entity the record is about — as { type, id }:
"entity": { "type": "service", "id": { "service.name": { "sql": "ServiceName" } }}type is a semconv entity type (service, host, k8s.pod, k8s.deployment, k8s.namespace, k8s.node, k8s.container, container, process, session, user, and the other Kubernetes workload kinds). id maps each of that type’s semconv identifying attributes to the per-row value the detection reads for it. The emit path stamps the row’s resource with the identifying attributes under their semconv keys — service.name, k8s.namespace.name, k8s.pod.name, … — plus entity.type and a stable entity.id hash. Every record therefore lands in its subject’s own OTel resource: an alert on the checkout service reads back as ServiceName = 'checkout' on otel_logs and correlates against RED metrics and application logs on the same column.
The alert_brief and incident_candidate reports match subjects by
entity.id — the hash agrees across every record that names the same
entity. Subjects represented by subject.* attributes correlate by their attribute pairs, excluding subject.service.version.
HasDetectionSubjectIdentity on the logs view is true when either
entity.id is set or a subject.* attribute beyond subject.type is
present; unidentified records retain the triggering reading and condition
without inferred subject context in their briefs. Outbound dependency
context applies only when the entity type is service.
Subject types without a semconv resource key — Noemata-native concepts
like agent, database, mcp_server, pipeline — stay in
LogAttributes as subject.* pairs; the same identity fallback picks
them up in the reports.
noemata.workflow.run
One record describes each finished execution slice. The server emits it without waiting for export. A killed process may not emit a terminal record. The record uses the noemata.workflows scope and carries noemata.workflow.ref, noemata.workflow.hash, noemata.workflow.run_id, noemata.workflow.occurrence, and noemata.event.id. Frame-hosted runs also include noemata.frame.id. The timestamp marks when the slice finished. Event identity includes the outcome; yielded slices also include their start time.
Trace and span IDs for the run’s active context.
| Attribute | Value |
|---|---|
run.outcome | completed · failed · aborted. |
run.trigger | What started the run; schedule today. |
run.phase_ms | Milliseconds the schedule’s phase deferred the run past its occurrence. |
run.duration_ms | Wall-clock milliseconds of this execution slice, including admission and state publication. |
run.evaluated_rows | Rows in a completed declarative detection’s evaluation table; absent for pipelines and errors. |
run.steps | Completed steps, including those retained at a deliberate initialization yield. |
run.failed_step | The index of the step that failed, failed only. |
run.error | The failure message, failed only. |
Severity follows the outcome: completed is info, aborted is warn, failed is error. The body is a generated sentence naming the workflow, the outcome, the step count, and the duration.
The views
The OpenTelemetry pack’s detections view selects the raw EventName against the seven default names only. Overriding emit.log.event_name with a custom name excludes the event from the default detection views, including alerts, changes, and recommendations. Query custom streams through logs with an explicit EventName filter. Use a time bound and explicit event-name filters when selecting a particular default detector stream. Event-name selectivity does not guarantee index pruning; check the deployed ClickHouse schema and query plan.
@opentelemetry/views/detectionsexposesDetectionKind,DetectionName,Instance,EventId,AlertTransition,AlertState, workflow identity, and inherited subject fields.@opentelemetry/views/alertsselects alert transitions. It exposesKind,State,Level,PreviousLevel,Value,FiredAt, andEvaluatedLevel. AggregateIsFiringby workflow and instance; one-shot findings do not represent an active persistent alert.@opentelemetry/views/recommendationsselects advice presence. It exposesRecommendationName,RecommendationBody,AlertTransition,AlertState, andValue. Advice may be conditional, so its latest record alone does not establish current alert state; use the alerts view for that.@opentelemetry/views/changesselectsappears,disappears,changes, andvalue_change, including associated alert recovery events. It exposesKind,Of,ValueBefore,ValueAfter,Magnitude,Direction,ChangeType,FirstSeen, andLastSeen. UseAlertTransitionto distinguish a finding from its recovery.@opentelemetry/views/extractionsselects extraction detections and standalonenoemata.extract,noemata.report, andnoemata.briefrecords.Levelreads OTel severity andSourceEventNameidentifies the copied source.@noemata/views/workflow_runsexposes run outcomes, durations, evaluated rows, and errors fromnoemata.workflow.run.