Documentation / Conception / Guides pratiques / Monitor executions

Monitor executions

The Executions view is where you watch workflows run: a live list of every run, the timeline of a selected run, the records of its subjects, and a composer to emit an event by hand. It merges what used to be the console and the monitoring page into one screen (apps/config-plane/app/executions/ExecutionsView.tsx; the run list, timeline, and record pane are the shared components in apps/config-plane/lib/runs.tsx). This recipe walks the four things you do there, then the event traffic of the Routing screen.

Every published workflow that receives an event starts its own run. One event can therefore start several runs, one per workflow; a domain event's run id is <eventId>:<slug> (see Run and resolve).

Prerequisites

  • A running Meridian instance with the config plane open — see Your first instance.
  • At least one deployed workflow. Runs are created either by an event source or by the composer below.
  • To resolve a validation, a workflow with a human-validation node — see Add human validation.

Read the run list

The left pane lists all runs, newest first, and in live mode refreshes itself every 2 seconds — a new run (from an event source or the composer) appears without a reload.

  1. Read the pane header: Runs · N is the total, and a to resolve tag counts runs currently suspended (waiting on a validation).
  2. Scan each row. It shows the workflow name, then a colored status LED with the raw status, the run's subject ids (one per context kind present in the event — e.g. the patient), and the run's creation time. Status is one of running, completed, suspended, failed, or pending; anything else renders as an unknown state.
  3. Click a row to select it. The center pane loads that run's detail; if the run is unreadable (for example, a run recorded before a Restate service rename) the center pane shows the error instead of stale detail.
  4. To list the runs of one event, follow Same event from a run (below). The list is then filtered by the server (GET /api/runs?event=<eventId>), so older runs of the event are found beyond the 200 most recent ones; the pane shows an Event line with the event id, and its × button (or the filter reset) removes the filter.

The most recent run is auto-selected on first load. An empty list means no run has been created yet.

Read a run's timeline

Selecting a run fills the center pane. The header badge repeats the status, workflow name, subject ids, creation time, the (truncated) run id and the routing reason — trigger filter (its filter kept the event), no filter, designated (the event named this workflow; its filter is not evaluated) or own address (webhook, schedule, sub-workflow call, EAI connection). When the event id differs from the run id, a line reads Source event: and the event id, with a Same event link to the runs of that event. The workflow graph of a run shows the same reason and link in its run bar. Below the header, under Workflow flow, is the timeline.

  1. Read the timeline top to bottom — it is the engine's observations in execution order, one row per node. Each row has an index, a status icon, the node id, and a one-line summary of its outputs:
    • ✓ — node ran (done)
    • ✗ — node failed and failed the run; the summary is the error. A run that fails at its trigger (for example on an event no loaded plugin declares) has a single trigger row with this icon.
    • ⤼ — node was skipped; the summary gives the reason
    • ✍ — a validation on this node was resolved; the summary names the decision and who made it
    • ⏸ — this node is the one awaiting a decision right now
    • a trailing ↺ next to a node name marks a step that was replayed on resume (durable-execution replay — see Why durable execution)
  2. Click any row to expand it. You get the node's inputs, its config, and its outputs. On the trigger row, the expansion shows the raw event received that started the run: the workflow's copy of the event, whose eventId is the run id. The original event id is on the Source event: line of the run header.
  3. In live mode the detail keeps refreshing every 2 seconds while the run is running or suspended, so a suspended run flips to its resolved state in place once someone decides.

