#!/usr/bin/env python3 """ Grafana Status Checker for Smart Intersection System Checks dashboards, datasources, and real-time data connectivity """ import requests import json import time from datetime import datetime, timedelta import base64 class GrafanaStatusChecker: def __init__(self, base_url="http://localhost:3000", username="admin", password="admin"): self.base_url = base_url.rstrip('/') self.username = username self.password = password self.session = requests.Session() self.dashboards = [] self.datasources = [] # Setup authentication self.setup_auth() def setup_auth(self): """Setup authentication for Grafana API""" auth_string = f"{self.username}:{self.password}" encoded_auth = base64.b64encode(auth_string.encode()).decode() self.session.headers.update({ 'Authorization': f'Basic {encoded_auth}', 'Content-Type': 'application/json' }) def check_grafana_health(self): """Check if Grafana is accessible and healthy""" try: response = self.session.get(f"{self.base_url}/api/health") if response.status_code == 200: health_data = response.json() print(f"āœ… Grafana Health: {health_data.get('status', 'OK')}") print(f"šŸ“… Server Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") return True else: print(f"āŒ Grafana health check failed: {response.status_code}") return False except Exception as e: print(f"āŒ Cannot connect to Grafana: {e}") return False def get_datasources_status(self): """Check all datasources and their connectivity""" try: response = self.session.get(f"{self.base_url}/api/datasources") if response.status_code != 200: print(f"āŒ Failed to get datasources: {response.status_code}") return datasources = response.json() print(f"\nšŸ“Š GRAFANA DATASOURCES STATUS:") print(f"{'='*50}") for ds in datasources: self.datasources.append(ds) print(f"šŸ”Œ Datasource: {ds['name']}") print(f" Type: {ds['type']}") print(f" URL: {ds['url']}") print(f" ID: {ds['id']}") print(f" Default: {'Yes' if ds.get('isDefault') else 'No'}") # Test datasource connectivity self.test_datasource_connectivity(ds['id'], ds['name']) print() except Exception as e: print(f"āŒ Error getting datasources: {e}") def test_datasource_connectivity(self, ds_id, ds_name): """Test connectivity to a specific datasource""" try: response = self.session.get(f"{self.base_url}/api/datasources/{ds_id}/health") if response.status_code == 200: health_data = response.json() status = health_data.get('status', 'unknown') message = health_data.get('message', 'No message') if status == 'OK': print(f" āœ… Connectivity: HEALTHY") else: print(f" āš ļø Connectivity: {status}") if message and message != 'No message': print(f" šŸ“ Message: {message}") else: print(f" āŒ Connectivity: FAILED (HTTP {response.status_code})") except Exception as e: print(f" āŒ Connectivity test failed: {e}") def get_dashboards_status(self): """Get information about all dashboards""" try: response = self.session.get(f"{self.base_url}/api/search?type=dash-db") if response.status_code != 200: print(f"āŒ Failed to get dashboards: {response.status_code}") return dashboards = response.json() print(f"\nšŸ“Š GRAFANA DASHBOARDS:") print(f"{'='*40}") if not dashboards: print("āŒ No dashboards found") print(" Consider importing the Smart Intersection dashboard") return for dashboard in dashboards: self.dashboards.append(dashboard) print(f"šŸ“ˆ Dashboard: {dashboard['title']}") print(f" UID: {dashboard['uid']}") print(f" URL: {self.base_url}/d/{dashboard['uid']}") print(f" Tags: {', '.join(dashboard.get('tags', []))}") print(f" Folder: {dashboard.get('folderTitle', 'General')}") # Get detailed dashboard info self.check_dashboard_panels(dashboard['uid'], dashboard['title']) print() except Exception as e: print(f"āŒ Error getting dashboards: {e}") def check_dashboard_panels(self, dashboard_uid, dashboard_title): """Check panels in a specific dashboard""" try: response = self.session.get(f"{self.base_url}/api/dashboards/uid/{dashboard_uid}") if response.status_code != 200: print(f" āŒ Cannot get dashboard details") return dashboard_data = response.json()['dashboard'] panels = dashboard_data.get('panels', []) print(f" šŸ“Š Panels: {len(panels)}") if not panels: print(f" āš ļø No panels configured") return # Check each panel panel_info = [] for panel in panels: if 'targets' in panel: panel_type = panel.get('type', 'unknown') panel_title = panel.get('title', 'Untitled') targets = len(panel.get('targets', [])) panel_info.append(f"{panel_title} ({panel_type}, {targets} queries)") if panel_info: for info in panel_info[:3]: # Show first 3 panels print(f" - {info}") if len(panel_info) > 3: print(f" ... and {len(panel_info) - 3} more panels") except Exception as e: print(f" āŒ Error checking panels: {e}") def test_dashboard_data_refresh(self, dashboard_uid="smart-intersection-main"): """Test if dashboard data is refreshing""" print(f"\nšŸ”„ TESTING DASHBOARD DATA REFRESH:") print(f"{'-'*40}") try: # Try to get dashboard by UID response = self.session.get(f"{self.base_url}/api/dashboards/uid/{dashboard_uid}") if response.status_code == 404: print(f"āš ļø Dashboard '{dashboard_uid}' not found") print(f" Available dashboards:") for dash in self.dashboards: print(f" - {dash['title']} (UID: {dash['uid']})") return if response.status_code != 200: print(f"āŒ Cannot access dashboard: {response.status_code}") return dashboard_data = response.json()['dashboard'] panels = dashboard_data.get('panels', []) print(f"šŸŽÆ Testing dashboard: {dashboard_data.get('title', 'Unknown')}") # Test a few panels for data data_panels = [p for p in panels if 'targets' in p and p.get('targets')] if not data_panels: print(f"āŒ No data panels found in dashboard") return # Test first data panel test_panel = data_panels[0] print(f"šŸ“Š Testing panel: {test_panel.get('title', 'Untitled')}") # Simulate data query (this would require more complex API calls) print(f"āœ… Panel configured with {len(test_panel['targets'])} queries") print(f"ā±ļø Auto-refresh: {dashboard_data.get('refresh', 'Not set')}") except Exception as e: print(f"āŒ Error testing dashboard refresh: {e}") def check_alerts_and_notifications(self): """Check alert rules and notification channels""" print(f"\n🚨 ALERTS AND NOTIFICATIONS:") print(f"{'-'*35}") try: # Check alert rules response = self.session.get(f"{self.base_url}/api/alert-rules") if response.status_code == 200: alerts = response.json() print(f"šŸ“¢ Alert Rules: {len(alerts)}") if alerts: for alert in alerts[:3]: # Show first 3 print(f" - {alert.get('title', 'Untitled')}") else: print(f" No alert rules configured") else: print(f"āš ļø Cannot access alert rules (may not be available)") # Check notification channels response = self.session.get(f"{self.base_url}/api/alert-notifications") if response.status_code == 200: notifications = response.json() print(f"šŸ“« Notification Channels: {len(notifications)}") if notifications: for notif in notifications[:3]: # Show first 3 print(f" - {notif.get('name', 'Untitled')} ({notif.get('type', 'unknown')})") else: print(f"āš ļø Cannot access notification channels") except Exception as e: print(f"āŒ Error checking alerts: {e}") def generate_status_report(self): """Generate comprehensive Grafana status report""" print(f"\nšŸ“Š GRAFANA COMPREHENSIVE STATUS REPORT") print(f"{'='*60}") print(f"Report Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") print(f"Grafana URL: {self.base_url}") print(f"Username: {self.username}") # Check if Grafana is accessible if not self.check_grafana_health(): print("āŒ Cannot generate report - Grafana not accessible") return # Check datasources self.get_datasources_status() # Check dashboards self.get_dashboards_status() # Test data refresh if self.dashboards: self.test_dashboard_data_refresh(self.dashboards[0]['uid']) # Check alerts self.check_alerts_and_notifications() # Summary print(f"\nšŸ“‹ SUMMARY:") print(f"{'-'*20}") print(f"āœ… Grafana Status: {'Healthy' if True else 'Unhealthy'}") print(f"šŸ“Š Datasources: {len(self.datasources)}") print(f"šŸ“ˆ Dashboards: {len(self.dashboards)}") print(f"🌐 Access URL: {self.base_url}") def main(): """Main function to run Grafana status check""" print("🚦 SMART INTERSECTION - GRAFANA STATUS CHECKER") print("="*60) # Default connection settings - modify if needed base_url = "http://localhost:3000" username = "admin" password = "admin" print(f"🌐 Checking Grafana at: {base_url}") print(f"šŸ‘¤ Username: {username}") checker = GrafanaStatusChecker(base_url, username, password) checker.generate_status_report() print(f"\nšŸ’” TROUBLESHOOTING TIPS:") print(f"{'-'*40}") print("If connection fails:") print("1. Check if Grafana is running: netstat -an | findstr :3000") print("2. Verify username/password (default: admin/admin)") print("3. Check Grafana logs for errors") print("4. Ensure firewall allows port 3000") print("5. Try accessing web UI directly in browser") if __name__ == "__main__": main()