mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
feat(logging): standardize logging across manual, scheduled, and api executions. persist manual executions to db
This commit is contained in:
@@ -175,6 +175,8 @@ export async function GET(req: NextRequest) {
|
||||
cronExpression: schedule.cronExpression,
|
||||
})
|
||||
|
||||
const executionId = uuidv4()
|
||||
|
||||
try {
|
||||
// Skip if this workflow is already running
|
||||
if (runningExecutions.has(schedule.workflowId)) {
|
||||
@@ -276,7 +278,6 @@ export async function GET(req: NextRequest) {
|
||||
// Serialize and execute the workflow
|
||||
const serializedWorkflow = new Serializer().serializeWorkflow(mergedStates, edges, loops)
|
||||
const executor = new Executor(serializedWorkflow, currentBlockStates, decryptedEnvVars)
|
||||
const executionId = uuidv4()
|
||||
const result = await executor.execute(schedule.workflowId)
|
||||
|
||||
// Log each execution step
|
||||
@@ -351,11 +352,12 @@ export async function GET(req: NextRequest) {
|
||||
await persistLog({
|
||||
id: uuidv4(),
|
||||
workflowId: schedule.workflowId,
|
||||
executionId: uuidv4(),
|
||||
executionId,
|
||||
level: 'error',
|
||||
message: error.message || 'Unknown error during scheduled workflow execution',
|
||||
createdAt: new Date(),
|
||||
message: `Scheduled workflow execution failed: ${error.message || 'Unknown error'}`,
|
||||
duration: 'NA',
|
||||
trigger: 'schedule',
|
||||
createdAt: new Date(),
|
||||
})
|
||||
|
||||
// On error, increment next_run_at by a small delay to prevent immediate retries
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import { NextRequest } from 'next/server'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { persistLog } from '@/lib/logging'
|
||||
import { validateWorkflowAccess } from '../../middleware'
|
||||
import { createErrorResponse, createSuccessResponse } from '../../utils'
|
||||
|
||||
export const dynamic = 'force-dynamic'
|
||||
|
||||
export async function POST(request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
|
||||
const { id } = await params
|
||||
|
||||
try {
|
||||
const validation = await validateWorkflowAccess(request, id, false)
|
||||
if (validation.error) {
|
||||
return createErrorResponse(validation.error.message, validation.error.status)
|
||||
}
|
||||
|
||||
const body = await request.json()
|
||||
const { logs, executionId } = body
|
||||
|
||||
// Persist each log
|
||||
for (const log of logs) {
|
||||
await persistLog({
|
||||
id: uuidv4(),
|
||||
workflowId: id,
|
||||
executionId,
|
||||
level: log.level,
|
||||
message: log.message,
|
||||
duration: log.duration,
|
||||
trigger: 'manual',
|
||||
createdAt: new Date(log.createdAt || new Date()),
|
||||
})
|
||||
}
|
||||
|
||||
return createSuccessResponse({ message: 'Logs persisted successfully' })
|
||||
} catch (error: any) {
|
||||
console.error('Error persisting logs:', error)
|
||||
return createErrorResponse(error.message || 'Failed to persist logs', 500)
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useCallback, useState } from 'react'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { useConsoleStore } from '@/stores/console/store'
|
||||
import { useNotificationStore } from '@/stores/notifications/store'
|
||||
import { useEnvironmentStore } from '@/stores/settings/environment/store'
|
||||
@@ -19,6 +20,24 @@ export function useWorkflowExecution() {
|
||||
const { toggleConsole, isOpen } = useConsoleStore()
|
||||
const { getAllVariables } = useEnvironmentStore()
|
||||
|
||||
const persistLogs = async (logs: any[], executionId: string) => {
|
||||
try {
|
||||
const response = await fetch(`/api/workflow/${activeWorkflowId}/log`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ logs, executionId }),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to persist logs')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error persisting logs:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const handleRunWorkflow = useCallback(async () => {
|
||||
if (!activeWorkflowId) return
|
||||
setIsExecuting(true)
|
||||
@@ -28,6 +47,8 @@ export function useWorkflowExecution() {
|
||||
toggleConsole()
|
||||
}
|
||||
|
||||
const executionId = uuidv4()
|
||||
|
||||
try {
|
||||
// Use the mergeSubblockState utility to get all block states
|
||||
const mergedStates = mergeSubblockState(blocks)
|
||||
@@ -70,6 +91,34 @@ export function useWorkflowExecution() {
|
||||
const executor = new Executor(workflow, currentBlockStates, envVarValues)
|
||||
const result = await executor.execute(activeWorkflowId)
|
||||
|
||||
// Prepare logs for persistence
|
||||
const blockLogs = (result.logs || []).map((log) => ({
|
||||
level: log.success ? 'info' : 'error',
|
||||
message: `Block ${log.blockName || log.blockId} (${log.blockType}): ${
|
||||
log.error || 'Completed successfully'
|
||||
}`,
|
||||
duration: log.success ? `${log.durationMs}ms` : 'NA',
|
||||
createdAt: new Date(log.endedAt || log.startedAt).toISOString(),
|
||||
}))
|
||||
|
||||
// Calculate total duration from successful block logs
|
||||
const totalDuration = (result.logs || [])
|
||||
.filter((log) => log.success)
|
||||
.reduce((sum, log) => sum + log.durationMs, 0)
|
||||
|
||||
// Add final execution result log
|
||||
blockLogs.push({
|
||||
level: result.success ? 'info' : 'error',
|
||||
message: result.success
|
||||
? 'Manual workflow executed successfully'
|
||||
: `Manual workflow execution failed: ${result.error}`,
|
||||
duration: result.success ? `${totalDuration}ms` : 'NA',
|
||||
createdAt: new Date().toISOString(),
|
||||
})
|
||||
|
||||
// Persist all logs
|
||||
await persistLogs(blockLogs, executionId)
|
||||
|
||||
setExecutionResult(result)
|
||||
|
||||
// Show execution result notification
|
||||
@@ -90,6 +139,19 @@ export function useWorkflowExecution() {
|
||||
logs: [],
|
||||
})
|
||||
|
||||
// Persist error log
|
||||
await persistLogs(
|
||||
[
|
||||
{
|
||||
level: 'error',
|
||||
message: `Manual workflow execution failed: ${errorMessage}`,
|
||||
duration: 'NA',
|
||||
createdAt: new Date().toISOString(),
|
||||
},
|
||||
],
|
||||
executionId
|
||||
)
|
||||
|
||||
addNotification('error', `Workflow execution failed: ${errorMessage}`, activeWorkflowId)
|
||||
} finally {
|
||||
setIsExecuting(false)
|
||||
|
||||
Reference in New Issue
Block a user