@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
|
@@ -32,6 +32,13 @@ export default class BasePermission {
|
|
|
32
32
|
props: DatabaseCommonInteractionProps,
|
|
33
33
|
type: DatabaseRequestType,
|
|
34
34
|
): Promise<CheckPermissionBaseInterface<TBaseModel>> {
|
|
35
|
+
/*
|
|
36
|
+
* Permission checks add predicates and QueryUtil serializes values in
|
|
37
|
+
* place. Callers such as BaseAPI intentionally reuse the original query
|
|
38
|
+
* for list and count, so work on a fresh top-level object.
|
|
39
|
+
*/
|
|
40
|
+
query = { ...query };
|
|
41
|
+
|
|
35
42
|
const model: BaseModel = new modelType();
|
|
36
43
|
|
|
37
44
|
if (props.isRoot || props.isMasterAdmin) {
|
|
@@ -34,6 +34,8 @@ export default class DeletePermission {
|
|
|
34
34
|
query: Query<TBaseModel>,
|
|
35
35
|
props: DatabaseCommonInteractionProps,
|
|
36
36
|
): Promise<Query<TBaseModel>> {
|
|
37
|
+
query = { ...query };
|
|
38
|
+
|
|
37
39
|
if (props.isRoot || props.isMasterAdmin) {
|
|
38
40
|
query = await PermissionUtil.addTenantScopeToQueryAsRoot(
|
|
39
41
|
modelType,
|
|
@@ -29,6 +29,9 @@ export default class ReadPermission {
|
|
|
29
29
|
select: Select<TBaseModel> | null,
|
|
30
30
|
props: DatabaseCommonInteractionProps,
|
|
31
31
|
): Promise<CheckReadPermissionType<TBaseModel>> {
|
|
32
|
+
// Block and base permission checks both add predicates to the query.
|
|
33
|
+
query = { ...query };
|
|
34
|
+
|
|
32
35
|
// check block permission first.
|
|
33
36
|
await this.checkReadBlockPermission(modelType, query, props);
|
|
34
37
|
|
|
@@ -45,6 +45,40 @@ export default class TenantPermission {
|
|
|
45
45
|
);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
const isAccessGrantedOnlyByCurrentUser: boolean =
|
|
49
|
+
TenantPermission.isAccessGrantedOnlyByCurrentUser(modelType, props, type);
|
|
50
|
+
const userColumn: string | null = model.getUserColumn();
|
|
51
|
+
|
|
52
|
+
/*
|
|
53
|
+
* CurrentUser is an auto-granted permission, not a tenant-wide role. A
|
|
54
|
+
* query operation that relies on it must declare an ownership column so
|
|
55
|
+
* the permission can be converted into a row predicate.
|
|
56
|
+
*/
|
|
57
|
+
if (
|
|
58
|
+
isAccessGrantedOnlyByCurrentUser &&
|
|
59
|
+
type !== DatabaseRequestType.Create &&
|
|
60
|
+
!userColumn
|
|
61
|
+
) {
|
|
62
|
+
throw new NotAuthorizedException(
|
|
63
|
+
`Current user scope is not configured for ${model.singularName}.`,
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const shouldScopeQueryByCurrentUser: boolean =
|
|
68
|
+
isAccessGrantedOnlyByCurrentUser && Boolean(userColumn);
|
|
69
|
+
|
|
70
|
+
/*
|
|
71
|
+
* API keys and other non-user callers can carry the auto-granted
|
|
72
|
+
* CurrentUser permission without having a userId. Such a grant can never
|
|
73
|
+
* be converted into an ownership filter, so reject it instead of running
|
|
74
|
+
* the caller's query without a user scope.
|
|
75
|
+
*/
|
|
76
|
+
if (shouldScopeQueryByCurrentUser && !props.userId) {
|
|
77
|
+
throw new NotAuthorizedException(
|
|
78
|
+
`A user session is required to ${type} ${model.singularName}.`,
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
48
82
|
// If this model has a tenantColumn, and request has tenantId, and is multiTenantQuery null then add tenantId to query.
|
|
49
83
|
if (tenantColumn && props.tenantId && !props.isMultiTenantRequest) {
|
|
50
84
|
(query as any)[tenantColumn] = props.tenantId;
|
|
@@ -56,13 +90,12 @@ export default class TenantPermission {
|
|
|
56
90
|
* row in the project (CVE-class issue when CurrentUser appears in a
|
|
57
91
|
* model's delete/update list alongside admin permissions).
|
|
58
92
|
*/
|
|
59
|
-
if (
|
|
60
|
-
TenantPermission.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
93
|
+
if (shouldScopeQueryByCurrentUser) {
|
|
94
|
+
TenantPermission.addCurrentUserScopeToQuery(
|
|
95
|
+
model,
|
|
96
|
+
query,
|
|
97
|
+
props.userId as ObjectID,
|
|
98
|
+
);
|
|
66
99
|
}
|
|
67
100
|
}
|
|
68
101
|
// if model allows user query without tenant, and user column is present, and userId is present, then add userId to query.
|
|
@@ -71,7 +104,7 @@ export default class TenantPermission {
|
|
|
71
104
|
model.getUserColumn() &&
|
|
72
105
|
props.userId
|
|
73
106
|
) {
|
|
74
|
-
(
|
|
107
|
+
TenantPermission.addCurrentUserScopeToQuery(model, query, props.userId);
|
|
75
108
|
} else if (
|
|
76
109
|
tenantColumn &&
|
|
77
110
|
props.userGlobalAccessPermission &&
|
|
@@ -114,6 +147,7 @@ export default class TenantPermission {
|
|
|
114
147
|
}
|
|
115
148
|
|
|
116
149
|
let lastException: Error | null = null;
|
|
150
|
+
const queryForEachProject: Query<TBaseModel> = { ...query };
|
|
117
151
|
|
|
118
152
|
for (const projectId of projectIDs) {
|
|
119
153
|
if (!props.userId) {
|
|
@@ -124,7 +158,7 @@ export default class TenantPermission {
|
|
|
124
158
|
const checkBasePermissions: CheckPermissionBaseInterface<TBaseModel> =
|
|
125
159
|
await BasePermission.checkPermissions(
|
|
126
160
|
modelType,
|
|
127
|
-
|
|
161
|
+
{ ...queryForEachProject },
|
|
128
162
|
select,
|
|
129
163
|
{
|
|
130
164
|
...props,
|
|
@@ -154,25 +188,76 @@ export default class TenantPermission {
|
|
|
154
188
|
return queries as any;
|
|
155
189
|
}
|
|
156
190
|
|
|
191
|
+
/*
|
|
192
|
+
* A model that relies on CurrentUser must resolve that permission to the
|
|
193
|
+
* requester's exact ownership column. This catches missing decorators and
|
|
194
|
+
* prevents a future model misconfiguration from silently becoming an
|
|
195
|
+
* instance-wide query.
|
|
196
|
+
*/
|
|
197
|
+
if (shouldScopeQueryByCurrentUser) {
|
|
198
|
+
const scopedUserId: unknown = (query as any)[userColumn as string];
|
|
199
|
+
|
|
200
|
+
if (
|
|
201
|
+
!TenantPermission.isExactUserScope(scopedUserId) ||
|
|
202
|
+
scopedUserId.toString() !== (props.userId as ObjectID).toString()
|
|
203
|
+
) {
|
|
204
|
+
throw new NotAuthorizedException(
|
|
205
|
+
`Current user scope could not be applied to ${model.singularName}.`,
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
157
210
|
return query;
|
|
158
211
|
}
|
|
159
212
|
|
|
213
|
+
/**
|
|
214
|
+
* Add the authenticated user's ownership predicate without redirecting an
|
|
215
|
+
* operation that explicitly targeted another user. Rejecting a conflict is
|
|
216
|
+
* important because service hooks run before the final permission check;
|
|
217
|
+
* silently replacing the target would let a hook inspect one row and the
|
|
218
|
+
* database operation mutate a different one.
|
|
219
|
+
*/
|
|
220
|
+
private static addCurrentUserScopeToQuery<TBaseModel extends BaseModel>(
|
|
221
|
+
model: BaseModel,
|
|
222
|
+
query: Query<TBaseModel>,
|
|
223
|
+
userId: ObjectID,
|
|
224
|
+
): void {
|
|
225
|
+
const userColumn: string = model.getUserColumn() as string;
|
|
226
|
+
const existingUserScope: unknown = (query as any)[userColumn];
|
|
227
|
+
|
|
228
|
+
if (
|
|
229
|
+
existingUserScope !== undefined &&
|
|
230
|
+
(!TenantPermission.isExactUserScope(existingUserScope) ||
|
|
231
|
+
existingUserScope.toString() !== userId.toString())
|
|
232
|
+
) {
|
|
233
|
+
throw new NotAuthorizedException(
|
|
234
|
+
`You do not have permission to access another user's ${model.singularName}.`,
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
(query as any)[userColumn] = userId;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Ownership filters must be exact scalar ids. Query operators such as
|
|
243
|
+
* NotEqual stringify to their wrapped id as well, so comparing only their
|
|
244
|
+
* string value would allow a broad hook query to masquerade as an exact
|
|
245
|
+
* current-user predicate.
|
|
246
|
+
*/
|
|
247
|
+
private static isExactUserScope(value: unknown): value is string | ObjectID {
|
|
248
|
+
return typeof value === "string" || value instanceof ObjectID;
|
|
249
|
+
}
|
|
250
|
+
|
|
160
251
|
/**
|
|
161
252
|
* True if the only permission letting this user through the table-level
|
|
162
253
|
* check for this op is Permission.CurrentUser. In that case the query must
|
|
163
254
|
* be restricted to rows the user owns (via the model's user column).
|
|
164
255
|
*/
|
|
165
|
-
private static
|
|
256
|
+
private static isAccessGrantedOnlyByCurrentUser<TBaseModel extends BaseModel>(
|
|
166
257
|
modelType: { new (): TBaseModel },
|
|
167
258
|
props: DatabaseCommonInteractionProps,
|
|
168
259
|
type: DatabaseRequestType,
|
|
169
260
|
): boolean {
|
|
170
|
-
const model: BaseModel = new modelType();
|
|
171
|
-
|
|
172
|
-
if (!model.getUserColumn() || !props.userId) {
|
|
173
|
-
return false;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
261
|
const modelPermissions: Array<Permission> =
|
|
177
262
|
TablePermission.getTablePermission(modelType, type);
|
|
178
263
|
|
|
@@ -185,9 +185,9 @@ export default class FixRunBudget {
|
|
|
185
185
|
: "Daily Other AI Fix Task Limit";
|
|
186
186
|
const settingsLocation: string =
|
|
187
187
|
lane === "incident"
|
|
188
|
-
? "Incidents >
|
|
188
|
+
? "Incidents > AI > Investigation"
|
|
189
189
|
: lane === "alert"
|
|
190
|
-
? "Alerts >
|
|
190
|
+
? "Alerts > AI > Investigation"
|
|
191
191
|
: "Project Settings > AI > AI Guardrails";
|
|
192
192
|
const laneLabel: string = lane === "other" ? "other AI" : `${lane} AI`;
|
|
193
193
|
|
|
@@ -17,6 +17,7 @@ import ProjectService from "../../../Services/ProjectService";
|
|
|
17
17
|
import LlmProviderService from "../../../Services/LlmProviderService";
|
|
18
18
|
import AIInvestigationQueue from "./InvestigationQueue";
|
|
19
19
|
import AIConfidenceSignal, { ConfidenceSignal } from "./ConfidenceSignal";
|
|
20
|
+
import InvestigationTldr from "./InvestigationTldr";
|
|
20
21
|
import ObservabilityAssistant, {
|
|
21
22
|
ObservabilityAssistantExtraTool,
|
|
22
23
|
ObservabilityAssistantResult,
|
|
@@ -124,6 +125,13 @@ export interface InvestigationRequest {
|
|
|
124
125
|
* remain NotRecommended throughout their lifecycle.
|
|
125
126
|
*/
|
|
126
127
|
persistCodeFixRecommendation?: boolean | undefined;
|
|
128
|
+
/*
|
|
129
|
+
* Incident and alert RCA runs opt into the AI-written TL;DR that the
|
|
130
|
+
* dashboard panel shows above the report. Display-only and best-effort:
|
|
131
|
+
* a failed generation leaves the run without one and changes nothing else.
|
|
132
|
+
* Engine users with no panel (insight triage, remediation) omit it.
|
|
133
|
+
*/
|
|
134
|
+
persistAnalysisTldr?: boolean | undefined;
|
|
127
135
|
/*
|
|
128
136
|
* Runs only after a Recommended decision and its exact analysis snapshot
|
|
129
137
|
* have been durably committed. Incident/alert runners use this for the
|
|
@@ -407,17 +415,62 @@ export default class AIInvestigationEngine {
|
|
|
407
415
|
* the WON Completed transition also means a falsely-requeued duplicate
|
|
408
416
|
* attempt can never double-spend it.
|
|
409
417
|
*/
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
418
|
+
/*
|
|
419
|
+
* The display-only TL;DR (see InvestigationTldr) runs CONCURRENTLY with
|
|
420
|
+
* the classification: both are post-loop calls over the same analysis,
|
|
421
|
+
* so serializing them would add their latencies to the delay before the
|
|
422
|
+
* RCA reaches the on-call engineer. Neither call throws — the TL;DR
|
|
423
|
+
* degrades to null and the report is published regardless.
|
|
424
|
+
*/
|
|
425
|
+
const [confidence, analysisTldr]: [ConfidenceSignal, string | null] =
|
|
426
|
+
await Promise.all([
|
|
427
|
+
AIConfidenceSignal.computeConfidenceSignal({
|
|
428
|
+
projectId,
|
|
429
|
+
aiRunId,
|
|
430
|
+
incidentId: request.incidentId,
|
|
431
|
+
alertId: request.alertId,
|
|
432
|
+
analysisMarkdown: analysis,
|
|
433
|
+
evidence: AIConfidenceSignal.evidenceFromCitations(
|
|
434
|
+
result.citations || [],
|
|
435
|
+
),
|
|
436
|
+
}),
|
|
437
|
+
request.persistAnalysisTldr === true
|
|
438
|
+
? InvestigationTldr.generateTldr({
|
|
439
|
+
projectId,
|
|
440
|
+
aiRunId,
|
|
441
|
+
incidentId: request.incidentId,
|
|
442
|
+
alertId: request.alertId,
|
|
443
|
+
/*
|
|
444
|
+
* Summarize the model's own analysis, not the branded form —
|
|
445
|
+
* the branding wrapper is boilerplate plus an evidence list,
|
|
446
|
+
* and a summary of it would waste the TL;DR on both.
|
|
447
|
+
*/
|
|
448
|
+
analysisMarkdown: analysis,
|
|
449
|
+
}).catch((error: unknown): null => {
|
|
450
|
+
/*
|
|
451
|
+
* generateTldr is total by construction, but it sits in a
|
|
452
|
+
* Promise.all inside the main try: a rejection would land in
|
|
453
|
+
* the catch below AFTER the Completed transition was won, so
|
|
454
|
+
* the run would be failed and the report never posted at all
|
|
455
|
+
* — a cosmetic line of text destroying the whole RCA. Belt
|
|
456
|
+
* and braces, because the blast radius is that asymmetric.
|
|
457
|
+
*/
|
|
458
|
+
logger.error(
|
|
459
|
+
`AI: TL;DR generation threw for run ${aiRunId.toString()}; publishing the report without one: ${error}`,
|
|
460
|
+
);
|
|
461
|
+
return null;
|
|
462
|
+
})
|
|
463
|
+
: Promise.resolve(null),
|
|
464
|
+
]);
|
|
465
|
+
|
|
466
|
+
/*
|
|
467
|
+
* Persist the TL;DR BEFORE the report is posted, so the panel can never
|
|
468
|
+
* render the report for a beat without its summary. Best-effort: a
|
|
469
|
+
* write failure is logged and the report still posts.
|
|
470
|
+
*/
|
|
471
|
+
if (analysisTldr) {
|
|
472
|
+
await this.persistAnalysisTldr({ aiRunId, analysisTldr });
|
|
473
|
+
}
|
|
421
474
|
|
|
422
475
|
/*
|
|
423
476
|
* Build the posted form exactly once. The same immutable string is
|
|
@@ -579,6 +632,32 @@ export default class AIInvestigationEngine {
|
|
|
579
632
|
}
|
|
580
633
|
}
|
|
581
634
|
|
|
635
|
+
/*
|
|
636
|
+
* Store the display-only TL;DR on the run. Unlike the code-fix decision
|
|
637
|
+
* this authorizes nothing, so it is not retried: a failed write (or a run
|
|
638
|
+
* that is no longer Completed) simply leaves the panel showing the report
|
|
639
|
+
* with no summary above it.
|
|
640
|
+
*/
|
|
641
|
+
private static async persistAnalysisTldr(data: {
|
|
642
|
+
aiRunId: ObjectID;
|
|
643
|
+
analysisTldr: string;
|
|
644
|
+
}): Promise<void> {
|
|
645
|
+
try {
|
|
646
|
+
const updatedCount: number =
|
|
647
|
+
await AIRunService.setInvestigationAnalysisTldr(data);
|
|
648
|
+
|
|
649
|
+
if (updatedCount === 0) {
|
|
650
|
+
logger.warn(
|
|
651
|
+
`AI: could not store the TL;DR for run ${data.aiRunId.toString()} — it was no longer Completed.`,
|
|
652
|
+
);
|
|
653
|
+
}
|
|
654
|
+
} catch (error) {
|
|
655
|
+
logger.error(
|
|
656
|
+
`AI: failed to store the TL;DR for run ${data.aiRunId.toString()}: ${error}`,
|
|
657
|
+
);
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
|
|
582
661
|
/*
|
|
583
662
|
* Resolve the recommendation exactly once. Pending is written by the
|
|
584
663
|
* winning Completed CAS, so this conditional update cannot race a stale
|
|
@@ -172,6 +172,7 @@ export default class AIAlertInvestigationRunner {
|
|
|
172
172
|
alertId,
|
|
173
173
|
contextSummary,
|
|
174
174
|
persistCodeFixRecommendation: true,
|
|
175
|
+
persistAnalysisTldr: true,
|
|
175
176
|
postAnalysis: async (postData: {
|
|
176
177
|
analysisMarkdown: string;
|
|
177
178
|
confidence: ConfidenceSignal;
|
|
@@ -354,6 +354,7 @@ export default class AIIncidentInvestigationRunner {
|
|
|
354
354
|
incidentId,
|
|
355
355
|
contextSummary,
|
|
356
356
|
persistCodeFixRecommendation: true,
|
|
357
|
+
persistAnalysisTldr: true,
|
|
357
358
|
postAnalysis: async (postData: {
|
|
358
359
|
analysisMarkdown: string;
|
|
359
360
|
confidence: ConfidenceSignal;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import ObjectID from "../../../../../../Types/ObjectID";
|
|
2
|
+
import Crypto from "../../../../../../Utils/Crypto";
|
|
3
|
+
import { normalizeExceptionText } from "../../../../Telemetry/ExceptionSanitizer";
|
|
4
|
+
|
|
5
|
+
/*
|
|
6
|
+
* Shared exception identity for the two exception detectors (NewException and
|
|
7
|
+
* ExceptionSpike).
|
|
8
|
+
*
|
|
9
|
+
* THE PROBLEM THIS SOLVES. A TelemetryException GROUP is keyed at ingest on
|
|
10
|
+
* sha256(projectId + primaryEntityId + normalizedMessage + normalizedStackTrace
|
|
11
|
+
* + exceptionType) — the STACK TRACE is part of that key. One logical failure
|
|
12
|
+
* raised from several call sites is therefore several groups, and a detector
|
|
13
|
+
* that emits one insight per group files the same finding several times over.
|
|
14
|
+
* Worse, the insight TITLE used to be the exceptionType alone, so those rows
|
|
15
|
+
* were not merely duplicated, they were indistinguishable: a service whose
|
|
16
|
+
* instrumentation reports `exception.type = "401"` produced a wall of
|
|
17
|
+
* identical "New exception: 401 in api" rows.
|
|
18
|
+
*
|
|
19
|
+
* THE FAILURE MODE is the unit a human actually triages: one service, one
|
|
20
|
+
* exception type, one normalized message. Everything below that (which call
|
|
21
|
+
* stack it surfaced on) is detail that belongs inside the insight, not a
|
|
22
|
+
* separate row in the inbox.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/*
|
|
26
|
+
* How much of the message rides in the insight title. Titles must stay
|
|
27
|
+
* scannable in a list, but they must also carry enough of the message to tell
|
|
28
|
+
* two findings apart — the type alone frequently cannot (HTTP status codes,
|
|
29
|
+
* bare `Error`, `Exception`).
|
|
30
|
+
*/
|
|
31
|
+
export const EXCEPTION_LABEL_MESSAGE_MAX_LENGTH: number = 80;
|
|
32
|
+
|
|
33
|
+
/*
|
|
34
|
+
* Human label for an exception: the type AND the message, because either one
|
|
35
|
+
* alone collides. `TypeError` is not a finding; `TypeError: Cannot read
|
|
36
|
+
* properties of undefined (reading 'user')` is.
|
|
37
|
+
*
|
|
38
|
+
* Only the message is truncated (the type is short by construction), so a
|
|
39
|
+
* label is never longer than the type plus the cap plus the separator.
|
|
40
|
+
*/
|
|
41
|
+
export function buildExceptionLabel(
|
|
42
|
+
exceptionType: string | undefined,
|
|
43
|
+
message: string | undefined,
|
|
44
|
+
messageMaxLength: number = EXCEPTION_LABEL_MESSAGE_MAX_LENGTH,
|
|
45
|
+
): string {
|
|
46
|
+
const type: string = (exceptionType || "").trim();
|
|
47
|
+
const fullMessage: string = (message || "").trim();
|
|
48
|
+
|
|
49
|
+
if (!type && !fullMessage) {
|
|
50
|
+
return "Unknown exception";
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (!fullMessage) {
|
|
54
|
+
return type;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const shortMessage: string =
|
|
58
|
+
fullMessage.length <= messageMaxLength
|
|
59
|
+
? fullMessage
|
|
60
|
+
: `${fullMessage.slice(0, messageMaxLength)}…`;
|
|
61
|
+
|
|
62
|
+
if (!type) {
|
|
63
|
+
return shortMessage;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/*
|
|
67
|
+
* Runtimes routinely prefix the message with the type ("Error: connect
|
|
68
|
+
* ECONNREFUSED", "ValueError: invalid literal"), and some SDKs report the
|
|
69
|
+
* message as the type verbatim. Saying it twice reads as a bug.
|
|
70
|
+
*/
|
|
71
|
+
const lowerType: string = type.toLowerCase();
|
|
72
|
+
const lowerMessage: string = fullMessage.toLowerCase();
|
|
73
|
+
|
|
74
|
+
if (
|
|
75
|
+
lowerMessage === lowerType ||
|
|
76
|
+
lowerMessage.startsWith(`${lowerType}:`) ||
|
|
77
|
+
lowerMessage.startsWith(`${lowerType} `)
|
|
78
|
+
) {
|
|
79
|
+
return shortMessage;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return `${type}: ${shortMessage}`;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/*
|
|
86
|
+
* Stable identity of a FAILURE MODE — the dedupe key insights are filed under.
|
|
87
|
+
*
|
|
88
|
+
* (entity, type, normalized message) and deliberately NOT the stack trace:
|
|
89
|
+
* collapsing stack-trace-only variants of one failure into one insight is the
|
|
90
|
+
* entire point. The entity id stays in the clear so a fingerprint is greppable
|
|
91
|
+
* back to a service, and it guarantees the key can never collide across
|
|
92
|
+
* services; the type+message half is hashed so an unbounded telemetry string
|
|
93
|
+
* cannot blow past the fingerprint column.
|
|
94
|
+
*
|
|
95
|
+
* `${exceptionType}|${normalizeExceptionText(message)}` is the SAME signature
|
|
96
|
+
* TelemetryExceptionService.validateNoOpenFixForSimilarException already uses
|
|
97
|
+
* to stop the fix lane opening near-identical pull requests for one throw site
|
|
98
|
+
* ("observed: 15 near-identical PRs for one invalid-uuid throw site"). The
|
|
99
|
+
* insight lane had no equivalent — this is that same rule, applied one stage
|
|
100
|
+
* earlier so the duplicates never reach the inbox in the first place.
|
|
101
|
+
*
|
|
102
|
+
* The RAW message is normalized here rather than the sanitized one: the
|
|
103
|
+
* fingerprint is an identity that MUST stay byte-for-byte stable across ticks
|
|
104
|
+
* and releases (a key that drifts files a duplicate on every drift), and
|
|
105
|
+
* normalizeExceptionText carries exactly that stability contract, while the
|
|
106
|
+
* secret redactor layered on top of it for display does not.
|
|
107
|
+
*/
|
|
108
|
+
export function buildExceptionFailureModeKey(data: {
|
|
109
|
+
primaryEntityId: ObjectID | undefined;
|
|
110
|
+
exceptionType: string | undefined;
|
|
111
|
+
message: string | undefined;
|
|
112
|
+
}): string {
|
|
113
|
+
const entityId: string =
|
|
114
|
+
data.primaryEntityId?.toString() || "unattributed-entity";
|
|
115
|
+
const type: string = (data.exceptionType || "").trim();
|
|
116
|
+
const normalizedMessage: string = normalizeExceptionText(
|
|
117
|
+
(data.message || "").trim(),
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
const contentHash: string = Crypto.getSha256Hash(
|
|
121
|
+
`${type}|${normalizedMessage}`,
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
return `${entityId}:${contentHash}`;
|
|
125
|
+
}
|
|
@@ -14,6 +14,10 @@ import ExceptionInstanceService from "../../../../../Services/ExceptionInstanceS
|
|
|
14
14
|
import ServiceService from "../../../../../Services/ServiceService";
|
|
15
15
|
import QueryHelper from "../../../../../Types/Database/QueryHelper";
|
|
16
16
|
import { sanitizeExceptionMessage } from "../../../../Telemetry/ExceptionSanitizer";
|
|
17
|
+
import {
|
|
18
|
+
EXCEPTION_LABEL_MESSAGE_MAX_LENGTH,
|
|
19
|
+
buildExceptionLabel,
|
|
20
|
+
} from "./ExceptionIdentity";
|
|
17
21
|
import {
|
|
18
22
|
InsightCandidate,
|
|
19
23
|
InsightDetector,
|
|
@@ -65,7 +69,8 @@ export const EXCEPTION_SPIKE_HIGH_SEVERITY_MULTIPLIER: number = 10;
|
|
|
65
69
|
export const EXCEPTION_SPIKE_CANDIDATE_LIMIT: number = 25;
|
|
66
70
|
|
|
67
71
|
// Titles must stay scannable in a list — truncate long exception messages.
|
|
68
|
-
export const EXCEPTION_SPIKE_TITLE_MESSAGE_MAX_LENGTH: number =
|
|
72
|
+
export const EXCEPTION_SPIKE_TITLE_MESSAGE_MAX_LENGTH: number =
|
|
73
|
+
EXCEPTION_LABEL_MESSAGE_MAX_LENGTH;
|
|
69
74
|
|
|
70
75
|
export interface ExceptionSpikeDecision {
|
|
71
76
|
isSpike: boolean;
|
|
@@ -114,27 +119,32 @@ export default class ExceptionSpikeDetector implements InsightDetector {
|
|
|
114
119
|
}
|
|
115
120
|
|
|
116
121
|
/*
|
|
117
|
-
* Human label for the exception: the type
|
|
118
|
-
*
|
|
122
|
+
* Human label for the exception: the type AND the message, because either
|
|
123
|
+
* one alone collides across findings (see ExceptionIdentity).
|
|
119
124
|
*/
|
|
120
125
|
public static buildExceptionLabel(
|
|
121
126
|
exceptionType: string | undefined,
|
|
122
127
|
message: string | undefined,
|
|
123
128
|
): string {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
return "Unknown exception";
|
|
130
|
-
}
|
|
131
|
-
if (trimmedMessage.length <= EXCEPTION_SPIKE_TITLE_MESSAGE_MAX_LENGTH) {
|
|
132
|
-
return trimmedMessage;
|
|
133
|
-
}
|
|
134
|
-
return `${trimmedMessage.slice(0, EXCEPTION_SPIKE_TITLE_MESSAGE_MAX_LENGTH)}…`;
|
|
129
|
+
return buildExceptionLabel(
|
|
130
|
+
exceptionType,
|
|
131
|
+
message,
|
|
132
|
+
EXCEPTION_SPIKE_TITLE_MESSAGE_MAX_LENGTH,
|
|
133
|
+
);
|
|
135
134
|
}
|
|
136
135
|
|
|
137
|
-
|
|
136
|
+
/*
|
|
137
|
+
* Stable dedupe key, keyed on the exception GROUP id (ingest dedupe unit).
|
|
138
|
+
*
|
|
139
|
+
* DELIBERATELY NOT the failure-mode key NewExceptionDetector files under.
|
|
140
|
+
* That detector's evidence is a Postgres column it can simply add up across
|
|
141
|
+
* the groups of one failure mode; a spike is a RATE, measured per ingest
|
|
142
|
+
* fingerprint in ClickHouse. Rolling several fingerprints into one insight
|
|
143
|
+
* would mean summing their windows and re-deciding the spike on the total —
|
|
144
|
+
* which changes what counts as a spike, not just how many rows it files.
|
|
145
|
+
* The title carries the type, the message and the multiplier, so sibling
|
|
146
|
+
* groups read as distinct rows rather than as copies.
|
|
147
|
+
*/
|
|
138
148
|
public static buildFingerprint(telemetryExceptionId: string): string {
|
|
139
149
|
return `exception-spike:${telemetryExceptionId}`;
|
|
140
150
|
}
|