cleanup and files added
This commit is contained in:
309
qt_app_pyside1/check_grafana_status.py
Normal file
309
qt_app_pyside1/check_grafana_status.py
Normal file
@@ -0,0 +1,309 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user