Flow Studio
Log Entries in executionStore
executionStore.logs is a growing array of LogEntry objects appended by SignalR events during execution. appendLog is idempotent — duplicate logIds are silently discarded. The Logs tab reads this array through a virtual scroller.
LogEntry Schema
// logEntry.types.ts
export interface LogEntry {
logId : string; // Unique ID — used for deduplication
nodeId : string; // Source node
level : LogLevel; // 'Trace' | 'Debug' | 'Info' | 'Warning' | 'Error'
message : string;
timestamp : string; // ISO 8601
fields : Record<string, unknown>; // Structured log fields from INodeLogger
traceId ?: string; // OTel TraceId — links to distributed trace
}
appendLog — Idempotent Append
appendLog: (entry: LogEntry) => set(state => {
// Deduplication: skip if logId already exists
if (state.logs.some(l => l.logId === entry.logId)) {
return state; // No change
}
return { logs: [...state.logs, entry] };
});
// Called by useExecutionSignalR on NodeLogEmitted events
connection.on("NodeLogEmitted", (entry: LogEntry) => {
useExecutionStore.getState().appendLog(entry);
});
Log Level Color Mapping
| Level | Color | When to Expect It |
|---|---|---|
| Trace | Grey (dim) | Very detailed diagnostic entries — disabled in production by default |
| Debug | Grey | Diagnostic info for development |
| Info | White | Normal operational messages |
| Warning | Yellow | Unexpected but recoverable conditions |
| Error | Red | Node threw an exception or returned a failure |
Log Array Growth
The logs array grows unbounded during a run. For long-running workflows with verbose logging, the array can reach tens of thousands of entries. The Logs tab handles this with virtual scrolling — only visible rows are rendered. The store does not cap or truncate the array.
Historical logs come from the REST API, not SignalR. When viewing a past execution, logs are fetched via
GET /api/executions/{id}/logs (paginated) and batch-appended with appendLog. The display path is identical — same array, same component.