Commit
Β·
620e5bd
1
Parent(s):
9864381
Update app/streamlit_app.py
Browse files- app/streamlit_app.py +124 -4
app/streamlit_app.py
CHANGED
@@ -211,6 +211,41 @@ class StreamlitAppManager:
|
|
211 |
return None
|
212 |
|
213 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
214 |
# Initialize app manager
|
215 |
app_manager = StreamlitAppManager()
|
216 |
|
@@ -297,7 +332,9 @@ def show_logs_section():
|
|
297 |
"Scheduler Log": path_manager.get_logs_path("scheduler_execution.json"),
|
298 |
"Drift History": path_manager.get_logs_path("drift_history.json"),
|
299 |
"Drift Alerts": path_manager.get_logs_path("drift_alerts.json"),
|
300 |
-
"
|
|
|
|
|
301 |
}
|
302 |
|
303 |
col1, col2 = st.columns([2, 1])
|
@@ -984,15 +1021,17 @@ def main():
|
|
984 |
'<div class="error-message">π΄ API Service: Offline</div>', unsafe_allow_html=True)
|
985 |
|
986 |
# Main content area
|
987 |
-
tab1, tab2, tab3, tab4, tab5, tab6 = st.tabs([
|
988 |
"π Prediction",
|
989 |
-
"π Batch Analysis",
|
990 |
"π Analytics",
|
991 |
"π― Model Training",
|
992 |
"π Logs",
|
993 |
-
"βοΈ System Status"
|
|
|
994 |
])
|
995 |
|
|
|
996 |
# Tab 1: Individual Prediction
|
997 |
with tab1:
|
998 |
st.header("Single Text Analysis")
|
@@ -1503,6 +1542,19 @@ def main():
|
|
1503 |
with tab6:
|
1504 |
render_system_status()
|
1505 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1506 |
def render_system_status():
|
1507 |
"""Render system status tab"""
|
1508 |
st.header("System Status & Monitoring")
|
@@ -1604,6 +1656,74 @@ def render_system_status():
|
|
1604 |
else:
|
1605 |
st.warning("No model metadata available")
|
1606 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1607 |
|
1608 |
# Auto-refresh logic
|
1609 |
if st.session_state.auto_refresh:
|
|
|
211 |
return None
|
212 |
|
213 |
|
214 |
+
def get_monitoring_metrics_from_api(self):
|
215 |
+
"""Get current monitoring metrics from API"""
|
216 |
+
try:
|
217 |
+
if not self.api_available:
|
218 |
+
return None
|
219 |
+
response = self.session.get(f"{self.config['api_url']}/monitor/metrics/current", timeout=10)
|
220 |
+
return response.json() if response.status_code == 200 else None
|
221 |
+
except Exception as e:
|
222 |
+
logger.warning(f"Could not fetch monitoring metrics: {e}")
|
223 |
+
return None
|
224 |
+
|
225 |
+
def get_monitoring_alerts_from_api(self):
|
226 |
+
"""Get monitoring alerts from API"""
|
227 |
+
try:
|
228 |
+
if not self.api_available:
|
229 |
+
return None
|
230 |
+
response = self.session.get(f"{self.config['api_url']}/monitor/alerts", timeout=10)
|
231 |
+
return response.json() if response.status_code == 200 else None
|
232 |
+
except Exception as e:
|
233 |
+
logger.warning(f"Could not fetch monitoring alerts: {e}")
|
234 |
+
return None
|
235 |
+
|
236 |
+
def get_prediction_patterns_from_api(self, hours: int = 24):
|
237 |
+
"""Get prediction patterns from API"""
|
238 |
+
try:
|
239 |
+
if not self.api_available:
|
240 |
+
return None
|
241 |
+
response = self.session.get(f"{self.config['api_url']}/monitor/patterns?hours={hours}", timeout=10)
|
242 |
+
return response.json() if response.status_code == 200 else None
|
243 |
+
except Exception as e:
|
244 |
+
logger.warning(f"Could not fetch prediction patterns: {e}")
|
245 |
+
return None
|
246 |
+
|
247 |
+
|
248 |
+
|
249 |
# Initialize app manager
|
250 |
app_manager = StreamlitAppManager()
|
251 |
|
|
|
332 |
"Scheduler Log": path_manager.get_logs_path("scheduler_execution.json"),
|
333 |
"Drift History": path_manager.get_logs_path("drift_history.json"),
|
334 |
"Drift Alerts": path_manager.get_logs_path("drift_alerts.json"),
|
335 |
+
"Prediction Monitor": path_manager.get_logs_path("monitor/predictions.json"),
|
336 |
+
"Metrics Log": path_manager.get_logs_path("monitor/metrics.json"),
|
337 |
+
"Alerts Log": path_manager.get_logs_path("monitor/alerts.json")
|
338 |
}
|
339 |
|
340 |
col1, col2 = st.columns([2, 1])
|
|
|
1021 |
'<div class="error-message">π΄ API Service: Offline</div>', unsafe_allow_html=True)
|
1022 |
|
1023 |
# Main content area
|
1024 |
+
tab1, tab2, tab3, tab4, tab5, tab6, tab7 = st.tabs([
|
1025 |
"π Prediction",
|
1026 |
+
"π Batch Analysis",
|
1027 |
"π Analytics",
|
1028 |
"π― Model Training",
|
1029 |
"π Logs",
|
1030 |
+
"βοΈ System Status",
|
1031 |
+
"π Monitoring" # New monitoring tab
|
1032 |
])
|
1033 |
|
1034 |
+
|
1035 |
# Tab 1: Individual Prediction
|
1036 |
with tab1:
|
1037 |
st.header("Single Text Analysis")
|
|
|
1542 |
with tab6:
|
1543 |
render_system_status()
|
1544 |
|
1545 |
+
# Tab 7: Monitoring
|
1546 |
+
with tab7:
|
1547 |
+
st.header("Real-time System Monitoring")
|
1548 |
+
|
1549 |
+
col1, col2 = st.columns([1, 1])
|
1550 |
+
with col1:
|
1551 |
+
if st.button("π Refresh Monitoring", use_container_width=True):
|
1552 |
+
st.rerun()
|
1553 |
+
|
1554 |
+
render_monitoring_dashboard()
|
1555 |
+
st.divider()
|
1556 |
+
render_monitoring_alerts()
|
1557 |
+
|
1558 |
def render_system_status():
|
1559 |
"""Render system status tab"""
|
1560 |
st.header("System Status & Monitoring")
|
|
|
1656 |
else:
|
1657 |
st.warning("No model metadata available")
|
1658 |
|
1659 |
+
def render_monitoring_dashboard():
|
1660 |
+
"""Render real-time monitoring dashboard"""
|
1661 |
+
st.subheader("π Real-time Monitoring Dashboard")
|
1662 |
+
|
1663 |
+
monitoring_data = app_manager.get_monitoring_metrics_from_api()
|
1664 |
+
|
1665 |
+
if monitoring_data:
|
1666 |
+
# Current metrics display
|
1667 |
+
col1, col2, col3, col4 = st.columns(4)
|
1668 |
+
|
1669 |
+
pred_metrics = monitoring_data.get('prediction_metrics', {})
|
1670 |
+
system_metrics = monitoring_data.get('system_metrics', {})
|
1671 |
+
api_metrics = monitoring_data.get('api_metrics', {})
|
1672 |
+
|
1673 |
+
with col1:
|
1674 |
+
st.metric("Predictions/Min", f"{pred_metrics.get('predictions_per_minute', 0):.1f}")
|
1675 |
+
st.metric("Avg Confidence", f"{pred_metrics.get('avg_confidence', 0):.2f}")
|
1676 |
+
|
1677 |
+
with col2:
|
1678 |
+
st.metric("Response Time", f"{api_metrics.get('avg_response_time', 0):.2f}s")
|
1679 |
+
st.metric("Error Rate", f"{api_metrics.get('error_rate', 0):.1%}")
|
1680 |
+
|
1681 |
+
with col3:
|
1682 |
+
st.metric("CPU Usage", f"{system_metrics.get('cpu_percent', 0):.1f}%")
|
1683 |
+
st.metric("Memory Usage", f"{system_metrics.get('memory_percent', 0):.1f}%")
|
1684 |
+
|
1685 |
+
with col4:
|
1686 |
+
anomaly_score = pred_metrics.get('anomaly_score', 0)
|
1687 |
+
st.metric("Anomaly Score", f"{anomaly_score:.3f}")
|
1688 |
+
if anomaly_score > 0.3:
|
1689 |
+
st.warning("High anomaly score detected!")
|
1690 |
+
else:
|
1691 |
+
st.warning("Monitoring data not available")
|
1692 |
+
|
1693 |
+
def render_monitoring_alerts():
|
1694 |
+
"""Render monitoring alerts section"""
|
1695 |
+
st.subheader("π¨ Active Alerts")
|
1696 |
+
|
1697 |
+
alerts_data = app_manager.get_monitoring_alerts_from_api()
|
1698 |
+
|
1699 |
+
if alerts_data:
|
1700 |
+
active_alerts = alerts_data.get('active_alerts', [])
|
1701 |
+
alert_stats = alerts_data.get('alert_statistics', {})
|
1702 |
+
|
1703 |
+
# Alert statistics
|
1704 |
+
col1, col2, col3 = st.columns(3)
|
1705 |
+
with col1:
|
1706 |
+
st.metric("Active Alerts", alert_stats.get('active_alerts', 0))
|
1707 |
+
with col2:
|
1708 |
+
st.metric("Critical Alerts", alert_stats.get('critical_alerts_active', 0))
|
1709 |
+
with col3:
|
1710 |
+
st.metric("24h Alert Rate", f"{alert_stats.get('alert_rate_per_hour', 0):.1f}/hr")
|
1711 |
+
|
1712 |
+
# Active alerts display
|
1713 |
+
if active_alerts:
|
1714 |
+
for alert in active_alerts:
|
1715 |
+
alert_type = alert.get('type', 'info')
|
1716 |
+
if alert_type == 'critical':
|
1717 |
+
st.error(f"π΄ **{alert.get('title', 'Unknown')}**: {alert.get('message', '')}")
|
1718 |
+
elif alert_type == 'warning':
|
1719 |
+
st.warning(f"π‘ **{alert.get('title', 'Unknown')}**: {alert.get('message', '')}")
|
1720 |
+
else:
|
1721 |
+
st.info(f"π΅ **{alert.get('title', 'Unknown')}**: {alert.get('message', '')}")
|
1722 |
+
else:
|
1723 |
+
st.success("No active alerts")
|
1724 |
+
else:
|
1725 |
+
st.warning("Alert data not available")
|
1726 |
+
|
1727 |
|
1728 |
# Auto-refresh logic
|
1729 |
if st.session_state.auto_refresh:
|