import {Activity, RefreshCw, Timer, TriangleAlert} from 'lucide-react' import {useQuery} from '@tanstack/react-query' import {queryLogs} from '@/api/cloudProxyClient' import type {CloudProvider} from '@/types/cloud' interface LambdaInvocationHistoryPanelProps { cloud: CloudProvider functionName: string runtimeReachable: boolean } interface InvocationRecord { requestId: string timestamp: string durationMs: number errorType: string | null } const HISTORY_QUERY = 'fields @timestamp, @message\n| filter @message like /REPORT RequestId:/\n| sort @timestamp desc\n| limit 20' export function LambdaInvocationHistoryPanel({cloud, functionName, runtimeReachable}: LambdaInvocationHistoryPanelProps) { const history = useQuery({ queryKey: ['lambda-invocation-history', cloud, functionName], queryFn: async () => { const endTime = Math.floor(Date.now() / 1000) try { const result = await queryLogs(cloud, `/aws/lambda/${functionName}`, { queryString: HISTORY_QUERY, startTime: endTime - 24 * 60 * 60, endTime, }) return result.rows.map(toInvocationRecord).filter((record): record is InvocationRecord => record !== null) } catch (error) { if (isMissingLogGroup(error)) return [] throw error } }, enabled: cloud === 'aws' && runtimeReachable, }) const records = history.data ?? [] const errors = records.filter((record) => record.errorType !== null).length const averageDuration = records.length === 0 ? null : records.reduce((sum, record) => sum + record.durationMs, 0) / records.length return

Observability

Invocation history

Real Lambda platform records from the last 24 hours.

{averageDuration === null ? 'No duration' : `${averageDuration.toFixed(1)} ms`}Average duration
{errors}Function errors
{records.length}Recorded invocations
{history.isError &&

{history.error instanceof Error ? history.error.message : 'Unable to load invocation history.'}

} {!history.isLoading && records.length === 0 &&

No Lambda platform records yet. Invoke the function or trigger it from S3, then refresh.

} {records.length > 0 && {records.map((record) => )}
TimeRequest IDDurationOutcome
{record.timestamp}{record.requestId}{record.durationMs.toFixed(2)} ms{record.errorType ? {record.errorType} : 'Success'}
}
} function toInvocationRecord(row: Record): InvocationRecord | null { const message = row['@message'] ?? '' const match = /REPORT RequestId: (\S+) Duration: ([\d.]+) ms.*?(?: Error Type: (.+))?$/.exec(message) if (!match) return null return {requestId: match[1], timestamp: row['@timestamp'] ?? '', durationMs: Number(match[2]), errorType: match[3] ?? null} } function isMissingLogGroup(error: unknown): boolean { return error instanceof Error && /log group does not exist|resource_not_found/i.test(error.message) }