@oneuptime/common 13.0.1 → 13.0.4
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/AnalyticsModels/RumSession.ts +34 -0
- package/Models/DatabaseModels/AlertEpisodeLabelRule.ts +2 -2
- package/Models/DatabaseModels/AlertEpisodeOnCallRule.ts +2 -2
- package/Models/DatabaseModels/AlertEpisodeOwnerRule.ts +2 -2
- package/Models/DatabaseModels/AlertEpisodePrivacyRule.ts +2 -2
- package/Models/DatabaseModels/AlertGroupingRule.ts +2 -2
- package/Models/DatabaseModels/AlertLabelRule.ts +2 -2
- package/Models/DatabaseModels/AlertOnCallRule.ts +2 -2
- package/Models/DatabaseModels/AlertOwnerRule.ts +2 -2
- package/Models/DatabaseModels/AlertPrivacyRule.ts +2 -2
- package/Models/DatabaseModels/AlertReminderRule.ts +6 -4
- package/Models/DatabaseModels/AutoRemediationRule.ts +2 -2
- package/Models/DatabaseModels/CephClusterLabelRule.ts +2 -2
- package/Models/DatabaseModels/CephClusterOwnerRule.ts +2 -2
- package/Models/DatabaseModels/CloudResourceLabelRule.ts +2 -2
- package/Models/DatabaseModels/CloudResourceOwnerRule.ts +2 -2
- package/Models/DatabaseModels/DashboardLabelRule.ts +2 -2
- package/Models/DatabaseModels/DashboardOwnerRule.ts +2 -2
- package/Models/DatabaseModels/DatabaseBaseModel/RelationOnlyRuleBaseModel.ts +11 -0
- package/Models/DatabaseModels/DatabaseBaseModel/RuleBaseModel.ts +44 -0
- package/Models/DatabaseModels/DockerHostLabelRule.ts +2 -2
- package/Models/DatabaseModels/DockerHostOwnerRule.ts +2 -2
- package/Models/DatabaseModels/DockerSwarmClusterLabelRule.ts +2 -2
- package/Models/DatabaseModels/DockerSwarmClusterOwnerRule.ts +2 -2
- package/Models/DatabaseModels/HostLabelRule.ts +2 -2
- package/Models/DatabaseModels/HostOwnerRule.ts +2 -2
- package/Models/DatabaseModels/IncidentEpisodeLabelRule.ts +2 -2
- package/Models/DatabaseModels/IncidentEpisodeOnCallRule.ts +2 -2
- package/Models/DatabaseModels/IncidentEpisodeOwnerRule.ts +2 -2
- package/Models/DatabaseModels/IncidentEpisodePrivacyRule.ts +2 -2
- package/Models/DatabaseModels/IncidentGroupingRule.ts +2 -2
- package/Models/DatabaseModels/IncidentLabelRule.ts +2 -2
- package/Models/DatabaseModels/IncidentOnCallRule.ts +2 -2
- package/Models/DatabaseModels/IncidentOwnerRule.ts +2 -2
- package/Models/DatabaseModels/IncidentPrivacyRule.ts +2 -2
- package/Models/DatabaseModels/IncidentReminderRule.ts +6 -4
- package/Models/DatabaseModels/IncidentSlaRule.ts +2 -2
- package/Models/DatabaseModels/IncomingCallPolicy.ts +3 -4
- package/Models/DatabaseModels/IncomingCallPolicyLabelRule.ts +2 -2
- package/Models/DatabaseModels/IncomingCallPolicyOwnerRule.ts +2 -2
- package/Models/DatabaseModels/IncomingCallPolicyPhoneNumber.ts +254 -0
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/IoTFleetLabelRule.ts +2 -2
- package/Models/DatabaseModels/IoTFleetOwnerRule.ts +2 -2
- package/Models/DatabaseModels/KubernetesClusterLabelRule.ts +2 -2
- package/Models/DatabaseModels/KubernetesClusterOwnerRule.ts +2 -2
- package/Models/DatabaseModels/MonitorLabelRule.ts +2 -2
- package/Models/DatabaseModels/MonitorOwnerRule.ts +2 -2
- package/Models/DatabaseModels/NetworkDeviceAutoImportRule.ts +2 -2
- package/Models/DatabaseModels/NetworkDeviceLabelRule.ts +2 -2
- package/Models/DatabaseModels/NetworkDeviceOwnerRule.ts +2 -2
- package/Models/DatabaseModels/NetworkSiteAssignmentRule.ts +2 -2
- package/Models/DatabaseModels/OnCallDutyPolicyLabelRule.ts +2 -2
- package/Models/DatabaseModels/OnCallDutyPolicyOwnerRule.ts +2 -2
- package/Models/DatabaseModels/OnCallDutyPolicyScheduleLabelRule.ts +2 -2
- package/Models/DatabaseModels/OnCallDutyPolicyScheduleOwnerRule.ts +2 -2
- package/Models/DatabaseModels/PodmanHostLabelRule.ts +2 -2
- package/Models/DatabaseModels/PodmanHostOwnerRule.ts +2 -2
- package/Models/DatabaseModels/ProxmoxClusterLabelRule.ts +2 -2
- package/Models/DatabaseModels/ProxmoxClusterOwnerRule.ts +2 -2
- package/Models/DatabaseModels/RumApplicationLabelRule.ts +2 -2
- package/Models/DatabaseModels/RumApplicationOwnerRule.ts +2 -2
- package/Models/DatabaseModels/RunbookLabelRule.ts +2 -2
- package/Models/DatabaseModels/RunbookOwnerRule.ts +2 -2
- package/Models/DatabaseModels/RunbookRule.ts +2 -2
- package/Models/DatabaseModels/ScheduledMaintenanceLabelRule.ts +2 -2
- package/Models/DatabaseModels/ScheduledMaintenanceOwnerRule.ts +2 -2
- package/Models/DatabaseModels/ScheduledMaintenanceReminderRule.ts +6 -4
- package/Models/DatabaseModels/ServerlessFunctionLabelRule.ts +2 -2
- package/Models/DatabaseModels/ServerlessFunctionOwnerRule.ts +2 -2
- package/Models/DatabaseModels/ServiceLabelRule.ts +2 -2
- package/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.ts +283 -4
- package/Models/DatabaseModels/ServiceOwnerRule.ts +2 -2
- package/Models/DatabaseModels/StatusPageLabelRule.ts +2 -2
- package/Models/DatabaseModels/StatusPageMonitorRule.ts +2 -2
- package/Models/DatabaseModels/StatusPageOwnerRule.ts +2 -2
- package/Models/DatabaseModels/VMwareVCenterLabelRule.ts +2 -2
- package/Models/DatabaseModels/VMwareVCenterOwnerRule.ts +2 -2
- package/Models/DatabaseModels/WorkflowLabelRule.ts +2 -2
- package/Models/DatabaseModels/WorkflowOwnerRule.ts +2 -2
- package/Server/API/TelemetryAPI.ts +323 -2
- package/Server/Infrastructure/Postgres/SchemaMigrations/1792400000000-AddSloBurnRateRuleIncidents.ts +111 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1792500000000-AddConfigurableRuleCriteria.ts +644 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1792600000000-AddIncomingCallPolicyPhoneNumbers.ts +72 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Middleware/MultipartFormData.ts +46 -21
- package/Server/Services/AlertEpisodeLabelRuleEngineService.ts +21 -0
- package/Server/Services/AlertEpisodeOnCallRuleEngineService.ts +21 -0
- package/Server/Services/AlertEpisodeOwnerRuleEngineService.ts +21 -0
- package/Server/Services/AlertEpisodePrivacyRuleEngineService.ts +21 -0
- package/Server/Services/AlertGroupingEngineService.ts +27 -0
- package/Server/Services/AlertLabelRuleEngineService.ts +27 -0
- package/Server/Services/AlertOnCallRuleEngineService.ts +27 -0
- package/Server/Services/AlertOwnerRuleEngineService.ts +27 -0
- package/Server/Services/AlertPrivacyRuleEngineService.ts +27 -0
- package/Server/Services/AlertReminderRuleService.ts +65 -33
- package/Server/Services/AutoRemediationRuleEngineService.ts +90 -8
- package/Server/Services/CephClusterLabelRuleEngineService.ts +20 -0
- package/Server/Services/CephClusterOwnerRuleEngineService.ts +20 -0
- package/Server/Services/CloudResourceLabelRuleEngineService.ts +20 -0
- package/Server/Services/CloudResourceOwnerRuleEngineService.ts +20 -0
- package/Server/Services/DashboardLabelRuleEngineService.ts +20 -0
- package/Server/Services/DashboardOwnerRuleEngineService.ts +20 -0
- package/Server/Services/DatabaseService.ts +409 -6
- package/Server/Services/DockerHostLabelRuleEngineService.ts +20 -0
- package/Server/Services/DockerHostOwnerRuleEngineService.ts +20 -0
- package/Server/Services/DockerSwarmClusterLabelRuleEngineService.ts +23 -0
- package/Server/Services/DockerSwarmClusterOwnerRuleEngineService.ts +23 -0
- package/Server/Services/HostLabelRuleEngineService.ts +13 -0
- package/Server/Services/HostOwnerRuleEngineService.ts +13 -0
- package/Server/Services/IncidentEpisodeLabelRuleEngineService.ts +21 -0
- package/Server/Services/IncidentEpisodeOnCallRuleEngineService.ts +21 -0
- package/Server/Services/IncidentEpisodeOwnerRuleEngineService.ts +21 -0
- package/Server/Services/IncidentEpisodePrivacyRuleEngineService.ts +21 -0
- package/Server/Services/IncidentGroupingEngineService.ts +64 -13
- package/Server/Services/IncidentLabelRuleEngineService.ts +64 -9
- package/Server/Services/IncidentOnCallRuleEngineService.ts +64 -10
- package/Server/Services/IncidentOwnerRuleEngineService.ts +64 -10
- package/Server/Services/IncidentPrivacyRuleEngineService.ts +64 -10
- package/Server/Services/IncidentReminderRuleService.ts +66 -34
- package/Server/Services/IncidentSlaRuleService.ts +55 -12
- package/Server/Services/IncomingCallPolicyLabelRuleEngineService.ts +20 -0
- package/Server/Services/IncomingCallPolicyOwnerRuleEngineService.ts +20 -0
- package/Server/Services/IncomingCallPolicyPhoneNumberService.ts +184 -0
- package/Server/Services/IncomingCallPolicyService.ts +276 -5
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/IoTFleetLabelRuleEngineService.ts +20 -0
- package/Server/Services/IoTFleetOwnerRuleEngineService.ts +20 -0
- package/Server/Services/KubernetesClusterLabelRuleEngineService.ts +23 -0
- package/Server/Services/KubernetesClusterOwnerRuleEngineService.ts +23 -0
- package/Server/Services/LabelService.ts +50 -7
- package/Server/Services/MonitorLabelRuleEngineService.ts +20 -0
- package/Server/Services/MonitorOwnerRuleEngineService.ts +20 -0
- package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +2 -0
- package/Server/Services/NetworkDeviceAutoImportRuleService.ts +93 -1
- package/Server/Services/NetworkDeviceLabelRuleEngineService.ts +26 -0
- package/Server/Services/NetworkDeviceOwnerRuleEngineService.ts +25 -0
- package/Server/Services/NetworkDeviceService.ts +2 -0
- package/Server/Services/NetworkSiteAssignmentRuleService.ts +90 -1
- package/Server/Services/NetworkSiteService.ts +242 -29
- package/Server/Services/NetworkSiteTypeService.ts +177 -77
- package/Server/Services/OnCallDutyPolicyLabelRuleEngineService.ts +20 -0
- package/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.ts +20 -0
- package/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.ts +22 -0
- package/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.ts +22 -0
- package/Server/Services/PodmanHostLabelRuleEngineService.ts +20 -0
- package/Server/Services/PodmanHostOwnerRuleEngineService.ts +20 -0
- package/Server/Services/ProjectCallSMSConfigService.ts +156 -7
- package/Server/Services/ProxmoxClusterLabelRuleEngineService.ts +25 -0
- package/Server/Services/ProxmoxClusterOwnerRuleEngineService.ts +25 -0
- package/Server/Services/RumApplicationLabelRuleEngineService.ts +22 -0
- package/Server/Services/RumApplicationOwnerRuleEngineService.ts +22 -0
- package/Server/Services/RunbookLabelRuleEngineService.ts +20 -0
- package/Server/Services/RunbookOwnerRuleEngineService.ts +20 -0
- package/Server/Services/RunbookRuleEngineService.ts +18 -1
- package/Server/Services/ScheduledMaintenanceLabelRuleEngineService.ts +62 -10
- package/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.ts +62 -11
- package/Server/Services/ScheduledMaintenanceReminderRuleService.ts +48 -18
- package/Server/Services/ServerlessFunctionLabelRuleEngineService.ts +25 -0
- package/Server/Services/ServerlessFunctionOwnerRuleEngineService.ts +25 -0
- package/Server/Services/ServiceLabelRuleEngineService.ts +20 -0
- package/Server/Services/ServiceLevelObjectiveBurnRateRuleService.ts +675 -12
- package/Server/Services/ServiceLevelObjectiveService.ts +55 -13
- package/Server/Services/ServiceOwnerRuleEngineService.ts +20 -0
- package/Server/Services/StatusPageLabelRuleEngineService.ts +20 -0
- package/Server/Services/StatusPageMonitorRuleEngineService.ts +31 -2
- package/Server/Services/StatusPageMonitorRuleService.ts +34 -1
- package/Server/Services/StatusPageOwnerRuleEngineService.ts +20 -0
- package/Server/Services/UserService.ts +23 -50
- package/Server/Services/VMwareVCenterLabelRuleEngineService.ts +25 -0
- package/Server/Services/VMwareVCenterOwnerRuleEngineService.ts +25 -0
- package/Server/Services/WorkflowLabelRuleEngineService.ts +20 -0
- package/Server/Services/WorkflowOwnerRuleEngineService.ts +20 -0
- package/Server/Static/Brand/README.md +10 -5
- package/Server/Static/Brand/favicons/oneuptime-up-v1.svg +8 -0
- package/Server/Types/Database/QueryHelper.ts +88 -0
- package/Server/Utils/AI/Toolbox/SloTools.ts +19 -2
- package/Server/Utils/IncomingCallPhoneNumber.ts +29 -16
- package/Server/Utils/Profiling.ts +13 -1
- package/Server/Utils/Rules/MonitorRuleCriteriaCache.ts +38 -0
- package/Server/Utils/SessionReplay/SessionReplayReadService.ts +498 -0
- package/Server/Utils/Telemetry.ts +3 -1
- package/Server/Utils/VendorAssets.ts +3 -0
- package/Tests/App/Dashboard/AIInsightViewTriage.test.tsx +348 -0
- package/Tests/App/Dashboard/ArchiveResourceCard.test.tsx +476 -0
- package/Tests/App/Dashboard/CloudDocumentationCard.test.tsx +25 -0
- package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +449 -24
- package/Tests/App/Dashboard/DashboardPersistentSideMenuLayouts.test.tsx +702 -0
- package/Tests/App/Dashboard/ExceptionsLandingRedirect.test.tsx +63 -0
- package/Tests/App/Dashboard/FeedOrdering.test.ts +150 -0
- package/Tests/App/Dashboard/GoogleSecOpsConnectionsErrors.test.tsx +279 -100
- package/Tests/App/Dashboard/InventoryItemSideMenu.test.tsx +155 -0
- package/Tests/App/Dashboard/InvestigationFeedRefresh.test.tsx +11 -0
- package/Tests/App/Dashboard/PasskeySettings.test.tsx +215 -71
- package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +347 -0
- package/Tests/App/Dashboard/ResourceAuditLogsSideMenus.test.tsx +263 -0
- package/Tests/App/Dashboard/ResourceFeed.test.tsx +413 -17
- package/Tests/App/Dashboard/RumSessionReplaySideMenu.test.tsx +138 -0
- package/Tests/App/Dashboard/SloDashboardTemplateWidgets.test.tsx +940 -0
- package/Tests/App/Dashboard/TelemetryIngestionKeyEdit.test.tsx +378 -0
- package/Tests/App/Dashboard/TelemetryIngestionKeyForm.test.tsx +735 -0
- package/Tests/App/Dashboard/TwoFactorStatus.test.tsx +275 -108
- package/Tests/App/StatusPage/BulkAddStatusPageMonitorsModal.test.tsx +13 -3
- package/Tests/Models/AnalyticsModels/RumSessionReplayColumns.test.ts +127 -4
- package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +5 -4
- package/Tests/Models/DatabaseModels/IncomingCallPolicyPhoneNumber.test.ts +362 -0
- package/Tests/Models/DatabaseModels/RuleBaseModel.test.ts +69 -0
- package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +181 -0
- package/Tests/Server/API/SessionReplayAPI.test.ts +1303 -145
- package/Tests/Server/API/UserTwoFactorSelfService.test.ts +407 -0
- package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +611 -0
- package/Tests/Server/Middleware/MultipartFormData.test.ts +61 -3
- package/Tests/Server/Middleware/TelemetryIngestionDisabled.test.ts +211 -0
- package/Tests/Server/Services/AlertIncidentRuleCriteriaEngineServices.test.ts +651 -0
- package/Tests/Server/Services/AutoRemediationRuleEngineService.test.ts +79 -0
- package/Tests/Server/Services/DatabaseServiceRelationOnlyRuleRollout.test.ts +330 -0
- package/Tests/Server/Services/DatabaseServiceRuleCriteriaValidation.test.ts +522 -0
- package/Tests/Server/Services/IncidentSlaRuleCriteriaCorrelation.test.ts +99 -0
- package/Tests/Server/Services/IncomingCallPolicyPhoneNumberService.test.ts +1540 -0
- package/Tests/Server/Services/NetworkDeviceRuleEngines.test.ts +179 -2
- package/Tests/Server/Services/NetworkSiteAssignmentRuleService.test.ts +170 -0
- package/Tests/Server/Services/NetworkSiteService.test.ts +559 -53
- package/Tests/Server/Services/NetworkSiteTypeService.test.ts +122 -55
- package/Tests/Server/Services/ReminderRuleCriteria.test.ts +173 -0
- package/Tests/Server/Services/ResourceRuleCriteriaEngineServices.test.ts +170 -0
- package/Tests/Server/Services/ScheduledMaintenanceRuleCriteriaCorrelation.test.ts +154 -0
- package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleService.test.ts +2450 -470
- package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +464 -121
- package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +281 -0
- package/Tests/Server/Services/StatusPageMonitorRuleEngineService.test.ts +132 -0
- package/Tests/Server/Services/StatusPageMonitorRuleHooks.test.ts +159 -14
- package/Tests/Server/Services/UserEmailChangePasswordResetExpiry.test.ts +6 -8
- package/Tests/Server/Services/UserTwoFactorAuthAdmin.test.ts +203 -34
- package/Tests/Server/Types/Database/QueryHelperJsonArrayObjects.test.ts +128 -0
- package/Tests/Server/Utils/AI/SloTools.test.ts +190 -1
- package/Tests/Server/Utils/AI/Toolbox/AIToolbox.test.ts +461 -0
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +25 -0
- package/Tests/Server/Utils/Billing/BillingFailureNoticeThrottle.test.ts +359 -0
- package/Tests/Server/Utils/CodeRepository/GitHub/GitHubWebhookEvents.test.ts +318 -0
- package/Tests/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.test.ts +220 -0
- package/Tests/Server/Utils/Dashboard/SloTemplatePublicDashboard.test.ts +1043 -0
- package/Tests/Server/Utils/Execute.test.ts +302 -0
- package/Tests/Server/Utils/GracefulShutdown.test.ts +565 -0
- package/Tests/Server/Utils/IncomingCallPhoneNumber.test.ts +36 -20
- package/Tests/Server/Utils/LoggerCore.test.ts +597 -0
- package/Tests/Server/Utils/Monitor/MonitorTemplateUtil.test.ts +1109 -0
- package/Tests/Server/Utils/Monitor/SloTemplateMetricEmitterContract.test.ts +750 -0
- package/Tests/Server/Utils/ProductAnalytics.test.ts +404 -0
- package/Tests/Server/Utils/Profiling.test.ts +366 -0
- package/Tests/Server/Utils/Rules/MonitorRuleCriteriaCache.test.ts +99 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +558 -0
- package/Tests/Server/Utils/Telemetry/EntityRegistry.test.ts +711 -0
- package/Tests/Server/Utils/Telemetry/ResourceFacetResolver.test.ts +522 -0
- package/Tests/Server/Utils/VendorAssets.test.ts +17 -0
- package/Tests/Types/Dashboard/DashboardTemplateEditorialInvariants.test.ts +659 -0
- package/Tests/Types/Dashboard/DashboardTemplateInvariants.test.ts +97 -0
- package/Tests/Types/Dashboard/SloDashboardTemplate.test.ts +1179 -0
- package/Tests/Types/Database/AccessControl/OwnedThrough.test.ts +136 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilCorePaths.test.ts +1014 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveRotation.test.ts +9 -6
- package/Tests/Types/Rules/RuleCriteriaFieldRegistry.test.ts +276 -0
- package/Tests/Types/Rum/SessionReplayApiContracts.test.ts +180 -1
- package/Tests/Types/Telemetry/LlmConventions.test.ts +495 -0
- package/Tests/UI/Components/AiInvestigationSettingsCard.test.tsx +13 -6
- package/Tests/UI/Components/Alert.test.tsx +532 -93
- package/Tests/UI/Components/Feed.test.tsx +241 -0
- package/Tests/UI/Components/Forms/BasicFormStepNavigation.test.tsx +368 -0
- package/Tests/UI/Components/Forms/FormSummary.test.tsx +454 -0
- package/Tests/UI/Components/Forms/ModelFormJsonColumns.test.tsx +290 -0
- package/Tests/UI/Components/Forms/ModelFormRuleCriteria.test.tsx +331 -0
- package/Tests/UI/Components/IconOpticalSize.test.tsx +79 -31
- package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +6 -6
- package/Tests/UI/Components/NavBar.test.tsx +91 -2
- package/Tests/UI/Components/PencilButton.test.tsx +211 -0
- package/Tests/UI/Components/RuleCriteria/RuleCriteriaBuilder.test.tsx +510 -0
- package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +350 -0
- package/Tests/UI/Components/TableSortAndMobileColumns.test.tsx +50 -0
- package/Tests/UI/Components/Telemetry/TelemetryRetentionConfigForm.test.tsx +329 -0
- package/Tests/UI/Components/useFeedItems.test.tsx +107 -0
- package/Tests/UI/Rum/ChunkLoader.test.ts +401 -0
- package/Tests/UI/Rum/RecordingHealthCard.test.tsx +1 -1
- package/Tests/UI/Rum/RecordingHealthStrip.test.tsx +7 -1
- package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +2 -0
- package/Tests/UI/Rum/ReplayEngine.test.ts +1069 -5
- package/Tests/UI/Rum/ReplayHeader.test.tsx +579 -2
- package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +23 -5
- package/Tests/UI/Rum/ReplayRail.test.tsx +143 -1
- package/Tests/UI/Rum/ReplayRenderBudget.test.tsx +338 -0
- package/Tests/UI/Rum/ReplaySignals.test.ts +179 -0
- package/Tests/UI/Rum/ReplayStage.test.tsx +210 -3
- package/Tests/UI/Rum/ReplayTimeline.test.tsx +180 -1
- package/Tests/UI/Rum/ReplayUserSessionsMenu.test.tsx +405 -0
- package/Tests/UI/Rum/SessionReplayEmptyState.test.tsx +13 -16
- package/Tests/UI/Rum/SessionReplayFacets.test.tsx +199 -0
- package/Tests/UI/Rum/SessionReplaySearchBar.test.tsx +58 -21
- package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +2 -0
- package/Tests/UI/Rum/SessionReplayTable.test.tsx +717 -4
- package/Tests/UI/Rum/SessionReplayUsersPage.test.tsx +435 -0
- package/Tests/UI/Rum/SessionReplayUsersTable.test.tsx +577 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +1 -1
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +1 -1
- package/Tests/UI/Utils/LabelRuleImportExport.test.ts +192 -0
- package/Tests/UI/Utils/Navigation.test.ts +30 -0
- package/Tests/Utils/Dashboard/SloTemplateVariableScoping.test.ts +880 -0
- package/Tests/Utils/LabelRuleImportExport.test.ts +158 -0
- package/Tests/Utils/NetworkDiscovery/AutoImportRuleMatcher.test.ts +93 -0
- package/Tests/Utils/NetworkSite/CidrMatchUtil.test.ts +138 -0
- package/Tests/Utils/NetworkSite/TypeHierarchyUtil.test.ts +174 -0
- package/Tests/Utils/Rules/RuleCriteriaMatcher.test.ts +1424 -0
- package/Tests/Utils/Rum/SessionIdentity.test.ts +72 -0
- package/Tests/Utils/Rum/SessionReplayHealth.test.ts +884 -0
- package/Tests/Utils/Slo/SloBurnRateRuleState.test.ts +374 -28
- package/Tests/Utils/Telemetry/OriginAllowList.test.ts +118 -0
- package/Types/Dashboard/DashboardTemplates.ts +465 -0
- package/Types/OnCallDutyPolicy/Layer.ts +12 -0
- package/Types/Rules/RuleCriteria.ts +51 -0
- package/Types/Rules/RuleCriteriaFieldRegistry.ts +449 -0
- package/Types/Rum/SessionReplay.ts +75 -0
- package/Types/Rum/SessionReplayApi.ts +93 -0
- package/UI/Components/Alerts/Alert.tsx +102 -72
- package/UI/Components/Button/Button.tsx +4 -1
- package/UI/Components/Dropdown/Dropdown.tsx +2 -0
- package/UI/Components/Feed/Feed.tsx +15 -0
- package/UI/Components/Feed/useFeedItems.ts +227 -0
- package/UI/Components/Forms/BasicForm.tsx +42 -21
- package/UI/Components/Forms/ModelForm.tsx +80 -1
- package/UI/Components/Icon/Icon.tsx +3 -35
- package/UI/Components/ModelTable/ModelTable.tsx +19 -0
- package/UI/Components/Navbar/NavBar.tsx +1 -0
- package/UI/Components/RuleCriteria/RuleCriteriaBuilder.tsx +735 -0
- package/UI/Components/RuleCriteria/RuleCriteriaModelForm.tsx +209 -0
- package/UI/Components/RuleCriteria/RuleCriteriaModelTable.tsx +205 -0
- package/UI/Components/RuleCriteria/RuleCriteriaSummary.tsx +123 -0
- package/UI/Components/Table/Table.tsx +3 -0
- package/UI/Components/Table/TableBody.tsx +3 -0
- package/UI/Components/Table/TableRow.tsx +8 -2
- package/UI/Components/Telemetry/TelemetryRetentionConfigForm.tsx +14 -2
- package/UI/Styles/Theme.css +1 -0
- package/UI/Utils/LabelRuleImportExport.ts +114 -6
- package/UI/Utils/Navigation.ts +1 -2
- package/UI/esbuild-config.js +46 -0
- package/Utils/Faker.ts +93 -6
- package/Utils/LabelRuleImportExport.ts +295 -2
- package/Utils/NetworkDiscovery/AutoImportRuleMatcher.ts +108 -8
- package/Utils/NetworkSite/CidrMatchUtil.ts +102 -0
- package/Utils/NetworkSite/TypeHierarchyUtil.ts +152 -2
- package/Utils/Rules/RuleCriteriaMatcher.ts +931 -0
- package/Utils/Rum/SessionIdentity.ts +16 -0
- package/Utils/Slo/SloBurnRateRuleState.ts +87 -33
- package/Utils/Telemetry/OriginAllowList.ts +74 -0
- package/build/dist/Models/AnalyticsModels/RumSession.js +32 -0
- package/build/dist/Models/AnalyticsModels/RumSession.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodeLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/AlertEpisodeLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodeOnCallRule.js +2 -2
- package/build/dist/Models/DatabaseModels/AlertEpisodeOnCallRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodePrivacyRule.js +2 -2
- package/build/dist/Models/DatabaseModels/AlertEpisodePrivacyRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertGroupingRule.js +2 -2
- package/build/dist/Models/DatabaseModels/AlertGroupingRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/AlertLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertOnCallRule.js +2 -2
- package/build/dist/Models/DatabaseModels/AlertOnCallRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/AlertOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertPrivacyRule.js +2 -2
- package/build/dist/Models/DatabaseModels/AlertPrivacyRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertReminderRule.js +6 -5
- package/build/dist/Models/DatabaseModels/AlertReminderRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AutoRemediationRule.js +2 -2
- package/build/dist/Models/DatabaseModels/AutoRemediationRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CephClusterLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/CephClusterLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CephClusterOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/CephClusterOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CloudResourceLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/CloudResourceLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CloudResourceOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/CloudResourceOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DashboardLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/DashboardLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DashboardOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/DashboardOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/RelationOnlyRuleBaseModel.js +12 -0
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/RelationOnlyRuleBaseModel.js.map +1 -0
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/RuleBaseModel.js +50 -0
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/RuleBaseModel.js.map +1 -0
- package/build/dist/Models/DatabaseModels/DockerHostLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/DockerHostLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerHostOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/DockerHostOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerSwarmClusterLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/DockerSwarmClusterLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerSwarmClusterOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/DockerSwarmClusterOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/HostLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/HostLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/HostOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/HostOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IncidentEpisodeLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeOnCallRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IncidentEpisodeOnCallRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IncidentEpisodeOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodePrivacyRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IncidentEpisodePrivacyRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentGroupingRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IncidentGroupingRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IncidentLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentOnCallRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IncidentOnCallRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IncidentOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentPrivacyRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IncidentPrivacyRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentReminderRule.js +6 -5
- package/build/dist/Models/DatabaseModels/IncidentReminderRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentSlaRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IncidentSlaRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncomingCallPolicy.js +3 -4
- package/build/dist/Models/DatabaseModels/IncomingCallPolicy.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncomingCallPolicyLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IncomingCallPolicyLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncomingCallPolicyOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IncomingCallPolicyOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncomingCallPolicyPhoneNumber.js +277 -0
- package/build/dist/Models/DatabaseModels/IncomingCallPolicyPhoneNumber.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/IoTFleetLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IoTFleetLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IoTFleetOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/IoTFleetOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesClusterLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/KubernetesClusterLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesClusterOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/KubernetesClusterOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/MonitorLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/MonitorOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceAutoImportRule.js +2 -2
- package/build/dist/Models/DatabaseModels/NetworkDeviceAutoImportRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/NetworkDeviceLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/NetworkDeviceOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js +2 -2
- package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/PodmanHostLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/PodmanHostLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/PodmanHostOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/PodmanHostOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProxmoxClusterLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/ProxmoxClusterLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProxmoxClusterOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/ProxmoxClusterOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RumApplicationLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/RumApplicationLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RumApplicationOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/RumApplicationOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RunbookLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/RunbookLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RunbookOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/RunbookOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RunbookRule.js +2 -2
- package/build/dist/Models/DatabaseModels/RunbookRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceReminderRule.js +6 -5
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceReminderRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServerlessFunctionLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/ServerlessFunctionLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServerlessFunctionOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/ServerlessFunctionOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/ServiceLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js +281 -4
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/ServiceOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/StatusPageLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageMonitorRule.js +2 -2
- package/build/dist/Models/DatabaseModels/StatusPageMonitorRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/StatusPageOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/VMwareVCenterLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/VMwareVCenterLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowLabelRule.js +2 -2
- package/build/dist/Models/DatabaseModels/WorkflowLabelRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowOwnerRule.js +2 -2
- package/build/dist/Models/DatabaseModels/WorkflowOwnerRule.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +211 -4
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792400000000-AddSloBurnRateRuleIncidents.js +60 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792400000000-AddSloBurnRateRuleIncidents.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792500000000-AddConfigurableRuleCriteria.js +301 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792500000000-AddConfigurableRuleCriteria.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792600000000-AddIncomingCallPolicyPhoneNumbers.js +30 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792600000000-AddIncomingCallPolicyPhoneNumbers.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/Middleware/MultipartFormData.js +38 -21
- package/build/dist/Server/Middleware/MultipartFormData.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeLabelRuleEngineService.js +17 -0
- package/build/dist/Server/Services/AlertEpisodeLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeOnCallRuleEngineService.js +17 -0
- package/build/dist/Server/Services/AlertEpisodeOnCallRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeOwnerRuleEngineService.js +17 -0
- package/build/dist/Server/Services/AlertEpisodeOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodePrivacyRuleEngineService.js +17 -0
- package/build/dist/Server/Services/AlertEpisodePrivacyRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertGroupingEngineService.js +21 -0
- package/build/dist/Server/Services/AlertGroupingEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertLabelRuleEngineService.js +21 -0
- package/build/dist/Server/Services/AlertLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertOnCallRuleEngineService.js +21 -0
- package/build/dist/Server/Services/AlertOnCallRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertOwnerRuleEngineService.js +21 -0
- package/build/dist/Server/Services/AlertOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertPrivacyRuleEngineService.js +21 -0
- package/build/dist/Server/Services/AlertPrivacyRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertReminderRuleService.js +44 -26
- package/build/dist/Server/Services/AlertReminderRuleService.js.map +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleEngineService.js +54 -11
- package/build/dist/Server/Services/AutoRemediationRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/CephClusterLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/CephClusterLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/CloudResourceLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/CloudResourceLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/DashboardLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/DashboardLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/DashboardOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/DashboardOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +235 -10
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DockerHostLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/DockerHostLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/DockerHostOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/DockerHostOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/DockerSwarmClusterLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/DockerSwarmClusterLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/DockerSwarmClusterOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/DockerSwarmClusterOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/HostLabelRuleEngineService.js +12 -0
- package/build/dist/Server/Services/HostLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/HostOwnerRuleEngineService.js +12 -0
- package/build/dist/Server/Services/HostOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeLabelRuleEngineService.js +17 -0
- package/build/dist/Server/Services/IncidentEpisodeLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeOnCallRuleEngineService.js +17 -0
- package/build/dist/Server/Services/IncidentEpisodeOnCallRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeOwnerRuleEngineService.js +17 -0
- package/build/dist/Server/Services/IncidentEpisodeOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodePrivacyRuleEngineService.js +17 -0
- package/build/dist/Server/Services/IncidentEpisodePrivacyRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentGroupingEngineService.js +39 -13
- package/build/dist/Server/Services/IncidentGroupingEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentLabelRuleEngineService.js +39 -9
- package/build/dist/Server/Services/IncidentLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentOnCallRuleEngineService.js +39 -10
- package/build/dist/Server/Services/IncidentOnCallRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentOwnerRuleEngineService.js +39 -10
- package/build/dist/Server/Services/IncidentOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentPrivacyRuleEngineService.js +39 -10
- package/build/dist/Server/Services/IncidentPrivacyRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentReminderRuleService.js +44 -26
- package/build/dist/Server/Services/IncidentReminderRuleService.js.map +1 -1
- package/build/dist/Server/Services/IncidentSlaRuleService.js +33 -12
- package/build/dist/Server/Services/IncidentSlaRuleService.js.map +1 -1
- package/build/dist/Server/Services/IncomingCallPolicyLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/IncomingCallPolicyLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncomingCallPolicyOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/IncomingCallPolicyOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncomingCallPolicyPhoneNumberService.js +127 -0
- package/build/dist/Server/Services/IncomingCallPolicyPhoneNumberService.js.map +1 -0
- package/build/dist/Server/Services/IncomingCallPolicyService.js +187 -4
- package/build/dist/Server/Services/IncomingCallPolicyService.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/IoTFleetLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/IoTFleetLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IoTFleetOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/IoTFleetOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesClusterLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/KubernetesClusterLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesClusterOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/KubernetesClusterOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/LabelService.js +39 -7
- package/build/dist/Server/Services/LabelService.js.map +1 -1
- package/build/dist/Server/Services/MonitorLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/MonitorLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/MonitorOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/MonitorOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +2 -0
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js +57 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js +17 -0
- package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceService.js +2 -0
- package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js +56 -1
- package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteService.js +187 -22
- package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteTypeService.js +126 -51
- package/build/dist/Server/Services/NetworkSiteTypeService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/OnCallDutyPolicyLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/PodmanHostLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/PodmanHostLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/PodmanHostOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/PodmanHostOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ProjectCallSMSConfigService.js +115 -6
- package/build/dist/Server/Services/ProjectCallSMSConfigService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxClusterLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/ProxmoxClusterLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/RumApplicationLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/RumApplicationLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/RunbookLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/RunbookLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/RunbookOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/RunbookOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/RunbookRuleEngineService.js +12 -0
- package/build/dist/Server/Services/RunbookRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceLabelRuleEngineService.js +38 -9
- package/build/dist/Server/Services/ScheduledMaintenanceLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.js +38 -10
- package/build/dist/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js +32 -14
- package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js.map +1 -1
- package/build/dist/Server/Services/ServerlessFunctionLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/ServerlessFunctionLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/ServiceLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js +554 -12
- package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js +50 -14
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
- package/build/dist/Server/Services/ServiceOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/ServiceOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/StatusPageLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js +25 -2
- package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageMonitorRuleService.js +19 -1
- package/build/dist/Server/Services/StatusPageMonitorRuleService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/StatusPageOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +14 -49
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Services/VMwareVCenterLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/VMwareVCenterLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/VMwareVCenterOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/VMwareVCenterOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/WorkflowLabelRuleEngineService.js +16 -0
- package/build/dist/Server/Services/WorkflowLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/WorkflowOwnerRuleEngineService.js +16 -0
- package/build/dist/Server/Services/WorkflowOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js +67 -0
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/SloTools.js +21 -4
- package/build/dist/Server/Utils/AI/Toolbox/SloTools.js.map +1 -1
- package/build/dist/Server/Utils/IncomingCallPhoneNumber.js +9 -3
- package/build/dist/Server/Utils/IncomingCallPhoneNumber.js.map +1 -1
- package/build/dist/Server/Utils/Profiling.js +10 -1
- package/build/dist/Server/Utils/Profiling.js.map +1 -1
- package/build/dist/Server/Utils/Rules/MonitorRuleCriteriaCache.js +30 -0
- package/build/dist/Server/Utils/Rules/MonitorRuleCriteriaCache.js.map +1 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +344 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry.js +1 -1
- package/build/dist/Server/Utils/Telemetry.js.map +1 -1
- package/build/dist/Server/Utils/VendorAssets.js +2 -0
- package/build/dist/Server/Utils/VendorAssets.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardTemplates.js +425 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
- package/build/dist/Types/OnCallDutyPolicy/Layer.js +11 -0
- package/build/dist/Types/OnCallDutyPolicy/Layer.js.map +1 -1
- package/build/dist/Types/Rules/RuleCriteria.js +18 -0
- package/build/dist/Types/Rules/RuleCriteria.js.map +1 -0
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +435 -0
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -0
- package/build/dist/Types/Rum/SessionReplay.js +64 -0
- package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -1
- package/build/dist/UI/Components/Alerts/Alert.js +63 -41
- package/build/dist/UI/Components/Alerts/Alert.js.map +1 -1
- package/build/dist/UI/Components/Button/Button.js +3 -1
- package/build/dist/UI/Components/Button/Button.js.map +1 -1
- package/build/dist/UI/Components/Dropdown/Dropdown.js +1 -1
- package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
- package/build/dist/UI/Components/Feed/Feed.js +4 -1
- package/build/dist/UI/Components/Feed/Feed.js.map +1 -1
- package/build/dist/UI/Components/Feed/useFeedItems.js +137 -0
- package/build/dist/UI/Components/Feed/useFeedItems.js.map +1 -0
- package/build/dist/UI/Components/Forms/BasicForm.js +38 -19
- package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/ModelForm.js +65 -1
- package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +3 -35
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/ModelTable.js +12 -1
- package/build/dist/UI/Components/ModelTable/ModelTable.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBar.js +1 -0
- package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
- package/build/dist/UI/Components/RuleCriteria/RuleCriteriaBuilder.js +383 -0
- package/build/dist/UI/Components/RuleCriteria/RuleCriteriaBuilder.js.map +1 -0
- package/build/dist/UI/Components/RuleCriteria/RuleCriteriaModelForm.js +124 -0
- package/build/dist/UI/Components/RuleCriteria/RuleCriteriaModelForm.js.map +1 -0
- package/build/dist/UI/Components/RuleCriteria/RuleCriteriaModelTable.js +126 -0
- package/build/dist/UI/Components/RuleCriteria/RuleCriteriaModelTable.js.map +1 -0
- package/build/dist/UI/Components/RuleCriteria/RuleCriteriaSummary.js +63 -0
- package/build/dist/UI/Components/RuleCriteria/RuleCriteriaSummary.js.map +1 -0
- package/build/dist/UI/Components/Table/Table.js +1 -1
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableBody.js +4 -2
- package/build/dist/UI/Components/Table/TableBody.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +3 -2
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigForm.js +14 -2
- package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigForm.js.map +1 -1
- package/build/dist/UI/Utils/LabelRuleImportExport.js +81 -5
- package/build/dist/UI/Utils/LabelRuleImportExport.js.map +1 -1
- package/build/dist/UI/Utils/Navigation.js.map +1 -1
- package/build/dist/Utils/Faker.js +76 -6
- package/build/dist/Utils/Faker.js.map +1 -1
- package/build/dist/Utils/LabelRuleImportExport.js +157 -3
- package/build/dist/Utils/LabelRuleImportExport.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js +81 -5
- package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js.map +1 -1
- package/build/dist/Utils/NetworkSite/CidrMatchUtil.js +77 -0
- package/build/dist/Utils/NetworkSite/CidrMatchUtil.js.map +1 -1
- package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js +109 -2
- package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js.map +1 -1
- package/build/dist/Utils/Rules/RuleCriteriaMatcher.js +526 -0
- package/build/dist/Utils/Rules/RuleCriteriaMatcher.js.map +1 -0
- package/build/dist/Utils/Rum/SessionIdentity.js +13 -1
- package/build/dist/Utils/Rum/SessionIdentity.js.map +1 -1
- package/build/dist/Utils/Slo/SloBurnRateRuleState.js +28 -15
- package/build/dist/Utils/Slo/SloBurnRateRuleState.js.map +1 -1
- package/build/dist/Utils/Telemetry/OriginAllowList.js +61 -0
- package/build/dist/Utils/Telemetry/OriginAllowList.js.map +1 -1
- package/package.json +20 -20
|
@@ -1,18 +1,27 @@
|
|
|
1
1
|
import Alert from "../../Models/DatabaseModels/Alert";
|
|
2
2
|
import AlertStateTimeline from "../../Models/DatabaseModels/AlertStateTimeline";
|
|
3
|
+
import Incident from "../../Models/DatabaseModels/Incident";
|
|
4
|
+
import IncidentStateTimeline from "../../Models/DatabaseModels/IncidentStateTimeline";
|
|
3
5
|
import Model from "../../Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule";
|
|
4
6
|
import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
|
|
7
|
+
import PartialEntity from "../../Types/Database/PartialEntity";
|
|
8
|
+
import Dictionary from "../../Types/Dictionary";
|
|
5
9
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
6
10
|
import ObjectID from "../../Types/ObjectID";
|
|
7
11
|
import CreateBy from "../Types/Database/CreateBy";
|
|
8
12
|
import DeleteBy from "../Types/Database/DeleteBy";
|
|
9
13
|
import { OnCreate, OnDelete, OnUpdate } from "../Types/Database/Hooks";
|
|
10
14
|
import UpdateBy from "../Types/Database/UpdateBy";
|
|
15
|
+
import ProjectScopedReferenceValidator from "../Utils/Database/ProjectScopedReferenceValidator";
|
|
11
16
|
import logger, { LogAttributes } from "../Utils/Logger";
|
|
12
17
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
13
18
|
import AlertService from "./AlertService";
|
|
19
|
+
import AlertSeverityService from "./AlertSeverityService";
|
|
14
20
|
import AlertStateTimelineService from "./AlertStateTimelineService";
|
|
15
21
|
import DatabaseService from "./DatabaseService";
|
|
22
|
+
import IncidentService from "./IncidentService";
|
|
23
|
+
import IncidentSeverityService from "./IncidentSeverityService";
|
|
24
|
+
import IncidentStateTimelineService from "./IncidentStateTimelineService";
|
|
16
25
|
|
|
17
26
|
const THRESHOLD_ERROR_MESSAGE: string =
|
|
18
27
|
"Burn rate threshold must be greater than 0.";
|
|
@@ -20,6 +29,16 @@ const WINDOWS_REQUIRED_ERROR_MESSAGE: string =
|
|
|
20
29
|
"Long window and short window are required for a burn rate rule.";
|
|
21
30
|
const WINDOWS_NOT_NUMERIC_ERROR_MESSAGE: string =
|
|
22
31
|
"Long window and short window must be a number of minutes.";
|
|
32
|
+
export const NO_OUTPUT_ERROR_MESSAGE: string =
|
|
33
|
+
"A burn rate rule must create an alert, declare an incident, or both.";
|
|
34
|
+
|
|
35
|
+
/*
|
|
36
|
+
* Mirrors the column defaults on the model. Every rule that predates incident
|
|
37
|
+
* support raised an alert and declared nothing, so that is what an unset
|
|
38
|
+
* payload still means.
|
|
39
|
+
*/
|
|
40
|
+
const DEFAULT_SHOULD_CREATE_ALERT: boolean = true;
|
|
41
|
+
const DEFAULT_SHOULD_CREATE_INCIDENT: boolean = false;
|
|
23
42
|
|
|
24
43
|
export class Service extends DatabaseService<Model> {
|
|
25
44
|
public constructor() {
|
|
@@ -27,12 +46,17 @@ export class Service extends DatabaseService<Model> {
|
|
|
27
46
|
}
|
|
28
47
|
|
|
29
48
|
/*
|
|
30
|
-
* Deterministic fingerprint carried on
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
49
|
+
* Deterministic fingerprint carried on everything a burn rate rule
|
|
50
|
+
* declares — the Alert it raises, the Incident it declares, or both. The
|
|
51
|
+
* evaluation worker sets it as `seriesFingerprint` when the rule fires, and
|
|
52
|
+
* lifecycle hooks use it to find (and resolve) those records when the rule
|
|
53
|
+
* or its SLO goes away.
|
|
54
|
+
*
|
|
55
|
+
* One fingerprint serves both because Alert and Incident are separate
|
|
56
|
+
* tables: a rule can have at most one open Alert and one open Incident, and
|
|
57
|
+
* each dedupe query is already scoped to its own table.
|
|
34
58
|
*/
|
|
35
|
-
public
|
|
59
|
+
public getBurnRateFingerprint(data: {
|
|
36
60
|
serviceLevelObjectiveId: ObjectID;
|
|
37
61
|
burnRateRuleId: ObjectID;
|
|
38
62
|
}): string {
|
|
@@ -94,6 +118,34 @@ export class Service extends DatabaseService<Model> {
|
|
|
94
118
|
);
|
|
95
119
|
}
|
|
96
120
|
|
|
121
|
+
/*
|
|
122
|
+
* What the rule declares. Both are written back explicitly — leaving them
|
|
123
|
+
* off would let Postgres apply the column default, which is right for a
|
|
124
|
+
* fresh create but hides the decision from the row that the update hook
|
|
125
|
+
* later reads back.
|
|
126
|
+
*/
|
|
127
|
+
const shouldCreateAlert: boolean = this.normalizeBooleanInput(
|
|
128
|
+
createBy.data.shouldCreateAlert,
|
|
129
|
+
DEFAULT_SHOULD_CREATE_ALERT,
|
|
130
|
+
);
|
|
131
|
+
const shouldCreateIncident: boolean = this.normalizeBooleanInput(
|
|
132
|
+
createBy.data.shouldCreateIncident,
|
|
133
|
+
DEFAULT_SHOULD_CREATE_INCIDENT,
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
if (!shouldCreateAlert && !shouldCreateIncident) {
|
|
137
|
+
throw new BadDataException(NO_OUTPUT_ERROR_MESSAGE);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
createBy.data.shouldCreateAlert = shouldCreateAlert;
|
|
141
|
+
createBy.data.shouldCreateIncident = shouldCreateIncident;
|
|
142
|
+
|
|
143
|
+
await this.validateSeverityReferences({
|
|
144
|
+
projectId: createBy.data.projectId || createBy.props.tenantId,
|
|
145
|
+
alertSeverityId: createBy.data.alertSeverityId,
|
|
146
|
+
incidentSeverityId: createBy.data.incidentSeverityId,
|
|
147
|
+
});
|
|
148
|
+
|
|
97
149
|
return {
|
|
98
150
|
createBy,
|
|
99
151
|
carryForward: null,
|
|
@@ -131,6 +183,10 @@ export class Service extends DatabaseService<Model> {
|
|
|
131
183
|
);
|
|
132
184
|
}
|
|
133
185
|
|
|
186
|
+
await this.validateOutputsOnUpdate(updateBy);
|
|
187
|
+
|
|
188
|
+
await this.validateSeverityReferencesOnUpdate(updateBy);
|
|
189
|
+
|
|
134
190
|
const newLongWindow: unknown = updateBy.data.longWindowInMinutes as unknown;
|
|
135
191
|
const newShortWindow: unknown = updateBy.data
|
|
136
192
|
.shortWindowInMinutes as unknown;
|
|
@@ -216,9 +272,9 @@ export class Service extends DatabaseService<Model> {
|
|
|
216
272
|
deleteBy: DeleteBy<Model>,
|
|
217
273
|
): Promise<OnDelete<Model>> {
|
|
218
274
|
/*
|
|
219
|
-
* Resolve
|
|
220
|
-
*
|
|
221
|
-
* evaluation worker only resolves
|
|
275
|
+
* Resolve anything the rules being deleted left open — otherwise the alert
|
|
276
|
+
* or incident (and its on-call escalations) stays open forever, because the
|
|
277
|
+
* evaluation worker only resolves records for rules that still exist.
|
|
222
278
|
*/
|
|
223
279
|
const itemsToDelete: Array<Model> = await this.findBy({
|
|
224
280
|
query: deleteBy.query,
|
|
@@ -240,16 +296,16 @@ export class Service extends DatabaseService<Model> {
|
|
|
240
296
|
}
|
|
241
297
|
|
|
242
298
|
try {
|
|
243
|
-
await this.
|
|
299
|
+
await this.resolveOpenAlertsAndIncidentsForRule({
|
|
244
300
|
serviceLevelObjectiveId: item.serviceLevelObjectiveId,
|
|
245
301
|
burnRateRuleId: item.id,
|
|
246
302
|
projectId: item.projectId,
|
|
247
303
|
rootCause:
|
|
248
|
-
"
|
|
304
|
+
"Auto-resolved because the SLO burn rate rule that created it was deleted.",
|
|
249
305
|
});
|
|
250
306
|
} catch (err) {
|
|
251
307
|
logger.error(
|
|
252
|
-
`Error resolving open alerts for SLO burn rate rule ${item.id?.toString()} before delete: ${err}`,
|
|
308
|
+
`Error resolving open alerts and incidents for SLO burn rate rule ${item.id?.toString()} before delete: ${err}`,
|
|
253
309
|
{ projectId: item.projectId?.toString() } as LogAttributes,
|
|
254
310
|
);
|
|
255
311
|
}
|
|
@@ -263,6 +319,236 @@ export class Service extends DatabaseService<Model> {
|
|
|
263
319
|
};
|
|
264
320
|
}
|
|
265
321
|
|
|
322
|
+
/*
|
|
323
|
+
* A rule stops declaring something — it is disabled, or one of its two
|
|
324
|
+
* outputs is switched off — and whatever it already has open is now an
|
|
325
|
+
* orphan. The evaluation worker cannot clean it up: it only loads rules
|
|
326
|
+
* where `isEnabled` is true, and for an enabled rule it only resolves the
|
|
327
|
+
* output it is still allowed to create. So the alert (or incident) and its
|
|
328
|
+
* on-call escalation would page someone about a rule that can no longer
|
|
329
|
+
* justify the page.
|
|
330
|
+
*
|
|
331
|
+
* Runs after the write commits, so an update that was rejected leaves the
|
|
332
|
+
* open records exactly where they were.
|
|
333
|
+
*/
|
|
334
|
+
@CaptureSpan()
|
|
335
|
+
protected override async onUpdateSuccess(
|
|
336
|
+
onUpdate: OnUpdate<Model>,
|
|
337
|
+
updatedItemIds: Array<ObjectID>,
|
|
338
|
+
): Promise<OnUpdate<Model>> {
|
|
339
|
+
/*
|
|
340
|
+
* These three reads are strict `=== false`, and that is only sound because
|
|
341
|
+
* onBeforeUpdate ran first: validateOutputsOnUpdate coerces both output
|
|
342
|
+
* flags, so the string `"false"` a form or a raw API call can send has
|
|
343
|
+
* already become a real boolean by the time it reaches here. If a path
|
|
344
|
+
* ever reaches onUpdateSuccess without that coercion, `"false" === false`
|
|
345
|
+
* is false and the orphaned record silently stays open — so the coercion
|
|
346
|
+
* is load-bearing, not tidiness.
|
|
347
|
+
*
|
|
348
|
+
* `isEnabled` is a plain Boolean column with no coercion hook, so a
|
|
349
|
+
* literal "false" string would slip past this check. That is pre-existing
|
|
350
|
+
* across every model in the codebase and is not worked around here; the
|
|
351
|
+
* dashboard's toggle sends a real boolean.
|
|
352
|
+
*/
|
|
353
|
+
const isRuleDisabled: boolean =
|
|
354
|
+
(onUpdate.updateBy.data.isEnabled as boolean | undefined) === false;
|
|
355
|
+
const areAlertsTurnedOff: boolean =
|
|
356
|
+
(onUpdate.updateBy.data.shouldCreateAlert as boolean | undefined) ===
|
|
357
|
+
false;
|
|
358
|
+
const areIncidentsTurnedOff: boolean =
|
|
359
|
+
(onUpdate.updateBy.data.shouldCreateIncident as boolean | undefined) ===
|
|
360
|
+
false;
|
|
361
|
+
|
|
362
|
+
if (!isRuleDisabled && !areAlertsTurnedOff && !areIncidentsTurnedOff) {
|
|
363
|
+
return onUpdate;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
for (const updatedItemId of updatedItemIds) {
|
|
367
|
+
try {
|
|
368
|
+
const rule: Model | null = await this.findOneById({
|
|
369
|
+
id: updatedItemId,
|
|
370
|
+
select: {
|
|
371
|
+
_id: true,
|
|
372
|
+
projectId: true,
|
|
373
|
+
serviceLevelObjectiveId: true,
|
|
374
|
+
},
|
|
375
|
+
props: {
|
|
376
|
+
isRoot: true,
|
|
377
|
+
},
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
if (!rule || !rule.projectId || !rule.serviceLevelObjectiveId) {
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/*
|
|
385
|
+
* The two outputs get their own try: they are independent lifecycles,
|
|
386
|
+
* and an alert that fails to resolve must not take the incident's
|
|
387
|
+
* resolve down with it — that is exactly how a live incident ends up
|
|
388
|
+
* escalating for a rule that no longer declares incidents.
|
|
389
|
+
*/
|
|
390
|
+
let clearAlert: boolean = false;
|
|
391
|
+
let clearIncident: boolean = false;
|
|
392
|
+
|
|
393
|
+
if (isRuleDisabled || areAlertsTurnedOff) {
|
|
394
|
+
try {
|
|
395
|
+
await this.resolveOpenAlertsForRule({
|
|
396
|
+
serviceLevelObjectiveId: rule.serviceLevelObjectiveId,
|
|
397
|
+
burnRateRuleId: updatedItemId,
|
|
398
|
+
projectId: rule.projectId,
|
|
399
|
+
rootCause: isRuleDisabled
|
|
400
|
+
? "Alert auto-resolved because the SLO burn rate rule that created it was disabled."
|
|
401
|
+
: "Alert auto-resolved because the SLO burn rate rule that created it no longer raises alerts.",
|
|
402
|
+
});
|
|
403
|
+
clearAlert = true;
|
|
404
|
+
} catch (err) {
|
|
405
|
+
logger.error(
|
|
406
|
+
`Error resolving open alerts for SLO burn rate rule ${updatedItemId.toString()} after update: ${err}`,
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
if (isRuleDisabled || areIncidentsTurnedOff) {
|
|
412
|
+
try {
|
|
413
|
+
await this.resolveOpenIncidentsForRule({
|
|
414
|
+
serviceLevelObjectiveId: rule.serviceLevelObjectiveId,
|
|
415
|
+
burnRateRuleId: updatedItemId,
|
|
416
|
+
projectId: rule.projectId,
|
|
417
|
+
rootCause: isRuleDisabled
|
|
418
|
+
? "Incident auto-resolved because the SLO burn rate rule that declared it was disabled."
|
|
419
|
+
: "Incident auto-resolved because the SLO burn rate rule that declared it no longer declares incidents.",
|
|
420
|
+
});
|
|
421
|
+
clearIncident = true;
|
|
422
|
+
} catch (err) {
|
|
423
|
+
logger.error(
|
|
424
|
+
`Error resolving open incidents for SLO burn rate rule ${updatedItemId.toString()} after update: ${err}`,
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/*
|
|
430
|
+
* Only forget the outputs that actually closed. A side that threw
|
|
431
|
+
* still has its record open, and clearing its column would tell the
|
|
432
|
+
* worker to declare a second one on top.
|
|
433
|
+
*/
|
|
434
|
+
await this.clearOpenOutputStateForRule({
|
|
435
|
+
burnRateRuleId: updatedItemId,
|
|
436
|
+
clearAlert: clearAlert,
|
|
437
|
+
clearIncident: clearIncident,
|
|
438
|
+
});
|
|
439
|
+
} catch (err) {
|
|
440
|
+
logger.error(
|
|
441
|
+
`Error resolving open alerts and incidents for SLO burn rate rule ${updatedItemId.toString()} after update: ${err}`,
|
|
442
|
+
);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
return onUpdate;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/*
|
|
450
|
+
* "A rule must declare something", enforced against the row that will
|
|
451
|
+
* EXIST after the update rather than against the payload alone.
|
|
452
|
+
*
|
|
453
|
+
* A form that only sends the field the user touched is the common case, so
|
|
454
|
+
* turning alerts off on a rule that already declares incidents has to be
|
|
455
|
+
* allowed while turning them off on a rule that declares nothing else must
|
|
456
|
+
* not be. Same shape as the single-window update path below: coerce the
|
|
457
|
+
* incoming value, then check it against each affected row's persisted
|
|
458
|
+
* sibling.
|
|
459
|
+
*/
|
|
460
|
+
private async validateOutputsOnUpdate(
|
|
461
|
+
updateBy: UpdateBy<Model>,
|
|
462
|
+
): Promise<void> {
|
|
463
|
+
const newShouldCreateAlert: unknown = updateBy.data
|
|
464
|
+
.shouldCreateAlert as unknown;
|
|
465
|
+
const newShouldCreateIncident: unknown = updateBy.data
|
|
466
|
+
.shouldCreateIncident as unknown;
|
|
467
|
+
|
|
468
|
+
const isShouldCreateAlertUpdated: boolean =
|
|
469
|
+
newShouldCreateAlert !== undefined && newShouldCreateAlert !== null;
|
|
470
|
+
const isShouldCreateIncidentUpdated: boolean =
|
|
471
|
+
newShouldCreateIncident !== undefined && newShouldCreateIncident !== null;
|
|
472
|
+
|
|
473
|
+
if (!isShouldCreateAlertUpdated && !isShouldCreateIncidentUpdated) {
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
if (isShouldCreateAlertUpdated) {
|
|
478
|
+
updateBy.data.shouldCreateAlert = this.normalizeBooleanInput(
|
|
479
|
+
newShouldCreateAlert,
|
|
480
|
+
DEFAULT_SHOULD_CREATE_ALERT,
|
|
481
|
+
);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
if (isShouldCreateIncidentUpdated) {
|
|
485
|
+
updateBy.data.shouldCreateIncident = this.normalizeBooleanInput(
|
|
486
|
+
newShouldCreateIncident,
|
|
487
|
+
DEFAULT_SHOULD_CREATE_INCIDENT,
|
|
488
|
+
);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
const updatedShouldCreateAlert: boolean = Boolean(
|
|
492
|
+
updateBy.data.shouldCreateAlert,
|
|
493
|
+
);
|
|
494
|
+
const updatedShouldCreateIncident: boolean = Boolean(
|
|
495
|
+
updateBy.data.shouldCreateIncident,
|
|
496
|
+
);
|
|
497
|
+
|
|
498
|
+
if (isShouldCreateAlertUpdated && isShouldCreateIncidentUpdated) {
|
|
499
|
+
if (!updatedShouldCreateAlert && !updatedShouldCreateIncident) {
|
|
500
|
+
throw new BadDataException(NO_OUTPUT_ERROR_MESSAGE);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
/*
|
|
507
|
+
* Only one flag is being written. Switching one ON can never leave a rule
|
|
508
|
+
* with nothing, so there is nothing to read back for it.
|
|
509
|
+
*/
|
|
510
|
+
if (
|
|
511
|
+
(isShouldCreateAlertUpdated && updatedShouldCreateAlert) ||
|
|
512
|
+
(isShouldCreateIncidentUpdated && updatedShouldCreateIncident)
|
|
513
|
+
) {
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
const rulesToUpdate: Array<Model> = await this.findBy({
|
|
518
|
+
query: updateBy.query,
|
|
519
|
+
select: {
|
|
520
|
+
_id: true,
|
|
521
|
+
shouldCreateAlert: true,
|
|
522
|
+
shouldCreateIncident: true,
|
|
523
|
+
},
|
|
524
|
+
limit: LIMIT_PER_PROJECT,
|
|
525
|
+
skip: 0,
|
|
526
|
+
props: {
|
|
527
|
+
isRoot: true,
|
|
528
|
+
},
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
for (const rule of rulesToUpdate) {
|
|
532
|
+
const resultingShouldCreateAlert: boolean = isShouldCreateAlertUpdated
|
|
533
|
+
? updatedShouldCreateAlert
|
|
534
|
+
: this.normalizeBooleanInput(
|
|
535
|
+
rule.shouldCreateAlert,
|
|
536
|
+
DEFAULT_SHOULD_CREATE_ALERT,
|
|
537
|
+
);
|
|
538
|
+
const resultingShouldCreateIncident: boolean =
|
|
539
|
+
isShouldCreateIncidentUpdated
|
|
540
|
+
? updatedShouldCreateIncident
|
|
541
|
+
: this.normalizeBooleanInput(
|
|
542
|
+
rule.shouldCreateIncident,
|
|
543
|
+
DEFAULT_SHOULD_CREATE_INCIDENT,
|
|
544
|
+
);
|
|
545
|
+
|
|
546
|
+
if (!resultingShouldCreateAlert && !resultingShouldCreateIncident) {
|
|
547
|
+
throw new BadDataException(NO_OUTPUT_ERROR_MESSAGE);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
266
552
|
/*
|
|
267
553
|
* Resolve all open Alerts carrying this rule's fingerprint by appending a
|
|
268
554
|
* resolved AlertStateTimeline row. Mirrors
|
|
@@ -276,7 +562,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
276
562
|
projectId: ObjectID;
|
|
277
563
|
rootCause?: string | undefined;
|
|
278
564
|
}): Promise<void> {
|
|
279
|
-
const fingerprint: string = this.
|
|
565
|
+
const fingerprint: string = this.getBurnRateFingerprint({
|
|
280
566
|
serviceLevelObjectiveId: data.serviceLevelObjectiveId,
|
|
281
567
|
burnRateRuleId: data.burnRateRuleId,
|
|
282
568
|
});
|
|
@@ -309,6 +595,20 @@ export class Service extends DatabaseService<Model> {
|
|
|
309
595
|
data.projectId,
|
|
310
596
|
);
|
|
311
597
|
|
|
598
|
+
/*
|
|
599
|
+
* Per-record isolation, but NOT per-record silence: one record that fails
|
|
600
|
+
* to resolve must not stop the others, and must still reach the caller.
|
|
601
|
+
* Every caller above this treats a clean return as "there is nothing left
|
|
602
|
+
* open" — the worker stamps the rule resolved, and its Paused /
|
|
603
|
+
* Misconfigured guard commits a status change that makes the whole attempt
|
|
604
|
+
* one-shot. Swallowing a single failed state-timeline write therefore
|
|
605
|
+
* strands that record, and its on-call escalation, permanently.
|
|
606
|
+
*
|
|
607
|
+
* The idempotent same-state race below is not a failure and is
|
|
608
|
+
* deliberately not counted.
|
|
609
|
+
*/
|
|
610
|
+
let firstError: unknown = null;
|
|
611
|
+
|
|
312
612
|
for (const openAlert of openAlerts) {
|
|
313
613
|
try {
|
|
314
614
|
const alertStateTimeline: AlertStateTimeline = new AlertStateTimeline();
|
|
@@ -350,8 +650,371 @@ export class Service extends DatabaseService<Model> {
|
|
|
350
650
|
`Error resolving open alert ${openAlert.id?.toString()} for SLO burn rate rule ${data.burnRateRuleId?.toString()}: ${err}`,
|
|
351
651
|
{ projectId: data.projectId?.toString() } as LogAttributes,
|
|
352
652
|
);
|
|
653
|
+
|
|
654
|
+
if (firstError === null) {
|
|
655
|
+
firstError = err;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
if (firstError !== null) {
|
|
661
|
+
throw firstError;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/*
|
|
666
|
+
* Both severity columns are plain foreign keys with no project scoping of
|
|
667
|
+
* their own, so the public CRUD API will happily persist a severity that
|
|
668
|
+
* belongs to a different project. Nothing notices until the worker fires:
|
|
669
|
+
* IncidentService.onBeforeCreate rejects the cross-project reference on
|
|
670
|
+
* EVERY tick, the evaluation loop swallows the throw into a log line, and
|
|
671
|
+
* the rule looks configured while declaring nothing forever.
|
|
672
|
+
*
|
|
673
|
+
* The validator also rejects an id that matches no row at all, which is the
|
|
674
|
+
* other way a hand-written API call produces a rule that can never fire.
|
|
675
|
+
*/
|
|
676
|
+
private async validateSeverityReferences(data: {
|
|
677
|
+
projectId: ObjectID | undefined;
|
|
678
|
+
alertSeverityId: ObjectID | undefined;
|
|
679
|
+
incidentSeverityId: ObjectID | undefined;
|
|
680
|
+
}): Promise<void> {
|
|
681
|
+
if (!data.projectId) {
|
|
682
|
+
/*
|
|
683
|
+
* No project to validate against. The tenant column is required, so the
|
|
684
|
+
* write is going to fail anyway — and failing here would turn a clear
|
|
685
|
+
* "projectId is required" into a confusing severity error.
|
|
686
|
+
*/
|
|
687
|
+
return;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
if (!data.alertSeverityId && !data.incidentSeverityId) {
|
|
691
|
+
return;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
await ProjectScopedReferenceValidator.validateReferencesBelongToProject({
|
|
695
|
+
projectId: data.projectId,
|
|
696
|
+
subject: "SLO burn rate rule",
|
|
697
|
+
references: [
|
|
698
|
+
{
|
|
699
|
+
modelName: "Alert Severity",
|
|
700
|
+
id: data.alertSeverityId,
|
|
701
|
+
service: AlertSeverityService,
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
modelName: "Incident Severity",
|
|
705
|
+
id: data.incidentSeverityId,
|
|
706
|
+
service: IncidentSeverityService,
|
|
707
|
+
},
|
|
708
|
+
],
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
/*
|
|
713
|
+
* The update twin. A root or API update does not always carry a tenantId, so
|
|
714
|
+
* fall back to the projects of the rows the query actually matches — the
|
|
715
|
+
* shape ScheduledMaintenanceService uses for the same problem.
|
|
716
|
+
*/
|
|
717
|
+
private async validateSeverityReferencesOnUpdate(
|
|
718
|
+
updateBy: UpdateBy<Model>,
|
|
719
|
+
): Promise<void> {
|
|
720
|
+
const alertSeverityId: ObjectID | undefined = updateBy.data
|
|
721
|
+
.alertSeverityId as ObjectID | undefined;
|
|
722
|
+
const incidentSeverityId: ObjectID | undefined = updateBy.data
|
|
723
|
+
.incidentSeverityId as ObjectID | undefined;
|
|
724
|
+
|
|
725
|
+
if (!alertSeverityId && !incidentSeverityId) {
|
|
726
|
+
return;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
const projectIds: Array<ObjectID> = updateBy.props.tenantId
|
|
730
|
+
? [updateBy.props.tenantId]
|
|
731
|
+
: await this.getProjectIdsForUpdateQuery(updateBy);
|
|
732
|
+
|
|
733
|
+
for (const projectId of projectIds) {
|
|
734
|
+
await this.validateSeverityReferences({
|
|
735
|
+
projectId: projectId,
|
|
736
|
+
alertSeverityId: alertSeverityId,
|
|
737
|
+
incidentSeverityId: incidentSeverityId,
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
private async getProjectIdsForUpdateQuery(
|
|
743
|
+
updateBy: UpdateBy<Model>,
|
|
744
|
+
): Promise<Array<ObjectID>> {
|
|
745
|
+
const rules: Array<Model> = await this.findBy({
|
|
746
|
+
query: updateBy.query,
|
|
747
|
+
select: {
|
|
748
|
+
projectId: true,
|
|
749
|
+
},
|
|
750
|
+
limit: LIMIT_PER_PROJECT,
|
|
751
|
+
skip: 0,
|
|
752
|
+
props: {
|
|
753
|
+
isRoot: true,
|
|
754
|
+
},
|
|
755
|
+
});
|
|
756
|
+
|
|
757
|
+
const projectIds: Dictionary<ObjectID> = {};
|
|
758
|
+
|
|
759
|
+
for (const rule of rules) {
|
|
760
|
+
if (rule.projectId) {
|
|
761
|
+
projectIds[rule.projectId.toString()] = rule.projectId;
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
return Object.values(projectIds);
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
/*
|
|
769
|
+
* Forget that the rule has an output open, WITHOUT stamping a resolve.
|
|
770
|
+
*
|
|
771
|
+
* The rule's four lifecycle columns are what the evaluation worker reads to
|
|
772
|
+
* decide whether an output is already open, so a path that closes the record
|
|
773
|
+
* but leaves `lastAlertCreatedAt` / `lastIncidentCreatedAt` set tells the
|
|
774
|
+
* next tick "there is already an alert open" when there is not — and the
|
|
775
|
+
* worker then refuses to declare anything for the rest of the burn. That is
|
|
776
|
+
* how "turn Create Alert off to stop the noise, then turn it back on" used
|
|
777
|
+
* to silence a live 14.4x fast burn.
|
|
778
|
+
*
|
|
779
|
+
* Clearing the CREATED column rather than stamping the RESOLVED one is the
|
|
780
|
+
* whole point. Stamping a resolve would open a re-fire suppression window of
|
|
781
|
+
* up to the rule's long window (six hours for the seeded Slow burn), so
|
|
782
|
+
* re-enabling a rule mid-outage would go quiet anyway. Nothing about the
|
|
783
|
+
* burn rate recovered here; an administrator ended the lifecycle, and the
|
|
784
|
+
* honest record of that is "nothing is open", not "it just resolved".
|
|
785
|
+
*
|
|
786
|
+
* The cost is the rule's "last fired" history: a rule whose SLO was disabled
|
|
787
|
+
* once reads as never having fired. That is the right trade against silently
|
|
788
|
+
* losing a page, and it is the same reset an administrator just performed.
|
|
789
|
+
*
|
|
790
|
+
* Hookless on purpose. These are worker-owned columns that no workflow can
|
|
791
|
+
* meaningfully trigger on, and the caller is often onUpdateSuccess — a
|
|
792
|
+
* hooked write from inside an update hook re-enters the whole pipeline to
|
|
793
|
+
* write two nullable timestamps.
|
|
794
|
+
*/
|
|
795
|
+
@CaptureSpan()
|
|
796
|
+
public async clearOpenOutputStateForRule(data: {
|
|
797
|
+
burnRateRuleId: ObjectID;
|
|
798
|
+
clearAlert: boolean;
|
|
799
|
+
clearIncident: boolean;
|
|
800
|
+
}): Promise<void> {
|
|
801
|
+
const columns: {
|
|
802
|
+
lastAlertCreatedAt?: null;
|
|
803
|
+
lastIncidentCreatedAt?: null;
|
|
804
|
+
} = {};
|
|
805
|
+
|
|
806
|
+
if (data.clearAlert) {
|
|
807
|
+
columns.lastAlertCreatedAt = null;
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
if (data.clearIncident) {
|
|
811
|
+
columns.lastIncidentCreatedAt = null;
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
if (Object.keys(columns).length === 0) {
|
|
815
|
+
return;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
await this.updateColumnsByIdWithoutHooks({
|
|
819
|
+
id: data.burnRateRuleId,
|
|
820
|
+
data: columns as unknown as PartialEntity<Model>,
|
|
821
|
+
});
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
/*
|
|
825
|
+
* The Incident twin of resolveOpenAlertsForRule. Same shape, different
|
|
826
|
+
* table: find every open Incident carrying this rule's fingerprint and
|
|
827
|
+
* append a resolved IncidentStateTimeline row.
|
|
828
|
+
*
|
|
829
|
+
* Kept as its own method rather than folded into the alert path because the
|
|
830
|
+
* two are resolved independently — turning `shouldCreateIncident` off must close
|
|
831
|
+
* the incident and leave the alert alone, and vice versa.
|
|
832
|
+
*/
|
|
833
|
+
@CaptureSpan()
|
|
834
|
+
public async resolveOpenIncidentsForRule(data: {
|
|
835
|
+
serviceLevelObjectiveId: ObjectID;
|
|
836
|
+
burnRateRuleId: ObjectID;
|
|
837
|
+
projectId: ObjectID;
|
|
838
|
+
rootCause?: string | undefined;
|
|
839
|
+
}): Promise<void> {
|
|
840
|
+
const fingerprint: string = this.getBurnRateFingerprint({
|
|
841
|
+
serviceLevelObjectiveId: data.serviceLevelObjectiveId,
|
|
842
|
+
burnRateRuleId: data.burnRateRuleId,
|
|
843
|
+
});
|
|
844
|
+
|
|
845
|
+
const openIncidents: Array<Incident> = await IncidentService.findBy({
|
|
846
|
+
query: {
|
|
847
|
+
projectId: data.projectId,
|
|
848
|
+
seriesFingerprint: fingerprint,
|
|
849
|
+
currentIncidentState: {
|
|
850
|
+
isResolvedState: false,
|
|
851
|
+
},
|
|
852
|
+
},
|
|
853
|
+
select: {
|
|
854
|
+
_id: true,
|
|
855
|
+
projectId: true,
|
|
856
|
+
},
|
|
857
|
+
skip: 0,
|
|
858
|
+
limit: LIMIT_PER_PROJECT,
|
|
859
|
+
props: {
|
|
860
|
+
isRoot: true,
|
|
861
|
+
},
|
|
862
|
+
});
|
|
863
|
+
|
|
864
|
+
if (openIncidents.length === 0) {
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
/*
|
|
869
|
+
* Looked up once for the batch, and only once there is something to
|
|
870
|
+
* resolve: it throws when the project has no resolved incident state, and
|
|
871
|
+
* a project with nothing open must not be failed for a state it never
|
|
872
|
+
* needed.
|
|
873
|
+
*/
|
|
874
|
+
const resolvedStateId: ObjectID =
|
|
875
|
+
await IncidentStateTimelineService.getResolvedStateIdForProject(
|
|
876
|
+
data.projectId,
|
|
877
|
+
);
|
|
878
|
+
|
|
879
|
+
/*
|
|
880
|
+
* Per-record isolation, but NOT per-record silence: one record that fails
|
|
881
|
+
* to resolve must not stop the others, and must still reach the caller.
|
|
882
|
+
* Every caller above this treats a clean return as "there is nothing left
|
|
883
|
+
* open" — the worker stamps the rule resolved, and its Paused /
|
|
884
|
+
* Misconfigured guard commits a status change that makes the whole attempt
|
|
885
|
+
* one-shot. Swallowing a single failed state-timeline write therefore
|
|
886
|
+
* strands that record, and its on-call escalation, permanently.
|
|
887
|
+
*
|
|
888
|
+
* The idempotent same-state race below is not a failure and is
|
|
889
|
+
* deliberately not counted.
|
|
890
|
+
*/
|
|
891
|
+
let firstError: unknown = null;
|
|
892
|
+
|
|
893
|
+
for (const openIncident of openIncidents) {
|
|
894
|
+
try {
|
|
895
|
+
const incidentStateTimeline: IncidentStateTimeline =
|
|
896
|
+
new IncidentStateTimeline();
|
|
897
|
+
incidentStateTimeline.incidentId = openIncident.id!;
|
|
898
|
+
incidentStateTimeline.incidentStateId = resolvedStateId;
|
|
899
|
+
incidentStateTimeline.projectId = openIncident.projectId!;
|
|
900
|
+
incidentStateTimeline.rootCause =
|
|
901
|
+
data.rootCause ||
|
|
902
|
+
"Incident auto-resolved because the SLO burn rate rule that declared it is no longer active.";
|
|
903
|
+
|
|
904
|
+
try {
|
|
905
|
+
await IncidentStateTimelineService.create({
|
|
906
|
+
data: incidentStateTimeline,
|
|
907
|
+
props: {
|
|
908
|
+
isRoot: true,
|
|
909
|
+
},
|
|
910
|
+
});
|
|
911
|
+
} catch (err) {
|
|
912
|
+
/*
|
|
913
|
+
* Idempotent concurrency race, exactly as on the alert path: the
|
|
914
|
+
* evaluation worker and a lifecycle hook can both decide to resolve
|
|
915
|
+
* the same open incident. The loser's onBeforeCreate dedupe throws
|
|
916
|
+
* this exact BadDataException. Match the message so unrelated
|
|
917
|
+
* BadDataExceptions (state ordering, for instance) still propagate.
|
|
918
|
+
*/
|
|
919
|
+
if (
|
|
920
|
+
err instanceof BadDataException &&
|
|
921
|
+
err.message === "Incident state cannot be same as previous state."
|
|
922
|
+
) {
|
|
923
|
+
logger.debug(
|
|
924
|
+
`${openIncident.id?.toString()} - Incident already in resolved state; skipping duplicate state timeline (concurrent race).`,
|
|
925
|
+
);
|
|
926
|
+
} else {
|
|
927
|
+
throw err;
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
} catch (err) {
|
|
931
|
+
logger.error(
|
|
932
|
+
`Error resolving open incident ${openIncident.id?.toString()} for SLO burn rate rule ${data.burnRateRuleId?.toString()}: ${err}`,
|
|
933
|
+
{ projectId: data.projectId?.toString() } as LogAttributes,
|
|
934
|
+
);
|
|
935
|
+
|
|
936
|
+
if (firstError === null) {
|
|
937
|
+
firstError = err;
|
|
938
|
+
}
|
|
353
939
|
}
|
|
354
940
|
}
|
|
941
|
+
|
|
942
|
+
if (firstError !== null) {
|
|
943
|
+
throw firstError;
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
/*
|
|
948
|
+
* Close everything a rule has open, whichever of the two outputs produced
|
|
949
|
+
* it. This is what every "the rule can no longer justify what it opened"
|
|
950
|
+
* caller wants — the worker's recovery branch, the delete hook, and the
|
|
951
|
+
* SLO-level disable/delete path — because a rule's configuration can have
|
|
952
|
+
* changed since the record was opened, so "it declares incidents now" is not
|
|
953
|
+
* a safe proxy for "it has no open alert".
|
|
954
|
+
*
|
|
955
|
+
* A failure on one side must not strand the other, so the incident pass runs
|
|
956
|
+
* even when the alert pass throws, and the first error is rethrown after
|
|
957
|
+
* both have run.
|
|
958
|
+
*/
|
|
959
|
+
@CaptureSpan()
|
|
960
|
+
public async resolveOpenAlertsAndIncidentsForRule(data: {
|
|
961
|
+
serviceLevelObjectiveId: ObjectID;
|
|
962
|
+
burnRateRuleId: ObjectID;
|
|
963
|
+
projectId: ObjectID;
|
|
964
|
+
rootCause?: string | undefined;
|
|
965
|
+
}): Promise<void> {
|
|
966
|
+
let firstError: unknown = null;
|
|
967
|
+
|
|
968
|
+
try {
|
|
969
|
+
await this.resolveOpenAlertsForRule(data);
|
|
970
|
+
} catch (err) {
|
|
971
|
+
firstError = err;
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
try {
|
|
975
|
+
await this.resolveOpenIncidentsForRule(data);
|
|
976
|
+
} catch (err) {
|
|
977
|
+
if (firstError === null) {
|
|
978
|
+
firstError = err;
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
if (firstError !== null) {
|
|
983
|
+
throw firstError;
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
/*
|
|
988
|
+
* Coerce an API-supplied boolean column. Toggles in the dashboard send real
|
|
989
|
+
* booleans, but the CRUD API is public and BaseModel.fromJSON does not
|
|
990
|
+
* coerce Boolean columns, so `"false"` arrives as a non-empty string — which
|
|
991
|
+
* is truthy, and would quietly turn a rule that declares nothing into a rule
|
|
992
|
+
* that declares both. An absent value means "leave it at the default", which
|
|
993
|
+
* is what a create payload that never mentions the field intends.
|
|
994
|
+
*/
|
|
995
|
+
private normalizeBooleanInput(
|
|
996
|
+
value: unknown,
|
|
997
|
+
defaultValue: boolean,
|
|
998
|
+
): boolean {
|
|
999
|
+
if (value === undefined || value === null) {
|
|
1000
|
+
return defaultValue;
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
if (typeof value === "boolean") {
|
|
1004
|
+
return value;
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
if (typeof value === "string") {
|
|
1008
|
+
const normalized: string = value.trim().toLowerCase();
|
|
1009
|
+
|
|
1010
|
+
if (normalized === "") {
|
|
1011
|
+
return defaultValue;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
return normalized !== "false" && normalized !== "0";
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
return Boolean(value);
|
|
355
1018
|
}
|
|
356
1019
|
|
|
357
1020
|
/*
|