name: dev-log-monitoring description: This skill should be used when testing ScreenGraph end-to-end flows (drift detection, agent runs) while monitoring backend and frontend logs in real-time. Use when the user wants to observe system behavior across services, debug live runs, or verify event streaming.
Dev Log Monitoring
Overview
Monitor backend (Encore.ts) and frontend (SvelteKit) logs during ScreenGraph development and testing. This skill provides a systematic workflow for starting services, capturing logs, navigating the app with Playwright MCP, and analyzing the complete event flow after execution.
Workflow Decision Tree
Use this skill when:
- Testing drift detection end-to-end flow
- Debugging agent runs and observing state transitions
- Verifying WebSocket event streaming (run events + graph events)
- Analyzing performance metrics across services
- Troubleshooting backend/frontend integration issues
Do NOT use this skill when:
- Writing unit tests (use backend-testing skill)
- Debugging specific backend services (use backend-debugging skill)
- Writing E2E tests (use webapp-testing skill)
Step 1: Start Services with Log Capture
1.1 Start Backend with Logs
Start Encore backend and pipe logs to a temporary file for later analysis:
cd /path/to/ScreenGraph/backend && encore run 2>&1 | tee /tmp/backend-logs.txt &
Wait for backend health check:
sleep 8 && curl -s http://localhost:4000/health
Expected response:
{"status":"healthy","database":"connected","timestamp":"..."}
1.2 Start Frontend with Logs
Start SvelteKit frontend and pipe logs to a temporary file:
cd /path/to/ScreenGraph/frontend && bun run dev 2>&1 | tee /tmp/frontend-logs.txt &
Wait for frontend to be ready:
sleep 5 && curl -s http://localhost:5173 | head -n 1
Expected response:
<!doctype html>
1.3 Verify Services Are Running
Check both services are healthy:
# Backend
curl -s http://localhost:4000/health
# Frontend
curl -s http://localhost:5173 | head -n 1
Step 2: Navigate and Execute Flow with Playwright MCP
2.1 Navigate to Application
Use Playwright MCP to open the app:
mcp_playwright_browser_navigate(url: "http://localhost:5173")
2.2 Trigger Drift Detection
Click the "Detect My First Drift" button:
mcp_playwright_browser_click(
element: "Detect My First Drift button",
ref: [element_ref_from_snapshot]
)
Handle any alerts if backend wasn't ready:
mcp_playwright_browser_handle_dialog(accept: true)
2.3 Navigate to Run Page
The frontend should automatically redirect to /run/[runId]. If not:
mcp_playwright_browser_navigate(url: "http://localhost:5173/run/[runId]")
2.4 Verify Page State
Get current page snapshot to verify run page loaded:
mcp_playwright_browser_snapshot()
Look for:
- Run Timeline heading with runId
- Discovered Screens section
- Graph Events section
- Run Events timeline
2.5 Check Browser Console and Network
Monitor frontend activity:
mcp_playwright_browser_console_messages()
mcp_playwright_browser_network_requests()
Look for:
[Graph Stream] WebSocket opened[Graph Stream] Received event from stream- Screenshot fetch:
GET /artifacts/content?refId=obj://... - WebSocket upgrade status:
101(successful)
Step 3: Monitor Real-Time Logs
3.1 Check Backend Logs for Agent Flow
Grep for agent state machine activity:
tail -100 /tmp/backend-logs.txt | grep -E "(agent|graph|screenshot|drift)" -i
Key patterns to look for (see references/log_patterns.md for complete list):
Agent Nodes:
INF Node started actor=orchestrator nodeName=EnsureDeviceINF Node finished actor=orchestrator nodeName=EnsureDevice outcomeStatus=SUCCESSINF Node started actor=orchestrator nodeName=ProvisionAppINF Node started actor=orchestrator nodeName=LaunchOrAttachINF Node started actor=orchestrator nodeName=PerceiveINF Node started actor=orchestrator nodeName=WaitIdleINF Node started actor=orchestrator nodeName=Stop
Event Recording:
INF Event recorded: agent.run.started eventSeq=1INF Event recorded: agent.event.screenshot_capturedINF Event recorded: agent.event.screen_perceivedINF Event recorded: agent.run.finished
Graph Projection:
INF Projection batch processed projectedScreens=1INF Backfill complete runEventsCount=23 graphOutcomesCount=1
3.2 Check Frontend Logs
Grep for Vite and WebSocket activity:
tail -50 /tmp/frontend-logs.txt
Look for:
VITE v6.4.1 ready in [N] ms[vite] connected- No repeated connection errors
Step 4: Analyze Complete Flow After Run Completes
4.1 Extract Agent Flow Timeline
Get full agent execution timeline with timestamps:
grep -E "5:07PM" /tmp/backend-logs.txt | grep -E "(Node started|Node finished|Event recorded)" | head -50
4.2 Verify Event Sequence
Check all events were recorded in order:
grep "Event recorded:" /tmp/backend-logs.txt | grep "5:07PM"
Expected sequence:
agent.run.started(seq=1)agent.node.startedfor each node- Device/Appium health checks
agent.event.screenshot_capturedagent.event.ui_hierarchy_capturedagent.event.screen_perceivedgraph.screen.discovered(graph event)agent.run.finished(final)
4.3 Extract Run Metrics
Look for Stop node output with final metrics:
grep "Stop OUTPUT" /tmp/backend-logs.txt | grep "5:07PM"
Example output:
metrics={"runDurationInMilliseconds":5326,"totalIterationsExecuted":5,"uniqueActionsPersistedCount":0,"uniqueScreensDiscoveredCount":0}
4.4 Check Stream Backfill
Verify both streams delivered all events:
grep "Backfill complete" /tmp/backend-logs.txt | grep "5:07PM"
Expected:
- Run stream:
runEventsCount=23 - Graph stream:
graphOutcomesCount=1
4.5 Verify Screenshot Storage
Check artifacts were stored:
grep "screenshot" /tmp/backend-logs.txt | grep "5:07PM"
Look for artifact reference like:
obj://artifacts/[runId]/screenshot/[hash].png
Step 5: Generate Summary Report
5.1 Print Complete Flow Summary
Create a comprehensive summary with:
- Run Metadata: runId, app package, duration, status
- Agent State Machine Flow: All node transitions with timestamps
- Graph Projection: Screens discovered, hashes computed
- Streaming Architecture: Event counts, WebSocket status
- Frontend Activity: Console logs, network requests
- Metrics: Budget usage, counters, errors
Example summary structure:
═══════════════════════════════════════════════════════════════════
🎯 DRIFT DETECTION FLOW - COMPLETE LOG SUMMARY
═══════════════════════════════════════════════════════════════════
Run ID: [runId]
App: [package]
Duration: [duration]
Status: ✅ COMPLETED
─────────────────────────────────────────────────────────────────
📊 AGENT STATE MACHINE FLOW
─────────────────────────────────────────────────────────────────
Step 1: EnsureDevice ([start] → [end])
✅ Device check: [deviceId] online
✅ Appium health check: port 4723 healthy
Step 2: ProvisionApp ([start] → [end])
✅ App install check: [package] already installed
[... continue for all nodes ...]
─────────────────────────────────────────────────────────────────
🎨 GRAPH PROJECTION
─────────────────────────────────────────────────────────────────
✅ [N] screen(s) discovered
✅ Hashes: [hash1], [hash2], ...
✅ Screenshots stored
─────────────────────────────────────────────────────────────────
📡 STREAMING ARCHITECTURE
─────────────────────────────────────────────────────────────────
Run Events: [N] events backfilled
Graph Events: [N] events backfilled
WebSocket: ✅ Connected
─────────────────────────────────────────────────────────────────
🌐 FRONTEND ACTIVITY
─────────────────────────────────────────────────────────────────
Console Logs:
- [LOG] [Graph Stream] WebSocket opened
- [LOG] [Graph Stream] Received event: graph.screen.discovered
Network:
- Screenshot fetch: ✅ 200 OK
- WebSocket upgrade: ✅ 101
─────────────────────────────────────────────────────────────────
📈 METRICS
─────────────────────────────────────────────────────────────────
Steps: [N]
Screens: [N]
Errors: [N]
Duration: [N]ms
Step 6: Cleanup
6.1 Stop Services (Optional)
If needed to stop services:
# Kill backend
pkill -f "encore run"
# Kill frontend
pkill -f "vite"
6.2 Preserve Logs (Optional)
If logs need to be saved for later analysis:
# Copy logs to permanent location
cp /tmp/backend-logs.txt ./logs/backend-run-$(date +%Y%m%d-%H%M%S).txt
cp /tmp/frontend-logs.txt ./logs/frontend-run-$(date +%Y%m%d-%H%M%S).txt
Troubleshooting
Backend Not Responding
Symptom: Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:4000/
Fix:
# Check if encore is running
ps aux | grep "encore run"
# Restart if needed
cd backend && encore run 2>&1 | tee /tmp/backend-logs.txt &
sleep 8 && curl -s http://localhost:4000/health
Frontend Dev Server Crashed
Symptom: WebSocket connection to 'ws://localhost:5173/' failed
Fix:
# Kill existing processes
pkill -f "vite"
# Restart frontend
cd frontend && bun run dev 2>&1 | tee /tmp/frontend-logs.txt &
sleep 5
No Events in Stream
Symptom: Run page shows "0 events"
Check:
# Look for event recording in backend logs
grep "Event recorded:" /tmp/backend-logs.txt
# Check if run actually started
grep "agent.run.started" /tmp/backend-logs.txt
Graph Not Projecting Screens
Symptom: projectedScreens=0 in all projection logs
Check:
# Verify graph service is loaded
curl -s http://localhost:4000/graph/diagnostics
# Check if screen perceived event was emitted
grep "agent.event.screen_perceived" /tmp/backend-logs.txt
Resources
references/log_patterns.md
Complete reference of all log patterns, event types, and metrics to watch for across backend and frontend services. Load this when analyzing specific log patterns or troubleshooting issues.