Spaces:
Runtime error
Runtime error
import os | |
import time | |
import requests | |
import json | |
import logging | |
from typing import Dict, Any | |
# Set up logging | |
logging.basicConfig( | |
level=logging.INFO, | |
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' | |
) | |
logger = logging.getLogger(__name__) | |
class GrafanaInitializer: | |
def __init__(self): | |
self.grafana_url = os.getenv('GRAFANA_URL', 'http://localhost:3000') | |
self.grafana_user = os.getenv('GRAFANA_ADMIN_USER', 'admin') | |
self.grafana_password = os.getenv('GRAFANA_ADMIN_PASSWORD', 'admin') | |
self.postgres_host = os.getenv('POSTGRES_HOST', 'postgres') | |
self.postgres_port = os.getenv('POSTGRES_PORT', '5432') | |
self.postgres_db = os.getenv('POSTGRES_DB', 'mental_health') | |
self.postgres_user = os.getenv('POSTGRES_USER', 'newton') | |
self.postgres_password = os.getenv('POSTGRES_PASSWORD', 'Admin') | |
self.headers = { | |
'Content-Type': 'application/json', | |
'Accept': 'application/json', | |
} | |
self.session = requests.Session() | |
self.session.auth = (self.grafana_user, self.grafana_password) | |
def wait_for_grafana(self, max_retries: int = 30, delay: int = 5) -> bool: | |
"""Wait for Grafana to become available.""" | |
for i in range(max_retries): | |
try: | |
response = self.session.get(f"{self.grafana_url}/api/health") | |
if response.status_code == 200: | |
logger.info("Grafana is available") | |
return True | |
except requests.exceptions.RequestException: | |
pass | |
logger.info(f"Waiting for Grafana to become available (attempt {i + 1}/{max_retries})") | |
time.sleep(delay) | |
return False | |
def setup_datasource(self) -> None: | |
"""Configure PostgreSQL as a data source.""" | |
datasource_config = { | |
"name": "PostgreSQL", | |
"type": "postgres", | |
"url": f"{self.postgres_host}:{self.postgres_port}", | |
"access": "proxy", | |
"basicAuth": False, | |
"database": self.postgres_db, | |
"user": self.postgres_user, | |
"secureJsonData": { | |
"password": self.postgres_password | |
}, | |
"jsonData": { | |
"sslmode": "disable", | |
"maxOpenConns": 100, | |
"maxIdleConns": 100, | |
"connMaxLifetime": 14400, | |
"postgresVersion": 1300, | |
"timescaledb": False | |
} | |
} | |
response = self.session.post( | |
f"{self.grafana_url}/api/datasources", | |
json=datasource_config | |
) | |
if response.status_code == 200: | |
logger.info("PostgreSQL datasource configured successfully") | |
else: | |
logger.error(f"Failed to configure datasource: {response.text}") | |
def create_dashboards(self) -> None: | |
"""Initialize Grafana dashboards for system monitoring.""" | |
# System Performance Dashboard | |
performance_dashboard = { | |
"dashboard": { | |
"title": "Mental Health Assistant Performance", | |
"timezone": "browser", | |
"panels": [ | |
# Response Time Panel | |
{ | |
"title": "Average Response Time", | |
"type": "graph", | |
"gridPos": {"h": 8, "w": 12, "x": 0, "y": 0}, | |
"targets": [{ | |
"rawSql": """ | |
SELECT | |
timestamp as time, | |
avg(response_time) as "Response Time" | |
FROM conversations | |
WHERE $__timeFilter(timestamp) | |
GROUP BY timestamp | |
ORDER BY timestamp | |
""", | |
"format": "time_series" | |
}] | |
}, | |
# Model Usage Panel | |
{ | |
"title": "Model Usage Distribution", | |
"type": "piechart", | |
"gridPos": {"h": 8, "w": 12, "x": 12, "y": 0}, | |
"targets": [{ | |
"rawSql": """ | |
SELECT | |
model_used as metric, | |
count(*) as value | |
FROM conversations | |
WHERE $__timeFilter(timestamp) | |
GROUP BY model_used | |
""" | |
}] | |
}, | |
# Token Usage Panel | |
{ | |
"title": "Average Token Usage", | |
"type": "graph", | |
"gridPos": {"h": 8, "w": 12, "x": 0, "y": 8}, | |
"targets": [{ | |
"rawSql": """ | |
SELECT | |
timestamp as time, | |
avg(total_tokens) as "Total Tokens", | |
avg(prompt_tokens) as "Prompt Tokens", | |
avg(completion_tokens) as "Completion Tokens" | |
FROM conversations | |
WHERE $__timeFilter(timestamp) | |
GROUP BY timestamp | |
ORDER BY timestamp | |
""", | |
"format": "time_series" | |
}] | |
} | |
], | |
"refresh": "5s" | |
} | |
} | |
# User Feedback Dashboard | |
feedback_dashboard = { | |
"dashboard": { | |
"title": "User Feedback Analysis", | |
"timezone": "browser", | |
"panels": [ | |
# Feedback Distribution | |
{ | |
"title": "Feedback Distribution", | |
"type": "stat", | |
"gridPos": {"h": 8, "w": 12, "x": 0, "y": 0}, | |
"targets": [{ | |
"rawSql": """ | |
SELECT | |
sum(case when feedback > 0 then 1 else 0 end) as "Positive", | |
sum(case when feedback < 0 then 1 else 0 end) as "Negative" | |
FROM feedback | |
WHERE $__timeFilter(timestamp) | |
""" | |
}] | |
}, | |
# Relevance Distribution | |
{ | |
"title": "Answer Relevance Distribution", | |
"type": "piechart", | |
"gridPos": {"h": 8, "w": 12, "x": 12, "y": 0}, | |
"targets": [{ | |
"rawSql": """ | |
SELECT | |
relevance as metric, | |
count(*) as value | |
FROM conversations | |
WHERE $__timeFilter(timestamp) | |
GROUP BY relevance | |
""" | |
}] | |
}, | |
# Feedback Timeline | |
{ | |
"title": "Feedback Timeline", | |
"type": "graph", | |
"gridPos": {"h": 8, "w": 24, "x": 0, "y": 8}, | |
"targets": [{ | |
"rawSql": """ | |
SELECT | |
date_trunc('hour', timestamp) as time, | |
count(*) FILTER (WHERE feedback > 0) as "Positive", | |
count(*) FILTER (WHERE feedback < 0) as "Negative" | |
FROM feedback | |
WHERE $__timeFilter(timestamp) | |
GROUP BY date_trunc('hour', timestamp) | |
ORDER BY time | |
""", | |
"format": "time_series" | |
}] | |
} | |
], | |
"refresh": "5s" | |
} | |
} | |
# Create dashboards | |
for dashboard in [performance_dashboard, feedback_dashboard]: | |
response = self.session.post( | |
f"{self.grafana_url}/api/dashboards/db", | |
json=dashboard | |
) | |
if response.status_code == 200: | |
logger.info(f"Dashboard '{dashboard['dashboard']['title']}' created successfully") | |
else: | |
logger.error(f"Failed to create dashboard: {response.text}") | |
def main(): | |
initializer = GrafanaInitializer() | |
# Wait for Grafana to become available | |
if not initializer.wait_for_grafana(): | |
logger.error("Grafana is not available after maximum retries") | |
return | |
# Set up data source and dashboards | |
try: | |
initializer.setup_datasource() | |
initializer.create_dashboards() | |
logger.info("Grafana initialization completed successfully") | |
except Exception as e: | |
logger.error(f"Failed to initialize Grafana: {str(e)}") | |
if __name__ == "__main__": | |
main() |