@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.
Files changed (385) hide show
  1. package/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.ts +14 -0
  2. package/Models/DatabaseModels/Host.ts +12 -4
  3. package/Models/DatabaseModels/Index.ts +2 -0
  4. package/Models/DatabaseModels/KubernetesContainer.ts +5 -4
  5. package/Models/DatabaseModels/KubernetesResource.ts +8 -7
  6. package/Models/DatabaseModels/LogDropFilter.ts +9 -20
  7. package/Models/DatabaseModels/PodmanResource.ts +6 -6
  8. package/Models/DatabaseModels/ServiceLevelObjective.ts +91 -0
  9. package/Models/DatabaseModels/StatusPage.ts +95 -0
  10. package/Models/DatabaseModels/StatusPageMonitorRule.ts +911 -0
  11. package/Models/DatabaseModels/StatusPageResource.ts +73 -0
  12. package/Models/DatabaseModels/TraceDropFilter.ts +9 -20
  13. package/Server/API/BaseAPI.ts +13 -2
  14. package/Server/API/DashboardAPI.ts +39 -0
  15. package/Server/API/TeamMemberAPI.ts +85 -0
  16. package/Server/EnvironmentConfig.ts +31 -1
  17. package/Server/Infrastructure/GlobalCache.ts +115 -0
  18. package/Server/Infrastructure/Postgres/DataSourceOptions.ts +16 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/1785900000000-AddSloMonitorLabelRule.ts +84 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1785915638551-IncreaseHostIpAddressesLength.ts +40 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/1785930000000-WidenInventoryResourceNameColumns.ts +131 -0
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1785930709405-AddStatusPageReportPeriod.ts +25 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1786005052769-AddStatusPageMonitorRule.ts +123 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
  25. package/Server/Middleware/ProjectAuthorization.ts +66 -4
  26. package/Server/Services/AlertStateTimelineService.ts +20 -0
  27. package/Server/Services/BillingService.ts +600 -51
  28. package/Server/Services/CephClusterService.ts +27 -45
  29. package/Server/Services/CephResourceService.ts +43 -4
  30. package/Server/Services/CloudResourceService.ts +24 -42
  31. package/Server/Services/DatabaseService.ts +198 -6
  32. package/Server/Services/DockerHostService.ts +20 -38
  33. package/Server/Services/DockerResourceService.ts +62 -8
  34. package/Server/Services/DockerSwarmClusterService.ts +28 -46
  35. package/Server/Services/DockerSwarmResourceService.ts +53 -4
  36. package/Server/Services/HostService.ts +47 -57
  37. package/Server/Services/IncidentStateTimelineService.ts +20 -0
  38. package/Server/Services/Index.ts +2 -0
  39. package/Server/Services/IoTDeviceService.ts +1 -17
  40. package/Server/Services/IoTFleetService.ts +20 -38
  41. package/Server/Services/KubernetesClusterService.ts +18 -36
  42. package/Server/Services/KubernetesContainerService.ts +50 -9
  43. package/Server/Services/KubernetesResourceService.ts +53 -7
  44. package/Server/Services/LabelService.ts +153 -1
  45. package/Server/Services/MetricTypeService.ts +84 -0
  46. package/Server/Services/MonitorService.ts +146 -14
  47. package/Server/Services/MonitorStatusTimelineService.ts +29 -0
  48. package/Server/Services/MonitorTemplateService.ts +65 -0
  49. package/Server/Services/PodmanHostService.ts +20 -38
  50. package/Server/Services/PodmanResourceService.ts +62 -8
  51. package/Server/Services/ProjectService.ts +165 -35
  52. package/Server/Services/ProxmoxClusterService.ts +24 -42
  53. package/Server/Services/ProxmoxResourceService.ts +43 -4
  54. package/Server/Services/RumApplicationService.ts +20 -38
  55. package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +21 -0
  56. package/Server/Services/ServerlessFunctionService.ts +25 -43
  57. package/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.ts +426 -0
  58. package/Server/Services/ServiceLevelObjectiveService.ts +39 -0
  59. package/Server/Services/ServiceService.ts +299 -73
  60. package/Server/Services/StatusPageMonitorRuleEngineService.ts +752 -0
  61. package/Server/Services/StatusPageMonitorRuleService.ts +471 -0
  62. package/Server/Services/StatusPageService.ts +95 -36
  63. package/Server/Services/StatusPageSubscriberNotificationTemplateService.ts +18 -1
  64. package/Server/Services/StatusPageSubscriberService.ts +3 -0
  65. package/Server/Services/TelemetryEntityRelationshipService.ts +1 -0
  66. package/Server/Services/TelemetryEntityService.ts +1 -0
  67. package/Server/Types/Database/JSONColumnQuery.ts +621 -0
  68. package/Server/Types/Database/Permissions/PublicPermission.ts +9 -2
  69. package/Server/Types/Database/QueryHelper.ts +17 -32
  70. package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +170 -39
  71. package/Server/Utils/Database/TruncateColumnValue.ts +84 -0
  72. package/Server/Utils/Monitor/MonitorResource.ts +63 -36
  73. package/Server/Utils/Monitor/MonitorStatusTimeline.ts +36 -0
  74. package/Server/Utils/Monitor/MonitorStepsProjectValidator.ts +148 -127
  75. package/Server/Utils/Monitor/MonitorStepsReferenceExtractor.ts +434 -0
  76. package/Server/Utils/SingleFlight.ts +83 -0
  77. package/Server/Utils/StatusPage/MonitorRulePatternValidator.ts +46 -0
  78. package/Server/Utils/Telemetry/EntityRegistry.ts +107 -26
  79. package/Server/Utils/Telemetry/ResourceHeartbeat.ts +314 -0
  80. package/Server/Utils/Telemetry/Telemetry.ts +351 -122
  81. package/Tests/App/Dashboard/UsersTableGroupsByPerson.test.tsx +448 -0
  82. package/Tests/App/Dashboard/WidgetCatalog.test.ts +2 -0
  83. package/Tests/Models/DatabaseModels/ColumnTransformerInvariants.test.ts +306 -0
  84. package/Tests/Models/DatabaseModels/NumberColumnDeserialization.test.ts +333 -0
  85. package/Tests/Models/DatabaseModels/StatusPageMonitorRuleModel.test.ts +190 -0
  86. package/Tests/Server/API/BaseAPIApiKeyAuth.test.ts +704 -0
  87. package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +26 -0
  88. package/Tests/Server/API/TeamMemberRemoveUserFromProjectAPI.test.ts +303 -0
  89. package/Tests/Server/Infrastructure/GlobalCache.test.ts +226 -0
  90. package/Tests/Server/Infrastructure/PostgresLockTimeoutOptions.test.ts +181 -0
  91. package/Tests/Server/Middleware/MasterAdminAuthorization.test.ts +350 -0
  92. package/Tests/Server/Middleware/ProjectAuthorizationApiKeyHeader.test.ts +362 -0
  93. package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +687 -0
  94. package/Tests/Server/Services/BillingService.test.ts +78 -3
  95. package/Tests/Server/Services/BillingServiceChangePlanCancel.test.ts +645 -0
  96. package/Tests/Server/Services/BillingServiceTrialPlanChange.test.ts +1005 -0
  97. package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlocked.test.ts +342 -0
  98. package/Tests/Server/Services/DropFilterSaveValidation.test.ts +245 -0
  99. package/Tests/Server/Services/HookFreeWriteLengthClamp.test.ts +503 -0
  100. package/Tests/Server/Services/HostIpAddressesColumnWidth.test.ts +198 -0
  101. package/Tests/Server/Services/HostServiceUpdateLastSeen.test.ts +658 -0
  102. package/Tests/Server/Services/InventoryResourceNameColumnWidth.test.ts +500 -0
  103. package/Tests/Server/Services/InventoryUpsertSchemaParity.test.ts +586 -0
  104. package/Tests/Server/Services/InventoryUpsertTruncationGuard.test.ts +1242 -0
  105. package/Tests/Server/Services/MetricTypeAttachServices.test.ts +222 -0
  106. package/Tests/Server/Services/MissingReferenceWriteGuard.test.ts +614 -0
  107. package/Tests/Server/Services/MonitorStatusTimelineFastPath.test.ts +23 -0
  108. package/Tests/Server/Services/ProjectServiceChangePlan.test.ts +650 -0
  109. package/Tests/Server/Services/ProjectServiceExtendTrial.test.ts +1 -0
  110. package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +636 -0
  111. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.test.ts +770 -0
  112. package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +130 -0
  113. package/Tests/Server/Services/ServiceUpdateLastSeenSplitGates.test.ts +705 -0
  114. package/Tests/Server/Services/SloMonitorLabelRuleHooks.test.ts +352 -0
  115. package/Tests/Server/Services/StatusPageMonitorRuleEngineService.test.ts +1719 -0
  116. package/Tests/Server/Services/StatusPageMonitorRuleHooks.test.ts +1212 -0
  117. package/Tests/Server/Services/StatusPageMonitorRuleMonitorCreateHook.test.ts +228 -0
  118. package/Tests/Server/Services/StatusPageSubscriberReport.test.ts +29 -13
  119. package/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts +69 -8
  120. package/Tests/Server/Types/Database/JSONColumnQuery.test.ts +593 -0
  121. package/Tests/Server/Types/Database/Permissions/PublicPermission.test.ts +495 -0
  122. package/Tests/Server/Types/Database/QueryUtil.test.ts +113 -0
  123. package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +267 -0
  124. package/Tests/Server/Utils/Database/ProjectScopedReferenceValidator.test.ts +260 -13
  125. package/Tests/Server/Utils/Database/TruncateColumnValue.test.ts +179 -0
  126. package/Tests/Server/Utils/EntityRegistryRowFence.test.ts +302 -0
  127. package/Tests/Server/Utils/MetricTypeIndexConvergence.test.ts +598 -0
  128. package/Tests/Server/Utils/Monitor/MonitorStatusTimelineUnusableStatus.test.ts +154 -0
  129. package/Tests/Server/Utils/Monitor/MonitorStepsProjectValidator.test.ts +638 -92
  130. package/Tests/Server/Utils/Monitor/MonitorStepsReferenceExtractor.test.ts +724 -0
  131. package/Tests/Server/Utils/SingleFlight.test.ts +221 -0
  132. package/Tests/Types/Dashboard/NetworkDashboardTemplate.test.ts +793 -0
  133. package/Tests/Types/Database/BigIntColumnTransformer.test.ts +147 -0
  134. package/Tests/Types/Database/DatabasePropertyTransformer.test.ts +140 -0
  135. package/Tests/Types/Database/NumericColumnValue.test.ts +127 -0
  136. package/Tests/Types/Decimal.test.ts +37 -0
  137. package/Tests/Types/Events/Recurring.test.ts +157 -0
  138. package/Tests/Types/Monitor/SnmpVersionParsing.test.ts +152 -0
  139. package/Tests/Types/Port.test.ts +38 -0
  140. package/Tests/UI/Components/LogsHistogram.test.tsx +276 -0
  141. package/Tests/UI/Components/ModelTable/ModelTableGroupsProjectUsers.test.tsx +375 -0
  142. package/Tests/UI/Components/ModelTable/useCustomFieldColumns.test.tsx +196 -0
  143. package/Tests/UI/Components/UseLiveLogsRefresh.test.tsx +489 -0
  144. package/Tests/UI/Components/UseLogsHistogram.test.tsx +500 -0
  145. package/Tests/UI/Utils/ProjectUsersModelAPI.test.ts +739 -0
  146. package/Tests/UI/Utils/TeamMembersByUser.test.ts +633 -0
  147. package/Tests/Utils/Dashboard/Components/DashboardComponentsUtil.test.ts +120 -0
  148. package/Tests/Utils/Dashboard/DashboardNetworkMapComponent.test.ts +327 -0
  149. package/Tests/Utils/StatusPage/ReportPeriod.test.ts +218 -0
  150. package/Tests/Utils/Telemetry/HostIpAddresses.test.ts +291 -0
  151. package/Types/CustomField/CustomFieldDefinition.ts +24 -0
  152. package/Types/Dashboard/DashboardComponentType.ts +1 -0
  153. package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +1 -0
  154. package/Types/Dashboard/DashboardComponents/DashboardNetworkMapComponent.ts +40 -0
  155. package/Types/Dashboard/DashboardTemplates.ts +397 -0
  156. package/Types/Database/BigIntColumnTransformer.ts +74 -0
  157. package/Types/Database/DatabaseProperty.ts +26 -0
  158. package/Types/Database/NumericColumnValue.ts +128 -0
  159. package/Types/Date.ts +112 -0
  160. package/Types/Decimal.ts +16 -4
  161. package/Types/Events/Recurring.ts +99 -1
  162. package/Types/Permission.ts +48 -0
  163. package/Types/Port.ts +16 -4
  164. package/Types/StatusPage/StatusPageReport.ts +11 -0
  165. package/Types/StatusPage/StatusPageReportPeriodType.ts +21 -0
  166. package/UI/Components/LogsViewer/useLiveLogsRefresh.ts +86 -0
  167. package/UI/Components/LogsViewer/useLogsHistogram.ts +113 -0
  168. package/UI/Components/ModelTable/CustomFieldColumns.tsx +2 -6
  169. package/UI/Components/ModelTable/useCustomFieldColumns.ts +21 -2
  170. package/UI/Utils/ModelAPI/ProjectUsersModelAPI.ts +305 -0
  171. package/UI/Utils/TeamMembersByUser.ts +302 -0
  172. package/Utils/Dashboard/Components/DashboardNetworkMapComponent.ts +136 -0
  173. package/Utils/Dashboard/Components/Index.ts +7 -0
  174. package/Utils/StatusPage/ReportPeriod.ts +236 -0
  175. package/Utils/Telemetry/HostIpAddresses.ts +98 -0
  176. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js +12 -0
  177. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js.map +1 -1
  178. package/build/dist/Models/DatabaseModels/Host.js +12 -4
  179. package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
  180. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  181. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  182. package/build/dist/Models/DatabaseModels/KubernetesContainer.js +4 -4
  183. package/build/dist/Models/DatabaseModels/KubernetesContainer.js.map +1 -1
  184. package/build/dist/Models/DatabaseModels/KubernetesResource.js +7 -7
  185. package/build/dist/Models/DatabaseModels/KubernetesResource.js.map +1 -1
  186. package/build/dist/Models/DatabaseModels/LogDropFilter.js +9 -20
  187. package/build/dist/Models/DatabaseModels/LogDropFilter.js.map +1 -1
  188. package/build/dist/Models/DatabaseModels/PodmanResource.js +6 -6
  189. package/build/dist/Models/DatabaseModels/PodmanResource.js.map +1 -1
  190. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js +87 -0
  191. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js.map +1 -1
  192. package/build/dist/Models/DatabaseModels/StatusPage.js +98 -0
  193. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  194. package/build/dist/Models/DatabaseModels/StatusPageMonitorRule.js +925 -0
  195. package/build/dist/Models/DatabaseModels/StatusPageMonitorRule.js.map +1 -0
  196. package/build/dist/Models/DatabaseModels/StatusPageResource.js +72 -0
  197. package/build/dist/Models/DatabaseModels/StatusPageResource.js.map +1 -1
  198. package/build/dist/Models/DatabaseModels/TraceDropFilter.js +9 -20
  199. package/build/dist/Models/DatabaseModels/TraceDropFilter.js.map +1 -1
  200. package/build/dist/Server/API/BaseAPI.js +11 -1
  201. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  202. package/build/dist/Server/API/DashboardAPI.js +39 -0
  203. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  204. package/build/dist/Server/API/TeamMemberAPI.js +57 -2
  205. package/build/dist/Server/API/TeamMemberAPI.js.map +1 -1
  206. package/build/dist/Server/EnvironmentConfig.js +27 -1
  207. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  208. package/build/dist/Server/Infrastructure/GlobalCache.js +91 -0
  209. package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
  210. package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js +5 -3
  211. package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js.map +1 -1
  212. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785900000000-AddSloMonitorLabelRule.js +45 -0
  213. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785900000000-AddSloMonitorLabelRule.js.map +1 -0
  214. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785915638551-IncreaseHostIpAddressesLength.js +31 -0
  215. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785915638551-IncreaseHostIpAddressesLength.js.map +1 -0
  216. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930000000-WidenInventoryResourceNameColumns.js +90 -0
  217. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930000000-WidenInventoryResourceNameColumns.js.map +1 -0
  218. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930709405-AddStatusPageReportPeriod.js +14 -0
  219. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930709405-AddStatusPageReportPeriod.js.map +1 -0
  220. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786005052769-AddStatusPageMonitorRule.js +48 -0
  221. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786005052769-AddStatusPageMonitorRule.js.map +1 -0
  222. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
  223. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  224. package/build/dist/Server/Middleware/ProjectAuthorization.js +59 -4
  225. package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
  226. package/build/dist/Server/Services/AlertStateTimelineService.js +19 -0
  227. package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -1
  228. package/build/dist/Server/Services/BillingService.js +466 -36
  229. package/build/dist/Server/Services/BillingService.js.map +1 -1
  230. package/build/dist/Server/Services/CephClusterService.js +26 -39
  231. package/build/dist/Server/Services/CephClusterService.js.map +1 -1
  232. package/build/dist/Server/Services/CephResourceService.js +28 -3
  233. package/build/dist/Server/Services/CephResourceService.js.map +1 -1
  234. package/build/dist/Server/Services/CloudResourceService.js +23 -36
  235. package/build/dist/Server/Services/CloudResourceService.js.map +1 -1
  236. package/build/dist/Server/Services/DatabaseService.js +155 -2
  237. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  238. package/build/dist/Server/Services/DockerHostService.js +19 -32
  239. package/build/dist/Server/Services/DockerHostService.js.map +1 -1
  240. package/build/dist/Server/Services/DockerResourceService.js +34 -4
  241. package/build/dist/Server/Services/DockerResourceService.js.map +1 -1
  242. package/build/dist/Server/Services/DockerSwarmClusterService.js +27 -40
  243. package/build/dist/Server/Services/DockerSwarmClusterService.js.map +1 -1
  244. package/build/dist/Server/Services/DockerSwarmResourceService.js +28 -3
  245. package/build/dist/Server/Services/DockerSwarmResourceService.js.map +1 -1
  246. package/build/dist/Server/Services/HostService.js +58 -64
  247. package/build/dist/Server/Services/HostService.js.map +1 -1
  248. package/build/dist/Server/Services/IncidentStateTimelineService.js +19 -0
  249. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  250. package/build/dist/Server/Services/Index.js +2 -0
  251. package/build/dist/Server/Services/Index.js.map +1 -1
  252. package/build/dist/Server/Services/IoTDeviceService.js +1 -8
  253. package/build/dist/Server/Services/IoTDeviceService.js.map +1 -1
  254. package/build/dist/Server/Services/IoTFleetService.js +19 -32
  255. package/build/dist/Server/Services/IoTFleetService.js.map +1 -1
  256. package/build/dist/Server/Services/KubernetesClusterService.js +17 -30
  257. package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
  258. package/build/dist/Server/Services/KubernetesContainerService.js +29 -3
  259. package/build/dist/Server/Services/KubernetesContainerService.js.map +1 -1
  260. package/build/dist/Server/Services/KubernetesResourceService.js +32 -4
  261. package/build/dist/Server/Services/KubernetesResourceService.js.map +1 -1
  262. package/build/dist/Server/Services/LabelService.js +127 -0
  263. package/build/dist/Server/Services/LabelService.js.map +1 -1
  264. package/build/dist/Server/Services/MetricTypeService.js +74 -0
  265. package/build/dist/Server/Services/MetricTypeService.js.map +1 -1
  266. package/build/dist/Server/Services/MonitorService.js +128 -9
  267. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  268. package/build/dist/Server/Services/MonitorStatusTimelineService.js +28 -0
  269. package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
  270. package/build/dist/Server/Services/MonitorTemplateService.js +60 -0
  271. package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
  272. package/build/dist/Server/Services/PodmanHostService.js +19 -32
  273. package/build/dist/Server/Services/PodmanHostService.js.map +1 -1
  274. package/build/dist/Server/Services/PodmanResourceService.js +34 -4
  275. package/build/dist/Server/Services/PodmanResourceService.js.map +1 -1
  276. package/build/dist/Server/Services/ProjectService.js +135 -21
  277. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  278. package/build/dist/Server/Services/ProxmoxClusterService.js +23 -36
  279. package/build/dist/Server/Services/ProxmoxClusterService.js.map +1 -1
  280. package/build/dist/Server/Services/ProxmoxResourceService.js +28 -3
  281. package/build/dist/Server/Services/ProxmoxResourceService.js.map +1 -1
  282. package/build/dist/Server/Services/RumApplicationService.js +19 -32
  283. package/build/dist/Server/Services/RumApplicationService.js.map +1 -1
  284. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +20 -0
  285. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
  286. package/build/dist/Server/Services/ServerlessFunctionService.js +24 -37
  287. package/build/dist/Server/Services/ServerlessFunctionService.js.map +1 -1
  288. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js +347 -0
  289. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js.map +1 -0
  290. package/build/dist/Server/Services/ServiceLevelObjectiveService.js +33 -1
  291. package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
  292. package/build/dist/Server/Services/ServiceService.js +236 -61
  293. package/build/dist/Server/Services/ServiceService.js.map +1 -1
  294. package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js +603 -0
  295. package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js.map +1 -0
  296. package/build/dist/Server/Services/StatusPageMonitorRuleService.js +401 -0
  297. package/build/dist/Server/Services/StatusPageMonitorRuleService.js.map +1 -0
  298. package/build/dist/Server/Services/StatusPageService.js +69 -46
  299. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  300. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js +17 -1
  301. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js.map +1 -1
  302. package/build/dist/Server/Services/StatusPageSubscriberService.js +3 -0
  303. package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
  304. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js +1 -0
  305. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +1 -1
  306. package/build/dist/Server/Services/TelemetryEntityService.js +1 -0
  307. package/build/dist/Server/Services/TelemetryEntityService.js.map +1 -1
  308. package/build/dist/Server/Types/Database/JSONColumnQuery.js +402 -0
  309. package/build/dist/Server/Types/Database/JSONColumnQuery.js.map +1 -0
  310. package/build/dist/Server/Types/Database/Permissions/PublicPermission.js +9 -2
  311. package/build/dist/Server/Types/Database/Permissions/PublicPermission.js.map +1 -1
  312. package/build/dist/Server/Types/Database/QueryHelper.js +17 -27
  313. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  314. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +105 -29
  315. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
  316. package/build/dist/Server/Utils/Database/TruncateColumnValue.js +32 -0
  317. package/build/dist/Server/Utils/Database/TruncateColumnValue.js.map +1 -0
  318. package/build/dist/Server/Utils/Monitor/MonitorResource.js +56 -32
  319. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  320. package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js +30 -3
  321. package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js.map +1 -1
  322. package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js +110 -98
  323. package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js.map +1 -1
  324. package/build/dist/Server/Utils/Monitor/MonitorStepsReferenceExtractor.js +312 -0
  325. package/build/dist/Server/Utils/Monitor/MonitorStepsReferenceExtractor.js.map +1 -0
  326. package/build/dist/Server/Utils/SingleFlight.js +76 -0
  327. package/build/dist/Server/Utils/SingleFlight.js.map +1 -0
  328. package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js +29 -0
  329. package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js.map +1 -0
  330. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +78 -19
  331. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
  332. package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js +160 -0
  333. package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js.map +1 -0
  334. package/build/dist/Server/Utils/Telemetry/Telemetry.js +279 -104
  335. package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
  336. package/build/dist/Types/CustomField/CustomFieldDefinition.js +2 -0
  337. package/build/dist/Types/CustomField/CustomFieldDefinition.js.map +1 -0
  338. package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
  339. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  340. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +1 -0
  341. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
  342. package/build/dist/Types/Dashboard/DashboardComponents/DashboardNetworkMapComponent.js +2 -0
  343. package/build/dist/Types/Dashboard/DashboardComponents/DashboardNetworkMapComponent.js.map +1 -0
  344. package/build/dist/Types/Dashboard/DashboardTemplates.js +368 -0
  345. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  346. package/build/dist/Types/Database/BigIntColumnTransformer.js +66 -0
  347. package/build/dist/Types/Database/BigIntColumnTransformer.js.map +1 -0
  348. package/build/dist/Types/Database/DatabaseProperty.js +25 -0
  349. package/build/dist/Types/Database/DatabaseProperty.js.map +1 -1
  350. package/build/dist/Types/Database/NumericColumnValue.js +97 -0
  351. package/build/dist/Types/Database/NumericColumnValue.js.map +1 -0
  352. package/build/dist/Types/Date.js +68 -0
  353. package/build/dist/Types/Date.js.map +1 -1
  354. package/build/dist/Types/Decimal.js +14 -3
  355. package/build/dist/Types/Decimal.js.map +1 -1
  356. package/build/dist/Types/Events/Recurring.js +63 -0
  357. package/build/dist/Types/Events/Recurring.js.map +1 -1
  358. package/build/dist/Types/Permission.js +42 -0
  359. package/build/dist/Types/Permission.js.map +1 -1
  360. package/build/dist/Types/Port.js +15 -5
  361. package/build/dist/Types/Port.js.map +1 -1
  362. package/build/dist/Types/StatusPage/StatusPageReportPeriodType.js +22 -0
  363. package/build/dist/Types/StatusPage/StatusPageReportPeriodType.js.map +1 -0
  364. package/build/dist/UI/Components/LogsViewer/useLiveLogsRefresh.js +44 -0
  365. package/build/dist/UI/Components/LogsViewer/useLiveLogsRefresh.js.map +1 -0
  366. package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js +75 -0
  367. package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js.map +1 -0
  368. package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js.map +1 -1
  369. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +18 -2
  370. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -1
  371. package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js +213 -0
  372. package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js.map +1 -0
  373. package/build/dist/UI/Utils/TeamMembersByUser.js +195 -0
  374. package/build/dist/UI/Utils/TeamMembersByUser.js.map +1 -0
  375. package/build/dist/Utils/Dashboard/Components/DashboardNetworkMapComponent.js +114 -0
  376. package/build/dist/Utils/Dashboard/Components/DashboardNetworkMapComponent.js.map +1 -0
  377. package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
  378. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  379. package/build/dist/Utils/StatusPage/ReportPeriod.js +131 -0
  380. package/build/dist/Utils/StatusPage/ReportPeriod.js.map +1 -0
  381. package/build/dist/Utils/Telemetry/HostIpAddresses.js +82 -0
  382. package/build/dist/Utils/Telemetry/HostIpAddresses.js.map +1 -0
  383. package/jest.config.json +2 -0
  384. package/package.json +1 -1
  385. package/tsconfig.json +12 -1
