@oneuptime/common 12.0.5 → 12.0.6
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/Models/DatabaseModels/AIRun.ts +33 -0
- package/Models/DatabaseModels/DataSource.ts +744 -0
- package/Models/DatabaseModels/Index.ts +3 -0
- package/Models/DatabaseModels/ProjectCallSMSConfig.ts +10 -2
- package/Models/DatabaseModels/User.ts +2 -0
- package/Models/DatabaseModels/UserOnCallLog.ts +2 -0
- package/Models/DatabaseModels/UserOnCallLogTimeline.ts +2 -0
- package/Models/DatabaseModels/UserSession.ts +2 -0
- package/Models/DatabaseModels/UserTotpAuth.ts +6 -4
- package/Models/DatabaseModels/UserWebAuthn.ts +5 -3
- package/Server/API/AIInsightAPI.ts +47 -4
- package/Server/API/AIInvestigationAPI.ts +25 -0
- package/Server/API/DashboardAPI.ts +176 -492
- package/Server/API/DataSourceAPI.ts +268 -0
- package/Server/API/StatusPageAPI.ts +11 -1
- package/Server/API/UserAPI.ts +119 -0
- package/Server/Infrastructure/ClickhouseConfig.ts +59 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.ts +39 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.ts +24 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.ts +76 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Infrastructure/Queue.ts +26 -0
- package/Server/Infrastructure/QueueWorker.ts +17 -0
- package/Server/Middleware/TelemetryIngest.ts +8 -3
- package/Server/Services/AIInsightService.ts +132 -12
- package/Server/Services/AIRunService.ts +34 -0
- package/Server/Services/AIService.ts +17 -2
- package/Server/Services/AlertService.ts +38 -32
- package/Server/Services/AnalyticsDatabaseService.ts +8 -4
- package/Server/Services/DataSourceService.ts +200 -0
- package/Server/Services/HostService.ts +92 -0
- package/Server/Services/IncidentService.ts +45 -0
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/MonitorService.ts +49 -0
- package/Server/Services/MonitorStatusService.ts +166 -0
- package/Server/Services/OpenTelemetryIngestService.ts +255 -184
- package/Server/Services/RumSessionPinService.ts +7 -21
- package/Server/Services/StatusPageSubscriberService.ts +13 -0
- package/Server/Services/UserService.ts +280 -9
- package/Server/Static/Vendor/README.md +62 -0
- package/Server/Static/Vendor/fonts/InterVariable.woff2 +0 -0
- package/Server/Static/Vendor/highlight/highlight.min.js +1244 -0
- package/Server/Static/Vendor/highlight/languages/apache.min.js +15 -0
- package/Server/Static/Vendor/highlight/languages/bash.min.js +21 -0
- package/Server/Static/Vendor/highlight/languages/c.min.js +41 -0
- package/Server/Static/Vendor/highlight/languages/cpp.min.js +47 -0
- package/Server/Static/Vendor/highlight/languages/csharp.min.js +49 -0
- package/Server/Static/Vendor/highlight/languages/css.min.js +31 -0
- package/Server/Static/Vendor/highlight/languages/diff.min.js +9 -0
- package/Server/Static/Vendor/highlight/languages/dns.min.js +11 -0
- package/Server/Static/Vendor/highlight/languages/dockerfile.min.js +8 -0
- package/Server/Static/Vendor/highlight/languages/go.min.js +20 -0
- package/Server/Static/Vendor/highlight/languages/graphql.min.js +12 -0
- package/Server/Static/Vendor/highlight/languages/http.min.js +14 -0
- package/Server/Static/Vendor/highlight/languages/ini.min.js +15 -0
- package/Server/Static/Vendor/highlight/languages/java.min.js +38 -0
- package/Server/Static/Vendor/highlight/languages/javascript.min.js +81 -0
- package/Server/Static/Vendor/highlight/languages/json.min.js +8 -0
- package/Server/Static/Vendor/highlight/languages/kotlin.min.js +46 -0
- package/Server/Static/Vendor/highlight/languages/lua.min.js +15 -0
- package/Server/Static/Vendor/highlight/languages/makefile.min.js +14 -0
- package/Server/Static/Vendor/highlight/languages/nginx.min.js +21 -0
- package/Server/Static/Vendor/highlight/languages/perl.min.js +41 -0
- package/Server/Static/Vendor/highlight/languages/php.min.js +59 -0
- package/Server/Static/Vendor/highlight/languages/powershell.min.js +39 -0
- package/Server/Static/Vendor/highlight/languages/python.min.js +42 -0
- package/Server/Static/Vendor/highlight/languages/r.min.js +26 -0
- package/Server/Static/Vendor/highlight/languages/ruby.min.js +54 -0
- package/Server/Static/Vendor/highlight/languages/rust.min.js +27 -0
- package/Server/Static/Vendor/highlight/languages/scala.min.js +28 -0
- package/Server/Static/Vendor/highlight/languages/sql.min.js +21 -0
- package/Server/Static/Vendor/highlight/languages/swift.min.js +68 -0
- package/Server/Static/Vendor/highlight/languages/typescript.min.js +99 -0
- package/Server/Static/Vendor/highlight/languages/xml.min.js +29 -0
- package/Server/Static/Vendor/highlight/languages/yaml.min.js +28 -0
- package/Server/Static/Vendor/highlight/styles/github-dark.min.css +10 -0
- package/Server/Static/Vendor/highlight/styles/vs2015.min.css +1 -0
- package/Server/Static/Vendor/tailwind/tailwind-3.4.5.js +21028 -0
- package/Server/Types/Database/Permissions/BasePermission.ts +7 -0
- package/Server/Types/Database/Permissions/DeletePermission.ts +2 -0
- package/Server/Types/Database/Permissions/ReadPermission.ts +3 -0
- package/Server/Types/Database/Permissions/TenantPermission.ts +101 -16
- package/Server/Utils/AI/CodeFix/FixRunBudget.ts +2 -2
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +90 -11
- package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +1 -0
- package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +1 -0
- package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.ts +125 -0
- package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts +25 -15
- package/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts +256 -57
- package/Server/Utils/AI/SRE/Insights/InsightStore.ts +76 -18
- package/Server/Utils/AI/SRE/InvestigationTldr.ts +352 -0
- package/Server/Utils/AnalyticsDatabase/InsertDedupContext.ts +7 -2
- package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +1793 -0
- package/Server/Utils/Dashboard/PublicDashboardViewConfig.ts +65 -0
- package/Server/Utils/DataSource/ConnectorRegistry.ts +53 -0
- package/Server/Utils/DataSource/Connectors/ClickHouseConnector.ts +338 -0
- package/Server/Utils/DataSource/Connectors/ElasticsearchConnector.ts +717 -0
- package/Server/Utils/DataSource/Connectors/LokiConnector.ts +606 -0
- package/Server/Utils/DataSource/Connectors/MySqlConnector.ts +307 -0
- package/Server/Utils/DataSource/Connectors/PostgresConnector.ts +260 -0
- package/Server/Utils/DataSource/Connectors/PrometheusConnector.ts +555 -0
- package/Server/Utils/DataSource/Connectors/RestApiConnector.ts +597 -0
- package/Server/Utils/DataSource/Connectors/SqlServerConnector.ts +318 -0
- package/Server/Utils/DataSource/EgressGuard.ts +446 -0
- package/Server/Utils/DataSource/HttpFetch.ts +221 -0
- package/Server/Utils/DataSource/SqlQueryGuard.ts +383 -0
- package/Server/Utils/DataSource/SqlResultShaper.ts +372 -0
- package/Server/Utils/DataSource/Types.ts +93 -0
- package/Server/Utils/Database/PostgresErrorTranslator.ts +172 -17
- package/Server/Utils/InProcessMemo.ts +141 -0
- package/Server/Utils/InstanceHealth/TelemetryIngestion.ts +628 -0
- package/Server/Utils/Monitor/MonitorMetricUtil.ts +58 -0
- package/Server/Utils/Monitor/MonitorResource.ts +14 -0
- package/Server/Utils/Response.ts +12 -1
- package/Server/Utils/SSRFProtection.ts +237 -0
- package/Server/Utils/StartServer.ts +8 -0
- package/Server/Utils/StatusPageSubscriberWebhook.ts +30 -0
- package/Server/Utils/Telemetry/CaptureSpan.ts +30 -18
- package/Server/Utils/Telemetry/IngestionTimestamp.ts +75 -0
- package/Server/Utils/Telemetry/ResourceHeartbeat.ts +99 -7
- package/Server/Utils/Telemetry/Telemetry.ts +112 -1
- package/Server/Utils/Telemetry.ts +104 -3
- package/Server/Utils/VendorAssets.ts +165 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +28 -5
- package/Server/Utils/Workspace/Slack/Slack.ts +5 -0
- package/Server/Views/Partials/Head.ejs +21 -7
- package/Tests/App/AdminDashboard/AdminProjectsIdFilter.test.tsx +207 -0
- package/Tests/App/AdminDashboard/AdminUsersIdFilter.test.tsx +216 -0
- package/Tests/App/Dashboard/AIInsightViewActions.test.tsx +422 -0
- package/Tests/App/Dashboard/AddWidgetModal.test.tsx +10 -3
- package/Tests/App/Dashboard/AlertsSideMenu.test.tsx +387 -0
- package/Tests/App/Dashboard/ChatActivityFeed.test.tsx +199 -0
- package/Tests/App/Dashboard/DataSourceChartSyntheticConfig.test.tsx +736 -0
- package/Tests/App/Dashboard/DataSourceQueryEditor.test.tsx +868 -0
- package/Tests/App/Dashboard/DataSourceWidgetCatalog.test.ts +440 -0
- package/Tests/App/Dashboard/DataSourceWidgetFetching.test.tsx +2109 -0
- package/Tests/App/Dashboard/DataSourceWidgetViews.test.tsx +726 -0
- package/Tests/App/Dashboard/IncidentsSideMenu.test.tsx +447 -0
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +514 -3
- package/Tests/App/Dashboard/ProductMenuBreadcrumbs.test.tsx +391 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceSideMenu.test.tsx +326 -0
- package/Tests/App/Dashboard/SideMenuHarness.tsx +187 -0
- package/Tests/App/Dashboard/WidgetCatalog.test.ts +6 -1
- package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +1858 -0
- package/Tests/Models/DatabaseModels/DataSourceModelSecrets.test.ts +70 -0
- package/Tests/Server/API/AIInvestigationAPI.test.ts +187 -0
- package/Tests/Server/API/DashboardPublicDataSourceStrip.test.ts +686 -0
- package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +585 -823
- package/Tests/Server/API/DataSourceAPIRoutes.test.ts +486 -0
- package/Tests/Server/API/StatusPageSubscriberOwnership.test.ts +291 -0
- package/Tests/Server/API/UserAuthenticationAPI.test.ts +641 -0
- package/Tests/Server/Infrastructure/ClickhouseKeepAliveOptions.test.ts +441 -0
- package/Tests/Server/Middleware/TelemetryIngestTokenLog.test.ts +140 -0
- package/Tests/Server/Services/AIInsightService.test.ts +266 -11
- package/Tests/Server/Services/AIRunAnalysisTldrPersistence.test.ts +160 -0
- package/Tests/Server/Services/AIServiceDailyBudget.test.ts +4 -0
- package/Tests/Server/Services/AlertMetricResourceAttributes.test.ts +352 -0
- package/Tests/Server/Services/DataSourceServiceSettings.test.ts +244 -0
- package/Tests/Server/Services/HostServiceFindOrCreateMemo.test.ts +397 -0
- package/Tests/Server/Services/HostServiceUpdateLastSeen.test.ts +41 -2
- package/Tests/Server/Services/IncidentMetricResourceAttributes.test.ts +408 -0
- package/Tests/Server/Services/MonitorStatusServiceDeleteReferenceCleanup.test.ts +351 -0
- package/Tests/Server/Services/MonitorStatusServiceValidation.test.ts +171 -0
- package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +398 -0
- package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +19 -0
- package/Tests/Server/Services/ProjectCallSMSConfigCredentialUniqueness.test.ts +305 -0
- package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +36 -1
- package/Tests/Server/Services/RumSessionPinUniqueViolationRecovery.test.ts +163 -0
- package/Tests/Server/Services/UserAuthenticationService.test.ts +973 -0
- package/Tests/Server/Types/Database/ObjectIdColumnQuery.test.ts +262 -0
- package/Tests/Server/Types/Database/Permissions/TenantPermission.test.ts +358 -0
- package/Tests/Server/Utils/AI/FixRunBudget.test.ts +2 -2
- package/Tests/Server/Utils/AI/Insights/ExceptionSpikeDetector.test.ts +6 -1
- package/Tests/Server/Utils/AI/Insights/InsightStore.test.ts +121 -4
- package/Tests/Server/Utils/AI/Insights/NewExceptionDetector.test.ts +361 -10
- package/Tests/Server/Utils/AI/InvestigationSettlement.test.ts +292 -0
- package/Tests/Server/Utils/AI/InvestigationTldr.test.ts +623 -0
- package/Tests/Server/Utils/AI/InvestigationTldrWiring.test.ts +98 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +857 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardViewConfig.test.ts +480 -0
- package/Tests/Server/Utils/DataSource/ClickHouseConnector.test.ts +759 -0
- package/Tests/Server/Utils/DataSource/ConnectorRegistry.test.ts +37 -0
- package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +645 -0
- package/Tests/Server/Utils/DataSource/ElasticsearchConnector.test.ts +1206 -0
- package/Tests/Server/Utils/DataSource/HttpFetch.test.ts +616 -0
- package/Tests/Server/Utils/DataSource/LokiConnector.test.ts +970 -0
- package/Tests/Server/Utils/DataSource/MySqlConnector.test.ts +935 -0
- package/Tests/Server/Utils/DataSource/PostgresConnector.test.ts +854 -0
- package/Tests/Server/Utils/DataSource/PrometheusConnector.test.ts +881 -0
- package/Tests/Server/Utils/DataSource/RestApiConnector.test.ts +1020 -0
- package/Tests/Server/Utils/DataSource/SqlQueryGuard.test.ts +425 -0
- package/Tests/Server/Utils/DataSource/SqlResultShaper.test.ts +555 -0
- package/Tests/Server/Utils/DataSource/SqlServerConnector.test.ts +934 -0
- package/Tests/Server/Utils/Database/PostgresErrorTranslator.test.ts +228 -7
- package/Tests/Server/Utils/InProcessMemo.test.ts +292 -0
- package/Tests/Server/Utils/InstanceHealth/TelemetryIngestion.test.ts +960 -0
- package/Tests/Server/Utils/MicrosoftTeamsWebhookUrlValidation.test.ts +103 -0
- package/Tests/Server/Utils/Monitor/MonitorMetricResourceAttributes.test.ts +336 -0
- package/Tests/Server/Utils/OfflineAssetHygiene.test.ts +521 -0
- package/Tests/Server/Utils/ResponseRenderAnalytics.test.ts +143 -0
- package/Tests/Server/Utils/SSRFProtection.test.ts +193 -0
- package/Tests/Server/Utils/StatusPageSubscriberWebhook.test.ts +101 -0
- package/Tests/Server/Utils/TailwindBuildCopy.test.ts +225 -0
- package/Tests/Server/Utils/Telemetry/ResourceHeartbeatL1Memo.test.ts +355 -0
- package/Tests/Server/Utils/Telemetry/TelemetryFanInWriter.test.ts +128 -0
- package/Tests/Server/Utils/Telemetry/TelemetryUtilAttributeKeys.test.ts +381 -0
- package/Tests/Server/Utils/Telemetry.test.ts +87 -0
- package/Tests/Server/Utils/VendorAssetIntegrity.test.ts +343 -0
- package/Tests/Server/Utils/VendorAssets.test.ts +671 -0
- package/Tests/Server/Views/OfflineRender.test.ts +297 -0
- package/Tests/Types/Dashboard/DataSourceComponentTypes.test.ts +618 -0
- package/Tests/Types/DateClickhouseFormat.test.ts +192 -0
- package/Tests/Types/Password.test.ts +363 -0
- package/Tests/UI/Components/ConfirmModal.test.tsx +7 -0
- package/Tests/UI/Components/ErrorBoundary.test.tsx +53 -0
- package/Tests/UI/Components/Modal.test.tsx +281 -1
- package/Tests/UI/Components/ObjectIdFilterPipeline.test.tsx +396 -0
- package/Tests/UI/Components/StatusPage/ResourceGroupNavigator.test.tsx +1147 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +116 -1
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +2 -0
- package/Tests/Utils/Analytics.test.ts +23 -0
- package/Tests/Utils/Dashboard/Components/DashboardDataSourceComponents.test.ts +640 -0
- package/Tests/Utils/DataSource/DataSourceQueryText.test.ts +138 -0
- package/Tests/Utils/DataSource/DataSourceValueReducer.test.ts +526 -0
- package/Tests/Utils/Metrics/MetricResourceAttributeUtil.test.ts +691 -0
- package/Tests/Utils/StatusPage/GroupHierarchyView.test.ts +1452 -0
- package/Tests/Utils/StatusPage/ResourceExplorer.test.ts +931 -0
- package/Tests/Utils/Telemetry/CaptureSpanExportGating.test.ts +288 -0
- package/Tests/Utils/Telemetry/IngestionTimestamp.test.ts +170 -0
- package/Types/AI/AIInsightEvidence.ts +6 -0
- package/Types/Analytics/RevenueEvent.ts +31 -0
- package/Types/Dashboard/DashboardComponentType.ts +31 -0
- package/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.ts +27 -0
- package/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.ts +32 -0
- package/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.ts +30 -0
- package/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.ts +55 -0
- package/Types/DataSource/DataSourceLimits.ts +62 -0
- package/Types/DataSource/DataSourceQueryConfig.ts +41 -0
- package/Types/DataSource/DataSourceTableResult.ts +38 -0
- package/Types/DataSource/DataSourceType.ts +213 -0
- package/Types/Date.ts +43 -3
- package/Types/Password.ts +64 -0
- package/Types/Permission.ts +46 -0
- package/Types/UserAuthenticationStatus.ts +34 -0
- package/UI/Components/Button/Button.tsx +1 -1
- package/UI/Components/ErrorBoundary.tsx +459 -108
- package/UI/Components/Icon/Icon.tsx +10 -9
- package/UI/Components/Modal/ConfirmModal.tsx +6 -1
- package/UI/Components/Modal/Modal.tsx +267 -35
- package/UI/Components/Modal/ModalFooter.tsx +6 -1
- package/UI/Components/MoreMenu/MoreMenu.tsx +19 -4
- package/UI/Components/MoreMenu/MoreMenuItem.tsx +6 -1
- package/UI/Components/StatusPage/ResourceGrid.tsx +314 -0
- package/UI/Components/StatusPage/ResourceGroupNavigator.tsx +808 -0
- package/UI/Components/StatusPage/ResourceList.tsx +570 -0
- package/UI/Styles/Theme.css +18 -0
- package/UI/Utils/API/RequestOptions.ts +7 -0
- package/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.ts +1 -0
- package/UI/Utils/ModelAPI/ModelAPI.ts +1 -0
- package/UI/Utils/TestDataSource.ts +61 -0
- package/UI/esbuild-config.js +45 -0
- package/Utils/Analytics.ts +15 -0
- package/Utils/Dashboard/Components/DashboardDataSourceChartComponent.ts +88 -0
- package/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.ts +123 -0
- package/Utils/Dashboard/Components/DashboardDataSourceShared.ts +16 -0
- package/Utils/Dashboard/Components/DashboardDataSourceTableComponent.ts +72 -0
- package/Utils/Dashboard/Components/DashboardDataSourceValueComponent.ts +126 -0
- package/Utils/Dashboard/Components/Index.ts +28 -0
- package/Utils/DataSource/DataSourceQueryText.ts +94 -0
- package/Utils/DataSource/DataSourceValueReducer.ts +156 -0
- package/Utils/Metrics/MetricResourceAttributeUtil.ts +380 -0
- package/Utils/NetworkDiscovery/ScanTargetUtil.ts +8 -6
- package/Utils/StatusPage/GroupHierarchyView.ts +931 -0
- package/Utils/StatusPage/ResourceExplorer.ts +853 -0
- package/build/dist/Models/DatabaseModels/AIRun.js +34 -0
- package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DataSource.js +774 -0
- package/build/dist/Models/DatabaseModels/DataSource.js.map +1 -0
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js +14 -4
- package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/User.js +2 -0
- package/build/dist/Models/DatabaseModels/User.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserOnCallLog.js +2 -0
- package/build/dist/Models/DatabaseModels/UserOnCallLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js +2 -0
- package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserSession.js +2 -0
- package/build/dist/Models/DatabaseModels/UserSession.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserTotpAuth.js +6 -4
- package/build/dist/Models/DatabaseModels/UserTotpAuth.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserWebAuthn.js +5 -3
- package/build/dist/Models/DatabaseModels/UserWebAuthn.js.map +1 -1
- package/build/dist/Server/API/AIInsightAPI.js +34 -4
- package/build/dist/Server/API/AIInsightAPI.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +23 -0
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/DashboardAPI.js +119 -433
- package/build/dist/Server/API/DashboardAPI.js.map +1 -1
- package/build/dist/Server/API/DataSourceAPI.js +173 -0
- package/build/dist/Server/API/DataSourceAPI.js.map +1 -0
- package/build/dist/Server/API/StatusPageAPI.js +11 -1
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/UserAPI.js +94 -2
- package/build/dist/Server/API/UserAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/ClickhouseConfig.js +49 -0
- package/build/dist/Server/Infrastructure/ClickhouseConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.js +19 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.js +64 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/Queue.js +27 -0
- package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
- package/build/dist/Server/Infrastructure/QueueWorker.js +13 -0
- package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +8 -3
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/AIInsightService.js +110 -10
- package/build/dist/Server/Services/AIInsightService.js.map +1 -1
- package/build/dist/Server/Services/AIRunService.js +34 -0
- package/build/dist/Server/Services/AIRunService.js.map +1 -1
- package/build/dist/Server/Services/AIService.js +16 -2
- package/build/dist/Server/Services/AIService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +28 -35
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +8 -4
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DataSourceService.js +159 -0
- package/build/dist/Server/Services/DataSourceService.js.map +1 -0
- package/build/dist/Server/Services/HostService.js +74 -0
- package/build/dist/Server/Services/HostService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +35 -24
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +45 -0
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorStatusService.js +129 -0
- package/build/dist/Server/Services/MonitorStatusService.js.map +1 -1
- package/build/dist/Server/Services/OpenTelemetryIngestService.js +222 -159
- package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
- package/build/dist/Server/Services/RumSessionPinService.js +7 -15
- package/build/dist/Server/Services/RumSessionPinService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberService.js +10 -0
- package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +241 -10
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/BasePermission.js +6 -0
- package/build/dist/Server/Types/Database/Permissions/BasePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/DeletePermission.js +1 -0
- package/build/dist/Server/Types/Database/Permissions/DeletePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/ReadPermission.js +2 -0
- package/build/dist/Server/Types/Database/Permissions/ReadPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/TenantPermission.js +68 -12
- package/build/dist/Server/Types/Database/Permissions/TenantPermission.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +2 -2
- package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +68 -8
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +1 -0
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +1 -0
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.js +97 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js +17 -15
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js +178 -54
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js +65 -16
- package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationTldr.js +303 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationTldr.js.map +1 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/InsertDedupContext.js.map +1 -1
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +1261 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardViewConfig.js +47 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardViewConfig.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/ConnectorRegistry.js +42 -0
- package/build/dist/Server/Utils/DataSource/ConnectorRegistry.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/ClickHouseConnector.js +187 -0
- package/build/dist/Server/Utils/DataSource/Connectors/ClickHouseConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/ElasticsearchConnector.js +493 -0
- package/build/dist/Server/Utils/DataSource/Connectors/ElasticsearchConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/LokiConnector.js +399 -0
- package/build/dist/Server/Utils/DataSource/Connectors/LokiConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/MySqlConnector.js +195 -0
- package/build/dist/Server/Utils/DataSource/Connectors/MySqlConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/PostgresConnector.js +149 -0
- package/build/dist/Server/Utils/DataSource/Connectors/PostgresConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/PrometheusConnector.js +362 -0
- package/build/dist/Server/Utils/DataSource/Connectors/PrometheusConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/RestApiConnector.js +342 -0
- package/build/dist/Server/Utils/DataSource/Connectors/RestApiConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Connectors/SqlServerConnector.js +186 -0
- package/build/dist/Server/Utils/DataSource/Connectors/SqlServerConnector.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/EgressGuard.js +305 -0
- package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/HttpFetch.js +134 -0
- package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/SqlQueryGuard.js +331 -0
- package/build/dist/Server/Utils/DataSource/SqlQueryGuard.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/SqlResultShaper.js +280 -0
- package/build/dist/Server/Utils/DataSource/SqlResultShaper.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/Types.js +2 -0
- package/build/dist/Server/Utils/DataSource/Types.js.map +1 -0
- package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js +103 -9
- package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js.map +1 -1
- package/build/dist/Server/Utils/InProcessMemo.js +113 -0
- package/build/dist/Server/Utils/InProcessMemo.js.map +1 -0
- package/build/dist/Server/Utils/InstanceHealth/TelemetryIngestion.js +406 -0
- package/build/dist/Server/Utils/InstanceHealth/TelemetryIngestion.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +34 -0
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +14 -0
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Response.js +9 -1
- package/build/dist/Server/Utils/Response.js.map +1 -1
- package/build/dist/Server/Utils/SSRFProtection.js +192 -0
- package/build/dist/Server/Utils/SSRFProtection.js.map +1 -0
- package/build/dist/Server/Utils/StartServer.js +7 -0
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/StatusPageSubscriberWebhook.js +24 -0
- package/build/dist/Server/Utils/StatusPageSubscriberWebhook.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/CaptureSpan.js +25 -11
- package/build/dist/Server/Utils/Telemetry/CaptureSpan.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/IngestionTimestamp.js +32 -0
- package/build/dist/Server/Utils/Telemetry/IngestionTimestamp.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js +92 -5
- package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/Telemetry.js +92 -6
- package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry.js +93 -6
- package/build/dist/Server/Utils/Telemetry.js.map +1 -1
- package/build/dist/Server/Utils/VendorAssets.js +121 -0
- package/build/dist/Server/Utils/VendorAssets.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +25 -4
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js +5 -0
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
- package/build/dist/Types/Analytics/RevenueEvent.js +26 -0
- package/build/dist/Types/Analytics/RevenueEvent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js +27 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.js +16 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.js.map +1 -0
- package/build/dist/Types/DataSource/DataSourceLimits.js +47 -0
- package/build/dist/Types/DataSource/DataSourceLimits.js.map +1 -0
- package/build/dist/Types/DataSource/DataSourceQueryConfig.js +10 -0
- package/build/dist/Types/DataSource/DataSourceQueryConfig.js.map +1 -0
- package/build/dist/Types/DataSource/DataSourceTableResult.js +14 -0
- package/build/dist/Types/DataSource/DataSourceTableResult.js.map +1 -0
- package/build/dist/Types/DataSource/DataSourceType.js +183 -0
- package/build/dist/Types/DataSource/DataSourceType.js.map +1 -0
- package/build/dist/Types/Date.js +38 -3
- package/build/dist/Types/Date.js.map +1 -1
- package/build/dist/Types/Password.js +56 -0
- package/build/dist/Types/Password.js.map +1 -0
- package/build/dist/Types/Permission.js +42 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/UserAuthenticationStatus.js +2 -0
- package/build/dist/Types/UserAuthenticationStatus.js.map +1 -0
- package/build/dist/UI/Components/ErrorBoundary.js +388 -72
- package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +10 -4
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/Modal/ConfirmModal.js +1 -1
- package/build/dist/UI/Components/Modal/ConfirmModal.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +178 -19
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/Modal/ModalFooter.js +3 -1
- package/build/dist/UI/Components/Modal/ModalFooter.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js +9 -6
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +7 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceGrid.js +119 -0
- package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -0
- package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js +354 -0
- package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js.map +1 -0
- package/build/dist/UI/Components/StatusPage/ResourceList.js +203 -0
- package/build/dist/UI/Components/StatusPage/ResourceList.js.map +1 -0
- package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js +1 -6
- package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +3 -8
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/TestDataSource.js +39 -0
- package/build/dist/UI/Utils/TestDataSource.js.map +1 -0
- package/build/dist/Utils/Analytics.js +4 -0
- package/build/dist/Utils/Analytics.js.map +1 -1
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceChartComponent.js +79 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceChartComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.js +111 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceShared.js +15 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceShared.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceTableComponent.js +62 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceTableComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceValueComponent.js +112 -0
- package/build/dist/Utils/Dashboard/Components/DashboardDataSourceValueComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/Index.js +16 -0
- package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
- package/build/dist/Utils/DataSource/DataSourceQueryText.js +64 -0
- package/build/dist/Utils/DataSource/DataSourceQueryText.js.map +1 -0
- package/build/dist/Utils/DataSource/DataSourceValueReducer.js +124 -0
- package/build/dist/Utils/DataSource/DataSourceValueReducer.js.map +1 -0
- package/build/dist/Utils/Metrics/MetricResourceAttributeUtil.js +281 -0
- package/build/dist/Utils/Metrics/MetricResourceAttributeUtil.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js +8 -6
- package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js.map +1 -1
- package/build/dist/Utils/StatusPage/GroupHierarchyView.js +560 -0
- package/build/dist/Utils/StatusPage/GroupHierarchyView.js.map +1 -0
- package/build/dist/Utils/StatusPage/ResourceExplorer.js +519 -0
- package/build/dist/Utils/StatusPage/ResourceExplorer.js.map +1 -0
- package/jest.config.json +1 -0
- package/package.json +5 -1
- package/tsconfig.json +12 -10
|
@@ -0,0 +1,628 @@
|
|
|
1
|
+
import { ClickhouseDatabase } from "../../EnvironmentConfig";
|
|
2
|
+
import {
|
|
3
|
+
ClickhouseAppInstance,
|
|
4
|
+
ClickhouseClient,
|
|
5
|
+
} from "../../Infrastructure/ClickhouseDatabase";
|
|
6
|
+
import AnalyticsTableName from "../../../Types/AnalyticsDatabase/AnalyticsTableName";
|
|
7
|
+
import { JSONObject } from "../../../Types/JSON";
|
|
8
|
+
import logger from "../Logger";
|
|
9
|
+
import {
|
|
10
|
+
getClickhouseClusterName,
|
|
11
|
+
getStorageTableName,
|
|
12
|
+
} from "../AnalyticsDatabase/ClusterConfig";
|
|
13
|
+
|
|
14
|
+
/*
|
|
15
|
+
* -----------------------------------------------------------------------------
|
|
16
|
+
* Telemetry ingestion probes for the master-admin OneUptime Health dashboard.
|
|
17
|
+
*
|
|
18
|
+
* Two views over the same three tables:
|
|
19
|
+
*
|
|
20
|
+
* - by SIGNAL — how many log / metric / trace rows landed in ClickHouse over
|
|
21
|
+
* the last minute, hour and day, plus each signal's actual
|
|
22
|
+
* (uncompressed) footprint. This answers "is the pipeline
|
|
23
|
+
* flowing, and how fast".
|
|
24
|
+
* - by PROJECT — the same three windows split per tenant, which answers
|
|
25
|
+
* "who is sending it" — the question behind a sudden ingest
|
|
26
|
+
* spike, a noisy-neighbour investigation or a capacity
|
|
27
|
+
* conversation with one customer.
|
|
28
|
+
*
|
|
29
|
+
* Only counts and size metadata are read; no telemetry row data ever leaves
|
|
30
|
+
* ClickHouse through here. Every query is capped with max_execution_time so a
|
|
31
|
+
* dashboard poll can never pin the cluster.
|
|
32
|
+
* -----------------------------------------------------------------------------
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
export enum TelemetryIngestionSignal {
|
|
36
|
+
Logs = "Logs",
|
|
37
|
+
Metrics = "Metrics",
|
|
38
|
+
Traces = "Traces",
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface TelemetryIngestionSignalSpec {
|
|
42
|
+
telemetryType: TelemetryIngestionSignal;
|
|
43
|
+
table: AnalyticsTableName;
|
|
44
|
+
// The event-time column this table is partitioned and primary-key ordered on.
|
|
45
|
+
timeColumn: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface TelemetryIngestionCounts {
|
|
49
|
+
lastMinute: number | null;
|
|
50
|
+
lastHour: number | null;
|
|
51
|
+
lastDay: number | null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface TelemetrySignalIngestion extends TelemetryIngestionCounts {
|
|
55
|
+
telemetryType: string;
|
|
56
|
+
table: string;
|
|
57
|
+
uncompressedBytes: number | null;
|
|
58
|
+
available: boolean;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface TelemetrySignalIngestionResult {
|
|
62
|
+
connected: boolean;
|
|
63
|
+
tables: Array<TelemetrySignalIngestion>;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// One project's counts for one signal.
|
|
67
|
+
export interface TelemetryProjectSignalIngestion
|
|
68
|
+
extends TelemetryIngestionCounts {
|
|
69
|
+
telemetryType: string;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface TelemetryProjectIngestion extends TelemetryIngestionCounts {
|
|
73
|
+
projectId: string;
|
|
74
|
+
// Filled in by attachProjectNames; null when the project no longer exists.
|
|
75
|
+
projectName: string | null;
|
|
76
|
+
signals: Array<TelemetryProjectSignalIngestion>;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// A single GROUP BY projectId row, before the three signals are merged.
|
|
80
|
+
export interface TelemetryProjectIngestionRow extends TelemetryIngestionCounts {
|
|
81
|
+
projectId: string;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface TelemetrySignalProjectRows {
|
|
85
|
+
telemetryType: string;
|
|
86
|
+
/*
|
|
87
|
+
* False when the per-project query failed for this signal (missing table,
|
|
88
|
+
* timeout). The signal's counts then stay null for every project instead of
|
|
89
|
+
* being reported as a truthful-looking zero.
|
|
90
|
+
*/
|
|
91
|
+
available: boolean;
|
|
92
|
+
// True when the signal had more projects than the per-signal cap allowed.
|
|
93
|
+
truncated: boolean;
|
|
94
|
+
rows: Array<TelemetryProjectIngestionRow>;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface TelemetryProjectIngestionResult {
|
|
98
|
+
connected: boolean;
|
|
99
|
+
projects: Array<TelemetryProjectIngestion>;
|
|
100
|
+
signals: Array<{
|
|
101
|
+
telemetryType: string;
|
|
102
|
+
available: boolean;
|
|
103
|
+
truncated: boolean;
|
|
104
|
+
}>;
|
|
105
|
+
truncated: boolean;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/*
|
|
109
|
+
* The three telemetry signals OneUptime ingests into ClickHouse and the
|
|
110
|
+
* event-time column each table is partitioned + primary-key ordered on. We count
|
|
111
|
+
* ingestion on THIS column (never `createdAt`) precisely because it is the
|
|
112
|
+
* partition key (toYYYYMMDD) and the leading primary-key column: ClickHouse can
|
|
113
|
+
* prune to the last day's partitions and use the primary index, so the count
|
|
114
|
+
* stays cheap even on multi-billion-row tables. `createdAt` — the true write
|
|
115
|
+
* time — is unindexed and unpartitioned here, so filtering on it would force a
|
|
116
|
+
* full-table scan; for a live pipeline event-time and write-time agree to within
|
|
117
|
+
* seconds, and the only divergence (historical backfill) is not what a
|
|
118
|
+
* "current ingestion rate" view is meant to show.
|
|
119
|
+
*/
|
|
120
|
+
export const TELEMETRY_INGESTION_SIGNALS: Array<TelemetryIngestionSignalSpec> =
|
|
121
|
+
[
|
|
122
|
+
{
|
|
123
|
+
telemetryType: TelemetryIngestionSignal.Logs,
|
|
124
|
+
table: AnalyticsTableName.Log,
|
|
125
|
+
timeColumn: "time",
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
telemetryType: TelemetryIngestionSignal.Metrics,
|
|
129
|
+
table: AnalyticsTableName.Metric,
|
|
130
|
+
timeColumn: "time",
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
telemetryType: TelemetryIngestionSignal.Traces,
|
|
134
|
+
table: AnalyticsTableName.Span,
|
|
135
|
+
timeColumn: "startTime",
|
|
136
|
+
},
|
|
137
|
+
];
|
|
138
|
+
|
|
139
|
+
/*
|
|
140
|
+
* How many projects one signal's GROUP BY may return. Every OneUptime instance
|
|
141
|
+
* we have seen has far fewer active tenants than this, so the cap is a runaway
|
|
142
|
+
* guard rather than a real ceiling — but when it does bite, the caller is told
|
|
143
|
+
* (`truncated`) so the page can say the list is partial instead of quietly
|
|
144
|
+
* dropping tenants off the bottom.
|
|
145
|
+
*/
|
|
146
|
+
export const MAX_PROJECTS_PER_SIGNAL: number = 500;
|
|
147
|
+
|
|
148
|
+
// Every diagnostic query here is read-only, and none of them may outlive this.
|
|
149
|
+
const QUERY_TIMEOUT_IN_SECONDS: number = 10;
|
|
150
|
+
|
|
151
|
+
type ClickhouseJsonResult = { data: Array<JSONObject> };
|
|
152
|
+
|
|
153
|
+
function escapeStringLiteral(value: string): string {
|
|
154
|
+
return value.replace(/'/g, "''");
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function quoteIdentifier(value: string): string {
|
|
158
|
+
return `\`${value.replace(/`/g, "``")}\``;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/*
|
|
162
|
+
* ClickHouse returns UInt64 aggregates as JSON strings. A value we could not
|
|
163
|
+
* read stays null and renders as "—" rather than as a confident zero.
|
|
164
|
+
*/
|
|
165
|
+
export function toCountOrNull(value: unknown): number | null {
|
|
166
|
+
if (value === null || value === undefined || value === "") {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const parsed: number = Number(value);
|
|
171
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/*
|
|
175
|
+
* Sum counts where null means "unknown". A total is only meaningful when at
|
|
176
|
+
* least one input reported a number, so an all-unknown sum stays unknown
|
|
177
|
+
* instead of collapsing to 0.
|
|
178
|
+
*/
|
|
179
|
+
export function sumCountsOrNull(values: Array<number | null>): number | null {
|
|
180
|
+
const known: Array<number> = values.filter(
|
|
181
|
+
(value: number | null): value is number => {
|
|
182
|
+
return value !== null;
|
|
183
|
+
},
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
if (known.length === 0) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return known.reduce((sum: number, value: number): number => {
|
|
191
|
+
return sum + value;
|
|
192
|
+
}, 0);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/*
|
|
196
|
+
* Counts for one table across the three windows. All three come from ONE scan:
|
|
197
|
+
* the WHERE clause bounds it to the last day (so only the last day's partitions
|
|
198
|
+
* are touched) and countIf picks the smaller windows out of that same pass. The
|
|
199
|
+
* upper `<= now()` bound stops a future-dated event from inflating the counts.
|
|
200
|
+
*/
|
|
201
|
+
export function buildSignalIngestionQuery(data: {
|
|
202
|
+
spec: TelemetryIngestionSignalSpec;
|
|
203
|
+
databaseName: string;
|
|
204
|
+
}): string {
|
|
205
|
+
const timeColumn: string = quoteIdentifier(data.spec.timeColumn);
|
|
206
|
+
|
|
207
|
+
return (
|
|
208
|
+
"SELECT " +
|
|
209
|
+
`countIf(${timeColumn} >= now() - INTERVAL 1 MINUTE) AS last_minute, ` +
|
|
210
|
+
`countIf(${timeColumn} >= now() - INTERVAL 1 HOUR) AS last_hour, ` +
|
|
211
|
+
"count() AS last_day " +
|
|
212
|
+
`FROM ${quoteIdentifier(data.databaseName)}.${quoteIdentifier(
|
|
213
|
+
data.spec.table,
|
|
214
|
+
)} ` +
|
|
215
|
+
`WHERE ${timeColumn} >= now() - INTERVAL 1 DAY AND ${timeColumn} <= now()`
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/*
|
|
220
|
+
* The same three windows, split by tenant. projectId is the LEADING primary-key
|
|
221
|
+
* column of all three telemetry tables, so this is the one dimension the tables
|
|
222
|
+
* can be grouped on without paying for a full scan of the day's partitions.
|
|
223
|
+
*
|
|
224
|
+
* Ordered by the widest window descending so that, if the cap ever bites, it is
|
|
225
|
+
* the smallest tenants that fall off rather than an arbitrary slice; projectId
|
|
226
|
+
* breaks ties so the list is stable between refreshes.
|
|
227
|
+
*/
|
|
228
|
+
export function buildProjectIngestionQuery(data: {
|
|
229
|
+
spec: TelemetryIngestionSignalSpec;
|
|
230
|
+
databaseName: string;
|
|
231
|
+
limit: number;
|
|
232
|
+
}): string {
|
|
233
|
+
const timeColumn: string = quoteIdentifier(data.spec.timeColumn);
|
|
234
|
+
|
|
235
|
+
return (
|
|
236
|
+
"SELECT projectId AS project_id, " +
|
|
237
|
+
`countIf(${timeColumn} >= now() - INTERVAL 1 MINUTE) AS last_minute, ` +
|
|
238
|
+
`countIf(${timeColumn} >= now() - INTERVAL 1 HOUR) AS last_hour, ` +
|
|
239
|
+
"count() AS last_day " +
|
|
240
|
+
`FROM ${quoteIdentifier(data.databaseName)}.${quoteIdentifier(
|
|
241
|
+
data.spec.table,
|
|
242
|
+
)} ` +
|
|
243
|
+
`WHERE ${timeColumn} >= now() - INTERVAL 1 DAY AND ${timeColumn} <= now() ` +
|
|
244
|
+
"GROUP BY projectId " +
|
|
245
|
+
"ORDER BY last_day DESC, project_id ASC " +
|
|
246
|
+
`LIMIT ${Math.max(1, Math.floor(data.limit))}`
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/*
|
|
251
|
+
* Total ACTUAL (uncompressed) data volume per telemetry table, read from
|
|
252
|
+
* system.parts metadata — the real data size, not the compressed bytes_on_disk.
|
|
253
|
+
* It is a metadata aggregate (no data scan), so it stays cheap regardless of
|
|
254
|
+
* table size.
|
|
255
|
+
*
|
|
256
|
+
* Two cluster subtleties are handled here:
|
|
257
|
+
*
|
|
258
|
+
* 1. The app-facing table names (LogItemV3, …) are Distributed wrappers, which
|
|
259
|
+
* hold NO parts of their own — the rows live in the per-shard local storage
|
|
260
|
+
* tables (`<tableName>Local`). So we filter system.parts on the *Local
|
|
261
|
+
* names (and key the size map by them); the Distributed names would match
|
|
262
|
+
* nothing and leave every "Actual size" cell blank.
|
|
263
|
+
*
|
|
264
|
+
* 2. system.parts is node-local, so a plain read would only size the connected
|
|
265
|
+
* node's shard. We read it through `cluster(<name>, system.parts)` which —
|
|
266
|
+
* like the Distributed read path the ingestion counts use — hits ONE replica
|
|
267
|
+
* per shard, so sum(...) GROUP BY table totals every shard exactly once (no
|
|
268
|
+
* replica double-counting; clusterAllReplicas would overcount by the
|
|
269
|
+
* replication factor). On a single-node "cluster of one" this equals
|
|
270
|
+
* reading system.parts directly.
|
|
271
|
+
*/
|
|
272
|
+
export function buildTelemetryStorageSizeQuery(data: {
|
|
273
|
+
clusterName: string;
|
|
274
|
+
databaseName: string;
|
|
275
|
+
storageTableNames: Array<string>;
|
|
276
|
+
}): string {
|
|
277
|
+
const tableList: string = data.storageTableNames
|
|
278
|
+
.map((tableName: string): string => {
|
|
279
|
+
return `'${escapeStringLiteral(tableName)}'`;
|
|
280
|
+
})
|
|
281
|
+
.join(", ");
|
|
282
|
+
|
|
283
|
+
return (
|
|
284
|
+
"SELECT table, sum(data_uncompressed_bytes) AS uncompressed_bytes " +
|
|
285
|
+
`FROM cluster('${escapeStringLiteral(data.clusterName)}', system.parts) ` +
|
|
286
|
+
`WHERE active AND database = '${escapeStringLiteral(
|
|
287
|
+
data.databaseName,
|
|
288
|
+
)}' AND table IN (${tableList}) ` +
|
|
289
|
+
"GROUP BY table"
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/*
|
|
294
|
+
* Fold the three per-signal GROUP BY results into one row per project.
|
|
295
|
+
*
|
|
296
|
+
* A project that appears in one signal's rows but not another's really did
|
|
297
|
+
* ingest zero of that signal, so it gets 0 — but only when that signal's query
|
|
298
|
+
* SUCCEEDED. When the query failed the signal is unknown for every project and
|
|
299
|
+
* stays null, which is what keeps a missing table from reading as "this tenant
|
|
300
|
+
* stopped sending traces".
|
|
301
|
+
*
|
|
302
|
+
* Rows come back ordered by the day window descending, the order the page shows
|
|
303
|
+
* them in; projectId breaks ties so the order does not shuffle between polls.
|
|
304
|
+
*/
|
|
305
|
+
export function mergeProjectIngestionRows(
|
|
306
|
+
signalResults: Array<TelemetrySignalProjectRows>,
|
|
307
|
+
): Array<TelemetryProjectIngestion> {
|
|
308
|
+
const countsByProject: Map<
|
|
309
|
+
string,
|
|
310
|
+
Map<string, TelemetryIngestionCounts>
|
|
311
|
+
> = new Map();
|
|
312
|
+
|
|
313
|
+
for (const signalResult of signalResults) {
|
|
314
|
+
if (!signalResult.available) {
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
for (const row of signalResult.rows) {
|
|
319
|
+
const byTelemetryType: Map<string, TelemetryIngestionCounts> =
|
|
320
|
+
countsByProject.get(row.projectId) ||
|
|
321
|
+
new Map<string, TelemetryIngestionCounts>();
|
|
322
|
+
|
|
323
|
+
byTelemetryType.set(signalResult.telemetryType, {
|
|
324
|
+
lastMinute: row.lastMinute,
|
|
325
|
+
lastHour: row.lastHour,
|
|
326
|
+
lastDay: row.lastDay,
|
|
327
|
+
});
|
|
328
|
+
countsByProject.set(row.projectId, byTelemetryType);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const projects: Array<TelemetryProjectIngestion> = [];
|
|
333
|
+
|
|
334
|
+
for (const [projectId, byTelemetryType] of countsByProject) {
|
|
335
|
+
const signals: Array<TelemetryProjectSignalIngestion> = signalResults.map(
|
|
336
|
+
(
|
|
337
|
+
signalResult: TelemetrySignalProjectRows,
|
|
338
|
+
): TelemetryProjectSignalIngestion => {
|
|
339
|
+
const counts: TelemetryIngestionCounts | undefined =
|
|
340
|
+
signalResult.available
|
|
341
|
+
? byTelemetryType.get(signalResult.telemetryType) || {
|
|
342
|
+
lastMinute: 0,
|
|
343
|
+
lastHour: 0,
|
|
344
|
+
lastDay: 0,
|
|
345
|
+
}
|
|
346
|
+
: undefined;
|
|
347
|
+
|
|
348
|
+
return {
|
|
349
|
+
telemetryType: signalResult.telemetryType,
|
|
350
|
+
lastMinute: counts ? counts.lastMinute : null,
|
|
351
|
+
lastHour: counts ? counts.lastHour : null,
|
|
352
|
+
lastDay: counts ? counts.lastDay : null,
|
|
353
|
+
};
|
|
354
|
+
},
|
|
355
|
+
);
|
|
356
|
+
|
|
357
|
+
projects.push({
|
|
358
|
+
projectId,
|
|
359
|
+
projectName: null,
|
|
360
|
+
signals,
|
|
361
|
+
lastMinute: sumCountsOrNull(
|
|
362
|
+
signals.map(
|
|
363
|
+
(signal: TelemetryProjectSignalIngestion): number | null => {
|
|
364
|
+
return signal.lastMinute;
|
|
365
|
+
},
|
|
366
|
+
),
|
|
367
|
+
),
|
|
368
|
+
lastHour: sumCountsOrNull(
|
|
369
|
+
signals.map(
|
|
370
|
+
(signal: TelemetryProjectSignalIngestion): number | null => {
|
|
371
|
+
return signal.lastHour;
|
|
372
|
+
},
|
|
373
|
+
),
|
|
374
|
+
),
|
|
375
|
+
lastDay: sumCountsOrNull(
|
|
376
|
+
signals.map(
|
|
377
|
+
(signal: TelemetryProjectSignalIngestion): number | null => {
|
|
378
|
+
return signal.lastDay;
|
|
379
|
+
},
|
|
380
|
+
),
|
|
381
|
+
),
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
return projects.sort(
|
|
386
|
+
(
|
|
387
|
+
left: TelemetryProjectIngestion,
|
|
388
|
+
right: TelemetryProjectIngestion,
|
|
389
|
+
): number => {
|
|
390
|
+
return (
|
|
391
|
+
(right.lastDay ?? 0) - (left.lastDay ?? 0) ||
|
|
392
|
+
left.projectId.localeCompare(right.projectId)
|
|
393
|
+
);
|
|
394
|
+
},
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/*
|
|
399
|
+
* ClickHouse only knows tenants by id. Names come from Postgres, and a project
|
|
400
|
+
* deleted while its telemetry is still inside the retention window has none —
|
|
401
|
+
* that project keeps a null name and the page labels it by id, rather than
|
|
402
|
+
* disappearing from a total it still contributes to.
|
|
403
|
+
*/
|
|
404
|
+
export function attachProjectNames(
|
|
405
|
+
projects: Array<TelemetryProjectIngestion>,
|
|
406
|
+
namesByProjectId: Map<string, string>,
|
|
407
|
+
): Array<TelemetryProjectIngestion> {
|
|
408
|
+
return projects.map(
|
|
409
|
+
(project: TelemetryProjectIngestion): TelemetryProjectIngestion => {
|
|
410
|
+
return {
|
|
411
|
+
...project,
|
|
412
|
+
projectName: namesByProjectId.get(project.projectId) || null,
|
|
413
|
+
};
|
|
414
|
+
},
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
function getClient(): ClickhouseClient | null {
|
|
419
|
+
return ClickhouseAppInstance.getDataSource();
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
async function queryJson(
|
|
423
|
+
client: ClickhouseClient,
|
|
424
|
+
query: string,
|
|
425
|
+
): Promise<Array<JSONObject>> {
|
|
426
|
+
const result: ClickhouseJsonResult = (await (
|
|
427
|
+
await client.query({
|
|
428
|
+
query,
|
|
429
|
+
format: "JSON",
|
|
430
|
+
clickhouse_settings: {
|
|
431
|
+
max_execution_time: QUERY_TIMEOUT_IN_SECONDS,
|
|
432
|
+
},
|
|
433
|
+
})
|
|
434
|
+
).json()) as ClickhouseJsonResult;
|
|
435
|
+
|
|
436
|
+
return result.data || [];
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/*
|
|
440
|
+
* Ingestion throughput per signal, with each signal's actual (uncompressed)
|
|
441
|
+
* footprint alongside it. Each table is probed independently so a missing table
|
|
442
|
+
* (e.g. an instance that only ingests logs) degrades gracefully rather than
|
|
443
|
+
* blanking the whole card.
|
|
444
|
+
*/
|
|
445
|
+
export async function getTelemetryIngestionBySignal(): Promise<TelemetrySignalIngestionResult> {
|
|
446
|
+
const result: TelemetrySignalIngestionResult = {
|
|
447
|
+
connected: false,
|
|
448
|
+
tables: [],
|
|
449
|
+
};
|
|
450
|
+
|
|
451
|
+
try {
|
|
452
|
+
const client: ClickhouseClient | null = getClient();
|
|
453
|
+
|
|
454
|
+
if (!client) {
|
|
455
|
+
return result;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
result["connected"] = true;
|
|
459
|
+
|
|
460
|
+
/*
|
|
461
|
+
* Guarded independently so a failure here never drops the ingestion counts
|
|
462
|
+
* below — a blank "Actual size" column is a much smaller loss than a blank
|
|
463
|
+
* ingestion rate.
|
|
464
|
+
*/
|
|
465
|
+
const uncompressedBytesByStorageTable: Map<string, number | null> =
|
|
466
|
+
new Map();
|
|
467
|
+
|
|
468
|
+
try {
|
|
469
|
+
const rows: Array<JSONObject> = await queryJson(
|
|
470
|
+
client,
|
|
471
|
+
buildTelemetryStorageSizeQuery({
|
|
472
|
+
clusterName: getClickhouseClusterName(),
|
|
473
|
+
databaseName: ClickhouseDatabase,
|
|
474
|
+
storageTableNames: TELEMETRY_INGESTION_SIGNALS.map(
|
|
475
|
+
(spec: TelemetryIngestionSignalSpec): string => {
|
|
476
|
+
return getStorageTableName(String(spec.table));
|
|
477
|
+
},
|
|
478
|
+
),
|
|
479
|
+
}),
|
|
480
|
+
);
|
|
481
|
+
|
|
482
|
+
for (const row of rows) {
|
|
483
|
+
uncompressedBytesByStorageTable.set(
|
|
484
|
+
String(row["table"]),
|
|
485
|
+
toCountOrNull(row["uncompressed_bytes"]),
|
|
486
|
+
);
|
|
487
|
+
}
|
|
488
|
+
} catch (err) {
|
|
489
|
+
logger.debug("AdminHealth: telemetry uncompressed-size query failed");
|
|
490
|
+
logger.debug(err);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
for (const spec of TELEMETRY_INGESTION_SIGNALS) {
|
|
494
|
+
const entry: TelemetrySignalIngestion = {
|
|
495
|
+
telemetryType: spec.telemetryType,
|
|
496
|
+
table: String(spec.table),
|
|
497
|
+
lastMinute: null,
|
|
498
|
+
lastHour: null,
|
|
499
|
+
lastDay: null,
|
|
500
|
+
uncompressedBytes:
|
|
501
|
+
uncompressedBytesByStorageTable.get(
|
|
502
|
+
getStorageTableName(String(spec.table)),
|
|
503
|
+
) ?? null,
|
|
504
|
+
available: false,
|
|
505
|
+
};
|
|
506
|
+
|
|
507
|
+
try {
|
|
508
|
+
const rows: Array<JSONObject> = await queryJson(
|
|
509
|
+
client,
|
|
510
|
+
buildSignalIngestionQuery({
|
|
511
|
+
spec,
|
|
512
|
+
databaseName: ClickhouseDatabase,
|
|
513
|
+
}),
|
|
514
|
+
);
|
|
515
|
+
const row: JSONObject = rows[0] || {};
|
|
516
|
+
|
|
517
|
+
entry.lastMinute = toCountOrNull(row["last_minute"]);
|
|
518
|
+
entry.lastHour = toCountOrNull(row["last_hour"]);
|
|
519
|
+
entry.lastDay = toCountOrNull(row["last_day"]);
|
|
520
|
+
entry.available = true;
|
|
521
|
+
} catch (err) {
|
|
522
|
+
logger.debug(
|
|
523
|
+
`AdminHealth: telemetry ingestion query failed for ${spec.table}`,
|
|
524
|
+
);
|
|
525
|
+
logger.debug(err);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
result.tables.push(entry);
|
|
529
|
+
}
|
|
530
|
+
} catch (err) {
|
|
531
|
+
logger.error("AdminHealth: failed to read ClickHouse telemetry ingestion");
|
|
532
|
+
logger.error(err);
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
return result;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/*
|
|
539
|
+
* Ingestion split by tenant. Each signal is queried independently — one failing
|
|
540
|
+
* table must not blank the other two — and the three results are folded into one
|
|
541
|
+
* row per project. Names are NOT resolved here: they live in Postgres, and the
|
|
542
|
+
* caller attaches them with attachProjectNames.
|
|
543
|
+
*/
|
|
544
|
+
export async function getTelemetryIngestionByProject(): Promise<TelemetryProjectIngestionResult> {
|
|
545
|
+
const result: TelemetryProjectIngestionResult = {
|
|
546
|
+
connected: false,
|
|
547
|
+
projects: [],
|
|
548
|
+
signals: [],
|
|
549
|
+
truncated: false,
|
|
550
|
+
};
|
|
551
|
+
|
|
552
|
+
try {
|
|
553
|
+
const client: ClickhouseClient | null = getClient();
|
|
554
|
+
|
|
555
|
+
if (!client) {
|
|
556
|
+
return result;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
result.connected = true;
|
|
560
|
+
|
|
561
|
+
const signalResults: Array<TelemetrySignalProjectRows> = [];
|
|
562
|
+
|
|
563
|
+
for (const spec of TELEMETRY_INGESTION_SIGNALS) {
|
|
564
|
+
const signalResult: TelemetrySignalProjectRows = {
|
|
565
|
+
telemetryType: spec.telemetryType,
|
|
566
|
+
available: false,
|
|
567
|
+
truncated: false,
|
|
568
|
+
rows: [],
|
|
569
|
+
};
|
|
570
|
+
|
|
571
|
+
try {
|
|
572
|
+
const rows: Array<JSONObject> = await queryJson(
|
|
573
|
+
client,
|
|
574
|
+
buildProjectIngestionQuery({
|
|
575
|
+
spec,
|
|
576
|
+
databaseName: ClickhouseDatabase,
|
|
577
|
+
limit: MAX_PROJECTS_PER_SIGNAL,
|
|
578
|
+
}),
|
|
579
|
+
);
|
|
580
|
+
|
|
581
|
+
signalResult.rows = rows.map(
|
|
582
|
+
(row: JSONObject): TelemetryProjectIngestionRow => {
|
|
583
|
+
return {
|
|
584
|
+
projectId: String(row["project_id"] || ""),
|
|
585
|
+
lastMinute: toCountOrNull(row["last_minute"]),
|
|
586
|
+
lastHour: toCountOrNull(row["last_hour"]),
|
|
587
|
+
lastDay: toCountOrNull(row["last_day"]),
|
|
588
|
+
};
|
|
589
|
+
},
|
|
590
|
+
);
|
|
591
|
+
signalResult.available = true;
|
|
592
|
+
signalResult.truncated = rows.length >= MAX_PROJECTS_PER_SIGNAL;
|
|
593
|
+
} catch (err) {
|
|
594
|
+
logger.debug(
|
|
595
|
+
`AdminHealth: per-project telemetry ingestion query failed for ${spec.table}`,
|
|
596
|
+
);
|
|
597
|
+
logger.debug(err);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
signalResults.push(signalResult);
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
result.projects = mergeProjectIngestionRows(signalResults);
|
|
604
|
+
result.signals = signalResults.map(
|
|
605
|
+
(
|
|
606
|
+
signalResult: TelemetrySignalProjectRows,
|
|
607
|
+
): { telemetryType: string; available: boolean; truncated: boolean } => {
|
|
608
|
+
return {
|
|
609
|
+
telemetryType: signalResult.telemetryType,
|
|
610
|
+
available: signalResult.available,
|
|
611
|
+
truncated: signalResult.truncated,
|
|
612
|
+
};
|
|
613
|
+
},
|
|
614
|
+
);
|
|
615
|
+
result.truncated = signalResults.some(
|
|
616
|
+
(signalResult: TelemetrySignalProjectRows): boolean => {
|
|
617
|
+
return signalResult.truncated;
|
|
618
|
+
},
|
|
619
|
+
);
|
|
620
|
+
} catch (err) {
|
|
621
|
+
logger.error(
|
|
622
|
+
"AdminHealth: failed to read per-project ClickHouse telemetry ingestion",
|
|
623
|
+
);
|
|
624
|
+
logger.error(err);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
return result;
|
|
628
|
+
}
|