@oneuptime/common 11.6.1 → 11.7.0
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/Index.ts +4 -0
- package/Models/AnalyticsModels/KubernetesCostAllocation.ts +842 -0
- package/Models/AnalyticsModels/NetworkFlow.ts +54 -0
- package/Models/AnalyticsModels/SloHistory.ts +243 -0
- package/Models/DatabaseModels/Index.ts +20 -0
- package/Models/DatabaseModels/NetworkDevice.ts +453 -6
- package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +7 -6
- package/Models/DatabaseModels/NetworkEndpoint.ts +753 -0
- package/Models/DatabaseModels/NetworkSite.ts +1155 -0
- package/Models/DatabaseModels/NetworkSiteAssignmentRule.ts +517 -0
- package/Models/DatabaseModels/NetworkSiteLink.ts +611 -0
- package/Models/DatabaseModels/NetworkSiteStatusTimeline.ts +520 -0
- package/Models/DatabaseModels/NetworkSiteType.ts +499 -0
- package/Models/DatabaseModels/ServiceLevelObjective.ts +1115 -0
- package/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.ts +762 -0
- package/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.ts +444 -0
- package/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.ts +443 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.ts +359 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.ts +48 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.ts +65 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.ts +88 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.ts +391 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785066759532-MigrationName.ts +30 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +12 -0
- package/Server/Services/AnalyticsDatabaseService.ts +25 -9
- package/Server/Services/Index.ts +24 -0
- package/Server/Services/KubernetesCostAllocationService.ts +14 -0
- package/Server/Services/MetricService.ts +21 -2
- package/Server/Services/MonitorService.ts +22 -0
- package/Server/Services/NetworkDeviceService.ts +438 -2
- package/Server/Services/NetworkEndpointService.ts +414 -0
- package/Server/Services/NetworkSiteAssignmentRuleService.ts +98 -0
- package/Server/Services/NetworkSiteLinkService.ts +10 -0
- package/Server/Services/NetworkSiteService.ts +1254 -0
- package/Server/Services/NetworkSiteStatusTimelineService.ts +10 -0
- package/Server/Services/NetworkSiteTypeService.ts +10 -0
- package/Server/Services/ProjectService.ts +122 -2
- package/Server/Services/ServiceLevelObjectiveBurnRateRuleService.ts +457 -0
- package/Server/Services/ServiceLevelObjectiveOwnerTeamService.ts +10 -0
- package/Server/Services/ServiceLevelObjectiveOwnerUserService.ts +10 -0
- package/Server/Services/ServiceLevelObjectiveService.ts +685 -0
- package/Server/Services/SloHistoryService.ts +101 -0
- package/Server/Services/UserNotificationSettingService.ts +37 -0
- package/Server/Types/AnalyticsDatabase/AggregateBy.ts +9 -0
- package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +15 -0
- package/Server/Utils/AnalyticsDatabase/Statement.ts +39 -3
- package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +87 -48
- package/Server/Utils/Memory.ts +9 -1
- package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +190 -12
- package/Server/Utils/Monitor/Data/OuiVendors.json +6920 -0
- package/Server/Utils/Monitor/DnsResolutionCache.ts +129 -0
- package/Server/Utils/Monitor/MonitorResource.ts +4 -30
- package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +214 -39
- package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +343 -0
- package/Server/Utils/Monitor/NetworkDeviceWalkUtil.ts +251 -0
- package/Server/Utils/Monitor/NetworkInventoryUtil.ts +176 -142
- package/Server/Utils/Monitor/OuiLookupUtil.ts +49 -0
- package/Server/Utils/Monitor/SnmpInterfaceRateUtil.ts +17 -13
- package/Server/Utils/WhatsAppTemplateUtil.ts +7 -3
- package/Tests/Models/AnalyticsModels/KubernetesCostAllocation.test.ts +135 -0
- package/Tests/Models/NetworkSiteHierarchy.test.ts +134 -0
- package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +239 -0
- package/Tests/Server/Services/KubernetesCostAllocationAggregate.test.ts +338 -0
- package/Tests/Server/Services/MetricServiceAggregate.test.ts +142 -0
- package/Tests/Server/Services/NetworkDeviceSiteAssignment.test.ts +484 -0
- package/Tests/Server/Services/NetworkEndpointServiceUpsert.test.ts +686 -0
- package/Tests/Server/Services/NetworkSiteAssignmentRuleService.test.ts +185 -0
- package/Tests/Server/Services/NetworkSiteService.test.ts +1354 -0
- package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleService.test.ts +1313 -0
- package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +1988 -0
- package/Tests/Server/Utils/AnalyticsDatabase/Statement.test.ts +22 -0
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +404 -0
- package/Tests/Server/Utils/Encryption.test.ts +70 -0
- package/Tests/Server/Utils/FileAttachmentMarkdownUtil.test.ts +225 -0
- package/Tests/Server/Utils/JsonWebToken.test.ts +175 -0
- package/Tests/Server/Utils/LocalFile.test.ts +258 -0
- package/Tests/Server/Utils/Memory.test.ts +213 -0
- package/Tests/Server/Utils/Monitor/Criteria/LogMonitorCriteria.test.ts +30 -0
- package/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.ts +385 -0
- package/Tests/Server/Utils/Monitor/DnsResolutionCache.test.ts +194 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +155 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +600 -0
- package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +151 -124
- package/Tests/Server/Utils/Monitor/SnmpInterfaceRateUtil.test.ts +496 -0
- package/Tests/Server/Utils/MonitorCriteriaDataExtractor.test.ts +175 -0
- package/Tests/Server/Utils/MonitorCriteriaMessageFormatter.test.ts +282 -0
- package/Tests/Server/Utils/OuiLookupUtil.test.ts +59 -0
- package/Tests/Server/Utils/SeriesResourceLabels.test.ts +117 -0
- package/Tests/Server/Utils/StackTraceParser.test.ts +370 -0
- package/Tests/Server/Utils/Stream.test.ts +87 -0
- package/Tests/Server/Utils/ValidateGlobalProviderProjectTeams.test.ts +221 -0
- package/Tests/Server/Utils/WhatsAppTemplateUtil.test.ts +199 -0
- package/Tests/Types/Database/CompareOperatorWireSerialization.test.ts +33 -0
- package/Tests/Types/Email.test.ts +198 -0
- package/Tests/Types/Kubernetes/KubernetesObjectParser.test.ts +177 -0
- package/Tests/Types/Log/LogQueryToFilter.test.ts +111 -0
- package/Tests/Types/Monitor/MonitorCriteria.test.ts +155 -0
- package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +465 -0
- package/Tests/Types/Monitor/MonitorStep.test.ts +183 -0
- package/Tests/Types/Monitor/MonitorStepNetworkDeviceMonitor.test.ts +141 -1
- package/Tests/Types/Monitor/MonitorSteps.test.ts +183 -0
- package/Tests/Types/Monitor/MonitorType.test.ts +59 -1
- package/Tests/Types/Monitor/NetworkDeviceAlertPack.test.ts +97 -0
- package/Tests/Types/Monitor/SnmpEndpointDiscovery.test.ts +151 -0
- package/Tests/Types/Monitor/SnmpVendorTemplate.test.ts +110 -6
- package/Tests/Types/NetworkSite/DefaultNetworkSiteType.test.ts +129 -0
- package/Tests/Types/SerializableObjectDictionary.test.ts +166 -0
- package/Tests/Types/Time/RangeStartAndEndDateTime.test.ts +98 -0
- package/Tests/Types/WebsiteRequest.test.ts +230 -0
- package/Tests/UI/Components/EntityFilterRoundTrip.test.tsx +103 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableUrlState.test.tsx +612 -0
- package/Tests/UI/Components/ModelTable/FilterDataToQuery.test.ts +275 -0
- package/Tests/UI/Utils/LogExport.test.ts +159 -0
- package/Tests/UI/Utils/Navigation.test.ts +183 -0
- package/Tests/UI/Utils/TableFilterUrlState.test.ts +539 -0
- package/Tests/UI/Utils/TableViewUrlState.test.ts +272 -0
- package/Tests/Utils/Base64.test.ts +51 -0
- package/Tests/Utils/Boolean.test.ts +76 -0
- package/Tests/Utils/Crypto.test.ts +48 -0
- package/Tests/Utils/Dashboard/DashboardSloComponent.test.ts +259 -0
- package/Tests/Utils/Dashboard/ModelQueryVariableInterpolation.test.ts +162 -0
- package/Tests/Utils/Enum.test.ts +54 -0
- package/Tests/Utils/IpCanonicalUtil.test.ts +85 -0
- package/Tests/Utils/Memory.test.ts +44 -0
- package/Tests/Utils/Metrics/MetricSeriesFingerprint.test.ts +160 -0
- package/Tests/Utils/Monitor/EndpointAttachmentUtil.test.ts +836 -0
- package/Tests/Utils/Monitor/MonitorMetricType.test.ts +218 -0
- package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +447 -0
- package/Tests/Utils/NetworkSite/CidrMatchUtil.test.ts +440 -0
- package/Tests/Utils/NetworkSite/MaterializedPathUtil.test.ts +205 -0
- package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +221 -0
- package/Tests/Utils/NetworkSite/SiteUptimeUtil.test.ts +283 -0
- package/Tests/Utils/ObjectUtil.test.ts +30 -0
- package/Tests/Utils/Slo/SloBurnRateRuleState.test.ts +124 -0
- package/Tests/Utils/Slo/SloDuration.test.ts +148 -0
- package/Tests/Utils/Slo/SloHealth.test.ts +334 -0
- package/Tests/Utils/Slo/SloStatusColor.test.ts +89 -0
- package/Tests/Utils/Slo/SloUtil.test.ts +1980 -0
- package/Tests/Utils/Slo/SloWidgetFormat.test.ts +605 -0
- package/Tests/Utils/TechStack.test.ts +50 -0
- package/Tests/Utils/Traces/CriticalPath.test.ts +178 -0
- package/Types/AnalyticsDatabase/AnalyticsTableName.ts +10 -0
- package/Types/BaseDatabase/EqualTo.ts +9 -1
- package/Types/BaseDatabase/EqualToOrNull.ts +9 -1
- package/Types/BaseDatabase/NotEqual.ts +9 -1
- package/Types/Dashboard/DashboardComponentType.ts +1 -0
- package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +1 -0
- package/Types/Dashboard/DashboardComponents/DashboardSloComponent.ts +42 -0
- package/Types/Dashboard/DashboardTemplates.ts +214 -0
- package/Types/Email/EmailTemplateType.ts +2 -0
- package/Types/Kubernetes/KubernetesCostIngest.ts +79 -0
- package/Types/Monitor/CriteriaFilter.ts +9 -0
- package/Types/Monitor/MonitorStep.ts +5 -8
- package/Types/Monitor/MonitorStepNetworkDeviceMonitor.ts +27 -5
- package/Types/Monitor/MonitorType.ts +15 -5
- package/Types/Monitor/SnmpMonitor/ArpEntry.ts +14 -0
- package/Types/Monitor/SnmpMonitor/FdbEntry.ts +18 -0
- package/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.ts +10 -3
- package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +31 -5
- package/Types/Monitor/SnmpMonitor/SnmpMonitorResponse.ts +12 -0
- package/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.ts +231 -3
- package/Types/NetworkSite/DefaultNetworkSiteType.ts +20 -0
- package/Types/NotificationSetting/NotificationSettingEventType.ts +4 -0
- package/Types/Permission.ts +449 -0
- package/Types/ServiceLevelObjective/SliType.ts +6 -0
- package/Types/ServiceLevelObjective/SloMultiMonitorMode.ts +6 -0
- package/Types/ServiceLevelObjective/SloStatus.ts +9 -0
- package/Types/ServiceLevelObjective/SloWindowType.ts +6 -0
- package/Types/Telemetry/ServiceType.ts +1 -0
- package/UI/Components/Filters/EntityFilter.tsx +16 -0
- package/UI/Components/Filters/FilterViewer.tsx +22 -5
- package/UI/Components/List/List.tsx +8 -0
- package/UI/Components/ModelTable/BaseModelTable.tsx +309 -106
- package/UI/Components/ModelTable/FilterDataToQuery.ts +172 -0
- package/UI/Components/Navbar/NavBar.tsx +16 -2
- package/UI/Components/Navbar/NavBarMenuModal.tsx +3 -3
- package/UI/Utils/Navigation.ts +10 -0
- package/UI/Utils/TableFilterUrlState.ts +204 -17
- package/UI/Utils/TableViewUrlState.ts +165 -0
- package/Utils/Dashboard/Components/DashboardSloComponent.ts +114 -0
- package/Utils/Dashboard/Components/Index.ts +7 -0
- package/Utils/IpCanonicalUtil.ts +134 -0
- package/Utils/Monitor/EndpointAttachmentUtil.ts +508 -0
- package/Utils/Monitor/NetworkTopologyUtil.ts +157 -5
- package/Utils/NetworkSite/CidrMatchUtil.ts +296 -0
- package/Utils/NetworkSite/MaterializedPathUtil.ts +115 -0
- package/Utils/NetworkSite/SiteStatusRollupUtil.ts +97 -0
- package/Utils/NetworkSite/SiteUptimeUtil.ts +111 -0
- package/Utils/Slo/SloBurnRateRuleState.ts +91 -0
- package/Utils/Slo/SloDuration.ts +165 -0
- package/Utils/Slo/SloEvaluation.ts +22 -0
- package/Utils/Slo/SloHealth.ts +302 -0
- package/Utils/Slo/SloStatusColor.ts +54 -0
- package/Utils/Slo/SloUtil.ts +637 -0
- package/Utils/Slo/SloWidgetFormat.ts +383 -0
- package/build/dist/Models/AnalyticsModels/Index.js +4 -0
- package/build/dist/Models/AnalyticsModels/Index.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js +713 -0
- package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js.map +1 -0
- package/build/dist/Models/AnalyticsModels/NetworkFlow.js +44 -0
- package/build/dist/Models/AnalyticsModels/NetworkFlow.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/SloHistory.js +218 -0
- package/build/dist/Models/AnalyticsModels/SloHistory.js.map +1 -0
- package/build/dist/Models/DatabaseModels/Index.js +20 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +458 -6
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +0 -6
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkEndpoint.js +779 -0
- package/build/dist/Models/DatabaseModels/NetworkEndpoint.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkSite.js +1180 -0
- package/build/dist/Models/DatabaseModels/NetworkSite.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js +534 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteLink.js +629 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteLink.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js +538 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteType.js +522 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteType.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js +1134 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js +769 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js +460 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js +459 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.js +130 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.js +31 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.js +36 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.js +49 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.js +140 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785066759532-MigrationName.js +21 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785066759532-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +23 -6
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +24 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/KubernetesCostAllocationService.js +12 -0
- package/build/dist/Server/Services/KubernetesCostAllocationService.js.map +1 -0
- package/build/dist/Server/Services/MetricService.js +21 -3
- package/build/dist/Server/Services/MetricService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +19 -0
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceService.js +351 -1
- package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
- package/build/dist/Server/Services/NetworkEndpointService.js +319 -0
- package/build/dist/Server/Services/NetworkEndpointService.js.map +1 -0
- package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js +90 -0
- package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js.map +1 -0
- package/build/dist/Server/Services/NetworkSiteLinkService.js +9 -0
- package/build/dist/Server/Services/NetworkSiteLinkService.js.map +1 -0
- package/build/dist/Server/Services/NetworkSiteService.js +1038 -0
- package/build/dist/Server/Services/NetworkSiteService.js.map +1 -0
- package/build/dist/Server/Services/NetworkSiteStatusTimelineService.js +9 -0
- package/build/dist/Server/Services/NetworkSiteStatusTimelineService.js.map +1 -0
- package/build/dist/Server/Services/NetworkSiteTypeService.js +9 -0
- package/build/dist/Server/Services/NetworkSiteTypeService.js.map +1 -0
- package/build/dist/Server/Services/ProjectService.js +98 -2
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js +358 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js.map +1 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js +9 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js.map +1 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js +9 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js.map +1 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js +588 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -0
- package/build/dist/Server/Services/SloHistoryService.js +77 -0
- package/build/dist/Server/Services/SloHistoryService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationSettingService.js +20 -0
- package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
- package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js +9 -0
- package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +15 -0
- package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js +31 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +76 -48
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
- package/build/dist/Server/Utils/Memory.js +9 -1
- package/build/dist/Server/Utils/Memory.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +132 -10
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Data/OuiVendors.json +6920 -0
- package/build/dist/Server/Utils/Monitor/DnsResolutionCache.js +77 -0
- package/build/dist/Server/Utils/Monitor/DnsResolutionCache.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +21 -41
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +152 -40
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +262 -0
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js +201 -0
- package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +152 -120
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/OuiLookupUtil.js +44 -0
- package/build/dist/Server/Utils/Monitor/OuiLookupUtil.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/SnmpInterfaceRateUtil.js +10 -10
- package/build/dist/Server/Utils/Monitor/SnmpInterfaceRateUtil.js.map +1 -1
- package/build/dist/Server/Utils/WhatsAppTemplateUtil.js +5 -0
- package/build/dist/Server/Utils/WhatsAppTemplateUtil.js.map +1 -1
- package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +10 -0
- package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -1
- package/build/dist/Types/BaseDatabase/EqualTo.js +9 -1
- package/build/dist/Types/BaseDatabase/EqualTo.js.map +1 -1
- package/build/dist/Types/BaseDatabase/EqualToOrNull.js +9 -1
- package/build/dist/Types/BaseDatabase/EqualToOrNull.js.map +1 -1
- package/build/dist/Types/BaseDatabase/NotEqual.js +9 -1
- package/build/dist/Types/BaseDatabase/NotEqual.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloComponent.js +23 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.js +205 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
- package/build/dist/Types/Email/EmailTemplateType.js +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/Kubernetes/KubernetesCostIngest.js +21 -0
- package/build/dist/Types/Kubernetes/KubernetesCostIngest.js.map +1 -0
- package/build/dist/Types/Monitor/CriteriaFilter.js +1 -0
- package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +5 -5
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepNetworkDeviceMonitor.js +8 -0
- package/build/dist/Types/Monitor/MonitorStepNetworkDeviceMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorType.js +15 -5
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/ArpEntry.js +2 -0
- package/build/dist/Types/Monitor/SnmpMonitor/ArpEntry.js.map +1 -0
- package/build/dist/Types/Monitor/SnmpMonitor/FdbEntry.js +2 -0
- package/build/dist/Types/Monitor/SnmpMonitor/FdbEntry.js.map +1 -0
- package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js +9 -3
- package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js +217 -3
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js.map +1 -1
- package/build/dist/Types/NetworkSite/DefaultNetworkSiteType.js +21 -0
- package/build/dist/Types/NetworkSite/DefaultNetworkSiteType.js.map +1 -0
- package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js +3 -0
- package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js.map +1 -1
- package/build/dist/Types/Permission.js +409 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/ServiceLevelObjective/SliType.js +7 -0
- package/build/dist/Types/ServiceLevelObjective/SliType.js.map +1 -0
- package/build/dist/Types/ServiceLevelObjective/SloMultiMonitorMode.js +7 -0
- package/build/dist/Types/ServiceLevelObjective/SloMultiMonitorMode.js.map +1 -0
- package/build/dist/Types/ServiceLevelObjective/SloStatus.js +10 -0
- package/build/dist/Types/ServiceLevelObjective/SloStatus.js.map +1 -0
- package/build/dist/Types/ServiceLevelObjective/SloWindowType.js +7 -0
- package/build/dist/Types/ServiceLevelObjective/SloWindowType.js.map +1 -0
- package/build/dist/Types/Telemetry/ServiceType.js +1 -0
- package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
- package/build/dist/UI/Components/Filters/EntityFilter.js +15 -0
- package/build/dist/UI/Components/Filters/EntityFilter.js.map +1 -1
- package/build/dist/UI/Components/Filters/FilterViewer.js +19 -4
- package/build/dist/UI/Components/Filters/FilterViewer.js.map +1 -1
- package/build/dist/UI/Components/List/List.js +1 -1
- package/build/dist/UI/Components/List/List.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +235 -89
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/FilterDataToQuery.js +96 -0
- package/build/dist/UI/Components/ModelTable/FilterDataToQuery.js.map +1 -0
- package/build/dist/UI/Components/Navbar/NavBar.js +14 -2
- package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +3 -2
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
- package/build/dist/UI/Utils/Navigation.js +9 -0
- package/build/dist/UI/Utils/Navigation.js.map +1 -1
- package/build/dist/UI/Utils/TableFilterUrlState.js +159 -15
- package/build/dist/UI/Utils/TableFilterUrlState.js.map +1 -1
- package/build/dist/UI/Utils/TableViewUrlState.js +103 -0
- package/build/dist/UI/Utils/TableViewUrlState.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js +93 -0
- package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
- package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
- package/build/dist/Utils/IpCanonicalUtil.js +110 -0
- package/build/dist/Utils/IpCanonicalUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/EndpointAttachmentUtil.js +311 -0
- package/build/dist/Utils/Monitor/EndpointAttachmentUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +98 -5
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/NetworkSite/CidrMatchUtil.js +222 -0
- package/build/dist/Utils/NetworkSite/CidrMatchUtil.js.map +1 -0
- package/build/dist/Utils/NetworkSite/MaterializedPathUtil.js +89 -0
- package/build/dist/Utils/NetworkSite/MaterializedPathUtil.js.map +1 -0
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +60 -0
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -0
- package/build/dist/Utils/NetworkSite/SiteUptimeUtil.js +76 -0
- package/build/dist/Utils/NetworkSite/SiteUptimeUtil.js.map +1 -0
- package/build/dist/Utils/Slo/SloBurnRateRuleState.js +35 -0
- package/build/dist/Utils/Slo/SloBurnRateRuleState.js.map +1 -0
- package/build/dist/Utils/Slo/SloDuration.js +87 -0
- package/build/dist/Utils/Slo/SloDuration.js.map +1 -0
- package/build/dist/Utils/Slo/SloEvaluation.js +21 -0
- package/build/dist/Utils/Slo/SloEvaluation.js.map +1 -0
- package/build/dist/Utils/Slo/SloHealth.js +179 -0
- package/build/dist/Utils/Slo/SloHealth.js.map +1 -0
- package/build/dist/Utils/Slo/SloStatusColor.js +18 -0
- package/build/dist/Utils/Slo/SloStatusColor.js.map +1 -0
- package/build/dist/Utils/Slo/SloUtil.js +393 -0
- package/build/dist/Utils/Slo/SloUtil.js.map +1 -0
- package/build/dist/Utils/Slo/SloWidgetFormat.js +174 -0
- package/build/dist/Utils/Slo/SloWidgetFormat.js.map +1 -0
- package/package.json +2 -2
- package/Types/Dashboard/DashboardComponents/Index.ts +0 -7
- package/build/dist/Types/Dashboard/DashboardComponents/Index.js +0 -8
- package/build/dist/Types/Dashboard/DashboardComponents/Index.js.map +0 -1
|
@@ -0,0 +1,637 @@
|
|
|
1
|
+
import OneUptimeDate, { Moment } from "../../Types/Date";
|
|
2
|
+
import ObjectID from "../../Types/ObjectID";
|
|
3
|
+
import BadDataException from "../../Types/Exception/BadDataException";
|
|
4
|
+
import MonitorStatus from "../../Models/DatabaseModels/MonitorStatus";
|
|
5
|
+
import MonitorStatusTimeline from "../../Models/DatabaseModels/MonitorStatusTimeline";
|
|
6
|
+
import SloMultiMonitorMode from "../../Types/ServiceLevelObjective/SloMultiMonitorMode";
|
|
7
|
+
import SloStatus from "../../Types/ServiceLevelObjective/SloStatus";
|
|
8
|
+
import UptimePrecision from "../../Types/StatusPage/UptimePrecision";
|
|
9
|
+
import UptimeUtil, { UptimeWindow } from "../Uptime/UptimeUtil";
|
|
10
|
+
import MonitorEvent from "../Uptime/MonitorEvent";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A half-open-ish downtime interval [startDate, endDate]. Intervals produced by this
|
|
14
|
+
* util are already clipped to the reporting window and capped at "now".
|
|
15
|
+
*/
|
|
16
|
+
export interface DowntimeInterval {
|
|
17
|
+
startDate: Date;
|
|
18
|
+
endDate: Date;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* One monitor's status timeline rows. Rows for other monitors that leak into the
|
|
23
|
+
* `timelines` array are ignored (they are filtered by `monitorId`).
|
|
24
|
+
*/
|
|
25
|
+
export interface MonitorTimelineSet {
|
|
26
|
+
monitorId: ObjectID;
|
|
27
|
+
timelines: Array<MonitorStatusTimeline>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface TimeSliResult {
|
|
31
|
+
/** Seconds counted against the SLO (downtime seconds). UNROUNDED. */
|
|
32
|
+
badSeconds: number;
|
|
33
|
+
/** Denominator seconds. 0 means "no data at all" (and sliPercentage is 100). */
|
|
34
|
+
totalSeconds: number;
|
|
35
|
+
/** UNROUNDED. Round only at render time via SloUtil.roundForDisplay. */
|
|
36
|
+
sliPercentage: number;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface ErrorBudgetResult {
|
|
40
|
+
/** allowedBadFraction * totalSeconds. */
|
|
41
|
+
budgetTotalSeconds: number;
|
|
42
|
+
/** Bad seconds consumed so far. */
|
|
43
|
+
budgetConsumedSeconds: number;
|
|
44
|
+
/**
|
|
45
|
+
* SIGNED: negative when the SLO is over budget ("-40 min over budget" is
|
|
46
|
+
* operationally useful). Clamp in the UI only, never here.
|
|
47
|
+
*/
|
|
48
|
+
budgetRemainingSeconds: number;
|
|
49
|
+
/** Signed, uncapped below 0, capped at 100. UNROUNDED. */
|
|
50
|
+
budgetRemainingPercentage: number;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface CalendarMonthWindow {
|
|
54
|
+
/** Start of the calendar month containing `at`, in the SLO's timezone. */
|
|
55
|
+
startDate: Date;
|
|
56
|
+
/** EXCLUSIVE end: the first instant of the next calendar month. */
|
|
57
|
+
endDate: Date;
|
|
58
|
+
/**
|
|
59
|
+
* Real elapsed seconds in the FULL calendar period (fixed at period start -
|
|
60
|
+
* NOT elapsed time, or a 1-minute blip at 00:10 on the 1st reads as instant
|
|
61
|
+
* budget exhaustion). This is the budget denominator for calendar windows.
|
|
62
|
+
* DST months in non-UTC timezones are 3600s shorter/longer - real seconds,
|
|
63
|
+
* on purpose.
|
|
64
|
+
*/
|
|
65
|
+
totalSecondsInFullPeriod: number;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* SLO / error budget math. Isomorphic (no server imports) so it is shared by the
|
|
70
|
+
* worker, the dashboard, and later the status page - exactly like UptimeUtil.
|
|
71
|
+
*
|
|
72
|
+
* Design notes (see SLO design doc paragraph 3.1 / 5):
|
|
73
|
+
*
|
|
74
|
+
* - Multi-monitor downtime must NOT be computed by feeding several monitors into
|
|
75
|
+
* UptimeUtil.getNonOverlappingMonitorEvents: its priority flatten lets a
|
|
76
|
+
* better-status event that merely ends later truncate a concurrent worse-status
|
|
77
|
+
* event (Monitor A Offline 10:00-11:00 + Monitor B Operational 10:30-12:00
|
|
78
|
+
* silently loses 30 minutes of downtime). That flatten was built for rendering
|
|
79
|
+
* one status-page bar, not cross-monitor budget math. This util therefore works
|
|
80
|
+
* per monitor (getMonitorEventsForId is per-monitor and correct) and combines
|
|
81
|
+
* monitors with explicit semantics (SloMultiMonitorMode).
|
|
82
|
+
*
|
|
83
|
+
* - Every comparison against a threshold uses UNROUNDED values. Round only at
|
|
84
|
+
* render time (roundForDisplay floors - fine for display, wrong for
|
|
85
|
+
* classification).
|
|
86
|
+
*/
|
|
87
|
+
export default class SloUtil {
|
|
88
|
+
/**
|
|
89
|
+
* Extracts the downtime intervals of a SINGLE monitor inside the window.
|
|
90
|
+
* Uses UptimeUtil.getMonitorEventsForId, which is per-monitor: it clips events
|
|
91
|
+
* to the window, caps them at "now" and imputes an end for open
|
|
92
|
+
* (endsAt = null) rows. Events whose status is not in `downtimeStatuses` are
|
|
93
|
+
* dropped.
|
|
94
|
+
*/
|
|
95
|
+
public static getDowntimeIntervalsForMonitor(
|
|
96
|
+
monitorId: ObjectID,
|
|
97
|
+
timelines: Array<MonitorStatusTimeline>,
|
|
98
|
+
downtimeStatuses: Array<MonitorStatus>,
|
|
99
|
+
window: UptimeWindow,
|
|
100
|
+
): Array<DowntimeInterval> {
|
|
101
|
+
const events: Array<MonitorEvent> = UptimeUtil.getMonitorEventsForId(
|
|
102
|
+
monitorId,
|
|
103
|
+
timelines,
|
|
104
|
+
window,
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
const intervals: Array<DowntimeInterval> = [];
|
|
108
|
+
|
|
109
|
+
for (const event of events) {
|
|
110
|
+
const isDowntimeEvent: boolean = Boolean(
|
|
111
|
+
downtimeStatuses.find((status: MonitorStatus) => {
|
|
112
|
+
return status.id?.toString() === event.eventStatusId.toString();
|
|
113
|
+
}),
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
if (isDowntimeEvent) {
|
|
117
|
+
intervals.push({
|
|
118
|
+
startDate: event.startDate,
|
|
119
|
+
endDate: event.endDate,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return intervals;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* The EARLIEST event start across the attached monitors inside `window`, or
|
|
129
|
+
* null when no monitor has an event that overlaps the window at all.
|
|
130
|
+
*
|
|
131
|
+
* Uses the SAME UptimeUtil.getMonitorEventsForId clipping path the SLI
|
|
132
|
+
* denominator uses, so the answer has identical semantics to the clamp inside
|
|
133
|
+
* computeTimeSli: because events are clipped to the window, the returned date
|
|
134
|
+
* is always >= window.startDate, i.e. it is "how far back this window can
|
|
135
|
+
* actually see data".
|
|
136
|
+
*
|
|
137
|
+
* This exists for callers that must distinguish "the metric is fine" from
|
|
138
|
+
* "we have not observed enough history to judge it yet" - most importantly the
|
|
139
|
+
* burn-rate evaluator, whose FIXED-LENGTH long window would otherwise silently
|
|
140
|
+
* collapse to the data age (see EvaluateSlos.evaluateBurnRateRule).
|
|
141
|
+
*/
|
|
142
|
+
public static getEarliestEventStartDate(
|
|
143
|
+
perMonitorTimelines: Array<MonitorTimelineSet>,
|
|
144
|
+
window: UptimeWindow,
|
|
145
|
+
): Date | null {
|
|
146
|
+
let earliestEventStart: Date | null = null;
|
|
147
|
+
|
|
148
|
+
for (const monitor of perMonitorTimelines) {
|
|
149
|
+
const events: Array<MonitorEvent> = UptimeUtil.getMonitorEventsForId(
|
|
150
|
+
monitor.monitorId,
|
|
151
|
+
monitor.timelines,
|
|
152
|
+
window,
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
for (const event of events) {
|
|
156
|
+
if (
|
|
157
|
+
!earliestEventStart ||
|
|
158
|
+
event.startDate.getTime() < earliestEventStart.getTime()
|
|
159
|
+
) {
|
|
160
|
+
earliestEventStart = event.startDate;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return earliestEventStart;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Merges overlapping and adjacent intervals into a disjoint, sorted set.
|
|
170
|
+
* Millisecond-precise (raw timestamps, not second-granularity moment
|
|
171
|
+
* comparisons) so the merged length agrees with
|
|
172
|
+
* OneUptimeDate.getSecondsBetweenDates.
|
|
173
|
+
*/
|
|
174
|
+
public static mergeIntervals(
|
|
175
|
+
intervals: Array<DowntimeInterval>,
|
|
176
|
+
): Array<DowntimeInterval> {
|
|
177
|
+
const sorted: Array<DowntimeInterval> = [...intervals].sort(
|
|
178
|
+
(a: DowntimeInterval, b: DowntimeInterval) => {
|
|
179
|
+
return a.startDate.getTime() - b.startDate.getTime();
|
|
180
|
+
},
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
const merged: Array<DowntimeInterval> = [];
|
|
184
|
+
|
|
185
|
+
for (const interval of sorted) {
|
|
186
|
+
// skip empty / inverted intervals.
|
|
187
|
+
if (interval.endDate.getTime() <= interval.startDate.getTime()) {
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const last: DowntimeInterval | undefined = merged[merged.length - 1];
|
|
192
|
+
|
|
193
|
+
// overlapping OR adjacent (start === last end) -> extend the last interval.
|
|
194
|
+
if (last && interval.startDate.getTime() <= last.endDate.getTime()) {
|
|
195
|
+
if (interval.endDate.getTime() > last.endDate.getTime()) {
|
|
196
|
+
last.endDate = interval.endDate;
|
|
197
|
+
}
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
merged.push({
|
|
202
|
+
startDate: interval.startDate,
|
|
203
|
+
endDate: interval.endDate,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return merged;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Union downtime across monitors: per monitor, extract its down intervals from
|
|
212
|
+
* its OWN event list, then take the interval union across monitors and sum the
|
|
213
|
+
* seconds. This is the AnyDown numerator.
|
|
214
|
+
*
|
|
215
|
+
* The correctness case this exists for: Monitor A Offline 10:00-11:00 while
|
|
216
|
+
* Monitor B is Operational 10:30-12:00 must yield 3600 seconds of downtime,
|
|
217
|
+
* NOT 1800 - which is what the cross-monitor priority flatten in
|
|
218
|
+
* UptimeUtil.getNonOverlappingMonitorEvents produces.
|
|
219
|
+
*/
|
|
220
|
+
public static getUnionDowntimeSeconds(
|
|
221
|
+
perMonitor: Array<MonitorTimelineSet>,
|
|
222
|
+
downtimeStatuses: Array<MonitorStatus>,
|
|
223
|
+
window: UptimeWindow,
|
|
224
|
+
): number {
|
|
225
|
+
const allIntervals: Array<DowntimeInterval> = [];
|
|
226
|
+
|
|
227
|
+
for (const monitor of perMonitor) {
|
|
228
|
+
allIntervals.push(
|
|
229
|
+
...this.getDowntimeIntervalsForMonitor(
|
|
230
|
+
monitor.monitorId,
|
|
231
|
+
monitor.timelines,
|
|
232
|
+
downtimeStatuses,
|
|
233
|
+
window,
|
|
234
|
+
),
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const merged: Array<DowntimeInterval> = this.mergeIntervals(allIntervals);
|
|
239
|
+
|
|
240
|
+
let totalSeconds: number = 0;
|
|
241
|
+
|
|
242
|
+
for (const interval of merged) {
|
|
243
|
+
totalSeconds += OneUptimeDate.getSecondsBetweenDates(
|
|
244
|
+
interval.startDate,
|
|
245
|
+
interval.endDate,
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return totalSeconds;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Time-based SLI over MonitorStatusTimeline data.
|
|
254
|
+
*
|
|
255
|
+
* Denominator rules:
|
|
256
|
+
* - The window end is always clipped to "now" (a window reaching into the
|
|
257
|
+
* future must not inflate the denominator).
|
|
258
|
+
* - AnyDown: the window start is clamped forward to the EARLIEST first event
|
|
259
|
+
* across the attached monitors, so a young SLO is measured from its first
|
|
260
|
+
* data point, not diluted by time before any monitor existed. The clamp uses
|
|
261
|
+
* the merged set's earliest event so that one old monitor anchors the window
|
|
262
|
+
* for the whole SLO.
|
|
263
|
+
* - MonitorSecondsAverage: the clamp happens PER MONITOR (each monitor's own
|
|
264
|
+
* first event), mirroring UptimeUtil.getTotalDowntimeInSeconds - otherwise
|
|
265
|
+
* adding a young monitor dilutes the SLI.
|
|
266
|
+
*
|
|
267
|
+
* No data at all (no timeline rows for any monitor) => totalSeconds 0,
|
|
268
|
+
* sliPercentage 100 - callers decide what "no data" means (the evaluator marks
|
|
269
|
+
* such SLOs Misconfigured/Paused; it never treats them as healthy 100%).
|
|
270
|
+
*
|
|
271
|
+
* Rows exist but none overlap the window => the monitor was up for the whole
|
|
272
|
+
* window as far as the window can tell: full-window denominator, 0 bad seconds
|
|
273
|
+
* (same answer UptimeUtil gives - see the "orphaned row" production incident
|
|
274
|
+
* test in UptimeUtil.test.ts).
|
|
275
|
+
*
|
|
276
|
+
* All values are UNROUNDED.
|
|
277
|
+
*/
|
|
278
|
+
public static computeTimeSli(data: {
|
|
279
|
+
perMonitorTimelines: Array<MonitorTimelineSet>;
|
|
280
|
+
downtimeStatuses: Array<MonitorStatus>;
|
|
281
|
+
window: UptimeWindow;
|
|
282
|
+
mode: SloMultiMonitorMode;
|
|
283
|
+
}): TimeSliResult {
|
|
284
|
+
const { perMonitorTimelines, downtimeStatuses, window, mode } = data;
|
|
285
|
+
|
|
286
|
+
const hasAnyTimelineRows: boolean = perMonitorTimelines.some(
|
|
287
|
+
(monitor: MonitorTimelineSet) => {
|
|
288
|
+
return monitor.timelines.length > 0;
|
|
289
|
+
},
|
|
290
|
+
);
|
|
291
|
+
|
|
292
|
+
if (!hasAnyTimelineRows) {
|
|
293
|
+
return {
|
|
294
|
+
badSeconds: 0,
|
|
295
|
+
totalSeconds: 0,
|
|
296
|
+
sliPercentage: 100,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (mode === SloMultiMonitorMode.MonitorSecondsAverage) {
|
|
301
|
+
return this.computeMonitorSecondsAverageSli({
|
|
302
|
+
perMonitorTimelines,
|
|
303
|
+
downtimeStatuses,
|
|
304
|
+
window,
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return this.computeAnyDownSli({
|
|
309
|
+
perMonitorTimelines,
|
|
310
|
+
downtimeStatuses,
|
|
311
|
+
window,
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
private static computeAnyDownSli(data: {
|
|
316
|
+
perMonitorTimelines: Array<MonitorTimelineSet>;
|
|
317
|
+
downtimeStatuses: Array<MonitorStatus>;
|
|
318
|
+
window: UptimeWindow;
|
|
319
|
+
}): TimeSliResult {
|
|
320
|
+
const { perMonitorTimelines, downtimeStatuses, window } = data;
|
|
321
|
+
|
|
322
|
+
const windowEndDate: Date = OneUptimeDate.getLesserDate(
|
|
323
|
+
window.endDate,
|
|
324
|
+
OneUptimeDate.getCurrentDate(),
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
/*
|
|
328
|
+
* Earliest first event across monitors. Events from getMonitorEventsForId are
|
|
329
|
+
* already clipped to the window, so every start is >= window.startDate: the
|
|
330
|
+
* clamp can only move the window start FORWARD (young SLO), never backward.
|
|
331
|
+
*/
|
|
332
|
+
const earliestEventStart: Date | null = this.getEarliestEventStartDate(
|
|
333
|
+
perMonitorTimelines,
|
|
334
|
+
window,
|
|
335
|
+
);
|
|
336
|
+
|
|
337
|
+
/*
|
|
338
|
+
* Rows exist but none clip into the window: as far as the window can tell the
|
|
339
|
+
* monitors were up throughout - full-window denominator, zero bad seconds
|
|
340
|
+
* (matches UptimeUtil's behaviour for the same input).
|
|
341
|
+
*/
|
|
342
|
+
const windowStartDate: Date = earliestEventStart
|
|
343
|
+
? OneUptimeDate.getGreaterDate(window.startDate, earliestEventStart)
|
|
344
|
+
: window.startDate;
|
|
345
|
+
|
|
346
|
+
const totalSeconds: number = OneUptimeDate.getSecondsBetweenDates(
|
|
347
|
+
windowStartDate,
|
|
348
|
+
windowEndDate,
|
|
349
|
+
);
|
|
350
|
+
|
|
351
|
+
if (totalSeconds <= 0) {
|
|
352
|
+
return {
|
|
353
|
+
badSeconds: 0,
|
|
354
|
+
totalSeconds: 0,
|
|
355
|
+
sliPercentage: 100,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
const badSeconds: number = this.getUnionDowntimeSeconds(
|
|
360
|
+
perMonitorTimelines,
|
|
361
|
+
downtimeStatuses,
|
|
362
|
+
window,
|
|
363
|
+
);
|
|
364
|
+
|
|
365
|
+
return {
|
|
366
|
+
badSeconds,
|
|
367
|
+
totalSeconds,
|
|
368
|
+
sliPercentage: ((totalSeconds - badSeconds) / totalSeconds) * 100,
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
private static computeMonitorSecondsAverageSli(data: {
|
|
373
|
+
perMonitorTimelines: Array<MonitorTimelineSet>;
|
|
374
|
+
downtimeStatuses: Array<MonitorStatus>;
|
|
375
|
+
window: UptimeWindow;
|
|
376
|
+
}): TimeSliResult {
|
|
377
|
+
const { perMonitorTimelines, downtimeStatuses, window } = data;
|
|
378
|
+
|
|
379
|
+
let badSeconds: number = 0;
|
|
380
|
+
let totalSeconds: number = 0;
|
|
381
|
+
|
|
382
|
+
for (const monitor of perMonitorTimelines) {
|
|
383
|
+
/*
|
|
384
|
+
* Guard against rows of other monitors leaking into this monitor's array -
|
|
385
|
+
* getTotalDowntimeInSeconds does not filter by monitor id, and feeding it a
|
|
386
|
+
* multi-monitor array would reintroduce the priority-flatten bug.
|
|
387
|
+
*/
|
|
388
|
+
const ownTimelines: Array<MonitorStatusTimeline> =
|
|
389
|
+
monitor.timelines.filter((timeline: MonitorStatusTimeline) => {
|
|
390
|
+
return (
|
|
391
|
+
timeline.monitorId?.toString() === monitor.monitorId.toString()
|
|
392
|
+
);
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
/*
|
|
396
|
+
* A monitor with no timeline rows at all has no data - skip it instead of
|
|
397
|
+
* letting it contribute a full window of implied uptime.
|
|
398
|
+
*/
|
|
399
|
+
if (ownTimelines.length === 0) {
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
const {
|
|
404
|
+
totalDowntimeInSeconds,
|
|
405
|
+
totalSecondsInTimePeriod,
|
|
406
|
+
}: { totalDowntimeInSeconds: number; totalSecondsInTimePeriod: number } =
|
|
407
|
+
UptimeUtil.getTotalDowntimeInSeconds(
|
|
408
|
+
ownTimelines,
|
|
409
|
+
downtimeStatuses,
|
|
410
|
+
window,
|
|
411
|
+
);
|
|
412
|
+
|
|
413
|
+
badSeconds += totalDowntimeInSeconds;
|
|
414
|
+
totalSeconds += totalSecondsInTimePeriod;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
if (totalSeconds <= 0) {
|
|
418
|
+
return {
|
|
419
|
+
badSeconds: 0,
|
|
420
|
+
totalSeconds: 0,
|
|
421
|
+
sliPercentage: 100,
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
return {
|
|
426
|
+
badSeconds,
|
|
427
|
+
totalSeconds,
|
|
428
|
+
sliPercentage: (1 - badSeconds / totalSeconds) * 100,
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Error budget from an SLI measurement.
|
|
434
|
+
*
|
|
435
|
+
* Provide either `sliPercentage` or `badSeconds` (badSeconds wins when both are
|
|
436
|
+
* given, since it is the exact number the SLI was derived from).
|
|
437
|
+
*
|
|
438
|
+
* budgetRemainingSeconds is SIGNED - negative when over budget. Never clamp it
|
|
439
|
+
* here; clamp in the UI only. budgetRemainingPercentage is capped at 100 but
|
|
440
|
+
* NOT floored at 0.
|
|
441
|
+
*/
|
|
442
|
+
public static getErrorBudget(data: {
|
|
443
|
+
sliPercentage?: number | undefined;
|
|
444
|
+
badSeconds?: number | undefined;
|
|
445
|
+
totalSeconds: number;
|
|
446
|
+
targetPercentage: number;
|
|
447
|
+
}): ErrorBudgetResult {
|
|
448
|
+
const { sliPercentage, badSeconds, totalSeconds, targetPercentage } = data;
|
|
449
|
+
|
|
450
|
+
this.validateTargetPercentage(targetPercentage);
|
|
451
|
+
|
|
452
|
+
if (badSeconds === undefined && sliPercentage === undefined) {
|
|
453
|
+
throw new BadDataException(
|
|
454
|
+
"Either sliPercentage or badSeconds must be provided to compute the error budget.",
|
|
455
|
+
);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// no elapsed window yet => nothing consumed, full budget remaining.
|
|
459
|
+
if (totalSeconds === 0) {
|
|
460
|
+
return {
|
|
461
|
+
budgetTotalSeconds: 0,
|
|
462
|
+
budgetConsumedSeconds: 0,
|
|
463
|
+
budgetRemainingSeconds: 0,
|
|
464
|
+
budgetRemainingPercentage: 100,
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
const allowedBadFraction: number = 1 - targetPercentage / 100;
|
|
469
|
+
|
|
470
|
+
const budgetTotalSeconds: number = allowedBadFraction * totalSeconds;
|
|
471
|
+
|
|
472
|
+
const budgetConsumedSeconds: number =
|
|
473
|
+
badSeconds !== undefined
|
|
474
|
+
? badSeconds
|
|
475
|
+
: (1 - sliPercentage! / 100) * totalSeconds;
|
|
476
|
+
|
|
477
|
+
const budgetRemainingSeconds: number =
|
|
478
|
+
budgetTotalSeconds - budgetConsumedSeconds;
|
|
479
|
+
|
|
480
|
+
const budgetRemainingPercentage: number = Math.min(
|
|
481
|
+
100,
|
|
482
|
+
(budgetRemainingSeconds / budgetTotalSeconds) * 100,
|
|
483
|
+
);
|
|
484
|
+
|
|
485
|
+
return {
|
|
486
|
+
budgetTotalSeconds,
|
|
487
|
+
budgetConsumedSeconds,
|
|
488
|
+
budgetRemainingSeconds,
|
|
489
|
+
budgetRemainingPercentage,
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* Burn rate: how many times faster than "exactly on target" the budget is being
|
|
495
|
+
* consumed over the measured period. 1 = burning exactly the sustainable rate,
|
|
496
|
+
* 14.4 = the canonical fast-burn page threshold for a 30-day window.
|
|
497
|
+
*
|
|
498
|
+
* Works identically for seconds (time-based SLIs) and event counts (event-based
|
|
499
|
+
* SLIs) - pass bad/total counts in badSeconds/totalSeconds.
|
|
500
|
+
*
|
|
501
|
+
* totalSeconds === 0 (no data in the lookback) => 0: no evidence of burn -
|
|
502
|
+
* callers skip burn rules on no-data windows.
|
|
503
|
+
*/
|
|
504
|
+
public static computeBurnRate(data: {
|
|
505
|
+
badSeconds: number;
|
|
506
|
+
totalSeconds: number;
|
|
507
|
+
targetPercentage: number;
|
|
508
|
+
}): number {
|
|
509
|
+
const { badSeconds, totalSeconds, targetPercentage } = data;
|
|
510
|
+
|
|
511
|
+
this.validateTargetPercentage(targetPercentage);
|
|
512
|
+
|
|
513
|
+
if (totalSeconds === 0) {
|
|
514
|
+
return 0;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
const allowedBadFraction: number = 1 - targetPercentage / 100;
|
|
518
|
+
|
|
519
|
+
return badSeconds / totalSeconds / allowedBadFraction;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* Status from remaining budget, with hysteresis so rolling windows that
|
|
524
|
+
* re-cross a boundary as bad seconds age out do not flap:
|
|
525
|
+
*
|
|
526
|
+
* - enter BudgetExhausted when remaining <= 0; exit only when remaining >= 2
|
|
527
|
+
* - enter AtRisk when remaining <= atRiskThreshold; exit back to Healthy only
|
|
528
|
+
* when remaining >= atRiskThreshold + 5
|
|
529
|
+
*
|
|
530
|
+
* All comparisons use UNROUNDED percentages. This function never emits
|
|
531
|
+
* Misconfigured or Paused - those are set by the caller (zero monitors /
|
|
532
|
+
* all monitors paused) before any math runs.
|
|
533
|
+
*/
|
|
534
|
+
public static computeSloStatus(data: {
|
|
535
|
+
budgetRemainingPercentage: number;
|
|
536
|
+
currentStatus: SloStatus;
|
|
537
|
+
atRiskThresholdPercentage: number;
|
|
538
|
+
}): SloStatus {
|
|
539
|
+
const { budgetRemainingPercentage, currentStatus } = data;
|
|
540
|
+
const threshold: number = data.atRiskThresholdPercentage;
|
|
541
|
+
|
|
542
|
+
// enter exhausted.
|
|
543
|
+
if (budgetRemainingPercentage <= 0) {
|
|
544
|
+
return SloStatus.BudgetExhausted;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// hysteresis: stay exhausted until the budget has meaningfully recovered.
|
|
548
|
+
if (
|
|
549
|
+
currentStatus === SloStatus.BudgetExhausted &&
|
|
550
|
+
budgetRemainingPercentage < 2
|
|
551
|
+
) {
|
|
552
|
+
return SloStatus.BudgetExhausted;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
// enter at risk.
|
|
556
|
+
if (budgetRemainingPercentage <= threshold) {
|
|
557
|
+
return SloStatus.AtRisk;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// hysteresis: stay at risk until comfortably above the threshold.
|
|
561
|
+
if (
|
|
562
|
+
currentStatus === SloStatus.AtRisk &&
|
|
563
|
+
budgetRemainingPercentage < threshold + 5
|
|
564
|
+
) {
|
|
565
|
+
return SloStatus.AtRisk;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
return SloStatus.Healthy;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* The full calendar month containing `at`, resolved in the given IANA timezone
|
|
573
|
+
* (default UTC - calendar boundaries are undefined without a zone). Timezone
|
|
574
|
+
* support comes from moment-timezone, which OneUptimeDate already wraps.
|
|
575
|
+
*
|
|
576
|
+
* `endDate` is EXCLUSIVE (the first instant of the next month).
|
|
577
|
+
* `totalSecondsInFullPeriod` is the real elapsed seconds of the whole month and
|
|
578
|
+
* is the budget denominator for calendar windows - fixed at period start, NOT
|
|
579
|
+
* elapsed time. Note the rollover consequence: on the 1st the budget silently
|
|
580
|
+
* resets to full.
|
|
581
|
+
*/
|
|
582
|
+
public static getCalendarMonthWindow(data: {
|
|
583
|
+
timezone?: string | undefined;
|
|
584
|
+
at: Date;
|
|
585
|
+
}): CalendarMonthWindow {
|
|
586
|
+
const timezone: string = data.timezone || "UTC";
|
|
587
|
+
|
|
588
|
+
if (!Moment.tz.zone(timezone)) {
|
|
589
|
+
throw new BadDataException(`Unknown timezone: ${timezone}`);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
const startOfMonth: ReturnType<typeof Moment.tz> = Moment.tz(
|
|
593
|
+
data.at,
|
|
594
|
+
timezone,
|
|
595
|
+
).startOf("month");
|
|
596
|
+
|
|
597
|
+
const startDate: Date = startOfMonth.toDate();
|
|
598
|
+
const endDate: Date = startOfMonth.clone().add(1, "month").toDate();
|
|
599
|
+
|
|
600
|
+
return {
|
|
601
|
+
startDate,
|
|
602
|
+
endDate,
|
|
603
|
+
totalSecondsInFullPeriod: OneUptimeDate.getSecondsBetweenDates(
|
|
604
|
+
startDate,
|
|
605
|
+
endDate,
|
|
606
|
+
),
|
|
607
|
+
};
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/**
|
|
611
|
+
* Display-only rounding (delegates to UptimeUtil.roundToPrecision, which
|
|
612
|
+
* FLOORS). All status/threshold comparisons in this util use unrounded values;
|
|
613
|
+
* use this at render time only - never before classification.
|
|
614
|
+
*/
|
|
615
|
+
public static roundForDisplay(
|
|
616
|
+
value: number,
|
|
617
|
+
precision: UptimePrecision,
|
|
618
|
+
): number {
|
|
619
|
+
return UptimeUtil.roundToPrecision({
|
|
620
|
+
number: value,
|
|
621
|
+
precision,
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
private static validateTargetPercentage(targetPercentage: number): void {
|
|
626
|
+
/*
|
|
627
|
+
* target >= 100 makes allowedBadFraction 0 (or negative): every budget
|
|
628
|
+
* formula divides by zero and NaN propagates everywhere. target <= 0 is
|
|
629
|
+
* meaningless.
|
|
630
|
+
*/
|
|
631
|
+
if (targetPercentage >= 100 || targetPercentage <= 0) {
|
|
632
|
+
throw new BadDataException(
|
|
633
|
+
"SLO target percentage must be greater than 0 and less than 100.",
|
|
634
|
+
);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
}
|