JSON Output Example¶
Overview¶
Mooncake now supports structured JSON event output via the event system. This enables integration with external tools, monitoring systems, and custom processing pipelines.
Usage¶
# Run with JSON event output
mooncake run --config myconfig.yml --raw --output-format json
# Process events with jq
mooncake run --config myconfig.yml --raw --output-format json | jq '.'
# Filter specific event types
mooncake run --config myconfig.yml --raw --output-format json | \
jq 'select(.type == "step.completed")'
# Extract step durations
mooncake run --config myconfig.yml --raw --output-format json | \
jq 'select(.type == "step.completed") | {name: .data.name, duration_ms: .data.duration_ms}'
# Monitor execution in real-time
mooncake run --config myconfig.yml --raw --output-format json | \
jq --unbuffered -c 'select(.type | startswith("step."))'
Event Types¶
Run Lifecycle¶
run.started- Execution beginsplan.loaded- Plan has been builtrun.completed- Execution finished
Step Lifecycle¶
step.started- Step begins executionstep.completed- Step completed successfullystep.failed- Step failed with errorstep.skipped- Step was skipped
Output Streaming¶
step.stdout- Standard output line from shell stepstep.stderr- Standard error line from shell step
File Operations¶
file.created- File was createdfile.updated- File was updateddirectory.created- Directory was createdtemplate.rendered- Template was rendered
Variables¶
variables.set- Variables were set inlinevariables.loaded- Variables were loaded from file
Event Schema¶
run.started¶
{
"type": "run.started",
"timestamp": "2026-02-04T14:14:19.699336+01:00",
"data": {
"root_file": "/path/to/config.yml",
"tags": ["tag1", "tag2"],
"dry_run": false,
"total_steps": 10
}
}
step.started¶
{
"type": "step.started",
"timestamp": "2026-02-04T14:14:19.699372+01:00",
"data": {
"step_id": "step-0001",
"name": "Install nginx",
"level": 0,
"global_step": 1,
"action": "shell",
"tags": ["setup"],
"when": ""
}
}
step.completed¶
{
"type": "step.completed",
"timestamp": "2026-02-04T14:14:19.705515+01:00",
"data": {
"step_id": "step-0001",
"name": "Install nginx",
"level": 0,
"duration_ms": 1250,
"changed": true
}
}
step.stdout¶
{
"type": "step.stdout",
"timestamp": "2026-02-04T14:14:19.705324+01:00",
"data": {
"step_id": "step-0001",
"stream": "stdout",
"line": "nginx installed successfully",
"line_number": 1
}
}
run.completed¶
{
"type": "run.completed",
"timestamp": "2026-02-04T14:14:29.180581+01:00",
"data": {
"total_steps": 10,
"success_steps": 9,
"failed_steps": 1,
"skipped_steps": 0,
"changed_steps": 7,
"duration_ms": 15432,
"success": false,
"error_message": "Step 'Deploy app' failed: connection refused"
}
}
Use Cases¶
1. CI/CD Integration¶
# Parse execution results in CI/CD pipeline
mooncake run --config deploy.yml --raw --output-format json > execution.jsonl
# Check if execution succeeded
if jq -e '.type == "run.completed" and .data.success == true' execution.jsonl > /dev/null; then
echo "Deployment successful"
exit 0
else
echo "Deployment failed"
exit 1
fi
2. Performance Monitoring¶
# Extract step performance metrics
mooncake run --config myconfig.yml --raw --output-format json | \
jq 'select(.type == "step.completed") |
{step: .data.name, duration: .data.duration_ms}' | \
jq -s 'sort_by(.duration) | reverse'
3. Real-Time Dashboard¶
# Stream events to monitoring dashboard
mooncake run --config myconfig.yml --raw --output-format json | \
while read -r event; do
# Send to Elasticsearch, Prometheus, etc.
curl -X POST http://dashboard/api/events -d "$event"
done
4. Log Aggregation¶
# Forward events to log aggregation system
mooncake run --config myconfig.yml --raw --output-format json | \
jq -c '.' | \
filebeat -e -c filebeat.yml
5. Custom Processing¶
# Filter and transform events with custom script
mooncake run --config myconfig.yml --raw --output-format json | \
python process_events.py
Notes¶
- JSON output requires
--rawflag (disables TUI) - Each event is a single-line JSON object (JSONL format)
- Events are emitted in real-time as execution progresses
- All timestamps are in ISO 8601 format
- Step IDs are unique within a run (e.g., "step-0001", "step-0002")
- Output lines include line numbers for multi-line output
Example Processing Script¶
#!/usr/bin/env python3
import sys
import json
for line in sys.stdin:
event = json.loads(line)
if event['type'] == 'step.completed':
data = event['data']
print(f"✓ {data['name']} ({data['duration_ms']}ms)")
elif event['type'] == 'step.failed':
data = event['data']
print(f"✗ {data['name']}: {data['error_message']}")
elif event['type'] == 'run.completed':
data = event['data']
if data['success']:
print(f"\nSuccess! {data['success_steps']}/{data['total_steps']} steps completed")
else:
print(f"\nFailed: {data['error_message']}")
Save as process_events.py and use: