Business flows
Most monitoring is organised around servers and services. Flowhawk adds a business map on top, which says which requests belong to which flow and step. With it, an alert names the flow that broke and how many customers it affected, and you can filter traces, logs, errors, sessions and metrics to a single flow.
The business map
The map is a list of flows. Each flow has steps, and each step has one or more rules that match requests by service and route, span name or queue.
flows:
- id: checkout
name: Checkout
criticality: critical # critical, important or background
slo:
availability: 99.5 # percent of requests that succeed
latencyP95Ms: 800
steps:
- id: cart
name: Add to cart
match:
- service: web
route: POST /cart/items
- id: pay
name: Pay
match:
- service: payments
route: POST /payments
- id: confirm
name: Send confirmation
match:
- queue: order-confirmations
Routes are written as METHOD /path, with :name for path parameters (GET /orders/:id). A rule can leave out the service to match the route in any service.
Drafting the map
Once traffic arrives, Setup drafts the map from the routes it sees, with alerts for the important flows and a first dashboard. You look through the drafts and accept the ones that fit. A coding agent connected over MCP can draft it from your code instead. Later changes go through Settings > Business map, the agent, or the YAML, and every change is a reviewed diff you can undo (config as code).
How requests are matched
- The first span of a request in a service (its entry) is matched to a step. Spans and logs below it in the same trace inherit the flow and step.
- With a Flowhawk SDK, the match happens in your service, and the flow travels to the services it calls in the trace's baggage, so a downstream service's work counts toward the same flow.
- With plain OpenTelemetry or a Sentry SDK, the match happens on our side by service and route. You still see flows. Downstream services are tagged by their own routes.
- Work that no route starts, such as a cron job or a queue consumer, can name its flow and step itself, with
withStep("payouts", "settle", fn)in the SDKs or the span attributesbusiness.flowandbusiness.stepwith plain OpenTelemetry.
What a flow gives you
- Requests, error rate and p95 latency for each flow and step, compared with the flow's SLO.
- How many requests and users failed, and since when.
- The deploys, flag changes and config changes that line up with a change in the flow, which are the likely causes.
- Links from the flow to its traces, logs, errors, sessions and metrics, filtered to that flow and the same time window.
- Collection settings per flow, so you can keep every checkout trace but only a tenth of a background job's (Settings > Collection). Errors and slow requests are kept on top of the sample rate.
Criticality decides how loud a flow is. A broken critical flow pages someone, while a broken background flow only shows in the app.