Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion apps/sim/app/workspace/[workspaceId]/logs/logs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,9 @@ export default function Logs() {
(query: { state: { data?: WorkflowLogDetail } }) => {
if (!isLive) return false
const status = query.state.data?.status
return status === 'running' || status === 'pending' ? ACTIVE_RUN_DETAIL_REFRESH_MS : false
return status === 'running' || status === 'pending' || status === 'redacting'
? ACTIVE_RUN_DETAIL_REFRESH_MS
: false
},
[isLive]
)
Expand Down
12 changes: 11 additions & 1 deletion apps/sim/app/workspace/[workspaceId]/logs/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,14 @@ export const LOG_COLUMNS = {

export const DELETED_WORKFLOW_LABEL = 'Deleted Workflow'

export type LogStatus = 'error' | 'pending' | 'running' | 'info' | 'cancelled' | 'cancelling'
export type LogStatus =
| 'error'
| 'pending'
| 'running'
| 'redacting'
| 'info'
| 'cancelled'
| 'cancelling'

/**
* Maps raw status string to LogStatus for display.
Expand All @@ -29,6 +36,8 @@ export function getDisplayStatus(status: string | null | undefined): LogStatus {
switch (status) {
case 'running':
return 'running'
case 'redacting':
return 'redacting'
case 'pending':
return 'pending'
case 'cancelling':
Expand All @@ -55,6 +64,7 @@ export const STATUS_CONFIG: Record<
error: { variant: 'red', label: 'Error', color: 'var(--text-error)', filterable: true },
pending: { variant: 'amber', label: 'Pending', color: '#f59e0b', filterable: true },
running: { variant: 'amber', label: 'Running', color: '#f59e0b', filterable: true },
redacting: { variant: 'amber', label: 'Redacting', color: '#f59e0b', filterable: false },
cancelling: { variant: 'amber', label: 'Cancelling...', color: '#f59e0b', filterable: false },
cancelled: { variant: 'orange', label: 'Cancelled', color: '#f97316', filterable: true },
info: {
Expand Down
30 changes: 29 additions & 1 deletion apps/sim/lib/logs/execution/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,8 @@ export class ExecutionLogger implements IExecutionLoggerService {
private async applyPiiRedaction(
workspaceId: string | null,
payload: RedactablePayload,
storeContext: { workflowId?: string | null; executionId: string; userId?: string | null }
storeContext: { workflowId?: string | null; executionId: string; userId?: string | null },
onRedactionStart?: () => Promise<void>
): Promise<RedactablePayload> {
if (!workspaceId) return payload

Expand All @@ -666,6 +667,10 @@ export class ExecutionLogger implements IExecutionLoggerService {
const config = resolveEffectivePiiRedaction({ orgSettings: row.orgSettings, workspaceId }).logs
if (!config.enabled) return payload

// Masking large payloads can take a while; let the caller surface the phase
// (e.g. flip the log row to 'redacting') before the slow work starts.
await onRedactionStart?.()
Comment thread
TheodoreSpeaks marked this conversation as resolved.

// The string redactor can't reach values already offloaded to large-value
// storage (>8MB refs). Always hydrate → mask → re-store them under the LOGS
// policy, even if the block-output stage already masked before offload: that
Expand Down Expand Up @@ -867,6 +872,29 @@ export class ExecutionLogger implements IExecutionLoggerService {
workflowId: existingLog?.workflowId ?? null,
executionId,
userId: actorUserId,
},
async () => {
// Execution is done but the log payload is still being masked — surface
// that as 'redacting' so the Logs UI doesn't show a stale 'running'.
// Guarded on 'running' so a concurrent cancellation is never clobbered;
// the terminal update below overwrites with the final status either way.
// Purely cosmetic: a failed write must never abort masking/finalization.
try {
await db
.update(workflowExecutionLogs)
.set({ status: 'redacting' })
.where(
and(
eq(workflowExecutionLogs.executionId, executionId),
eq(workflowExecutionLogs.status, 'running')
)
)
} catch (error) {
logger.warn('Failed to set redacting status on execution log', {
executionId,
error: getErrorMessage(error),
})
}
}
)

Expand Down
2 changes: 1 addition & 1 deletion apps/sim/lib/logs/fetch-log-detail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ export async function fetchLogDetail({
)

const liveMarkers =
log.status === 'running' || log.status === 'pending'
log.status === 'running' || log.status === 'pending' || log.status === 'redacting'
? ((await getProgressMarkers(log.executionId)) ?? {})
: {}
const rowMarkers = (executionData ?? {}) as ExecutionProgressMarkers
Expand Down
Loading