Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
- ADD_CHAIN138_TO_LEDGER_LIVE: Ledger form done; public code review repo bis-innovations/LedgerLive; init/push commands - CONTRACT_DEPLOYMENT_RUNBOOK: Chain 138 gas price 1 gwei, 36-addr check, TransactionMirror workaround - CONTRACT_*: AddressMapper, MirrorManager deployed 2026-02-12; 36-address on-chain check - NEXT_STEPS_FOR_YOU: Ledger done; steps completable now (no LAN); run-completable-tasks-from-anywhere - MASTER_INDEX, OPERATOR_OPTIONAL, SMART_CONTRACTS_INVENTORY_SIMPLE: updates - LEDGER_BLOCKCHAIN_INTEGRATION_COMPLETE: bis-innovations/LedgerLive reference Co-authored-by: Cursor <cursoragent@cursor.com>
272 lines
8.7 KiB
Bash
Executable File
272 lines
8.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Create Monitoring Dashboard
|
|
# Generates a simple HTML dashboard for monitoring status
|
|
|
|
set -euo pipefail
|
|
|
|
# Load IP configuration
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
source "${PROJECT_ROOT}/config/ip-addresses.conf" 2>/dev/null || true
|
|
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
|
|
# Colors
|
|
GREEN='\033[0;32m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
|
log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
|
|
|
|
create_dashboard() {
|
|
log_info "Creating monitoring dashboard..."
|
|
|
|
local dashboard_file="${PROJECT_ROOT}/logs/monitoring/dashboard.html"
|
|
mkdir -p "$(dirname "$dashboard_file")"
|
|
|
|
cat > "$dashboard_file" <<'DASHBOARD'
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Blockchain Monitoring Dashboard</title>
|
|
<style>
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
body {
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
background: #0f172a;
|
|
color: #e2e8f0;
|
|
padding: 20px;
|
|
}
|
|
.container { max-width: 1400px; margin: 0 auto; }
|
|
h1 {
|
|
color: #60a5fa;
|
|
margin-bottom: 30px;
|
|
font-size: 2.5em;
|
|
text-align: center;
|
|
}
|
|
.status-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
|
gap: 20px;
|
|
margin-bottom: 30px;
|
|
}
|
|
.status-card {
|
|
background: #1e293b;
|
|
border-radius: 12px;
|
|
padding: 20px;
|
|
border: 2px solid #334155;
|
|
transition: all 0.3s;
|
|
}
|
|
.status-card:hover {
|
|
border-color: #60a5fa;
|
|
transform: translateY(-2px);
|
|
}
|
|
.status-card.active { border-color: #10b981; }
|
|
.status-card.warning { border-color: #f59e0b; }
|
|
.status-card.error { border-color: #ef4444; }
|
|
.card-title {
|
|
font-size: 1.2em;
|
|
color: #94a3b8;
|
|
margin-bottom: 10px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
}
|
|
.status-indicator {
|
|
width: 12px;
|
|
height: 12px;
|
|
border-radius: 50%;
|
|
display: inline-block;
|
|
margin-right: 8px;
|
|
}
|
|
.status-indicator.active { background: #10b981; box-shadow: 0 0 8px #10b981; }
|
|
.status-indicator.warning { background: #f59e0b; box-shadow: 0 0 8px #f59e0b; }
|
|
.status-indicator.error { background: #ef4444; box-shadow: 0 0 8px #ef4444; }
|
|
.card-value {
|
|
font-size: 2em;
|
|
color: #60a5fa;
|
|
font-weight: bold;
|
|
}
|
|
.log-section {
|
|
background: #1e293b;
|
|
border-radius: 12px;
|
|
padding: 20px;
|
|
margin-top: 20px;
|
|
border: 2px solid #334155;
|
|
}
|
|
.log-section h2 {
|
|
color: #60a5fa;
|
|
margin-bottom: 15px;
|
|
}
|
|
.log-viewer {
|
|
background: #0f172a;
|
|
border: 1px solid #334155;
|
|
border-radius: 8px;
|
|
padding: 15px;
|
|
font-family: 'Courier New', monospace;
|
|
font-size: 0.9em;
|
|
max-height: 400px;
|
|
overflow-y: auto;
|
|
color: #94a3b8;
|
|
}
|
|
.log-entry { margin-bottom: 5px; }
|
|
.log-entry.error { color: #ef4444; }
|
|
.log-entry.warning { color: #f59e0b; }
|
|
.log-entry.success { color: #10b981; }
|
|
.refresh-btn {
|
|
background: #3b82f6;
|
|
color: white;
|
|
border: none;
|
|
padding: 10px 20px;
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
font-size: 1em;
|
|
margin-bottom: 20px;
|
|
}
|
|
.refresh-btn:hover { background: #2563eb; }
|
|
.timestamp {
|
|
color: #64748b;
|
|
font-size: 0.9em;
|
|
text-align: center;
|
|
margin-top: 20px;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<h1>🔗 Blockchain Monitoring Dashboard</h1>
|
|
|
|
<button class="refresh-btn" onclick="location.reload()">🔄 Refresh</button>
|
|
|
|
<div class="status-grid" id="statusGrid">
|
|
<!-- Status cards will be populated by JavaScript -->
|
|
</div>
|
|
|
|
<div class="log-section">
|
|
<h2>Recent Activity</h2>
|
|
<div class="log-viewer" id="logViewer">
|
|
<!-- Logs will be populated by JavaScript -->
|
|
</div>
|
|
</div>
|
|
|
|
<div class="timestamp" id="timestamp"></div>
|
|
</div>
|
|
|
|
<script>
|
|
function fetchStatus() {
|
|
// This would normally fetch from an API
|
|
// For now, we'll use static data or file reading
|
|
|
|
const statusGrid = document.getElementById('statusGrid');
|
|
const logViewer = document.getElementById('logViewer');
|
|
|
|
// Example status data (replace with actual API calls)
|
|
const statuses = [
|
|
{ name: 'Block Production', status: 'active', value: 'Active', detail: 'Block: 1153290+' },
|
|
{ name: 'Validators', status: 'active', value: '5/5', detail: 'All validators running' },
|
|
{ name: 'Health Checks', status: 'active', value: 'OK', detail: 'All checks passing' },
|
|
{ name: 'Transaction Pool', status: 'active', value: 'Normal', detail: 'No stuck transactions' },
|
|
{ name: 'Network Sync', status: 'active', value: 'Synced', detail: 'All nodes synchronized' },
|
|
{ name: 'Consensus', status: 'active', value: 'QBFT', detail: 'Quorum maintained' }
|
|
];
|
|
|
|
statusGrid.innerHTML = statuses.map(s => `
|
|
<div class="status-card ${s.status}">
|
|
<div class="card-title">
|
|
<span><span class="status-indicator ${s.status}"></span>${s.name}</span>
|
|
</div>
|
|
<div class="card-value">${s.value}</div>
|
|
<div style="color: #94a3b8; margin-top: 5px;">${s.detail}</div>
|
|
</div>
|
|
`).join('');
|
|
|
|
logViewer.innerHTML = `
|
|
<div class="log-entry success">[${new Date().toLocaleTimeString()}] All systems operational</div>
|
|
<div class="log-entry">[${new Date().toLocaleTimeString()}] Health checks running normally</div>
|
|
<div class="log-entry">[${new Date().toLocaleTimeString()}] Block production active</div>
|
|
`;
|
|
|
|
document.getElementById('timestamp').textContent =
|
|
`Last updated: ${new Date().toLocaleString()}`;
|
|
}
|
|
|
|
// Initial load
|
|
fetchStatus();
|
|
|
|
// Auto-refresh every 30 seconds
|
|
setInterval(fetchStatus, 30000);
|
|
</script>
|
|
</body>
|
|
</html>
|
|
DASHBOARD
|
|
|
|
log_success "Dashboard created: $dashboard_file"
|
|
log_info "Open in browser: file://$dashboard_file"
|
|
}
|
|
|
|
create_dashboard_script() {
|
|
log_info "Creating dashboard update script..."
|
|
|
|
cat > "$SCRIPT_DIR/update-dashboard.sh" <<'DASHBOARDSCRIPT'
|
|
#!/usr/bin/env bash
|
|
# Update Monitoring Dashboard
|
|
# Fetches current status and updates dashboard
|
|
|
|
set -euo pipefail
|
|
|
|
# Load IP configuration
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
source "${PROJECT_ROOT}/config/ip-addresses.conf" 2>/dev/null || true
|
|
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
|
|
# Source environment
|
|
if [ -f "$PROJECT_ROOT/smom-dbis-138/.env" ]; then
|
|
source "$PROJECT_ROOT/smom-dbis-138/.env" 2>/dev/null || true
|
|
fi
|
|
|
|
RPC_URL="${RPC_URL_138:-http://${RPC_CORE_1}:8545}"
|
|
|
|
# Get current block
|
|
BLOCK=$(cast block-number --rpc-url "$RPC_URL" 2>/dev/null || echo "0")
|
|
|
|
# Get validator status (simplified)
|
|
VALIDATOR_COUNT=5
|
|
|
|
# Update dashboard with real data
|
|
# This would be integrated with the HTML dashboard
|
|
echo "Dashboard update script ready"
|
|
echo "Block: $BLOCK"
|
|
echo "Validators: $VALIDATOR_COUNT/5"
|
|
|
|
DASHBOARDSCRIPT
|
|
|
|
chmod +x "$SCRIPT_DIR/update-dashboard.sh"
|
|
log_success "update-dashboard.sh script created"
|
|
}
|
|
|
|
main() {
|
|
log_info "Creating monitoring dashboard..."
|
|
echo ""
|
|
|
|
create_dashboard
|
|
echo ""
|
|
|
|
create_dashboard_script
|
|
echo ""
|
|
|
|
log_success "Monitoring dashboard created!"
|
|
log_info "Dashboard location: logs/monitoring/dashboard.html"
|
|
log_info "You can open it in a web browser or set up a web server to serve it"
|
|
}
|
|
|
|
main "$@"
|