--- phase: 04-logs-intelligence plan: 01 type: execute wave: 1 depends_on: [] files_modified: [n8n-workflow.json] autonomous: true user_setup: - service: anthropic why: "Claude API for natural language understanding" env_vars: - name: ANTHROPIC_API_KEY source: "Anthropic Console -> API Keys -> Create Key" dashboard_config: [] must_haves: truths: - "User can request logs for a container by name" - "User can specify number of log lines (default 50)" - "Logs are returned in readable format in Telegram" artifacts: - path: "n8n-workflow.json" provides: "Logs command routing and Docker API integration" contains: "logs" key_links: - from: "Switch node" to: "Docker logs API call" via: "logs command pattern match" pattern: "logs|show logs" - from: "Docker API response" to: "Telegram reply" via: "log formatting code node" --- Implement container log retrieval via Telegram commands. Purpose: Delivers REQ-07 (view logs with configurable line count) - users can troubleshoot containers directly from their phone by viewing recent logs. Output: Extended n8n workflow with logs command routing, Docker logs API call, and formatted log response. @/home/luc/.claude/get-shit-done/workflows/execute-plan.md @/home/luc/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/04-logs-intelligence/04-RESEARCH.md @.planning/phases/02-docker-integration/02-02-SUMMARY.md @n8n-workflow.json Task 1: Add logs command routing to workflow n8n-workflow.json Extend the main Switch node to detect logs commands. Pattern: "logs " or "show logs " with optional line count. Add new route in Switch node: - Condition: message matches /^(show\s+)?logs\s+/i - Route to new "Parse Logs Command" Code node Create "Parse Logs Command" Code node: - Extract container name from message - Extract line count if specified (e.g., "logs plex 100"), default to 50 - Return: { container: string, lines: number } Example inputs to handle: - "logs plex" -> { container: "plex", lines: 50 } - "show logs sonarr" -> { container: "sonarr", lines: 50 } - "logs nginx 100" -> { container: "nginx", lines: 100 } - "show logs radarr last 200" -> { container: "radarr", lines: 200 } In n8n workflow editor, send message "logs test" - should route to Parse Logs Command node (visible in execution view). Check output includes container and lines fields. Logs commands route to dedicated branch with parsed container name and line count. Task 2: Implement Docker logs API call with formatting n8n-workflow.json After Parse Logs Command, add container matching (reuse existing fuzzy match pattern from actions branch). Create "Build Logs Command" Code node: - Input: matched container ID and requested line count - Build curl command: ``` curl -s --unix-socket /var/run/docker.sock "http://localhost/v1.53/containers/CONTAINER_ID/logs?stdout=1&stderr=1&tail=LINES×tamps=1" ``` - Note: Docker logs API returns binary stream with 8-byte header per line. First byte indicates stream (1=stdout, 2=stderr). Create "Execute Logs" Execute Command node: - Run the curl command Create "Format Logs" Code node: - Parse Docker log stream format (strip 8-byte headers from each line) - Format for Telegram: - Truncate if > 4000 chars (Telegram message limit) - Add header: "Logs for (last N lines):" - Use monospace formatting with
 tags (HTML parse mode already enabled)
- Handle empty logs gracefully: "No logs available for "
- Handle errors: "Could not retrieve logs for : "

Wire to Telegram Send Message node for reply.
  
  
Test via Telegram:
1. "logs n8n" - should return recent n8n container logs in monospace format
2. "logs n8n 10" - should return only 10 lines
3. "logs nonexistent" - should return friendly "no container found" message
  
  Users can retrieve container logs via Telegram with configurable line count, formatted for readability.



  Task 3: Handle Docker log stream binary format
  n8n-workflow.json
  
The Docker logs API returns a multiplexed stream with 8-byte headers. Each frame:
- Byte 0: stream type (1=stdout, 2=stderr)
- Bytes 1-3: reserved (zeros)
- Bytes 4-7: frame size (big-endian uint32)
- Remaining bytes: log content

Update "Format Logs" Code node to properly decode this:

```javascript
// Docker logs binary stream decoder
const rawOutput = $input.item.json.stdout || '';

// Docker API with timestamps returns text lines when using tail parameter
// But may have 8-byte binary headers we need to strip
const lines = rawOutput.split('\n')
  .filter(line => line.length > 0)
  .map(line => {
    // Check if line starts with binary header (non-printable chars in first 8 bytes)
    if (line.length > 8 && line.charCodeAt(0) <= 2) {
      return line.substring(8);
    }
    return line;
  })
  .join('\n');

// Truncate for Telegram (4096 char limit, leave room for header)
const maxLen = 3800;
const truncated = lines.length > maxLen
  ? lines.substring(0, maxLen) + '\n... (truncated)'
  : lines;

return {
  formatted: truncated,
  lineCount: lines.split('\n').length
};
```

Add error indicator prefix for stderr lines if desired (optional enhancement).
  
  
Test with a container known to have logs:
1. Send "logs n8n 20" via Telegram
2. Verify output is readable text (no garbled binary characters)
3. Verify timestamps appear if container outputs them
  
  Docker log binary stream format properly decoded into readable text.





After all tasks:
1. Send "logs n8n" - returns formatted logs
2. Send "logs plex 100" - returns up to 100 lines
3. Send "show logs sonarr" - alternative syntax works
4. Send "logs nonexistent" - friendly error message
5. Logs display in monospace (preformatted) in Telegram



- REQ-07 delivered: Users can view container logs with configurable line count
- Default 50 lines when not specified
- Multiple syntax variations supported (logs X, show logs X)
- Binary stream format properly decoded
- Output formatted for Telegram readability (monospace, truncated if needed)



After completion, create `.planning/phases/04-logs-intelligence/04-01-SUMMARY.md`