A node inside a flow.map body has one row per iteration, with the iteration index after the node id (#0 for the first element). On the workflow graph of the run (display mode Workflow), selecting such a node shows one execution at a time in the inspector. The previous and next buttons and the rank selector (2 / 5) switch between executions; the selector names the skipped and failed ones. The Item block shows the list element the iteration processed, once the loop has finished. The execution shown first is the failed one, otherwise the last.

Runs recorded without observations (very old runs) fall back to the raw step trace instead of the node timeline.

A run in flight whose journal no longer matches the endpoint's code, for example after the plugin that declares its trigger's event was unloaded, keeps its last status (waiting, suspended…) and its timeline while Restate retries it; it goes on once the plugin is back. See Observability signals, and, for the operator, Recover runs blocked by a missing plugin.

Resolve a pending validation

When the selected run is suspended, a validation block appears above the timeline with the question title and the payload to judge.

  1. Read the payload, then click Accept or Reject. From anywhere on the page (except while typing in a field or with the composer open) the keyboard shortcuts A and R do the same.
  2. The decision posts to the run, the timeline updates, and the run list refreshes.

That is the operator side of the two-level validation model; for the full picture of resolving and what happens next, see Run and resolve and Two-level validation.

Inspect the subjects' records

The right pane shows the live record of each subject of the selected run, one per context kind (patient · patient-42, flight · AFR011-20260929…): whatever the adapter declared as the record port of that kind holds now, for example the in-memory adapter or a real FHIR warehouse (served by GET /api/records/:kind/:id). Only the kinds whose bound adapter declares a record are read (recordKinds of GET /api/catalog); a subject of another kind has no record.

The record's shape belongs to the plugin that owns the record port. The console renders it as the plugin returns it: the record's own keys, untranslated, in the record's order, with no layout specific to a plugin:

  1. Read the subject heading (<kind> · <id>), then the record's simple fields as key and value.
  2. Open the sections: one per list or object of the record, named by its key; a list also shows its number of items. Each item lists its fields as key and value, nested fields as dotted paths (coding.display). A list shows its first 20 items, then the next ones under N more items; a section folds away. A value longer than 280 characters is cut, and its full text shows on hover.
  3. Read Mémoire, below the records: the workflow memory of the run's subjects and the workflow's items for all subjects — for each item its key, its version (v12), its scope (the owning workflow, partagée, or the owning workflow followed by tous les sujets), its stored type, its value, which workflow and node wrote it when, and its expiry. Oublier deletes an item (served by GET and DELETE /api/memory/:kind/:id, and /api/workflows/:slug/memory for the workflow's items).

The pane reads Reading records… until the records of the selected run are read, then No record when no subject of the run has one. A record that cannot be read shows why under its subject: the API's message, Unreadable record: invalid API response., or the API unreachable.

Emit an event

Use the composer to trigger a run by hand — to test a workflow end to end without wiring an event source.

  1. Click Emit an event in the top bar. The composer opens in the center pane.

  2. Pick the target workflow from the dropdown. A ⚠ next to a name means that workflow currently fails static validation (validate it first). The note beside the dropdown states the workflow's trigger type. The first option, None: every workflow that receives the type, sends the event without a target: every published workflow that receives it starts.

  3. Edit the event payload. It is prefilled with the example of the trigger's event. Each required context id missing from that example is a placeholder named <kind>-exemple (for instance "patientId": "patient-exemple"): replace it with a real id. Keep the payload valid JSON matching the trigger's event type.

  4. Click Send the event. The composer posts the payload (with the target workflow when one is picked) and reads the list of runs the API returns:

    • with a target, one run starts and is selected;
    • without a target, the center pane reads N runs started and the first one is selected;
    • an event already received starts nothing (Event already received: no new run.) and its first run is selected;
    • an event that no filter keeps starts nothing (Event filtered: no filter keeps it.);
    • when some deliveries fail, the composer stays open with the number of runs started and one Could not start line per failed workflow and its error. It writes the event's eventId into the payload: sending again is the same event and only starts the missing runs.

    Escape or Cancel closes the composer without sending. The catalogue example has no eventId: each send is a new event unless the payload carries one, as after a failed delivery.

Emitting here and receiving from a source are the same mechanism — both create a run from an event. To make events arrive automatically, see Connect an event source and The open event model.

Read the event traffic

The right half of the Routing screen (/routing) is the traffic history: recent events and EAI messages, newest first (apps/config-plane/app/routing/LiveEvents.tsx).

  1. Read one row per event. Its Source cell gives the event type and id, Status the outcome — Routed, Duplicate, Filtered (workflows receive this type, none of their filters keeps the event), Filter in error or Rejected — and Reason why the workflow received it (trigger filter, no filter, designated, own address), or the reason of a filtered, failed or rejected event.
  2. An event that started several runs shows ×N: click it to unfold one row per delivery, each with its workflow and a link to its run. A filtered or rejected event stays one row without a workflow.
  3. An event of a declared type that does not conform to its contract: refused, its issues are listed under its reason, headed Contract issues (in observe, an event refused for another reason shows them the same way); accepted (EVENT_CONTRACTS=observe), it carries a non-conforming mark next to its type, which shows the issues on hover and unfolds them on click (see Contract check).
  4. The summary counts the rows shown and the distinct events.

On the left half, a workflow whose filter raised an error on a recent event carries a filter in error mark: it did not start for that event, the other workflows did.

Freeze the view with live mode

The Live toggle in the top bar controls auto-refresh.

  1. Leave it on (Live on) to keep the list and the open run polling every 2 seconds — the default for watching activity as it happens.
  2. Turn it off (Live off) to freeze the current snapshot while you read a timeline without it moving under you. The status bar reads frozen and stops updating the last-sync time.

The status bar at the bottom always shows live/frozen, the run count, the count of runs awaiting a decision, and the time of the last sync.

97 documents9 sectionssource : /docs · généré au build