Execution detail
Execution detail workspace
https://fve.meiermade.com/components/page-examples/execution-detail?state=ready&item=run-2407&view=fetch
Relay
Workspace
Customer analytics
run-2407
warehouse.customers · Production
- Dependency
- warehouse.customers
- Worker
- warehouse-worker-01
- Started
- 17 Sep 2026, 09:42:18 UTC
- Duration
- 1.24 s
- Attempt
- 1
- Execution
- run-2407
SucceededView in dependency graph
Trace waterfall
Select a span to inspect its timing and service. All timings are relative to execution start.
| Operation | Service | Start | Duration | 0 — 620 — 1,240 ms |
|---|---|---|---|---|
| Operation | Serviceworker-01 | Start0 ms | Duration1240 ms | 0 — 620 — 1,240 ms |
| Operation | Serviceidentity | Start20 ms | Duration90 ms | 0 — 620 — 1,240 ms |
| Operation | Servicesource-api | Start140 ms | Duration460 ms | 0 — 620 — 1,240 ms |
| Operation | Serviceworker-01 | Start600 ms | Duration120 ms | 0 — 620 — 1,240 ms |
| Operation | Servicepostgres | Start740 ms | Duration420 ms | 0 — 620 — 1,240 ms |
| Operation | Serviceworker-01 | Start1160 ms | Duration80 ms | 0 — 620 — 1,240 ms |
Span · GET /customers
- Service
- source-api
- Start offset
- 140 ms
- Duration
- 460 ms
- Span ID
- fetch
- Result
- Succeeded
- Execution
- run-2407
Correlated logs
- 09:42:18.000INFOExecution started on warehouse-worker-01
- 09:42:18.600INFOFetched 1,842 source records
- 09:42:19.160INFOCommitted 1,842 records to customer_dimension
open System
open FSharp.ViewEngine
open Acme.Components.Primitives
open Acme.Components.Application
open Acme.Components.Documentation
open type Html
open type Svg
open type Datastar
type ExamplePage =
| DependencyGraph
| ExecutionDetail
| FinancialReporting
| Messaging
| Operations
| Scheduling
| MediaManagement
type ReviewState =
| Setup
| Ready
| Loading
| Empty
| Failed
type ExampleQuery =
{ state: ReviewState
item: string
view: string
range: string }
let defaultQuery =
{ state = Ready
item = ""
view = ""
range = "" }
let slug =
function
| DependencyGraph -> "dependency-graph"
| ExecutionDetail -> "execution-detail"
| FinancialReporting -> "financial-reporting"
| Messaging -> "messaging"
| Operations -> "operations-dashboard"
| Scheduling -> "scheduling"
| MediaManagement -> "media-management"
let title =
function
| DependencyGraph -> "Dependency graph"
| ExecutionDetail -> "Execution detail"
| FinancialReporting -> "Financial reporting"
| Messaging -> "Messaging"
| Operations -> "Operations dashboard"
| Scheduling -> "Scheduling"
| MediaManagement -> "Media management"
let url page =
"/components/page-examples/" + slug page
let stateKey =
function
| Setup -> "setup"
| Ready -> "ready"
| Loading -> "loading"
| Empty -> "empty"
| Failed -> "error"
let queryUrl page query =
let pairs =
[ "state", stateKey query.state
"item", query.item
"view", query.view
"range", query.range ]
url page
+ "?"
+ (pairs
|> List.filter (snd >> String.IsNullOrEmpty >> not)
|> List.map (fun (key, value) -> key + "=" + Uri.EscapeDataString value)
|> String.concat "&")
let link (href: string) (label: string) : HtmlElement =
a {
_href href
_class
"font-medium text-[var(--fve-brand-text)] underline-offset-4 hover:underline focus-visible:outline-2 focus-visible:outline-[var(--fve-brand-ring)]"
label
}
let section (heading: string) (content: HtmlElement) =
Section.create (SectionHeader.create heading |> SectionHeader.withDivider) content
|> Section.render id
let details (fields: (string * string) list) =
DescriptionList.create [ for label, value in fields -> DetailField.text label value ]
|> DescriptionList.withColumns DescriptionListColumns.Three
|> DescriptionList.render
let reviewStates page =
(if page = Operations then [ Setup, "Setup" ] else [])
@ [ Ready, "Populated"; Loading, "Loading"; Empty, "Empty"; Failed, "Error" ]
let stateContent page query content =
match query.state with
| Setup
| Ready -> content
| Loading ->
div {
_class "p-8"
LoadingIndicator.create ("Loading " + (title page).ToLowerInvariant())
|> LoadingIndicator.withVisibleLabel
|> LoadingIndicator.render
}
| Empty ->
EmptyState.create "Nothing to show yet" "Change the current selection or return to the populated workspace."
|> EmptyState.withActions (link (queryUrl page { query with state = Ready }) "Return to workspace")
|> EmptyState.render
| Failed ->
Notice.create
"workspace-error"
"This view could not be loaded"
(p { "Your selection is preserved. Try loading it again." })
|> Notice.withTone Tone.Critical
|> Notice.withActions (link (queryUrl page { query with state = Ready }) "Try again")
|> Notice.render
/// Place durable workspace identity above the scrollable destination list.
let sideNavWorkspace (name: string) =
div {
p {
_class "text-xs font-semibold uppercase tracking-wide text-[var(--fve-muted-text)]"
"Workspace"
}
p {
_class "mt-1 truncate text-sm font-semibold"
name
}
}
let workspace page heading subtitle canvas actions content =
let product, workspaceName, destinations =
match page with
| DependencyGraph
| ExecutionDetail ->
"Relay", "Customer analytics", [ DependencyGraph, "Dependencies"; ExecutionDetail, "Executions" ]
| FinancialReporting -> "Ledger", "Northwind Studio", [ FinancialReporting, "Overview" ]
| Messaging -> "Gather", "Northwind Outdoor", [ Messaging, "Messages" ]
| _ ->
"Fieldwork", "Northwind Outdoor", [ Operations, "Overview"; Scheduling, "Schedule"; MediaManagement, "Photos" ]
let items =
[ for destination, label in destinations -> SideNavItem.create destination label ]
let navigation =
SideNav.create
(slug page + "-nav")
(product + " navigation")
(SideNavHeader.create product)
[ SideNavSection.ungrouped items ]
|> SideNav.withCurrent page
|> SideNav.withWidth SideNavWidth.Narrow
|> SideNav.withContext (sideNavWorkspace workspaceName)
|> SideNav.withMobileContext (sideNavWorkspace workspaceName)
|> SideNav.withFooter (
div {
_class "flex min-w-0 items-center gap-3"
Avatar.create "Andy Meier" "AM" |> Avatar.render
p {
_class "truncate text-sm font-medium"
"Andy Meier"
}
}
)
let header =
PageHeader.create heading
|> PageHeader.withSubtitle subtitle
|> PageHeader.withActions (ActionCluster.create (slug page + "-actions") actions)
let topBar =
PageTopBar.create ()
|> PageTopBar.withContent (
div {
_class "flex min-h-[var(--fve-shell-bar-min-height)] items-center px-4 sm:px-6 lg:px-8"
Breadcrumbs.create
(slug page + "-breadcrumbs")
(product + " breadcrumb")
[ BreadcrumbItem.create page product; BreadcrumbItem.create page heading ]
|> Breadcrumbs.render url
}
)
let body =
Page.create header content
|> Page.withTopBar topBar
|> Page.withWidth PageWidth.Full
|> Page.withBodyLayout (
if canvas then
PageBodyLayout.Canvas
else
PageBodyLayout.Padded
)
|> Page.render id
AppShell.create (slug page + "-shell") navigation body
|> AppShell.withTheme (
ComponentsTheme.sky
|> ComponentsTheme.withDensity Density.Compact
|> ComponentsTheme.withControlSize ControlSize.Small)
|> AppShell.withBoundary AppShellBoundary.Container
|> AppShell.asPreview (product + " workspace")
|> AppShell.render url
type DependencyNode =
{ key: string
name: string
operation: string
status: string
x: int
y: int
run: string }
let dependencyNodes =
[ { key = "customers"
name = "source.customers"
operation = "Fetch customer records"
status = "Succeeded"
x = 1
y = 2
run = "run-2401" }
{ key = "orders"
name = "source.orders"
operation = "Fetch recent orders"
status = "Succeeded"
x = 1
y = 15
run = "run-2402" }
{ key = "customer-load"
name = "warehouse.customers"
operation = "Load customer dimension"
status = "Succeeded"
x = 20
y = 2
run = "run-2407" }
{ key = "order-load"
name = "warehouse.orders"
operation = "Load order facts"
status = "Failed"
x = 20
y = 15
run = "run-2408" }
{ key = "revenue"
name = "reporting.revenue"
operation = "Build revenue summary"
status = "Blocked"
x = 39
y = 2
run = "run-2410" }
{ key = "retention"
name = "reporting.retention"
operation = "Calculate returning customers"
status = "Succeeded"
x = 39
y = 15
run = "run-2411" } ]
let nodeStatus status =
Status.create status
|> Status.withTone (
match status with
| "Succeeded" -> Tone.Positive
| "Failed" -> Tone.Critical
| _ -> Tone.Warning
)
|> Status.render
let selectedNode query =
dependencyNodes
|> List.tryFind (fun node -> node.key = query.item || node.run = query.item)
|> Option.defaultValue dependencyNodes[2]
type TraceSpan =
{ id: string
operation: string
service: string
start: int
duration: int
depth: int }
let traceSpans =
[ { id = "worker"
operation = "Execute dependency"
service = "worker-01"
start = 0
duration = 1240
depth = 0 }
{ id = "auth"
operation = "Check credentials"
service = "identity"
start = 20
duration = 90
depth = 1 }
{ id = "fetch"
operation = "GET /customers"
service = "source-api"
start = 140
duration = 460
depth = 1 }
{ id = "parse"
operation = "Decode 1,842 records"
service = "worker-01"
start = 600
duration = 120
depth = 1 }
{ id = "write"
operation = "INSERT customer_dimension"
service = "postgres"
start = 740
duration = 420
depth = 1 }
{ id = "commit"
operation = "Commit and publish"
service = "worker-01"
start = 1160
duration = 80
depth = 1 } ]
let spansFor node =
let order = node.name.Contains("orders", StringComparison.Ordinal)
traceSpans
|> List.map (fun span ->
{ span with
operation =
match span.id with
| "fetch" when order -> "GET /orders"
| "parse" when order -> "Decode 962 order records"
| "write" when order -> "INSERT order_facts"
| "commit" when node.status = "Failed" -> "Roll back transaction"
| _ -> span.operation })
let executionContent query =
let node = selectedNode query
let spans = spansFor node
let selectedSpan =
spans
|> List.tryFind (fun span -> span.id = query.view)
|> Option.defaultValue spans[4]
let failed = node.status = "Failed"
div {
_class "grid gap-6"
details
[ "Dependency", node.name
"Worker", "warehouse-worker-01"
"Started",
(if node.status = "Blocked" then
"Not started"
else
"17 Sep 2026, 09:42:18 UTC")
"Duration", (if node.status = "Blocked" then "—" else "1.24 s")
"Attempt", (if node.status = "Blocked" then "0" else "1")
"Execution", node.run ]
div {
_class "flex flex-wrap items-center gap-3"
nodeStatus node.status
link (queryUrl DependencyGraph { defaultQuery with item = node.key }) "View in dependency graph"
}
if node.status = "Blocked" then
Notice.create
"blocked-run"
"Waiting for an upstream dependency"
(p { "warehouse.orders must succeed before this execution can start." })
|> Notice.withTone Tone.Warning
|> Notice.withActions (
link (queryUrl ExecutionDetail { defaultQuery with item = "run-2408" }) "Inspect failed dependency"
)
|> Notice.render
else
section
"Trace waterfall"
(div {
_class "grid gap-3"
p {
_class "text-sm text-[var(--fve-muted-text)]"
"Select a span to inspect its timing and service. All timings are relative to execution start."
}
div {
_role "region"
_ariaLabel "Trace timings"
_tabindex 0
_class "overflow-x-auto"
Table.create
"Execution spans"
[ Table.column "Operation" (fun (item: TraceSpan) ->
div {
_style $"padding-left:{item.depth}rem"
link (queryUrl ExecutionDetail { query with view = item.id }) item.operation
})
|> Table.asRowHeader
Table.column "Service" (fun item -> text item.service)
Table.column "Start" (fun item -> text $"{item.start} ms") |> Table.alignEnd
Table.column "Duration" (fun item -> text $"{item.duration} ms")
|> Table.alignEnd
Table.column "0 — 620 — 1,240 ms" (fun item ->
div {
_ariaHidden "true"
_class "relative h-6 min-w-64 rounded bg-[var(--fve-surface-subtle)]"
div {
_class (
if failed && item.id = "write" then
"absolute top-1 h-4 rounded bg-[var(--fve-critical-text)]"
else
"absolute top-1 h-4 rounded bg-[var(--fve-brand-solid)]"
)
_style (
sprintf
"left:%.2f%%;width:%.2f%%"
(float item.start / 12.4)
(float item.duration / 12.4)
)
}
}) ]
spans
|> Table.withDensity Density.Compact
|> Table.render
}
})
section
("Span · " + selectedSpan.operation)
(details
[ "Service", selectedSpan.service
"Start offset", $"{selectedSpan.start} ms"
"Duration", $"{selectedSpan.duration} ms"
"Span ID", selectedSpan.id
"Result",
(if failed && selectedSpan.id = "write" then
"Failed · unique constraint"
else
"Succeeded")
"Execution", node.run ])
section
"Correlated logs"
(ul {
_class "divide-y divide-[var(--fve-border)] font-mono text-xs"
for time, level, message in
[ "09:42:18.000", "INFO", "Execution started on warehouse-worker-01"
"09:42:18.600",
"INFO",
(if failed then
"Fetched 962 order records"
else
"Fetched 1,842 source records")
"09:42:19.160",
(if failed then "ERROR" else "INFO"),
(if failed then
"Duplicate order key: ORD-1042. Transaction rolled back."
else
"Committed 1,842 records to customer_dimension") ] do
li {
_class "grid gap-2 py-3 sm:grid-cols-[8rem_4rem_1fr]"
span { time }
strong { level }
span {
_class "break-words"
message
}
}
})
}
let executionDetail query =
let node = selectedNode query
workspace
ExecutionDetail
node.run
(node.name + " · Production")
false
[ ApplicationAction.link (queryUrl DependencyGraph { defaultQuery with item = node.key }) "View dependency" ]
(stateContent ExecutionDetail query (executionContent query))
div { _class "h-[44rem]"; executionDetail defaultQuery }
|> Browser.create
|> Browser.withAddress "https://fve.meiermade.com/components/page-examples/execution-detail?state=ready"
|> Fixture.browser "page-workspace" "Workspace" "/components/page-examples/execution-detail?state=ready"
|> Fixture.render