@oneuptime/common 13.0.8 → 14.0.1
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/AuditLog.ts +23 -15
- package/Models/DatabaseModels/GlobalConfig.ts +24 -0
- package/Models/DatabaseModels/Index.ts +4 -0
- package/Models/DatabaseModels/Monitor.ts +3 -2
- package/Models/DatabaseModels/MonitorTemplate.ts +2 -1
- package/Models/DatabaseModels/ServiceLevelObjectiveFeed.ts +2 -0
- package/Models/DatabaseModels/ServiceLevelObjectiveLabelRule.ts +522 -0
- package/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.ts +38 -4
- package/Models/DatabaseModels/ServiceLevelObjectiveOwnerRule.ts +603 -0
- package/Scripts/generate-service-worker.js +65 -4
- package/Server/API/BaseAPI.ts +26 -5
- package/Server/API/GlobalConfigAPI.ts +228 -462
- package/Server/API/ProjectOIDC.ts +25 -16
- package/Server/API/ProjectSSO.ts +24 -16
- package/Server/API/StatusPageAPI.ts +100 -42
- package/Server/API/TeamMemberAPI.ts +10 -1
- package/Server/Enterprise/EnterpriseEdition.ts +649 -0
- package/Server/Enterprise/EnterpriseFeature.ts +48 -0
- package/Server/Enterprise/EnterpriseLicenseSnapshot.ts +192 -0
- package/Server/Enterprise/EnterpriseServerModule.ts +233 -0
- package/Server/EnvironmentConfig.ts +147 -2
- package/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794100000000-AddSloLabelAndOwnerRules.ts +248 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794200000000-AddSloMonitorRuleMonitorType.ts +19 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Middleware/UserAuthorization.ts +38 -16
- package/Server/Services/AuditLogService.ts +84 -1079
- package/Server/Services/DatabaseService.ts +10 -0
- package/Server/Services/EnterpriseLicenseService.ts +38 -0
- package/Server/Services/GlobalConfigService.ts +80 -1
- package/Server/Services/Index.ts +4 -0
- package/Server/Services/MonitorProbeService.ts +116 -20
- package/Server/Services/MonitorService.ts +59 -6
- package/Server/Services/MonitorStatusTimelineService.ts +284 -0
- package/Server/Services/MonitorTemplateService.ts +26 -0
- package/Server/Services/ProjectService.ts +284 -0
- package/Server/Services/RumSessionPinService.ts +25 -6
- package/Server/Services/ServiceLevelObjectiveLabelRuleEngineService.ts +385 -0
- package/Server/Services/ServiceLevelObjectiveLabelRuleService.ts +51 -0
- package/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.ts +92 -16
- package/Server/Services/ServiceLevelObjectiveMonitorRuleService.ts +36 -1
- package/Server/Services/ServiceLevelObjectiveOwnerRuleEngineService.ts +521 -0
- package/Server/Services/ServiceLevelObjectiveOwnerRuleService.ts +51 -0
- package/Server/Services/ServiceLevelObjectiveService.ts +28 -0
- package/Server/Services/StatusPagePrivateUserService.ts +7 -3
- package/Server/Services/StatusPageService.ts +78 -1
- package/Server/Services/TeamMemberService.ts +11 -0
- package/Server/Services/TeamService.ts +10 -0
- package/Server/Services/UserService.ts +10 -17
- package/Server/Types/Database/Permissions/CreatePermission.ts +15 -0
- package/Server/Types/Database/Permissions/EditionPermission.ts +208 -18
- package/Server/Types/Database/Permissions/TablePermission.ts +10 -3
- package/Server/Types/Database/Permissions/UpdatePermission.ts +29 -0
- package/Server/Types/Markdown.ts +41 -0
- package/Server/Types/Workflow/Components/Telegram/SendMessageToChat.ts +27 -1
- package/Server/Utils/AI/Toolbox/SloTools.ts +1 -0
- package/Server/Utils/CommunityEditionSsoReport.ts +361 -0
- package/Server/Utils/EditionEnforcement.ts +233 -0
- package/Server/Utils/FrontendEnvironment.ts +41 -2
- package/Server/Utils/InstanceHealth/RedisHealth.ts +12 -277
- package/Server/Utils/Monitor/AffectedResourceList.ts +148 -0
- package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +1 -1
- package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +10 -1
- package/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.ts +1 -1
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +720 -465
- package/Server/Utils/Monitor/MonitoringIntervalValidator.ts +116 -0
- package/Server/Utils/Monitor/RootCauseList.ts +139 -0
- package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +28 -0
- package/Server/Utils/Slo/SloRulePatternValidator.ts +42 -0
- package/Server/Utils/Workspace/Slack/Slack.ts +423 -10
- package/Tests/App/Accounts/LoginPasskey.test.tsx +18 -0
- package/Tests/App/Accounts/LoginSsoEdition.test.tsx +616 -0
- package/Tests/App/AdminDashboard/AdminAuthenticationSsoEdition.test.tsx +217 -0
- package/Tests/App/AdminDashboard/AdminEnterprisePluginPage.test.tsx +357 -0
- package/Tests/App/AdminDashboard/EnterpriseLicensesShell.test.tsx +214 -0
- package/Tests/App/AdminDashboard/GlobalSSOEnterpriseShells.test.tsx +271 -0
- package/Tests/App/AdminDashboard/HealthShells.test.tsx +659 -0
- package/Tests/App/Dashboard/AuditLogsAndComplianceShells.test.tsx +572 -0
- package/Tests/App/Dashboard/EnterpriseFeatureUpgrade.test.tsx +547 -0
- package/Tests/App/Dashboard/EnterprisePluginPage.test.tsx +667 -0
- package/Tests/App/Dashboard/FeedFilterSortIntegration.test.tsx +1632 -0
- package/Tests/App/Dashboard/FeedOptionsLocales.test.ts +250 -0
- package/Tests/App/Dashboard/FeedOrdering.test.ts +279 -9
- package/Tests/App/Dashboard/IdentityEnterpriseShells.test.tsx +319 -0
- package/Tests/App/Dashboard/InvestigationFeedRefresh.test.tsx +60 -1
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +594 -3
- package/Tests/App/Dashboard/OnboardingSsoEmptyState.test.tsx +185 -0
- package/Tests/App/Dashboard/ProductOrientation.test.tsx +646 -0
- package/Tests/App/Dashboard/ResourceFeed.test.tsx +612 -2
- package/Tests/App/Dashboard/ResourceFeedPageWiring.test.ts +30 -0
- package/Tests/App/Dashboard/ResourceFeedPagesFilterSort.test.tsx +1202 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceFeedRefresh.test.tsx +52 -1
- package/Tests/App/Dashboard/SecurityEventConnectionDiagnostics.test.tsx +45 -9
- package/Tests/App/Dashboard/SecurityEventDetailPanel.test.tsx +399 -0
- package/Tests/App/Dashboard/SecurityEventListRow.test.tsx +214 -0
- package/Tests/App/Dashboard/SecurityEventsEmptyState.test.tsx +1 -83
- package/Tests/App/Dashboard/SecurityEventsNavTabs.test.tsx +248 -0
- package/Tests/App/Dashboard/SecurityEventsViewer.test.tsx +1203 -0
- package/Tests/App/Dashboard/SloFeed.test.tsx +106 -1
- package/Tests/App/Dashboard/SloMonitorRuleCriteria.test.tsx +566 -0
- package/Tests/App/Dashboard/SloNavigationWiring.test.tsx +6 -4
- package/Tests/App/Dashboard/SloNoticeBanner.test.tsx +186 -0
- package/Tests/App/Dashboard/SloOverviewKpiStrip.test.tsx +388 -44
- package/Tests/App/Dashboard/SloOverviewLayout.test.tsx +613 -0
- package/Tests/App/Dashboard/UserEmailCallSites.test.tsx +11 -91
- package/Tests/App/StatusPage/StatusPageSsoEmptyState.test.tsx +319 -0
- package/Tests/Helpers/RefreshAwareApiScan.ts +757 -0
- package/Tests/Helpers/TenantScopedRequestScan.ts +515 -0
- package/Tests/Models/DatabaseModels/ResourceFeedModels.test.ts +0 -8
- package/Tests/Models/DatabaseModels/SloLabelAndOwnerRuleModels.test.ts +404 -0
- package/Tests/Models/DatabaseModels/SloOverhaulModels.test.ts +17 -1
- package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +4 -2
- package/Tests/Scripts/GenerateServiceWorker.test.ts +931 -0
- package/Tests/Server/API/BaseAPICreateItemDoesNotMutateModel.test.ts +130 -0
- package/Tests/Server/API/GlobalConfigLicense.test.ts +742 -497
- package/Tests/Server/API/OnCallReadinessAPI.test.ts +35 -909
- package/Tests/Server/API/SsoProviderListingsEdition.test.ts +432 -0
- package/Tests/Server/API/TeamMemberLeaveScimLockEdition.test.ts +252 -0
- package/Tests/Server/Enterprise/EnterpriseEdition.test.ts +824 -0
- package/Tests/Server/Enterprise/EnterpriseFeatureActive.test.ts +643 -0
- package/Tests/Server/Enterprise/EnterpriseLicenseSnapshot.test.ts +294 -0
- package/Tests/Server/Enterprise/EnterpriseModelFeatureMap.test.ts +93 -0
- package/Tests/Server/Enterprise/EnterpriseOnlyModulesLiveInEe.test.ts +582 -0
- package/Tests/Server/Enterprise/EnterpriseServerModule.test.ts +247 -0
- package/Tests/Server/Enterprise/FakeEnterpriseModule.ts +502 -0
- package/Tests/Server/Enterprise/TestBillingFlag.ts +70 -0
- package/Tests/Server/EnvironmentConfigEnterpriseEdition.test.ts +314 -0
- package/Tests/Server/Infrastructure/ContainerBootConfiguration.test.ts +289 -0
- package/Tests/Server/Infrastructure/E2EClickHouseFixtureAccess.test.ts +5 -1
- package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +3 -0
- package/Tests/Server/Infrastructure/Postgres/AddSloLabelAndOwnerRulesMigration.test.ts +407 -0
- package/Tests/Server/Infrastructure/Postgres/AddSloMonitorRuleMonitorTypeMigration.test.ts +171 -0
- package/Tests/Server/Infrastructure/Postgres/SloProductOverhaulMigration.test.ts +88 -4
- package/Tests/Server/Middleware/UserAuthorization.test.ts +37 -2
- package/Tests/Server/Middleware/UserAuthorizationEditionEnforcement.test.ts +516 -0
- package/Tests/Server/Services/AuditLogService.test.ts +460 -990
- package/Tests/Server/Services/CreateAndReadResponsesKeepIds.test.ts +263 -0
- package/Tests/Server/Services/DatabaseServiceRuleCriteriaValidation.test.ts +104 -0
- package/Tests/Server/Services/EnterpriseLicenseServiceKeyGeneration.test.ts +151 -0
- package/Tests/Server/Services/GlobalConfigServiceLicenseColumns.test.ts +357 -0
- package/Tests/Server/Services/MonitorDestinationInfoIPv6.test.ts +101 -0
- package/Tests/Server/Services/MonitorProbeServiceIntervalScheduling.test.ts +333 -0
- package/Tests/Server/Services/MonitorStatusTimelineDailyAggregates.test.ts +303 -0
- package/Tests/Server/Services/ProjectServiceAuditLogLicense.test.ts +701 -0
- package/Tests/Server/Services/ProjectServiceAuditLogSettingsCache.test.ts +31 -35
- package/Tests/Server/Services/RuleRun/LabelRuleEnginesGroupBRun.test.ts +48 -1
- package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupBRun.test.ts +30 -0
- package/Tests/Server/Services/ScimPushGroupsTeamLocksEdition.test.ts +431 -0
- package/Tests/Server/Services/ServiceLevelObjectiveLabelAndOwnerRuleEngines.test.ts +1170 -0
- package/Tests/Server/Services/ServiceLevelObjectiveLabelAndOwnerRuleServices.test.ts +172 -0
- package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.test.ts +323 -0
- package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleService.test.ts +115 -0
- package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleTriggers.test.ts +21 -2
- package/Tests/Server/Services/ServiceLevelObjectiveMonitorTypePostgres.test.ts +480 -0
- package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +162 -0
- package/Tests/Server/Services/SsoRequirementReadMasking.test.ts +419 -0
- package/Tests/Server/Services/SsoRequirementWriteGuard.test.ts +769 -0
- package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +45 -6
- package/Tests/Server/Services/StatusPagePrivateUserInvitationPolicy.test.ts +94 -0
- package/Tests/Server/Services/UserAuthenticationService.test.ts +35 -0
- package/Tests/Server/Services/UserServiceSeatLimit.test.ts +94 -56
- package/Tests/Server/Types/Database/FeedEventTypeFilterQuery.test.ts +745 -0
- package/Tests/Server/Types/Database/Permissions/EditionPermission.test.ts +1823 -0
- package/Tests/Server/Types/Markdown.test.ts +183 -1
- package/Tests/Server/Types/Workflow/Components/ApiComponentSsrf.test.ts +49 -0
- package/Tests/Server/Types/Workflow/Components/TelegramSendMessageToChat.test.ts +331 -0
- package/Tests/Server/Utils/AI/SloTools.test.ts +10 -0
- package/Tests/Server/Utils/CommunityEditionSsoReport.test.ts +565 -0
- package/Tests/Server/Utils/EditionEnforcement.test.ts +303 -0
- package/Tests/Server/Utils/FrontendEnvironment.test.ts +367 -0
- package/Tests/Server/Utils/InstanceHealth/RedisHealth.test.ts +38 -418
- package/Tests/Server/Utils/Monitor/AffectedResourceList.test.ts +518 -0
- package/Tests/Server/Utils/Monitor/Criteria/EvaluateOverTime.test.ts +24 -4
- package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaAnomalyUnits.test.ts +1 -1
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +1339 -96
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorBreachingSamples.test.ts +1101 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorMetricUnits.test.ts +106 -80
- package/Tests/Server/Utils/Monitor/MonitoringIntervalValidator.test.ts +188 -0
- package/Tests/Server/Utils/Monitor/RootCauseList.test.ts +252 -0
- package/Tests/Server/Utils/Rules/RuleRun/RuleRunPermission.test.ts +154 -0
- package/Tests/Server/Utils/SSRFProtection.test.ts +111 -0
- package/Tests/Server/Utils/Slo/SloRulePatternValidator.test.ts +67 -0
- package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +213 -0
- package/Tests/Server/Utils/Workspace/Slack/SlackMarkdownSectionSplit.test.ts +1209 -0
- package/Tests/Types/API/HostnameFromAuthority.test.ts +20 -10
- package/Tests/Types/API/HostnameIPv6.test.ts +149 -0
- package/Tests/Types/API/Route.test.ts +56 -0
- package/Tests/Types/API/URLSchemeLikePath.test.ts +304 -0
- package/Tests/Types/Database/CanonicalModelInstance.test.ts +190 -0
- package/Tests/UI/Components/EditionLabelLapseCopy.ts +104 -0
- package/Tests/UI/Components/EditionLabelLicenseManagerWiring.test.tsx +254 -0
- package/Tests/UI/Components/EditionLabelLicenseRefresh.test.tsx +84 -178
- package/Tests/UI/Components/EditionLabelLicenseStatus.test.tsx +1586 -0
- package/Tests/UI/Components/EditionLabelLicenseWritesGuard.test.tsx +157 -0
- package/Tests/UI/Components/FeedOptions.test.ts +1404 -0
- package/Tests/UI/Components/FeedOptionsButton.test.tsx +2603 -0
- package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +49 -2
- package/Tests/UI/Components/Icon.test.tsx +26 -0
- package/Tests/UI/Components/MarkdownConverters.test.ts +684 -0
- package/Tests/UI/Components/ModelListEmptyState.test.tsx +289 -0
- package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
- package/Tests/UI/Components/TelemetryViewer/TelemetryViewerEmptyContent.test.tsx +131 -0
- package/Tests/UI/Components/useFeedItemsViewKey.test.tsx +1017 -0
- package/Tests/UI/Components/useFeedOptions.test.tsx +1107 -0
- package/Tests/UI/EsbuildEnterpriseAlias.test.ts +1127 -0
- package/Tests/Utils/HostAddressUtil.test.ts +138 -0
- package/Tests/Utils/LabelRuleImportExport.test.ts +102 -0
- package/Tests/Utils/Monitor/MonitorDestinationUtil.test.ts +313 -0
- package/Tests/Utils/Monitor/MonitoringIntervalUtil.test.ts +304 -0
- package/Tests/Utils/Slo/SloDuration.test.ts +115 -24
- package/Tests/Utils/Slo/SloHealth.test.ts +93 -10
- package/Tests/Utils/Slo/SloMonitorRuleCriteria.test.ts +109 -0
- package/Tests/Utils/Slo/SloOverviewText.test.ts +64 -0
- package/Tests/Utils/StatusPage/UptimeDailyAggregateUtil.test.ts +248 -0
- package/Types/API/Hostname.ts +63 -16
- package/Types/API/Route.ts +19 -2
- package/Types/API/URL.ts +26 -2
- package/Types/Database/AccessControl/ColumnAccessControl.ts +19 -7
- package/Types/Database/AccessControl/ColumnBillingAccessControl.ts +19 -7
- package/Types/Database/AccessControl/OwnerOnlyColumn.ts +15 -6
- package/Types/Database/CanonicalModelInstance.ts +102 -0
- package/Types/Database/TableColumn.ts +20 -6
- package/Types/EnterpriseLicense/EnterpriseLicensePeriods.ts +29 -0
- package/Types/IP/IPv6.ts +6 -1
- package/Types/Monitor/MetricMonitor/MetricCriteriaContext.ts +6 -5
- package/Types/Monitor/MetricMonitor/MetricMonitorResponse.ts +9 -0
- package/Types/Monitor/MonitorStep.ts +6 -1
- package/Types/Monitor/ProxmoxAlertTemplates.ts +1 -1
- package/Types/Permission.ts +90 -0
- package/Types/Rules/RuleCriteriaFieldRegistry.ts +11 -0
- package/Types/Rules/RuleRun.ts +4 -0
- package/Types/StatusPage/UptimeDailyAggregate.ts +110 -0
- package/UI/Components/EditionLabel/EditionLabel.tsx +796 -1195
- package/UI/Components/EditionLabel/LicenseManager.ts +119 -0
- package/UI/Components/Feed/FeedOptions.ts +427 -0
- package/UI/Components/Feed/FeedOptionsButton.tsx +692 -0
- package/UI/Components/Feed/useFeedItems.ts +28 -9
- package/UI/Components/Feed/useFeedOptions.ts +225 -0
- package/UI/Components/Graphs/DayUptimeGraph.tsx +123 -15
- package/UI/Components/Icon/Icon.tsx +1 -1
- package/UI/Components/Markdown.tsx/MarkdownConverters.ts +0 -0
- package/UI/Components/ModelList/ModelList.tsx +11 -1
- package/UI/Components/MonitorGraphs/Uptime.tsx +69 -0
- package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +28 -12
- package/UI/esbuild-enterprise.js +263 -0
- package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +7 -2
- package/Utils/HostAddressUtil.ts +94 -0
- package/Utils/LabelRuleImportExport.ts +27 -9
- package/Utils/Monitor/MetricValueFormatter.ts +2 -2
- package/Utils/Monitor/MonitorDestinationUtil.ts +157 -0
- package/Utils/Monitor/MonitoringIntervalUtil.ts +436 -0
- package/Utils/Rules/MonitorTypeRuleCriteria.ts +31 -0
- package/Utils/Slo/SloDuration.ts +22 -6
- package/Utils/Slo/SloHealth.ts +8 -7
- package/Utils/Slo/SloMonitorRuleCriteria.ts +33 -1
- package/Utils/Slo/SloOverviewText.ts +33 -0
- package/Utils/Slo/SloProjection.ts +4 -3
- package/Utils/StatusPage/UptimeDailyAggregateUtil.ts +192 -0
- package/build/dist/Models/AnalyticsModels/AuditLog.js +23 -15
- package/build/dist/Models/AnalyticsModels/AuditLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js +25 -0
- package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +4 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js +2 -2
- package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorTemplate.js +2 -1
- package/build/dist/Models/DatabaseModels/MonitorTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveFeed.js +2 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveLabelRule.js +530 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveLabelRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.js +39 -4
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerRule.js +612 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerRule.js.map +1 -0
- package/build/dist/Server/API/BaseAPI.js +26 -5
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/GlobalConfigAPI.js +148 -344
- package/build/dist/Server/API/GlobalConfigAPI.js.map +1 -1
- package/build/dist/Server/API/ProjectOIDC.js +24 -16
- package/build/dist/Server/API/ProjectOIDC.js.map +1 -1
- package/build/dist/Server/API/ProjectSSO.js +24 -16
- package/build/dist/Server/API/ProjectSSO.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +93 -43
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/TeamMemberAPI.js +8 -1
- package/build/dist/Server/API/TeamMemberAPI.js.map +1 -1
- package/build/dist/Server/Enterprise/EnterpriseEdition.js +466 -0
- package/build/dist/Server/Enterprise/EnterpriseEdition.js.map +1 -0
- package/build/dist/Server/Enterprise/EnterpriseFeature.js +39 -0
- package/build/dist/Server/Enterprise/EnterpriseFeature.js.map +1 -0
- package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js +70 -0
- package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js.map +1 -0
- package/build/dist/Server/Enterprise/EnterpriseServerModule.js +84 -0
- package/build/dist/Server/Enterprise/EnterpriseServerModule.js.map +1 -0
- package/build/dist/Server/EnvironmentConfig.js +84 -2
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794100000000-AddSloLabelAndOwnerRules.js +93 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794100000000-AddSloLabelAndOwnerRules.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794200000000-AddSloMonitorRuleMonitorType.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794200000000-AddSloMonitorRuleMonitorType.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/UserAuthorization.js +30 -11
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Services/AuditLogService.js +71 -740
- package/build/dist/Server/Services/AuditLogService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +7 -0
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/EnterpriseLicenseService.js +34 -0
- package/build/dist/Server/Services/EnterpriseLicenseService.js.map +1 -1
- package/build/dist/Server/Services/GlobalConfigService.js +63 -0
- package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +4 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/MonitorProbeService.js +90 -17
- package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +48 -6
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorStatusTimelineService.js +242 -0
- package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
- package/build/dist/Server/Services/MonitorTemplateService.js +16 -0
- package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +214 -0
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/RumSessionPinService.js +24 -6
- package/build/dist/Server/Services/RumSessionPinService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveLabelRuleEngineService.js +295 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveLabelRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveLabelRuleService.js +56 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveLabelRuleService.js.map +1 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js +59 -14
- package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleService.js +22 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveOwnerRuleEngineService.js +400 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveOwnerRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveOwnerRuleService.js +56 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveOwnerRuleService.js.map +1 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js +21 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
- package/build/dist/Server/Services/StatusPagePrivateUserService.js +7 -3
- package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +71 -0
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +10 -0
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TeamService.js +9 -0
- package/build/dist/Server/Services/TeamService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +10 -16
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js +10 -0
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/EditionPermission.js +154 -14
- package/build/dist/Server/Types/Database/Permissions/EditionPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/TablePermission.js +10 -3
- package/build/dist/Server/Types/Database/Permissions/TablePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js +17 -0
- package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js.map +1 -1
- package/build/dist/Server/Types/Markdown.js +31 -0
- package/build/dist/Server/Types/Markdown.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/Telegram/SendMessageToChat.js +20 -1
- package/build/dist/Server/Types/Workflow/Components/Telegram/SendMessageToChat.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/SloTools.js +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/SloTools.js.map +1 -1
- package/build/dist/Server/Utils/CommunityEditionSsoReport.js +223 -0
- package/build/dist/Server/Utils/CommunityEditionSsoReport.js.map +1 -0
- package/build/dist/Server/Utils/EditionEnforcement.js +187 -0
- package/build/dist/Server/Utils/EditionEnforcement.js.map +1 -0
- package/build/dist/Server/Utils/FrontendEnvironment.js +31 -2
- package/build/dist/Server/Utils/FrontendEnvironment.js.map +1 -1
- package/build/dist/Server/Utils/InstanceHealth/RedisHealth.js +6 -193
- package/build/dist/Server/Utils/InstanceHealth/RedisHealth.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/AffectedResourceList.js +67 -0
- package/build/dist/Server/Utils/Monitor/AffectedResourceList.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +8 -1
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +585 -367
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitoringIntervalValidator.js +88 -0
- package/build/dist/Server/Utils/Monitor/MonitoringIntervalValidator.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/RootCauseList.js +101 -0
- package/build/dist/Server/Utils/Monitor/RootCauseList.js.map +1 -0
- package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +28 -0
- package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Slo/SloRulePatternValidator.js +28 -0
- package/build/dist/Server/Utils/Slo/SloRulePatternValidator.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js +331 -11
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
- package/build/dist/Types/API/Hostname.js +59 -11
- package/build/dist/Types/API/Hostname.js.map +1 -1
- package/build/dist/Types/API/Route.js +18 -2
- package/build/dist/Types/API/Route.js.map +1 -1
- package/build/dist/Types/API/URL.js +23 -2
- package/build/dist/Types/API/URL.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js +19 -7
- package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js +19 -7
- package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js +13 -6
- package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js.map +1 -1
- package/build/dist/Types/Database/CanonicalModelInstance.js +88 -0
- package/build/dist/Types/Database/CanonicalModelInstance.js.map +1 -0
- package/build/dist/Types/Database/TableColumn.js +19 -6
- package/build/dist/Types/Database/TableColumn.js.map +1 -1
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js +28 -0
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js.map +1 -0
- package/build/dist/Types/IP/IPv6.js +6 -1
- package/build/dist/Types/IP/IPv6.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +5 -0
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +1 -1
- package/build/dist/Types/Permission.js +84 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +11 -0
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
- package/build/dist/Types/Rules/RuleRun.js +4 -0
- package/build/dist/Types/Rules/RuleRun.js.map +1 -1
- package/build/dist/Types/StatusPage/UptimeDailyAggregate.js +32 -0
- package/build/dist/Types/StatusPage/UptimeDailyAggregate.js.map +1 -0
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js +414 -585
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
- package/build/dist/UI/Components/EditionLabel/LicenseManager.js +2 -0
- package/build/dist/UI/Components/EditionLabel/LicenseManager.js.map +1 -0
- package/build/dist/UI/Components/Feed/FeedOptions.js +235 -0
- package/build/dist/UI/Components/Feed/FeedOptions.js.map +1 -0
- package/build/dist/UI/Components/Feed/FeedOptionsButton.js +346 -0
- package/build/dist/UI/Components/Feed/FeedOptionsButton.js.map +1 -0
- package/build/dist/UI/Components/Feed/useFeedItems.js +17 -7
- package/build/dist/UI/Components/Feed/useFeedItems.js.map +1 -1
- package/build/dist/UI/Components/Feed/useFeedOptions.js +130 -0
- package/build/dist/UI/Components/Feed/useFeedOptions.js.map +1 -0
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +90 -17
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +1 -1
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js +0 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js.map +1 -1
- package/build/dist/UI/Components/ModelList/ModelList.js +4 -1
- package/build/dist/UI/Components/ModelList/ModelList.js.map +1 -1
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js +42 -1
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +2 -2
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +6 -2
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js.map +1 -1
- package/build/dist/Utils/HostAddressUtil.js +80 -0
- package/build/dist/Utils/HostAddressUtil.js.map +1 -0
- package/build/dist/Utils/LabelRuleImportExport.js +22 -6
- package/build/dist/Utils/LabelRuleImportExport.js.map +1 -1
- package/build/dist/Utils/Monitor/MetricValueFormatter.js +2 -2
- package/build/dist/Utils/Monitor/MonitorDestinationUtil.js +127 -0
- package/build/dist/Utils/Monitor/MonitorDestinationUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitoringIntervalUtil.js +374 -0
- package/build/dist/Utils/Monitor/MonitoringIntervalUtil.js.map +1 -0
- package/build/dist/Utils/Rules/MonitorTypeRuleCriteria.js +18 -0
- package/build/dist/Utils/Rules/MonitorTypeRuleCriteria.js.map +1 -0
- package/build/dist/Utils/Slo/SloDuration.js +13 -5
- package/build/dist/Utils/Slo/SloDuration.js.map +1 -1
- package/build/dist/Utils/Slo/SloHealth.js +8 -7
- package/build/dist/Utils/Slo/SloHealth.js.map +1 -1
- package/build/dist/Utils/Slo/SloMonitorRuleCriteria.js +16 -1
- package/build/dist/Utils/Slo/SloMonitorRuleCriteria.js.map +1 -1
- package/build/dist/Utils/Slo/SloOverviewText.js +16 -0
- package/build/dist/Utils/Slo/SloOverviewText.js.map +1 -1
- package/build/dist/Utils/Slo/SloProjection.js.map +1 -1
- package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js +148 -0
- package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js.map +1 -0
- package/jest.config.json +3 -1
- package/package.json +1 -1
- package/test-setup.sh +103 -34
- package/tsconfig.json +13 -0
- package/Server/API/EnterpriseLicenseAPI.ts +0 -925
- package/Server/API/TeamComplianceAPI.ts +0 -158
- package/Server/Middleware/SCIMAuthorization.ts +0 -141
- package/Server/Services/TeamComplianceService.ts +0 -733
- package/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.ts +0 -186
- package/Server/Utils/InstanceHealth/PostgresHealth.ts +0 -286
- package/Tests/App/AdminDashboard/EnterpriseLicenseInstanceActivity.test.tsx +0 -451
- package/Tests/App/Dashboard/AuditLogsTable.test.tsx +0 -598
- package/Tests/App/Dashboard/SecurityEventsExplorer.test.tsx +0 -761
- package/Tests/App/Dashboard/SecurityEventsSideMenu.test.tsx +0 -247
- package/Tests/App/Dashboard/SecurityEventsTableColumns.test.tsx +0 -382
- package/Tests/App/Dashboard/SecurityEventsVolumeChart.test.tsx +0 -321
- package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +0 -1851
- package/Tests/Server/Middleware/SCIMAuthorization.test.ts +0 -525
- package/Tests/Server/Services/TeamComplianceServiceBehaviour.test.ts +0 -1845
- package/Tests/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.test.ts +0 -495
- package/Tests/Server/Utils/InstanceHealth/PostgresHealth.test.ts +0 -337
- package/Tests/Utils/EnterpriseLicenseSeats.test.ts +0 -576
- package/Tests/Utils/EnterpriseLicenseSync.test.ts +0 -568
- package/Utils/EnterpriseLicense/EnterpriseLicenseSeats.ts +0 -287
- package/Utils/EnterpriseLicense/EnterpriseLicenseSync.ts +0 -244
- package/build/dist/Server/API/EnterpriseLicenseAPI.js +0 -646
- package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +0 -1
- package/build/dist/Server/API/TeamComplianceAPI.js +0 -111
- package/build/dist/Server/API/TeamComplianceAPI.js.map +0 -1
- package/build/dist/Server/Middleware/SCIMAuthorization.js +0 -124
- package/build/dist/Server/Middleware/SCIMAuthorization.js.map +0 -1
- package/build/dist/Server/Services/TeamComplianceService.js +0 -537
- package/build/dist/Server/Services/TeamComplianceService.js.map +0 -1
- package/build/dist/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.js +0 -145
- package/build/dist/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.js.map +0 -1
- package/build/dist/Server/Utils/InstanceHealth/PostgresHealth.js +0 -194
- package/build/dist/Server/Utils/InstanceHealth/PostgresHealth.js.map +0 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js +0 -168
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js.map +0 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSync.js +0 -174
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSync.js.map +0 -1
|
@@ -1,10 +1,49 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
getFrontendEnvVars,
|
|
3
|
+
isEnterpriseEditionRequested,
|
|
4
|
+
} from "../EnvironmentConfig";
|
|
5
|
+
import EnterpriseEdition from "../Enterprise/EnterpriseEdition";
|
|
2
6
|
import { ExpressRequest, ExpressResponse } from "./Express";
|
|
3
7
|
import Response from "./Response";
|
|
8
|
+
import { JSONObject } from "../../Types/JSON";
|
|
4
9
|
|
|
5
10
|
export const FRONTEND_ENVIRONMENT_CACHE_CONTROL: string =
|
|
6
11
|
"private, no-store, no-cache, must-revalidate";
|
|
7
12
|
|
|
13
|
+
/*
|
|
14
|
+
* The edition the frontends are told about is the EFFECTIVE one: whether the
|
|
15
|
+
* enterprise module actually loaded in this process, not what the raw
|
|
16
|
+
* IS_ENTERPRISE_EDITION variable claims. A Community image with a leftover
|
|
17
|
+
* IS_ENTERPRISE_EDITION=true must not show enterprise pages whose server
|
|
18
|
+
* routes do not exist; ENTERPRISE_EDITION_REQUESTED_BUT_NOT_LOADED lets the
|
|
19
|
+
* admin UI explain that mismatch to a master admin instead.
|
|
20
|
+
*
|
|
21
|
+
* "Requested" is EnvironmentConfig's isEnterpriseEditionRequested, the same
|
|
22
|
+
* definition the App's boot guard uses: an explicit ONEUPTIME_EDITION=community
|
|
23
|
+
* withdraws the request, so the Enterprise image (which bakes
|
|
24
|
+
* IS_ENTERPRISE_EDITION=true) run as the Community Edition on purpose is not
|
|
25
|
+
* told to switch images. It is read on every call, like the rest of the
|
|
26
|
+
* environment served here.
|
|
27
|
+
*/
|
|
28
|
+
export const getFrontendEnvironmentVariables: () => JSONObject =
|
|
29
|
+
(): JSONObject => {
|
|
30
|
+
const frontendEnv: JSONObject = getFrontendEnvVars();
|
|
31
|
+
const isEnterpriseEditionLoaded: boolean = EnterpriseEdition.isLoaded();
|
|
32
|
+
const isEnterpriseEditionExpected: boolean = isEnterpriseEditionRequested(
|
|
33
|
+
process.env,
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
frontendEnv["IS_ENTERPRISE_EDITION"] = isEnterpriseEditionLoaded
|
|
37
|
+
? "true"
|
|
38
|
+
: "false";
|
|
39
|
+
frontendEnv["ENTERPRISE_EDITION_REQUESTED_BUT_NOT_LOADED"] =
|
|
40
|
+
isEnterpriseEditionExpected && !isEnterpriseEditionLoaded
|
|
41
|
+
? "true"
|
|
42
|
+
: "false";
|
|
43
|
+
|
|
44
|
+
return frontendEnv;
|
|
45
|
+
};
|
|
46
|
+
|
|
8
47
|
/*
|
|
9
48
|
* The combined App server and the five standalone frontend servers must emit
|
|
10
49
|
* exactly the same environment payload. Keeping the serializer here prevents
|
|
@@ -19,7 +58,7 @@ if(!window.process){
|
|
|
19
58
|
if(!window.process.env){
|
|
20
59
|
window.process.env = {}
|
|
21
60
|
}
|
|
22
|
-
window.process.env = ${JSON.stringify(
|
|
61
|
+
window.process.env = ${JSON.stringify(getFrontendEnvironmentVariables())};
|
|
23
62
|
`;
|
|
24
63
|
};
|
|
25
64
|
|
|
@@ -2,38 +2,14 @@ import Redis, { ClientType } from "../../Infrastructure/Redis";
|
|
|
2
2
|
import Dictionary from "../../../Types/Dictionary";
|
|
3
3
|
|
|
4
4
|
/*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* What a single Redis/Valkey INFO call reports, for the admin health API
|
|
6
|
+
* (packages/App/API/AdminHealth.ts).
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* Under memory pressure with an eviction policy this key can itself be evicted,
|
|
14
|
-
* which costs one interval of eviction detection: the next run finds no sample,
|
|
15
|
-
* re-seeds it, and reports deltas again from there.
|
|
16
|
-
*/
|
|
17
|
-
const COUNTER_SAMPLE_KEY: string = "oneuptime-instance-health-redis-sample";
|
|
18
|
-
const COUNTER_SAMPLE_TTL_IN_SECONDS: number = 60 * 60;
|
|
19
|
-
|
|
20
|
-
/*
|
|
21
|
-
* The minimum age of the baseline the counter deltas are measured against, so
|
|
22
|
-
* every evaluation answers "did this happen in at least the last half hour"
|
|
23
|
-
* rather than "did it happen in the last five minutes".
|
|
24
|
-
*
|
|
25
|
-
* That span is what keeps an edge-triggered signal from flapping. Evictions
|
|
26
|
-
* arriving in bursts would otherwise clear on the first quiet tick and fire
|
|
27
|
-
* again on the next, emailing every other cycle.
|
|
28
|
-
*
|
|
29
|
-
* Two samples are kept rather than one because a single rolling baseline is a
|
|
30
|
-
* TUMBLING window, not a sliding one: the tick immediately after a roll would
|
|
31
|
-
* compare against a five-minute-old sample and a lone quiet tick there would
|
|
32
|
-
* resolve the notification, re-notifying on the next burst of the same ongoing
|
|
33
|
-
* incident. Measuring against the OLDER of two samples makes the lookback
|
|
34
|
-
* always at least this long (and at most twice it).
|
|
8
|
+
* The counter history that turns INFO's cumulative totals into "did this
|
|
9
|
+
* happen recently" belongs to the Enterprise instance-health worker and lives
|
|
10
|
+
* next to it in ee/Server/Workers/InstanceHealth/RedisHealth.ts, which reads
|
|
11
|
+
* INFO through readInfoSnapshot below.
|
|
35
12
|
*/
|
|
36
|
-
export const COUNTER_WINDOW_IN_SECONDS: number = 30 * 60;
|
|
37
13
|
|
|
38
14
|
// Everything a single INFO call reports, with no history involved.
|
|
39
15
|
export interface RedisInfoSnapshot {
|
|
@@ -56,36 +32,6 @@ export interface RedisInfoSnapshot {
|
|
|
56
32
|
uptimeInSeconds: number;
|
|
57
33
|
}
|
|
58
34
|
|
|
59
|
-
export interface RedisHealthSnapshot extends RedisInfoSnapshot {
|
|
60
|
-
/*
|
|
61
|
-
* Increase over the baseline. null when this run has no baseline it can trust
|
|
62
|
-
* — no stored sample, or Redis restarted and reset the counters.
|
|
63
|
-
*/
|
|
64
|
-
evictedKeysDelta: number | null;
|
|
65
|
-
rejectedConnectionsDelta: number | null;
|
|
66
|
-
/*
|
|
67
|
-
* How far back the deltas above actually reach, so messages can state the
|
|
68
|
-
* real span instead of quoting a nominal constant. null alongside null deltas.
|
|
69
|
-
*/
|
|
70
|
-
counterWindowInSeconds: number | null;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export interface RedisCounterSample {
|
|
74
|
-
evictedKeys: number;
|
|
75
|
-
rejectedConnections: number;
|
|
76
|
-
uptimeInSeconds: number;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/*
|
|
80
|
-
* The two retained samples. Deltas are measured against `older`, which keeps
|
|
81
|
-
* the lookback at least COUNTER_WINDOW_IN_SECONDS at every tick; `newer` is the
|
|
82
|
-
* one promoted to `older` at the next roll.
|
|
83
|
-
*/
|
|
84
|
-
export interface RedisCounterSamples {
|
|
85
|
-
older: RedisCounterSample;
|
|
86
|
-
newer: RedisCounterSample;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
35
|
/*
|
|
90
36
|
* INFO is a flat `field:value` document split into `# Section` blocks. Section
|
|
91
37
|
* headers and comment lines are dropped; field names are unique across sections
|
|
@@ -191,144 +137,11 @@ async function getMaxClients(
|
|
|
191
137
|
return null;
|
|
192
138
|
}
|
|
193
139
|
|
|
194
|
-
function parseCounterSample(value: unknown): RedisCounterSample | null {
|
|
195
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
196
|
-
return null;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
const sample: Record<string, unknown> = value as Record<string, unknown>;
|
|
200
|
-
const evictedKeys: number = Number(sample["evictedKeys"]);
|
|
201
|
-
const rejectedConnections: number = Number(sample["rejectedConnections"]);
|
|
202
|
-
const uptimeInSeconds: number = Number(sample["uptimeInSeconds"]);
|
|
203
|
-
|
|
204
|
-
if (
|
|
205
|
-
!Number.isFinite(evictedKeys) ||
|
|
206
|
-
!Number.isFinite(rejectedConnections) ||
|
|
207
|
-
!Number.isFinite(uptimeInSeconds)
|
|
208
|
-
) {
|
|
209
|
-
return null;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
return { evictedKeys, rejectedConnections, uptimeInSeconds };
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
async function readCounterSamples(
|
|
216
|
-
client: ClientType,
|
|
217
|
-
): Promise<RedisCounterSamples | null> {
|
|
218
|
-
try {
|
|
219
|
-
const raw: string | null = await client.get(COUNTER_SAMPLE_KEY);
|
|
220
|
-
|
|
221
|
-
if (!raw) {
|
|
222
|
-
return null;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
const parsed: unknown = JSON.parse(raw);
|
|
226
|
-
|
|
227
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
228
|
-
return null;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
const stored: Record<string, unknown> = parsed as Record<string, unknown>;
|
|
232
|
-
const older: RedisCounterSample | null = parseCounterSample(
|
|
233
|
-
stored["older"],
|
|
234
|
-
);
|
|
235
|
-
const newer: RedisCounterSample | null = parseCounterSample(
|
|
236
|
-
stored["newer"],
|
|
237
|
-
);
|
|
238
|
-
|
|
239
|
-
if (older && newer) {
|
|
240
|
-
return { older, newer };
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
/*
|
|
244
|
-
* A single-sample payload is what the previous release wrote. Treat it as
|
|
245
|
-
* both ends of the pair so an upgrade keeps its baseline instead of going
|
|
246
|
-
* blind for a window.
|
|
247
|
-
*/
|
|
248
|
-
const legacy: RedisCounterSample | null = parseCounterSample(parsed);
|
|
249
|
-
|
|
250
|
-
return legacy ? { older: legacy, newer: legacy } : null;
|
|
251
|
-
} catch {
|
|
252
|
-
// A missing or unreadable sample simply means no delta this run.
|
|
253
|
-
return null;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
140
|
/*
|
|
258
|
-
*
|
|
259
|
-
*
|
|
260
|
-
* kept alive by other means — see getRedisHealthSnapshot.
|
|
141
|
+
* One INFO read, plus the CONFIG fallback for maxclients. Exported so the
|
|
142
|
+
* Enterprise worker's snapshot reads Redis exactly the way this file does.
|
|
261
143
|
*/
|
|
262
|
-
async function
|
|
263
|
-
client: ClientType,
|
|
264
|
-
samples: RedisCounterSamples,
|
|
265
|
-
): Promise<boolean> {
|
|
266
|
-
try {
|
|
267
|
-
await client.set(
|
|
268
|
-
COUNTER_SAMPLE_KEY,
|
|
269
|
-
JSON.stringify(samples),
|
|
270
|
-
"EX",
|
|
271
|
-
COUNTER_SAMPLE_TTL_IN_SECONDS,
|
|
272
|
-
);
|
|
273
|
-
return true;
|
|
274
|
-
} catch {
|
|
275
|
-
/*
|
|
276
|
-
* Losing the baseline must never fail the health evaluation that produced
|
|
277
|
-
* this snapshot, so the error is swallowed and reported through the return.
|
|
278
|
-
*/
|
|
279
|
-
return false;
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
// Keep a baseline alive across the runs that do not rewrite it.
|
|
284
|
-
async function refreshCounterSampleTtl(client: ClientType): Promise<void> {
|
|
285
|
-
try {
|
|
286
|
-
await client.expire(COUNTER_SAMPLE_KEY, COUNTER_SAMPLE_TTL_IN_SECONDS);
|
|
287
|
-
} catch {
|
|
288
|
-
// Same reasoning as writeCounterSamples: never fail the evaluation over this.
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
/*
|
|
293
|
-
* The pair rolls only once the NEWER sample has aged past the window, which
|
|
294
|
-
* promotes it to `older` and starts a fresh one. Deltas are always measured
|
|
295
|
-
* against `older`, so the lookback never drops below the window. Redis' own
|
|
296
|
-
* uptime measures that age, which avoids trusting either machine's clock.
|
|
297
|
-
*/
|
|
298
|
-
export function shouldRollCounterSamples(data: {
|
|
299
|
-
previous: RedisCounterSamples | null;
|
|
300
|
-
currentUptimeInSeconds: number;
|
|
301
|
-
didRestart: boolean;
|
|
302
|
-
}): boolean {
|
|
303
|
-
if (!data.previous || data.didRestart) {
|
|
304
|
-
return true;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
return (
|
|
308
|
-
data.currentUptimeInSeconds - data.previous.newer.uptimeInSeconds >=
|
|
309
|
-
COUNTER_WINDOW_IN_SECONDS
|
|
310
|
-
);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
/*
|
|
314
|
-
* Compare a monotonic counter against its previous value. A decrease, or a
|
|
315
|
-
* shorter uptime than the sample was taken at, means Redis restarted and the
|
|
316
|
-
* counter began again from zero — the difference is meaningless, so report no
|
|
317
|
-
* delta rather than a fabricated spike.
|
|
318
|
-
*/
|
|
319
|
-
export function getCounterDelta(data: {
|
|
320
|
-
current: number;
|
|
321
|
-
previous: number;
|
|
322
|
-
didRestart: boolean;
|
|
323
|
-
}): number | null {
|
|
324
|
-
if (data.didRestart || data.current < data.previous) {
|
|
325
|
-
return null;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
return data.current - data.previous;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
async function readInfoSnapshot(
|
|
144
|
+
export async function readInfoSnapshot(
|
|
332
145
|
client: ClientType,
|
|
333
146
|
): Promise<RedisInfoSnapshot> {
|
|
334
147
|
const info: Dictionary<string> = parseRedisInfo(await client.info());
|
|
@@ -341,9 +154,9 @@ async function readInfoSnapshot(
|
|
|
341
154
|
|
|
342
155
|
/*
|
|
343
156
|
* Read-only view for the admin health API. It deliberately does NOT touch the
|
|
344
|
-
*
|
|
345
|
-
* the worker needs, so a page refresh could hide
|
|
346
|
-
* notification that exists to catch it.
|
|
157
|
+
* counter sample the Enterprise health worker keeps: advancing that baseline
|
|
158
|
+
* here would consume the delta the worker needs, so a page refresh could hide
|
|
159
|
+
* an eviction burst from the notification that exists to catch it.
|
|
347
160
|
*/
|
|
348
161
|
export async function getRedisInfoSnapshot(): Promise<RedisInfoSnapshot | null> {
|
|
349
162
|
const client: ClientType | null = Redis.getClient();
|
|
@@ -354,81 +167,3 @@ export async function getRedisInfoSnapshot(): Promise<RedisInfoSnapshot | null>
|
|
|
354
167
|
|
|
355
168
|
return await readInfoSnapshot(client);
|
|
356
169
|
}
|
|
357
|
-
|
|
358
|
-
/*
|
|
359
|
-
* The evaluating worker's view: the same INFO read, plus the counter deltas
|
|
360
|
-
* that turn cumulative totals into "did this happen in roughly the last
|
|
361
|
-
* COUNTER_WINDOW_IN_SECONDS". Returns null when Redis is unreachable, which the
|
|
362
|
-
* caller treats as "cannot evaluate" rather than "healthy".
|
|
363
|
-
*/
|
|
364
|
-
export async function getRedisHealthSnapshot(): Promise<RedisHealthSnapshot | null> {
|
|
365
|
-
const client: ClientType | null = Redis.getClient();
|
|
366
|
-
|
|
367
|
-
if (!client || !Redis.isConnected()) {
|
|
368
|
-
return null;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
const snapshot: RedisInfoSnapshot = await readInfoSnapshot(client);
|
|
372
|
-
|
|
373
|
-
const previousSamples: RedisCounterSamples | null =
|
|
374
|
-
await readCounterSamples(client);
|
|
375
|
-
const didRestart: boolean = Boolean(
|
|
376
|
-
previousSamples &&
|
|
377
|
-
previousSamples.older.uptimeInSeconds > snapshot.uptimeInSeconds,
|
|
378
|
-
);
|
|
379
|
-
// Deltas always measure against the older half, never the freshly rolled one.
|
|
380
|
-
const baseline: RedisCounterSample | null = previousSamples
|
|
381
|
-
? previousSamples.older
|
|
382
|
-
: null;
|
|
383
|
-
|
|
384
|
-
const current: RedisCounterSample = {
|
|
385
|
-
evictedKeys: snapshot.evictedKeys,
|
|
386
|
-
rejectedConnections: snapshot.rejectedConnections,
|
|
387
|
-
uptimeInSeconds: snapshot.uptimeInSeconds,
|
|
388
|
-
};
|
|
389
|
-
const wantsRoll: boolean = shouldRollCounterSamples({
|
|
390
|
-
previous: previousSamples,
|
|
391
|
-
currentUptimeInSeconds: snapshot.uptimeInSeconds,
|
|
392
|
-
didRestart,
|
|
393
|
-
});
|
|
394
|
-
const didRoll: boolean = wantsRoll
|
|
395
|
-
? await writeCounterSamples(client, {
|
|
396
|
-
older: previousSamples && !didRestart ? previousSamples.newer : current,
|
|
397
|
-
newer: current,
|
|
398
|
-
})
|
|
399
|
-
: false;
|
|
400
|
-
|
|
401
|
-
/*
|
|
402
|
-
* Keep the existing samples alive whenever they were not rolled — including
|
|
403
|
-
* when the roll FAILED, which is the case that matters most. Under the
|
|
404
|
-
* noeviction policy Redis rejects SET once it is out of memory but still
|
|
405
|
-
* serves EXPIRE, so letting a failed write skip the refresh would expire the
|
|
406
|
-
* baseline precisely when memory is full: eviction detection would then go
|
|
407
|
-
* permanently blind at the moment it is needed, because every later write
|
|
408
|
-
* fails the same way and the key never returns.
|
|
409
|
-
*/
|
|
410
|
-
if (!didRoll) {
|
|
411
|
-
await refreshCounterSampleTtl(client);
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
return {
|
|
415
|
-
...snapshot,
|
|
416
|
-
counterWindowInSeconds: baseline
|
|
417
|
-
? snapshot.uptimeInSeconds - baseline.uptimeInSeconds
|
|
418
|
-
: null,
|
|
419
|
-
evictedKeysDelta: baseline
|
|
420
|
-
? getCounterDelta({
|
|
421
|
-
current: snapshot.evictedKeys,
|
|
422
|
-
previous: baseline.evictedKeys,
|
|
423
|
-
didRestart,
|
|
424
|
-
})
|
|
425
|
-
: null,
|
|
426
|
-
rejectedConnectionsDelta: baseline
|
|
427
|
-
? getCounterDelta({
|
|
428
|
-
current: snapshot.rejectedConnections,
|
|
429
|
-
previous: baseline.rejectedConnections,
|
|
430
|
-
didRestart,
|
|
431
|
-
})
|
|
432
|
-
: null,
|
|
433
|
-
};
|
|
434
|
-
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { escapeMarkdownInline } from "../../../Utils/Markdown/MarkdownEscape";
|
|
2
|
+
import RootCauseList, {
|
|
3
|
+
RootCauseListDetail,
|
|
4
|
+
RootCauseListItem,
|
|
5
|
+
} from "./RootCauseList";
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
* The "Affected Resources" block of a platform monitor's root cause.
|
|
9
|
+
*
|
|
10
|
+
* Kubernetes, Proxmox, VMware, Docker Swarm and Ceph monitors each attach a
|
|
11
|
+
* per-resource breakdown to the incident / alert they open, and each one
|
|
12
|
+
* used to render it as a GitHub-flavoured table: up to six columns of long,
|
|
13
|
+
* unbreakable identifiers (pod names, node names, pool paths). That table
|
|
14
|
+
* is read in three places, and it read badly in all of them:
|
|
15
|
+
*
|
|
16
|
+
* - the email: the DetailBox card leaves roughly 416px for the root
|
|
17
|
+
* cause, so every cell wrapped mid-identifier and a ten-row table
|
|
18
|
+
* became a wall of fragments,
|
|
19
|
+
* - Slack: mrkdwn has no tables, so the incident feed posted the raw
|
|
20
|
+
* "| … |" pipe rows, and convertMarkdownToSlackRichText unrolled each
|
|
21
|
+
* row into a "_Row 1_" block of "*Header:* value" lines,
|
|
22
|
+
* - the dashboard: the widest column decided the layout, and a single
|
|
23
|
+
* long node name squeezed the rest into two-line cells.
|
|
24
|
+
*
|
|
25
|
+
* So the breakdown is a ranked list instead. Each resource is one numbered
|
|
26
|
+
* item — worst first, the same order the table used — that says what the
|
|
27
|
+
* resource is, names it, and gives its value:
|
|
28
|
+
*
|
|
29
|
+
* 1. **Pod** `checkout-7d9f` — **3**
|
|
30
|
+
* - Namespace: `payments`
|
|
31
|
+
* - Deployment: `checkout`
|
|
32
|
+
* - Node: `gke-prod-pool-1-abcd`
|
|
33
|
+
*
|
|
34
|
+
* and the rest of its identity sits underneath as labelled bullets. A
|
|
35
|
+
* missing attribute is simply left out, where the table had to print "-".
|
|
36
|
+
*
|
|
37
|
+
* The list itself is a RootCauseList, the shape the Breaching Samples block
|
|
38
|
+
* of a metric monitor's root cause uses too.
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
export interface AffectedResourceListDetail {
|
|
42
|
+
// Plain text. Escaped when rendered.
|
|
43
|
+
label: string;
|
|
44
|
+
// Markdown, rendered as-is. An empty value drops the whole detail.
|
|
45
|
+
value: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface AffectedResourceListEntry {
|
|
49
|
+
// Plain text, e.g. "Pod" or "Virtual Machine". Escaped when rendered.
|
|
50
|
+
kind: string;
|
|
51
|
+
// Markdown, normally built with AffectedResourceList.code().
|
|
52
|
+
name: string;
|
|
53
|
+
// Markdown — the formatted metric value.
|
|
54
|
+
value: string;
|
|
55
|
+
details: Array<AffectedResourceListDetail>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export default class AffectedResourceList {
|
|
59
|
+
// How many resources the list shows before it summarises the rest.
|
|
60
|
+
public static readonly MAX_ENTRIES: number = 10;
|
|
61
|
+
|
|
62
|
+
public static render(input: {
|
|
63
|
+
// Plain text, e.g. "Affected Resources".
|
|
64
|
+
heading: string;
|
|
65
|
+
// Plain text, e.g. "affected resources" in "... and 3 more affected resources".
|
|
66
|
+
overflowNoun: string;
|
|
67
|
+
// Every resource that qualified for the list, including those not shown.
|
|
68
|
+
totalCount: number;
|
|
69
|
+
// The resources to show, already sorted worst first.
|
|
70
|
+
entries: Array<AffectedResourceListEntry>;
|
|
71
|
+
}): string {
|
|
72
|
+
const items: Array<RootCauseListItem> = input.entries.map(
|
|
73
|
+
(entry: AffectedResourceListEntry): RootCauseListItem => {
|
|
74
|
+
/*
|
|
75
|
+
* The kind is bold so each item's first line stands out from the
|
|
76
|
+
* detail bullets under it — the value at the end of the line is
|
|
77
|
+
* bold too, so the eye lands on what it is and how bad it is.
|
|
78
|
+
*/
|
|
79
|
+
const kind: string = escapeMarkdownInline(entry.kind).trim();
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
title: [kind ? `**${kind}**` : "", entry.name.trim()]
|
|
83
|
+
.filter((part: string): boolean => {
|
|
84
|
+
return part.length > 0;
|
|
85
|
+
})
|
|
86
|
+
.join(" "),
|
|
87
|
+
value: entry.value,
|
|
88
|
+
details: entry.details.map(
|
|
89
|
+
(detail: AffectedResourceListDetail): RootCauseListDetail => {
|
|
90
|
+
return {
|
|
91
|
+
label: escapeMarkdownInline(detail.label),
|
|
92
|
+
value: detail.value,
|
|
93
|
+
};
|
|
94
|
+
},
|
|
95
|
+
),
|
|
96
|
+
};
|
|
97
|
+
},
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
const lines: Array<string> = [RootCauseList.render(items)];
|
|
101
|
+
|
|
102
|
+
const hiddenCount: number = input.totalCount - input.entries.length;
|
|
103
|
+
|
|
104
|
+
if (hiddenCount > 0) {
|
|
105
|
+
/*
|
|
106
|
+
* The blank line matters: without it the summary is a lazy
|
|
107
|
+
* continuation of the last item's final bullet, not a paragraph of
|
|
108
|
+
* its own.
|
|
109
|
+
*/
|
|
110
|
+
lines.push("");
|
|
111
|
+
lines.push(
|
|
112
|
+
`*... and ${hiddenCount} more ${escapeMarkdownInline(input.overflowNoun)}*`,
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return `\n\n**${escapeMarkdownInline(input.heading)}** (${input.totalCount} total)\n\n${lines.join("\n")}`;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/*
|
|
120
|
+
* A resource identifier as an inline code span. The identifiers come from
|
|
121
|
+
* telemetry attributes, and a VMware VM or a Proxmox guest can be named
|
|
122
|
+
* anything — RootCauseList.code keeps a name with backticks or line breaks
|
|
123
|
+
* inside its span.
|
|
124
|
+
*/
|
|
125
|
+
public static code(value: string | undefined | null): string {
|
|
126
|
+
return RootCauseList.code(value);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/*
|
|
130
|
+
* A display name alongside the identifier it abbreviates — a Proxmox
|
|
131
|
+
* guest's name and its `qemu/100` id, a Ceph pool's name and number, a
|
|
132
|
+
* vSphere resource pool's name and inventory path. Either half may be
|
|
133
|
+
* missing; when both are the same only one is shown.
|
|
134
|
+
*/
|
|
135
|
+
public static codeWithId(input: {
|
|
136
|
+
name?: string | undefined;
|
|
137
|
+
id?: string | undefined;
|
|
138
|
+
}): string {
|
|
139
|
+
const name: string = AffectedResourceList.code(input.name);
|
|
140
|
+
const id: string = AffectedResourceList.code(input.id);
|
|
141
|
+
|
|
142
|
+
if (name && id && name !== id) {
|
|
143
|
+
return `${name} (${id})`;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return name || id;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
@@ -984,7 +984,7 @@ export default class CompareCriteria {
|
|
|
984
984
|
* reads naturally ("is 42, 55, 60"). For larger arrays, summarize
|
|
985
985
|
* — dumping 30+ numbers on one line makes the root cause unreadable
|
|
986
986
|
* and the detailed breakdown is shown in the Breaching Samples
|
|
987
|
-
*
|
|
987
|
+
* list below.
|
|
988
988
|
*/
|
|
989
989
|
const MAX_INLINE: number = 5;
|
|
990
990
|
|
|
@@ -17,6 +17,7 @@ import MetricService from "../../../Services/MetricService";
|
|
|
17
17
|
import CaptureSpan from "../../Telemetry/CaptureSpan";
|
|
18
18
|
import InBetween from "../../../../Types/BaseDatabase/InBetween";
|
|
19
19
|
import CronTab from "../../CronTab";
|
|
20
|
+
import MonitoringIntervalUtil from "../../../../Utils/Monitor/MonitoringIntervalUtil";
|
|
20
21
|
import logger from "../../Logger";
|
|
21
22
|
|
|
22
23
|
/**
|
|
@@ -488,8 +489,16 @@ export default class EvaluateOverTime {
|
|
|
488
489
|
monitoringInterval?: string | undefined;
|
|
489
490
|
sortedSampleTimes: Array<number>;
|
|
490
491
|
}): number | null {
|
|
492
|
+
/*
|
|
493
|
+
* Through the normalizer first: a monitor storing "5m" has a perfectly
|
|
494
|
+
* well-defined cadence, and treating it as "cadence unknown" made
|
|
495
|
+
* over-time windows fall back to guessing from the data.
|
|
496
|
+
*/
|
|
491
497
|
const configuredIntervalInSeconds: number | null =
|
|
492
|
-
CronTab.getIntervalInSeconds(
|
|
498
|
+
CronTab.getIntervalInSeconds(
|
|
499
|
+
MonitoringIntervalUtil.toCronOrNull(data.monitoringInterval) ||
|
|
500
|
+
data.monitoringInterval,
|
|
501
|
+
);
|
|
493
502
|
|
|
494
503
|
if (configuredIntervalInSeconds !== null) {
|
|
495
504
|
return configuredIntervalInSeconds;
|
|
@@ -1004,7 +1004,7 @@ export default class MetricMonitorCriteria {
|
|
|
1004
1004
|
const sigmaAbs: number = Math.abs(firstBreach.sigma);
|
|
1005
1005
|
|
|
1006
1006
|
/*
|
|
1007
|
-
* Same rendering as the breaching-samples
|
|
1007
|
+
* Same rendering as the breaching-samples list and the comparison
|
|
1008
1008
|
* sentence — an anomaly on a memory metric reads "1.07 GB", not
|
|
1009
1009
|
* "1073741824.000 By". σ is a count of standard deviations, not a
|
|
1010
1010
|
* quantity in the metric's unit, so it stays a bare number; the
|