12 KiB
12 KiB
Phase 0 Task 2: SDK Worker Comprehensive Logging
Summary
Added comprehensive logging to /Users/alexnewman/Scripts/claude-mem/src/sdk/worker.ts to trace the complete flow of the FINALIZE message from receipt through SDK agent processing to database storage.
Modified Files
/Users/alexnewman/Scripts/claude-mem/src/sdk/worker.ts- Added 20+ logging points throughout the worker lifecycle
Logging Points Added
All logs use the [claude-mem worker] prefix for easy searching and are sent to stderr using console.error().
1. Worker Initialization (Lines 70-73)
- Location:
constructor() - What: Logs when worker instance is created
- Data: sessionDbId, socketPath
2. Worker Run Started (Lines 80-83)
- Location:
run()method entry - What: Logs when main run loop begins
- Data: sessionDbId, socketPath
3. Session Loading (Lines 89-100)
- Location:
run()method afterloadSession() - What: Logs session load failure or success
- Data:
- Failure: sessionDbId
- Success: sessionDbId, project, sdkSessionId, userPromptLength
4. Socket Server Started (Lines 107-110)
- Location:
run()method afterstartSocketServer() - What: Logs successful socket server initialization
- Data: socketPath, sessionDbId
5. SDK Agent Starting (Lines 113-116)
- Location:
run()method beforerunSDKAgent() - What: Logs SDK agent invocation
- Data: sessionDbId, model
6. SDK Agent Completed (Lines 120-123)
- Location:
run()method afterrunSDKAgent()completes - What: Logs completion before marking session as done
- Data: sessionDbId, sdkSessionId
7. Fatal Error Handler (Lines 129-133)
- Location:
run()method catch block - What: Logs any fatal errors with full stack trace
- Data: sessionDbId, error message, stack trace
8. Socket Connection Received (Lines 157-160)
- Location:
startSocketServer()- connection handler - What: Logs when a client connects to the Unix socket
- Data: sessionDbId, socketPath
9. Data Received on Socket (Lines 164-167)
- Location:
startSocketServer()- data handler - What: Logs when data arrives on socket
- Data: sessionDbId, chunk size
10. Message Parsed from Socket (Lines 178-182)
- Location:
startSocketServer()- message parsing - What: Logs successfully parsed JSON message
- Data: sessionDbId, messageType, rawMessage (truncated to 500 chars)
11. Invalid Message Error (Lines 185-189)
- Location:
startSocketServer()- JSON parse error - What: Logs when message fails to parse
- Data: sessionDbId, error message, rawLine (truncated to 200 chars)
12. Socket Connection Error (Lines 196-200)
- Location:
startSocketServer()- socket error handler - What: Logs socket-level errors
- Data: sessionDbId, error message, stack trace
13. Server Errors (Lines 206-216)
- Location:
startSocketServer()- server error handler - What: Logs server-level errors (EADDRINUSE, etc.)
- Data: sessionDbId, socketPath (if EADDRINUSE), error details
14. Message Handler Entry (Lines 233-237)
- Location:
handleMessage()method entry - What: Logs when processing any message
- Data: sessionDbId, messageType, pendingMessagesCount
15. FINALIZE Message Detected (Lines 242-246)
- Location:
handleMessage()- finalize detection - What: Logs when FINALIZE message is received (CRITICAL LOG)
- Data: sessionDbId, isFinalized=true, pendingMessagesCount
16. Observation Message Queued (Lines 249-254)
- Location:
handleMessage()- observation handling - What: Logs observation message details
- Data: sessionDbId, toolName, input/output lengths
17. SDK Session Initialized (Lines 292-295)
- Location:
runSDKAgent()- onSystemInitMessage callback - What: Logs when SDK session ID is received
- Data: sessionDbId, sdkSessionId
18. SDK Agent Response Received (Lines 301-306)
- Location:
runSDKAgent()- onAgentMessage callback - What: Logs every response from SDK agent (CRITICAL LOG)
- Data: sessionDbId, sdkSessionId, contentLength, contentPreview (200 chars)
19. Initial Prompt Yielded (Lines 322-327)
- Location:
createMessageGenerator()- initial prompt - What: Logs when first prompt is sent to SDK agent
- Data: sessionDbId, claudeSessionId, project, promptLength
20. FINALIZE Processing in Generator (Lines 349-352)
- Location:
createMessageGenerator()- finalize handling - What: Logs when FINALIZE is processed in async generator (CRITICAL LOG)
- Data: sessionDbId, sdkSessionId
21. Finalize Prompt Yielded (Lines 357-362)
- Location:
createMessageGenerator()- after building finalize prompt - What: Logs finalize prompt being sent to SDK agent (CRITICAL LOG)
- Data: sessionDbId, sdkSessionId, promptLength, promptPreview (300 chars)
22. Failed to Load Session for Finalize (Lines 371-373)
- Location:
createMessageGenerator()- error case - What: Logs if session reload fails during finalize
- Data: sessionDbId
23. Observation Prompt Yielded (Lines 385-389)
- Location:
createMessageGenerator()- observation handling - What: Logs when observation prompt is sent to SDK agent
- Data: sessionDbId, toolName, promptLength
24. Parsing Agent Message (Lines 406-410)
- Location:
handleAgentMessage()method entry - What: Logs when starting to parse agent response
- Data: sessionDbId, sdkSessionId, contentLength
25. Observations Parsed (Lines 414-418)
- Location:
handleAgentMessage()- after parseObservations() - What: Logs how many observations were found
- Data: sessionDbId, sdkSessionId, observationCount
26. Storing Observation (Lines 422-428)
- Location:
handleAgentMessage()- in observation loop - What: Logs each observation being stored
- Data: sessionDbId, sdkSessionId, project, observationType, observationTextLength
27. Cannot Store Observation (Lines 431-434)
- Location:
handleAgentMessage()- error case - What: Logs when SDK session ID is missing
- Data: sessionDbId, observationType
28. Attempting to Parse Summary (Lines 439-442)
- Location:
handleAgentMessage()- before parseSummary() - What: Logs when attempting summary parse (CRITICAL LOG)
- Data: sessionDbId, sdkSessionId
29. Summary Parsed Successfully (Lines 446-456)
- Location:
handleAgentMessage()- after parseSummary() success - What: Logs summary structure details (CRITICAL LOG)
- Data: sessionDbId, sdkSessionId, project, hasRequest, hasInvestigated, hasLearned, hasCompleted, filesReadCount, filesEditedCount
30. Storing Summary in Database (Lines 470-474)
- Location:
handleAgentMessage()- before storeSummary() - What: Logs summary about to be stored (CRITICAL LOG)
- Data: sessionDbId, sdkSessionId, project
31. Summary Stored Successfully (Lines 478-482)
- Location:
handleAgentMessage()- after storeSummary() - What: Logs successful database storage (CRITICAL LOG)
- Data: sessionDbId, sdkSessionId, project
32. Summary Parsed but No SDK Session (Lines 484-486)
- Location:
handleAgentMessage()- error case - What: Logs when summary found but can't store
- Data: sessionDbId
33. No Summary Found (Lines 488-491)
- Location:
handleAgentMessage()- no summary case - What: Logs when response has no summary
- Data: sessionDbId, sdkSessionId
34. Cleanup Started (Lines 499-504)
- Location:
cleanup()method entry - What: Logs cleanup process beginning
- Data: sessionDbId, socketPath, hasServer, socketExists
35. Cleanup Complete (Lines 513-515)
- Location:
cleanup()method exit - What: Logs cleanup finished
- Data: sessionDbId
How to Test
1. Start the Worker
# Start a worker for session ID 1 (for example)
bun run src/sdk/worker.ts 1
Look for logs:
[claude-mem worker] Worker instance created[claude-mem worker] Worker run() started[claude-mem worker] Session loaded successfully[claude-mem worker] Socket server started successfully[claude-mem worker] Starting SDK agent
2. Send Messages via Socket
# From another terminal, send a message to the socket
# Socket path format: /tmp/claude-mem-worker-{sessionDbId}.sock
# Send an observation
echo '{"type":"observation","tool_name":"Read","tool_input":"...","tool_output":"..."}' | nc -U /tmp/claude-mem-worker-1.sock
# Send finalize
echo '{"type":"finalize"}' | nc -U /tmp/claude-mem-worker-1.sock
3. Monitor Logs
Use grep to filter for specific events:
# All worker logs
bun run src/sdk/worker.ts 1 2>&1 | grep '\[claude-mem worker\]'
# Only FINALIZE-related logs
bun run src/sdk/worker.ts 1 2>&1 | grep -i finalize
# Only summary-related logs
bun run src/sdk/worker.ts 1 2>&1 | grep -i summary
# Only database storage logs
bun run src/sdk/worker.ts 1 2>&1 | grep -i storing
What to Look for When FINALIZE is Sent
The expected log sequence when a FINALIZE message is sent:
-
Message Receipt:
[claude-mem worker] Data received on socket [claude-mem worker] Message received from socket { messageType: 'finalize', ... } -
Message Handling:
[claude-mem worker] Processing message in handleMessage() { messageType: 'finalize', ... } [claude-mem worker] FINALIZE message detected { isFinalized: true, ... } -
Generator Processing:
[claude-mem worker] Processing FINALIZE message in generator [claude-mem worker] Yielding finalize prompt to SDK agent { promptLength: ..., promptPreview: ... } -
SDK Agent Response:
[claude-mem worker] SDK agent response received { contentLength: ..., contentPreview: ... } -
Parsing and Storage:
[claude-mem worker] Parsing agent message for observations and summary [claude-mem worker] Observations parsed from response { observationCount: ... } [claude-mem worker] Attempting to parse summary from response [claude-mem worker] Summary parsed successfully { hasRequest: true, hasLearned: true, ... } [claude-mem worker] Storing summary in database [claude-mem worker] Summary stored successfully in database -
Completion:
[claude-mem worker] SDK agent completed, marking session as completed [claude-mem worker] Cleaning up worker resources [claude-mem worker] Cleanup complete
Issues and Concerns
1. Large Response Truncation
- Raw messages are truncated to 500 chars in socket logs
- Content previews are limited to 200-300 chars
- This prevents log spam but might make debugging harder if the critical info is beyond the truncation point
2. Async Generator Timing
- The generator waits in a loop (
while (!this.isFinalized)) with 100ms sleeps - Logs show when messages are queued but not when the generator processes them
- There could be a small delay between "FINALIZE message detected" and "Processing FINALIZE in generator"
3. Error Cases Not Fully Logged
- Parser errors in
parseObservations()andparseSummary()are not logged - Should consider adding try-catch in
handleAgentMessage()to catch parser exceptions - XML parsing errors would be silent
4. No Timing Information
- Logs don't include timestamps (relies on stderr default timestamps)
- Could add
Date.now()or elapsed time to measure performance bottlenecks
5. Socket Path Permissions
- No logging for socket file permissions or creation errors
- If socket can't be created due to permissions, error might not be clear
6. Multi-Message Batching
- If multiple messages arrive rapidly, they're processed in a batch
- Logs show individual messages but don't indicate batch boundaries
- Could add batch ID or sequence numbers
Recommendations for Next Steps
- Test the logging by running the worker and sending various messages
- Add parser error handling in
handleAgentMessage()to catch XML parse failures - Consider adding timing metrics to measure latency at each stage
- Validate socket connectivity early in startup (try writing a test message)
- Add structured logging library if JSON logs would be easier to parse programmatically
Related Files
/Users/alexnewman/Scripts/claude-mem/src/sdk/prompts.ts- Prompt builders used in logged operations/Users/alexnewman/Scripts/claude-mem/src/sdk/parser.ts- XML parsers for observations and summaries/Users/alexnewman/Scripts/claude-mem/src/services/sqlite/HooksDatabase.js- Database methods being called/Users/alexnewman/Scripts/claude-mem/src/shared/paths.js- Socket path generation