@oneuptime/common 12.0.1 → 12.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.ts +14 -0
- package/Models/DatabaseModels/Host.ts +12 -4
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/KubernetesContainer.ts +5 -4
- package/Models/DatabaseModels/KubernetesResource.ts +8 -7
- package/Models/DatabaseModels/LogDropFilter.ts +9 -20
- package/Models/DatabaseModels/PodmanResource.ts +6 -6
- package/Models/DatabaseModels/ServiceLevelObjective.ts +91 -0
- package/Models/DatabaseModels/StatusPage.ts +95 -0
- package/Models/DatabaseModels/StatusPageMonitorRule.ts +911 -0
- package/Models/DatabaseModels/StatusPageResource.ts +73 -0
- package/Models/DatabaseModels/TraceDropFilter.ts +9 -20
- package/Server/API/BaseAPI.ts +13 -2
- package/Server/API/DashboardAPI.ts +39 -0
- package/Server/API/TeamMemberAPI.ts +85 -0
- package/Server/EnvironmentConfig.ts +31 -1
- package/Server/Infrastructure/GlobalCache.ts +115 -0
- package/Server/Infrastructure/Postgres/DataSourceOptions.ts +16 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785900000000-AddSloMonitorLabelRule.ts +84 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785915638551-IncreaseHostIpAddressesLength.ts +40 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785930000000-WidenInventoryResourceNameColumns.ts +131 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785930709405-AddStatusPageReportPeriod.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786005052769-AddStatusPageMonitorRule.ts +123 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
- package/Server/Middleware/ProjectAuthorization.ts +66 -4
- package/Server/Services/AlertStateTimelineService.ts +20 -0
- package/Server/Services/BillingService.ts +600 -51
- package/Server/Services/CephClusterService.ts +27 -45
- package/Server/Services/CephResourceService.ts +43 -4
- package/Server/Services/CloudResourceService.ts +24 -42
- package/Server/Services/DatabaseService.ts +198 -6
- package/Server/Services/DockerHostService.ts +20 -38
- package/Server/Services/DockerResourceService.ts +62 -8
- package/Server/Services/DockerSwarmClusterService.ts +28 -46
- package/Server/Services/DockerSwarmResourceService.ts +53 -4
- package/Server/Services/HostService.ts +47 -57
- package/Server/Services/IncidentStateTimelineService.ts +20 -0
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/IoTDeviceService.ts +1 -17
- package/Server/Services/IoTFleetService.ts +20 -38
- package/Server/Services/KubernetesClusterService.ts +18 -36
- package/Server/Services/KubernetesContainerService.ts +50 -9
- package/Server/Services/KubernetesResourceService.ts +53 -7
- package/Server/Services/LabelService.ts +153 -1
- package/Server/Services/MetricTypeService.ts +84 -0
- package/Server/Services/MonitorService.ts +146 -14
- package/Server/Services/MonitorStatusTimelineService.ts +29 -0
- package/Server/Services/MonitorTemplateService.ts +65 -0
- package/Server/Services/PodmanHostService.ts +20 -38
- package/Server/Services/PodmanResourceService.ts +62 -8
- package/Server/Services/ProjectService.ts +165 -35
- package/Server/Services/ProxmoxClusterService.ts +24 -42
- package/Server/Services/ProxmoxResourceService.ts +43 -4
- package/Server/Services/RumApplicationService.ts +20 -38
- package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +21 -0
- package/Server/Services/ServerlessFunctionService.ts +25 -43
- package/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.ts +426 -0
- package/Server/Services/ServiceLevelObjectiveService.ts +39 -0
- package/Server/Services/ServiceService.ts +299 -73
- package/Server/Services/StatusPageMonitorRuleEngineService.ts +752 -0
- package/Server/Services/StatusPageMonitorRuleService.ts +471 -0
- package/Server/Services/StatusPageService.ts +95 -36
- package/Server/Services/StatusPageSubscriberNotificationTemplateService.ts +18 -1
- package/Server/Services/StatusPageSubscriberService.ts +3 -0
- package/Server/Services/TelemetryEntityRelationshipService.ts +1 -0
- package/Server/Services/TelemetryEntityService.ts +1 -0
- package/Server/Types/Database/JSONColumnQuery.ts +621 -0
- package/Server/Types/Database/Permissions/PublicPermission.ts +9 -2
- package/Server/Types/Database/QueryHelper.ts +17 -32
- package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +170 -39
- package/Server/Utils/Database/TruncateColumnValue.ts +84 -0
- package/Server/Utils/Monitor/MonitorResource.ts +63 -36
- package/Server/Utils/Monitor/MonitorStatusTimeline.ts +36 -0
- package/Server/Utils/Monitor/MonitorStepsProjectValidator.ts +148 -127
- package/Server/Utils/Monitor/MonitorStepsReferenceExtractor.ts +434 -0
- package/Server/Utils/SingleFlight.ts +83 -0
- package/Server/Utils/StatusPage/MonitorRulePatternValidator.ts +46 -0
- package/Server/Utils/Telemetry/EntityRegistry.ts +107 -26
- package/Server/Utils/Telemetry/ResourceHeartbeat.ts +314 -0
- package/Server/Utils/Telemetry/Telemetry.ts +351 -122
- package/Tests/App/Dashboard/UsersTableGroupsByPerson.test.tsx +448 -0
- package/Tests/App/Dashboard/WidgetCatalog.test.ts +2 -0
- package/Tests/Models/DatabaseModels/ColumnTransformerInvariants.test.ts +306 -0
- package/Tests/Models/DatabaseModels/NumberColumnDeserialization.test.ts +333 -0
- package/Tests/Models/DatabaseModels/StatusPageMonitorRuleModel.test.ts +190 -0
- package/Tests/Server/API/BaseAPIApiKeyAuth.test.ts +704 -0
- package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +26 -0
- package/Tests/Server/API/TeamMemberRemoveUserFromProjectAPI.test.ts +303 -0
- package/Tests/Server/Infrastructure/GlobalCache.test.ts +226 -0
- package/Tests/Server/Infrastructure/PostgresLockTimeoutOptions.test.ts +181 -0
- package/Tests/Server/Middleware/MasterAdminAuthorization.test.ts +350 -0
- package/Tests/Server/Middleware/ProjectAuthorizationApiKeyHeader.test.ts +362 -0
- package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +687 -0
- package/Tests/Server/Services/BillingService.test.ts +78 -3
- package/Tests/Server/Services/BillingServiceChangePlanCancel.test.ts +645 -0
- package/Tests/Server/Services/BillingServiceTrialPlanChange.test.ts +1005 -0
- package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlocked.test.ts +342 -0
- package/Tests/Server/Services/DropFilterSaveValidation.test.ts +245 -0
- package/Tests/Server/Services/HookFreeWriteLengthClamp.test.ts +503 -0
- package/Tests/Server/Services/HostIpAddressesColumnWidth.test.ts +198 -0
- package/Tests/Server/Services/HostServiceUpdateLastSeen.test.ts +658 -0
- package/Tests/Server/Services/InventoryResourceNameColumnWidth.test.ts +500 -0
- package/Tests/Server/Services/InventoryUpsertSchemaParity.test.ts +586 -0
- package/Tests/Server/Services/InventoryUpsertTruncationGuard.test.ts +1242 -0
- package/Tests/Server/Services/MetricTypeAttachServices.test.ts +222 -0
- package/Tests/Server/Services/MissingReferenceWriteGuard.test.ts +614 -0
- package/Tests/Server/Services/MonitorStatusTimelineFastPath.test.ts +23 -0
- package/Tests/Server/Services/ProjectServiceChangePlan.test.ts +650 -0
- package/Tests/Server/Services/ProjectServiceExtendTrial.test.ts +1 -0
- package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +636 -0
- package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.test.ts +770 -0
- package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +130 -0
- package/Tests/Server/Services/ServiceUpdateLastSeenSplitGates.test.ts +705 -0
- package/Tests/Server/Services/SloMonitorLabelRuleHooks.test.ts +352 -0
- package/Tests/Server/Services/StatusPageMonitorRuleEngineService.test.ts +1719 -0
- package/Tests/Server/Services/StatusPageMonitorRuleHooks.test.ts +1212 -0
- package/Tests/Server/Services/StatusPageMonitorRuleMonitorCreateHook.test.ts +228 -0
- package/Tests/Server/Services/StatusPageSubscriberReport.test.ts +29 -13
- package/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts +69 -8
- package/Tests/Server/Types/Database/JSONColumnQuery.test.ts +593 -0
- package/Tests/Server/Types/Database/Permissions/PublicPermission.test.ts +495 -0
- package/Tests/Server/Types/Database/QueryUtil.test.ts +113 -0
- package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +267 -0
- package/Tests/Server/Utils/Database/ProjectScopedReferenceValidator.test.ts +260 -13
- package/Tests/Server/Utils/Database/TruncateColumnValue.test.ts +179 -0
- package/Tests/Server/Utils/EntityRegistryRowFence.test.ts +302 -0
- package/Tests/Server/Utils/MetricTypeIndexConvergence.test.ts +598 -0
- package/Tests/Server/Utils/Monitor/MonitorStatusTimelineUnusableStatus.test.ts +154 -0
- package/Tests/Server/Utils/Monitor/MonitorStepsProjectValidator.test.ts +638 -92
- package/Tests/Server/Utils/Monitor/MonitorStepsReferenceExtractor.test.ts +724 -0
- package/Tests/Server/Utils/SingleFlight.test.ts +221 -0
- package/Tests/Types/Dashboard/NetworkDashboardTemplate.test.ts +793 -0
- package/Tests/Types/Database/BigIntColumnTransformer.test.ts +147 -0
- package/Tests/Types/Database/DatabasePropertyTransformer.test.ts +140 -0
- package/Tests/Types/Database/NumericColumnValue.test.ts +127 -0
- package/Tests/Types/Decimal.test.ts +37 -0
- package/Tests/Types/Events/Recurring.test.ts +157 -0
- package/Tests/Types/Monitor/SnmpVersionParsing.test.ts +152 -0
- package/Tests/Types/Port.test.ts +38 -0
- package/Tests/UI/Components/LogsHistogram.test.tsx +276 -0
- package/Tests/UI/Components/ModelTable/ModelTableGroupsProjectUsers.test.tsx +375 -0
- package/Tests/UI/Components/ModelTable/useCustomFieldColumns.test.tsx +196 -0
- package/Tests/UI/Components/UseLiveLogsRefresh.test.tsx +489 -0
- package/Tests/UI/Components/UseLogsHistogram.test.tsx +500 -0
- package/Tests/UI/Utils/ProjectUsersModelAPI.test.ts +739 -0
- package/Tests/UI/Utils/TeamMembersByUser.test.ts +633 -0
- package/Tests/Utils/Dashboard/Components/DashboardComponentsUtil.test.ts +120 -0
- package/Tests/Utils/Dashboard/DashboardNetworkMapComponent.test.ts +327 -0
- package/Tests/Utils/StatusPage/ReportPeriod.test.ts +218 -0
- package/Tests/Utils/Telemetry/HostIpAddresses.test.ts +291 -0
- package/Types/CustomField/CustomFieldDefinition.ts +24 -0
- package/Types/Dashboard/DashboardComponentType.ts +1 -0
- package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +1 -0
- package/Types/Dashboard/DashboardComponents/DashboardNetworkMapComponent.ts +40 -0
- package/Types/Dashboard/DashboardTemplates.ts +397 -0
- package/Types/Database/BigIntColumnTransformer.ts +74 -0
- package/Types/Database/DatabaseProperty.ts +26 -0
- package/Types/Database/NumericColumnValue.ts +128 -0
- package/Types/Date.ts +112 -0
- package/Types/Decimal.ts +16 -4
- package/Types/Events/Recurring.ts +99 -1
- package/Types/Permission.ts +48 -0
- package/Types/Port.ts +16 -4
- package/Types/StatusPage/StatusPageReport.ts +11 -0
- package/Types/StatusPage/StatusPageReportPeriodType.ts +21 -0
- package/UI/Components/LogsViewer/useLiveLogsRefresh.ts +86 -0
- package/UI/Components/LogsViewer/useLogsHistogram.ts +113 -0
- package/UI/Components/ModelTable/CustomFieldColumns.tsx +2 -6
- package/UI/Components/ModelTable/useCustomFieldColumns.ts +21 -2
- package/UI/Utils/ModelAPI/ProjectUsersModelAPI.ts +305 -0
- package/UI/Utils/TeamMembersByUser.ts +302 -0
- package/Utils/Dashboard/Components/DashboardNetworkMapComponent.ts +136 -0
- package/Utils/Dashboard/Components/Index.ts +7 -0
- package/Utils/StatusPage/ReportPeriod.ts +236 -0
- package/Utils/Telemetry/HostIpAddresses.ts +98 -0
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js +12 -0
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Host.js +12 -4
- package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesContainer.js +4 -4
- package/build/dist/Models/DatabaseModels/KubernetesContainer.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesResource.js +7 -7
- package/build/dist/Models/DatabaseModels/KubernetesResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/LogDropFilter.js +9 -20
- package/build/dist/Models/DatabaseModels/LogDropFilter.js.map +1 -1
- package/build/dist/Models/DatabaseModels/PodmanResource.js +6 -6
- package/build/dist/Models/DatabaseModels/PodmanResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js +87 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +98 -0
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageMonitorRule.js +925 -0
- package/build/dist/Models/DatabaseModels/StatusPageMonitorRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/StatusPageResource.js +72 -0
- package/build/dist/Models/DatabaseModels/StatusPageResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TraceDropFilter.js +9 -20
- package/build/dist/Models/DatabaseModels/TraceDropFilter.js.map +1 -1
- package/build/dist/Server/API/BaseAPI.js +11 -1
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/DashboardAPI.js +39 -0
- package/build/dist/Server/API/DashboardAPI.js.map +1 -1
- package/build/dist/Server/API/TeamMemberAPI.js +57 -2
- package/build/dist/Server/API/TeamMemberAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +27 -1
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/GlobalCache.js +91 -0
- package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js +5 -3
- package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785900000000-AddSloMonitorLabelRule.js +45 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785900000000-AddSloMonitorLabelRule.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785915638551-IncreaseHostIpAddressesLength.js +31 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785915638551-IncreaseHostIpAddressesLength.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930000000-WidenInventoryResourceNameColumns.js +90 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930000000-WidenInventoryResourceNameColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930709405-AddStatusPageReportPeriod.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930709405-AddStatusPageReportPeriod.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786005052769-AddStatusPageMonitorRule.js +48 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786005052769-AddStatusPageMonitorRule.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/ProjectAuthorization.js +59 -4
- package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
- package/build/dist/Server/Services/AlertStateTimelineService.js +19 -0
- package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/BillingService.js +466 -36
- package/build/dist/Server/Services/BillingService.js.map +1 -1
- package/build/dist/Server/Services/CephClusterService.js +26 -39
- package/build/dist/Server/Services/CephClusterService.js.map +1 -1
- package/build/dist/Server/Services/CephResourceService.js +28 -3
- package/build/dist/Server/Services/CephResourceService.js.map +1 -1
- package/build/dist/Server/Services/CloudResourceService.js +23 -36
- package/build/dist/Server/Services/CloudResourceService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +155 -2
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DockerHostService.js +19 -32
- package/build/dist/Server/Services/DockerHostService.js.map +1 -1
- package/build/dist/Server/Services/DockerResourceService.js +34 -4
- package/build/dist/Server/Services/DockerResourceService.js.map +1 -1
- package/build/dist/Server/Services/DockerSwarmClusterService.js +27 -40
- package/build/dist/Server/Services/DockerSwarmClusterService.js.map +1 -1
- package/build/dist/Server/Services/DockerSwarmResourceService.js +28 -3
- package/build/dist/Server/Services/DockerSwarmResourceService.js.map +1 -1
- package/build/dist/Server/Services/HostService.js +58 -64
- package/build/dist/Server/Services/HostService.js.map +1 -1
- package/build/dist/Server/Services/IncidentStateTimelineService.js +19 -0
- package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/IoTDeviceService.js +1 -8
- package/build/dist/Server/Services/IoTDeviceService.js.map +1 -1
- package/build/dist/Server/Services/IoTFleetService.js +19 -32
- package/build/dist/Server/Services/IoTFleetService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesClusterService.js +17 -30
- package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesContainerService.js +29 -3
- package/build/dist/Server/Services/KubernetesContainerService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesResourceService.js +32 -4
- package/build/dist/Server/Services/KubernetesResourceService.js.map +1 -1
- package/build/dist/Server/Services/LabelService.js +127 -0
- package/build/dist/Server/Services/LabelService.js.map +1 -1
- package/build/dist/Server/Services/MetricTypeService.js +74 -0
- package/build/dist/Server/Services/MetricTypeService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +128 -9
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorStatusTimelineService.js +28 -0
- package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
- package/build/dist/Server/Services/MonitorTemplateService.js +60 -0
- package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
- package/build/dist/Server/Services/PodmanHostService.js +19 -32
- package/build/dist/Server/Services/PodmanHostService.js.map +1 -1
- package/build/dist/Server/Services/PodmanResourceService.js +34 -4
- package/build/dist/Server/Services/PodmanResourceService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +135 -21
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxClusterService.js +23 -36
- package/build/dist/Server/Services/ProxmoxClusterService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxResourceService.js +28 -3
- package/build/dist/Server/Services/ProxmoxResourceService.js.map +1 -1
- package/build/dist/Server/Services/RumApplicationService.js +19 -32
- package/build/dist/Server/Services/RumApplicationService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +20 -0
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/ServerlessFunctionService.js +24 -37
- package/build/dist/Server/Services/ServerlessFunctionService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js +347 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js +33 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
- package/build/dist/Server/Services/ServiceService.js +236 -61
- package/build/dist/Server/Services/ServiceService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js +603 -0
- package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/StatusPageMonitorRuleService.js +401 -0
- package/build/dist/Server/Services/StatusPageMonitorRuleService.js.map +1 -0
- package/build/dist/Server/Services/StatusPageService.js +69 -46
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js +17 -1
- package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberService.js +3 -0
- package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryEntityRelationshipService.js +1 -0
- package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryEntityService.js +1 -0
- package/build/dist/Server/Services/TelemetryEntityService.js.map +1 -1
- package/build/dist/Server/Types/Database/JSONColumnQuery.js +402 -0
- package/build/dist/Server/Types/Database/JSONColumnQuery.js.map +1 -0
- package/build/dist/Server/Types/Database/Permissions/PublicPermission.js +9 -2
- package/build/dist/Server/Types/Database/Permissions/PublicPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js +17 -27
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +105 -29
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
- package/build/dist/Server/Utils/Database/TruncateColumnValue.js +32 -0
- package/build/dist/Server/Utils/Database/TruncateColumnValue.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +56 -32
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js +30 -3
- package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js +110 -98
- package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorStepsReferenceExtractor.js +312 -0
- package/build/dist/Server/Utils/Monitor/MonitorStepsReferenceExtractor.js.map +1 -0
- package/build/dist/Server/Utils/SingleFlight.js +76 -0
- package/build/dist/Server/Utils/SingleFlight.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js +29 -0
- package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +78 -19
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js +160 -0
- package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/Telemetry.js +279 -104
- package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
- package/build/dist/Types/CustomField/CustomFieldDefinition.js +2 -0
- package/build/dist/Types/CustomField/CustomFieldDefinition.js.map +1 -0
- 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/DashboardNetworkMapComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardNetworkMapComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.js +368 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
- package/build/dist/Types/Database/BigIntColumnTransformer.js +66 -0
- package/build/dist/Types/Database/BigIntColumnTransformer.js.map +1 -0
- package/build/dist/Types/Database/DatabaseProperty.js +25 -0
- package/build/dist/Types/Database/DatabaseProperty.js.map +1 -1
- package/build/dist/Types/Database/NumericColumnValue.js +97 -0
- package/build/dist/Types/Database/NumericColumnValue.js.map +1 -0
- package/build/dist/Types/Date.js +68 -0
- package/build/dist/Types/Date.js.map +1 -1
- package/build/dist/Types/Decimal.js +14 -3
- package/build/dist/Types/Decimal.js.map +1 -1
- package/build/dist/Types/Events/Recurring.js +63 -0
- package/build/dist/Types/Events/Recurring.js.map +1 -1
- package/build/dist/Types/Permission.js +42 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Port.js +15 -5
- package/build/dist/Types/Port.js.map +1 -1
- package/build/dist/Types/StatusPage/StatusPageReportPeriodType.js +22 -0
- package/build/dist/Types/StatusPage/StatusPageReportPeriodType.js.map +1 -0
- package/build/dist/UI/Components/LogsViewer/useLiveLogsRefresh.js +44 -0
- package/build/dist/UI/Components/LogsViewer/useLiveLogsRefresh.js.map +1 -0
- package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js +75 -0
- package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +18 -2
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js +213 -0
- package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js.map +1 -0
- package/build/dist/UI/Utils/TeamMembersByUser.js +195 -0
- package/build/dist/UI/Utils/TeamMembersByUser.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardNetworkMapComponent.js +114 -0
- package/build/dist/Utils/Dashboard/Components/DashboardNetworkMapComponent.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/StatusPage/ReportPeriod.js +131 -0
- package/build/dist/Utils/StatusPage/ReportPeriod.js.map +1 -0
- package/build/dist/Utils/Telemetry/HostIpAddresses.js +82 -0
- package/build/dist/Utils/Telemetry/HostIpAddresses.js.map +1 -0
- package/jest.config.json +2 -0
- package/package.json +1 -1
- package/tsconfig.json +12 -1
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import DatabaseService from "./DatabaseService";
|
|
2
2
|
import Model from "../../Models/DatabaseModels/DockerResource";
|
|
3
3
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
4
|
+
import ColumnLength from "../../Types/Database/ColumnLength";
|
|
4
5
|
import ObjectID from "../../Types/ObjectID";
|
|
5
6
|
import OneUptimeDate from "../../Types/Date";
|
|
6
7
|
import { JSONObject } from "../../Types/JSON";
|
|
8
|
+
import {
|
|
9
|
+
truncateLongText,
|
|
10
|
+
truncateShortText,
|
|
11
|
+
} from "../Utils/Database/TruncateColumnValue";
|
|
7
12
|
import logger from "../Utils/Logger";
|
|
8
13
|
|
|
9
14
|
/*
|
|
@@ -56,6 +61,35 @@ export interface DockerHostInventoryCounts {
|
|
|
56
61
|
const UPSERT_BATCH_SIZE: number = 500;
|
|
57
62
|
const STALE_DELETE_WARN_THRESHOLD: number = 100;
|
|
58
63
|
|
|
64
|
+
/*
|
|
65
|
+
* DockerResource's text columns are bounded varchars — name / imageName
|
|
66
|
+
* at 500 chars, kind / containerId / state at 100. These bulk paths go
|
|
67
|
+
* through manager.query(), which skips the length validation
|
|
68
|
+
* DatabaseService applies to ordinary writes, so a single oversized
|
|
69
|
+
* value aborts the whole 500-row INSERT chunk it rides in. Clamp per
|
|
70
|
+
* value instead, so one pathological container can never drop the rest.
|
|
71
|
+
*/
|
|
72
|
+
function sanitizeContainer(c: ParsedDockerContainer): ParsedDockerContainer {
|
|
73
|
+
return {
|
|
74
|
+
...c,
|
|
75
|
+
containerName: truncateLongText(c.containerName),
|
|
76
|
+
containerId: truncateShortText(c.containerId),
|
|
77
|
+
imageName: truncateLongText(c.imageName),
|
|
78
|
+
state: truncateShortText(c.state),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function sanitizeResource(r: ParsedDockerResource): ParsedDockerResource {
|
|
83
|
+
return {
|
|
84
|
+
...r,
|
|
85
|
+
kind: truncateShortText(r.kind),
|
|
86
|
+
name: truncateLongText(r.name),
|
|
87
|
+
containerId: truncateShortText(r.containerId),
|
|
88
|
+
imageName: truncateLongText(r.imageName),
|
|
89
|
+
state: truncateShortText(r.state),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
59
93
|
export class Service extends DatabaseService<Model> {
|
|
60
94
|
public constructor() {
|
|
61
95
|
super(Model);
|
|
@@ -83,12 +117,20 @@ export class Service extends DatabaseService<Model> {
|
|
|
83
117
|
return;
|
|
84
118
|
}
|
|
85
119
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
120
|
+
const containers: Array<ParsedDockerContainer> = data.containers.map(
|
|
121
|
+
(c: ParsedDockerContainer) => {
|
|
122
|
+
const sanitized: ParsedDockerContainer = sanitizeContainer(c);
|
|
123
|
+
if (sanitized.containerName !== c.containerName) {
|
|
124
|
+
logger.warn(
|
|
125
|
+
`DockerResource container name exceeds ${ColumnLength.LongText} chars; truncated to "${sanitized.containerName}" (host ${data.dockerHostId.toString()}).`,
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
return sanitized;
|
|
129
|
+
},
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
for (let i: number = 0; i < containers.length; i += UPSERT_BATCH_SIZE) {
|
|
133
|
+
const chunk: Array<ParsedDockerContainer> = containers.slice(
|
|
92
134
|
i,
|
|
93
135
|
i + UPSERT_BATCH_SIZE,
|
|
94
136
|
);
|
|
@@ -164,8 +206,20 @@ export class Service extends DatabaseService<Model> {
|
|
|
164
206
|
return;
|
|
165
207
|
}
|
|
166
208
|
|
|
167
|
-
|
|
168
|
-
|
|
209
|
+
const resources: Array<ParsedDockerResource> = data.resources.map(
|
|
210
|
+
(r: ParsedDockerResource) => {
|
|
211
|
+
const sanitized: ParsedDockerResource = sanitizeResource(r);
|
|
212
|
+
if (sanitized.name !== r.name) {
|
|
213
|
+
logger.warn(
|
|
214
|
+
`DockerResource name exceeds ${ColumnLength.LongText} chars; truncated to "${sanitized.name}" (host ${data.dockerHostId.toString()}).`,
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
return sanitized;
|
|
218
|
+
},
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
for (let i: number = 0; i < resources.length; i += UPSERT_BATCH_SIZE) {
|
|
222
|
+
const chunk: Array<ParsedDockerResource> = resources.slice(
|
|
169
223
|
i,
|
|
170
224
|
i + UPSERT_BATCH_SIZE,
|
|
171
225
|
);
|
|
@@ -5,6 +5,7 @@ import Model from "../../Models/DatabaseModels/DockerSwarmCluster";
|
|
|
5
5
|
import Label from "../../Models/DatabaseModels/Label";
|
|
6
6
|
import { OnCreate } from "../Types/Database/Hooks";
|
|
7
7
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
8
|
+
import ResourceHeartbeat from "../Utils/Telemetry/ResourceHeartbeat";
|
|
8
9
|
import ObjectID from "../../Types/ObjectID";
|
|
9
10
|
import QueryHelper from "../Types/Database/QueryHelper";
|
|
10
11
|
import OneUptimeDate from "../../Types/Date";
|
|
@@ -182,7 +183,6 @@ export class Service extends DatabaseService<Model> {
|
|
|
182
183
|
networkCount?: number | undefined;
|
|
183
184
|
},
|
|
184
185
|
): Promise<void> {
|
|
185
|
-
const cacheKey: string = clusterId.toString();
|
|
186
186
|
const extrasFingerprint: string = crypto
|
|
187
187
|
.createHash("sha1")
|
|
188
188
|
.update(
|
|
@@ -202,83 +202,65 @@ export class Service extends DatabaseService<Model> {
|
|
|
202
202
|
)
|
|
203
203
|
.digest("hex");
|
|
204
204
|
|
|
205
|
-
let cached: string | null = null;
|
|
206
|
-
try {
|
|
207
|
-
cached = await GlobalCache.getString(LAST_SEEN_CACHE_NAMESPACE, cacheKey);
|
|
208
|
-
} catch {
|
|
209
|
-
/*
|
|
210
|
-
* Cache unavailable — fail open and refresh lastSeenAt anyway. A
|
|
211
|
-
* cache error must never skip the DB write below, otherwise the
|
|
212
|
-
* resource is wrongly marked "disconnected" while telemetry is
|
|
213
|
-
* still flowing. Mirrors shouldRunMaintenance's fail-open stance.
|
|
214
|
-
*/
|
|
215
|
-
cached = null;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
if (cached === extrasFingerprint) {
|
|
219
|
-
return; // same data was written recently
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
try {
|
|
223
|
-
await GlobalCache.setString(
|
|
224
|
-
LAST_SEEN_CACHE_NAMESPACE,
|
|
225
|
-
cacheKey,
|
|
226
|
-
extrasFingerprint,
|
|
227
|
-
{ expiresInSeconds: LAST_SEEN_THROTTLE_SECONDS },
|
|
228
|
-
);
|
|
229
|
-
} catch {
|
|
230
|
-
// Best-effort throttle write; proceed with the DB update regardless.
|
|
231
|
-
}
|
|
232
|
-
|
|
233
205
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
234
|
-
const
|
|
206
|
+
const liveness: any = {
|
|
235
207
|
lastSeenAt: OneUptimeDate.getCurrentDate(),
|
|
236
208
|
otelCollectorStatus: "connected",
|
|
237
209
|
};
|
|
238
210
|
|
|
211
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
212
|
+
const metadata: any = {};
|
|
213
|
+
|
|
239
214
|
if (extra?.dockerVersion) {
|
|
240
|
-
|
|
215
|
+
metadata.dockerVersion = extra.dockerVersion;
|
|
241
216
|
}
|
|
242
217
|
if (extra?.swarmId) {
|
|
243
|
-
|
|
218
|
+
metadata.swarmId = extra.swarmId;
|
|
244
219
|
}
|
|
245
220
|
if (extra?.agentVersion) {
|
|
246
|
-
|
|
221
|
+
metadata.agentVersion = extra.agentVersion;
|
|
247
222
|
}
|
|
248
223
|
// Counts: 0 is a legitimate value — gate on undefined, not falsiness.
|
|
249
224
|
if (extra?.nodeCount !== undefined) {
|
|
250
|
-
|
|
225
|
+
metadata.nodeCount = extra.nodeCount;
|
|
251
226
|
}
|
|
252
227
|
if (extra?.readyNodeCount !== undefined) {
|
|
253
|
-
|
|
228
|
+
metadata.readyNodeCount = extra.readyNodeCount;
|
|
254
229
|
}
|
|
255
230
|
if (extra?.managerNodeCount !== undefined) {
|
|
256
|
-
|
|
231
|
+
metadata.managerNodeCount = extra.managerNodeCount;
|
|
257
232
|
}
|
|
258
233
|
if (extra?.serviceCount !== undefined) {
|
|
259
|
-
|
|
234
|
+
metadata.serviceCount = extra.serviceCount;
|
|
260
235
|
}
|
|
261
236
|
if (extra?.taskCount !== undefined) {
|
|
262
|
-
|
|
237
|
+
metadata.taskCount = extra.taskCount;
|
|
263
238
|
}
|
|
264
239
|
if (extra?.runningTaskCount !== undefined) {
|
|
265
|
-
|
|
240
|
+
metadata.runningTaskCount = extra.runningTaskCount;
|
|
266
241
|
}
|
|
267
242
|
if (extra?.stackCount !== undefined) {
|
|
268
|
-
|
|
243
|
+
metadata.stackCount = extra.stackCount;
|
|
269
244
|
}
|
|
270
245
|
if (extra?.networkCount !== undefined) {
|
|
271
|
-
|
|
246
|
+
metadata.networkCount = extra.networkCount;
|
|
272
247
|
}
|
|
273
248
|
|
|
274
249
|
/*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
250
|
+
* One gated, non-blocking heartbeat write. The gates, the fail-open /
|
|
251
|
+
* fail-closed split and the liveness-only fallback all live in
|
|
252
|
+
* ResourceHeartbeat — see there for why this row's throttle used to
|
|
253
|
+
* provide no throttling at all.
|
|
278
254
|
*/
|
|
279
|
-
await
|
|
255
|
+
await ResourceHeartbeat.write({
|
|
256
|
+
service: this,
|
|
280
257
|
id: clusterId,
|
|
281
|
-
|
|
258
|
+
cacheNamespace: LAST_SEEN_CACHE_NAMESPACE,
|
|
259
|
+
throttleInSeconds: LAST_SEEN_THROTTLE_SECONDS,
|
|
260
|
+
liveness: liveness,
|
|
261
|
+
metadata: metadata,
|
|
262
|
+
fingerprint: extrasFingerprint,
|
|
263
|
+
describe: `docker swarm cluster ${clusterId.toString()}`,
|
|
282
264
|
});
|
|
283
265
|
}
|
|
284
266
|
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import DatabaseService from "./DatabaseService";
|
|
2
2
|
import Model from "../../Models/DatabaseModels/DockerSwarmResource";
|
|
3
3
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
4
|
+
import ColumnLength from "../../Types/Database/ColumnLength";
|
|
4
5
|
import ObjectID from "../../Types/ObjectID";
|
|
5
6
|
import OneUptimeDate from "../../Types/Date";
|
|
6
7
|
import { JSONObject } from "../../Types/JSON";
|
|
8
|
+
import {
|
|
9
|
+
truncateLongText,
|
|
10
|
+
truncateShortText,
|
|
11
|
+
} from "../Utils/Database/TruncateColumnValue";
|
|
7
12
|
import logger from "../Utils/Logger";
|
|
8
13
|
|
|
9
14
|
/*
|
|
@@ -95,6 +100,33 @@ const UPSERT_COLUMNS: Array<string> = [
|
|
|
95
100
|
"version",
|
|
96
101
|
];
|
|
97
102
|
|
|
103
|
+
/*
|
|
104
|
+
* DockerSwarmResource's text columns are bounded varchars — image at
|
|
105
|
+
* 500 chars, everything else at 100. The bulk paths below go through
|
|
106
|
+
* manager.query(), which skips the length validation DatabaseService
|
|
107
|
+
* applies to ordinary writes, so a single oversized value aborts the
|
|
108
|
+
* whole 500-row INSERT chunk it rides in. Clamp per value instead, so
|
|
109
|
+
* one pathological task can never drop the rest of the snapshot.
|
|
110
|
+
*/
|
|
111
|
+
function sanitizeResource(
|
|
112
|
+
r: ParsedDockerSwarmResource,
|
|
113
|
+
): ParsedDockerSwarmResource {
|
|
114
|
+
return {
|
|
115
|
+
...r,
|
|
116
|
+
kind: truncateShortText(r.kind),
|
|
117
|
+
externalId: truncateShortText(r.externalId),
|
|
118
|
+
name: truncateShortText(r.name),
|
|
119
|
+
state: truncateShortText(r.state),
|
|
120
|
+
role: truncateShortText(r.role),
|
|
121
|
+
serviceMode: truncateShortText(r.serviceMode),
|
|
122
|
+
image: truncateLongText(r.image),
|
|
123
|
+
stackName: truncateShortText(r.stackName),
|
|
124
|
+
serviceName: truncateShortText(r.serviceName),
|
|
125
|
+
nodeHostname: truncateShortText(r.nodeHostname),
|
|
126
|
+
driver: truncateShortText(r.driver),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
98
130
|
export class Service extends DatabaseService<Model> {
|
|
99
131
|
public constructor() {
|
|
100
132
|
super(Model);
|
|
@@ -120,8 +152,20 @@ export class Service extends DatabaseService<Model> {
|
|
|
120
152
|
return;
|
|
121
153
|
}
|
|
122
154
|
|
|
123
|
-
|
|
124
|
-
|
|
155
|
+
const resources: Array<ParsedDockerSwarmResource> = data.resources.map(
|
|
156
|
+
(r: ParsedDockerSwarmResource) => {
|
|
157
|
+
const sanitized: ParsedDockerSwarmResource = sanitizeResource(r);
|
|
158
|
+
if (sanitized.externalId !== r.externalId) {
|
|
159
|
+
logger.warn(
|
|
160
|
+
`DockerSwarmResource externalId exceeds ${ColumnLength.ShortText} chars; truncated to "${sanitized.externalId}" (cluster ${data.dockerSwarmClusterId.toString()}).`,
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
return sanitized;
|
|
164
|
+
},
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
for (let i: number = 0; i < resources.length; i += UPSERT_BATCH_SIZE) {
|
|
168
|
+
const chunk: Array<ParsedDockerSwarmResource> = resources.slice(
|
|
125
169
|
i,
|
|
126
170
|
i + UPSERT_BATCH_SIZE,
|
|
127
171
|
);
|
|
@@ -231,9 +275,14 @@ export class Service extends DatabaseService<Model> {
|
|
|
231
275
|
valueFragments.push(
|
|
232
276
|
`($${paramIndex++}, $${paramIndex++}, $${paramIndex++}::numeric, $${paramIndex++}::bigint, $${paramIndex++}::bigint, $${paramIndex++}::numeric, $${paramIndex++}::timestamptz)`,
|
|
233
277
|
);
|
|
278
|
+
/*
|
|
279
|
+
* The identity clamps MUST match bulkUpsert's, or this mirror
|
|
280
|
+
* UPDATE would silently miss the row the upsert just wrote
|
|
281
|
+
* under the truncated externalId.
|
|
282
|
+
*/
|
|
234
283
|
params.push(
|
|
235
|
-
m.kind,
|
|
236
|
-
m.externalId,
|
|
284
|
+
truncateShortText(m.kind),
|
|
285
|
+
truncateShortText(m.externalId),
|
|
237
286
|
m.cpuPercent !== null && m.cpuPercent !== undefined
|
|
238
287
|
? m.cpuPercent
|
|
239
288
|
: null,
|
|
@@ -5,6 +5,7 @@ import Model from "../../Models/DatabaseModels/Host";
|
|
|
5
5
|
import Label from "../../Models/DatabaseModels/Label";
|
|
6
6
|
import { OnCreate } from "../Types/Database/Hooks";
|
|
7
7
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
8
|
+
import ResourceHeartbeat from "../Utils/Telemetry/ResourceHeartbeat";
|
|
8
9
|
import ObjectID from "../../Types/ObjectID";
|
|
9
10
|
import QueryHelper from "../Types/Database/QueryHelper";
|
|
10
11
|
import OneUptimeDate from "../../Types/Date";
|
|
@@ -212,111 +213,93 @@ export class Service extends DatabaseService<Model> {
|
|
|
212
213
|
* once per throttle window. If any extra value changed (e.g. cpuCores
|
|
213
214
|
* updated, IP address changed), bust the cache and write immediately.
|
|
214
215
|
*/
|
|
215
|
-
const cacheKey: string = hostId.toString();
|
|
216
216
|
const extrasFingerprint: string = this.fingerprintExtras(extra);
|
|
217
|
-
let cached: string | null = null;
|
|
218
|
-
try {
|
|
219
|
-
cached = await GlobalCache.getString(LAST_SEEN_CACHE_NAMESPACE, cacheKey);
|
|
220
|
-
} catch {
|
|
221
|
-
/*
|
|
222
|
-
* Cache unavailable — fail open and refresh lastSeenAt anyway. A
|
|
223
|
-
* cache error must never skip the DB write below, otherwise the
|
|
224
|
-
* resource is wrongly marked "disconnected" while telemetry is
|
|
225
|
-
* still flowing. Mirrors shouldRunMaintenance's fail-open stance.
|
|
226
|
-
*/
|
|
227
|
-
cached = null;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
if (cached === extrasFingerprint) {
|
|
231
|
-
return; // same data was written recently
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
try {
|
|
235
|
-
await GlobalCache.setString(
|
|
236
|
-
LAST_SEEN_CACHE_NAMESPACE,
|
|
237
|
-
cacheKey,
|
|
238
|
-
extrasFingerprint,
|
|
239
|
-
{ expiresInSeconds: LAST_SEEN_THROTTLE_SECONDS },
|
|
240
|
-
);
|
|
241
|
-
} catch {
|
|
242
|
-
// Best-effort throttle write; proceed with the DB update regardless.
|
|
243
|
-
}
|
|
244
217
|
|
|
245
218
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
246
|
-
const
|
|
219
|
+
const liveness: any = {
|
|
247
220
|
lastSeenAt: OneUptimeDate.getCurrentDate(),
|
|
248
221
|
otelCollectorStatus: "connected",
|
|
249
222
|
};
|
|
250
223
|
|
|
224
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
225
|
+
const metadata: any = {};
|
|
226
|
+
|
|
251
227
|
if (extra?.osType) {
|
|
252
|
-
|
|
228
|
+
metadata.osType = extra.osType;
|
|
253
229
|
}
|
|
254
230
|
if (extra?.osVersion) {
|
|
255
|
-
|
|
231
|
+
metadata.osVersion = extra.osVersion;
|
|
256
232
|
}
|
|
257
233
|
if (extra?.hostId) {
|
|
258
|
-
|
|
234
|
+
metadata.hostId = extra.hostId;
|
|
259
235
|
}
|
|
260
236
|
if (extra?.hostArch) {
|
|
261
|
-
|
|
237
|
+
metadata.hostArch = extra.hostArch;
|
|
262
238
|
}
|
|
263
239
|
if (extra?.hostType) {
|
|
264
|
-
|
|
240
|
+
metadata.hostType = extra.hostType;
|
|
265
241
|
}
|
|
266
242
|
if (extra?.hostIpAddresses) {
|
|
267
|
-
|
|
243
|
+
metadata.hostIpAddresses = extra.hostIpAddresses;
|
|
268
244
|
}
|
|
269
245
|
if (extra?.cpuCores !== undefined) {
|
|
270
|
-
|
|
246
|
+
metadata.cpuCores = extra.cpuCores;
|
|
271
247
|
}
|
|
272
248
|
if (extra?.totalMemoryBytes !== undefined) {
|
|
273
|
-
|
|
249
|
+
metadata.totalMemoryBytes = extra.totalMemoryBytes;
|
|
274
250
|
}
|
|
275
251
|
if (extra?.processCount !== undefined) {
|
|
276
|
-
|
|
252
|
+
metadata.processCount = extra.processCount;
|
|
277
253
|
}
|
|
278
254
|
if (extra?.containerRuntime) {
|
|
279
|
-
|
|
255
|
+
metadata.containerRuntime = extra.containerRuntime;
|
|
280
256
|
}
|
|
281
257
|
if (extra?.dockerHostId) {
|
|
282
|
-
|
|
258
|
+
metadata.dockerHostId = extra.dockerHostId;
|
|
283
259
|
}
|
|
284
260
|
if (extra?.kubernetesClusterId) {
|
|
285
|
-
|
|
261
|
+
metadata.kubernetesClusterId = extra.kubernetesClusterId;
|
|
286
262
|
}
|
|
287
263
|
if (extra?.agentVersion) {
|
|
288
|
-
|
|
264
|
+
metadata.agentVersion = extra.agentVersion;
|
|
289
265
|
}
|
|
290
266
|
if (extra?.deploymentEnvironment) {
|
|
291
|
-
|
|
267
|
+
metadata.deploymentEnvironment = extra.deploymentEnvironment;
|
|
292
268
|
}
|
|
293
269
|
if (extra?.runtimeName) {
|
|
294
|
-
|
|
270
|
+
metadata.runtimeName = extra.runtimeName;
|
|
295
271
|
}
|
|
296
272
|
if (extra?.runtimeVersion) {
|
|
297
|
-
|
|
273
|
+
metadata.runtimeVersion = extra.runtimeVersion;
|
|
298
274
|
}
|
|
299
275
|
if (extra?.cloudProvider) {
|
|
300
|
-
|
|
276
|
+
metadata.cloudProvider = extra.cloudProvider;
|
|
301
277
|
}
|
|
302
278
|
if (extra?.cloudPlatform) {
|
|
303
|
-
|
|
279
|
+
metadata.cloudPlatform = extra.cloudPlatform;
|
|
304
280
|
}
|
|
305
281
|
if (extra?.cloudRegion) {
|
|
306
|
-
|
|
282
|
+
metadata.cloudRegion = extra.cloudRegion;
|
|
307
283
|
}
|
|
308
284
|
if (extra?.cloudAccountId) {
|
|
309
|
-
|
|
285
|
+
metadata.cloudAccountId = extra.cloudAccountId;
|
|
310
286
|
}
|
|
311
287
|
|
|
312
288
|
/*
|
|
313
|
-
*
|
|
314
|
-
*
|
|
315
|
-
*
|
|
289
|
+
* One gated, non-blocking heartbeat write. The gates, the fail-open /
|
|
290
|
+
* fail-closed split and the liveness-only fallback all live in
|
|
291
|
+
* ResourceHeartbeat — see there for why this row's throttle used to
|
|
292
|
+
* provide no throttling at all.
|
|
316
293
|
*/
|
|
317
|
-
await
|
|
294
|
+
await ResourceHeartbeat.write({
|
|
295
|
+
service: this,
|
|
318
296
|
id: hostId,
|
|
319
|
-
|
|
297
|
+
cacheNamespace: LAST_SEEN_CACHE_NAMESPACE,
|
|
298
|
+
throttleInSeconds: LAST_SEEN_THROTTLE_SECONDS,
|
|
299
|
+
liveness: liveness,
|
|
300
|
+
metadata: metadata,
|
|
301
|
+
fingerprint: extrasFingerprint,
|
|
302
|
+
describe: `host ${hostId.toString()}`,
|
|
320
303
|
});
|
|
321
304
|
}
|
|
322
305
|
|
|
@@ -349,9 +332,16 @@ export class Service extends DatabaseService<Model> {
|
|
|
349
332
|
hostArch: extra?.hostArch ?? null,
|
|
350
333
|
hostType: extra?.hostType ?? null,
|
|
351
334
|
hostIpAddresses: extra?.hostIpAddresses ?? null,
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
335
|
+
/*
|
|
336
|
+
* cpuCores / totalMemoryBytes / processCount are DELIBERATELY not
|
|
337
|
+
* hashed. They are per-scrape gauges, and `system.processes.count` in
|
|
338
|
+
* particular is partitioned by process.status and summed, so it changes
|
|
339
|
+
* on essentially every scrape. Hashing them made the throttle key differ
|
|
340
|
+
* every time and the 60s window never engaged — for exactly the hosts
|
|
341
|
+
* producing the most batches, which is the worst possible place to lose
|
|
342
|
+
* a throttle. The columns are still written; they simply ride along on
|
|
343
|
+
* whatever write the throttle admits rather than forcing one.
|
|
344
|
+
*/
|
|
355
345
|
containerRuntime: extra?.containerRuntime ?? null,
|
|
356
346
|
dockerHostId: extra?.dockerHostId?.toString() ?? null,
|
|
357
347
|
kubernetesClusterId: extra?.kubernetesClusterId?.toString() ?? null,
|
|
@@ -25,6 +25,7 @@ import IncidentStateTimeline from "../../Models/DatabaseModels/IncidentStateTime
|
|
|
25
25
|
import IncidentMember from "../../Models/DatabaseModels/IncidentMember";
|
|
26
26
|
import IncidentRole from "../../Models/DatabaseModels/IncidentRole";
|
|
27
27
|
import { IsBillingEnabled } from "../EnvironmentConfig";
|
|
28
|
+
import ProjectScopedReferenceValidator from "../Utils/Database/ProjectScopedReferenceValidator";
|
|
28
29
|
import logger, { LogAttributes } from "../Utils/Logger";
|
|
29
30
|
import IncidentFeedService from "./IncidentFeedService";
|
|
30
31
|
import AIIncidentPostmortemRunner from "../Utils/AI/SRE/IncidentPostmortemRunner";
|
|
@@ -128,6 +129,25 @@ export class Service extends DatabaseService<IncidentStateTimeline> {
|
|
|
128
129
|
throw new BadDataException("incidentStateId is null");
|
|
129
130
|
}
|
|
130
131
|
|
|
132
|
+
/*
|
|
133
|
+
* Same guard, same reason, as MonitorStatusTimelineService: an id that
|
|
134
|
+
* exists nowhere (or belongs to another project) used to reach Postgres
|
|
135
|
+
* and come back as a raw foreign key violation. The ordering check below
|
|
136
|
+
* does look the state up, but only when there IS a preceding row with an
|
|
137
|
+
* order, so the first timeline row for an incident went through unchecked.
|
|
138
|
+
*/
|
|
139
|
+
await ProjectScopedReferenceValidator.validateReferencesBelongToProject({
|
|
140
|
+
projectId: createBy.props.tenantId || createBy.data.projectId,
|
|
141
|
+
subject: "incident state timeline",
|
|
142
|
+
references: [
|
|
143
|
+
{
|
|
144
|
+
modelName: "Incident State",
|
|
145
|
+
id: incidentStateId,
|
|
146
|
+
service: IncidentStateService,
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
});
|
|
150
|
+
|
|
131
151
|
// Execute queries for before and after states in parallel for better performance
|
|
132
152
|
const [stateBeforeThis, stateAfterThis] = await Promise.all([
|
|
133
153
|
this.findOneBy({
|
package/Server/Services/Index.ts
CHANGED
|
@@ -177,6 +177,7 @@ import StatusPageOwnerUserService from "./StatusPageOwnerUserService";
|
|
|
177
177
|
import StatusPagePrivateUserService from "./StatusPagePrivateUserService";
|
|
178
178
|
import StatusPagePrivateUserSessionService from "./StatusPagePrivateUserSessionService";
|
|
179
179
|
import StatusPageResourceService from "./StatusPageResourceService";
|
|
180
|
+
import StatusPageMonitorRuleService from "./StatusPageMonitorRuleService";
|
|
180
181
|
// Status Page
|
|
181
182
|
import StatusPageService from "./StatusPageService";
|
|
182
183
|
import StatusPageSsoService from "./StatusPageSsoService";
|
|
@@ -438,6 +439,7 @@ const services: Array<BaseService> = [
|
|
|
438
439
|
StatusPagePrivateUserService,
|
|
439
440
|
StatusPagePrivateUserSessionService,
|
|
440
441
|
StatusPageResourceService,
|
|
442
|
+
StatusPageMonitorRuleService,
|
|
441
443
|
StatusPageService,
|
|
442
444
|
StatusPageSsoService,
|
|
443
445
|
StatusPageOidcService,
|
|
@@ -5,6 +5,7 @@ import ColumnLength from "../../Types/Database/ColumnLength";
|
|
|
5
5
|
import ObjectID from "../../Types/ObjectID";
|
|
6
6
|
import OneUptimeDate from "../../Types/Date";
|
|
7
7
|
import { clampIoTTimestamp } from "../Utils/Telemetry/IoTSnapshotScan";
|
|
8
|
+
import { truncateShortText } from "../Utils/Database/TruncateColumnValue";
|
|
8
9
|
import logger from "../Utils/Logger";
|
|
9
10
|
|
|
10
11
|
/*
|
|
@@ -59,23 +60,6 @@ export interface IoTInventorySummary {
|
|
|
59
60
|
const UPSERT_BATCH_SIZE: number = 500;
|
|
60
61
|
const STALE_DELETE_WARN_THRESHOLD: number = 100;
|
|
61
62
|
|
|
62
|
-
/*
|
|
63
|
-
* The identity/text columns are ShortText (100 chars). A single value
|
|
64
|
-
* over the column limit fails the whole multi-row INSERT chunk it rides
|
|
65
|
-
* in — truncate per value instead so one malformed device can never
|
|
66
|
-
* drop the other rows of its chunk.
|
|
67
|
-
*/
|
|
68
|
-
function truncateShortText(value: string): string;
|
|
69
|
-
function truncateShortText(value: string | null): string | null;
|
|
70
|
-
function truncateShortText(value: string | null): string | null {
|
|
71
|
-
if (value === null) {
|
|
72
|
-
return value;
|
|
73
|
-
}
|
|
74
|
-
return value.length > ColumnLength.ShortText
|
|
75
|
-
? value.substring(0, ColumnLength.ShortText)
|
|
76
|
-
: value;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
63
|
/*
|
|
80
64
|
* Column order used by bulkUpsert() and its generated parameter tuples.
|
|
81
65
|
* Keep this and the INSERT column list in perfect sync.
|
|
@@ -5,6 +5,7 @@ import Model from "../../Models/DatabaseModels/IoTFleet";
|
|
|
5
5
|
import Label from "../../Models/DatabaseModels/Label";
|
|
6
6
|
import { OnCreate } from "../Types/Database/Hooks";
|
|
7
7
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
8
|
+
import ResourceHeartbeat from "../Utils/Telemetry/ResourceHeartbeat";
|
|
8
9
|
import ObjectID from "../../Types/ObjectID";
|
|
9
10
|
import QueryHelper from "../Types/Database/QueryHelper";
|
|
10
11
|
import OneUptimeDate from "../../Types/Date";
|
|
@@ -173,7 +174,6 @@ export class Service extends DatabaseService<Model> {
|
|
|
173
174
|
onlineDeviceCount?: number | undefined;
|
|
174
175
|
},
|
|
175
176
|
): Promise<void> {
|
|
176
|
-
const cacheKey: string = fleetId.toString();
|
|
177
177
|
const extrasFingerprint: string = crypto
|
|
178
178
|
.createHash("sha1")
|
|
179
179
|
.update(
|
|
@@ -185,59 +185,41 @@ export class Service extends DatabaseService<Model> {
|
|
|
185
185
|
)
|
|
186
186
|
.digest("hex");
|
|
187
187
|
|
|
188
|
-
let cached: string | null = null;
|
|
189
|
-
try {
|
|
190
|
-
cached = await GlobalCache.getString(LAST_SEEN_CACHE_NAMESPACE, cacheKey);
|
|
191
|
-
} catch {
|
|
192
|
-
/*
|
|
193
|
-
* Cache unavailable — fail open and refresh lastSeenAt anyway. A
|
|
194
|
-
* cache error must never skip the DB write below, otherwise the
|
|
195
|
-
* resource is wrongly marked "disconnected" while telemetry is
|
|
196
|
-
* still flowing. Mirrors shouldRunMaintenance's fail-open stance.
|
|
197
|
-
*/
|
|
198
|
-
cached = null;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
if (cached === extrasFingerprint) {
|
|
202
|
-
return; // same data was written recently
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
try {
|
|
206
|
-
await GlobalCache.setString(
|
|
207
|
-
LAST_SEEN_CACHE_NAMESPACE,
|
|
208
|
-
cacheKey,
|
|
209
|
-
extrasFingerprint,
|
|
210
|
-
{ expiresInSeconds: LAST_SEEN_THROTTLE_SECONDS },
|
|
211
|
-
);
|
|
212
|
-
} catch {
|
|
213
|
-
// Best-effort throttle write; proceed with the DB update regardless.
|
|
214
|
-
}
|
|
215
|
-
|
|
216
188
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
217
|
-
const
|
|
189
|
+
const liveness: any = {
|
|
218
190
|
lastSeenAt: OneUptimeDate.getCurrentDate(),
|
|
219
191
|
otelCollectorStatus: "connected",
|
|
220
192
|
};
|
|
221
193
|
|
|
194
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
195
|
+
const metadata: any = {};
|
|
196
|
+
|
|
222
197
|
if (extra?.agentVersion) {
|
|
223
|
-
|
|
198
|
+
metadata.agentVersion = extra.agentVersion;
|
|
224
199
|
}
|
|
225
200
|
// Counts: 0 is a legitimate value — gate on undefined, not falsiness.
|
|
226
201
|
if (extra?.deviceCount !== undefined) {
|
|
227
|
-
|
|
202
|
+
metadata.deviceCount = extra.deviceCount;
|
|
228
203
|
}
|
|
229
204
|
if (extra?.onlineDeviceCount !== undefined) {
|
|
230
|
-
|
|
205
|
+
metadata.onlineDeviceCount = extra.onlineDeviceCount;
|
|
231
206
|
}
|
|
232
207
|
|
|
233
208
|
/*
|
|
234
|
-
*
|
|
235
|
-
*
|
|
236
|
-
*
|
|
209
|
+
* One gated, non-blocking heartbeat write. The gates, the fail-open /
|
|
210
|
+
* fail-closed split and the liveness-only fallback all live in
|
|
211
|
+
* ResourceHeartbeat — see there for why this row's throttle used to
|
|
212
|
+
* provide no throttling at all.
|
|
237
213
|
*/
|
|
238
|
-
await
|
|
214
|
+
await ResourceHeartbeat.write({
|
|
215
|
+
service: this,
|
|
239
216
|
id: fleetId,
|
|
240
|
-
|
|
217
|
+
cacheNamespace: LAST_SEEN_CACHE_NAMESPACE,
|
|
218
|
+
throttleInSeconds: LAST_SEEN_THROTTLE_SECONDS,
|
|
219
|
+
liveness: liveness,
|
|
220
|
+
metadata: metadata,
|
|
221
|
+
fingerprint: extrasFingerprint,
|
|
222
|
+
describe: `iot fleet ${fleetId.toString()}`,
|
|
241
223
|
});
|
|
242
224
|
}
|
|
243
225
|
|