claude-flow-novice 2.14.36 → 2.14.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/commands/cfn-loop-cli.md +491 -456
- package/.claude/skills/cfn-redis-coordination/invoke-waiting-mode.sh +220 -220
- package/claude-assets/agents/custom/claude-code-expert.md +151 -2
- package/claude-assets/agents/docker-coordinators/cfn-docker-v3-coordinator.md +43 -3
- package/claude-assets/commands/cfn-loop-cli.md +491 -456
- package/claude-assets/skills/cfn-error-logging/SKILL.md +339 -0
- package/claude-assets/skills/cfn-error-logging/cleanup-error-logs.sh +334 -0
- package/claude-assets/skills/cfn-error-logging/integrate-cli.sh +232 -0
- package/claude-assets/skills/cfn-error-logging/integrate-docker.sh +294 -0
- package/claude-assets/skills/cfn-error-logging/invoke-error-logging.sh +839 -0
- package/claude-assets/skills/cfn-error-logging/test-error-logging.sh +475 -0
- package/claude-assets/skills/cfn-process-instrumentation/instrument-process.sh +5 -3
- package/claude-assets/skills/cfn-redis-coordination/invoke-waiting-mode.sh +220 -220
- package/claude-assets/skills/cfn-task-mode-sanitize/task-mode-env-sanitizer.sh +21 -9
- package/claude-assets/skills/cfn-validation-runner-instrumentation/wrapped-executor.sh +3 -1
- package/dist/hello.js +27 -3
- package/dist/hello.js.map +1 -1
- package/dist/server.js +194 -0
- package/dist/server.js.map +1 -0
- package/dist/server.test.js +207 -0
- package/dist/server.test.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,839 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
##############################################################################
|
|
4
|
+
# CFN Error Logging Skill - Main Invocation Script
|
|
5
|
+
# Version: 1.0.0
|
|
6
|
+
#
|
|
7
|
+
# Comprehensive error logging and diagnostic capture for CFN Loop failures
|
|
8
|
+
# Creates detailed error reports that users can send for debugging
|
|
9
|
+
#
|
|
10
|
+
# Usage:
|
|
11
|
+
# invoke-error-logging.sh --action <capture|report|cleanup|list> \
|
|
12
|
+
# --task-id <unique-id> \
|
|
13
|
+
# [--error-type <type>] \
|
|
14
|
+
# [--error-message <message>] \
|
|
15
|
+
# [--exit-code <number>] \
|
|
16
|
+
# [--context <json>]
|
|
17
|
+
##############################################################################
|
|
18
|
+
|
|
19
|
+
set -euo pipefail
|
|
20
|
+
|
|
21
|
+
# Determine script directory
|
|
22
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
23
|
+
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
24
|
+
|
|
25
|
+
# Configuration
|
|
26
|
+
LOG_BASE_DIR="/tmp/cfn_error_logs"
|
|
27
|
+
RETENTION_DAYS="${CFN_ERROR_LOG_RETENTION:-7}"
|
|
28
|
+
MAX_LOG_SIZE_MB="${CFN_ERROR_LOG_MAX_SIZE_MB:-100}"
|
|
29
|
+
|
|
30
|
+
# Initialize variables
|
|
31
|
+
ACTION=""
|
|
32
|
+
TASK_ID=""
|
|
33
|
+
ERROR_TYPE=""
|
|
34
|
+
ERROR_MESSAGE=""
|
|
35
|
+
EXIT_CODE=""
|
|
36
|
+
CONTEXT_JSON=""
|
|
37
|
+
FORMAT="markdown"
|
|
38
|
+
SINCE_TIME=""
|
|
39
|
+
|
|
40
|
+
# Helper functions
|
|
41
|
+
log() {
|
|
42
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >&2
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
show_usage() {
|
|
46
|
+
cat << EOF
|
|
47
|
+
CFN Error Logging Skill v1.0.0
|
|
48
|
+
|
|
49
|
+
Usage: $0 --action <action> --task-id <id> [options]
|
|
50
|
+
|
|
51
|
+
ACTIONS:
|
|
52
|
+
capture Capture error data and diagnostics
|
|
53
|
+
report Generate user-friendly error report
|
|
54
|
+
cleanup Clean up old error logs
|
|
55
|
+
list List error logs
|
|
56
|
+
diagnostics Run system diagnostics
|
|
57
|
+
validate Validate dependencies
|
|
58
|
+
|
|
59
|
+
REQUIRED:
|
|
60
|
+
--action <action> Action to perform
|
|
61
|
+
|
|
62
|
+
OPTIONAL:
|
|
63
|
+
--task-id <id> CFN Loop task identifier (required for capture, report, list)
|
|
64
|
+
|
|
65
|
+
OPTIONS:
|
|
66
|
+
--error-type <type> Type of error (orchestrator, agent-spawn, timeout, etc.)
|
|
67
|
+
--error-message <msg> Human-readable error description
|
|
68
|
+
--exit-code <code> Process exit code
|
|
69
|
+
--context <json> Additional context data
|
|
70
|
+
--format <format> Report format (markdown|json)
|
|
71
|
+
--since <time> List errors since time (e.g., "24h", "7d")
|
|
72
|
+
--retention-days <n> Cleanup retention period (default: 7)
|
|
73
|
+
|
|
74
|
+
EXAMPLES:
|
|
75
|
+
# Capture error on CFN Loop failure
|
|
76
|
+
$0 --action capture --task-id "cfn-cli-1731234567" --error-type "orchestrator" --error-message "Agent spawning failed" --exit-code 1
|
|
77
|
+
|
|
78
|
+
# Generate user report
|
|
79
|
+
$0 --action report --task-id "cfn-cli-1731234567" --format markdown
|
|
80
|
+
|
|
81
|
+
# List recent errors
|
|
82
|
+
$0 --action list --since "24h" --format table
|
|
83
|
+
|
|
84
|
+
# Clean old logs
|
|
85
|
+
$0 --action cleanup --retention-days 7
|
|
86
|
+
EOF
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
validate_parameters() {
|
|
90
|
+
if [ -z "$ACTION" ]; then
|
|
91
|
+
echo "❌ Error: Missing required action parameter"
|
|
92
|
+
echo "Use --help for usage information"
|
|
93
|
+
exit 1
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
# Task ID is required for most actions but optional for diagnostics, validate, cleanup, and list
|
|
97
|
+
case "$ACTION" in
|
|
98
|
+
diagnostics|validate|cleanup|list)
|
|
99
|
+
# Task ID optional for these actions
|
|
100
|
+
;;
|
|
101
|
+
*)
|
|
102
|
+
if [ -z "$TASK_ID" ]; then
|
|
103
|
+
echo "❌ Error: Missing required task-id parameter for action '$ACTION'"
|
|
104
|
+
echo "Use --help for usage information"
|
|
105
|
+
exit 1
|
|
106
|
+
fi
|
|
107
|
+
;;
|
|
108
|
+
esac
|
|
109
|
+
|
|
110
|
+
# Validate action
|
|
111
|
+
case "$ACTION" in
|
|
112
|
+
capture|report|cleanup|list|diagnostics|validate)
|
|
113
|
+
;;
|
|
114
|
+
*)
|
|
115
|
+
echo "❌ Error: Invalid action '$ACTION'"
|
|
116
|
+
echo "Valid actions: capture, report, cleanup, list, diagnostics, validate"
|
|
117
|
+
exit 1
|
|
118
|
+
;;
|
|
119
|
+
esac
|
|
120
|
+
|
|
121
|
+
# Validate task ID format (only if task ID is provided)
|
|
122
|
+
if [ -n "$TASK_ID" ] && [[ ! "$TASK_ID" =~ ^[a-zA-Z0-9_-]+$ ]]; then
|
|
123
|
+
echo "❌ Error: Invalid task ID format"
|
|
124
|
+
echo "Task ID should contain only letters, numbers, hyphens, and underscores"
|
|
125
|
+
exit 1
|
|
126
|
+
fi
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
setup_directories() {
|
|
130
|
+
# Create log directory structure
|
|
131
|
+
mkdir -p "$LOG_BASE_DIR"
|
|
132
|
+
mkdir -p "$LOG_BASE_DIR/reports"
|
|
133
|
+
mkdir -p "$LOG_BASE_DIR/compressed"
|
|
134
|
+
|
|
135
|
+
# Set permissions
|
|
136
|
+
chmod 755 "$LOG_BASE_DIR"
|
|
137
|
+
chmod 755 "$LOG_BASE_DIR/reports"
|
|
138
|
+
chmod 755 "$LOG_BASE_DIR/compressed"
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
collect_system_diagnostics() {
|
|
142
|
+
local diagnostics_file="$1"
|
|
143
|
+
|
|
144
|
+
log "Collecting system diagnostics..."
|
|
145
|
+
|
|
146
|
+
# System information
|
|
147
|
+
{
|
|
148
|
+
echo "{"
|
|
149
|
+
echo " \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\","
|
|
150
|
+
echo " \"hostname\": \"$(hostname 2>/dev/null || echo 'unknown')\","
|
|
151
|
+
echo " \"user\": \"$(whoami 2>/dev/null || echo 'unknown')\","
|
|
152
|
+
echo " \"working_directory\": \"$(pwd)\","
|
|
153
|
+
echo " \"os\": \"$(uname -s 2>/dev/null || echo 'unknown')\","
|
|
154
|
+
echo " \"os_version\": \"$(uname -r 2>/dev/null || echo 'unknown')\","
|
|
155
|
+
echo " \"architecture\": \"$(uname -m 2>/dev/null || echo 'unknown')\","
|
|
156
|
+
|
|
157
|
+
# Hardware information
|
|
158
|
+
echo " \"hardware\": {"
|
|
159
|
+
echo " \"cpu_cores\": $(nproc 2>/dev/null || echo 'unknown'),"
|
|
160
|
+
|
|
161
|
+
if command -v free >/dev/null 2>&1; then
|
|
162
|
+
local mem_info=$(free -h 2>/dev/null || echo "Memory: Unknown")
|
|
163
|
+
echo " \"memory\": \"$mem_info\""
|
|
164
|
+
else
|
|
165
|
+
echo " \"memory\": \"Memory information unavailable\""
|
|
166
|
+
fi
|
|
167
|
+
|
|
168
|
+
if command -v df >/dev/null 2>&1; then
|
|
169
|
+
local disk_info=$(df -h / 2>/dev/null | tail -1 || echo "Disk: Unknown")
|
|
170
|
+
echo " \"disk\": \"$disk_info\""
|
|
171
|
+
else
|
|
172
|
+
echo " \"disk\": \"Disk information unavailable\""
|
|
173
|
+
fi
|
|
174
|
+
|
|
175
|
+
echo " },"
|
|
176
|
+
|
|
177
|
+
# Software information
|
|
178
|
+
echo " \"software\": {"
|
|
179
|
+
|
|
180
|
+
if command -v node >/dev/null 2>&1; then
|
|
181
|
+
echo " \"node_version\": \"$(node --version 2>/dev/null || echo 'unknown')\","
|
|
182
|
+
else
|
|
183
|
+
echo " \"node_version\": \"not found\""
|
|
184
|
+
fi
|
|
185
|
+
|
|
186
|
+
if command -v npx >/dev/null 2>&1; then
|
|
187
|
+
echo " \"npx_version\": \"$(npx --version 2>/dev/null || echo 'unknown')\","
|
|
188
|
+
else
|
|
189
|
+
echo " \"npx_version\": \"not found\""
|
|
190
|
+
fi
|
|
191
|
+
|
|
192
|
+
if command -v docker >/dev/null 2>&1; then
|
|
193
|
+
echo " \"docker_version\": \"$(docker --version 2>/dev/null || echo 'unknown')\","
|
|
194
|
+
else
|
|
195
|
+
echo " \"docker_version\": \"not found\""
|
|
196
|
+
fi
|
|
197
|
+
|
|
198
|
+
if command -v redis-cli >/dev/null 2>&1; then
|
|
199
|
+
echo " \"redis_available\": true"
|
|
200
|
+
if redis-cli ping >/dev/null 2>&1; then
|
|
201
|
+
echo " \"redis_connected\": true"
|
|
202
|
+
echo " \"redis_info\": \"$(redis-cli info server 2>/dev/null | head -5 | tr '\n' ' ' || echo '')\""
|
|
203
|
+
else
|
|
204
|
+
echo " \"redis_connected\": false"
|
|
205
|
+
fi
|
|
206
|
+
else
|
|
207
|
+
echo " \"redis_available\": false"
|
|
208
|
+
echo " "redis_connected": false"
|
|
209
|
+
fi
|
|
210
|
+
|
|
211
|
+
echo " },"
|
|
212
|
+
|
|
213
|
+
# Environment
|
|
214
|
+
echo " \"environment\": {"
|
|
215
|
+
echo " \"path\": \"${PATH:-not set}\","
|
|
216
|
+
echo " \"home\": \"${HOME:-not set}\","
|
|
217
|
+
echo " \"shell\": \"${SHELL:-not set}\","
|
|
218
|
+
echo " \"lang\": \"${LANG:-not set}\""
|
|
219
|
+
echo " },"
|
|
220
|
+
|
|
221
|
+
# Processes
|
|
222
|
+
if command -v pgrep >/dev/null 2>&1; then
|
|
223
|
+
local cfn_processes=$(pgrep -f "claude-flow-novice\|cfn-" 2>/dev/null | wc -l || echo "0")
|
|
224
|
+
echo " \"processes\": {"
|
|
225
|
+
echo " \"cfn_running\": $cfn_processes,"
|
|
226
|
+
echo " \"total_processes\": $(ps aux 2>/dev/null | wc -l || echo 'unknown')"
|
|
227
|
+
echo " }"
|
|
228
|
+
else
|
|
229
|
+
echo " \"processes\": {"
|
|
230
|
+
echo " \"cfn_running\": \"unknown\","
|
|
231
|
+
echo " \"total_processes\": \"unknown\""
|
|
232
|
+
echo " }"
|
|
233
|
+
fi
|
|
234
|
+
|
|
235
|
+
echo "}"
|
|
236
|
+
} > "$diagnostics_file"
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
collect_cfn_state() {
|
|
240
|
+
local state_file="$1"
|
|
241
|
+
|
|
242
|
+
log "Collecting CFN Loop state..."
|
|
243
|
+
|
|
244
|
+
{
|
|
245
|
+
echo "{"
|
|
246
|
+
echo " \"task_id\": \"$TASK_ID\","
|
|
247
|
+
echo " \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\","
|
|
248
|
+
echo " \"error_type\": \"$ERROR_TYPE\","
|
|
249
|
+
echo " \"error_message\": \"$ERROR_MESSAGE\","
|
|
250
|
+
echo " \"exit_code\": ${EXIT_CODE:-null},"
|
|
251
|
+
|
|
252
|
+
# Redis state
|
|
253
|
+
if command -v redis-cli >/dev/null 2>&1 && redis-cli ping >/dev/null 2>&1; then
|
|
254
|
+
echo " \"redis_state\": {"
|
|
255
|
+
echo " \"connected\": true,"
|
|
256
|
+
|
|
257
|
+
# Task context
|
|
258
|
+
local task_context=$(redis-cli HGETALL "cfn_loop:task:$TASK_ID:context" 2>/dev/null || echo "")
|
|
259
|
+
if [ -n "$task_context" ]; then
|
|
260
|
+
echo " \"task_context\": {"
|
|
261
|
+
echo "$task_context" | sed 's/^/ "/' | sed 's/" "/", "/g' | sed 's/$/"/'
|
|
262
|
+
echo " },"
|
|
263
|
+
else
|
|
264
|
+
echo " \"task_context\": null,"
|
|
265
|
+
fi
|
|
266
|
+
|
|
267
|
+
# Agent PIDs
|
|
268
|
+
local agent_pids=$(redis-cli KEYS "cfn_loop:task:$TASK_ID:agent:*:pid" 2>/dev/null | wc -l || echo "0")
|
|
269
|
+
echo " \"tracked_agents\": $agent_pids,"
|
|
270
|
+
|
|
271
|
+
# Recent signals
|
|
272
|
+
local recent_signals=$(redis-cli LRANGE "swarm:$TASK_ID:*:done" 0 9 2>/dev/null | wc -l || echo "0")
|
|
273
|
+
echo " \"recent_signals\": $recent_signals"
|
|
274
|
+
echo " },"
|
|
275
|
+
else
|
|
276
|
+
echo " \"redis_state\": {"
|
|
277
|
+
echo " \"connected\": false,"
|
|
278
|
+
echo " \"reason\": \"Redis not available or not connected\""
|
|
279
|
+
echo " },"
|
|
280
|
+
fi
|
|
281
|
+
|
|
282
|
+
# Checkpoint state
|
|
283
|
+
local checkpoint_file="/tmp/cfn_loop_${TASK_ID}_checkpoint.json"
|
|
284
|
+
if [ -f "$checkpoint_file" ]; then
|
|
285
|
+
echo " \"checkpoint\": {"
|
|
286
|
+
echo " \"available\": true,"
|
|
287
|
+
echo " \"last_iteration\": $(jq -r '.iteration' "$checkpoint_file" 2>/dev/null || echo 'unknown'),"
|
|
288
|
+
echo " \"mode\": \"$(jq -r '.mode' "$checkpoint_file" 2>/dev/null || echo 'unknown')\","
|
|
289
|
+
echo " \"timestamp\": $(jq -r '.timestamp' "$checkpoint_file" 2>/dev/null || echo 'unknown')"
|
|
290
|
+
echo " },"
|
|
291
|
+
else
|
|
292
|
+
echo " \"checkpoint\": {"
|
|
293
|
+
echo " \"available\": false"
|
|
294
|
+
echo " },"
|
|
295
|
+
fi
|
|
296
|
+
|
|
297
|
+
# Temporary files
|
|
298
|
+
local temp_dir="/tmp/cfn_loop_${TASK_ID}"
|
|
299
|
+
if [ -d "$temp_dir" ]; then
|
|
300
|
+
local temp_files=$(find "$temp_dir" -type f 2>/dev/null | wc -l || echo "0")
|
|
301
|
+
echo " \"temp_files\": {"
|
|
302
|
+
echo " \"directory\": \"$temp_dir\","
|
|
303
|
+
echo " \"file_count\": $temp_files"
|
|
304
|
+
echo " },"
|
|
305
|
+
else
|
|
306
|
+
echo " \"temp_files\": null,"
|
|
307
|
+
fi
|
|
308
|
+
|
|
309
|
+
# Context JSON
|
|
310
|
+
if [ -n "$CONTEXT_JSON" ]; then
|
|
311
|
+
echo " \"context\": $CONTEXT_JSON"
|
|
312
|
+
fi
|
|
313
|
+
|
|
314
|
+
echo "}"
|
|
315
|
+
} > "$state_file"
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
capture_error() {
|
|
319
|
+
local timestamp=$(date +%s)
|
|
320
|
+
local error_log_file="$LOG_BASE_DIR/cfn-error-${TASK_ID}-${timestamp}.json"
|
|
321
|
+
|
|
322
|
+
log "Capturing error data for task: $TASK_ID"
|
|
323
|
+
|
|
324
|
+
setup_directories
|
|
325
|
+
|
|
326
|
+
# Create comprehensive error log
|
|
327
|
+
{
|
|
328
|
+
echo "{"
|
|
329
|
+
echo " \"capture_id\": \"error-${TASK_ID}-${timestamp}\","
|
|
330
|
+
echo " \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\","
|
|
331
|
+
echo " \"unix_timestamp\": $timestamp,"
|
|
332
|
+
|
|
333
|
+
# Error details
|
|
334
|
+
echo " \"error\": {"
|
|
335
|
+
echo " \"type\": \"$ERROR_TYPE\","
|
|
336
|
+
echo " \"message\": \"$ERROR_MESSAGE\","
|
|
337
|
+
echo " \"exit_code\": ${EXIT_CODE:-null},"
|
|
338
|
+
echo " \"task_id\": \"$TASK_ID\""
|
|
339
|
+
echo " },"
|
|
340
|
+
|
|
341
|
+
# Include system diagnostics and CFN state
|
|
342
|
+
echo " \"system_diagnostics\": $(cat "${LOG_BASE_DIR}/sys-diagnostics-${timestamp}.json"),"
|
|
343
|
+
echo " \"cfn_state\": $(cat "${LOG_BASE_DIR}/cfn-state-${TASK_ID}-${timestamp}.json")"
|
|
344
|
+
|
|
345
|
+
echo "}"
|
|
346
|
+
} > "$error_log_file"
|
|
347
|
+
|
|
348
|
+
# Clean up temporary diagnostic files
|
|
349
|
+
rm -f "${LOG_BASE_DIR}/sys-diagnostics-${timestamp}.json" 2>/dev/null || true
|
|
350
|
+
rm -f "${LOG_BASE_DIR}/cfn-state-${TASK_ID}-${timestamp}.json" 2>/dev/null || true
|
|
351
|
+
|
|
352
|
+
log "Error data captured: $error_log_file"
|
|
353
|
+
log "Generate report with: $0 --action report --task-id $TASK_ID"
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
generate_report() {
|
|
357
|
+
local timestamp=$(date +%s)
|
|
358
|
+
local file_ext="md"
|
|
359
|
+
|
|
360
|
+
if [ "$FORMAT" = "json" ]; then
|
|
361
|
+
file_ext="json"
|
|
362
|
+
fi
|
|
363
|
+
|
|
364
|
+
local report_file="$LOG_BASE_DIR/reports/cfn-report-${TASK_ID}-${timestamp}.${file_ext}"
|
|
365
|
+
|
|
366
|
+
# Find the most recent error log for this task
|
|
367
|
+
local error_log=$(find "$LOG_BASE_DIR" -name "cfn-error-${TASK_ID}-*.json" -type f -printf '%T@ %p\n' 2>/dev/null | sort -n | tail -1 | cut -d' ' -f2- || echo "")
|
|
368
|
+
|
|
369
|
+
if [ -z "$error_log" ] || [ ! -f "$error_log" ]; then
|
|
370
|
+
echo "❌ No error log found for task: $TASK_ID"
|
|
371
|
+
echo "Available tasks:"
|
|
372
|
+
find "$LOG_BASE_DIR" -name "cfn-error-*.json" -type f -exec basename {} \; 2>/dev/null | sort -u | sed 's/cfn-error-//g' | sed 's/-[0-9]*\.json$//' | head -10
|
|
373
|
+
return 1
|
|
374
|
+
fi
|
|
375
|
+
|
|
376
|
+
log "Generating error report for task: $TASK_ID"
|
|
377
|
+
|
|
378
|
+
# Parse error log data
|
|
379
|
+
local error_type=$(jq -r '.error.type' "$error_log" 2>/dev/null || echo "unknown")
|
|
380
|
+
local error_message=$(jq -r '.error.message' "$error_log" 2>/dev/null || echo "No message")
|
|
381
|
+
local exit_code=$(jq -r '.error.exit_code' "$error_log" 2>/dev/null || echo "unknown")
|
|
382
|
+
local error_timestamp=$(jq -r '.timestamp' "$error_log" 2>/dev/null || echo "unknown")
|
|
383
|
+
|
|
384
|
+
# System diagnostics
|
|
385
|
+
local redis_available=$(jq -r '.system_diagnostics.software.redis_connected' "$error_log" 2>/dev/null || echo "false")
|
|
386
|
+
local node_version=$(jq -r '.system_diagnostics.software.node_version' "$error_log" 2>/dev/null || echo "not found")
|
|
387
|
+
local npx_version=$(jq -r '.system_diagnostics.software.npx_version' "$error_log" 2>/dev/null || echo "not found")
|
|
388
|
+
|
|
389
|
+
# Generate troubleshooting steps
|
|
390
|
+
local troubleshooting_steps=""
|
|
391
|
+
case "$error_type" in
|
|
392
|
+
"orchestrator")
|
|
393
|
+
troubleshooting_steps="1. ✅ Check task configuration parameters\n2. ✅ Verify orchestrator script permissions\n3. ❌ Check system resources (memory/disk)\n4. ✅ Validate agent availability"
|
|
394
|
+
;;
|
|
395
|
+
"agent-spawn")
|
|
396
|
+
troubleshooting_steps="1. ✅ Check Node.js installation: node --version\n2. ✅ Check npx availability: npx --version\n3. ❌ Check Redis connection: redis-cli ping\n4. ✅ Check available memory: free -h"
|
|
397
|
+
;;
|
|
398
|
+
"timeout")
|
|
399
|
+
troubleshooting_steps="1. ✅ Check system load: top\n2. ✅ Verify network connectivity\n3. ❌ Increase timeout values if needed\n4. ✅ Check for stuck processes"
|
|
400
|
+
;;
|
|
401
|
+
"resource")
|
|
402
|
+
troubleshooting_steps="1. ✅ Check available memory: free -h\n2. ✅ Check disk space: df -h\n3. ❌ Close unnecessary applications\n4. ✅ Check process limits: ulimit -a"
|
|
403
|
+
;;
|
|
404
|
+
*)
|
|
405
|
+
troubleshooting_steps="1. ✅ Check system diagnostics below\n2. ✅ Review error message context\n3. ❌ Check CFN Loop configuration\n4. ✅ Verify all dependencies"
|
|
406
|
+
;;
|
|
407
|
+
esac
|
|
408
|
+
|
|
409
|
+
# Generate report
|
|
410
|
+
cat > "$report_file" << EOF
|
|
411
|
+
# CFN Loop Error Report
|
|
412
|
+
|
|
413
|
+
## 🚨 Error Summary
|
|
414
|
+
- **Task ID**: $TASK_ID
|
|
415
|
+
- **Error Type**: $error_type
|
|
416
|
+
- **Message**: $error_message
|
|
417
|
+
- **Timestamp**: $error_timestamp
|
|
418
|
+
- **Exit Code**: $exit_code
|
|
419
|
+
|
|
420
|
+
## 📋 Quick Diagnosis
|
|
421
|
+
**Most Likely Cause**: Based on error type $error_type
|
|
422
|
+
**Recommended Action**: Follow troubleshooting steps below
|
|
423
|
+
|
|
424
|
+
## 🔧 Troubleshooting Steps
|
|
425
|
+
$troubleshooting_steps
|
|
426
|
+
|
|
427
|
+
## 📊 System State
|
|
428
|
+
|
|
429
|
+
### Software Dependencies
|
|
430
|
+
- **Node.js**: $node_version
|
|
431
|
+
- **npx**: $npx_version
|
|
432
|
+
- **Redis**: $(if [ "$redis_available" = "true" ]; then echo "✅ Connected"; else echo "❌ Not Connected"; fi)
|
|
433
|
+
- **Docker**: $(if command -v docker >/dev/null 2>&1; then docker --version | head -1; else echo "Not installed"; fi)
|
|
434
|
+
|
|
435
|
+
### System Resources
|
|
436
|
+
$(jq -r '.system_diagnostics.hardware.memory' "$error_log" 2>/dev/null || echo "Memory information unavailable")
|
|
437
|
+
$(jq -r '.system_diagnostics.hardware.disk' "$error_log" 2>/dev/null || echo "Disk information unavailable")
|
|
438
|
+
|
|
439
|
+
### Process Status
|
|
440
|
+
- **CFN Processes Running**: $(jq -r '.system_diagnostics.processes.cfn_running' "$error_log" 2>/dev/null || echo "Unknown")
|
|
441
|
+
- **Total Processes**: $(jq -r '.system_diagnostics.processes.total_processes' "$error_log" 2>/dev/null || echo "Unknown")
|
|
442
|
+
|
|
443
|
+
## 📝 Send This Report
|
|
444
|
+
**To**: Your Claude assistant
|
|
445
|
+
**Include**:
|
|
446
|
+
- Complete error details above
|
|
447
|
+
- Any recent changes to your setup
|
|
448
|
+
- Steps you were trying to perform
|
|
449
|
+
- Command you executed
|
|
450
|
+
|
|
451
|
+
## 📁 Log Files
|
|
452
|
+
- **Error Log**: $(basename "$error_log")
|
|
453
|
+
- **Log Location**: $LOG_BASE_DIR
|
|
454
|
+
- **Generated**: $(date)
|
|
455
|
+
|
|
456
|
+
## 🔍 Additional Information
|
|
457
|
+
|
|
458
|
+
### CFN Loop State
|
|
459
|
+
$(if [ -f "/tmp/cfn_loop_${TASK_ID}_checkpoint.json" ]; then
|
|
460
|
+
echo "- **Last Checkpoint**: $(jq -r '.iteration' "/tmp/cfn_loop_${TASK_ID}_checkpoint.json" 2>/dev/null || echo "Unknown")"
|
|
461
|
+
echo "- **Mode**: $(jq -r '.mode' "/tmp/cfn_loop_${TASK_ID}_checkpoint.json" 2>/dev/null || echo "Unknown")"
|
|
462
|
+
else
|
|
463
|
+
echo "- **No checkpoint available**"
|
|
464
|
+
fi)
|
|
465
|
+
|
|
466
|
+
### Temporary Files
|
|
467
|
+
$(if [ -d "/tmp/cfn_loop_${TASK_ID}" ]; then
|
|
468
|
+
local temp_count=$(find "/tmp/cfn_loop_${TASK_ID}" -type f 2>/dev/null | wc -l || echo "0")
|
|
469
|
+
echo "- **Temp Files**: $temp_count files"
|
|
470
|
+
else
|
|
471
|
+
echo "- **No temporary files**"
|
|
472
|
+
fi)
|
|
473
|
+
EOF
|
|
474
|
+
|
|
475
|
+
log "Error report generated: $report_file"
|
|
476
|
+
echo ""
|
|
477
|
+
echo "📋 Error report saved to: $report_file"
|
|
478
|
+
echo "📤 Send this file to your Claude assistant for debugging help"
|
|
479
|
+
echo ""
|
|
480
|
+
echo "💡 Quick copy command:"
|
|
481
|
+
echo " cat $report_file | pbcopy # macOS"
|
|
482
|
+
echo " cat $report_file | xclip -selection clipboard # Linux"
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
list_error_logs() {
|
|
486
|
+
local query="$1"
|
|
487
|
+
|
|
488
|
+
log "Listing error logs..."
|
|
489
|
+
|
|
490
|
+
case "$FORMAT" in
|
|
491
|
+
"table")
|
|
492
|
+
echo "Available Error Logs:"
|
|
493
|
+
printf "%-20s %-12s %-20s %-30s\n" "Task ID" "Type" "Timestamp" "Error Message"
|
|
494
|
+
printf "%-20s %-12s %-20s %-30s\n" "--------------------" "------------" "--------------------" "------------------------------"
|
|
495
|
+
|
|
496
|
+
find "$LOG_BASE_DIR" -name "cfn-error-*.json" -type f -printf '%T@ %p\n' 2>/dev/null | sort -n | while read -r timestamp file; do
|
|
497
|
+
local task_id=$(basename "$file" | sed 's/cfn-error-//' | sed 's/-[0-9]*\.json$//')
|
|
498
|
+
local error_type=$(jq -r '.error.type' "$file" 2>/dev/null || echo "unknown")
|
|
499
|
+
local error_message=$(jq -r '.error.message' "$file" 2>/dev/null | head -c 30)
|
|
500
|
+
local file_timestamp=$(date -d "@$timestamp" "+%Y-%m-%d %H:%M" 2>/dev/null || echo "unknown")
|
|
501
|
+
|
|
502
|
+
printf "%-20s %-12s %-20s %-30s\n" "$task_id" "$error_type" "$file_timestamp" "$error_message"
|
|
503
|
+
done
|
|
504
|
+
;;
|
|
505
|
+
"json")
|
|
506
|
+
find "$LOG_BASE_DIR" -name "cfn-error-*.json" -type f -exec basename {} \; 2>/dev/null | sort -u | sed 's/cfn-error-//g' | sed 's/-[0-9]*\.json$//' | jq -R '{
|
|
507
|
+
"task_id": .,
|
|
508
|
+
"logs": [
|
|
509
|
+
(input | split("\n")[] | select(length > 0) | . as $task_id |
|
|
510
|
+
"cfn-error-\($task_id)-*.json" |
|
|
511
|
+
[
|
|
512
|
+
inputs | select(test("cfn-error-\($task_id)-"; .)) |
|
|
513
|
+
{
|
|
514
|
+
"file": .,
|
|
515
|
+
"timestamp": (inputs | test(.; test("cfn-error-\($task_id)-"; .)) | input_filename | split("-") | .[2] | split("\\.") | .[0] | tonumber) | strftime("%Y-%m-%d %H:%M:%S")
|
|
516
|
+
}
|
|
517
|
+
]
|
|
518
|
+
)
|
|
519
|
+
]
|
|
520
|
+
}' | while read -r line; do
|
|
521
|
+
if [ -n "$query" ] && [[ "$line" =~ "$query" ]]; then
|
|
522
|
+
echo "$line"
|
|
523
|
+
elif [ -z "$query" ]; then
|
|
524
|
+
echo "$line"
|
|
525
|
+
fi
|
|
526
|
+
done
|
|
527
|
+
;;
|
|
528
|
+
*)
|
|
529
|
+
echo "Available error logs:"
|
|
530
|
+
find "$LOG_BASE_DIR" -name "cfn-error-*.json" -type f -exec basename {} \; 2>/dev/null | sort -u | sed 's/cfn-error-//g' | sed 's/-[0-9]*\.json$//'
|
|
531
|
+
;;
|
|
532
|
+
esac
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
cleanup_logs() {
|
|
536
|
+
local retention_secs=$((RETENTION_DAYS * 24 * 3600))
|
|
537
|
+
local current_time=$(date +%s)
|
|
538
|
+
local cutoff_time=$((current_time - retention_secs))
|
|
539
|
+
|
|
540
|
+
log "Cleaning up error logs older than $RETENTION_DAYS days..."
|
|
541
|
+
|
|
542
|
+
local cleaned_count=0
|
|
543
|
+
local compressed_count=0
|
|
544
|
+
|
|
545
|
+
# Compress old logs
|
|
546
|
+
while IFS= read -r -d '' file; do
|
|
547
|
+
local file_time=$(date -r "$file" +%s 2>/dev/null || echo "0")
|
|
548
|
+
if [ "$file_time" -lt "$cutoff_time" ]; then
|
|
549
|
+
if gzip "$file" 2>/dev/null; then
|
|
550
|
+
mv "$file.gz" "$LOG_BASE_DIR/compressed/"
|
|
551
|
+
((compressed_count++))
|
|
552
|
+
fi
|
|
553
|
+
fi
|
|
554
|
+
done < <(find "$LOG_BASE_DIR" -name "cfn-error-*.json" -type f -print0 2>/dev/null)
|
|
555
|
+
|
|
556
|
+
# Remove very old compressed logs (30 days)
|
|
557
|
+
local old_cutoff=$((current_time - (30 * 24 * 3600)))
|
|
558
|
+
while IFS= read -r -d '' file; do
|
|
559
|
+
local file_time=$(date -r "$file" +%s 2>/dev/null || echo "0")
|
|
560
|
+
if [ "$file_time" -lt "$old_cutoff" ]; then
|
|
561
|
+
rm -f "$file"
|
|
562
|
+
((cleaned_count++))
|
|
563
|
+
fi
|
|
564
|
+
done < <(find "$LOG_BASE_DIR/compressed" -name "*.json.gz" -type f -print0 2>/dev/null)
|
|
565
|
+
|
|
566
|
+
# Check total size and enforce limit
|
|
567
|
+
local total_size=$(du -sm "$LOG_BASE_DIR" 2>/dev/null | cut -f1 || echo "0")
|
|
568
|
+
if [ "$total_size" -gt "$MAX_LOG_SIZE_MB" ]; then
|
|
569
|
+
log "Log directory size (${total_size}MB) exceeds limit (${MAX_LOG_SIZE_MB}MB)"
|
|
570
|
+
# Remove oldest files until under limit
|
|
571
|
+
while [ "$total_size" -gt "$MAX_LOG_SIZE_MB" ]; do
|
|
572
|
+
local oldest_file=$(find "$LOG_BASE_DIR" -name "*.json*" -type f -printf '%T@ %p\n' 2>/dev/null | sort -n | head -1 | cut -d' ' -f2-)
|
|
573
|
+
if [ -n "$oldest_file" ] && [ -f "$oldest_file" ]; then
|
|
574
|
+
rm -f "$oldest_file"
|
|
575
|
+
total_size=$(du -sm "$LOG_BASE_DIR" 2>/dev/null | cut -f1 || echo "0")
|
|
576
|
+
fi
|
|
577
|
+
done
|
|
578
|
+
fi
|
|
579
|
+
|
|
580
|
+
log "Cleanup completed: $compressed_count files compressed, $cleaned_count files removed"
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
run_diagnostics() {
|
|
584
|
+
log "Running system diagnostics..."
|
|
585
|
+
|
|
586
|
+
echo "=== CFN Loop System Diagnostics ==="
|
|
587
|
+
echo ""
|
|
588
|
+
|
|
589
|
+
# Basic system info
|
|
590
|
+
echo "🖥️ System Information:"
|
|
591
|
+
echo " Hostname: $(hostname 2>/dev/null || echo 'unknown')"
|
|
592
|
+
echo " User: $(whoami 2>/dev/null || echo 'unknown')"
|
|
593
|
+
echo " Shell: $SHELL"
|
|
594
|
+
echo " Working Directory: $(pwd)"
|
|
595
|
+
echo ""
|
|
596
|
+
|
|
597
|
+
# Dependency checks
|
|
598
|
+
echo "📦 Dependency Status:"
|
|
599
|
+
|
|
600
|
+
local deps_status=0
|
|
601
|
+
|
|
602
|
+
if command -v node >/dev/null 2>&1; then
|
|
603
|
+
echo " ✅ Node.js: $(node --version)"
|
|
604
|
+
else
|
|
605
|
+
echo " ❌ Node.js: NOT FOUND"
|
|
606
|
+
((deps_status++))
|
|
607
|
+
fi
|
|
608
|
+
|
|
609
|
+
if command -v npx >/dev/null 2>&1; then
|
|
610
|
+
echo " ✅ npx: $(npx --version)"
|
|
611
|
+
else
|
|
612
|
+
echo " ❌ npx: NOT FOUND"
|
|
613
|
+
((deps_status++))
|
|
614
|
+
fi
|
|
615
|
+
|
|
616
|
+
if command -v docker >/dev/null 2>&1; then
|
|
617
|
+
echo " ✅ Docker: $(docker --version | head -1)"
|
|
618
|
+
else
|
|
619
|
+
echo " ⚠️ Docker: NOT FOUND (optional)"
|
|
620
|
+
fi
|
|
621
|
+
|
|
622
|
+
if command -v redis-cli >/dev/null 2>&1; then
|
|
623
|
+
echo " ✅ Redis CLI: Available"
|
|
624
|
+
if redis-cli ping >/dev/null 2>&1; then
|
|
625
|
+
echo " ✅ Redis Server: CONNECTED"
|
|
626
|
+
else
|
|
627
|
+
echo " ❌ Redis Server: NOT CONNECTED"
|
|
628
|
+
((deps_status++))
|
|
629
|
+
fi
|
|
630
|
+
else
|
|
631
|
+
echo " ❌ Redis CLI: NOT FOUND"
|
|
632
|
+
((deps_status++))
|
|
633
|
+
fi
|
|
634
|
+
|
|
635
|
+
echo ""
|
|
636
|
+
|
|
637
|
+
# Resource status
|
|
638
|
+
echo "💻 Resource Status:"
|
|
639
|
+
|
|
640
|
+
if command -v free >/dev/null 2>&1; then
|
|
641
|
+
echo " Memory: $(free -h | grep '^Mem:' | awk '{print $3 "/" $2 " (" $4 ")"}')"
|
|
642
|
+
echo " Swap: $(free -h | grep '^Swap:' | awk '{print $3 "/" $2 " (" $4 ")"}' || echo 'Swap not available')"
|
|
643
|
+
else
|
|
644
|
+
echo " Memory: Information unavailable"
|
|
645
|
+
fi
|
|
646
|
+
|
|
647
|
+
if command -v df >/dev/null 2>&1; then
|
|
648
|
+
echo " Disk: $(df -h / | tail -1 | awk '{print $3 "/" $2 " (" $4 ")"}')"
|
|
649
|
+
else
|
|
650
|
+
echo " Disk: Information unavailable"
|
|
651
|
+
fi
|
|
652
|
+
|
|
653
|
+
echo ""
|
|
654
|
+
|
|
655
|
+
# CFN Loop specific
|
|
656
|
+
echo "🔄 CFN Loop Status:"
|
|
657
|
+
|
|
658
|
+
local cfn_processes=$(pgrep -f "claude-flow-novice\|cfn-" 2>/dev/null | wc -l || echo "0")
|
|
659
|
+
echo " CFN Processes Running: $cfn_processes"
|
|
660
|
+
|
|
661
|
+
if [ -d "/tmp" ]; then
|
|
662
|
+
local cfn_temp_dirs=$(find /tmp -name "cfn_loop_*" -type d 2>/dev/null | wc -l || echo "0")
|
|
663
|
+
echo " Temporary Directories: $cfn_temp_dirs"
|
|
664
|
+
fi
|
|
665
|
+
|
|
666
|
+
echo ""
|
|
667
|
+
|
|
668
|
+
# Error log status
|
|
669
|
+
if [ -d "$LOG_BASE_DIR" ]; then
|
|
670
|
+
local error_count=$(find "$LOG_BASE_DIR" -name "cfn-error-*.json" -type f 2>/dev/null | wc -l || echo "0")
|
|
671
|
+
local report_count=$(find "$LOG_BASE_DIR/reports" -name "*.md" -type f 2>/dev/null | wc -l || echo "0")
|
|
672
|
+
echo "📊 Error Log Status:"
|
|
673
|
+
echo " Error Logs: $error_count"
|
|
674
|
+
echo " Reports Generated: $report_count"
|
|
675
|
+
echo " Log Directory: $LOG_BASE_DIR"
|
|
676
|
+
echo " Total Size: $(du -sh "$LOG_BASE_DIR" 2>/dev/null | cut -f1 || echo 'unknown')"
|
|
677
|
+
else
|
|
678
|
+
echo "📊 Error Log Status: Directory not found"
|
|
679
|
+
fi
|
|
680
|
+
|
|
681
|
+
echo ""
|
|
682
|
+
|
|
683
|
+
# Overall status
|
|
684
|
+
if [ "$deps_status" -eq 0 ]; then
|
|
685
|
+
echo "✅ Overall Status: HEALTHY"
|
|
686
|
+
else
|
|
687
|
+
echo "⚠️ Overall Status: ISSUES DETECTED ($deps_status problems)"
|
|
688
|
+
fi
|
|
689
|
+
|
|
690
|
+
echo ""
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
validate_dependencies() {
|
|
694
|
+
log "Validating CFN Loop dependencies..."
|
|
695
|
+
|
|
696
|
+
local validation_status=0
|
|
697
|
+
local missing_deps=()
|
|
698
|
+
|
|
699
|
+
# Check required dependencies
|
|
700
|
+
local required_deps=("node" "npx" "jq" "bc")
|
|
701
|
+
for dep in "${required_deps[@]}"; do
|
|
702
|
+
if ! command -v "$dep" >/dev/null 2>&1; then
|
|
703
|
+
missing_deps+=("$dep")
|
|
704
|
+
((validation_status++))
|
|
705
|
+
fi
|
|
706
|
+
done
|
|
707
|
+
|
|
708
|
+
if [ ${#missing_deps[@]} -gt 0 ]; then
|
|
709
|
+
echo "❌ Missing Dependencies:"
|
|
710
|
+
for dep in "${missing_deps[@]}"; do
|
|
711
|
+
echo " - $dep"
|
|
712
|
+
done
|
|
713
|
+
echo ""
|
|
714
|
+
echo "💡 Installation Commands:"
|
|
715
|
+
if [[ " ${missing_deps[*]}" =~ "node" ]] || [[ " ${missing_deps[*]}" =~ "npx" ]]; then
|
|
716
|
+
echo " # Install Node.js and npx:"
|
|
717
|
+
echo " curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -"
|
|
718
|
+
echo " sudo apt-get install -y nodejs npm"
|
|
719
|
+
echo " sudo npm install -g npx"
|
|
720
|
+
fi
|
|
721
|
+
if [[ " ${missing_deps[*]}" =~ "jq" ]]; then
|
|
722
|
+
echo " # Install jq:"
|
|
723
|
+
echo " sudo apt-get install -y jq"
|
|
724
|
+
fi
|
|
725
|
+
if [[ " ${missing_deps[*]}" =~ "bc" ]]; then
|
|
726
|
+
echo " # Install bc:"
|
|
727
|
+
echo " sudo apt-get install -y bc"
|
|
728
|
+
fi
|
|
729
|
+
else
|
|
730
|
+
echo "✅ All required dependencies are available"
|
|
731
|
+
fi
|
|
732
|
+
|
|
733
|
+
echo ""
|
|
734
|
+
|
|
735
|
+
# Check optional dependencies
|
|
736
|
+
echo "🔍 Optional Dependencies:"
|
|
737
|
+
|
|
738
|
+
local optional_deps=("redis-cli" "docker")
|
|
739
|
+
for dep in "${optional_deps[@]}"; do
|
|
740
|
+
if command -v "$dep" >/dev/null 2>&1; then
|
|
741
|
+
case "$dep" in
|
|
742
|
+
"redis-cli")
|
|
743
|
+
if redis-cli ping >/dev/null 2>&1; then
|
|
744
|
+
echo " ✅ Redis Server: Running"
|
|
745
|
+
else
|
|
746
|
+
echo " ⚠️ Redis CLI: Available, Server Not Connected"
|
|
747
|
+
fi
|
|
748
|
+
;;
|
|
749
|
+
"docker")
|
|
750
|
+
echo " ✅ Docker: $(docker --version | head -1)"
|
|
751
|
+
;;
|
|
752
|
+
esac
|
|
753
|
+
else
|
|
754
|
+
echo " ⚪ $dep: Not Available (optional)"
|
|
755
|
+
fi
|
|
756
|
+
done
|
|
757
|
+
|
|
758
|
+
return $validation_status
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
# Parse arguments
|
|
762
|
+
while [[ $# -gt 0 ]]; do
|
|
763
|
+
case $1 in
|
|
764
|
+
--action)
|
|
765
|
+
ACTION="$2"
|
|
766
|
+
shift 2
|
|
767
|
+
;;
|
|
768
|
+
--task-id)
|
|
769
|
+
TASK_ID="$2"
|
|
770
|
+
shift 2
|
|
771
|
+
;;
|
|
772
|
+
--error-type)
|
|
773
|
+
ERROR_TYPE="$2"
|
|
774
|
+
shift 2
|
|
775
|
+
;;
|
|
776
|
+
--error-message)
|
|
777
|
+
ERROR_MESSAGE="$2"
|
|
778
|
+
shift 2
|
|
779
|
+
;;
|
|
780
|
+
--exit-code)
|
|
781
|
+
EXIT_CODE="$2"
|
|
782
|
+
shift 2
|
|
783
|
+
;;
|
|
784
|
+
--context)
|
|
785
|
+
CONTEXT_JSON="$2"
|
|
786
|
+
shift 2
|
|
787
|
+
;;
|
|
788
|
+
--format)
|
|
789
|
+
FORMAT="$2"
|
|
790
|
+
shift 2
|
|
791
|
+
;;
|
|
792
|
+
--since)
|
|
793
|
+
SINCE_TIME="$2"
|
|
794
|
+
shift 2
|
|
795
|
+
;;
|
|
796
|
+
--retention-days)
|
|
797
|
+
RETENTION_DAYS="$2"
|
|
798
|
+
shift 2
|
|
799
|
+
;;
|
|
800
|
+
--help|-h)
|
|
801
|
+
show_usage
|
|
802
|
+
exit 0
|
|
803
|
+
;;
|
|
804
|
+
*)
|
|
805
|
+
echo "Unknown option: $1"
|
|
806
|
+
show_usage
|
|
807
|
+
exit 1
|
|
808
|
+
;;
|
|
809
|
+
esac
|
|
810
|
+
done
|
|
811
|
+
|
|
812
|
+
# Validate parameters
|
|
813
|
+
validate_parameters
|
|
814
|
+
|
|
815
|
+
# Execute action
|
|
816
|
+
case "$ACTION" in
|
|
817
|
+
capture)
|
|
818
|
+
collect_system_diagnostics "${LOG_BASE_DIR}/sys-diagnostics-$(date +%s).json"
|
|
819
|
+
collect_cfn_state "${LOG_BASE_DIR}/cfn-state-${TASK_ID}-$(date +%s).json"
|
|
820
|
+
capture_error
|
|
821
|
+
;;
|
|
822
|
+
report)
|
|
823
|
+
generate_report
|
|
824
|
+
;;
|
|
825
|
+
cleanup)
|
|
826
|
+
cleanup_logs
|
|
827
|
+
;;
|
|
828
|
+
list)
|
|
829
|
+
list_error_logs "$SINCE_TIME"
|
|
830
|
+
;;
|
|
831
|
+
diagnostics)
|
|
832
|
+
run_diagnostics
|
|
833
|
+
;;
|
|
834
|
+
validate)
|
|
835
|
+
validate_dependencies
|
|
836
|
+
;;
|
|
837
|
+
esac
|
|
838
|
+
|
|
839
|
+
log "Error logging action '$ACTION' completed"
|