Files
Traffic-Intersection-Monito…/qt_app_pyside1/advanced_grafana_repair.py
2025-08-26 13:24:53 -07:00

492 lines
18 KiB
Python

"""
Direct InfluxDB to Grafana connection tester with more verbose error reporting
"""
import requests
import json
import subprocess
import os
import sys
import time
from datetime import datetime, timedelta
from influxdb_client import InfluxDBClient, Point
from influxdb_client.client.write_api import SYNCHRONOUS
# Configuration
INFLUX_URL = "http://localhost:8086"
INFLUX_TOKEN = "kNFfXEpPQoWrk5Tteowda21Dzv6xD3jY7QHSHHQHb5oYW6VH6mkAgX9ZMjQJkaHHa8FwzmyVFqDG7qqzxN09uQ=="
INFLUX_ORG = "smart-intersection-org"
INFLUX_BUCKET = "traffic_monitoring"
GRAFANA_URL = "http://localhost:3000"
GRAFANA_USER = "admin"
GRAFANA_PASSWORD = "admin"
def check_service_status(service_name):
"""Check if a service is running"""
try:
# For Windows
output = subprocess.check_output(f"tasklist /FI \"IMAGENAME eq {service_name}*\"", shell=True).decode()
if service_name.lower() in output.lower():
print(f"{service_name} appears to be running")
return True
else:
print(f"{service_name} doesn't appear to be running")
return False
except Exception as e:
print(f"❌ Error checking {service_name} status: {e}")
return False
def test_influxdb_connection():
"""Test direct connection to InfluxDB"""
print("\n===== TESTING INFLUXDB CONNECTION =====")
try:
client = InfluxDBClient(url=INFLUX_URL, token=INFLUX_TOKEN, org=INFLUX_ORG)
health = client.health()
print(f"✅ InfluxDB connection successful")
print(f" Status: {health.status}")
print(f" Version: {health.version}")
print(f" Message: {health.message}")
# Check if bucket exists
buckets_api = client.buckets_api()
buckets = buckets_api.find_buckets().buckets
bucket_exists = False
for bucket in buckets:
if bucket.name == INFLUX_BUCKET:
bucket_exists = True
print(f"✅ Bucket '{INFLUX_BUCKET}' exists")
break
if not bucket_exists:
print(f"❌ Bucket '{INFLUX_BUCKET}' does not exist")
return False
return True
except Exception as e:
print(f"❌ InfluxDB connection failed: {e}")
return False
def check_influx_data():
"""Query InfluxDB directly to check if data exists"""
print("\n===== CHECKING INFLUXDB DATA =====")
try:
client = InfluxDBClient(url=INFLUX_URL, token=INFLUX_TOKEN, org=INFLUX_ORG)
query_api = client.query_api()
# Query for performance data
query = f'''
from(bucket: "{INFLUX_BUCKET}")
|> range(start: -1h)
|> filter(fn: (r) => r._measurement == "performance")
|> count()
'''
result = query_api.query(query=query, org=INFLUX_ORG)
if result and len(result) > 0:
count = 0
for table in result:
for record in table.records:
count = record.get_value()
print(f"✅ Found {count} performance data points in InfluxDB")
# If data exists, print a sample to verify structure
if count > 0:
sample_query = f'''
from(bucket: "{INFLUX_BUCKET}")
|> range(start: -1h)
|> filter(fn: (r) => r._measurement == "performance")
|> limit(n: 1)
'''
sample_result = query_api.query(query=sample_query, org=INFLUX_ORG)
if sample_result and len(sample_result) > 0:
print("Sample data structure:")
for table in sample_result:
for record in table.records:
print(f" _measurement: {record.get_measurement()}")
print(f" _field: {record.get_field()}")
print(f" _value: {record.get_value()}")
print(f" _time: {record.get_time()}")
for key, value in record.values.items():
if key not in ['_measurement', '_field', '_value', '_time']:
print(f" {key}: {value}")
else:
print("❌ No data found in InfluxDB")
return False
return True
except Exception as e:
print(f"❌ Error querying InfluxDB: {e}")
return False
def check_grafana_datasource():
"""Check Grafana InfluxDB datasource configuration"""
print("\n===== CHECKING GRAFANA DATASOURCE =====")
try:
response = requests.get(
f"{GRAFANA_URL}/api/datasources",
auth=(GRAFANA_USER, GRAFANA_PASSWORD)
)
if response.status_code != 200:
print(f"❌ Failed to get Grafana datasources: {response.status_code}")
print(f"Response: {response.text}")
return False
datasources = response.json()
influx_ds = None
for ds in datasources:
if "influx" in ds["type"].lower():
influx_ds = ds
break
if not influx_ds:
print("❌ No InfluxDB datasource found in Grafana")
return False
print("InfluxDB datasource details:")
print(f" Name: {influx_ds.get('name')}")
print(f" Type: {influx_ds.get('type')}")
print(f" URL: {influx_ds.get('url')}")
print(f" Access: {influx_ds.get('access')}")
# Check JSON data
json_data = influx_ds.get('jsonData', {})
print(" JSON Data:")
print(f" Version: {json_data.get('version')}")
print(f" Default Bucket: {json_data.get('defaultBucket')}")
print(f" Organization: {json_data.get('organization')}")
print(f" HTTP Mode: {json_data.get('httpMode')}")
# Validate critical settings
issues = []
if json_data.get('version') != 'Flux':
issues.append("⚠️ Version is not set to 'Flux'")
if json_data.get('defaultBucket') != INFLUX_BUCKET:
issues.append(f"⚠️ Default bucket ({json_data.get('defaultBucket')}) doesn't match expected ({INFLUX_BUCKET})")
if json_data.get('organization') != INFLUX_ORG:
issues.append(f"⚠️ Organization ({json_data.get('organization')}) doesn't match expected ({INFLUX_ORG})")
if influx_ds.get('url') != INFLUX_URL:
issues.append(f"⚠️ URL ({influx_ds.get('url')}) doesn't match expected ({INFLUX_URL})")
if issues:
print("\nPotential configuration issues:")
for issue in issues:
print(f" {issue}")
# Try to fix the datasource
print("\nAttempting to fix data source configuration...")
fixed_ds = {
"id": influx_ds.get('id'),
"name": influx_ds.get('name'),
"type": "influxdb",
"url": INFLUX_URL,
"access": "proxy",
"basicAuth": False,
"isDefault": True,
"jsonData": {
"defaultBucket": INFLUX_BUCKET,
"organization": INFLUX_ORG,
"version": "Flux",
"timeInterval": "10s"
},
"secureJsonData": {
"token": INFLUX_TOKEN
}
}
# Update datasource
response = requests.put(
f"{GRAFANA_URL}/api/datasources/{influx_ds.get('id')}",
auth=(GRAFANA_USER, GRAFANA_PASSWORD),
headers={"Content-Type": "application/json"},
data=json.dumps(fixed_ds)
)
if response.status_code == 200:
print("✅ Datasource updated successfully")
else:
print(f"❌ Failed to update datasource: {response.status_code}")
print(f"Response: {response.text}")
else:
print("✅ Datasource configuration appears correct")
# Test datasource
print("\nTesting datasource connection from Grafana...")
response = requests.post(
f"{GRAFANA_URL}/api/datasources/{influx_ds.get('id')}/health",
auth=(GRAFANA_USER, GRAFANA_PASSWORD)
)
if response.status_code == 200:
result = response.json()
print(f"✅ Datasource health check: {result.get('status')} - {result.get('message')}")
else:
print(f"❌ Datasource health check failed: {response.status_code}")
print(f"Response: {response.text}")
return False
return True
except Exception as e:
print(f"❌ Error checking Grafana datasource: {e}")
return False
def write_timestamp_correction_data():
"""Write data with corrected timestamps"""
print("\n===== WRITING TIMESTAMP CORRECTED DATA =====")
try:
client = InfluxDBClient(url=INFLUX_URL, token=INFLUX_TOKEN, org=INFLUX_ORG)
write_api = client.write_api(write_options=SYNCHRONOUS)
# Current time
now = datetime.utcnow()
# Write data for the last 15 minutes with correct timestamps
for i in range(15):
# Calculate timestamp (going backwards from now to 15 minutes ago)
timestamp = now - timedelta(minutes=i)
# Create points
perf_point = Point("performance") \
.tag("camera_id", "timestamp_fixed") \
.field("fps", 30.0 - i*0.5) \
.field("processing_time_ms", 40.0 + i) \
.time(timestamp)
# Write the point
write_api.write(bucket=INFLUX_BUCKET, org=INFLUX_ORG, record=perf_point)
print(f"Written timestamp-corrected data point {i+1}/15 at {timestamp}")
print("✅ Wrote 15 data points with corrected timestamps")
return True
except Exception as e:
print(f"❌ Error writing timestamp-corrected data: {e}")
return False
def force_recreate_datasource():
"""Delete and recreate the InfluxDB datasource"""
print("\n===== FORCE RECREATING INFLUXDB DATASOURCE =====")
try:
# Get existing datasources
response = requests.get(
f"{GRAFANA_URL}/api/datasources",
auth=(GRAFANA_USER, GRAFANA_PASSWORD)
)
if response.status_code != 200:
print(f"❌ Failed to get Grafana datasources: {response.status_code}")
print(f"Response: {response.text}")
return False
datasources = response.json()
influx_ds = None
for ds in datasources:
if "influx" in ds["type"].lower():
influx_ds = ds
break
# Delete existing datasource if found
if influx_ds:
print(f"Deleting existing datasource: {influx_ds.get('name')}")
response = requests.delete(
f"{GRAFANA_URL}/api/datasources/{influx_ds.get('id')}",
auth=(GRAFANA_USER, GRAFANA_PASSWORD)
)
if response.status_code != 200:
print(f"❌ Failed to delete datasource: {response.status_code}")
print(f"Response: {response.text}")
# Create new datasource
new_ds = {
"name": "InfluxDB_Fixed",
"type": "influxdb",
"url": INFLUX_URL,
"access": "proxy",
"basicAuth": False,
"isDefault": True,
"jsonData": {
"defaultBucket": INFLUX_BUCKET,
"organization": INFLUX_ORG,
"version": "Flux",
"timeInterval": "10s"
},
"secureJsonData": {
"token": INFLUX_TOKEN
}
}
response = requests.post(
f"{GRAFANA_URL}/api/datasources",
auth=(GRAFANA_USER, GRAFANA_PASSWORD),
headers={"Content-Type": "application/json"},
data=json.dumps(new_ds)
)
if response.status_code == 200:
print("✅ New datasource created successfully")
return True
else:
print(f"❌ Failed to create new datasource: {response.status_code}")
print(f"Response: {response.text}")
return False
except Exception as e:
print(f"❌ Error recreating datasource: {e}")
return False
def create_minimal_dashboard():
"""Create an extremely minimal dashboard with basic queries"""
print("\n===== CREATING MINIMAL TEST DASHBOARD =====")
try:
# Get data source ID
response = requests.get(
f"{GRAFANA_URL}/api/datasources",
auth=(GRAFANA_USER, GRAFANA_PASSWORD)
)
if response.status_code != 200:
print(f"❌ Failed to get datasources: {response.status_code}")
return False
datasources = response.json()
influx_ds = None
for ds in datasources:
if "influx" in ds["type"].lower():
influx_ds = ds
break
if not influx_ds:
print("❌ No InfluxDB datasource found")
return False
# Create minimal dashboard
dashboard = {
"dashboard": {
"id": None,
"uid": "minimal-test",
"title": "MINIMAL TEST - Timestamp Fixed",
"tags": ["test"],
"timezone": "browser",
"refresh": "5s",
"time": {
"from": "now-15m",
"to": "now"
},
"panels": [
{
"id": 1,
"title": "Minimal FPS Test",
"type": "timeseries",
"gridPos": {"h": 8, "w": 24, "x": 0, "y": 0},
"datasource": {
"type": influx_ds["type"],
"uid": influx_ds["uid"]
},
"fieldConfig": {
"defaults": {
"custom": {
"drawStyle": "line",
"lineInterpolation": "linear",
"fillOpacity": 10
}
}
},
"options": {
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"refId": "A",
"datasource": {
"type": influx_ds["type"],
"uid": influx_ds["uid"]
},
"query": f'from(bucket: "{INFLUX_BUCKET}")\n |> range(start: -15m)\n |> filter(fn: (r) => r._measurement == "performance")\n |> filter(fn: (r) => r._field == "fps")\n |> aggregateWindow(every: 10s, fn: mean, createEmpty: false)',
"hide": False
}
]
}
]
},
"overwrite": True,
"message": "Created minimal test dashboard"
}
response = requests.post(
f"{GRAFANA_URL}/api/dashboards/db",
auth=(GRAFANA_USER, GRAFANA_PASSWORD),
headers={"Content-Type": "application/json"},
data=json.dumps(dashboard)
)
if response.status_code == 200:
result = response.json()
dashboard_url = f"{GRAFANA_URL}/d/{result['uid']}"
print(f"✅ Minimal dashboard created: {dashboard_url}")
print(f"👉 Please open this URL in your browser: {dashboard_url}")
return True
else:
print(f"❌ Failed to create dashboard: {response.status_code}")
print(f"Response: {response.text}")
return False
except Exception as e:
print(f"❌ Error creating minimal dashboard: {e}")
return False
if __name__ == "__main__":
print("===== ADVANCED GRAFANA-INFLUXDB DIAGNOSTICS AND REPAIR =====")
# Check service status
print("\n===== CHECKING SERVICE STATUS =====")
influx_running = check_service_status("influxd")
grafana_running = check_service_status("grafana")
if not influx_running or not grafana_running:
print("⚠️ One or more required services not running. Cannot proceed with diagnostics.")
sys.exit(1)
# Test InfluxDB connection and check data
influx_connected = test_influxdb_connection()
data_exists = check_influx_data()
# Check Grafana datasource
ds_ok = check_grafana_datasource()
# If datasource has issues, force recreate it
if not ds_ok:
print("⚠️ Datasource has issues. Attempting to recreate it...")
force_recreate_datasource()
# Write timestamp-corrected data
write_timestamp_correction_data()
# Create minimal dashboard
create_minimal_dashboard()
print("\n===== SUMMARY =====")
print(f"InfluxDB Running: {'' if influx_running else ''}")
print(f"Grafana Running: {'' if grafana_running else ''}")
print(f"InfluxDB Connection: {'' if influx_connected else ''}")
print(f"Data Exists in InfluxDB: {'' if data_exists else ''}")
print(f"Datasource Configuration: {'' if ds_ok else '🔄 Attempted repair'}")
print("\nTroubleshooting Instructions:")
print("1. Check the minimal test dashboard URL provided above")
print("2. Ensure browser cache is cleared or try in private/incognito mode")
print("3. If still no data, restart both Grafana and InfluxDB services")
print("4. Check if your firewall is blocking localhost connections")
print("5. Try changing the time range in the Grafana dashboard")
print("6. Check your system time and timezone settings - InfluxDB is time-sensitive")
print("7. Look for errors in the Grafana and InfluxDB log files")
print("8. If needed, restart your computer and try again")