Team Ai
Apppublic

javitechjkd/backtestingv2

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
monitoring_dashboard.py213 linesDownload Raw Back to ui
1"""2Dashboard de Monitoreo - Fase 53Visualización de logs y métricas en Streamlit4"""5 6import streamlit as st7from datetime import datetime, timedelta8import sys9from pathlib import Path10import json11 12# Add parent directory for imports13sys.path.insert(0, str(Path(__file__).parent.parent))14 15from backtesting_app.core.logger import get_logger, OperationType16 17 18def render_monitoring_dashboard():19    """Renderiza el dashboard de monitoreo"""20    21    st.markdown("## 📊 Dashboard de Monitoreo")22    st.write("Visualiza logs de operaciones y estadísticas de rendimiento en tiempo real")23    24    # Obtener logger25    logger = get_logger()26    27    # Tabs28    tab1, tab2, tab3 = st.tabs(["📈 Resumen Hoy", "📊 Estadísticas Globales", "📋 Logs Detallados"])29    30    with tab1:31        st.markdown("### Operaciones de Hoy")32        33        # Resumen general34        col1, col2, col3, col4 = st.columns(4)35        36        summary = logger.get_operations_summary()37        38        with col1:39            st.metric(40                "📊 Total Ops",41                summary['total_operations'],42                delta=None,43                label_visibility="visible"44            )45        46        with col2:47            st.metric(48                "✅ Exitosas",49                summary['successful'],50                delta=None,51                label_visibility="visible"52            )53        54        with col3:55            st.metric(56                "❌ Fallidas",57                summary['failed'],58                delta=None,59                label_visibility="visible"60            )61        62        with col4:63            if summary['total_operations'] > 0:64                success_rate = (summary['successful'] / summary['total_operations']) * 10065                st.metric(66                    "📈 Tasa Éxito",67                    f"{success_rate:.1f}%",68                    delta=None,69                    label_visibility="visible"70                )71            else:72                st.metric(73                    "📈 Tasa Éxito",74                    "N/A",75                    delta=None,76                    label_visibility="visible"77                )78        79        st.divider()80        81        # Desglose por tipo de operación82        st.markdown("### Por Tipo de Operación")83        84        # Obtener resumen por cada tipo85        op_summary = {}86        for op_type in OperationType:87            summary = logger.get_operations_summary(op_type)88            if summary['total_operations'] > 0:89                op_summary[op_type.value] = summary90        91        if op_summary:92            cols = st.columns(len(op_summary))93            94            for col, (op_type, summary) in zip(cols, op_summary.items()):95                with col:96                    st.markdown(f"**{op_type}**")97                    st.write(f"Total: {summary['total_operations']}")98                    st.write(f"✅ {summary['successful']} exitosas")99                    st.write(f"❌ {summary['failed']} fallidas")100                    if summary['total_operations'] > 0:101                        st.write(f"⏱️ {summary['avg_duration']:.2f}s promedio")102        else:103            st.info("No hay operaciones registradas hoy")104    105    with tab2:106        st.markdown("### Estadísticas Globales")107        108        stats = logger.get_performance_stats()109        110        if stats:111            st.markdown("#### Resumen por Tipo de Operación")112            113            # Tabla de estadísticas114            data = []115            for op_type, stat in stats.items():116                data.append({117                    "Operación": op_type,118                    "Cantidad": stat['count'],119                    "Min (s)": f"{stat['min_duration']:.3f}",120                    "Max (s)": f"{stat['max_duration']:.3f}",121                    "Promedio (s)": f"{stat['avg_duration']:.3f}",122                    "Éxito %": f"{stat['success_rate']:.1f}%"123                })124            125            st.dataframe(126                data,127                use_container_width=True,128                hide_index=True129            )130        else:131            st.info("No hay estadísticas disponibles")132    133    with tab3:134        st.markdown("### Logs Detallados")135        136        # Filtros137        col1, col2, col3 = st.columns(3)138        139        with col1:140            operation_filter = st.selectbox(141                "Filtrar por tipo de operación",142                options=["Todas"] + [op.value for op in OperationType],143                index=0144            )145        146        with col2:147            log_limit = st.slider(148                "Mostrar últimos N logs",149                min_value=5,150                max_value=100,151                value=20,152                step=5153            )154        155        with col3:156            st.empty()157        158        # Aplicar filtros159        filtered_logs = logger.json_logs[-log_limit:]160        161        if operation_filter != "Todas":162            filtered_logs = [163                log for log in filtered_logs164                if log.get('operation_type') == operation_filter165            ]166        167        if filtered_logs:168            # Mostrar logs en orden reverso (más recientes primero)169            for log in reversed(filtered_logs):170                timestamp = log.get('timestamp', 'N/A')171                op_type = log.get('operation_type', log.get('level', 'EVENT'))172                status = log.get('status', log.get('level', 'INFO'))173                174                # Emoji basado en el estado175                if status == 'success':176                    emoji = "✅"177                elif status == 'error':178                    emoji = "❌"179                else:180                    emoji = "📝"181                182                # Expandible con detalles183                with st.expander(184                    f"{emoji} {op_type} - {timestamp}",185                    expanded=False186                ):187                    st.json(log)188        else:189            st.info("No hay logs que coincidan con los filtros")190        191        # Limpieza de logs antiguos192        st.divider()193        st.markdown("### Mantenimiento")194        195        col1, col2 = st.columns(2)196        197        with col1:198            if st.button("🧹 Limpiar logs > 30 días", use_container_width=True):199                old_count = len(logger.json_logs)200                logger.clear_old_logs(days=30)201                new_count = len(logger.json_logs)202                deleted = old_count - new_count203                204                st.success(f"✅ Eliminados {deleted} logs antiguos")205                st.rerun()206        207        with col2:208            st.metric("📁 Total logs", len(logger.json_logs), label_visibility="visible")209 210 211if __name__ == "__main__":212    render_monitoring_dashboard()213