@@ -14,6 +14,8 @@ import MonitorOwnerTeamService from "./MonitorOwnerTeamService";
14
14
  import MonitorOwnerUserService from "./MonitorOwnerUserService";
15
15
  import MonitorProbeService from "./MonitorProbeService";
16
16
  import MonitorStatusService from "./MonitorStatusService";
17
+ import ServiceLevelObjectiveMonitorRuleEngineService from "./ServiceLevelObjectiveMonitorRuleEngineService";
18
+ import StatusPageMonitorRuleEngineService from "./StatusPageMonitorRuleEngineService";
17
19
  import NetworkSiteService from "./NetworkSiteService";
18
20
  import MonitorStatusTimelineService, {
19
21
  MONITOR_STATUS_SAME_AS_PREVIOUS_ERROR_MESSAGE,
@@ -403,27 +405,47 @@ export class Service extends DatabaseService<Model> {
403
405
  resolveReferenceId(updateBy.data.currentMonitorStatusId) ||
404
406
  resolveReferenceId(updateBy.data.currentMonitorStatus);
405
407
 
406
- if (updateBy.data.monitorSteps || currentMonitorStatusId) {
408
+ if (updateBy.data.monitorSteps) {
407
409
  /*
408
- * Root/API updates do not always carry a tenantId, so fall back to the
409
- * project of each monitor the query actually matches.
410
+ * Validated per matched monitor rather than per distinct project, because
411
+ * the check needs that monitor's CURRENT monitorSteps: a reference id it
412
+ * already holds is exempt from the existence check, so an update never
413
+ * refuses a monitor that was stored broken before the guard existed. See
414
+ * MonitorStepsProjectValidator.
410
415
  */
416
+ const monitors: Array<Model> = await this.findBy({
417
+ query: updateBy.query,
418
+ select: {
419
+ projectId: true,
420
+ monitorSteps: true,
421
+ },
422
+ limit: LIMIT_MAX,
423
+ skip: 0,
424
+ props: {
425
+ isRoot: true,
426
+ ignoreHooks: true,
427
+ },
428
+ });
429
+
430
+ for (const monitor of monitors) {
431
+ await MonitorStepsProjectValidator.validateMonitorStepsBelongToProject({
432
+ monitorSteps: updateBy.data.monitorSteps as MonitorSteps | JSONObject,
433
+ /*
434
+ * Root/API updates do not always carry a tenantId, so fall back to
435
+ * the project of the monitor being updated.
436
+ */
437
+ projectId: updateBy.props.tenantId || monitor.projectId,
438
+ alreadyStoredMonitorSteps: monitor.monitorSteps,
439
+ });
440
+ }
441
+ }
442
+
443
+ if (currentMonitorStatusId) {
411
444
  const projectIds: Array<ObjectID> = updateBy.props.tenantId
412
445
  ? [updateBy.props.tenantId]
413
446
  : await this.getProjectIdsForUpdateQuery(updateBy);
414
447
 
415
448
  for (const projectId of projectIds) {
416
- if (updateBy.data.monitorSteps) {
417
- await MonitorStepsProjectValidator.validateMonitorStepsBelongToProject(
418
- {
419
- monitorSteps: updateBy.data.monitorSteps as
420
- | MonitorSteps
421
- | JSONObject,
422
- projectId: projectId,
423
- },
424
- );
425
- }
426
-
427
449
  await ProjectScopedReferenceValidator.validateReferencesBelongToProject(
428
450
  {
429
451
  projectId: projectId,
@@ -612,6 +634,68 @@ export class Service extends DatabaseService<Model> {
612
634
  }
613
635
  }
614
636
 
637
+ /*
638
+ * Labels decide SLO membership, so a label added or removed here can pull
639
+ * this monitor into an SLO's error budget or push it out of one. Keyed on
640
+ * `!== undefined` rather than on a non-empty array: clearing every label
641
+ * arrives as `[]`, and that is precisely the edit that should detach the
642
+ * monitor from every rule-driven SLO.
643
+ */
644
+ if (
645
+ onUpdate.updateBy.data.labels !== undefined &&
646
+ updatedItemIds.length > 0
647
+ ) {
648
+ for (const monitorId of updatedItemIds) {
649
+ try {
650
+ await ServiceLevelObjectiveMonitorRuleEngineService.syncSlosForMonitor(
651
+ {
652
+ monitorId: monitorId,
653
+ projectId: onUpdate.updateBy.props.tenantId as ObjectID,
654
+ },
655
+ );
656
+ } catch (error) {
657
+ logger.error(
658
+ "Syncing SLO label rules failed in MonitorService.onUpdateSuccess",
659
+ {
660
+ monitorId: monitorId?.toString(),
661
+ } as LogAttributes,
662
+ );
663
+ logger.error(error as Error);
664
+ }
665
+ }
666
+ }
667
+
668
+ /*
669
+ * Status page monitor rules match on labels, name and description, so an
670
+ * edit to any of the three can pull this monitor onto a status page or
671
+ * push it off one. Keyed on `!== undefined` for the same reason as the SLO
672
+ * block above: clearing every label arrives as `[]`, and that is exactly
673
+ * the edit that should detach the monitor from every label-driven rule.
674
+ */
675
+ if (
676
+ (onUpdate.updateBy.data.labels !== undefined ||
677
+ onUpdate.updateBy.data.name !== undefined ||
678
+ onUpdate.updateBy.data.description !== undefined) &&
679
+ updatedItemIds.length > 0
680
+ ) {
681
+ for (const monitorId of updatedItemIds) {
682
+ try {
683
+ await StatusPageMonitorRuleEngineService.syncRulesForMonitor({
684
+ monitorId: monitorId,
685
+ projectId: onUpdate.updateBy.props.tenantId as ObjectID,
686
+ });
687
+ } catch (error) {
688
+ logger.error(
689
+ "Syncing status page monitor rules failed in MonitorService.onUpdateSuccess",
690
+ {
691
+ monitorId: monitorId?.toString(),
692
+ } as LogAttributes,
693
+ );
694
+ logger.error(error as Error);
695
+ }
696
+ }
697
+ }
698
+
615
699
  return onUpdate;
616
700
  }
617
701
 
@@ -983,6 +1067,54 @@ ${createdItem.description?.trim() || "No description provided."}
983
1067
  }
984
1068
  return Promise.resolve();
985
1069
  })
1070
+ .then(async () => {
1071
+ /*
1072
+ * Runs after the label rules above so a monitor created with no labels
1073
+ * of its own, but given some by a MonitorLabelRule, still lands in the
1074
+ * SLOs those labels imply.
1075
+ */
1076
+ try {
1077
+ await ServiceLevelObjectiveMonitorRuleEngineService.syncSlosForMonitor(
1078
+ {
1079
+ monitorId: createdItem.id!,
1080
+ projectId: createdItem.projectId!,
1081
+ },
1082
+ );
1083
+ } catch (error) {
1084
+ logger.error(
1085
+ "Syncing SLO label rules failed in MonitorService.onCreateSuccess",
1086
+ {
1087
+ projectId: createdItem.projectId?.toString(),
1088
+ monitorId: createdItem.id?.toString(),
1089
+ } as LogAttributes,
1090
+ );
1091
+ logger.error(error as Error);
1092
+ }
1093
+ return Promise.resolve();
1094
+ })
1095
+ .then(async () => {
1096
+ /*
1097
+ * Also runs after the label rules above, so a monitor that only earns
1098
+ * its labels from a MonitorLabelRule still lands on the status pages
1099
+ * those labels imply.
1100
+ */
1101
+ try {
1102
+ await StatusPageMonitorRuleEngineService.syncRulesForMonitor({
1103
+ monitorId: createdItem.id!,
1104
+ projectId: createdItem.projectId!,
1105
+ });
1106
+ } catch (error) {
1107
+ logger.error(
1108
+ "Syncing status page monitor rules failed in MonitorService.onCreateSuccess",
1109
+ {
1110
+ projectId: createdItem.projectId?.toString(),
1111
+ monitorId: createdItem.id?.toString(),
1112
+ } as LogAttributes,
1113
+ );
1114
+ logger.error(error as Error);
1115
+ }
1116
+ return Promise.resolve();
1117
+ })
986
1118
  .then(async () => {
987
1119
  try {
988
1120
  return await this.refreshMonitorProbeStatus(createdItem.id!);
@@ -4,6 +4,7 @@ import DeleteBy from "../Types/Database/DeleteBy";
4
4
  import { OnCreate, OnDelete } from "../Types/Database/Hooks";
5
5
  import QueryHelper from "../Types/Database/QueryHelper";
6
6
  import logger, { LogAttributes } from "../Utils/Logger";
7
+ import ProjectScopedReferenceValidator from "../Utils/Database/ProjectScopedReferenceValidator";
7
8
  import DatabaseService from "./DatabaseService";
8
9
  import MonitorService from "./MonitorService";
9
10
  import UserService from "./UserService";
@@ -191,6 +192,34 @@ export class Service extends DatabaseService<MonitorStatusTimeline> {
191
192
  throw new BadDataException("monitorStatusId is null");
192
193
  }
193
194
 
195
+ /*
196
+ * Every writer of this table funnels through here, so this is the one place
197
+ * that can turn issue #3039's failure mode into an answer. A monitorStatusId
198
+ * that does not exist (or belongs to another project) used to travel all the
199
+ * way to Postgres and come back as
200
+ * insert or update on table "MonitorStatusTimeline" violates foreign key
201
+ * constraint "FK_574feb4161c5216c2c7ee0faaf8"
202
+ * — an opaque 500 over the API, and a job that fails and retries forever in
203
+ * the probe worker. Reject it here instead, naming the id.
204
+ *
205
+ * The probe/telemetry ingest callers screen the id themselves before they
206
+ * get here (Utils/Monitor/MonitorStatusTimeline and Utils/Monitor/MonitorResource)
207
+ * so a monitor whose stored criteria already point at a deleted status skip
208
+ * the status change rather than failing their whole run. This check is the
209
+ * backstop for everything else, chiefly direct API writes.
210
+ */
211
+ await ProjectScopedReferenceValidator.validateReferencesBelongToProject({
212
+ projectId: createBy.props.tenantId || createBy.data.projectId,
213
+ subject: "monitor status timeline",
214
+ references: [
215
+ {
216
+ modelName: "Monitor Status",
217
+ id: monitorStatusId,
218
+ service: MonitorStatusService,
219
+ },
220
+ ],
221
+ });
222
+
194
223
  const stateBeforeThis: MonitorStatusTimeline | null = await this.findOneBy({
195
224
  query: {
196
225
  monitorId: monitorId,
@@ -1,8 +1,14 @@
1
1
  import DatabaseService from "./DatabaseService";
2
2
  import MonitorService from "./MonitorService";
3
+ import CreateBy from "../Types/Database/CreateBy";
4
+ import UpdateBy from "../Types/Database/UpdateBy";
5
+ import { OnCreate, OnUpdate } from "../Types/Database/Hooks";
6
+ import MonitorStepsProjectValidator from "../Utils/Monitor/MonitorStepsProjectValidator";
3
7
  import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCommonInteractionProps";
4
8
  import BadDataException from "../../Types/Exception/BadDataException";
5
9
  import LIMIT_MAX from "../../Types/Database/LimitMax";
10
+ import { JSONObject } from "../../Types/JSON";
11
+ import MonitorSteps from "../../Types/Monitor/MonitorSteps";
6
12
  import ObjectID from "../../Types/ObjectID";
7
13
  import PositiveNumber from "../../Types/PositiveNumber";
8
14
  import Model from "../../Models/DatabaseModels/MonitorTemplate";
@@ -37,6 +43,65 @@ export class Service extends DatabaseService<Model> {
37
43
  super(Model);
38
44
  }
39
45
 
46
+ /*
47
+ * A template's monitorSteps embeds the same reference ids a monitor's does,
48
+ * and every one of them reaches a real monitor eventually — through "create
49
+ * monitor from template" and through syncLinkedMonitors, which pushes the
50
+ * blob onto every linked monitor. Validating it here is what makes the error
51
+ * land on the template the bad id was typed into, rather than on a monitor
52
+ * sync days later. Without this the template is the one place a dangling id
53
+ * can still enter the system.
54
+ */
55
+ @CaptureSpan()
56
+ protected override async onBeforeCreate(
57
+ createBy: CreateBy<Model>,
58
+ ): Promise<OnCreate<Model>> {
59
+ await MonitorStepsProjectValidator.validateMonitorStepsBelongToProject({
60
+ monitorSteps: createBy.data.monitorSteps,
61
+ projectId: createBy.props.tenantId || createBy.data.projectId,
62
+ });
63
+
64
+ return { createBy, carryForward: null };
65
+ }
66
+
67
+ @CaptureSpan()
68
+ protected override async onBeforeUpdate(
69
+ updateBy: UpdateBy<Model>,
70
+ ): Promise<OnUpdate<Model>> {
71
+ if (!updateBy.data.monitorSteps) {
72
+ return { updateBy, carryForward: null };
73
+ }
74
+
75
+ /*
76
+ * Per matched template, so each is checked against its own project and its
77
+ * own currently-stored ids — see MonitorService.onBeforeUpdate for why the
78
+ * stored ids matter.
79
+ */
80
+ const templates: Array<Model> = await this.findBy({
81
+ query: updateBy.query,
82
+ select: {
83
+ projectId: true,
84
+ monitorSteps: true,
85
+ },
86
+ limit: LIMIT_MAX,
87
+ skip: 0,
88
+ props: {
89
+ isRoot: true,
90
+ ignoreHooks: true,
91
+ },
92
+ });
93
+
94
+ for (const template of templates) {
95
+ await MonitorStepsProjectValidator.validateMonitorStepsBelongToProject({
96
+ monitorSteps: updateBy.data.monitorSteps as MonitorSteps | JSONObject,
97
+ projectId: updateBy.props.tenantId || template.projectId,
98
+ alreadyStoredMonitorSteps: template.monitorSteps,
99
+ });
100
+ }
101
+
102
+ return { updateBy, carryForward: null };
103
+ }
104
+
40
105
  /**
41
106
  * Count monitors created from this template.
42
107
  * Caller must already have read access on the template via the API layer.
@@ -5,6 +5,7 @@ import Model from "../../Models/DatabaseModels/PodmanHost";
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";
@@ -180,7 +181,6 @@ export class Service extends DatabaseService<Model> {
180
181
  agentVersion?: string | undefined;
181
182
  },
182
183
  ): Promise<void> {
183
- const cacheKey: string = hostId.toString();
184
184
  const extrasFingerprint: string = crypto
185
185
  .createHash("sha1")
186
186
  .update(
@@ -192,58 +192,40 @@ export class Service extends DatabaseService<Model> {
192
192
  )
193
193
  .digest("hex");
194
194
 
195
- let cached: string | null = null;
196
- try {
197
- cached = await GlobalCache.getString(LAST_SEEN_CACHE_NAMESPACE, cacheKey);
198
- } catch {
199
- /*
200
- * Cache unavailable — fail open and refresh lastSeenAt anyway. A
201
- * cache error must never skip the DB write below, otherwise the
202
- * resource is wrongly marked "disconnected" while telemetry is
203
- * still flowing. Mirrors shouldRunMaintenance's fail-open stance.
204
- */
205
- cached = null;
206
- }
207
-
208
- if (cached === extrasFingerprint) {
209
- return; // same data was written recently
210
- }
211
-
212
- try {
213
- await GlobalCache.setString(
214
- LAST_SEEN_CACHE_NAMESPACE,
215
- cacheKey,
216
- extrasFingerprint,
217
- { expiresInSeconds: LAST_SEEN_THROTTLE_SECONDS },
218
- );
219
- } catch {
220
- // Best-effort throttle write; proceed with the DB update regardless.
221
- }
222
-
223
195
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
224
- const data: any = {
196
+ const liveness: any = {
225
197
  lastSeenAt: OneUptimeDate.getCurrentDate(),
226
198
  otelCollectorStatus: "connected",
227
199
  };
228
200
 
201
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
202
+ const metadata: any = {};
203
+
229
204
  if (extra?.osType) {
230
- data.osType = extra.osType;
205
+ metadata.osType = extra.osType;
231
206
  }
232
207
  if (extra?.osVersion) {
233
- data.osVersion = extra.osVersion;
208
+ metadata.osVersion = extra.osVersion;
234
209
  }
235
210
  if (extra?.agentVersion) {
236
- data.agentVersion = extra.agentVersion;
211
+ metadata.agentVersion = extra.agentVersion;
237
212
  }
238
213
 
239
214
  /*
240
- * Heartbeat write: a single-statement UPDATE with no hooks and no
241
- * `version` bump, avoiding the hot-row Postgres lock convoy that the
242
- * full updateOneById pipeline causes. See ServiceService.updateLastSeen.
215
+ * One gated, non-blocking heartbeat write. The gates, the fail-open /
216
+ * fail-closed split and the liveness-only fallback all live in
217
+ * ResourceHeartbeat see there for why this row's throttle used to
218
+ * provide no throttling at all.
243
219
  */
244
- await this.updateColumnsByIdWithoutHooks({
220
+ await ResourceHeartbeat.write({
221
+ service: this,
245
222
  id: hostId,
246
- data: data,
223
+ cacheNamespace: LAST_SEEN_CACHE_NAMESPACE,
224
+ throttleInSeconds: LAST_SEEN_THROTTLE_SECONDS,
225
+ liveness: liveness,
226
+ metadata: metadata,
227
+ fingerprint: extrasFingerprint,
228
+ describe: `podman host ${hostId.toString()}`,
247
229
  });
248
230
  }
249
231
 
@@ -1,9 +1,14 @@
1
1
  import DatabaseService from "./DatabaseService";
2
2
  import Model from "../../Models/DatabaseModels/PodmanResource";
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 PodmanHostInventoryCounts {
56
61
  const UPSERT_BATCH_SIZE: number = 500;
57
62
  const STALE_DELETE_WARN_THRESHOLD: number = 100;
58
63
 
64
+ /*
65
+ * PodmanResource'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: ParsedPodmanContainer): ParsedPodmanContainer {
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: ParsedPodmanResource): ParsedPodmanResource {
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
- for (
87
- let i: number = 0;
88
- i < data.containers.length;
89
- i += UPSERT_BATCH_SIZE
90
- ) {
91
- const chunk: Array<ParsedPodmanContainer> = data.containers.slice(
120
+ const containers: Array<ParsedPodmanContainer> = data.containers.map(
121
+ (c: ParsedPodmanContainer) => {
122
+ const sanitized: ParsedPodmanContainer = sanitizeContainer(c);
123
+ if (sanitized.containerName !== c.containerName) {
124
+ logger.warn(
125
+ `PodmanResource container name exceeds ${ColumnLength.LongText} chars; truncated to "${sanitized.containerName}" (host ${data.podmanHostId.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<ParsedPodmanContainer> = 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
- for (let i: number = 0; i < data.resources.length; i += UPSERT_BATCH_SIZE) {
168
- const chunk: Array<ParsedPodmanResource> = data.resources.slice(
209
+ const resources: Array<ParsedPodmanResource> = data.resources.map(
210
+ (r: ParsedPodmanResource) => {
211
+ const sanitized: ParsedPodmanResource = sanitizeResource(r);
212
+ if (sanitized.name !== r.name) {
213
+ logger.warn(
214
+ `PodmanResource name exceeds ${ColumnLength.LongText} chars; truncated to "${sanitized.name}" (host ${data.podmanHostId.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<ParsedPodmanResource> = resources.slice(
169
223
  i,
170
224
  i + UPSERT_BATCH_SIZE,
171
225
  );