Skip to content

Commit 9efc08a

Browse files
authored
fix(telemetry): updated telemetry, added nested sanitization, added granular trace spans for logs and updated UI (#1627)
* feat(logs): updated telemetry, added nested sanitization, added granular trace spans for logs and updated UI * refactor trace spans into separate components * remove any's from tool defs * updated UI and overlayed spans * cleanup * ack PR comments * stricter type safety * clean
1 parent f345c4d commit 9efc08a

File tree

39 files changed

+2577
-1523
lines changed

39 files changed

+2577
-1523
lines changed

apps/sim/app/api/knowledge/[id]/documents/route.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,20 @@ export async function POST(req: NextRequest, { params }: { params: Promise<{ id:
186186
`[${requestId}] Starting controlled async processing of ${createdDocuments.length} documents`
187187
)
188188

189+
// Track bulk document upload
190+
try {
191+
const { trackPlatformEvent } = await import('@/lib/telemetry/tracer')
192+
trackPlatformEvent('platform.knowledge_base.documents_uploaded', {
193+
'knowledge_base.id': knowledgeBaseId,
194+
'documents.count': createdDocuments.length,
195+
'documents.upload_type': 'bulk',
196+
'processing.chunk_size': validatedData.processingOptions.chunkSize,
197+
'processing.recipe': validatedData.processingOptions.recipe,
198+
})
199+
} catch (_e) {
200+
// Silently fail
201+
}
202+
189203
processDocumentsWithQueue(
190204
createdDocuments,
191205
knowledgeBaseId,
@@ -231,6 +245,20 @@ export async function POST(req: NextRequest, { params }: { params: Promise<{ id:
231245

232246
const newDocument = await createSingleDocument(validatedData, knowledgeBaseId, requestId)
233247

248+
// Track single document upload
249+
try {
250+
const { trackPlatformEvent } = await import('@/lib/telemetry/tracer')
251+
trackPlatformEvent('platform.knowledge_base.documents_uploaded', {
252+
'knowledge_base.id': knowledgeBaseId,
253+
'documents.count': 1,
254+
'documents.upload_type': 'single',
255+
'document.mime_type': validatedData.mimeType,
256+
'document.file_size': validatedData.fileSize,
257+
})
258+
} catch (_e) {
259+
// Silently fail
260+
}
261+
234262
return NextResponse.json({
235263
success: true,
236264
data: newDocument,

apps/sim/app/api/knowledge/search/route.test.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -214,10 +214,6 @@ describe('Knowledge Search API Route', () => {
214214
const response = await POST(req)
215215
const data = await response.json()
216216

217-
if (response.status !== 200) {
218-
console.log('Test failed with response:', data)
219-
}
220-
221217
expect(response.status).toBe(200)
222218
expect(data.success).toBe(true)
223219
expect(data.data.results).toHaveLength(2)
@@ -723,10 +719,6 @@ describe('Knowledge Search API Route', () => {
723719
const response = await POST(req)
724720
const data = await response.json()
725721

726-
if (response.status !== 200) {
727-
console.log('Tag-only search test error:', data)
728-
}
729-
730722
expect(response.status).toBe(200)
731723
expect(data.success).toBe(true)
732724
expect(data.data.results).toHaveLength(2)
@@ -783,10 +775,6 @@ describe('Knowledge Search API Route', () => {
783775
const response = await POST(req)
784776
const data = await response.json()
785777

786-
if (response.status !== 200) {
787-
console.log('Query+tag combination test error:', data)
788-
}
789-
790778
expect(response.status).toBe(200)
791779
expect(data.success).toBe(true)
792780
expect(data.data.results).toHaveLength(2)

apps/sim/app/api/mcp/servers/route.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,20 @@ export const POST = withMcpAuth('write')(
106106
mcpService.clearCache(workspaceId)
107107

108108
logger.info(`[${requestId}] Successfully registered MCP server: ${body.name}`)
109+
110+
// Track MCP server registration
111+
try {
112+
const { trackPlatformEvent } = await import('@/lib/telemetry/tracer')
113+
trackPlatformEvent('platform.mcp.server_added', {
114+
'mcp.server_id': serverId,
115+
'mcp.server_name': body.name,
116+
'mcp.transport': body.transport,
117+
'workspace.id': workspaceId,
118+
})
119+
} catch (_e) {
120+
// Silently fail
121+
}
122+
109123
return createMcpSuccessResponse({ serverId }, 201)
110124
} catch (error) {
111125
logger.error(`[${requestId}] Error registering MCP server:`, error)

apps/sim/app/api/mcp/tools/execute/route.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,20 @@ export const POST = withMcpAuth('read')(
174174
)
175175
}
176176
logger.info(`[${requestId}] Successfully executed tool ${toolName} on server ${serverId}`)
177+
178+
// Track MCP tool execution
179+
try {
180+
const { trackPlatformEvent } = await import('@/lib/telemetry/tracer')
181+
trackPlatformEvent('platform.mcp.tool_executed', {
182+
'mcp.server_id': serverId,
183+
'mcp.tool_name': toolName,
184+
'mcp.execution_status': 'success',
185+
'workspace.id': workspaceId,
186+
})
187+
} catch (_e) {
188+
// Silently fail
189+
}
190+
177191
return createMcpSuccessResponse(transformedResult)
178192
} catch (error) {
179193
logger.error(`[${requestId}] Error executing MCP tool:`, error)

apps/sim/app/api/schedules/route.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,19 @@ export async function POST(req: NextRequest) {
366366
cronExpression,
367367
})
368368

369+
// Track schedule creation/update
370+
try {
371+
const { trackPlatformEvent } = await import('@/lib/telemetry/tracer')
372+
trackPlatformEvent('platform.schedule.created', {
373+
'workflow.id': workflowId,
374+
'schedule.type': scheduleType || 'daily',
375+
'schedule.timezone': timezone,
376+
'schedule.is_custom': scheduleType === 'custom',
377+
})
378+
} catch (_e) {
379+
// Silently fail
380+
}
381+
369382
return NextResponse.json({
370383
message: 'Schedule updated',
371384
nextRunAt,

apps/sim/app/api/telemetry/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const ALLOWED_CATEGORIES = [
1212
'error',
1313
'workflow',
1414
'consent',
15+
'batch',
1516
]
1617

1718
const DEFAULT_TIMEOUT = 5000 // 5 seconds timeout
@@ -132,7 +133,6 @@ async function forwardToCollector(data: any): Promise<boolean> {
132133
],
133134
}
134135

135-
// Create explicit AbortController for timeout
136136
const controller = new AbortController()
137137
const timeoutId = setTimeout(() => controller.abort(), timeout)
138138

apps/sim/app/api/templates/[id]/use/route.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,23 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
174174
`[${requestId}] Successfully used template: ${id}, created workflow: ${newWorkflowId}, database returned: ${result.id}`
175175
)
176176

177+
// Track template usage
178+
try {
179+
const { trackPlatformEvent } = await import('@/lib/telemetry/tracer')
180+
const templateState = templateData.state as any
181+
trackPlatformEvent('platform.template.used', {
182+
'template.id': id,
183+
'template.name': templateData.name,
184+
'workflow.created_id': newWorkflowId,
185+
'workflow.blocks_count': templateState?.blocks
186+
? Object.keys(templateState.blocks).length
187+
: 0,
188+
'workspace.id': workspaceId,
189+
})
190+
} catch (_e) {
191+
// Silently fail
192+
}
193+
177194
// Verify the workflow was actually created
178195
const verifyWorkflow = await db
179196
.select({ id: workflow.id })

apps/sim/app/api/workflows/[id]/deploy/route.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,31 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
353353

354354
logger.info(`[${requestId}] Workflow deployed successfully: ${id}`)
355355

356+
// Track workflow deployment
357+
try {
358+
const { trackPlatformEvent } = await import('@/lib/telemetry/tracer')
359+
360+
// Aggregate block types to understand which blocks are being used
361+
const blockTypeCounts: Record<string, number> = {}
362+
for (const block of Object.values(currentState.blocks)) {
363+
const blockType = (block as any).type || 'unknown'
364+
blockTypeCounts[blockType] = (blockTypeCounts[blockType] || 0) + 1
365+
}
366+
367+
trackPlatformEvent('platform.workflow.deployed', {
368+
'workflow.id': id,
369+
'workflow.name': workflowData!.name,
370+
'workflow.blocks_count': Object.keys(currentState.blocks).length,
371+
'workflow.edges_count': currentState.edges.length,
372+
'workflow.has_loops': Object.keys(currentState.loops).length > 0,
373+
'workflow.has_parallels': Object.keys(currentState.parallels).length > 0,
374+
'workflow.api_key_type': keyInfo?.type || 'default',
375+
'workflow.block_types': JSON.stringify(blockTypeCounts),
376+
})
377+
} catch (_e) {
378+
// Silently fail
379+
}
380+
356381
const responseApiKeyInfo = keyInfo ? `${keyInfo.name} (${keyInfo.type})` : 'Default key'
357382

358383
return createSuccessResponse({
@@ -400,6 +425,17 @@ export async function DELETE(
400425
})
401426

402427
logger.info(`[${requestId}] Workflow undeployed successfully: ${id}`)
428+
429+
// Track workflow undeployment
430+
try {
431+
const { trackPlatformEvent } = await import('@/lib/telemetry/tracer')
432+
trackPlatformEvent('platform.workflow.undeployed', {
433+
'workflow.id': id,
434+
})
435+
} catch (_e) {
436+
// Silently fail
437+
}
438+
403439
return createSuccessResponse({
404440
isDeployed: false,
405441
deployedAt: null,

apps/sim/app/api/workflows/[id]/log/route.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,20 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
4444
variables: {},
4545
})
4646

47-
const { traceSpans } = buildTraceSpans(result)
47+
const { traceSpans, totalDuration } = buildTraceSpans(result)
4848

4949
if (result.success === false) {
5050
const message = result.error || 'Workflow execution failed'
5151
await loggingSession.safeCompleteWithError({
5252
endedAt: new Date().toISOString(),
53-
totalDurationMs: result.metadata?.duration || 0,
53+
totalDurationMs: totalDuration || result.metadata?.duration || 0,
5454
error: { message },
5555
traceSpans,
5656
})
5757
} else {
5858
await loggingSession.safeComplete({
5959
endedAt: new Date().toISOString(),
60-
totalDurationMs: result.metadata?.duration || 0,
60+
totalDurationMs: totalDuration || result.metadata?.duration || 0,
6161
finalOutput: result.output || {},
6262
traceSpans,
6363
})

apps/sim/app/api/workflows/route.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,19 @@ export async function POST(req: NextRequest) {
9999

100100
logger.info(`[${requestId}] Creating workflow ${workflowId} for user ${session.user.id}`)
101101

102+
// Track workflow creation
103+
try {
104+
const { trackPlatformEvent } = await import('@/lib/telemetry/tracer')
105+
trackPlatformEvent('platform.workflow.created', {
106+
'workflow.id': workflowId,
107+
'workflow.name': name,
108+
'workflow.has_workspace': !!workspaceId,
109+
'workflow.has_folder': !!folderId,
110+
})
111+
} catch (_e) {
112+
// Silently fail
113+
}
114+
102115
await db.insert(workflow).values({
103116
id: workflowId,
104117
userId: session.user.id,

0 commit comments

Comments
 (0)