adonisjs-server-stats 1.5.4 → 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +351 -171
- package/dist/configure.d.ts.map +1 -1
- package/dist/core/api-client.d.ts +73 -0
- package/dist/core/api-client.d.ts.map +1 -0
- package/dist/core/config-utils.d.ts +109 -0
- package/dist/core/config-utils.d.ts.map +1 -0
- package/dist/core/constants.d.ts +11 -0
- package/dist/core/constants.d.ts.map +1 -0
- package/dist/core/dashboard-api.d.ts +65 -0
- package/dist/core/dashboard-api.d.ts.map +1 -0
- package/dist/core/dashboard-data-controller.d.ts +157 -0
- package/dist/core/dashboard-data-controller.d.ts.map +1 -0
- package/dist/core/debug-data-controller.d.ts +89 -0
- package/dist/core/debug-data-controller.d.ts.map +1 -0
- package/dist/core/feature-detect.d.ts +67 -0
- package/dist/core/feature-detect.d.ts.map +1 -0
- package/dist/core/formatters.d.ts +189 -0
- package/dist/core/formatters.d.ts.map +1 -0
- package/dist/core/history-buffer.d.ts +23 -0
- package/dist/core/history-buffer.d.ts.map +1 -0
- package/dist/core/icons.d.ts +36 -0
- package/dist/core/icons.d.ts.map +1 -0
- package/dist/core/index.d.ts +39 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +1961 -0
- package/dist/core/internals-utils.d.ts +71 -0
- package/dist/core/internals-utils.d.ts.map +1 -0
- package/dist/core/job-utils.d.ts +45 -0
- package/dist/core/job-utils.d.ts.map +1 -0
- package/dist/core/log-utils.d.ts +34 -0
- package/dist/core/log-utils.d.ts.map +1 -0
- package/dist/core/metrics.d.ts +41 -0
- package/dist/core/metrics.d.ts.map +1 -0
- package/dist/core/pagination.d.ts +128 -0
- package/dist/core/pagination.d.ts.map +1 -0
- package/dist/core/query-utils.d.ts +35 -0
- package/dist/core/query-utils.d.ts.map +1 -0
- package/dist/core/resizable-columns.d.ts +18 -0
- package/dist/core/resizable-columns.d.ts.map +1 -0
- package/dist/core/routes.d.ts +12 -0
- package/dist/core/routes.d.ts.map +1 -0
- package/dist/core/server-stats-controller.d.ts +106 -0
- package/dist/core/server-stats-controller.d.ts.map +1 -0
- package/dist/core/sparkline.d.ts +80 -0
- package/dist/core/sparkline.d.ts.map +1 -0
- package/dist/core/theme.d.ts +42 -0
- package/dist/core/theme.d.ts.map +1 -0
- package/dist/core/trace-utils.d.ts +62 -0
- package/dist/core/trace-utils.d.ts.map +1 -0
- package/dist/core/transmit-adapter.d.ts +59 -0
- package/dist/core/transmit-adapter.d.ts.map +1 -0
- package/dist/core/types.d.ts +619 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/react/CacheSection-DGxMDlWK.js +146 -0
- package/dist/react/CacheTab-CnVW5PLs.js +123 -0
- package/dist/react/ConfigContent-CnsEI4j3.js +397 -0
- package/dist/react/ConfigSection-DPcrfqXY.js +11 -0
- package/dist/react/ConfigTab-BSWq_o2p.js +15 -0
- package/dist/react/CustomPaneTab-xjkYwTvH.js +104 -0
- package/dist/react/DataTable-YyShr5B-.js +55 -0
- package/dist/react/EmailsSection-CSyTg1aX.js +262 -0
- package/dist/react/EmailsTab-Dh2YSa_f.js +131 -0
- package/dist/react/EventsSection-C1pbJDfW.js +86 -0
- package/dist/react/EventsTab-eCh02cdd.js +63 -0
- package/dist/react/FilterBar-DQRXpWrb.js +50 -0
- package/dist/react/InternalsContent-DBzsI0CG.js +346 -0
- package/dist/react/InternalsSection-t7ihcWO-.js +32 -0
- package/dist/react/InternalsTab-Oij0A2fN.js +30 -0
- package/dist/react/JobsSection-CLAin5vU.js +187 -0
- package/dist/react/JobsTab-Dl5nrj2z.js +141 -0
- package/dist/react/LogsSection-C1p81fXO.js +212 -0
- package/dist/react/LogsTab-D-kR7PjX.js +88 -0
- package/dist/react/OverviewSection-nm3xdACz.js +539 -0
- package/dist/react/Pagination-BkmzUDY8.js +64 -0
- package/dist/react/QueriesSection-DB12HMfQ.js +461 -0
- package/dist/react/QueriesTab-fyBB1u_Y.js +90 -0
- package/dist/react/RequestsSection-DTqB81ac.js +209 -0
- package/dist/react/RoutesSection-DJWa4NPV.js +74 -0
- package/dist/react/RoutesTab-D3l8TOpu.js +74 -0
- package/dist/react/TimelineSection-C4d-jRX1.js +158 -0
- package/dist/react/TimelineTab-C5TFaSmQ.js +193 -0
- package/dist/react/WaterfallChart-Cj73WdfM.js +100 -0
- package/dist/react/core/api-client.d.ts +73 -0
- package/dist/react/core/api-client.d.ts.map +1 -0
- package/dist/react/core/config-utils.d.ts +109 -0
- package/dist/react/core/config-utils.d.ts.map +1 -0
- package/dist/react/core/constants.d.ts +11 -0
- package/dist/react/core/constants.d.ts.map +1 -0
- package/dist/react/core/dashboard-api.d.ts +65 -0
- package/dist/react/core/dashboard-api.d.ts.map +1 -0
- package/dist/react/core/dashboard-data-controller.d.ts +157 -0
- package/dist/react/core/dashboard-data-controller.d.ts.map +1 -0
- package/dist/react/core/debug-data-controller.d.ts +89 -0
- package/dist/react/core/debug-data-controller.d.ts.map +1 -0
- package/dist/react/core/feature-detect.d.ts +67 -0
- package/dist/react/core/feature-detect.d.ts.map +1 -0
- package/dist/react/core/formatters.d.ts +189 -0
- package/dist/react/core/formatters.d.ts.map +1 -0
- package/dist/react/core/history-buffer.d.ts +23 -0
- package/dist/react/core/history-buffer.d.ts.map +1 -0
- package/dist/react/core/icons.d.ts +36 -0
- package/dist/react/core/icons.d.ts.map +1 -0
- package/dist/react/core/index.d.ts +39 -0
- package/dist/react/core/index.d.ts.map +1 -0
- package/dist/react/core/internals-utils.d.ts +71 -0
- package/dist/react/core/internals-utils.d.ts.map +1 -0
- package/dist/react/core/job-utils.d.ts +45 -0
- package/dist/react/core/job-utils.d.ts.map +1 -0
- package/dist/react/core/log-utils.d.ts +34 -0
- package/dist/react/core/log-utils.d.ts.map +1 -0
- package/dist/react/core/metrics.d.ts +41 -0
- package/dist/react/core/metrics.d.ts.map +1 -0
- package/dist/react/core/pagination.d.ts +128 -0
- package/dist/react/core/pagination.d.ts.map +1 -0
- package/dist/react/core/query-utils.d.ts +35 -0
- package/dist/react/core/query-utils.d.ts.map +1 -0
- package/dist/react/core/resizable-columns.d.ts +18 -0
- package/dist/react/core/resizable-columns.d.ts.map +1 -0
- package/dist/react/core/routes.d.ts +12 -0
- package/dist/react/core/routes.d.ts.map +1 -0
- package/dist/react/core/server-stats-controller.d.ts +106 -0
- package/dist/react/core/server-stats-controller.d.ts.map +1 -0
- package/dist/react/core/sparkline.d.ts +80 -0
- package/dist/react/core/sparkline.d.ts.map +1 -0
- package/dist/react/core/theme.d.ts +42 -0
- package/dist/react/core/theme.d.ts.map +1 -0
- package/dist/react/core/trace-utils.d.ts +62 -0
- package/dist/react/core/trace-utils.d.ts.map +1 -0
- package/dist/react/core/transmit-adapter.d.ts +59 -0
- package/dist/react/core/transmit-adapter.d.ts.map +1 -0
- package/dist/react/core/types.d.ts +619 -0
- package/dist/react/core/types.d.ts.map +1 -0
- package/dist/react/index-UdTfSvtO.js +1074 -0
- package/dist/react/index.js +18 -0
- package/dist/react/react/components/Dashboard/DashboardPage.d.ts +17 -0
- package/dist/react/react/components/Dashboard/DashboardPage.d.ts.map +1 -0
- package/dist/react/react/components/Dashboard/sections/CacheSection.d.ts +7 -0
- package/dist/react/react/components/Dashboard/sections/CacheSection.d.ts.map +1 -0
- package/dist/react/react/components/Dashboard/sections/ConfigSection.d.ts +7 -0
- package/dist/react/react/components/Dashboard/sections/ConfigSection.d.ts.map +1 -0
- package/dist/react/react/components/Dashboard/sections/EmailsSection.d.ts +7 -0
- package/dist/react/react/components/Dashboard/sections/EmailsSection.d.ts.map +1 -0
- package/dist/react/react/components/Dashboard/sections/EventsSection.d.ts +7 -0
- package/dist/react/react/components/Dashboard/sections/EventsSection.d.ts.map +1 -0
- package/dist/react/react/components/Dashboard/sections/InternalsSection.d.ts +14 -0
- package/dist/react/react/components/Dashboard/sections/InternalsSection.d.ts.map +1 -0
- package/dist/react/react/components/Dashboard/sections/JobsSection.d.ts +7 -0
- package/dist/react/react/components/Dashboard/sections/JobsSection.d.ts.map +1 -0
- package/dist/react/react/components/Dashboard/sections/LogsSection.d.ts +7 -0
- package/dist/react/react/components/Dashboard/sections/LogsSection.d.ts.map +1 -0
- package/dist/react/react/components/Dashboard/sections/OverviewSection.d.ts +7 -0
- package/dist/react/react/components/Dashboard/sections/OverviewSection.d.ts.map +1 -0
- package/dist/react/react/components/Dashboard/sections/QueriesSection.d.ts +7 -0
- package/dist/react/react/components/Dashboard/sections/QueriesSection.d.ts.map +1 -0
- package/dist/react/react/components/Dashboard/sections/RequestsSection.d.ts +7 -0
- package/dist/react/react/components/Dashboard/sections/RequestsSection.d.ts.map +1 -0
- package/dist/react/react/components/Dashboard/sections/RoutesSection.d.ts +7 -0
- package/dist/react/react/components/Dashboard/sections/RoutesSection.d.ts.map +1 -0
- package/dist/react/react/components/Dashboard/sections/TimelineSection.d.ts +9 -0
- package/dist/react/react/components/Dashboard/sections/TimelineSection.d.ts.map +1 -0
- package/dist/react/react/components/Dashboard/shared/DataTable.d.ts +27 -0
- package/dist/react/react/components/Dashboard/shared/DataTable.d.ts.map +1 -0
- package/dist/react/react/components/Dashboard/shared/FilterBar.d.ts +17 -0
- package/dist/react/react/components/Dashboard/shared/FilterBar.d.ts.map +1 -0
- package/dist/react/react/components/Dashboard/shared/Pagination.d.ts +13 -0
- package/dist/react/react/components/Dashboard/shared/Pagination.d.ts.map +1 -0
- package/dist/react/react/components/Dashboard/shared/TimeRangeSelector.d.ts +12 -0
- package/dist/react/react/components/Dashboard/shared/TimeRangeSelector.d.ts.map +1 -0
- package/dist/react/react/components/Dashboard/shared/WaterfallChart.d.ts +16 -0
- package/dist/react/react/components/Dashboard/shared/WaterfallChart.d.ts.map +1 -0
- package/dist/react/react/components/DebugPanel/DebugPanel.d.ts +16 -0
- package/dist/react/react/components/DebugPanel/DebugPanel.d.ts.map +1 -0
- package/dist/react/react/components/DebugPanel/tabs/CacheTab.d.ts +8 -0
- package/dist/react/react/components/DebugPanel/tabs/CacheTab.d.ts.map +1 -0
- package/dist/react/react/components/DebugPanel/tabs/ConfigTab.d.ts +8 -0
- package/dist/react/react/components/DebugPanel/tabs/ConfigTab.d.ts.map +1 -0
- package/dist/react/react/components/DebugPanel/tabs/CustomPaneTab.d.ts +14 -0
- package/dist/react/react/components/DebugPanel/tabs/CustomPaneTab.d.ts.map +1 -0
- package/dist/react/react/components/DebugPanel/tabs/EmailsTab.d.ts +7 -0
- package/dist/react/react/components/DebugPanel/tabs/EmailsTab.d.ts.map +1 -0
- package/dist/react/react/components/DebugPanel/tabs/EventsTab.d.ts +7 -0
- package/dist/react/react/components/DebugPanel/tabs/EventsTab.d.ts.map +1 -0
- package/dist/react/react/components/DebugPanel/tabs/InternalsTab.d.ts +12 -0
- package/dist/react/react/components/DebugPanel/tabs/InternalsTab.d.ts.map +1 -0
- package/dist/react/react/components/DebugPanel/tabs/JobsTab.d.ts +9 -0
- package/dist/react/react/components/DebugPanel/tabs/JobsTab.d.ts.map +1 -0
- package/dist/react/react/components/DebugPanel/tabs/LogsTab.d.ts +7 -0
- package/dist/react/react/components/DebugPanel/tabs/LogsTab.d.ts.map +1 -0
- package/dist/react/react/components/DebugPanel/tabs/QueriesTab.d.ts +7 -0
- package/dist/react/react/components/DebugPanel/tabs/QueriesTab.d.ts.map +1 -0
- package/dist/react/react/components/DebugPanel/tabs/RoutesTab.d.ts +8 -0
- package/dist/react/react/components/DebugPanel/tabs/RoutesTab.d.ts.map +1 -0
- package/dist/react/react/components/DebugPanel/tabs/TimelineTab.d.ts +7 -0
- package/dist/react/react/components/DebugPanel/tabs/TimelineTab.d.ts.map +1 -0
- package/dist/react/react/components/StatsBar/MetricCard.d.ts +21 -0
- package/dist/react/react/components/StatsBar/MetricCard.d.ts.map +1 -0
- package/dist/react/react/components/StatsBar/Sparkline.d.ts +15 -0
- package/dist/react/react/components/StatsBar/Sparkline.d.ts.map +1 -0
- package/dist/react/react/components/StatsBar/StatsBar.d.ts +22 -0
- package/dist/react/react/components/StatsBar/StatsBar.d.ts.map +1 -0
- package/dist/react/react/components/shared/Badge.d.ts +32 -0
- package/dist/react/react/components/shared/Badge.d.ts.map +1 -0
- package/dist/react/react/components/shared/ConfigContent.d.ts +13 -0
- package/dist/react/react/components/shared/ConfigContent.d.ts.map +1 -0
- package/dist/react/react/components/shared/InternalsContent.d.ts +10 -0
- package/dist/react/react/components/shared/InternalsContent.d.ts.map +1 -0
- package/dist/react/react/components/shared/JsonViewer.d.ts +12 -0
- package/dist/react/react/components/shared/JsonViewer.d.ts.map +1 -0
- package/dist/react/react/components/shared/ThemeToggle.d.ts +13 -0
- package/dist/react/react/components/shared/ThemeToggle.d.ts.map +1 -0
- package/dist/react/react/components/shared/Tooltip.d.ts +16 -0
- package/dist/react/react/components/shared/Tooltip.d.ts.map +1 -0
- package/dist/react/react/hooks/useApiClient.d.ts +10 -0
- package/dist/react/react/hooks/useApiClient.d.ts.map +1 -0
- package/dist/react/react/hooks/useDashboardApiBase.d.ts +19 -0
- package/dist/react/react/hooks/useDashboardApiBase.d.ts.map +1 -0
- package/dist/react/react/hooks/useDashboardData.d.ts +27 -0
- package/dist/react/react/hooks/useDashboardData.d.ts.map +1 -0
- package/dist/react/react/hooks/useDebugData.d.ts +17 -0
- package/dist/react/react/hooks/useDebugData.d.ts.map +1 -0
- package/dist/react/react/hooks/useFeatures.d.ts +13 -0
- package/dist/react/react/hooks/useFeatures.d.ts.map +1 -0
- package/dist/react/react/hooks/useResizableTable.d.ts +13 -0
- package/dist/react/react/hooks/useResizableTable.d.ts.map +1 -0
- package/dist/react/react/hooks/useServerStats.d.ts +21 -0
- package/dist/react/react/hooks/useServerStats.d.ts.map +1 -0
- package/dist/react/react/hooks/useTheme.d.ts +12 -0
- package/dist/react/react/hooks/useTheme.d.ts.map +1 -0
- package/dist/react/react/index.d.ts +14 -0
- package/dist/react/react/index.d.ts.map +1 -0
- package/dist/react/style.css +1 -0
- package/dist/react/useApiClient-BVtNCmnL.js +9 -0
- package/dist/react/useDashboardApiBase-Bi36pJ2L.js +14 -0
- package/dist/react/useResizableTable-CNJmACdt.js +13 -0
- package/dist/src/collectors/app_collector.d.ts.map +1 -1
- package/dist/src/collectors/app_collector.js +30 -2
- package/dist/src/collectors/auto_detect.d.ts +31 -0
- package/dist/src/collectors/auto_detect.d.ts.map +1 -0
- package/dist/src/collectors/auto_detect.js +120 -0
- package/dist/src/collectors/collector.d.ts +17 -0
- package/dist/src/collectors/collector.d.ts.map +1 -1
- package/dist/src/collectors/db_pool_collector.d.ts.map +1 -1
- package/dist/src/collectors/db_pool_collector.js +35 -1
- package/dist/src/collectors/http_collector.d.ts +4 -3
- package/dist/src/collectors/http_collector.d.ts.map +1 -1
- package/dist/src/collectors/http_collector.js +28 -11
- package/dist/src/collectors/index.d.ts +2 -0
- package/dist/src/collectors/index.d.ts.map +1 -1
- package/dist/src/collectors/index.js +1 -0
- package/dist/src/collectors/log_collector.d.ts +11 -4
- package/dist/src/collectors/log_collector.d.ts.map +1 -1
- package/dist/src/collectors/log_collector.js +51 -5
- package/dist/src/collectors/process_collector.d.ts.map +1 -1
- package/dist/src/collectors/process_collector.js +4 -0
- package/dist/src/collectors/queue_collector.d.ts.map +1 -1
- package/dist/src/collectors/queue_collector.js +55 -1
- package/dist/src/collectors/redis_collector.d.ts.map +1 -1
- package/dist/src/collectors/redis_collector.js +42 -3
- package/dist/src/collectors/system_collector.d.ts.map +1 -1
- package/dist/src/collectors/system_collector.js +4 -0
- package/dist/src/controller/api_controller.d.ts +101 -0
- package/dist/src/controller/api_controller.d.ts.map +1 -0
- package/dist/src/controller/api_controller.js +131 -0
- package/dist/src/controller/debug_controller.d.ts +19 -10
- package/dist/src/controller/debug_controller.d.ts.map +1 -1
- package/dist/src/controller/debug_controller.js +118 -101
- package/dist/src/core/theme.d.ts +42 -0
- package/dist/src/core/theme.d.ts.map +1 -0
- package/dist/src/core/theme.js +115 -0
- package/dist/src/dashboard/chart_aggregator.d.ts.map +1 -1
- package/dist/src/dashboard/chart_aggregator.js +3 -2
- package/dist/src/dashboard/dashboard_controller.d.ts +10 -14
- package/dist/src/dashboard/dashboard_controller.d.ts.map +1 -1
- package/dist/src/dashboard/dashboard_controller.js +132 -250
- package/dist/src/dashboard/dashboard_store.d.ts +62 -19
- package/dist/src/dashboard/dashboard_store.d.ts.map +1 -1
- package/dist/src/dashboard/dashboard_store.js +242 -53
- package/dist/src/dashboard/integrations/cache_inspector.d.ts +19 -1
- package/dist/src/dashboard/integrations/cache_inspector.d.ts.map +1 -1
- package/dist/src/dashboard/integrations/config_inspector.d.ts +1 -1
- package/dist/src/dashboard/integrations/config_inspector.d.ts.map +1 -1
- package/dist/src/dashboard/integrations/config_inspector.js +3 -2
- package/dist/src/dashboard/integrations/queue_inspector.d.ts +55 -10
- package/dist/src/dashboard/integrations/queue_inspector.d.ts.map +1 -1
- package/dist/src/dashboard/integrations/queue_inspector.js +70 -24
- package/dist/src/dashboard/migrator.d.ts +5 -0
- package/dist/src/dashboard/migrator.d.ts.map +1 -1
- package/dist/src/dashboard/migrator.js +44 -9
- package/dist/src/dashboard/models/stats_event.d.ts +1 -1
- package/dist/src/dashboard/models/stats_event.d.ts.map +1 -1
- package/dist/src/dashboard/models/stats_log.d.ts +1 -1
- package/dist/src/dashboard/models/stats_log.d.ts.map +1 -1
- package/dist/src/dashboard/models/stats_query.d.ts +1 -1
- package/dist/src/dashboard/models/stats_query.d.ts.map +1 -1
- package/dist/src/dashboard/models/stats_saved_filter.d.ts +1 -1
- package/dist/src/dashboard/models/stats_saved_filter.d.ts.map +1 -1
- package/dist/src/dashboard/models/stats_trace.d.ts +2 -1
- package/dist/src/dashboard/models/stats_trace.d.ts.map +1 -1
- package/dist/src/data/data_access.d.ts +105 -0
- package/dist/src/data/data_access.d.ts.map +1 -0
- package/dist/src/data/data_access.js +310 -0
- package/dist/src/data/index.d.ts +3 -0
- package/dist/src/data/index.d.ts.map +1 -0
- package/dist/src/data/index.js +1 -0
- package/dist/src/debug/debug_store.d.ts +20 -1
- package/dist/src/debug/debug_store.d.ts.map +1 -1
- package/dist/src/debug/debug_store.js +43 -15
- package/dist/src/debug/email_collector.d.ts +6 -2
- package/dist/src/debug/email_collector.d.ts.map +1 -1
- package/dist/src/debug/email_collector.js +3 -0
- package/dist/src/debug/event_collector.d.ts +6 -2
- package/dist/src/debug/event_collector.d.ts.map +1 -1
- package/dist/src/debug/event_collector.js +12 -8
- package/dist/src/debug/query_collector.d.ts +6 -2
- package/dist/src/debug/query_collector.d.ts.map +1 -1
- package/dist/src/debug/query_collector.js +3 -0
- package/dist/src/debug/ring_buffer.d.ts +1 -0
- package/dist/src/debug/ring_buffer.d.ts.map +1 -1
- package/dist/src/debug/ring_buffer.js +5 -2
- package/dist/src/debug/route_inspector.d.ts +2 -2
- package/dist/src/debug/route_inspector.d.ts.map +1 -1
- package/dist/src/debug/route_inspector.js +4 -3
- package/dist/src/debug/trace_collector.d.ts +7 -3
- package/dist/src/debug/trace_collector.d.ts.map +1 -1
- package/dist/src/debug/trace_collector.js +7 -5
- package/dist/src/debug/types.d.ts +107 -2
- package/dist/src/debug/types.d.ts.map +1 -1
- package/dist/src/debug/types.js +1 -1
- package/dist/src/define_config.d.ts +49 -5
- package/dist/src/define_config.d.ts.map +1 -1
- package/dist/src/define_config.js +361 -4
- package/dist/src/edge/bootstrap.d.ts +17 -0
- package/dist/src/edge/bootstrap.d.ts.map +1 -0
- package/dist/src/edge/bootstrap.js +29 -0
- package/dist/src/edge/client/dashboard.js +2 -3619
- package/dist/src/edge/client/debug-panel-deferred.js +1 -0
- package/dist/src/edge/client/debug-panel.js +1 -2140
- package/dist/src/edge/client/stats-bar.js +1 -801
- package/dist/src/edge/client-vue/dashboard.js +5 -0
- package/dist/src/edge/client-vue/debug-panel-deferred.js +4 -0
- package/dist/src/edge/client-vue/debug-panel.js +4 -0
- package/dist/src/edge/client-vue/stats-bar.js +4 -0
- package/dist/src/edge/plugin.d.ts +35 -2
- package/dist/src/edge/plugin.d.ts.map +1 -1
- package/dist/src/edge/plugin.js +30 -66
- package/dist/src/edge/types.d.ts +46 -0
- package/dist/src/edge/types.d.ts.map +1 -0
- package/dist/src/edge/types.js +4 -0
- package/dist/src/edge/views/dashboard.edge +1 -358
- package/dist/src/edge/views/debug-panel.edge +2 -154
- package/dist/src/edge/views/stats-bar.edge +15 -48
- package/dist/src/engine/stats_engine.d.ts +18 -0
- package/dist/src/engine/stats_engine.d.ts.map +1 -1
- package/dist/src/engine/stats_engine.js +45 -2
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/log_stream/log_stream_provider.d.ts.map +1 -1
- package/dist/src/log_stream/log_stream_provider.js +21 -4
- package/dist/src/log_stream/log_stream_service.d.ts +8 -1
- package/dist/src/log_stream/log_stream_service.d.ts.map +1 -1
- package/dist/src/log_stream/log_stream_service.js +27 -3
- package/dist/src/middleware/request_tracking_middleware.d.ts +1 -1
- package/dist/src/middleware/request_tracking_middleware.d.ts.map +1 -1
- package/dist/src/middleware/request_tracking_middleware.js +21 -6
- package/dist/src/prometheus/prometheus_collector.d.ts +2 -1
- package/dist/src/prometheus/prometheus_collector.d.ts.map +1 -1
- package/dist/src/provider/server_stats_provider.d.ts +100 -0
- package/dist/src/provider/server_stats_provider.d.ts.map +1 -1
- package/dist/src/provider/server_stats_provider.js +460 -104
- package/dist/src/routes/access_middleware.d.ts +2 -1
- package/dist/src/routes/access_middleware.d.ts.map +1 -1
- package/dist/src/routes/access_middleware.js +7 -1
- package/dist/src/routes/index.d.ts +4 -0
- package/dist/src/routes/index.d.ts.map +1 -0
- package/dist/src/routes/index.js +1 -0
- package/dist/src/routes/register_routes.d.ts +103 -0
- package/dist/src/routes/register_routes.d.ts.map +1 -0
- package/dist/src/routes/register_routes.js +356 -0
- package/dist/src/routes/router_types.d.ts +29 -0
- package/dist/src/routes/router_types.d.ts.map +1 -0
- package/dist/src/routes/router_types.js +1 -0
- package/dist/src/stubs/config.stub +12 -32
- package/dist/src/styles/components.css +1048 -0
- package/dist/src/{edge/client → styles}/dashboard.css +299 -736
- package/dist/src/{edge/client → styles}/debug-panel.css +117 -633
- package/dist/src/{edge/client → styles}/stats-bar.css +28 -10
- package/dist/src/styles/tokens.css +153 -0
- package/dist/src/styles/utilities.css +75 -0
- package/dist/src/types.d.ts +119 -16
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/app_import.d.ts +23 -0
- package/dist/src/utils/app_import.d.ts.map +1 -0
- package/dist/src/utils/app_import.js +44 -0
- package/dist/src/utils/json_helpers.d.ts +2 -2
- package/dist/src/utils/json_helpers.d.ts.map +1 -1
- package/dist/src/utils/logger.d.ts +17 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/src/utils/logger.js +27 -0
- package/dist/src/utils/mail_helpers.d.ts +1 -1
- package/dist/src/utils/mail_helpers.d.ts.map +1 -1
- package/dist/src/utils/mail_helpers.js +1 -1
- package/dist/vue/CacheSection-C788Yfai.js +149 -0
- package/dist/vue/CacheTab-BPisYYiQ.js +104 -0
- package/dist/vue/ConfigSection-CRzYxqW2.js +576 -0
- package/dist/vue/ConfigTab-C8cafGUj.js +361 -0
- package/dist/vue/CustomPaneTab-BJxT5Dp7.js +172 -0
- package/dist/vue/EmailsSection-C8JFMtW7.js +206 -0
- package/dist/vue/EmailsTab-DhFhoNmU.js +157 -0
- package/dist/vue/EventsSection-C4wXUgxG.js +107 -0
- package/dist/vue/EventsTab-DQ4Nd6AK.js +97 -0
- package/dist/vue/FilterBar.vue_vue_type_script_setup_true_lang-ClJ37hhT.js +62 -0
- package/dist/vue/InternalsSection-BJUXE-5F.js +468 -0
- package/dist/vue/InternalsTab-DEMjqtlw.js +471 -0
- package/dist/vue/JobsSection-CsKWTjgN.js +187 -0
- package/dist/vue/JobsTab-BCvhOARO.js +117 -0
- package/dist/vue/JsonViewer.vue_vue_type_script_setup_true_lang-Vsqar1zx.js +67 -0
- package/dist/vue/LogsSection-BFVjSZ24.js +227 -0
- package/dist/vue/LogsTab-DpEQ7euu.js +122 -0
- package/dist/vue/OverviewSection-CbMdAido.js +849 -0
- package/dist/vue/PaginationControls.vue_vue_type_script_setup_true_lang-CuN7g_8Z.js +50 -0
- package/dist/vue/QueriesSection-BPiv7u3r.js +429 -0
- package/dist/vue/QueriesTab-C8_7oprC.js +107 -0
- package/dist/vue/RequestsSection-LtImH4rD.js +243 -0
- package/dist/vue/RoutesSection-CrxOxmzx.js +106 -0
- package/dist/vue/RoutesTab-Dz0MkZuF.js +80 -0
- package/dist/vue/TimelineSection-DLxMW2J_.js +186 -0
- package/dist/vue/TimelineTab-Db6lKKsD.js +250 -0
- package/dist/vue/WaterfallChart.vue_vue_type_script_setup_true_lang-tZ13cNj1.js +118 -0
- package/dist/vue/components/Dashboard/DashboardPage.vue.d.ts +18 -0
- package/dist/vue/components/Dashboard/DashboardPage.vue.d.ts.map +1 -0
- package/dist/vue/components/Dashboard/sections/CacheSection.vue.d.ts +5 -0
- package/dist/vue/components/Dashboard/sections/CacheSection.vue.d.ts.map +1 -0
- package/dist/vue/components/Dashboard/sections/ConfigSection.vue.d.ts +3 -0
- package/dist/vue/components/Dashboard/sections/ConfigSection.vue.d.ts.map +1 -0
- package/dist/vue/components/Dashboard/sections/EmailsSection.vue.d.ts +5 -0
- package/dist/vue/components/Dashboard/sections/EmailsSection.vue.d.ts.map +1 -0
- package/dist/vue/components/Dashboard/sections/EventsSection.vue.d.ts +5 -0
- package/dist/vue/components/Dashboard/sections/EventsSection.vue.d.ts.map +1 -0
- package/dist/vue/components/Dashboard/sections/InternalsSection.vue.d.ts +3 -0
- package/dist/vue/components/Dashboard/sections/InternalsSection.vue.d.ts.map +1 -0
- package/dist/vue/components/Dashboard/sections/JobsSection.vue.d.ts +5 -0
- package/dist/vue/components/Dashboard/sections/JobsSection.vue.d.ts.map +1 -0
- package/dist/vue/components/Dashboard/sections/LogsSection.vue.d.ts +3 -0
- package/dist/vue/components/Dashboard/sections/LogsSection.vue.d.ts.map +1 -0
- package/dist/vue/components/Dashboard/sections/OverviewSection.vue.d.ts +5 -0
- package/dist/vue/components/Dashboard/sections/OverviewSection.vue.d.ts.map +1 -0
- package/dist/vue/components/Dashboard/sections/QueriesSection.vue.d.ts +45 -0
- package/dist/vue/components/Dashboard/sections/QueriesSection.vue.d.ts.map +1 -0
- package/dist/vue/components/Dashboard/sections/RequestsSection.vue.d.ts +5 -0
- package/dist/vue/components/Dashboard/sections/RequestsSection.vue.d.ts.map +1 -0
- package/dist/vue/components/Dashboard/sections/RoutesSection.vue.d.ts +5 -0
- package/dist/vue/components/Dashboard/sections/RoutesSection.vue.d.ts.map +1 -0
- package/dist/vue/components/Dashboard/sections/TimelineSection.vue.d.ts +11 -0
- package/dist/vue/components/Dashboard/sections/TimelineSection.vue.d.ts.map +1 -0
- package/dist/vue/components/Dashboard/shared/FilterBar.vue.d.ts +29 -0
- package/dist/vue/components/Dashboard/shared/FilterBar.vue.d.ts.map +1 -0
- package/dist/vue/components/Dashboard/shared/PaginationControls.vue.d.ts +12 -0
- package/dist/vue/components/Dashboard/shared/PaginationControls.vue.d.ts.map +1 -0
- package/dist/vue/components/Dashboard/shared/TimeRangeSelector.vue.d.ts +11 -0
- package/dist/vue/components/Dashboard/shared/TimeRangeSelector.vue.d.ts.map +1 -0
- package/dist/vue/components/Dashboard/shared/WaterfallChart.vue.d.ts +10 -0
- package/dist/vue/components/Dashboard/shared/WaterfallChart.vue.d.ts.map +1 -0
- package/dist/vue/components/DebugPanel/DebugPanel.vue.d.ts +21 -0
- package/dist/vue/components/DebugPanel/DebugPanel.vue.d.ts.map +1 -0
- package/dist/vue/components/DebugPanel/tabs/CacheTab.vue.d.ts +12 -0
- package/dist/vue/components/DebugPanel/tabs/CacheTab.vue.d.ts.map +1 -0
- package/dist/vue/components/DebugPanel/tabs/ConfigTab.vue.d.ts +11 -0
- package/dist/vue/components/DebugPanel/tabs/ConfigTab.vue.d.ts.map +1 -0
- package/dist/vue/components/DebugPanel/tabs/CustomPaneTab.vue.d.ts +11 -0
- package/dist/vue/components/DebugPanel/tabs/CustomPaneTab.vue.d.ts.map +1 -0
- package/dist/vue/components/DebugPanel/tabs/EmailsTab.vue.d.ts +12 -0
- package/dist/vue/components/DebugPanel/tabs/EmailsTab.vue.d.ts.map +1 -0
- package/dist/vue/components/DebugPanel/tabs/EventsTab.vue.d.ts +12 -0
- package/dist/vue/components/DebugPanel/tabs/EventsTab.vue.d.ts.map +1 -0
- package/dist/vue/components/DebugPanel/tabs/InternalsTab.vue.d.ts +11 -0
- package/dist/vue/components/DebugPanel/tabs/InternalsTab.vue.d.ts.map +1 -0
- package/dist/vue/components/DebugPanel/tabs/JobsTab.vue.d.ts +13 -0
- package/dist/vue/components/DebugPanel/tabs/JobsTab.vue.d.ts.map +1 -0
- package/dist/vue/components/DebugPanel/tabs/LogsTab.vue.d.ts +15 -0
- package/dist/vue/components/DebugPanel/tabs/LogsTab.vue.d.ts.map +1 -0
- package/dist/vue/components/DebugPanel/tabs/QueriesTab.vue.d.ts +12 -0
- package/dist/vue/components/DebugPanel/tabs/QueriesTab.vue.d.ts.map +1 -0
- package/dist/vue/components/DebugPanel/tabs/RoutesTab.vue.d.ts +12 -0
- package/dist/vue/components/DebugPanel/tabs/RoutesTab.vue.d.ts.map +1 -0
- package/dist/vue/components/DebugPanel/tabs/TimelineTab.vue.d.ts +15 -0
- package/dist/vue/components/DebugPanel/tabs/TimelineTab.vue.d.ts.map +1 -0
- package/dist/vue/components/StatsBar/MetricCard.vue.d.ts +19 -0
- package/dist/vue/components/StatsBar/MetricCard.vue.d.ts.map +1 -0
- package/dist/vue/components/StatsBar/Sparkline.vue.d.ts +17 -0
- package/dist/vue/components/StatsBar/Sparkline.vue.d.ts.map +1 -0
- package/dist/vue/components/StatsBar/StatsBar.vue.d.ts +22 -0
- package/dist/vue/components/StatsBar/StatsBar.vue.d.ts.map +1 -0
- package/dist/vue/components/shared/JsonViewer.vue.d.ts +13 -0
- package/dist/vue/components/shared/JsonViewer.vue.d.ts.map +1 -0
- package/dist/vue/components/shared/ThemeToggle.vue.d.ts +8 -0
- package/dist/vue/components/shared/ThemeToggle.vue.d.ts.map +1 -0
- package/dist/vue/composables/useApiClient.d.ts +9 -0
- package/dist/vue/composables/useApiClient.d.ts.map +1 -0
- package/dist/vue/composables/useDashboardData.d.ts +53 -0
- package/dist/vue/composables/useDashboardData.d.ts.map +1 -0
- package/dist/vue/composables/useDebugData.d.ts +25 -0
- package/dist/vue/composables/useDebugData.d.ts.map +1 -0
- package/dist/vue/composables/useFeatures.d.ts +80 -0
- package/dist/vue/composables/useFeatures.d.ts.map +1 -0
- package/dist/vue/composables/useResizableTable.d.ts +16 -0
- package/dist/vue/composables/useResizableTable.d.ts.map +1 -0
- package/dist/vue/composables/useServerStats.d.ts +104 -0
- package/dist/vue/composables/useServerStats.d.ts.map +1 -0
- package/dist/vue/composables/useTheme.d.ts +6 -0
- package/dist/vue/composables/useTheme.d.ts.map +1 -0
- package/dist/vue/index-qCQpBftQ.js +1233 -0
- package/dist/vue/index.d.ts +10 -0
- package/dist/vue/index.d.ts.map +1 -0
- package/dist/vue/index.js +11 -0
- package/dist/vue/style.css +1 -0
- package/dist/vue/useApiClient-BQQ9CF-q.js +10 -0
- package/dist/vue/useResizableTable-BoivAevK.js +17 -0
- package/package.json +72 -10
- package/dist/src/dashboard/dashboard_routes.d.ts +0 -16
- package/dist/src/dashboard/dashboard_routes.d.ts.map +0 -1
- package/dist/src/dashboard/dashboard_routes.js +0 -77
- package/dist/src/routes/debug_routes.d.ts +0 -14
- package/dist/src/routes/debug_routes.d.ts.map +0 -1
- package/dist/src/routes/debug_routes.js +0 -42
- package/dist/src/routes/stats_routes.d.ts +0 -14
- package/dist/src/routes/stats_routes.d.ts.map +0 -1
- package/dist/src/routes/stats_routes.js +0 -27
|
@@ -2,24 +2,38 @@ import { readFileSync } from 'node:fs';
|
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
import { safeParseJson, safeParseJsonArray } from '../utils/json_helpers.js';
|
|
5
|
+
import { log } from '../utils/logger.js';
|
|
5
6
|
import { round, clamp } from '../utils/math_helpers.js';
|
|
6
7
|
import { loadTransmitClient } from '../utils/transmit_client.js';
|
|
7
8
|
import { CacheInspector } from './integrations/cache_inspector.js';
|
|
8
9
|
import { ConfigInspector } from './integrations/config_inspector.js';
|
|
9
10
|
import { QueueInspector } from './integrations/queue_inspector.js';
|
|
10
|
-
const
|
|
11
|
+
const warnedDbReads = new Set();
|
|
12
|
+
const SRC_DIR = dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
const EDGE_DIR = join(SRC_DIR, '..', 'edge');
|
|
14
|
+
const STYLES_DIR = join(SRC_DIR, '..', 'styles');
|
|
15
|
+
function paginatedResponse(data, total, page, perPage) {
|
|
16
|
+
return {
|
|
17
|
+
data,
|
|
18
|
+
meta: { total, page, perPage, lastPage: Math.max(1, Math.ceil(total / perPage)) },
|
|
19
|
+
};
|
|
20
|
+
}
|
|
11
21
|
function emptyPage(page, perPage) {
|
|
12
|
-
return { data: [], total: 0, page, perPage };
|
|
22
|
+
return { data: [], meta: { total: 0, page, perPage, lastPage: 1 } };
|
|
13
23
|
}
|
|
14
24
|
/**
|
|
15
25
|
* Controller for the full-page dashboard.
|
|
16
26
|
*
|
|
17
|
-
* Serves the dashboard HTML page and
|
|
18
|
-
*
|
|
27
|
+
* Serves the dashboard HTML page and dashboard-specific JSON API
|
|
28
|
+
* endpoints (overview, requests, grouped queries, query explain,
|
|
29
|
+
* cache, jobs, config, saved filters).
|
|
30
|
+
*
|
|
31
|
+
* Data resource endpoints (queries, events, emails, traces, routes,
|
|
32
|
+
* logs) are handled by the unified ApiController — see
|
|
33
|
+
* `src/controller/api_controller.ts`.
|
|
19
34
|
*/
|
|
20
35
|
export default class DashboardController {
|
|
21
36
|
dashboardStore;
|
|
22
|
-
debugStore;
|
|
23
37
|
app;
|
|
24
38
|
cacheInspector = null;
|
|
25
39
|
queueInspector = null;
|
|
@@ -29,9 +43,8 @@ export default class DashboardController {
|
|
|
29
43
|
cachedCss = null;
|
|
30
44
|
cachedJs = null;
|
|
31
45
|
cachedTransmitClient = null;
|
|
32
|
-
constructor(dashboardStore,
|
|
46
|
+
constructor(dashboardStore, app) {
|
|
33
47
|
this.dashboardStore = dashboardStore;
|
|
34
|
-
this.debugStore = debugStore;
|
|
35
48
|
this.app = app;
|
|
36
49
|
this.configInspector = new ConfigInspector(app);
|
|
37
50
|
}
|
|
@@ -42,38 +55,40 @@ export default class DashboardController {
|
|
|
42
55
|
if (!this.checkAccess(ctx)) {
|
|
43
56
|
return ctx.response.forbidden({ error: 'Access denied' });
|
|
44
57
|
}
|
|
58
|
+
const config = this.app.config.get('server_stats');
|
|
59
|
+
const toolbarConfig = config?.devToolbar ?? {};
|
|
45
60
|
if (!this.cachedCss) {
|
|
46
|
-
|
|
61
|
+
const tokens = readFileSync(join(STYLES_DIR, 'tokens.css'), 'utf-8');
|
|
62
|
+
const components = readFileSync(join(STYLES_DIR, 'components.css'), 'utf-8');
|
|
63
|
+
const utilities = readFileSync(join(STYLES_DIR, 'utilities.css'), 'utf-8');
|
|
64
|
+
const dashboard = readFileSync(join(STYLES_DIR, 'dashboard.css'), 'utf-8');
|
|
65
|
+
this.cachedCss = tokens + '\n' + components + '\n' + utilities + '\n' + dashboard;
|
|
47
66
|
}
|
|
48
67
|
if (!this.cachedJs) {
|
|
49
|
-
|
|
68
|
+
const renderer = toolbarConfig.renderer || 'preact';
|
|
69
|
+
const clientDir = renderer === 'vue' ? 'client-vue' : 'client';
|
|
70
|
+
this.cachedJs = readFileSync(join(EDGE_DIR, clientDir, 'dashboard.js'), 'utf-8');
|
|
50
71
|
}
|
|
51
72
|
if (this.cachedTransmitClient === null) {
|
|
52
73
|
this.cachedTransmitClient = loadTransmitClient(this.app.makePath('package.json'));
|
|
53
74
|
if (this.cachedTransmitClient) {
|
|
54
|
-
|
|
75
|
+
log.info('Transmit client loaded for dashboard');
|
|
55
76
|
}
|
|
56
77
|
else {
|
|
57
|
-
|
|
78
|
+
log.info('Dashboard will use polling. Install @adonisjs/transmit-client for real-time updates.');
|
|
58
79
|
}
|
|
59
80
|
}
|
|
60
|
-
const config = this.app.config.get('server_stats');
|
|
61
|
-
const toolbarConfig = config?.devToolbar || {};
|
|
62
81
|
const dashPath = this.getDashboardPath();
|
|
63
82
|
return ctx.view.render('ss::dashboard', {
|
|
64
83
|
css: this.cachedCss,
|
|
65
84
|
js: this.cachedJs,
|
|
66
85
|
transmitClient: this.cachedTransmitClient,
|
|
67
|
-
dashboardPath: dashPath,
|
|
68
|
-
showTracing: !!toolbarConfig.tracing,
|
|
69
|
-
customPanes: toolbarConfig.panes || [],
|
|
70
86
|
dashConfig: {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
})),
|
|
87
|
+
baseUrl: '',
|
|
88
|
+
dashboardEndpoint: dashPath + '/api',
|
|
89
|
+
debugEndpoint: toolbarConfig.debugEndpoint || '/admin/api/debug',
|
|
90
|
+
channelName: 'server-stats/dashboard',
|
|
91
|
+
backUrl: '/',
|
|
77
92
|
},
|
|
78
93
|
});
|
|
79
94
|
}
|
|
@@ -81,7 +96,7 @@ export default class DashboardController {
|
|
|
81
96
|
// Overview
|
|
82
97
|
// ---------------------------------------------------------------------------
|
|
83
98
|
async overview({ request, response }) {
|
|
84
|
-
return this.withDb(response, emptyOverview(), async () => {
|
|
99
|
+
return this.withDb(response, 'overview', emptyOverview(), async () => {
|
|
85
100
|
const range = request.qs().range || '1h';
|
|
86
101
|
const [overview, widgets, sparklineData] = await Promise.all([
|
|
87
102
|
this.dashboardStore.getOverviewMetrics(range),
|
|
@@ -100,7 +115,9 @@ export default class DashboardController {
|
|
|
100
115
|
avgResponseTime: sparklineData.map((m) => m.avg_duration),
|
|
101
116
|
p95ResponseTime: sparklineData.map((m) => m.p95_duration),
|
|
102
117
|
requestsPerMinute: sparklineData.map((m) => m.request_count),
|
|
103
|
-
errorRate: sparklineData.map((m) => m.request_count > 0
|
|
118
|
+
errorRate: sparklineData.map((m) => m.request_count > 0
|
|
119
|
+
? round((m.error_count / m.request_count) * 100)
|
|
120
|
+
: 0),
|
|
104
121
|
},
|
|
105
122
|
...widgets,
|
|
106
123
|
cacheStats,
|
|
@@ -110,7 +127,7 @@ export default class DashboardController {
|
|
|
110
127
|
}
|
|
111
128
|
async overviewChart({ request, response }) {
|
|
112
129
|
const range = request.qs().range || '1h';
|
|
113
|
-
return this.withDb(response, { range, buckets: [] }, async () => {
|
|
130
|
+
return this.withDb(response, 'overviewChart', { range, buckets: [] }, async () => {
|
|
114
131
|
const buckets = await this.dashboardStore.getChartData(range);
|
|
115
132
|
return {
|
|
116
133
|
range,
|
|
@@ -132,18 +149,14 @@ export default class DashboardController {
|
|
|
132
149
|
const qs = request.qs();
|
|
133
150
|
const page = Math.max(1, Number(qs.page) || 1);
|
|
134
151
|
const perPage = clamp(Number(qs.perPage) || 25, 1, 100);
|
|
135
|
-
return this.withDb(response, emptyPage(page, perPage), async () => {
|
|
152
|
+
return this.withDb(response, 'requests', emptyPage(page, perPage), async () => {
|
|
136
153
|
const result = await this.dashboardStore.getRequests(page, perPage, {
|
|
137
154
|
method: qs.method ? qs.method.toUpperCase() : undefined,
|
|
138
155
|
url: qs.url || undefined,
|
|
139
156
|
status: qs.status ? Number(qs.status) : undefined,
|
|
157
|
+
search: qs.search || undefined,
|
|
140
158
|
});
|
|
141
|
-
return
|
|
142
|
-
data: result.data.map(formatRequest),
|
|
143
|
-
total: result.total,
|
|
144
|
-
page: result.page,
|
|
145
|
-
perPage: result.perPage,
|
|
146
|
-
};
|
|
159
|
+
return paginatedResponse(result.data.map(formatRequest), result.total, result.page, result.perPage);
|
|
147
160
|
});
|
|
148
161
|
}
|
|
149
162
|
async requestDetail({ params, response }) {
|
|
@@ -164,34 +177,13 @@ export default class DashboardController {
|
|
|
164
177
|
return response.notFound({ error: 'Not found' });
|
|
165
178
|
}
|
|
166
179
|
}
|
|
167
|
-
// ---------------------------------------------------------------------------
|
|
168
|
-
// Queries
|
|
169
|
-
// ---------------------------------------------------------------------------
|
|
170
|
-
async queries({ request, response }) {
|
|
171
|
-
const qs = request.qs();
|
|
172
|
-
const page = Math.max(1, Number(qs.page) || 1);
|
|
173
|
-
const perPage = clamp(Number(qs.perPage) || 25, 1, 100);
|
|
174
|
-
return this.withDb(response, emptyPage(page, perPage), async () => {
|
|
175
|
-
const result = await this.dashboardStore.getQueries(page, perPage, {
|
|
176
|
-
durationMin: qs.duration_min ? Number(qs.duration_min) : undefined,
|
|
177
|
-
model: qs.model || undefined,
|
|
178
|
-
method: qs.method || undefined,
|
|
179
|
-
connection: qs.connection || undefined,
|
|
180
|
-
});
|
|
181
|
-
return {
|
|
182
|
-
data: result.data.map(formatQuery),
|
|
183
|
-
total: result.total,
|
|
184
|
-
page: result.page,
|
|
185
|
-
perPage: result.perPage,
|
|
186
|
-
};
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
180
|
async queriesGrouped({ request, response }) {
|
|
190
|
-
return this.withDb(response, { groups: [] }, async () => {
|
|
181
|
+
return this.withDb(response, 'queriesGrouped', { groups: [] }, async () => {
|
|
191
182
|
const qs = request.qs();
|
|
192
183
|
const limit = clamp(Number(qs.limit) || 50, 1, 200);
|
|
193
184
|
const sort = qs.sort || 'total_duration';
|
|
194
|
-
const
|
|
185
|
+
const search = qs.search || undefined;
|
|
186
|
+
const groups = await this.dashboardStore.getQueriesGrouped(limit, sort, search);
|
|
195
187
|
const totalTime = groups.reduce((sum, g) => sum + (g.total_duration || 0), 0);
|
|
196
188
|
return {
|
|
197
189
|
groups: groups.map((g) => ({
|
|
@@ -212,21 +204,31 @@ export default class DashboardController {
|
|
|
212
204
|
}
|
|
213
205
|
try {
|
|
214
206
|
const db = this.dashboardStore.getDb();
|
|
207
|
+
if (!db)
|
|
208
|
+
return response.notFound({ error: 'Not found' });
|
|
215
209
|
const id = Number(params.id);
|
|
216
|
-
const query = await db('server_stats_queries')
|
|
210
|
+
const query = await db('server_stats_queries')
|
|
211
|
+
.where('id', id)
|
|
212
|
+
.first();
|
|
217
213
|
if (!query)
|
|
218
214
|
return response.notFound({ error: 'Query not found' });
|
|
219
215
|
const sqlTrimmed = query.sql_text.trim().toUpperCase();
|
|
220
216
|
if (!sqlTrimmed.startsWith('SELECT')) {
|
|
221
|
-
return response.badRequest({
|
|
217
|
+
return response.badRequest({
|
|
218
|
+
error: 'EXPLAIN is only supported for SELECT queries',
|
|
219
|
+
});
|
|
222
220
|
}
|
|
223
221
|
let appDb;
|
|
224
222
|
try {
|
|
225
223
|
const lucid = await this.app.container.make('lucid.db');
|
|
226
|
-
appDb = lucid
|
|
224
|
+
appDb = lucid
|
|
225
|
+
.connection()
|
|
226
|
+
.getWriteClient();
|
|
227
227
|
}
|
|
228
228
|
catch {
|
|
229
|
-
return response.serviceUnavailable({
|
|
229
|
+
return response.serviceUnavailable({
|
|
230
|
+
error: 'App database connection not available',
|
|
231
|
+
});
|
|
230
232
|
}
|
|
231
233
|
let bindings = [];
|
|
232
234
|
if (query.bindings) {
|
|
@@ -239,7 +241,8 @@ export default class DashboardController {
|
|
|
239
241
|
}
|
|
240
242
|
const explainResult = await appDb.raw(`EXPLAIN (FORMAT JSON) ${query.sql_text}`, bindings);
|
|
241
243
|
let plan = [];
|
|
242
|
-
const rawRows = explainResult?.rows ??
|
|
244
|
+
const rawRows = explainResult?.rows ??
|
|
245
|
+
(Array.isArray(explainResult) ? explainResult : []);
|
|
243
246
|
if (rawRows.length > 0 && rawRows[0]['QUERY PLAN']) {
|
|
244
247
|
plan = rawRows[0]['QUERY PLAN'];
|
|
245
248
|
}
|
|
@@ -256,163 +259,6 @@ export default class DashboardController {
|
|
|
256
259
|
}
|
|
257
260
|
}
|
|
258
261
|
// ---------------------------------------------------------------------------
|
|
259
|
-
// Events
|
|
260
|
-
// ---------------------------------------------------------------------------
|
|
261
|
-
async events({ request, response }) {
|
|
262
|
-
const qs = request.qs();
|
|
263
|
-
const page = Math.max(1, Number(qs.page) || 1);
|
|
264
|
-
const perPage = clamp(Number(qs.perPage) || 25, 1, 100);
|
|
265
|
-
return this.withDb(response, emptyPage(page, perPage), async () => {
|
|
266
|
-
const result = await this.dashboardStore.getEvents(page, perPage, {
|
|
267
|
-
eventName: qs.event_name || undefined,
|
|
268
|
-
});
|
|
269
|
-
return {
|
|
270
|
-
data: result.data.map((e) => ({
|
|
271
|
-
id: e.id,
|
|
272
|
-
requestId: e.request_id,
|
|
273
|
-
eventName: e.event_name,
|
|
274
|
-
data: safeParseJson(e.data),
|
|
275
|
-
createdAt: e.created_at,
|
|
276
|
-
})),
|
|
277
|
-
total: result.total,
|
|
278
|
-
page: result.page,
|
|
279
|
-
perPage: result.perPage,
|
|
280
|
-
};
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
// ---------------------------------------------------------------------------
|
|
284
|
-
// Routes
|
|
285
|
-
// ---------------------------------------------------------------------------
|
|
286
|
-
async routes({ response }) {
|
|
287
|
-
const routes = this.debugStore.routes.getRoutes();
|
|
288
|
-
return response.json({
|
|
289
|
-
routes,
|
|
290
|
-
total: this.debugStore.routes.getRouteCount(),
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
// ---------------------------------------------------------------------------
|
|
294
|
-
// Logs
|
|
295
|
-
// ---------------------------------------------------------------------------
|
|
296
|
-
async logs({ request, response }) {
|
|
297
|
-
const qs = request.qs();
|
|
298
|
-
const page = Math.max(1, Number(qs.page) || 1);
|
|
299
|
-
const perPage = clamp(Number(qs.perPage) || 50, 1, 200);
|
|
300
|
-
// Build structured filters from query string
|
|
301
|
-
const structured = [];
|
|
302
|
-
if (qs.field && qs.value !== undefined) {
|
|
303
|
-
const op = qs.operator || 'equals';
|
|
304
|
-
const operatorMap = {
|
|
305
|
-
equals: 'equals',
|
|
306
|
-
contains: 'contains',
|
|
307
|
-
starts_with: 'startsWith',
|
|
308
|
-
};
|
|
309
|
-
structured.push({
|
|
310
|
-
field: qs.field,
|
|
311
|
-
operator: operatorMap[op] || 'equals',
|
|
312
|
-
value: qs.value,
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
|
-
return this.withDb(response, emptyPage(page, perPage), async () => {
|
|
316
|
-
const result = await this.dashboardStore.getLogs(page, perPage, {
|
|
317
|
-
level: qs.level || undefined,
|
|
318
|
-
search: qs.message || undefined,
|
|
319
|
-
requestId: qs.request_id || undefined,
|
|
320
|
-
structured: structured.length > 0 ? structured : undefined,
|
|
321
|
-
});
|
|
322
|
-
return {
|
|
323
|
-
data: result.data.map((l) => ({
|
|
324
|
-
id: l.id,
|
|
325
|
-
level: l.level,
|
|
326
|
-
message: l.message,
|
|
327
|
-
requestId: l.request_id,
|
|
328
|
-
data: safeParseJson(l.data),
|
|
329
|
-
createdAt: l.created_at,
|
|
330
|
-
})),
|
|
331
|
-
total: result.total,
|
|
332
|
-
page: result.page,
|
|
333
|
-
perPage: result.perPage,
|
|
334
|
-
};
|
|
335
|
-
});
|
|
336
|
-
}
|
|
337
|
-
// ---------------------------------------------------------------------------
|
|
338
|
-
// Emails
|
|
339
|
-
// ---------------------------------------------------------------------------
|
|
340
|
-
async emails({ request, response }) {
|
|
341
|
-
const qs = request.qs();
|
|
342
|
-
const page = Math.max(1, Number(qs.page) || 1);
|
|
343
|
-
const perPage = clamp(Number(qs.perPage) || 25, 1, 100);
|
|
344
|
-
return this.withDb(response, emptyPage(page, perPage), async () => {
|
|
345
|
-
const result = await this.dashboardStore.getEmails(page, perPage, {
|
|
346
|
-
from: qs.from || undefined,
|
|
347
|
-
to: qs.to || undefined,
|
|
348
|
-
subject: qs.subject || undefined,
|
|
349
|
-
status: qs.status || undefined,
|
|
350
|
-
mailer: qs.mailer || undefined,
|
|
351
|
-
}, true);
|
|
352
|
-
return {
|
|
353
|
-
data: result.data.map(formatEmail),
|
|
354
|
-
total: result.total,
|
|
355
|
-
page: result.page,
|
|
356
|
-
perPage: result.perPage,
|
|
357
|
-
};
|
|
358
|
-
});
|
|
359
|
-
}
|
|
360
|
-
async emailPreview({ params, response }) {
|
|
361
|
-
if (!this.dashboardStore.isReady()) {
|
|
362
|
-
return response.notFound({ error: 'Not found' });
|
|
363
|
-
}
|
|
364
|
-
try {
|
|
365
|
-
const html = await this.dashboardStore.getEmailHtml(Number(params.id));
|
|
366
|
-
if (!html)
|
|
367
|
-
return response.notFound({ error: 'Email not found' });
|
|
368
|
-
return response.header('Content-Type', 'text/html; charset=utf-8').send(html);
|
|
369
|
-
}
|
|
370
|
-
catch {
|
|
371
|
-
return response.notFound({ error: 'Not found' });
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
// ---------------------------------------------------------------------------
|
|
375
|
-
// Traces
|
|
376
|
-
// ---------------------------------------------------------------------------
|
|
377
|
-
async traces({ request, response }) {
|
|
378
|
-
const qs = request.qs();
|
|
379
|
-
const page = Math.max(1, Number(qs.page) || 1);
|
|
380
|
-
const perPage = clamp(Number(qs.perPage) || 25, 1, 100);
|
|
381
|
-
return this.withDb(response, emptyPage(page, perPage), async () => {
|
|
382
|
-
const result = await this.dashboardStore.getTraces(page, perPage);
|
|
383
|
-
return {
|
|
384
|
-
data: result.data.map((t) => ({
|
|
385
|
-
id: t.id,
|
|
386
|
-
requestId: t.request_id,
|
|
387
|
-
method: t.method,
|
|
388
|
-
url: t.url,
|
|
389
|
-
statusCode: t.status_code,
|
|
390
|
-
totalDuration: t.total_duration,
|
|
391
|
-
spanCount: t.span_count,
|
|
392
|
-
warningCount: safeParseJsonArray(t.warnings).length,
|
|
393
|
-
createdAt: t.created_at,
|
|
394
|
-
})),
|
|
395
|
-
total: result.total,
|
|
396
|
-
page: result.page,
|
|
397
|
-
perPage: result.perPage,
|
|
398
|
-
};
|
|
399
|
-
});
|
|
400
|
-
}
|
|
401
|
-
async traceDetail({ params, response }) {
|
|
402
|
-
if (!this.dashboardStore.isReady()) {
|
|
403
|
-
return response.notFound({ error: 'Not found' });
|
|
404
|
-
}
|
|
405
|
-
try {
|
|
406
|
-
const trace = await this.dashboardStore.getTraceDetail(Number(params.id));
|
|
407
|
-
if (!trace)
|
|
408
|
-
return response.notFound({ error: 'Trace not found' });
|
|
409
|
-
return response.json(formatTrace(trace));
|
|
410
|
-
}
|
|
411
|
-
catch {
|
|
412
|
-
return response.notFound({ error: 'Not found' });
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
// ---------------------------------------------------------------------------
|
|
416
262
|
// Cache
|
|
417
263
|
// ---------------------------------------------------------------------------
|
|
418
264
|
async cacheStats({ request, response }) {
|
|
@@ -421,7 +267,8 @@ export default class DashboardController {
|
|
|
421
267
|
return response.json({ available: false, stats: null, keys: [] });
|
|
422
268
|
}
|
|
423
269
|
const qs = request.qs();
|
|
424
|
-
const
|
|
270
|
+
const searchTerm = qs.search || qs.pattern || '';
|
|
271
|
+
const pattern = searchTerm ? `*${searchTerm}*` : '*';
|
|
425
272
|
const cursor = qs.cursor || '0';
|
|
426
273
|
const count = clamp(Number(qs.count) || 100, 1, 500);
|
|
427
274
|
try {
|
|
@@ -456,34 +303,72 @@ export default class DashboardController {
|
|
|
456
303
|
return response.notFound({ error: 'Key not found' });
|
|
457
304
|
}
|
|
458
305
|
}
|
|
306
|
+
async cacheKeyDelete({ params, response }) {
|
|
307
|
+
const inspector = await this.getInspector('cache');
|
|
308
|
+
if (!inspector) {
|
|
309
|
+
return response.notFound({ error: 'Cache not available' });
|
|
310
|
+
}
|
|
311
|
+
try {
|
|
312
|
+
const key = decodeURIComponent(params.key);
|
|
313
|
+
const deleted = await inspector.deleteKey(key);
|
|
314
|
+
if (!deleted)
|
|
315
|
+
return response.notFound({ error: 'Key not found' });
|
|
316
|
+
return response.json({ deleted: true });
|
|
317
|
+
}
|
|
318
|
+
catch {
|
|
319
|
+
return response.internalServerError({ error: 'Failed to delete cache key' });
|
|
320
|
+
}
|
|
321
|
+
}
|
|
459
322
|
// ---------------------------------------------------------------------------
|
|
460
323
|
// Jobs / Queue
|
|
461
324
|
// ---------------------------------------------------------------------------
|
|
462
325
|
async jobs({ request, response }) {
|
|
463
326
|
const inspector = await this.getInspector('queue');
|
|
464
327
|
if (!inspector) {
|
|
465
|
-
return response.json({
|
|
328
|
+
return response.json({
|
|
329
|
+
available: false,
|
|
330
|
+
overview: null,
|
|
331
|
+
stats: null,
|
|
332
|
+
jobs: [],
|
|
333
|
+
total: 0,
|
|
334
|
+
});
|
|
466
335
|
}
|
|
467
336
|
const qs = request.qs();
|
|
468
|
-
const status = qs.status || '
|
|
337
|
+
const status = qs.status || 'all';
|
|
338
|
+
const searchTerm = qs.search || '';
|
|
469
339
|
const page = Math.max(1, Number(qs.page) || 1);
|
|
470
|
-
const perPage = clamp(Number(qs.perPage) || 25, 1, 100);
|
|
340
|
+
const perPage = clamp(Number(qs.perPage) || Number(qs.limit) || 25, 1, 100);
|
|
471
341
|
try {
|
|
472
342
|
const [overview, jobList] = await Promise.all([
|
|
473
343
|
inspector.getOverview(),
|
|
474
344
|
inspector.listJobs(status, page, perPage),
|
|
475
345
|
]);
|
|
346
|
+
// Filter jobs by search term (name match) if provided
|
|
347
|
+
let filteredJobs = jobList.jobs;
|
|
348
|
+
let filteredTotal = jobList.total;
|
|
349
|
+
if (searchTerm) {
|
|
350
|
+
const term = searchTerm.toLowerCase();
|
|
351
|
+
filteredJobs = jobList.jobs.filter((j) => j.name?.toLowerCase().includes(term) || j.id?.toString().toLowerCase().includes(term));
|
|
352
|
+
filteredTotal = filteredJobs.length;
|
|
353
|
+
}
|
|
476
354
|
return response.json({
|
|
477
355
|
available: true,
|
|
478
356
|
overview,
|
|
479
|
-
|
|
480
|
-
|
|
357
|
+
stats: overview,
|
|
358
|
+
jobs: filteredJobs,
|
|
359
|
+
total: filteredTotal,
|
|
481
360
|
page,
|
|
482
361
|
perPage,
|
|
483
362
|
});
|
|
484
363
|
}
|
|
485
364
|
catch {
|
|
486
|
-
return response.json({
|
|
365
|
+
return response.json({
|
|
366
|
+
available: false,
|
|
367
|
+
overview: null,
|
|
368
|
+
stats: null,
|
|
369
|
+
jobs: [],
|
|
370
|
+
total: 0,
|
|
371
|
+
});
|
|
487
372
|
}
|
|
488
373
|
}
|
|
489
374
|
async jobDetail({ params, response }) {
|
|
@@ -509,7 +394,9 @@ export default class DashboardController {
|
|
|
509
394
|
try {
|
|
510
395
|
const success = await inspector.retryJob(String(params.id));
|
|
511
396
|
if (!success) {
|
|
512
|
-
return response.badRequest({
|
|
397
|
+
return response.badRequest({
|
|
398
|
+
error: 'Job could not be retried (not in failed state)',
|
|
399
|
+
});
|
|
513
400
|
}
|
|
514
401
|
return response.json({ success: true });
|
|
515
402
|
}
|
|
@@ -524,7 +411,7 @@ export default class DashboardController {
|
|
|
524
411
|
const configData = this.configInspector.getConfig();
|
|
525
412
|
const envData = this.configInspector.getEnvVars();
|
|
526
413
|
return response.json({
|
|
527
|
-
|
|
414
|
+
app: configData.config,
|
|
528
415
|
env: envData.env,
|
|
529
416
|
});
|
|
530
417
|
}
|
|
@@ -532,7 +419,7 @@ export default class DashboardController {
|
|
|
532
419
|
// Saved Filters
|
|
533
420
|
// ---------------------------------------------------------------------------
|
|
534
421
|
async savedFilters({ response }) {
|
|
535
|
-
return this.withDb(response, { filters: [] }, async () => {
|
|
422
|
+
return this.withDb(response, 'savedFilters', { filters: [] }, async () => {
|
|
536
423
|
const filters = await this.dashboardStore.getSavedFilters();
|
|
537
424
|
return {
|
|
538
425
|
filters: filters.map((f) => ({
|
|
@@ -589,13 +476,17 @@ export default class DashboardController {
|
|
|
589
476
|
* Wraps a store call with null-guard + try/catch boilerplate.
|
|
590
477
|
* Returns emptyValue if the store is not ready or the fn throws.
|
|
591
478
|
*/
|
|
592
|
-
async withDb(response, emptyValue, fn) {
|
|
479
|
+
async withDb(response, label, emptyValue, fn) {
|
|
593
480
|
if (!this.dashboardStore.isReady())
|
|
594
481
|
return response.json(emptyValue);
|
|
595
482
|
try {
|
|
596
483
|
return response.json(await fn());
|
|
597
484
|
}
|
|
598
|
-
catch {
|
|
485
|
+
catch (err) {
|
|
486
|
+
if (!warnedDbReads.has(label)) {
|
|
487
|
+
warnedDbReads.add(label);
|
|
488
|
+
log.warn(`dashboard ${label}: DB read failed — ${err?.message}`);
|
|
489
|
+
}
|
|
599
490
|
return response.json(emptyValue);
|
|
600
491
|
}
|
|
601
492
|
}
|
|
@@ -623,14 +514,17 @@ export default class DashboardController {
|
|
|
623
514
|
try {
|
|
624
515
|
const available = await CacheInspector.isAvailable(this.app);
|
|
625
516
|
this.cacheAvailable = available;
|
|
626
|
-
if (!available)
|
|
517
|
+
if (!available) {
|
|
518
|
+
log.info('dashboard: Redis not detected — Cache panel disabled');
|
|
627
519
|
return null;
|
|
520
|
+
}
|
|
628
521
|
const redis = await this.app.container.make('redis');
|
|
629
522
|
this.cacheInspector = new CacheInspector(redis);
|
|
630
523
|
return this.cacheInspector;
|
|
631
524
|
}
|
|
632
|
-
catch {
|
|
525
|
+
catch (err) {
|
|
633
526
|
this.cacheAvailable = false;
|
|
527
|
+
log.warn('dashboard: CacheInspector init failed — ' + err?.message);
|
|
634
528
|
return null;
|
|
635
529
|
}
|
|
636
530
|
}
|
|
@@ -642,14 +536,17 @@ export default class DashboardController {
|
|
|
642
536
|
try {
|
|
643
537
|
const available = await QueueInspector.isAvailable(this.app);
|
|
644
538
|
this.queueAvailable = available;
|
|
645
|
-
if (!available)
|
|
539
|
+
if (!available) {
|
|
540
|
+
log.info('dashboard: Queue not detected — Jobs panel disabled');
|
|
646
541
|
return null;
|
|
647
|
-
|
|
542
|
+
}
|
|
543
|
+
const queue = await this.app.container.make('rlanz/queue');
|
|
648
544
|
this.queueInspector = new QueueInspector(queue);
|
|
649
545
|
return this.queueInspector;
|
|
650
546
|
}
|
|
651
|
-
catch {
|
|
547
|
+
catch (err) {
|
|
652
548
|
this.queueAvailable = false;
|
|
549
|
+
log.warn('dashboard: QueueInspector init failed — ' + err?.message);
|
|
653
550
|
return null;
|
|
654
551
|
}
|
|
655
552
|
}
|
|
@@ -736,21 +633,6 @@ function formatTrace(t) {
|
|
|
736
633
|
createdAt: t.created_at,
|
|
737
634
|
};
|
|
738
635
|
}
|
|
739
|
-
function formatEmail(e) {
|
|
740
|
-
return {
|
|
741
|
-
id: e.id,
|
|
742
|
-
from: e.from_addr,
|
|
743
|
-
to: e.to_addr,
|
|
744
|
-
cc: e.cc,
|
|
745
|
-
bcc: e.bcc,
|
|
746
|
-
subject: e.subject,
|
|
747
|
-
mailer: e.mailer,
|
|
748
|
-
status: e.status,
|
|
749
|
-
messageId: e.message_id,
|
|
750
|
-
attachmentCount: e.attachment_count,
|
|
751
|
-
createdAt: e.created_at,
|
|
752
|
-
};
|
|
753
|
-
}
|
|
754
636
|
function emptyOverview() {
|
|
755
637
|
return {
|
|
756
638
|
avgResponseTime: 0,
|