#!/usr/bin/env nu # Marimo Interactive Dashboard Integration # Creates interactive notebooks and dashboards for infrastructure monitoring use ../dataframes/polars_integration.nu * use ../observability/collectors.nu * use ../observability/agents.nu * use ../api/server.nu * # Check if Marimo is available export def check_marimo_available []: nothing -> bool { (which marimo | length > 0) } # Install Marimo if not available export def install_marimo []: nothing -> bool { if not (check_marimo_available) { print "📦 Installing Marimo..." try { ^pip install marimo true } catch { print "❌ Failed to install Marimo. Please install manually: pip install marimo" false } } else { true } } # Create interactive dashboard export def create_dashboard [ --name: string = "infrastructure-dashboard" --data_sources: list = ["logs", "metrics", "infrastructure"] --refresh_interval: duration = 30sec --port: int = 8080 ]: nothing -> nothing { if not (install_marimo) { error make { msg: "Marimo installation failed" } } print $"🚀 Creating interactive dashboard: ($name)" # Generate dashboard Python file let dashboard_code = generate_dashboard_code $data_sources $refresh_interval let dashboard_path = $"dashboards/($name).py" # Create dashboards directory mkdir dashboards # Write dashboard file $dashboard_code | save --force $dashboard_path print $"📊 Dashboard created at: ($dashboard_path)" print $"🌐 Starting dashboard on port ($port)..." # Start Marimo dashboard ^marimo run $dashboard_path --port $port --host "0.0.0.0" } # Generate dashboard Python code def generate_dashboard_code [ data_sources: list refresh_interval: duration ]: [list, duration] -> string { let refresh_ms = ($refresh_interval | into int) / 1000000 $" import marimo as mo import polars as pl import plotly.graph_objects as go import plotly.express as px from datetime import datetime, timedelta import asyncio import requests import json # Configure the app app = mo.App(width=\"full\") @app.cell def header(): mo.md( ''' # 🚀 Systems Provisioning Dashboard Real-time monitoring and analytics for your infrastructure ''' ) return @app.cell def data_sources_config(): # Data source configuration DATA_SOURCES = ($data_sources | to json) REFRESH_INTERVAL = ($refresh_ms) API_BASE = \"http://localhost:3000\" return DATA_SOURCES, REFRESH_INTERVAL, API_BASE @app.cell def fetch_data(DATA_SOURCES, API_BASE): '''Fetch data from provisioning API''' def get_api_data(endpoint): try: response = requests.get(f\"{API_BASE}/api/{endpoint}\") return response.json() if response.status_code == 200 else {} except: return {} # Fetch data from different sources logs_data = get_api_data(\"logs\") if \"logs\" in DATA_SOURCES else {} metrics_data = get_api_data(\"metrics\") if \"metrics\" in DATA_SOURCES else {} infra_data = get_api_data(\"query/infrastructure\") if \"infrastructure\" in DATA_SOURCES else {} return logs_data, metrics_data, infra_data @app.cell def logs_analysis(logs_data): '''Analyze logs data''' if not logs_data: return mo.md(\"📝 No logs data available\") # Convert to DataFrame try: df_logs = pl.DataFrame(logs_data.get('logs', [])) if df_logs.height == 0: return mo.md(\"📝 No log entries found\") # Log level distribution level_counts = df_logs.group_by(\"level\").agg(pl.count().alias(\"count\")) fig_levels = px.pie( level_counts.to_pandas(), values='count', names='level', title=\"Log Levels Distribution\" ) # Recent errors if \"timestamp\" in df_logs.columns: recent_errors = df_logs.filter( pl.col(\"level\").is_in([\"error\", \"fatal\", \"warn\"]) ).sort(\"timestamp\", descending=True).head(10) error_table = mo.ui.table( recent_errors.to_pandas(), selection=\"single\" ) else: error_table = mo.md(\"No timestamp data available\") return mo.vstack([ mo.md(\"## 📊 Logs Analysis\"), mo.ui.plotly(fig_levels), mo.md(\"### Recent Errors/Warnings\"), error_table ]) except Exception as e: return mo.md(f\"❌ Error processing logs: {e}\") @app.cell def metrics_dashboard(metrics_data): '''System metrics dashboard''' if not metrics_data: return mo.md(\"📈 No metrics data available\") try: # System metrics visualization metrics = metrics_data.get('metrics', {}) # CPU Usage cpu_data = metrics.get('cpu', {}) if cpu_data: fig_cpu = go.Figure() fig_cpu.add_trace(go.Scatter( x=list(range(len(cpu_data.get('values', [])))), y=cpu_data.get('values', []), mode='lines+markers', name='CPU %', line=dict(color='#ff6b6b') )) fig_cpu.update_layout(title='CPU Usage Over Time', yaxis_title='Percentage') else: fig_cpu = None # Memory Usage memory_data = metrics.get('memory', {}) if memory_data: fig_memory = go.Figure() fig_memory.add_trace(go.Scatter( x=list(range(len(memory_data.get('values', [])))), y=memory_data.get('values', []), mode='lines+markers', name='Memory %', line=dict(color='#4ecdc4') )) fig_memory.update_layout(title='Memory Usage Over Time', yaxis_title='Percentage') else: fig_memory = None # Infrastructure status infra_status = metrics.get('infrastructure', {}) status_cards = [] if infra_status: for service, data in infra_status.items(): status = \"🟢 Healthy\" if data.get('healthy', False) else \"🔴 Unhealthy\" status_cards.append( mo.md(f\"**{service}**: {status} (Load: {data.get('load', 'N/A')})\") ) components = [mo.md(\"## 📈 System Metrics\")] if fig_cpu: components.append(mo.ui.plotly(fig_cpu)) if fig_memory: components.append(mo.ui.plotly(fig_memory)) if status_cards: components.extend([mo.md(\"### Infrastructure Status\")] + status_cards) return mo.vstack(components) except Exception as e: return mo.md(f\"❌ Error processing metrics: {e}\") @app.cell def infrastructure_overview(infra_data): '''Infrastructure overview and topology''' if not infra_data: return mo.md(\"🏗️ No infrastructure data available\") try: infra = infra_data.get('infrastructure', {}) # Servers overview servers = infra.get('servers', []) if servers: df_servers = pl.DataFrame(servers) # Provider distribution if \"provider\" in df_servers.columns: provider_counts = df_servers.group_by(\"provider\").agg(pl.count().alias(\"count\")) fig_providers = px.bar( provider_counts.to_pandas(), x='provider', y='count', title='Servers by Provider' ) else: fig_providers = None # Status distribution if \"status\" in df_servers.columns: status_counts = df_servers.group_by(\"status\").agg(pl.count().alias(\"count\")) fig_status = px.pie( status_counts.to_pandas(), values='count', names='status', title='Server Status Distribution' ) else: fig_status = None # Server table server_table = mo.ui.table( df_servers.to_pandas(), selection=\"multiple\" ) components = [ mo.md(\"## 🏗️ Infrastructure Overview\"), mo.md(f\"**Total Servers**: {len(servers)}\") ] if fig_providers: components.append(mo.ui.plotly(fig_providers)) if fig_status: components.append(mo.ui.plotly(fig_status)) components.extend([ mo.md(\"### Server Details\"), server_table ]) return mo.vstack(components) else: return mo.md(\"🏗️ No server data available\") except Exception as e: return mo.md(f\"❌ Error processing infrastructure data: {e}\") @app.cell def ai_insights(): '''AI-powered insights and recommendations''' # This would integrate with our AI agents insights = [ \"💡 **Cost Optimization**: Consider downsizing instance i-12345 (38% CPU avg)\", \"⚠️ **Performance Alert**: Database response time increased 15% in last hour\", \"🔮 **Prediction**: Disk space on /var/log will be full in 3 days\", \"🛡️ **Security**: No failed login attempts detected in last 24h\", \"📈 **Scaling**: Web tier may need +2 instances based on traffic trends\" ] insight_cards = [mo.md(insight) for insight in insights] return mo.vstack([ mo.md(\"## 🤖 AI Insights & Recommendations\"), mo.md(\"_Powered by Rust-based AI agents_\"), *insight_cards ]) @app.cell def controls(): '''Dashboard controls and settings''' refresh_button = mo.ui.button( label=\"🔄 Refresh Data\", on_click=lambda: print(\"Refreshing dashboard data...\") ) auto_refresh = mo.ui.checkbox( label=\"Auto-refresh every 30 seconds\", value=True ) export_button = mo.ui.button( label=\"📊 Export Report\", on_click=lambda: print(\"Exporting dashboard report...\") ) return mo.hstack([refresh_button, auto_refresh, export_button]) @app.cell def footer(): mo.md( ''' --- **Systems Provisioning Dashboard** | Powered by Rust + Nushell + Marimo 🔗 [API Status](http://localhost:3000/health) | 📖 [Documentation](http://localhost:3000/docs) ''' ) return if __name__ == \"__main__\": app.run() " } # Create predefined dashboard templates export def create_template [ template: string --name: string = "" ]: string -> nothing { let dashboard_name = if ($name | is-empty) { $"($template)-dashboard" } else { $name } match $template { "monitoring" => { create_dashboard --name $dashboard_name --data_sources ["logs", "metrics"] --refresh_interval 15sec } "infrastructure" => { create_dashboard --name $dashboard_name --data_sources ["infrastructure", "metrics"] --refresh_interval 30sec } "full" => { create_dashboard --name $dashboard_name --data_sources ["logs", "metrics", "infrastructure"] --refresh_interval 30sec } "ai-insights" => { create_dashboard --name $dashboard_name --data_sources ["logs", "metrics", "infrastructure"] --refresh_interval 10sec } _ => { error make { msg: $"Unknown template: ($template). Available: monitoring, infrastructure, full, ai-insights" } } } } # List available dashboards export def list_dashboards []: nothing -> list { if not ("dashboards" | path exists) { return [] } ls dashboards/*.py | get name | each {|path| { name: ($path | path basename | str replace ".py" "") path: $path size: (stat $path | get size) modified: (stat $path | get modified) } } } # Start existing dashboard export def start_dashboard [ dashboard_name: string --port: int = 8080 --host: string = "0.0.0.0" ]: string -> nothing { let dashboard_path = $"dashboards/($dashboard_name).py" if not ($dashboard_path | path exists) { error make { msg: $"Dashboard not found: ($dashboard_path)" } } print $"🌐 Starting dashboard: ($dashboard_name) on ($host):($port)" ^marimo run $dashboard_path --port $port --host $host } # Export dashboard as static HTML export def export_dashboard [ dashboard_name: string --output: string = "" ]: string -> nothing { let dashboard_path = $"dashboards/($dashboard_name).py" let output_path = if ($output | is-empty) { $"exports/($dashboard_name).html" } else { $output } if not ($dashboard_path | path exists) { error make { msg: $"Dashboard not found: ($dashboard_path)" } } # Create exports directory mkdir exports print $"📤 Exporting dashboard to: ($output_path)" ^marimo export html $dashboard_path --output $output_path print $"✅ Dashboard exported successfully" } # Dashboard management commands export def main [ command: string ...args: string ]: [string, ...string] -> nothing { match $command { "create" => { if ($args | length) >= 1 { let template = $args.0 let name = if ($args | length) >= 2 { $args.1 } else { "" } create_template $template --name $name } else { create_dashboard } } "list" => { list_dashboards | table } "start" => { if ($args | length) >= 1 { let name = $args.0 let port = if ($args | length) >= 2 { $args.1 | into int } else { 8080 } start_dashboard $name --port $port } else { error make { msg: "Dashboard name required" } } } "export" => { if ($args | length) >= 1 { let name = $args.0 let output = if ($args | length) >= 2 { $args.1 } else { "" } export_dashboard $name --output $output } else { error make { msg: "Dashboard name required" } } } "install" => { install_marimo } _ => { print "📊 Marimo Dashboard Integration Commands:" print "" print "Usage: marimo_integration [args...]" print "" print "Commands:" print " create [template] [name] - Create new dashboard from template" print " list - List available dashboards" print " start [port] - Start existing dashboard" print " export [output] - Export dashboard to HTML" print " install - Install Marimo package" print "" print "Templates:" print " monitoring - Logs and metrics dashboard" print " infrastructure- Infrastructure overview" print " full - Complete monitoring dashboard" print " ai-insights - AI-powered insights dashboard" } } }