@oneuptime/common 12.0.33 → 13.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (877) hide show
  1. package/Models/AnalyticsModels/RumSession.ts +117 -1
  2. package/Models/AnalyticsModels/RumSessionChunk.ts +13 -0
  3. package/Models/DatabaseModels/AlertCustomField.ts +77 -3
  4. package/Models/DatabaseModels/ApiKeyPermission.ts +3 -27
  5. package/Models/DatabaseModels/GlobalConfig.ts +12 -12
  6. package/Models/DatabaseModels/IncidentCustomField.ts +77 -3
  7. package/Models/DatabaseModels/InventoryItem.ts +44 -1
  8. package/Models/DatabaseModels/InventoryItemCustomField.ts +77 -3
  9. package/Models/DatabaseModels/MonitorCustomField.ts +77 -3
  10. package/Models/DatabaseModels/NetworkDevice.ts +126 -0
  11. package/Models/DatabaseModels/OnCallDutyPolicyCustomField.ts +77 -3
  12. package/Models/DatabaseModels/RumApplication.ts +6 -6
  13. package/Models/DatabaseModels/ScheduledMaintenanceCustomField.ts +77 -3
  14. package/Models/DatabaseModels/StatusPageCustomField.ts +77 -3
  15. package/Models/DatabaseModels/TeamCustomField.ts +77 -3
  16. package/Models/DatabaseModels/TeamMember.ts +0 -9
  17. package/Models/DatabaseModels/TeamMemberCustomField.ts +77 -3
  18. package/Models/DatabaseModels/TeamPermission.ts +3 -24
  19. package/Models/DatabaseModels/TelemetryIngestionKey.ts +260 -0
  20. package/Models/DatabaseModels/UserTelegram.ts +0 -4
  21. package/Scripts/benchmark-fanin-capacity.js +181 -0
  22. package/Server/API/TelemetryAPI.ts +1284 -164
  23. package/Server/API/UserNotificationSettingAPI.ts +55 -0
  24. package/Server/API/UserTelegramAPI.ts +48 -4
  25. package/Server/EnvironmentConfig.ts +82 -18
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.ts +91 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.ts +67 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.ts +139 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.ts +121 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1791700000000-AddMacAddressToNetworkDevice.ts +25 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
  32. package/Server/Infrastructure/QueueWorker.ts +20 -14
  33. package/Server/Infrastructure/Redis.ts +8 -8
  34. package/Server/Infrastructure/Semaphore.ts +2 -0
  35. package/Server/Infrastructure/Status.ts +10 -4
  36. package/Server/Middleware/TelemetryIngest.ts +453 -7
  37. package/Server/Services/AccessTokenService.ts +1 -0
  38. package/Server/Services/AlertCustomFieldService.ts +98 -0
  39. package/Server/Services/AlertService.ts +37 -0
  40. package/Server/Services/ApiKeyPermissionService.ts +461 -29
  41. package/Server/Services/CustomFieldMappingService.ts +879 -0
  42. package/Server/Services/DatabaseService.ts +65 -13
  43. package/Server/Services/GlobalConfigService.ts +194 -0
  44. package/Server/Services/IncidentCustomFieldService.ts +98 -0
  45. package/Server/Services/IncidentService.ts +35 -0
  46. package/Server/Services/InventoryItemService.ts +31 -1
  47. package/Server/Services/MetricService.ts +194 -0
  48. package/Server/Services/MonitorService.ts +32 -0
  49. package/Server/Services/MonitorTemplateService.ts +140 -19
  50. package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +427 -66
  51. package/Server/Services/NetworkDeviceDiscoveryScanService.ts +87 -2
  52. package/Server/Services/NetworkDeviceService.ts +69 -0
  53. package/Server/Services/ProjectService.ts +22 -0
  54. package/Server/Services/RoutineEmailSettingsService.ts +73 -0
  55. package/Server/Services/RumSessionReplayViewService.ts +104 -24
  56. package/Server/Services/ScheduledMaintenanceCustomFieldService.ts +98 -0
  57. package/Server/Services/ScheduledMaintenanceService.ts +32 -0
  58. package/Server/Services/TeamMemberService.ts +78 -0
  59. package/Server/Services/TeamPermissionService.ts +235 -3
  60. package/Server/Services/TelemetryIngestionKeyService.ts +722 -19
  61. package/Server/Services/UserNotificationRuleService.ts +76 -25
  62. package/Server/Services/UserNotificationSettingService.ts +34 -6
  63. package/Server/Services/UserTelegramService.ts +326 -5
  64. package/Server/Types/Database/Permissions/ReadPermission.ts +45 -5
  65. package/Server/Types/Database/QueryHelper.ts +2 -0
  66. package/Server/Types/Database/QueryUtil.ts +56 -0
  67. package/Server/Types/Markdown.ts +93 -1
  68. package/Server/Utils/APIKey/AccessPermission.ts +5 -2
  69. package/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.ts +54 -0
  70. package/Server/Utils/CustomField/CustomFieldMappingRegistry.ts +415 -0
  71. package/Server/Utils/CustomField/CustomFieldMappingValidator.ts +335 -0
  72. package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +82 -17
  73. package/Server/Utils/DataSource/EgressGuard.ts +177 -8
  74. package/Server/Utils/EmailRollup/EmailRollupConstants.ts +38 -5
  75. package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +67 -5
  76. package/Server/Utils/EmailRollup/EmailRollupRenderer.ts +2 -2
  77. package/Server/Utils/FrontendEnvironment.ts +40 -0
  78. package/Server/Utils/LogRedaction.ts +20 -0
  79. package/Server/Utils/Logger.ts +11 -0
  80. package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +394 -86
  81. package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +30 -4
  82. package/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.ts +31 -5
  83. package/Server/Utils/Monitor/MonitorAlert.ts +29 -6
  84. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +312 -52
  85. package/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.ts +82 -9
  86. package/Server/Utils/Monitor/MonitorCriteriaMessageBuilder.ts +16 -7
  87. package/Server/Utils/Monitor/MonitorCriteriaMessageFormatter.ts +29 -17
  88. package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +107 -48
  89. package/Server/Utils/Monitor/MonitorIncident.ts +22 -6
  90. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +29 -0
  91. package/Server/Utils/Monitor/NetworkDeviceMacLearningUtil.ts +158 -0
  92. package/Server/Utils/Monitor/NetworkInventoryUtil.ts +27 -0
  93. package/Server/Utils/Monitor/SeriesContextEnricher.ts +304 -0
  94. package/Server/Utils/SSRFProtection.ts +217 -10
  95. package/Server/Utils/SessionReplay/SessionReplayGateCache.ts +239 -138
  96. package/Server/Utils/SessionReplay/SessionReplayHealthCounters.ts +305 -0
  97. package/Server/Utils/SessionReplay/SessionReplayReadService.ts +1430 -289
  98. package/Server/Utils/StartServer.ts +2 -17
  99. package/Server/Utils/TelegramVerificationToken.ts +185 -0
  100. package/Server/Utils/Telemetry/EntityRegistry.ts +11 -1
  101. package/Server/Utils/Telemetry/PinServiceName.ts +197 -0
  102. package/Server/Utils/Telemetry/TelemetryEntity.ts +83 -9
  103. package/Server/Utils/Telemetry/TelemetryFanInWriter.ts +38 -16
  104. package/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.ts +92 -0
  105. package/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.ts +217 -0
  106. package/Server/Utils/VM/VMAPI.ts +1 -0
  107. package/Server/Utils/VM/VMRunner.ts +975 -95
  108. package/Tests/App/AdminDashboard/AdminHeaderSmallScreens.test.tsx +202 -0
  109. package/Tests/App/Dashboard/AddNeighborToMonitoringModal.test.tsx +32 -0
  110. package/Tests/App/Dashboard/AdoptedDeviceDrawer.test.tsx +374 -0
  111. package/Tests/App/Dashboard/DashboardHeaderSmallScreens.test.tsx +404 -0
  112. package/Tests/App/Dashboard/DashboardLabelVariables.test.tsx +580 -0
  113. package/Tests/App/Dashboard/DashboardMonitorLabelVariable.test.tsx +438 -0
  114. package/Tests/App/Dashboard/DashboardVariableAllContract.test.tsx +5 -2
  115. package/Tests/App/Dashboard/DeviceAttachmentCard.test.tsx +273 -0
  116. package/Tests/App/Dashboard/DiscoveryReviewInventoryRefresh.test.tsx +505 -0
  117. package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +468 -0
  118. package/Tests/App/Dashboard/EntityDetailPanel.test.tsx +163 -0
  119. package/Tests/App/Dashboard/InfrastructureExplorer.test.tsx +401 -0
  120. package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +232 -0
  121. package/Tests/App/Dashboard/InventoryItems.test.tsx +201 -0
  122. package/Tests/App/Dashboard/InventoryTypeAndStatusFacets.test.tsx +798 -0
  123. package/Tests/App/Dashboard/NetworkTopologyLiveView.test.tsx +320 -0
  124. package/Tests/App/Dashboard/NetworkTopologyToolbar.test.tsx +275 -0
  125. package/Tests/App/Dashboard/OnCallCalendarFeedEmptyState.test.tsx +975 -0
  126. package/Tests/App/Dashboard/OnCallCalendarFeedPlanGate.test.tsx +63 -0
  127. package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +626 -0
  128. package/Tests/App/Dashboard/TopologyDataLoading.test.tsx +348 -0
  129. package/Tests/App/Dashboard/TopologyPageNavigation.test.tsx +331 -0
  130. package/Tests/App/Dashboard/UserSettingsEmailPreferences.test.tsx +603 -0
  131. package/Tests/App/Dashboard/UserSettingsNotificationSettings.test.tsx +324 -0
  132. package/Tests/App/PublicDashboard/DashboardVariableSelector.test.tsx +13 -4
  133. package/Tests/App/StatusPage/StatusPageLastUpdated.test.tsx +263 -0
  134. package/Tests/App/StatusPage/StatusPageOidcOrigin.test.tsx +223 -0
  135. package/Tests/App/StatusPage/StatusPageOverviewLiveAndSearch.test.tsx +753 -0
  136. package/Tests/App/StatusPage/StatusPageResourceSearchBox.test.tsx +224 -0
  137. package/Tests/Models/AnalyticsModels/RumSessionReplayColumns.test.ts +262 -0
  138. package/Tests/Models/CustomFieldMappingColumns.test.ts +166 -0
  139. package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +20 -6
  140. package/Tests/Models/InventoryItemStatus.test.ts +147 -0
  141. package/Tests/Models/NetworkDeviceMacAddressColumn.test.ts +294 -0
  142. package/Tests/ResponsiveVisibility.test.ts +115 -0
  143. package/Tests/ResponsiveVisibility.ts +183 -0
  144. package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +129 -0
  145. package/Tests/Server/API/SessionReplayAPI.test.ts +1940 -216
  146. package/Tests/Server/API/UserNotificationSettingAPI.test.ts +186 -0
  147. package/Tests/Server/API/UserTelegramAPISecurity.test.ts +231 -0
  148. package/Tests/Server/EnvironmentConfigFrontendSecurity.test.ts +234 -0
  149. package/Tests/Server/EnvironmentConfigValkey.test.ts +227 -0
  150. package/Tests/Server/Infrastructure/Postgres/AddMacAddressToNetworkDeviceMigration.test.ts +365 -0
  151. package/Tests/Server/Infrastructure/Postgres/CustomFieldValueMappingMigration.test.ts +241 -0
  152. package/Tests/Server/Infrastructure/Postgres/InventoryItemArchiveMigration.test.ts +41 -0
  153. package/Tests/Server/Infrastructure/Postgres/SessionReplayRecordEverySessionByDefaultMigration.test.ts +169 -0
  154. package/Tests/Server/Infrastructure/QueueWorkerTimeout.test.ts +210 -0
  155. package/Tests/Server/Infrastructure/TelemetryExporterDeploymentConfig.test.ts +130 -0
  156. package/Tests/Server/Infrastructure/ValkeyDeploymentConfig.test.ts +265 -0
  157. package/Tests/Server/Middleware/HttpMetricsMiddleware.test.ts +382 -0
  158. package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +4 -1
  159. package/Tests/Server/Middleware/SCIMAuthorization.test.ts +525 -0
  160. package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +1163 -0
  161. package/Tests/Server/Middleware/TelemetryIngestTokenLog.test.ts +5 -3
  162. package/Tests/Server/Services/AddTelemetryIngestionKeyTypeMigration.test.ts +555 -0
  163. package/Tests/Server/Services/ApiKeyPermissionSecurity.test.ts +678 -0
  164. package/Tests/Server/Services/ApiKeyPermissionService.test.ts +276 -28
  165. package/Tests/Server/Services/CustomFieldDropdownOptionsColumnWidth.test.ts +431 -0
  166. package/Tests/Server/Services/CustomFieldMappingService.test.ts +850 -0
  167. package/Tests/Server/Services/DatabaseServiceAggregateBy.test.ts +291 -56
  168. package/Tests/Server/Services/DatabaseServiceSortTiebreaker.test.ts +151 -0
  169. package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +32 -0
  170. package/Tests/Server/Services/GlobalConfigService.test.ts +414 -1
  171. package/Tests/Server/Services/InventoryItemManualCreate.test.ts +105 -0
  172. package/Tests/Server/Services/InventoryItemPromotionGate.test.ts +178 -0
  173. package/Tests/Server/Services/MetricRawEntityKeyPrune.test.ts +592 -0
  174. package/Tests/Server/Services/MonitorTemplateServiceCustomFieldSync.test.ts +502 -0
  175. package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +1351 -74
  176. package/Tests/Server/Services/NetworkDeviceDiscoveryScanRegistration.test.ts +520 -0
  177. package/Tests/Server/Services/NetworkDeviceMacAddressNormalization.test.ts +572 -0
  178. package/Tests/Server/Services/RoutineEmailSettingsPostgres.test.ts +329 -0
  179. package/Tests/Server/Services/RumSessionReplayViewService.test.ts +267 -0
  180. package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +9 -0
  181. package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +9 -0
  182. package/Tests/Server/Services/TeamPrivilegeEscalation.test.ts +834 -0
  183. package/Tests/Server/Services/TelemetryIngestionKeyPolicyResolution.test.ts +814 -0
  184. package/Tests/Server/Services/TelemetryIngestionKeyValidation.test.ts +998 -0
  185. package/Tests/Server/Services/UserNotificationSettingRollupRouting.test.ts +141 -0
  186. package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +18 -10
  187. package/Tests/Server/Services/UserTelegramVerificationSecurity.test.ts +688 -0
  188. package/Tests/Server/Types/Database/InventoryStatusPostgres.test.ts +368 -0
  189. package/Tests/Server/Types/Database/Permissions/ReadBlockPermission.test.ts +261 -14
  190. package/Tests/Server/Types/Database/QueryUtilIncludesAnyOfGroups.test.ts +169 -0
  191. package/Tests/Server/Types/Database/QueryUtilIncludesAnyOfGroupsPostgres.test.ts +297 -0
  192. package/Tests/Server/Types/Markdown.test.ts +194 -1
  193. package/Tests/Server/Types/Workflow/Components/IncomingWebhookUtils.test.ts +279 -0
  194. package/Tests/Server/Types/Workflow/Components/TextToJson.test.ts +212 -0
  195. package/Tests/Server/Utils/AI/SRE/Insights/FixRouting.test.ts +497 -0
  196. package/Tests/Server/Utils/AI/Toolbox/Serializer.test.ts +383 -0
  197. package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +7 -3
  198. package/Tests/Server/Utils/AnalyticsDatabase/ClusterConfig.test.ts +315 -0
  199. package/Tests/Server/Utils/CustomField/CustomFieldMappingRegistry.test.ts +436 -0
  200. package/Tests/Server/Utils/CustomField/CustomFieldMappingValidator.test.ts +437 -0
  201. package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +214 -0
  202. package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +300 -11
  203. package/Tests/Server/Utils/EmailRollup/EmailRollupBurstWindow.test.ts +83 -0
  204. package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerBehaviour.test.ts +2 -2
  205. package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerPreferences.test.ts +362 -0
  206. package/Tests/Server/Utils/EmailRollup/EmailRollupRenderer.test.ts +10 -3
  207. package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +77 -1
  208. package/Tests/Server/Utils/EventLoop.test.ts +359 -0
  209. package/Tests/Server/Utils/FrontendEnvironment.test.ts +190 -0
  210. package/Tests/Server/Utils/JsonWebToken.test.ts +30 -0
  211. package/Tests/Server/Utils/LogRedaction.test.ts +26 -0
  212. package/Tests/Server/Utils/LoggerCredentialLeak.test.ts +23 -9
  213. package/Tests/Server/Utils/Monitor/Criteria/CompareCriteria.test.ts +242 -0
  214. package/Tests/Server/Utils/Monitor/Criteria/CompareCriteriaAggregation.test.ts +590 -0
  215. package/Tests/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.test.ts +29 -0
  216. package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestHeaderCriteria.test.ts +236 -0
  217. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.ts +30 -6
  218. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaAnomalyUnits.test.ts +246 -0
  219. package/Tests/Server/Utils/Monitor/MonitorCriteriaEmailEvalLogAgreement.test.ts +280 -0
  220. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +659 -8
  221. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorMetricUnits.test.ts +570 -0
  222. package/Tests/Server/Utils/Monitor/MonitorCriteriaExpectationBuilderUnits.test.ts +30 -5
  223. package/Tests/Server/Utils/Monitor/MonitorCriteriaMessageBuilderUnits.test.ts +68 -21
  224. package/Tests/Server/Utils/Monitor/MonitorCriteriaObservationBuilderUnits.test.ts +36 -19
  225. package/Tests/Server/Utils/Monitor/MonitorTemplateUtilSeriesContext.test.ts +176 -0
  226. package/Tests/Server/Utils/Monitor/NetworkDeviceMacLearningUtil.test.ts +573 -0
  227. package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +317 -0
  228. package/Tests/Server/Utils/Monitor/SeriesContextEnricher.test.ts +356 -0
  229. package/Tests/Server/Utils/SSRFProtectionCloudServiceAddresses.test.ts +595 -0
  230. package/Tests/Server/Utils/SessionReplay/SessionReplayGateCachePolicy.test.ts +198 -1
  231. package/Tests/Server/Utils/SessionReplay/SessionReplayHealthCounters.test.ts +453 -0
  232. package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +1378 -0
  233. package/Tests/Server/Utils/SessionReplayOriginAllowListRefactor.test.ts +420 -0
  234. package/Tests/Server/Utils/TelegramVerificationToken.test.ts +253 -0
  235. package/Tests/Server/Utils/Telemetry/ContextSpanProcessor.test.ts +281 -0
  236. package/Tests/Server/Utils/Telemetry/InventoryDuplicateIdentity.test.ts +316 -0
  237. package/Tests/Server/Utils/Telemetry/PinServiceName.test.ts +666 -0
  238. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +111 -8
  239. package/Tests/Server/Utils/Telemetry/TelemetryFanInWriterCapacity.test.ts +458 -0
  240. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +424 -0
  241. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.test.ts +528 -0
  242. package/Tests/Server/Utils/TelemetryExporterEnvironment.test.ts +56 -0
  243. package/Tests/Server/Utils/VM/VMRunnerHostBridgeLatency.test.ts +74 -0
  244. package/Tests/Server/Utils/VM/VMRunnerPrivateNetworkWiring.test.ts +100 -7
  245. package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +1176 -6
  246. package/Tests/Types/CustomField/CustomFieldMappingCatalog.test.ts +220 -0
  247. package/Tests/Types/CustomField/CustomFieldValueMapping.test.ts +348 -0
  248. package/Tests/Types/Database/IncludesAnyOfGroups.test.ts +106 -0
  249. package/Tests/Types/JSONFunctions.test.ts +300 -0
  250. package/Tests/Types/Monitor/CephAlertTemplates.test.ts +422 -53
  251. package/Tests/Types/Monitor/DockerAlertTemplates.test.ts +495 -15
  252. package/Tests/Types/Monitor/DockerSwarmAlertTemplates.test.ts +191 -45
  253. package/Tests/Types/Monitor/HostAlertTemplates.test.ts +370 -42
  254. package/Tests/Types/Monitor/IotAlertTemplates.test.ts +375 -20
  255. package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +636 -42
  256. package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +189 -0
  257. package/Tests/Types/Monitor/KubernetesTemplateGroupByKeys.test.ts +95 -14
  258. package/Tests/Types/Monitor/PodmanAlertTemplates.test.ts +190 -21
  259. package/Tests/Types/Monitor/ProxmoxAlertTemplates.test.ts +352 -22
  260. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationAlertDebuggability.test.ts +363 -0
  261. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +93 -18
  262. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +259 -0
  263. package/Tests/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.test.ts +476 -0
  264. package/Tests/Types/Monitor/RumAlertTemplates.test.ts +136 -0
  265. package/Tests/Types/Monitor/SeriesContext/SeriesDebugHints.test.ts +661 -0
  266. package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +507 -0
  267. package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +270 -0
  268. package/Tests/Types/Monitor/TemplateGroupByKeys.test.ts +38 -10
  269. package/Tests/Types/Monitor/Utils/RecommendationCriteriaAssertions.ts +102 -0
  270. package/Tests/Types/NetworkAutomation/AutoImportRunMerge.test.ts +235 -0
  271. package/Tests/Types/NetworkAutomation/RuleRunResult.test.ts +66 -0
  272. package/Tests/Types/NetworkAutomation/RuleRunResultDescribe.test.ts +309 -1
  273. package/Tests/Types/NotificationSetting/RoutineEmailEvents.test.ts +47 -0
  274. package/Tests/Types/Rum/SessionReplayApiContracts.test.ts +608 -0
  275. package/Tests/Types/Rum/SessionReplayCustomEvents.test.ts +434 -0
  276. package/Tests/Types/Telemetry/InventoryLiveness.test.ts +99 -0
  277. package/Tests/Types/WebsiteRequest.test.ts +285 -3
  278. package/Tests/UI/Components/Charts/ChartBucketIdentity.test.ts +16 -3
  279. package/Tests/UI/Components/Charts/ChartTrailingBucketGap.test.ts +691 -0
  280. package/Tests/UI/Components/ComponentsModal.test.tsx +12 -4
  281. package/Tests/UI/Components/ComponentsModalUsability.test.tsx +518 -0
  282. package/Tests/UI/Components/CustomFields/CustomFieldsDetail.test.tsx +160 -0
  283. package/Tests/UI/Components/CustomFields/CustomFieldsDetailMapping.test.tsx +324 -0
  284. package/Tests/UI/Components/CustomFields/MapFromCustomFieldInput.test.tsx +176 -0
  285. package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +484 -0
  286. package/Tests/UI/Components/HeaderRightRail.test.tsx +157 -0
  287. package/Tests/UI/Components/IconDropdownItem.test.tsx +102 -0
  288. package/Tests/UI/Components/JSONTablePrototypePollution.test.tsx +117 -0
  289. package/Tests/UI/Components/KeyboardShortcutsModal.test.tsx +214 -0
  290. package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +561 -0
  291. package/Tests/UI/Components/MonitorGraphs/UptimeBarDayModal.test.tsx +302 -0
  292. package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +28 -12
  293. package/Tests/UI/Components/ShortcutDialogGuard.test.tsx +74 -0
  294. package/Tests/UI/Components/StatusPage/ResourceGroupSectionAutoExpand.test.tsx +248 -0
  295. package/Tests/UI/Components/TableCellWrapping.test.tsx +625 -0
  296. package/Tests/UI/Components/TableLoadingStates.test.tsx +205 -0
  297. package/Tests/UI/Components/Workflow/NodePlacement.test.ts +148 -0
  298. package/Tests/UI/Components/Workflow/Workflow.test.tsx +981 -0
  299. package/Tests/UI/ConfigBrowserTelemetry.test.ts +70 -0
  300. package/Tests/UI/ReactRouterSingletonBuild.test.ts +133 -0
  301. package/Tests/UI/Rum/ChunkLoader.test.ts +1036 -2
  302. package/Tests/UI/Rum/FidelityNotices.test.ts +187 -0
  303. package/Tests/UI/Rum/InactivityMap.test.ts +341 -0
  304. package/Tests/UI/Rum/PrivacySummaryCard.test.tsx +259 -0
  305. package/Tests/UI/Rum/RecordingHealthCard.test.tsx +855 -0
  306. package/Tests/UI/Rum/RecordingHealthStrip.test.tsx +594 -0
  307. package/Tests/UI/Rum/ReplayCard.test.tsx +451 -0
  308. package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +536 -0
  309. package/Tests/UI/Rum/ReplayEngine.test.ts +2503 -0
  310. package/Tests/UI/Rum/ReplayEngineTypes.test.ts +171 -0
  311. package/Tests/UI/Rum/ReplayHeader.test.tsx +719 -0
  312. package/Tests/UI/Rum/ReplayLink.test.tsx +119 -0
  313. package/Tests/UI/Rum/ReplayPinControl.test.tsx +408 -0
  314. package/Tests/UI/Rum/ReplayPlaybackIntent.test.ts +152 -0
  315. package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +514 -0
  316. package/Tests/UI/Rum/ReplayRail.test.tsx +1296 -0
  317. package/Tests/UI/Rum/ReplayRailDetail.test.tsx +900 -0
  318. package/Tests/UI/Rum/ReplayScrubber.test.tsx +763 -147
  319. package/Tests/UI/Rum/ReplaySignalTypes.test.ts +189 -0
  320. package/Tests/UI/Rum/ReplaySignals.test.ts +1579 -0
  321. package/Tests/UI/Rum/ReplayStage.test.tsx +396 -473
  322. package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +918 -0
  323. package/Tests/UI/Rum/ReplayTimeFormat.test.ts +94 -0
  324. package/Tests/UI/Rum/ReplayTimeline.test.tsx +696 -0
  325. package/Tests/UI/Rum/ReplayUi.test.tsx +559 -0
  326. package/Tests/UI/Rum/SessionReplayEmptyState.test.tsx +499 -0
  327. package/Tests/UI/Rum/SessionReplaySearchBar.test.tsx +346 -0
  328. package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +545 -0
  329. package/Tests/UI/Rum/SessionReplayTable.test.tsx +991 -0
  330. package/Tests/UI/Rum/TargetedCapturePanel.test.tsx +254 -0
  331. package/Tests/UI/Telemetry/BrowserExporterIsolation.test.ts +71 -0
  332. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +5 -0
  333. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +1 -0
  334. package/Tests/UI/Utils/GlobalKeyboardShortcut.test.ts +344 -0
  335. package/Tests/Utils/API.test.ts +308 -0
  336. package/Tests/Utils/Dashboard/Components/DashboardMonitorListComponent.test.ts +11 -1
  337. package/Tests/Utils/Dashboard/LabelVariable.test.ts +257 -0
  338. package/Tests/Utils/Dashboard/VariableUrlState.test.ts +144 -14
  339. package/Tests/Utils/HTTPResponseBodyReader.test.ts +323 -0
  340. package/Tests/Utils/MetricUnitUtil.test.ts +81 -0
  341. package/Tests/Utils/Monitor/DeviceMacLearningUtil.test.ts +497 -0
  342. package/Tests/Utils/Monitor/MetricValueFormatter.test.ts +546 -0
  343. package/Tests/Utils/Monitor/MonitorTemplateCustomFieldUtil.test.ts +218 -0
  344. package/Tests/Utils/Monitor/NetworkTopologyEndpointAdoption.test.ts +1755 -0
  345. package/Tests/Utils/NetworkAutomation/AutoImportRunChain.test.ts +320 -0
  346. package/Tests/Utils/NetworkDiscovery/DiscoveryScanStatus.test.ts +117 -0
  347. package/Tests/Utils/Rum/ChunkMath.test.ts +83 -0
  348. package/Tests/Utils/Rum/SessionReplayHealthDiagnosis.test.ts +993 -0
  349. package/Tests/Utils/Rum/SessionReplayStringMap.test.ts +245 -0
  350. package/Tests/Utils/StatusPage/ResourceSearch.test.ts +631 -0
  351. package/Tests/Utils/Telemetry/OriginAllowList.test.ts +633 -0
  352. package/Tests/Utils/Uptime/DayUptimeGraphUtil.test.ts +461 -0
  353. package/Tests/Utils/ValueFormatter.test.ts +148 -0
  354. package/Types/BaseDatabase/IncludesAnyOfGroups.ts +77 -0
  355. package/Types/CustomField/CustomFieldMappingCatalog.ts +161 -0
  356. package/Types/CustomField/CustomFieldMappingSourceResource.ts +19 -0
  357. package/Types/CustomField/CustomFieldValueMapping.ts +288 -0
  358. package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +1 -0
  359. package/Types/Dashboard/DashboardComponents/DashboardMonitorListComponent.ts +1 -0
  360. package/Types/Dashboard/DashboardVariable.ts +8 -0
  361. package/Types/Icon/IconProp.ts +1 -0
  362. package/Types/JSON.ts +4 -0
  363. package/Types/JSONFunctions.ts +205 -43
  364. package/Types/Monitor/CephAlertTemplates.ts +157 -195
  365. package/Types/Monitor/DockerAlertTemplates.ts +338 -128
  366. package/Types/Monitor/DockerSwarmAlertTemplates.ts +95 -112
  367. package/Types/Monitor/HostAlertTemplates.ts +302 -130
  368. package/Types/Monitor/IotAlertTemplates.ts +112 -104
  369. package/Types/Monitor/KubernetesAlertTemplates.ts +415 -224
  370. package/Types/Monitor/KubernetesMetricCatalog.ts +23 -19
  371. package/Types/Monitor/PodmanAlertTemplates.ts +116 -163
  372. package/Types/Monitor/ProxmoxAlertTemplates.ts +217 -99
  373. package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +98 -6
  374. package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +44 -7
  375. package/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.ts +383 -0
  376. package/Types/Monitor/RumAlertTemplates.ts +46 -7
  377. package/Types/Monitor/SeriesContext/SeriesDebugHints.ts +596 -0
  378. package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +554 -0
  379. package/Types/Monitor/ServiceAlertTemplates.ts +98 -11
  380. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +13 -0
  381. package/Types/Monitor/UptimeHistoryLabels.ts +56 -0
  382. package/Types/NetworkAutomation/RuleRunResult.ts +402 -13
  383. package/Types/NotificationSetting/RoutineEmailEvents.ts +30 -0
  384. package/Types/Rum/SessionReplay.ts +209 -0
  385. package/Types/Rum/SessionReplayApi.ts +722 -0
  386. package/Types/Rum/SessionReplayCaptureTrigger.ts +21 -12
  387. package/Types/Rum/SessionReplayConsentMode.ts +11 -7
  388. package/Types/Rum/SessionReplayCustomEvents.ts +549 -0
  389. package/Types/Rum/SessionReplayHealth.ts +238 -0
  390. package/Types/SerializableObjectDictionary.ts +4 -0
  391. package/Types/Telemetry/InventoryLiveness.ts +56 -0
  392. package/Types/Telemetry/TelemetryIngestSurface.ts +95 -0
  393. package/Types/Telemetry/TelemetryIngestionKeyPolicy.ts +75 -0
  394. package/Types/Telemetry/TelemetryIngestionKeyType.ts +29 -0
  395. package/Types/WebsiteRequest.ts +85 -3
  396. package/UI/Components/CSVFileUpload/CSVFileUpload.tsx +9 -2
  397. package/UI/Components/Charts/Area/AreaChart.tsx +13 -2
  398. package/UI/Components/Charts/Bar/BarChart.tsx +6 -2
  399. package/UI/Components/Charts/Line/LineChart.tsx +13 -2
  400. package/UI/Components/Charts/Types/XAxis/XAxis.ts +29 -0
  401. package/UI/Components/Charts/Utils/DataPoint.ts +22 -3
  402. package/UI/Components/Charts/Utils/TimeAnnotation.ts +76 -9
  403. package/UI/Components/Charts/Utils/XAxis.ts +217 -0
  404. package/UI/Components/CustomFields/CustomFieldsDetail.tsx +189 -46
  405. package/UI/Components/CustomFields/MapFromCustomFieldInput.tsx +216 -0
  406. package/UI/Components/Dashboard/DashboardVariableControl.tsx +285 -0
  407. package/UI/Components/Graphs/DayUptimeGraph.tsx +173 -8
  408. package/UI/Components/Graphs/UptimeBarTooltip.tsx +22 -278
  409. package/UI/Components/Graphs/UptimeDaySummary.tsx +327 -0
  410. package/UI/Components/Header/Header.tsx +25 -9
  411. package/UI/Components/Header/IconDropdown/IconDropdownItem.tsx +10 -1
  412. package/UI/Components/Header/IconDropdown/IconDropdownMenu.tsx +6 -1
  413. package/UI/Components/Header/ProjectPicker/ProjectPicker.tsx +6 -1
  414. package/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.tsx +6 -1
  415. package/UI/Components/Icon/Icon.tsx +11 -0
  416. package/UI/Components/JSONTable/JSONTable.tsx +2 -2
  417. package/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.tsx +125 -0
  418. package/UI/Components/KeyboardShortcut/Screenshots/README.md +19 -0
  419. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-command-palette.png +0 -0
  420. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog-dark.png +0 -0
  421. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog.png +0 -0
  422. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-help-menu.png +0 -0
  423. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-narrow.png +0 -0
  424. package/UI/Components/ModelTable/Column.ts +15 -0
  425. package/UI/Components/Monitor/SeriesDebugCommandsViewer.tsx +64 -0
  426. package/UI/Components/Monitor/SeriesLabelsViewer.tsx +93 -0
  427. package/UI/Components/MonitorGraphs/Uptime.tsx +14 -2
  428. package/UI/Components/MonitorGraphs/UptimeBarDayModal.tsx +63 -10
  429. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +44 -0
  430. package/UI/Components/StatusPage/ResourceGroupSection.tsx +40 -0
  431. package/UI/Components/Table/CellClassName.ts +81 -0
  432. package/UI/Components/Table/TableRow.tsx +20 -14
  433. package/UI/Components/Table/TableSkeletonRows.tsx +9 -9
  434. package/UI/Components/Table/Types/Column.ts +36 -0
  435. package/UI/Components/Tooltip/Tooltip.tsx +11 -1
  436. package/UI/Components/Workflow/ComponentsModal.tsx +60 -39
  437. package/UI/Components/Workflow/NodePlacement.ts +57 -0
  438. package/UI/Components/Workflow/Workflow.tsx +47 -18
  439. package/UI/Config.ts +15 -33
  440. package/UI/Utils/GlobalKeyboardShortcut.ts +208 -0
  441. package/UI/Utils/Telemetry/BrowserTelemetryConfig.ts +28 -0
  442. package/UI/Utils/Telemetry/Telemetry.ts +10 -8
  443. package/UI/esbuild-config.js +6 -0
  444. package/Utils/API.ts +129 -3
  445. package/Utils/Dashboard/Components/DashboardMonitorListComponent.ts +12 -1
  446. package/Utils/Dashboard/LabelVariable.ts +152 -0
  447. package/Utils/Dashboard/VariableUrlState.ts +27 -5
  448. package/Utils/HTTPResponseBodyReader.ts +221 -0
  449. package/Utils/MetricUnitUtil.ts +34 -0
  450. package/Utils/Monitor/DeviceMacLearningUtil.ts +177 -0
  451. package/Utils/Monitor/MetricValueFormatter.ts +342 -0
  452. package/Utils/Monitor/MonitorTemplateCustomFieldUtil.ts +124 -0
  453. package/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.ts +7 -2
  454. package/Utils/Monitor/NetworkTopologyUtil.ts +693 -0
  455. package/Utils/NetworkAutomation/AutoImportRunChain.ts +138 -0
  456. package/Utils/NetworkDiscovery/DiscoveryScanStatus.ts +77 -0
  457. package/Utils/Rum/ChunkMath.ts +106 -0
  458. package/Utils/Rum/SessionReplayHealth.ts +732 -0
  459. package/Utils/Rum/SessionReplayStringMap.ts +226 -0
  460. package/Utils/Schema/ModelSchema.ts +1 -0
  461. package/Utils/StatusPage/ResourceSearch.ts +290 -0
  462. package/Utils/Telemetry/OriginAllowList.ts +355 -0
  463. package/Utils/Uptime/DayUptimeGraphUtil.ts +205 -0
  464. package/Utils/ValueFormatter.ts +35 -1
  465. package/build/dist/Models/AnalyticsModels/RumSession.js +102 -19
  466. package/build/dist/Models/AnalyticsModels/RumSession.js.map +1 -1
  467. package/build/dist/Models/AnalyticsModels/RumSessionChunk.js +11 -9
  468. package/build/dist/Models/AnalyticsModels/RumSessionChunk.js.map +1 -1
  469. package/build/dist/Models/DatabaseModels/AlertCustomField.js +79 -3
  470. package/build/dist/Models/DatabaseModels/AlertCustomField.js.map +1 -1
  471. package/build/dist/Models/DatabaseModels/ApiKeyPermission.js +3 -27
  472. package/build/dist/Models/DatabaseModels/ApiKeyPermission.js.map +1 -1
  473. package/build/dist/Models/DatabaseModels/GlobalConfig.js +12 -12
  474. package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
  475. package/build/dist/Models/DatabaseModels/IncidentCustomField.js +79 -3
  476. package/build/dist/Models/DatabaseModels/IncidentCustomField.js.map +1 -1
  477. package/build/dist/Models/DatabaseModels/InventoryItem.js +34 -1
  478. package/build/dist/Models/DatabaseModels/InventoryItem.js.map +1 -1
  479. package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js +79 -3
  480. package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js.map +1 -1
  481. package/build/dist/Models/DatabaseModels/MonitorCustomField.js +79 -3
  482. package/build/dist/Models/DatabaseModels/MonitorCustomField.js.map +1 -1
  483. package/build/dist/Models/DatabaseModels/NetworkDevice.js +128 -0
  484. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  485. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js +79 -3
  486. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js.map +1 -1
  487. package/build/dist/Models/DatabaseModels/RumApplication.js +6 -6
  488. package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
  489. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js +79 -3
  490. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js.map +1 -1
  491. package/build/dist/Models/DatabaseModels/StatusPageCustomField.js +79 -3
  492. package/build/dist/Models/DatabaseModels/StatusPageCustomField.js.map +1 -1
  493. package/build/dist/Models/DatabaseModels/TeamCustomField.js +79 -3
  494. package/build/dist/Models/DatabaseModels/TeamCustomField.js.map +1 -1
  495. package/build/dist/Models/DatabaseModels/TeamMember.js +0 -9
  496. package/build/dist/Models/DatabaseModels/TeamMember.js.map +1 -1
  497. package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js +79 -3
  498. package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js.map +1 -1
  499. package/build/dist/Models/DatabaseModels/TeamPermission.js +3 -24
  500. package/build/dist/Models/DatabaseModels/TeamPermission.js.map +1 -1
  501. package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js +267 -0
  502. package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js.map +1 -1
  503. package/build/dist/Models/DatabaseModels/UserTelegram.js +0 -4
  504. package/build/dist/Models/DatabaseModels/UserTelegram.js.map +1 -1
  505. package/build/dist/Server/API/TelemetryAPI.js +769 -109
  506. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  507. package/build/dist/Server/API/UserNotificationSettingAPI.js +35 -0
  508. package/build/dist/Server/API/UserNotificationSettingAPI.js.map +1 -0
  509. package/build/dist/Server/API/UserTelegramAPI.js +28 -6
  510. package/build/dist/Server/API/UserTelegramAPI.js.map +1 -1
  511. package/build/dist/Server/EnvironmentConfig.js +73 -14
  512. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  513. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js +60 -0
  514. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js.map +1 -0
  515. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js +53 -0
  516. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js.map +1 -0
  517. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js +82 -0
  518. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js.map +1 -0
  519. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js +46 -0
  520. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js.map +1 -0
  521. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791700000000-AddMacAddressToNetworkDevice.js +14 -0
  522. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791700000000-AddMacAddressToNetworkDevice.js.map +1 -0
  523. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
  524. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  525. package/build/dist/Server/Infrastructure/QueueWorker.js +19 -7
  526. package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
  527. package/build/dist/Server/Infrastructure/Redis.js +8 -8
  528. package/build/dist/Server/Infrastructure/Redis.js.map +1 -1
  529. package/build/dist/Server/Infrastructure/Semaphore.js +1 -0
  530. package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
  531. package/build/dist/Server/Infrastructure/Status.js +10 -4
  532. package/build/dist/Server/Infrastructure/Status.js.map +1 -1
  533. package/build/dist/Server/Middleware/TelemetryIngest.js +315 -8
  534. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  535. package/build/dist/Server/Services/AccessTokenService.js +1 -0
  536. package/build/dist/Server/Services/AccessTokenService.js.map +1 -1
  537. package/build/dist/Server/Services/AlertCustomFieldService.js +93 -0
  538. package/build/dist/Server/Services/AlertCustomFieldService.js.map +1 -1
  539. package/build/dist/Server/Services/AlertService.js +34 -0
  540. package/build/dist/Server/Services/AlertService.js.map +1 -1
  541. package/build/dist/Server/Services/ApiKeyPermissionService.js +331 -28
  542. package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
  543. package/build/dist/Server/Services/CustomFieldMappingService.js +614 -0
  544. package/build/dist/Server/Services/CustomFieldMappingService.js.map +1 -0
  545. package/build/dist/Server/Services/DatabaseService.js +58 -13
  546. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  547. package/build/dist/Server/Services/GlobalConfigService.js +133 -0
  548. package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
  549. package/build/dist/Server/Services/IncidentCustomFieldService.js +93 -0
  550. package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
  551. package/build/dist/Server/Services/IncidentService.js +32 -0
  552. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  553. package/build/dist/Server/Services/InventoryItemService.js +28 -1
  554. package/build/dist/Server/Services/InventoryItemService.js.map +1 -1
  555. package/build/dist/Server/Services/MetricService.js +163 -0
  556. package/build/dist/Server/Services/MetricService.js.map +1 -1
  557. package/build/dist/Server/Services/MonitorService.js +29 -0
  558. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  559. package/build/dist/Server/Services/MonitorTemplateService.js +116 -17
  560. package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
  561. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +349 -64
  562. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
  563. package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js +65 -0
  564. package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js.map +1 -1
  565. package/build/dist/Server/Services/NetworkDeviceService.js +54 -0
  566. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  567. package/build/dist/Server/Services/ProjectService.js +22 -0
  568. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  569. package/build/dist/Server/Services/RoutineEmailSettingsService.js +69 -0
  570. package/build/dist/Server/Services/RoutineEmailSettingsService.js.map +1 -0
  571. package/build/dist/Server/Services/RumSessionReplayViewService.js +86 -24
  572. package/build/dist/Server/Services/RumSessionReplayViewService.js.map +1 -1
  573. package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js +93 -0
  574. package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js.map +1 -1
  575. package/build/dist/Server/Services/ScheduledMaintenanceService.js +29 -0
  576. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  577. package/build/dist/Server/Services/TeamMemberService.js +62 -2
  578. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  579. package/build/dist/Server/Services/TeamPermissionService.js +166 -3
  580. package/build/dist/Server/Services/TeamPermissionService.js.map +1 -1
  581. package/build/dist/Server/Services/TelemetryIngestionKeyService.js +562 -18
  582. package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
  583. package/build/dist/Server/Services/UserNotificationRuleService.js +60 -25
  584. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  585. package/build/dist/Server/Services/UserNotificationSettingService.js +26 -6
  586. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  587. package/build/dist/Server/Services/UserTelegramService.js +257 -4
  588. package/build/dist/Server/Services/UserTelegramService.js.map +1 -1
  589. package/build/dist/Server/Types/Database/Permissions/ReadPermission.js +29 -4
  590. package/build/dist/Server/Types/Database/Permissions/ReadPermission.js.map +1 -1
  591. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  592. package/build/dist/Server/Types/Database/QueryUtil.js +36 -0
  593. package/build/dist/Server/Types/Database/QueryUtil.js.map +1 -1
  594. package/build/dist/Server/Types/Markdown.js +75 -0
  595. package/build/dist/Server/Types/Markdown.js.map +1 -1
  596. package/build/dist/Server/Utils/APIKey/AccessPermission.js +2 -2
  597. package/build/dist/Server/Utils/APIKey/AccessPermission.js.map +1 -1
  598. package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js +27 -0
  599. package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js.map +1 -0
  600. package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js +226 -0
  601. package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js.map +1 -0
  602. package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js +189 -0
  603. package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js.map +1 -0
  604. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +53 -18
  605. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -1
  606. package/build/dist/Server/Utils/DataSource/EgressGuard.js +121 -7
  607. package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
  608. package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js +38 -5
  609. package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js.map +1 -1
  610. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +54 -3
  611. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -1
  612. package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js +2 -2
  613. package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js.map +1 -1
  614. package/build/dist/Server/Utils/FrontendEnvironment.js +33 -0
  615. package/build/dist/Server/Utils/FrontendEnvironment.js.map +1 -0
  616. package/build/dist/Server/Utils/LogRedaction.js +20 -0
  617. package/build/dist/Server/Utils/LogRedaction.js.map +1 -1
  618. package/build/dist/Server/Utils/Logger.js +10 -0
  619. package/build/dist/Server/Utils/Logger.js.map +1 -1
  620. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +323 -81
  621. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
  622. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +20 -4
  623. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
  624. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js +29 -5
  625. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js.map +1 -1
  626. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +29 -6
  627. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  628. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +254 -48
  629. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  630. package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js +58 -9
  631. package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js.map +1 -1
  632. package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageBuilder.js +9 -3
  633. package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageBuilder.js.map +1 -1
  634. package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageFormatter.js +26 -12
  635. package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageFormatter.js.map +1 -1
  636. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +74 -33
  637. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
  638. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +22 -6
  639. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  640. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +22 -0
  641. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  642. package/build/dist/Server/Utils/Monitor/NetworkDeviceMacLearningUtil.js +114 -0
  643. package/build/dist/Server/Utils/Monitor/NetworkDeviceMacLearningUtil.js.map +1 -0
  644. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +25 -0
  645. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
  646. package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js +237 -0
  647. package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js.map +1 -0
  648. package/build/dist/Server/Utils/SSRFProtection.js +136 -9
  649. package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
  650. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js +174 -89
  651. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js.map +1 -1
  652. package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js +223 -0
  653. package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js.map +1 -0
  654. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +945 -164
  655. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
  656. package/build/dist/Server/Utils/StartServer.js +3 -14
  657. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  658. package/build/dist/Server/Utils/TelegramVerificationToken.js +129 -0
  659. package/build/dist/Server/Utils/TelegramVerificationToken.js.map +1 -0
  660. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +9 -1
  661. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
  662. package/build/dist/Server/Utils/Telemetry/PinServiceName.js +163 -0
  663. package/build/dist/Server/Utils/Telemetry/PinServiceName.js.map +1 -0
  664. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +70 -13
  665. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
  666. package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js +28 -15
  667. package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js.map +1 -1
  668. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js +64 -0
  669. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js.map +1 -0
  670. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js +171 -0
  671. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js.map +1 -0
  672. package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
  673. package/build/dist/Server/Utils/VM/VMRunner.js +780 -69
  674. package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
  675. package/build/dist/Types/BaseDatabase/IncludesAnyOfGroups.js +54 -0
  676. package/build/dist/Types/BaseDatabase/IncludesAnyOfGroups.js.map +1 -0
  677. package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js +60 -0
  678. package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js.map +1 -0
  679. package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js +20 -0
  680. package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js.map +1 -0
  681. package/build/dist/Types/CustomField/CustomFieldValueMapping.js +141 -0
  682. package/build/dist/Types/CustomField/CustomFieldValueMapping.js.map +1 -0
  683. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +1 -0
  684. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
  685. package/build/dist/Types/Dashboard/DashboardVariable.js +1 -0
  686. package/build/dist/Types/Dashboard/DashboardVariable.js.map +1 -1
  687. package/build/dist/Types/Icon/IconProp.js +1 -0
  688. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  689. package/build/dist/Types/JSON.js +1 -0
  690. package/build/dist/Types/JSON.js.map +1 -1
  691. package/build/dist/Types/JSONFunctions.js +131 -37
  692. package/build/dist/Types/JSONFunctions.js.map +1 -1
  693. package/build/dist/Types/Monitor/CephAlertTemplates.js +130 -171
  694. package/build/dist/Types/Monitor/CephAlertTemplates.js.map +1 -1
  695. package/build/dist/Types/Monitor/DockerAlertTemplates.js +286 -121
  696. package/build/dist/Types/Monitor/DockerAlertTemplates.js.map +1 -1
  697. package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js +84 -105
  698. package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js.map +1 -1
  699. package/build/dist/Types/Monitor/HostAlertTemplates.js +250 -122
  700. package/build/dist/Types/Monitor/HostAlertTemplates.js.map +1 -1
  701. package/build/dist/Types/Monitor/IotAlertTemplates.js +81 -81
  702. package/build/dist/Types/Monitor/IotAlertTemplates.js.map +1 -1
  703. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +375 -215
  704. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
  705. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js +19 -19
  706. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js.map +1 -1
  707. package/build/dist/Types/Monitor/PodmanAlertTemplates.js +104 -153
  708. package/build/dist/Types/Monitor/PodmanAlertTemplates.js.map +1 -1
  709. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +156 -91
  710. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
  711. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +67 -6
  712. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -1
  713. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +38 -7
  714. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
  715. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js +261 -0
  716. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js.map +1 -0
  717. package/build/dist/Types/Monitor/RumAlertTemplates.js +46 -7
  718. package/build/dist/Types/Monitor/RumAlertTemplates.js.map +1 -1
  719. package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js +422 -0
  720. package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js.map +1 -0
  721. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +441 -0
  722. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -0
  723. package/build/dist/Types/Monitor/ServiceAlertTemplates.js +79 -15
  724. package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -1
  725. package/build/dist/Types/Monitor/UptimeHistoryLabels.js +17 -0
  726. package/build/dist/Types/Monitor/UptimeHistoryLabels.js.map +1 -0
  727. package/build/dist/Types/NetworkAutomation/RuleRunResult.js +291 -6
  728. package/build/dist/Types/NetworkAutomation/RuleRunResult.js.map +1 -1
  729. package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js +29 -0
  730. package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js.map +1 -0
  731. package/build/dist/Types/Rum/SessionReplay.js +117 -0
  732. package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
  733. package/build/dist/Types/Rum/SessionReplayApi.js +181 -0
  734. package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -0
  735. package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js +21 -12
  736. package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js.map +1 -1
  737. package/build/dist/Types/Rum/SessionReplayConsentMode.js +11 -7
  738. package/build/dist/Types/Rum/SessionReplayConsentMode.js.map +1 -1
  739. package/build/dist/Types/Rum/SessionReplayCustomEvents.js +172 -0
  740. package/build/dist/Types/Rum/SessionReplayCustomEvents.js.map +1 -0
  741. package/build/dist/Types/Rum/SessionReplayHealth.js +37 -0
  742. package/build/dist/Types/Rum/SessionReplayHealth.js.map +1 -0
  743. package/build/dist/Types/SerializableObjectDictionary.js +4 -0
  744. package/build/dist/Types/SerializableObjectDictionary.js.map +1 -1
  745. package/build/dist/Types/Telemetry/InventoryLiveness.js +37 -0
  746. package/build/dist/Types/Telemetry/InventoryLiveness.js.map +1 -0
  747. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +85 -0
  748. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -0
  749. package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js +15 -0
  750. package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js.map +1 -0
  751. package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js +30 -0
  752. package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js.map +1 -0
  753. package/build/dist/Types/WebsiteRequest.js +55 -3
  754. package/build/dist/Types/WebsiteRequest.js.map +1 -1
  755. package/build/dist/UI/Components/CSVFileUpload/CSVFileUpload.js +7 -0
  756. package/build/dist/UI/Components/CSVFileUpload/CSVFileUpload.js.map +1 -1
  757. package/build/dist/UI/Components/Charts/Area/AreaChart.js +13 -2
  758. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  759. package/build/dist/UI/Components/Charts/Bar/BarChart.js +6 -2
  760. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  761. package/build/dist/UI/Components/Charts/Line/LineChart.js +13 -2
  762. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  763. package/build/dist/UI/Components/Charts/Types/XAxis/XAxis.js.map +1 -1
  764. package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -3
  765. package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
  766. package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js +40 -9
  767. package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js.map +1 -1
  768. package/build/dist/UI/Components/Charts/Utils/XAxis.js +186 -0
  769. package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
  770. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +89 -8
  771. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
  772. package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js +118 -0
  773. package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js.map +1 -0
  774. package/build/dist/UI/Components/Dashboard/DashboardVariableControl.js +137 -0
  775. package/build/dist/UI/Components/Dashboard/DashboardVariableControl.js.map +1 -0
  776. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +112 -7
  777. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
  778. package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js +5 -162
  779. package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js.map +1 -1
  780. package/build/dist/UI/Components/Graphs/UptimeDaySummary.js +181 -0
  781. package/build/dist/UI/Components/Graphs/UptimeDaySummary.js.map +1 -0
  782. package/build/dist/UI/Components/Header/Header.js +2 -3
  783. package/build/dist/UI/Components/Header/Header.js.map +1 -1
  784. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js +2 -1
  785. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js.map +1 -1
  786. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js +7 -1
  787. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js.map +1 -1
  788. package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js +7 -1
  789. package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js.map +1 -1
  790. package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js +7 -1
  791. package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js.map +1 -1
  792. package/build/dist/UI/Components/Icon/Icon.js +5 -0
  793. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  794. package/build/dist/UI/Components/JSONTable/JSONTable.js +2 -2
  795. package/build/dist/UI/Components/JSONTable/JSONTable.js.map +1 -1
  796. package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js +35 -0
  797. package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js.map +1 -0
  798. package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js +34 -0
  799. package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js.map +1 -0
  800. package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js +49 -0
  801. package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js.map +1 -0
  802. package/build/dist/UI/Components/MonitorGraphs/Uptime.js +1 -1
  803. package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
  804. package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js +32 -6
  805. package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js.map +1 -1
  806. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +38 -0
  807. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
  808. package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js +22 -1
  809. package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js.map +1 -1
  810. package/build/dist/UI/Components/Table/CellClassName.js +55 -0
  811. package/build/dist/UI/Components/Table/CellClassName.js.map +1 -0
  812. package/build/dist/UI/Components/Table/TableRow.js +16 -13
  813. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  814. package/build/dist/UI/Components/Table/TableSkeletonRows.js +9 -8
  815. package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -1
  816. package/build/dist/UI/Components/Tooltip/Tooltip.js +25 -1
  817. package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
  818. package/build/dist/UI/Components/Workflow/ComponentsModal.js +47 -30
  819. package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
  820. package/build/dist/UI/Components/Workflow/NodePlacement.js +37 -0
  821. package/build/dist/UI/Components/Workflow/NodePlacement.js.map +1 -0
  822. package/build/dist/UI/Components/Workflow/Workflow.js +35 -18
  823. package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
  824. package/build/dist/UI/Config.js +10 -20
  825. package/build/dist/UI/Config.js.map +1 -1
  826. package/build/dist/UI/Utils/GlobalKeyboardShortcut.js +138 -0
  827. package/build/dist/UI/Utils/GlobalKeyboardShortcut.js.map +1 -0
  828. package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js +14 -0
  829. package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js.map +1 -0
  830. package/build/dist/UI/Utils/Telemetry/Telemetry.js +7 -5
  831. package/build/dist/UI/Utils/Telemetry/Telemetry.js.map +1 -1
  832. package/build/dist/Utils/API.js +67 -5
  833. package/build/dist/Utils/API.js.map +1 -1
  834. package/build/dist/Utils/Dashboard/Components/DashboardMonitorListComponent.js +9 -1
  835. package/build/dist/Utils/Dashboard/Components/DashboardMonitorListComponent.js.map +1 -1
  836. package/build/dist/Utils/Dashboard/LabelVariable.js +96 -0
  837. package/build/dist/Utils/Dashboard/LabelVariable.js.map +1 -0
  838. package/build/dist/Utils/Dashboard/VariableUrlState.js +19 -4
  839. package/build/dist/Utils/Dashboard/VariableUrlState.js.map +1 -1
  840. package/build/dist/Utils/HTTPResponseBodyReader.js +157 -0
  841. package/build/dist/Utils/HTTPResponseBodyReader.js.map +1 -0
  842. package/build/dist/Utils/MetricUnitUtil.js +26 -0
  843. package/build/dist/Utils/MetricUnitUtil.js.map +1 -1
  844. package/build/dist/Utils/Monitor/DeviceMacLearningUtil.js +112 -0
  845. package/build/dist/Utils/Monitor/DeviceMacLearningUtil.js.map +1 -0
  846. package/build/dist/Utils/Monitor/MetricValueFormatter.js +276 -0
  847. package/build/dist/Utils/Monitor/MetricValueFormatter.js.map +1 -0
  848. package/build/dist/Utils/Monitor/MonitorTemplateCustomFieldUtil.js +101 -0
  849. package/build/dist/Utils/Monitor/MonitorTemplateCustomFieldUtil.js.map +1 -0
  850. package/build/dist/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.js +7 -2
  851. package/build/dist/Utils/Monitor/NetworkDeviceMonitorTemplateUtil.js.map +1 -1
  852. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +484 -0
  853. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  854. package/build/dist/Utils/NetworkAutomation/AutoImportRunChain.js +59 -0
  855. package/build/dist/Utils/NetworkAutomation/AutoImportRunChain.js.map +1 -0
  856. package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js +69 -0
  857. package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js.map +1 -0
  858. package/build/dist/Utils/Rum/ChunkMath.js +76 -0
  859. package/build/dist/Utils/Rum/ChunkMath.js.map +1 -1
  860. package/build/dist/Utils/Rum/SessionReplayHealth.js +534 -0
  861. package/build/dist/Utils/Rum/SessionReplayHealth.js.map +1 -0
  862. package/build/dist/Utils/Rum/SessionReplayStringMap.js +165 -0
  863. package/build/dist/Utils/Rum/SessionReplayStringMap.js.map +1 -0
  864. package/build/dist/Utils/Schema/ModelSchema.js +1 -0
  865. package/build/dist/Utils/Schema/ModelSchema.js.map +1 -1
  866. package/build/dist/Utils/StatusPage/ResourceSearch.js +200 -0
  867. package/build/dist/Utils/StatusPage/ResourceSearch.js.map +1 -0
  868. package/build/dist/Utils/Telemetry/OriginAllowList.js +299 -0
  869. package/build/dist/Utils/Telemetry/OriginAllowList.js.map +1 -0
  870. package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js +147 -0
  871. package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js.map +1 -0
  872. package/build/dist/Utils/ValueFormatter.js +32 -1
  873. package/build/dist/Utils/ValueFormatter.js.map +1 -1
  874. package/jest.config.json +2 -0
  875. package/package.json +1 -1
  876. package/test-setup.sh +9 -9
  877. package/tsconfig.json +51 -11
@@ -2,8 +2,11 @@ import ObjectID from "../ObjectID";
2
2
  import MonitorStep from "./MonitorStep";
3
3
  import MonitorCriteria from "./MonitorCriteria";
4
4
  import MonitorCriteriaInstance from "./MonitorCriteriaInstance";
5
- import FilterCondition from "../Filter/FilterCondition";
6
- import { CheckOn, FilterType, EvaluateOverTimeType } from "./CriteriaFilter";
5
+ import {
6
+ buildHealthyCriteriaInstance,
7
+ buildUnhealthyCriteriaInstance,
8
+ } from "./Recommendation/RecommendationCriteriaBuilder";
9
+ import { FilterType, EvaluateOverTimeType } from "./CriteriaFilter";
7
10
  import MonitorStepKubernetesMonitor, {
8
11
  KubernetesResourceScope,
9
12
  } from "./MonitorStepKubernetesMonitor";
@@ -92,59 +95,12 @@ export function buildOfflineCriteriaInstance(args: {
92
95
  incidentDescription?: string;
93
96
  criteriaName?: string;
94
97
  criteriaDescription?: string;
98
+ metricAggregationType?: EvaluateOverTimeType | undefined;
95
99
  }): MonitorCriteriaInstance {
96
- const instance: MonitorCriteriaInstance = new MonitorCriteriaInstance();
97
-
98
- const incidentTitle: string =
99
- args.incidentTitle || `${args.monitorName} - Alert Triggered`;
100
- const incidentDescription: string =
101
- args.incidentDescription ||
102
- `${args.monitorName} has triggered an alert condition. See root cause for detailed Kubernetes resource information.`;
103
-
104
- instance.data = {
105
- id: ObjectID.generate().toString(),
106
- monitorStatusId: args.offlineMonitorStatusId,
107
- filterCondition: FilterCondition.Any,
108
- filters: [
109
- {
110
- checkOn: CheckOn.MetricValue,
111
- filterType: args.filterType,
112
- metricMonitorOptions: {
113
- metricAggregationType: EvaluateOverTimeType.AnyValue,
114
- metricAlias: args.metricAlias,
115
- },
116
- value: args.value,
117
- },
118
- ],
119
- incidents: [
120
- {
121
- title: incidentTitle,
122
- description: incidentDescription,
123
- incidentSeverityId: args.incidentSeverityId,
124
- autoResolveIncident: true,
125
- id: ObjectID.generate().toString(),
126
- onCallPolicyIds: [],
127
- },
128
- ],
129
- alerts: [
130
- {
131
- title: incidentTitle,
132
- description: incidentDescription,
133
- alertSeverityId: args.alertSeverityId,
134
- autoResolveAlert: true,
135
- id: ObjectID.generate().toString(),
136
- onCallPolicyIds: [],
137
- },
138
- ],
139
- changeMonitorStatus: true,
140
- createIncidents: true,
141
- createAlerts: true,
142
- name: args.criteriaName || `${args.monitorName} - Unhealthy`,
143
- description:
144
- args.criteriaDescription || `Criteria for detecting unhealthy state.`,
145
- };
146
-
147
- return instance;
100
+ return buildUnhealthyCriteriaInstance({
101
+ ...args,
102
+ resourceNoun: "Kubernetes resource",
103
+ });
148
104
  }
149
105
 
150
106
  export function buildOnlineCriteriaInstance(args: {
@@ -152,41 +108,19 @@ export function buildOnlineCriteriaInstance(args: {
152
108
  metricAlias: string;
153
109
  filterType: FilterType;
154
110
  value: number;
111
+ recoveryValue?: number | undefined;
112
+ marginFraction?: number | undefined;
113
+ isBinaryMetric?: boolean | undefined;
114
+ metricAggregationType?: EvaluateOverTimeType | undefined;
155
115
  }): MonitorCriteriaInstance {
156
- const instance: MonitorCriteriaInstance = new MonitorCriteriaInstance();
157
-
158
- instance.data = {
159
- id: ObjectID.generate().toString(),
160
- monitorStatusId: args.onlineMonitorStatusId,
161
- filterCondition: FilterCondition.Any,
162
- filters: [
163
- {
164
- checkOn: CheckOn.MetricValue,
165
- filterType: args.filterType,
166
- metricMonitorOptions: {
167
- metricAggregationType: EvaluateOverTimeType.AnyValue,
168
- metricAlias: args.metricAlias,
169
- },
170
- value: args.value,
171
- },
172
- ],
173
- incidents: [],
174
- alerts: [],
175
- changeMonitorStatus: true,
176
- createIncidents: false,
177
- createAlerts: false,
178
- name: "Healthy",
179
- description: "Criteria for healthy state.",
180
- };
181
-
182
- return instance;
116
+ return buildHealthyCriteriaInstance(args);
183
117
  }
184
118
 
185
119
  /**
186
120
  * Build a single-query monitor config.
187
121
  *
188
- * `groupByAttributeKey` makes the monitor PER-SERIES: the worker splits
189
- * the metric by that attribute and every group is evaluated — and paged —
122
+ * `groupByAttributeKeys` makes the monitor PER-SERIES: the worker splits
123
+ * the metric by those attributes and every group is evaluated — and paged —
190
124
  * on its own, so a cluster of 200 pods raises one incident per unhealthy
191
125
  * pod rather than one incident for the whole cluster that then dedupes
192
126
  * every later pod away. Omitting it keeps the monitor whole-cluster.
@@ -197,7 +131,17 @@ export function buildOnlineCriteriaInstance(args: {
197
131
  * scheduler backlog — where there is exactly one value for the cluster
198
132
  * and splitting it would invent series that do not exist.
199
133
  *
200
- * The key is the ClickHouse-stored attribute name, which carries the
134
+ * Pass MORE than one key when the object's identity genuinely needs
135
+ * them, and the group-by set is what the alert can name afterwards. A
136
+ * bare pod name is not an identity — pod names are unique only within a
137
+ * namespace — and, more practically, an alert that says
138
+ * "Pod: checkout-7d9f-2xk" without the namespace sends the engineer to
139
+ * `kubectl` with a guess. The series labels are stored on the alert and
140
+ * rendered into its title and description (SeriesLabelDisplay), so every
141
+ * key added here is one more thing the on-call engineer does not have to
142
+ * go and look up.
143
+ *
144
+ * The keys are the ClickHouse-stored attribute names, which carry the
201
145
  * `resource.` prefix for OTel resource attributes (see
202
146
  * OtelMetricsIngestService — resource attributes are stamped with
203
147
  * `prefixKeysWithString: "resource"`). So node grouping is
@@ -213,7 +157,21 @@ export function buildKubernetesMonitorConfig(args: {
213
157
  rollingTime: RollingTime;
214
158
  aggregationType: MetricsAggregationType;
215
159
  attributes?: Record<string, string>;
216
- groupByAttributeKey?: string | undefined;
160
+ groupByAttributeKeys?: Array<string> | undefined;
161
+ /*
162
+ * Native-to-display unit for this query. MetricResultUnitConverter
163
+ * (invoked on the monitor path in MonitorTelemetryMonitor, before the
164
+ * criteria are compared) rescales the query's values from the unit
165
+ * OpenTelemetry reported into this one, and MetricUnitUtil puts UCUM
166
+ * "1" — OTel's dimensionless marker for a 0-1 fraction — in the percent
167
+ * family with `toCanonical: 100`.
168
+ *
169
+ * So declaring "%" on a receiver-emitted 0-1 ratio lets the criteria
170
+ * below stay written in percent, and is a no-op if that metric ever
171
+ * arrives already scaled as "%" (the converter short-circuits when the
172
+ * native and display units match).
173
+ */
174
+ legendUnit?: string | undefined;
217
175
  }): MonitorStepKubernetesMonitor {
218
176
  return {
219
177
  clusterIdentifier: args.clusterIdentifier,
@@ -227,7 +185,7 @@ export function buildKubernetesMonitorConfig(args: {
227
185
  title: args.metricAlias,
228
186
  description: args.metricAlias,
229
187
  legend: args.metricAlias,
230
- legendUnit: undefined,
188
+ legendUnit: args.legendUnit,
231
189
  },
232
190
  metricQueryData: {
233
191
  filterData: {
@@ -236,8 +194,9 @@ export function buildKubernetesMonitorConfig(args: {
236
194
  aggegationType: args.aggregationType,
237
195
  aggregateBy: {},
238
196
  },
239
- ...(args.groupByAttributeKey
240
- ? { groupByAttributeKeys: [args.groupByAttributeKey] }
197
+ ...(args.groupByAttributeKeys &&
198
+ args.groupByAttributeKeys.length > 0
199
+ ? { groupByAttributeKeys: args.groupByAttributeKeys }
241
200
  : {}),
242
201
  },
243
202
  },
@@ -250,8 +209,8 @@ export function buildKubernetesMonitorConfig(args: {
250
209
 
251
210
  /**
252
211
  * Build a per-series ratio monitor: `(numerator / denominator) * 100`,
253
- * grouped by a single OpenTelemetry attribute so one incident fires per
254
- * group (e.g. per node).
212
+ * grouped by one or more OpenTelemetry attributes so one incident fires
213
+ * per group (e.g. per node, or per namespace+pod).
255
214
  *
256
215
  * Used for saturation metrics that aren't emitted as a single ready-made
257
216
  * series — e.g. node request utilization (summed pod requests ÷ node
@@ -279,17 +238,39 @@ export function buildKubernetesMonitorConfig(args: {
279
238
  * both reported the same row count every minute — fragile across
280
239
  * restarts / missed scrapes / minute-boundary jitter.
281
240
  *
282
- * The group-by key is the ClickHouse-stored attribute name, which carries
283
- * the `resource.` prefix for OTel resource attributes (see
241
+ * The group-by keys are the ClickHouse-stored attribute names, which
242
+ * carry the `resource.` prefix for OTel resource attributes (see
284
243
  * OtelMetricsIngestService — resource attributes are stamped with
285
244
  * `prefixKeysWithString: "resource"`). So node grouping is
286
245
  * `resource.k8s.node.name`, not the bare `k8s.node.name`.
246
+ *
247
+ * CHOOSING THE KEYS IS NOT FREE HERE, and the constraint is different
248
+ * from the single-query builder. The two queries are joined by series
249
+ * FINGERPRINT — `buildSeriesBreakdown` buckets each query's rows by the
250
+ * hash of this exact key set — so a key that only ONE side carries
251
+ * splits the two into fingerprints that never meet, the formula
252
+ * evaluates against an empty operand, and the monitor silently stops
253
+ * alerting. Not "alerts less precisely": stops. So only add a key both
254
+ * metrics are GUARANTEED to carry, from their receivers themselves
255
+ * rather than from best-effort enrichment:
256
+ *
257
+ * - `k8s.namespace.name` is safe for pod/container/workload ratios:
258
+ * kubeletstats stamps it on pod metrics and the k8s_cluster receiver
259
+ * stamps it on container and workload metrics, both directly.
260
+ *
261
+ * - `k8s.node.name` is NOT safe on a pod ratio whose denominator is a
262
+ * k8s_cluster metric. kubeletstats always has it (the receiver, plus
263
+ * the DaemonSet's `resource` processor stamping NODE_NAME); on the
264
+ * k8s_cluster side it can only arrive via the k8sattributes
265
+ * processor, which is best-effort and depends on pod association
266
+ * still resolving. A single-query template over a kubeletstats
267
+ * metric has no join to break and may group by it freely.
287
268
  */
288
269
  export function buildKubernetesRatioMonitorConfig(args: {
289
270
  clusterIdentifier: string;
290
271
  numeratorMetricName: string;
291
272
  denominatorMetricName: string;
292
- groupByAttributeKey: string;
273
+ groupByAttributeKeys: Array<string>;
293
274
  numeratorAlias: string;
294
275
  denominatorAlias: string;
295
276
  resultAlias: string;
@@ -297,6 +278,17 @@ export function buildKubernetesRatioMonitorConfig(args: {
297
278
  resourceScope: KubernetesResourceScope;
298
279
  rollingTime: RollingTime;
299
280
  aggregationType?: MetricsAggregationType | undefined;
281
+ /*
282
+ * Override the default `(numerator / denominator) * 100` when the
283
+ * percentage the template needs is not a plain ratio of the two
284
+ * operands. Node filesystem usage is the case this exists for: the
285
+ * only companion series this repo ingests is
286
+ * `k8s.node.filesystem.available`, so the denominator has to be built
287
+ * as `usage + available` — the same way `df` computes Use%, and the
288
+ * same way the cluster dashboard already computes node fill. Reference
289
+ * the operand ALIASES, not the metric names.
290
+ */
291
+ formula?: string | undefined;
300
292
  }): MonitorStepKubernetesMonitor {
301
293
  const aggregationType: MetricsAggregationType =
302
294
  args.aggregationType || MetricsAggregationType.Sum;
@@ -320,7 +312,7 @@ export function buildKubernetesRatioMonitorConfig(args: {
320
312
  aggegationType: aggregationType,
321
313
  aggregateBy: {},
322
314
  },
323
- groupByAttributeKeys: [args.groupByAttributeKey],
315
+ groupByAttributeKeys: args.groupByAttributeKeys,
324
316
  },
325
317
  };
326
318
  };
@@ -344,7 +336,9 @@ export function buildKubernetesRatioMonitorConfig(args: {
344
336
  legendUnit: "%",
345
337
  },
346
338
  metricFormulaData: {
347
- metricFormula: `(${args.numeratorAlias} / ${args.denominatorAlias}) * 100`,
339
+ metricFormula:
340
+ args.formula ||
341
+ `(${args.numeratorAlias} / ${args.denominatorAlias}) * 100`,
348
342
  },
349
343
  },
350
344
  ],
@@ -358,8 +352,14 @@ export function buildKubernetesRatioMonitorConfig(args: {
358
352
  const crashLoopBackOffTemplate: KubernetesAlertTemplate = {
359
353
  id: "k8s-crashloopbackoff",
360
354
  name: "CrashLoopBackOff Detection",
355
+ /*
356
+ * No backticks in here. `template.description` is rendered as raw JSX
357
+ * text on the recommendation card
358
+ * (KubernetesTemplatePicker.tsx renders `{template.description}` inside a
359
+ * <p>, not markdown), so a code span would show up as literal backticks.
360
+ */
361
361
  description:
362
- "Alert when container restart count exceeds threshold, indicating a CrashLoopBackOff condition.",
362
+ "Alert when a container has restarted more than 5 times since its pod was created. k8s.container.restarts is the container status' cumulative restartCount, so this is a lifetime count for the CURRENT pod rather than a rate: it resets only when the pod object is replaced, which is also when this alert auto-resolves.",
363
363
  category: "Workload",
364
364
  severity: "Critical",
365
365
  getMonitorStep: (args: KubernetesAlertTemplateArgs): MonitorStep => {
@@ -379,7 +379,11 @@ const crashLoopBackOffTemplate: KubernetesAlertTemplate = {
379
379
  * whichever pod in the cluster crashed first. Max over the window
380
380
  * therefore becomes "the worst container in THIS pod".
381
381
  */
382
- groupByAttributeKey: "resource.k8s.pod.name",
382
+ groupByAttributeKeys: [
383
+ "resource.k8s.namespace.name",
384
+ "resource.k8s.pod.name",
385
+ "resource.k8s.container.name",
386
+ ],
383
387
  }),
384
388
  offlineCriteriaInstance: buildOfflineCriteriaInstance({
385
389
  offlineMonitorStatusId: args.offlineMonitorStatusId,
@@ -390,10 +394,30 @@ const crashLoopBackOffTemplate: KubernetesAlertTemplate = {
390
394
  filterType: FilterType.GreaterThan,
391
395
  value: 5,
392
396
  incidentTitle: `[K8s] CrashLoopBackOff Detected - ${args.monitorName}`,
393
- incidentDescription: `A container in the Kubernetes cluster is repeatedly crashing and restarting (CrashLoopBackOff). The container restart count has exceeded the threshold of 5 restarts. Check the root cause for the specific pod, container, and node details.`,
397
+ /*
398
+ * `k8s.container.restarts` is containerStatus.restartCount: it only
399
+ * ever goes up for the life of the pod object. Everything this copy
400
+ * says follows from that, so keep the two facts in it — the count is
401
+ * cumulative, and the alert therefore clears on pod replacement
402
+ * rather than when the crashing stops.
403
+ *
404
+ * No angle-bracket placeholders in here. Incident.description is a
405
+ * Markdown column, and the subscriber path runs it through
406
+ * Markdown.convertToPlainText, which strips /<[^>]*>/g BEFORE it
407
+ * strips code-span backticks — so `<pod>` would silently vanish from
408
+ * every SMS.
409
+ *
410
+ * This template is GROUPED (namespace + pod + container), so it does
411
+ * NOT send the reader to the root cause for identity: a grouped
412
+ * alert's rootCause is only the compare line
413
+ * (MonitorCriteriaEvaluator.collectPerSeriesMatches). The identity
414
+ * lives in the block SeriesContextEnricher appends to the
415
+ * description.
416
+ */
417
+ incidentDescription: `A container has restarted more than 5 times since its pod was created — the signature of a CrashLoopBackOff. This count is cumulative for THIS pod and never decreases, so the alert clears when the pod is replaced (a redeploy, an eviction, a node drain) rather than at the moment the crashing stops. Common causes: a crash on startup, a missing config map or secret, an OOMKill against the container's memory limit, or a failing liveness probe. The affected namespace, pod and container are named under "Affected resource" below, with the kubectl commands to inspect them — including the previous instance's logs — under "Start here".`,
394
418
  criteriaName: "CrashLoopBackOff - Container Restarts > 5",
395
419
  criteriaDescription:
396
- "Triggers when any container restart count exceeds 5 in the monitoring window, indicating a CrashLoopBackOff condition.",
420
+ "Triggers when a container's cumulative restart count for its current pod exceeds 5. This is not a per-window rate: a container that crash-looped and then stabilised keeps the alert open until its pod is replaced, and a container that is actively crash-looping but has only reached 3 restarts does not fire yet.",
397
421
  }),
398
422
  onlineCriteriaInstance: buildOnlineCriteriaInstance({
399
423
  onlineMonitorStatusId: args.onlineMonitorStatusId,
@@ -413,7 +437,7 @@ const podPendingTemplate: KubernetesAlertTemplate = {
413
437
  category: "Scheduling",
414
438
  severity: "Warning",
415
439
  getMonitorStep: (args: KubernetesAlertTemplateArgs): MonitorStep => {
416
- const metricAlias: string = "pending_pods";
440
+ const metricAlias: string = "min_pod_phase";
417
441
 
418
442
  return buildKubernetesMonitorStep({
419
443
  kubernetesMonitor: buildKubernetesMonitorConfig({
@@ -421,16 +445,49 @@ const podPendingTemplate: KubernetesAlertTemplate = {
421
445
  metricName: "k8s.pod.phase",
422
446
  metricAlias,
423
447
  resourceScope: KubernetesResourceScope.Cluster,
424
- rollingTime: RollingTime.Past5Minutes,
425
- aggregationType: MetricsAggregationType.Sum,
426
- attributes: { "resource.k8s.pod.phase": "Pending" },
448
+ /*
449
+ * 15 minutes, with the sustained (AllValues) default: a pod that
450
+ * is Pending for a few seconds while it is scheduled is normal on
451
+ * any cluster doing deployments. "Stuck" means every per-minute
452
+ * bucket in the window still found a pod waiting.
453
+ */
454
+ rollingTime: RollingTime.Past15Minutes,
455
+ /*
456
+ * `k8s.pod.phase` encodes the phase in the VALUE, not in a label.
457
+ * The `k8s_cluster` receiver emits one gauge per pod per scrape,
458
+ * numbered in the order KubernetesMetricCatalog names them:
459
+ * 1 = Pending, 2 = Running, 3 = Succeeded, 4 = Failed,
460
+ * 5 = Unknown. The numeric mapping comes from the receiver itself;
461
+ * the catalog names the phases but carries no codes.
462
+ *
463
+ * This template used to carry
464
+ * `attributes: { "resource.k8s.pod.phase": "Pending" }` — an
465
+ * attribute nothing produces. The `k8s_cluster` receiver does not
466
+ * stamp it, the agent's `k8sattributes` processor extracts only
467
+ * name/uid/namespace/node/workload/container keys
468
+ * (configmap-deployment.yaml), and nothing in the ingest path
469
+ * synthesises it. The worker copies this map straight into the
470
+ * ClickHouse predicate (MonitorTelemetryMonitor.monitorKubernetes),
471
+ * so the query matched zero rows: the monitor never fired, never
472
+ * resolved, and never reported that it was watching nothing.
473
+ *
474
+ * Pending is the LOWEST phase code, so the cluster-wide Min is
475
+ * exactly 1 when at least one pod is Pending, and >= 2 otherwise.
476
+ * Min also avoids the trap the previous `Sum` walked into, which
477
+ * Common/Types/Dashboard/DashboardTemplates.ts documents: a
478
+ * per-resource gauge re-emitted on every scrape sums to
479
+ * (pods x scrapes). This is the same idiom k8s-node-not-ready
480
+ * already uses on `k8s.node.condition_ready` (Min + an equality
481
+ * against the bad value).
482
+ */
483
+ aggregationType: MetricsAggregationType.Min,
427
484
  /*
428
485
  * Deliberately NOT grouped, unlike the other pod-level templates.
429
486
  *
430
- * This is a cluster-wide COUNT of unschedulable pods (Cluster
431
- * scope, Sum, "Count > 0"), i.e. a statement about the cluster's
432
- * scheduling capacity rather than about any one pod's health — the
433
- * same signal as k8s-scheduler-backlog, seen from the pod side.
487
+ * This is a cluster-wide statement about scheduling capacity
488
+ * ("somebody is stuck waiting") rather than about any one pod's
489
+ * health the same signal as k8s-scheduler-backlog, seen from
490
+ * the pod side.
434
491
  *
435
492
  * Grouping it by `resource.k8s.pod.name` would fan out per pod
436
493
  * name, and pending pod names are ephemeral: a stuck rollout burns
@@ -447,19 +504,35 @@ const podPendingTemplate: KubernetesAlertTemplate = {
447
504
  alertSeverityId: args.defaultAlertSeverityId,
448
505
  monitorName: args.monitorName,
449
506
  metricAlias,
450
- filterType: FilterType.GreaterThan,
451
- value: 0,
507
+ filterType: FilterType.EqualTo,
508
+ value: 1,
452
509
  incidentTitle: `[K8s] Pods Stuck in Pending - ${args.monitorName}`,
453
- incidentDescription: `One or more pods in the Kubernetes cluster are stuck in Pending phase and cannot be scheduled. This typically indicates insufficient cluster resources, node affinity constraints, or unbound PersistentVolumeClaims. Check the root cause for specific pod and scheduling details.`,
454
- criteriaName: "Pods Pending - Count > 0",
510
+ /*
511
+ * Deliberately self-sufficient: it does NOT say "see the affected
512
+ * resources below". The shared Kubernetes breakdown renderer sorts
513
+ * affected resources by descending metric value ("worst first"),
514
+ * which for a phase code puts Unknown(5)/Failed(4)/Succeeded(3)
515
+ * pods above the Pending(1) one this alert is about, so the table
516
+ * cannot be relied on to name the stuck pod until that renderer
517
+ * learns a per-metric sort direction.
518
+ */
519
+ incidentDescription: `At least one pod has been in Pending phase in every sample of the last 15 minutes and cannot be scheduled. This typically indicates insufficient CPU/memory on the nodes, node affinity or taint restrictions, an unbound PersistentVolumeClaim, or an exceeded ResourceQuota. Run \`kubectl get pods --all-namespaces --field-selector=status.phase=Pending\` and \`kubectl describe\` one of them to see the scheduler's reason.`,
520
+ criteriaName: "Pods Pending - Phase = Pending (1)",
455
521
  criteriaDescription:
456
- "Triggers when any pods are in Pending phase, unable to be scheduled.",
522
+ "Triggers when the lowest pod phase code in the cluster is 1 (Pending) for every sample in the monitoring window.",
457
523
  }),
458
524
  onlineCriteriaInstance: buildOnlineCriteriaInstance({
459
525
  onlineMonitorStatusId: args.onlineMonitorStatusId,
460
526
  metricAlias,
461
- filterType: FilterType.EqualTo,
462
- value: 0,
527
+ /*
528
+ * NotEqualTo rather than GreaterThan: getRecoveryThreshold gives
529
+ * no dead band to an equality comparison, so the recovery value
530
+ * stays exactly 1. `GreaterThan` would complement back to
531
+ * LessThanOrEqualTo and derive a 1.1 recovery threshold — a
532
+ * fractional edge on a metric whose values are an enum.
533
+ */
534
+ filterType: FilterType.NotEqualTo,
535
+ value: 1,
463
536
  }),
464
537
  });
465
538
  },
@@ -488,7 +561,7 @@ const nodeNotReadyTemplate: KubernetesAlertTemplate = {
488
561
  * across the fleet is 0 as soon as ANY node is down, and the
489
562
  * second node to fail dedupes behind the first one's incident.
490
563
  */
491
- groupByAttributeKey: "resource.k8s.node.name",
564
+ groupByAttributeKeys: ["resource.k8s.node.name"],
492
565
  }),
493
566
  offlineCriteriaInstance: buildOfflineCriteriaInstance({
494
567
  offlineMonitorStatusId: args.offlineMonitorStatusId,
@@ -499,7 +572,7 @@ const nodeNotReadyTemplate: KubernetesAlertTemplate = {
499
572
  filterType: FilterType.EqualTo,
500
573
  value: 0,
501
574
  incidentTitle: `[K8s] Node Not Ready - ${args.monitorName}`,
502
- incidentDescription: `A Kubernetes node has transitioned to NotReady state. This is a critical condition that affects all pods scheduled on this node. Check the root cause for the specific node name, conditions, and recommended actions.`,
575
+ incidentDescription: `A Kubernetes node has transitioned to NotReady state. This is a critical condition that affects all pods scheduled on this node. The affected node is named under "Affected resource" below; use the kubectl commands under "Start here" to read its conditions and list what it is still hosting.`,
503
576
  criteriaName: "Node NotReady - Condition = 0",
504
577
  criteriaDescription:
505
578
  "Triggers when any node reports a NotReady condition (value 0).",
@@ -529,7 +602,7 @@ const highCpuTemplate: KubernetesAlertTemplate = {
529
602
  clusterIdentifier: args.clusterIdentifier,
530
603
  numeratorMetricName: "k8s.node.cpu.usage",
531
604
  denominatorMetricName: "k8s.node.allocatable_cpu",
532
- groupByAttributeKey: "resource.k8s.node.name",
605
+ groupByAttributeKeys: ["resource.k8s.node.name"],
533
606
  numeratorAlias: "used_cpu",
534
607
  denominatorAlias: "alloc_cpu",
535
608
  resultAlias: metricAlias,
@@ -553,7 +626,7 @@ const highCpuTemplate: KubernetesAlertTemplate = {
553
626
  filterType: FilterType.GreaterThan,
554
627
  value: 90,
555
628
  incidentTitle: `[K8s] High CPU Utilization (>90%) - ${args.monitorName}`,
556
- incidentDescription: `A node's average CPU usage has exceeded 90% of its allocatable CPU. Sustained high CPU usage can cause pod throttling, increased latency, and potential node instability. Check the root cause for the specific node and top CPU-consuming workloads.`,
629
+ incidentDescription: `A node's average CPU usage has exceeded 90% of its allocatable CPU. Sustained high CPU usage can cause pod throttling, increased latency, and potential node instability. The affected node is named under "Affected resource" below; use the kubectl commands under "Start here" to list the pods on it and find the top CPU consumers.`,
557
630
  criteriaName: "High CPU - Utilization > 90%",
558
631
  criteriaDescription:
559
632
  "Triggers when a node's average CPU usage exceeds 90% of its allocatable CPU over the monitoring window.",
@@ -583,7 +656,7 @@ const highMemoryTemplate: KubernetesAlertTemplate = {
583
656
  clusterIdentifier: args.clusterIdentifier,
584
657
  numeratorMetricName: "k8s.node.memory.usage",
585
658
  denominatorMetricName: "k8s.node.allocatable_memory",
586
- groupByAttributeKey: "resource.k8s.node.name",
659
+ groupByAttributeKeys: ["resource.k8s.node.name"],
587
660
  numeratorAlias: "used_mem",
588
661
  denominatorAlias: "alloc_mem",
589
662
  resultAlias: metricAlias,
@@ -607,7 +680,7 @@ const highMemoryTemplate: KubernetesAlertTemplate = {
607
680
  filterType: FilterType.GreaterThan,
608
681
  value: 85,
609
682
  incidentTitle: `[K8s] High Memory Utilization (>85%) - ${args.monitorName}`,
610
- incidentDescription: `A node's average memory usage has exceeded 85% of its allocatable memory. High memory usage can lead to OOMKilled pods, node instability, and potential evictions. Check the root cause for the specific node and top memory-consuming workloads.`,
683
+ incidentDescription: `A node's average memory usage has exceeded 85% of its allocatable memory. High memory usage can lead to OOMKilled pods, node instability, and potential evictions. The affected node is named under "Affected resource" below; use the kubectl commands under "Start here" to list the pods on it and find the top memory consumers.`,
611
684
  criteriaName: "High Memory - Utilization > 85%",
612
685
  criteriaDescription:
613
686
  "Triggers when a node's average memory usage exceeds 85% of its allocatable memory over the monitoring window.",
@@ -638,7 +711,17 @@ const deploymentReplicaMismatchTemplate: KubernetesAlertTemplate = {
638
711
  metricName: "k8s.deployment.unavailable_replicas",
639
712
  metricAlias,
640
713
  resourceScope: KubernetesResourceScope.Workload,
641
- rollingTime: RollingTime.Past5Minutes,
714
+ /*
715
+ * 15 minutes, not 5. With the sustained (AllValues) default, the
716
+ * window IS the "how long has this been stuck" knob: every
717
+ * per-minute bucket in it must report unavailable replicas. A
718
+ * normal rolling update makes unavailable_replicas non-zero for
719
+ * the duration of the rollout, and a ten-replica deployment with
720
+ * maxUnavailable 25% and real readiness probes routinely takes
721
+ * longer than five minutes — so a five-minute window still paged
722
+ * once per deploy for a condition that is the deploy working.
723
+ */
724
+ rollingTime: RollingTime.Past15Minutes,
642
725
  aggregationType: MetricsAggregationType.Max,
643
726
  /*
644
727
  * Per deployment: a stuck rollout is a property of one Deployment
@@ -647,7 +730,10 @@ const deploymentReplicaMismatchTemplate: KubernetesAlertTemplate = {
647
730
  * (the worker reads `resource.k8s.deployment.name` back off these
648
731
  * rows to build the affected-resource breakdown).
649
732
  */
650
- groupByAttributeKey: "resource.k8s.deployment.name",
733
+ groupByAttributeKeys: [
734
+ "resource.k8s.namespace.name",
735
+ "resource.k8s.deployment.name",
736
+ ],
651
737
  }),
652
738
  offlineCriteriaInstance: buildOfflineCriteriaInstance({
653
739
  offlineMonitorStatusId: args.offlineMonitorStatusId,
@@ -658,10 +744,10 @@ const deploymentReplicaMismatchTemplate: KubernetesAlertTemplate = {
658
744
  filterType: FilterType.GreaterThan,
659
745
  value: 0,
660
746
  incidentTitle: `[K8s] Deployment Replica Mismatch - ${args.monitorName}`,
661
- incidentDescription: `A Kubernetes deployment has unavailable replicas — the desired replica count does not match the available count. This may indicate a failed rollout, image pull errors, insufficient resources, or pod crash loops. Check the root cause for the specific deployment and replica details.`,
662
- criteriaName: "Replica Mismatch - Unavailable > 0",
747
+ incidentDescription: `A Kubernetes deployment has unavailable replicas — the desired replica count does not match the available count. This may indicate a failed rollout, image pull errors, insufficient resources, or pod crash loops. The affected namespace and deployment are named under "Affected resource" below, with the rollout-status command under "Start here".`,
748
+ criteriaName: "Replica Mismatch - Unavailable > 0 for 15 minutes",
663
749
  criteriaDescription:
664
- "Triggers when any deployment has unavailable replicas.",
750
+ "Triggers when a deployment reports unavailable replicas in every sample of a fifteen-minute window — long enough that a normal rolling update has completed and the rollout is genuinely stuck.",
665
751
  }),
666
752
  onlineCriteriaInstance: buildOnlineCriteriaInstance({
667
753
  onlineMonitorStatusId: args.onlineMonitorStatusId,
@@ -696,7 +782,10 @@ const jobFailuresTemplate: KubernetesAlertTemplate = {
696
782
  * arriving and the per-series pass auto-resolves that Job's alert
697
783
  * by absence, which is the behaviour we want here.
698
784
  */
699
- groupByAttributeKey: "resource.k8s.job.name",
785
+ groupByAttributeKeys: [
786
+ "resource.k8s.namespace.name",
787
+ "resource.k8s.job.name",
788
+ ],
700
789
  }),
701
790
  offlineCriteriaInstance: buildOfflineCriteriaInstance({
702
791
  offlineMonitorStatusId: args.offlineMonitorStatusId,
@@ -707,7 +796,7 @@ const jobFailuresTemplate: KubernetesAlertTemplate = {
707
796
  filterType: FilterType.GreaterThan,
708
797
  value: 0,
709
798
  incidentTitle: `[K8s] Job Failure Detected - ${args.monitorName}`,
710
- incidentDescription: `A Kubernetes Job has one or more failed pods. This indicates the job's workload is failing to complete successfully. Check the root cause for the specific job name, failed pod details, and error information.`,
799
+ incidentDescription: `A Kubernetes Job has one or more failed pods. This indicates the job's workload is failing to complete successfully. The affected namespace and job are named under "Affected resource" below, with the describe command under "Start here".`,
711
800
  criteriaName: "Job Failures - Failed Pods > 0",
712
801
  criteriaDescription:
713
802
  "Triggers when any Kubernetes Job has failed pods.",
@@ -725,8 +814,16 @@ const jobFailuresTemplate: KubernetesAlertTemplate = {
725
814
  const etcdNoLeaderTemplate: KubernetesAlertTemplate = {
726
815
  id: "k8s-etcd-no-leader",
727
816
  name: "etcd No Leader",
817
+ /*
818
+ * The requirement leads, deliberately: the card truncates long
819
+ * descriptions, and a user who one-clicks this on a managed cluster gets
820
+ * a monitor that is never Met and gives no indication it is inert.
821
+ *
822
+ * No backticks — KubernetesTemplatePicker renders this as raw JSX text,
823
+ * so a code span would show up as literal backticks on the card.
824
+ */
728
825
  description:
729
- "Alert immediately when etcd has no leader elected. This is a critical cluster health issue.",
826
+ "Requires the agent's control-plane scrape (controlPlane.enabled); managed clusters (EKS / GKE / AKS) do not expose etcd's metrics endpoint at all, so on those this monitor will never receive a data point. Alert immediately when etcd has no leader elected a critical cluster health issue.",
730
827
  category: "ControlPlane",
731
828
  severity: "Critical",
732
829
  getMonitorStep: (args: KubernetesAlertTemplateArgs): MonitorStep => {
@@ -772,27 +869,54 @@ const etcdNoLeaderTemplate: KubernetesAlertTemplate = {
772
869
 
773
870
  const apiServerThrottlingTemplate: KubernetesAlertTemplate = {
774
871
  id: "k8s-apiserver-throttling",
775
- name: "API Server Throttling",
872
+ name: "API Server Request Saturation",
776
873
  description:
777
- "Alert when the Kubernetes API server is dropping requests due to throttling.",
874
+ "Alert when the Kubernetes API server holds 200 or more concurrent in-flight requests for the whole window — the state in which it starts rejecting requests with 429. Requires the agent's control-plane scrape: set controlPlane.enabled and point controlPlane.apiServer.endpoints at an API server address the collector pod can actually reach (the chart's default, localhost:6443, is the collector's own loopback and scrapes nothing).",
778
875
  category: "ControlPlane",
779
876
  severity: "Critical",
780
877
  getMonitorStep: (args: KubernetesAlertTemplateArgs): MonitorStep => {
781
- const metricAlias: string = "dropped_requests";
878
+ const metricAlias: string = "inflight_requests";
782
879
 
783
880
  return buildKubernetesMonitorStep({
784
881
  kubernetesMonitor: buildKubernetesMonitorConfig({
785
882
  clusterIdentifier: args.clusterIdentifier,
786
- metricName: "apiserver_dropped_requests_total",
883
+ /*
884
+ * A GAUGE, deliberately.
885
+ *
886
+ * This template used to Sum `apiserver_dropped_requests_total`, a
887
+ * cumulative Prometheus counter. The agent scrapes the API
888
+ * server's /metrics raw (configmap-deployment.yaml, job_name:
889
+ * kube-apiserver, no metric_relabel_configs) and nothing in the
890
+ * shipped pipeline converts counters to deltas: there is no
891
+ * cumulativetodelta processor in the chart,
892
+ * OtelMetricsIngestService records `aggregationTemporality` /
893
+ * `isMonotonic` but never differences the value, and neither
894
+ * AggregationType nor CompareCriteria.reduceWindow has a Rate or
895
+ * Delta member. So every sample was the process's lifetime total.
896
+ * One throttled request at any point since the API server last
897
+ * started pinned the monitor Offline, and the "= 0" recovery could
898
+ * never be met again.
899
+ *
900
+ * `apiserver_current_inflight_requests` is the gauge the cluster's
901
+ * own control-plane dashboard already charts for this signal
902
+ * (App/FeatureSet/Dashboard/src/Pages/Kubernetes/View/
903
+ * ControlPlane.tsx: "Current number of in-flight requests being
904
+ * processed. High counts indicate API server saturation."). It is
905
+ * emitted per request_kind (mutating / readOnly).
906
+ */
907
+ metricName: "apiserver_current_inflight_requests",
787
908
  metricAlias,
788
909
  resourceScope: KubernetesResourceScope.Cluster,
789
910
  rollingTime: RollingTime.Past5Minutes,
790
- aggregationType: MetricsAggregationType.Sum,
791
911
  /*
792
- * Ungrouped: this is the control plane's aggregate throttling
793
- * rate. Splitting it would need a per-apiserver-instance identity
794
- * that this metric does not carry in the shipped agent config.
912
+ * Max across the two request_kind series: saturation of either
913
+ * queue is the condition, and the two have different ceilings.
914
+ *
915
+ * Ungrouped: this is the control plane's aggregate concurrency.
916
+ * Splitting it would need a per-apiserver-instance identity that
917
+ * this metric does not carry in the shipped agent config.
795
918
  */
919
+ aggregationType: MetricsAggregationType.Max,
796
920
  }),
797
921
  offlineCriteriaInstance: buildOfflineCriteriaInstance({
798
922
  offlineMonitorStatusId: args.offlineMonitorStatusId,
@@ -800,19 +924,42 @@ const apiServerThrottlingTemplate: KubernetesAlertTemplate = {
800
924
  alertSeverityId: args.defaultAlertSeverityId,
801
925
  monitorName: args.monitorName,
802
926
  metricAlias,
803
- filterType: FilterType.GreaterThan,
804
- value: 0,
805
- incidentTitle: `[K8s] CRITICAL: API Server Throttling - ${args.monitorName}`,
806
- incidentDescription: `The Kubernetes API server is dropping requests due to throttling. This indicates the API server is overloaded and cannot process all incoming requests, affecting cluster operations.`,
807
- criteriaName: "API Server Throttling - Dropped Requests > 0",
927
+ /*
928
+ * GreaterThanOrEqualTo, not GreaterThan.
929
+ *
930
+ * This gauge counts ADMITTED concurrency, so it is bounded above by
931
+ * the API server's own admission limit it saturates AT the limit
932
+ * rather than climbing past it. 200 is the default
933
+ * --max-mutating-requests-inflight exactly, so a strict "> 200"
934
+ * would ask the mutating queue to exceed its own ceiling and the
935
+ * one series this number describes would never fire at all. ">="
936
+ * catches a mutating queue pinned at its limit (actively rejecting
937
+ * with 429) and a readOnly queue at half of its default 400
938
+ * ceiling.
939
+ *
940
+ * The number is a heuristic tied to the upstream defaults, not a
941
+ * derived fact; the incident description tells the operator to
942
+ * retune it against their own flags.
943
+ */
944
+ filterType: FilterType.GreaterThanOrEqualTo,
945
+ value: 200,
946
+ incidentTitle: `[K8s] CRITICAL: API Server Request Saturation - ${args.monitorName}`,
947
+ incidentDescription: `The Kubernetes API server has held 200 or more concurrent in-flight requests for every sample in the monitoring window. The API server admits a bounded number of concurrent requests (--max-requests-inflight, default 400; --max-mutating-requests-inflight, default 200) and rejects the rest with 429, so sustained pressure here is the state immediately preceding cluster-wide API throttling. Common causes: a controller or client hot-looping on LIST, an operator with no resync backoff, or an undersized control plane. If your cluster runs different in-flight limits, retune this threshold to match them.`,
948
+ criteriaName: "API Server Saturation - In-Flight Requests >= 200",
808
949
  criteriaDescription:
809
- "Triggers when the API server reports any dropped requests.",
950
+ "Triggers when the API server's in-flight request count stays at or above 200 for every sample in the monitoring window.",
810
951
  }),
811
952
  onlineCriteriaInstance: buildOnlineCriteriaInstance({
812
953
  onlineMonitorStatusId: args.onlineMonitorStatusId,
813
954
  metricAlias,
814
- filterType: FilterType.EqualTo,
815
- value: 0,
955
+ /*
956
+ * Complement of the firing comparison. The builder derives the
957
+ * actual recovery threshold as a 10% dead band inside 200, i.e.
958
+ * "< 180", so a control plane parked at the limit cannot toggle the
959
+ * monitor on consecutive evaluations.
960
+ */
961
+ filterType: FilterType.LessThan,
962
+ value: 200,
816
963
  }),
817
964
  });
818
965
  },
@@ -821,8 +968,9 @@ const apiServerThrottlingTemplate: KubernetesAlertTemplate = {
821
968
  const schedulerBacklogTemplate: KubernetesAlertTemplate = {
822
969
  id: "k8s-scheduler-backlog",
823
970
  name: "Scheduler Backlog",
971
+ // See etcdNoLeaderTemplate for why the requirement leads and why no backticks.
824
972
  description:
825
- "Alert when there are pods waiting to be scheduled for more than 5 minutes.",
973
+ "Requires the agent's control-plane scrape (controlPlane.enabled); managed clusters (EKS / GKE / AKS) do not expose the scheduler's metrics endpoint at all, so on those this monitor will never receive a data point. Alert when the scheduler's pending-pod queue is non-empty in every sample of a five-minute window.",
826
974
  category: "Scheduling",
827
975
  severity: "Warning",
828
976
  getMonitorStep: (args: KubernetesAlertTemplateArgs): MonitorStep => {
@@ -868,27 +1016,50 @@ const schedulerBacklogTemplate: KubernetesAlertTemplate = {
868
1016
  const highDiskUsageTemplate: KubernetesAlertTemplate = {
869
1017
  id: "k8s-high-disk-usage",
870
1018
  name: "High Node Disk Usage",
871
- description: "Alert when node filesystem usage exceeds 90% capacity.",
1019
+ description:
1020
+ "Alert when a node's filesystem is more than 90% full. Computed per node as k8s.node.filesystem.usage / (k8s.node.filesystem.usage + k8s.node.filesystem.available) x 100 — both are bytes from the same kubeletstats node scrape, so this is a true percentage and matches what df reports as Use%.",
872
1021
  category: "Storage",
873
1022
  severity: "Warning",
874
1023
  getMonitorStep: (args: KubernetesAlertTemplateArgs): MonitorStep => {
875
1024
  const metricAlias: string = "disk_usage";
876
1025
 
877
1026
  return buildKubernetesMonitorStep({
878
- kubernetesMonitor: buildKubernetesMonitorConfig({
1027
+ kubernetesMonitor: buildKubernetesRatioMonitorConfig({
879
1028
  clusterIdentifier: args.clusterIdentifier,
880
- metricName: "k8s.node.filesystem.usage",
881
- metricAlias,
1029
+ /*
1030
+ * `k8s.node.filesystem.usage` is BYTES (KubernetesMetricCatalog
1031
+ * declares `unit: "bytes"`, and nothing converts it — the query
1032
+ * configs carry no `legendUnit`, so MetricResultUnitConverter
1033
+ * passes the raw value through). This template used to hand that
1034
+ * gauge straight to a `> 90` comparison, so every node in every
1035
+ * cluster breached on its first evaluation and the healthy
1036
+ * criterion — "90 bytes or less used" — was unreachable: a
1037
+ * permanently red monitor with an unresolvable incident.
1038
+ *
1039
+ * The denominator is built from the one companion series this
1040
+ * repo has actually ingested, `k8s.node.filesystem.available`
1041
+ * (KubernetesMetricCatalog, and the cluster dashboard's node
1042
+ * fill tile in App/FeatureSet/Dashboard/src/Pages/Kubernetes/
1043
+ * View/Index.tsx). usage / (usage + available) is what `df`
1044
+ * reports as Use%.
1045
+ */
1046
+ numeratorMetricName: "k8s.node.filesystem.usage",
1047
+ denominatorMetricName: "k8s.node.filesystem.available",
1048
+ groupByAttributeKeys: ["resource.k8s.node.name"],
1049
+ numeratorAlias: "used_disk",
1050
+ denominatorAlias: "avail_disk",
1051
+ resultAlias: metricAlias,
1052
+ resultLegend: "Node Disk Usage (%)",
1053
+ formula: `(used_disk / (used_disk + avail_disk)) * 100`,
882
1054
  resourceScope: KubernetesResourceScope.Node,
883
1055
  rollingTime: RollingTime.Past5Minutes,
884
- aggregationType: MetricsAggregationType.Avg,
885
1056
  /*
886
- * Per node: filesystem usage is per node (kubeletstats reports the
887
- * node's filesystem), and disk fills one node at a time. Ungrouped,
888
- * the Avg across the fleet dilutes a single full node into the
889
- * fleet mean and the alert never fires.
1057
+ * ONE series per node on BOTH sides, from the SAME kubeletstats
1058
+ * node scrape, so Avg gives the representative per-minute value
1059
+ * independent of scrape count. See
1060
+ * buildKubernetesRatioMonitorConfig.
890
1061
  */
891
- groupByAttributeKey: "resource.k8s.node.name",
1062
+ aggregationType: MetricsAggregationType.Avg,
892
1063
  }),
893
1064
  offlineCriteriaInstance: buildOfflineCriteriaInstance({
894
1065
  offlineMonitorStatusId: args.offlineMonitorStatusId,
@@ -899,10 +1070,10 @@ const highDiskUsageTemplate: KubernetesAlertTemplate = {
899
1070
  filterType: FilterType.GreaterThan,
900
1071
  value: 90,
901
1072
  incidentTitle: `[K8s] High Disk Usage (>90%) - ${args.monitorName}`,
902
- incidentDescription: `Node disk/filesystem usage has exceeded 90% capacity. High disk usage can lead to pod evictions, inability to pull new container images, and node instability. Check the root cause for the specific node and disk usage details.`,
1073
+ incidentDescription: `A node's filesystem is more than 90% full, sustained across the whole monitoring window. High disk usage leads to DiskPressure evictions, failure to pull new container images, and eventually a NotReady node. The affected node is named under "Affected resource" below, with the kubectl commands to inspect it under "Start here".`,
903
1074
  criteriaName: "High Disk - Usage > 90%",
904
1075
  criteriaDescription:
905
- "Triggers when average node filesystem usage exceeds 90% capacity.",
1076
+ "Triggers when a node's used bytes exceed 90% of used + available for every sample in the monitoring window.",
906
1077
  }),
907
1078
  onlineCriteriaInstance: buildOnlineCriteriaInstance({
908
1079
  onlineMonitorStatusId: args.onlineMonitorStatusId,
@@ -915,14 +1086,25 @@ const highDiskUsageTemplate: KubernetesAlertTemplate = {
915
1086
  };
916
1087
 
917
1088
  const daemonSetUnavailableTemplate: KubernetesAlertTemplate = {
1089
+ /*
1090
+ * The `id` still says "unavailable" and deliberately stays that way: it
1091
+ * is the stable key the recommendation catalog and the
1092
+ * already-created-monitor diff match on
1093
+ * (MonitorRecommendationCatalog.buildRecommendationId), so renaming it
1094
+ * would orphan every monitor a user already created from this card.
1095
+ * Everything the user actually READS now says what the metric measures:
1096
+ * KubernetesMetricCatalog defines `k8s.daemonset.misscheduled_nodes` as
1097
+ * "nodes running a daemon pod that should not be running one", which is
1098
+ * the opposite of "nodes missing the daemon pod".
1099
+ */
918
1100
  id: "k8s-daemonset-unavailable",
919
- name: "DaemonSet Unavailable Nodes",
1101
+ name: "DaemonSet Misscheduled Nodes",
920
1102
  description:
921
- "Alert when a DaemonSet has unavailable nodes where the daemon pod should be running.",
1103
+ "Alert when a DaemonSet is running daemon pods on nodes that no longer match its node selector, affinity or taint tolerations. k8s.daemonset.misscheduled_nodes counts nodes that ARE running the pod but should NOT be — it is not the count of nodes that are missing the pod.",
922
1104
  category: "Workload",
923
1105
  severity: "Warning",
924
1106
  getMonitorStep: (args: KubernetesAlertTemplateArgs): MonitorStep => {
925
- const metricAlias: string = "unavailable_nodes";
1107
+ const metricAlias: string = "misscheduled_nodes";
926
1108
 
927
1109
  return buildKubernetesMonitorStep({
928
1110
  kubernetesMonitor: buildKubernetesMonitorConfig({
@@ -937,7 +1119,10 @@ const daemonSetUnavailableTemplate: KubernetesAlertTemplate = {
937
1119
  * one has to own its own alert instead of dedupeing behind
938
1120
  * whichever DaemonSet in the cluster misscheduled first.
939
1121
  */
940
- groupByAttributeKey: "resource.k8s.daemonset.name",
1122
+ groupByAttributeKeys: [
1123
+ "resource.k8s.namespace.name",
1124
+ "resource.k8s.daemonset.name",
1125
+ ],
941
1126
  }),
942
1127
  offlineCriteriaInstance: buildOfflineCriteriaInstance({
943
1128
  offlineMonitorStatusId: args.offlineMonitorStatusId,
@@ -947,11 +1132,11 @@ const daemonSetUnavailableTemplate: KubernetesAlertTemplate = {
947
1132
  metricAlias,
948
1133
  filterType: FilterType.GreaterThan,
949
1134
  value: 0,
950
- incidentTitle: `[K8s] DaemonSet Unavailable Nodes - ${args.monitorName}`,
951
- incidentDescription: `A DaemonSet has nodes where the daemon pod is not running as expected. This indicates misscheduled or unavailable daemon pods, which may affect cluster-wide services like logging, monitoring, or networking.`,
952
- criteriaName: "DaemonSet Unavailable - Misscheduled > 0",
1135
+ incidentTitle: `[K8s] DaemonSet Misscheduled Nodes - ${args.monitorName}`,
1136
+ incidentDescription: `A DaemonSet has daemon pods running on nodes that should not be running them, sustained across the monitoring window. This is usually a stale node selector, affinity rule or taint toleration left behind after a node pool change — the pods were scheduled under the old rules and have not been evicted. It is NOT the same as a DaemonSet missing from nodes that need it. The affected namespace and DaemonSet are named under "Affected resource" below, with the describe command under "Start here"; compare its spec against the current node labels and taints.`,
1137
+ criteriaName: "DaemonSet Misscheduled Nodes > 0",
953
1138
  criteriaDescription:
954
- "Triggers when a DaemonSet has nodes where daemon pods are not properly scheduled.",
1139
+ "Triggers when a DaemonSet reports at least one misscheduled node for every sample in the monitoring window.",
955
1140
  }),
956
1141
  onlineCriteriaInstance: buildOnlineCriteriaInstance({
957
1142
  onlineMonitorStatusId: args.onlineMonitorStatusId,
@@ -978,7 +1163,7 @@ const nodeCpuRequestUtilizationTemplate: KubernetesAlertTemplate = {
978
1163
  clusterIdentifier: args.clusterIdentifier,
979
1164
  numeratorMetricName: "k8s.container.cpu_request",
980
1165
  denominatorMetricName: "k8s.node.allocatable_cpu",
981
- groupByAttributeKey: "resource.k8s.node.name",
1166
+ groupByAttributeKeys: ["resource.k8s.node.name"],
982
1167
  numeratorAlias: "req_cpu",
983
1168
  denominatorAlias: "alloc_cpu",
984
1169
  resultAlias: metricAlias,
@@ -995,7 +1180,7 @@ const nodeCpuRequestUtilizationTemplate: KubernetesAlertTemplate = {
995
1180
  filterType: FilterType.GreaterThan,
996
1181
  value: 90,
997
1182
  incidentTitle: `[K8s] High Node CPU Request Commitment (>90%) - ${args.monitorName}`,
998
- incidentDescription: `A node's committed CPU requests have exceeded 90% of its allocatable CPU. The node is nearly full from a scheduling standpoint and may be unable to place new pods, even if current CPU usage is low. Check the root cause for the specific node and its top CPU-requesting workloads.`,
1183
+ incidentDescription: `A node's committed CPU requests have exceeded 90% of its allocatable CPU. The node is nearly full from a scheduling standpoint and may be unable to place new pods, even if current CPU usage is low. The affected node is named under "Affected resource" below; use the kubectl commands under "Start here" to list the pods it hosts and their CPU requests.`,
999
1184
  criteriaName: "High CPU Request Commitment - Utilization > 90%",
1000
1185
  criteriaDescription:
1001
1186
  "Triggers when any node's summed container CPU requests exceed 90% of its allocatable CPU.",
@@ -1025,7 +1210,7 @@ const nodeMemoryRequestUtilizationTemplate: KubernetesAlertTemplate = {
1025
1210
  clusterIdentifier: args.clusterIdentifier,
1026
1211
  numeratorMetricName: "k8s.container.memory_request",
1027
1212
  denominatorMetricName: "k8s.node.allocatable_memory",
1028
- groupByAttributeKey: "resource.k8s.node.name",
1213
+ groupByAttributeKeys: ["resource.k8s.node.name"],
1029
1214
  numeratorAlias: "req_mem",
1030
1215
  denominatorAlias: "alloc_mem",
1031
1216
  resultAlias: metricAlias,
@@ -1042,7 +1227,7 @@ const nodeMemoryRequestUtilizationTemplate: KubernetesAlertTemplate = {
1042
1227
  filterType: FilterType.GreaterThan,
1043
1228
  value: 90,
1044
1229
  incidentTitle: `[K8s] High Node Memory Request Commitment (>90%) - ${args.monitorName}`,
1045
- incidentDescription: `A node's committed memory requests have exceeded 90% of its allocatable memory. The node is nearly full from a scheduling standpoint and may be unable to place new pods, even if current memory usage is low. Check the root cause for the specific node and its top memory-requesting workloads.`,
1230
+ incidentDescription: `A node's committed memory requests have exceeded 90% of its allocatable memory. The node is nearly full from a scheduling standpoint and may be unable to place new pods, even if current memory usage is low. The affected node is named under "Affected resource" below; use the kubectl commands under "Start here" to list the pods it hosts and their memory requests.`,
1046
1231
  criteriaName: "High Memory Request Commitment - Utilization > 90%",
1047
1232
  criteriaDescription:
1048
1233
  "Triggers when any node's summed container memory requests exceed 90% of its allocatable memory.",
@@ -1071,8 +1256,13 @@ const nodeMemoryRequestUtilizationTemplate: KubernetesAlertTemplate = {
1071
1256
  * hops from the cause. These catch the START: the HPA running out of
1072
1257
  * headroom, and the containers pinned at their own limits.
1073
1258
  *
1074
- * All three are per-series ratios, grouped by the ClickHouse-stored
1075
- * `resource.`-prefixed attribute (see buildKubernetesRatioMonitorConfig).
1259
+ * All three are grouped by the ClickHouse-stored `resource.`-prefixed
1260
+ * attribute. The HPA one is a ratio (there is no ready-made
1261
+ * current/max series); the two pod-limit ones read the kubeletstats
1262
+ * receiver's own `k8s.pod.*_limit_utilization` family directly, which is
1263
+ * enabled by default in the shipped chart and — unlike a hand-built ratio
1264
+ * against `k8s.container.*_limit` — divides by the SUM of a pod's
1265
+ * container limits rather than their mean.
1076
1266
  */
1077
1267
 
1078
1268
  const hpaAtMaxReplicasTemplate: KubernetesAlertTemplate = {
@@ -1090,7 +1280,10 @@ const hpaAtMaxReplicasTemplate: KubernetesAlertTemplate = {
1090
1280
  clusterIdentifier: args.clusterIdentifier,
1091
1281
  numeratorMetricName: "k8s.hpa.current_replicas",
1092
1282
  denominatorMetricName: "k8s.hpa.max_replicas",
1093
- groupByAttributeKey: "resource.k8s.hpa.name",
1283
+ groupByAttributeKeys: [
1284
+ "resource.k8s.namespace.name",
1285
+ "resource.k8s.hpa.name",
1286
+ ],
1094
1287
  numeratorAlias: "current_replicas",
1095
1288
  denominatorAlias: "max_replicas",
1096
1289
  resultAlias: metricAlias,
@@ -1116,7 +1309,7 @@ const hpaAtMaxReplicasTemplate: KubernetesAlertTemplate = {
1116
1309
  filterType: FilterType.GreaterThanOrEqualTo,
1117
1310
  value: 90,
1118
1311
  incidentTitle: `[K8s] HPA Saturated at Max Replicas (>=90%) - ${args.monitorName}`,
1119
- incidentDescription: `A HorizontalPodAutoscaler is running at 90% or more of its maxReplicas and has effectively no scaling headroom left. Any further load cannot be absorbed by scaling out, so it will surface as latency and errors instead. Check whether the workload is genuinely at capacity or whether its per-pod CPU/memory limits are set too low — an under-resourced pod gets throttled or OOMKilled, which inflates the metric the HPA scales on and drives it to the ceiling. Check the root cause for the specific HPA, its target workload, and current vs max replicas.`,
1312
+ incidentDescription: `A HorizontalPodAutoscaler is running at 90% or more of its maxReplicas and has effectively no scaling headroom left. Any further load cannot be absorbed by scaling out, so it will surface as latency and errors instead. Check whether the workload is genuinely at capacity or whether its per-pod CPU/memory limits are set too low — an under-resourced pod gets throttled or OOMKilled, which inflates the metric the HPA scales on and drives it to the ceiling. The affected namespace and HorizontalPodAutoscaler are named under "Affected resource" below, with the describe command under "Start here" for its target and current-vs-max replicas.`,
1120
1313
  criteriaName: "HPA Saturation - Current/Max Replicas >= 90%",
1121
1314
  criteriaDescription:
1122
1315
  "Triggers when any HPA's current replica count reaches 90% or more of its configured maxReplicas.",
@@ -1135,49 +1328,54 @@ const podMemoryLimitSaturationTemplate: KubernetesAlertTemplate = {
1135
1328
  id: "k8s-pod-memory-limit-saturation",
1136
1329
  name: "Pod Memory Saturating Container Limit",
1137
1330
  description:
1138
- "Alert when a pod's memory usage exceeds 90% of its configured container memory limit the state immediately preceding an OOMKill. Computed per pod as k8s.pod.memory.usage ÷ k8s.container.memory_limit × 100 (both bytes). This is the cause-side signal for CrashLoopBackOff and restart storms: a limit set too low shows up here minutes before the container is killed.",
1331
+ "Alert when a pod is using more than 90% of its container memory limit, read straight from the kubeletstats receiver's own k8s.pod.memory_limit_utilization which divides the pod's usage by the SUM of its containers' limits, so a pod with a sidecar is measured correctly. Note the kubelet's pod memory figure includes reclaimable page cache, so a file-heavy workload can sit high here without ever being OOMKilled: treat this as approaching the limit, not about to be killed.",
1139
1332
  category: "Workload",
1140
1333
  severity: "Critical",
1141
1334
  getMonitorStep: (args: KubernetesAlertTemplateArgs): MonitorStep => {
1142
1335
  const metricAlias: string = "pod_memory_limit_saturation";
1143
1336
 
1144
1337
  return buildKubernetesMonitorStep({
1145
- kubernetesMonitor: buildKubernetesRatioMonitorConfig({
1338
+ kubernetesMonitor: buildKubernetesMonitorConfig({
1146
1339
  clusterIdentifier: args.clusterIdentifier,
1147
- numeratorMetricName: "k8s.pod.memory.usage",
1148
- denominatorMetricName: "k8s.container.memory_limit",
1149
- groupByAttributeKey: "resource.k8s.pod.name",
1150
- numeratorAlias: "used_mem",
1151
- denominatorAlias: "limit_mem",
1152
- resultAlias: metricAlias,
1153
- resultLegend: "Pod Memory vs Limit (%)",
1340
+ /*
1341
+ * The agent enables this family by DEFAULT:
1342
+ * HelmChart/Public/kubernetes-agent/templates/configmap-daemonset.yaml
1343
+ * ("Saturation metrics — CPU/memory as a percentage of pod
1344
+ * limit/request") turns on k8s.pod.memory_limit_utilization inside
1345
+ * the existing kubeletstats receiver, gated on
1346
+ * `kubeletstats.utilizationMetrics.enabled`, which values.yaml sets
1347
+ * to `true`. No extra scrape.
1348
+ *
1349
+ * It replaces a cross-receiver ratio of `k8s.pod.memory.usage`
1350
+ * (kubeletstats, one series per POD) over
1351
+ * `k8s.container.memory_limit` (k8s_cluster, one series per
1352
+ * CONTAINER), which this template's own comment conceded took the
1353
+ * MEAN container limit for a multi-container pod — so any pod with
1354
+ * a sidecar over-reported its saturation by roughly its container
1355
+ * count — and which joined its two halves by series fingerprint
1356
+ * across two independent scrape cycles, a join that fails silently
1357
+ * rather than loudly.
1358
+ */
1359
+ metricName: "k8s.pod.memory_limit_utilization",
1360
+ metricAlias,
1361
+ /*
1362
+ * kubeletstats reports this family with UCUM unit "1" (a 0-1
1363
+ * fraction). Declaring "%" here makes MetricResultUnitConverter
1364
+ * scale it to 0-100 before the threshold below is compared, and
1365
+ * costs nothing if a collector ever reports it as "%" already.
1366
+ */
1367
+ legendUnit: "%",
1154
1368
  resourceScope: KubernetesResourceScope.Pod,
1155
1369
  rollingTime: RollingTime.Past5Minutes,
1156
1370
  /*
1157
- * Avg, deliberately and the one case in this file where the two
1158
- * sides have different series shapes, so the trade-off is worth
1159
- * stating.
1160
- *
1161
- * Numerator (k8s.pod.memory.usage, kubeletstats) is ONE series per
1162
- * pod. Denominator (k8s.container.memory_limit, k8s_cluster) is one
1163
- * series per CONTAINER, so a multi-container pod contributes
1164
- * several.
1165
- *
1166
- * Sum is definitively wrong here: the two metrics ride different
1167
- * receivers on independent scrape cycles, so the scrape multiple
1168
- * would not cancel. Avg is exact for single-container pods (the
1169
- * overwhelming majority, and the case this template exists for).
1170
- *
1171
- * For multi-container pods Avg takes the MEAN container limit
1172
- * rather than their sum, so the ratio over-reports and the alert
1173
- * fires early. That is the safe direction for an "OOMKill is
1174
- * imminent" warning — a false early page beats a missed kill — but
1175
- * it is a real caveat, not a rounding detail. A per-container
1176
- * variant needs a container-scoped usage metric to pair against
1177
- * (`container.memory.usage`), which the shipped catalog does not
1178
- * carry today.
1371
+ * ONE series per pod, so Max is "the worst sample in this minute"
1372
+ * rather than a mean that hides a spike against the limit.
1179
1373
  */
1180
- aggregationType: MetricsAggregationType.Avg,
1374
+ aggregationType: MetricsAggregationType.Max,
1375
+ groupByAttributeKeys: [
1376
+ "resource.k8s.namespace.name",
1377
+ "resource.k8s.pod.name",
1378
+ ],
1181
1379
  }),
1182
1380
  offlineCriteriaInstance: buildOfflineCriteriaInstance({
1183
1381
  offlineMonitorStatusId: args.offlineMonitorStatusId,
@@ -1188,7 +1386,7 @@ const podMemoryLimitSaturationTemplate: KubernetesAlertTemplate = {
1188
1386
  filterType: FilterType.GreaterThan,
1189
1387
  value: 90,
1190
1388
  incidentTitle: `[K8s] Pod Memory Saturating Container Limit (>90%) - ${args.monitorName}`,
1191
- incidentDescription: `A pod's memory usage has exceeded 90% of its configured container memory limit. The kubelet OOMKills a container the moment it crosses its limit, so this is the state immediately preceding a restart and, if the workload sits behind an autoscaler, the start of a restart/scale-up loop. Either the limit is set too low for the workload's real footprint or the workload has a memory leak. Check the root cause for the specific pod, its limit, and its usage trend.`,
1389
+ incidentDescription: `A pod is using more than 90% of its container memory limit, sustained across the monitoring window. The kubelet's pod memory figure includes page cache the kernel reclaims under pressure, so this is "approaching the limit" rather than a guarantee that an OOMKill is imminent but a pod that stays here is either under-limited for its real working set or leaking, and it is the cause-side signal for the CrashLoopBackOff and restart storms that follow. The affected namespace and pod are named under "Affected resource" below, with the kubectl commands to read its limits and current usage under "Start here".`,
1192
1390
  criteriaName: "Pod Memory Saturation - Usage/Limit > 90%",
1193
1391
  criteriaDescription:
1194
1392
  "Triggers when any pod's memory usage exceeds 90% of its container memory limit.",
@@ -1207,33 +1405,26 @@ const podCpuLimitSaturationTemplate: KubernetesAlertTemplate = {
1207
1405
  id: "k8s-pod-cpu-limit-saturation",
1208
1406
  name: "Pod CPU Saturating Container Limit",
1209
1407
  description:
1210
- "Alert when a pod's CPU usage exceeds 90% of its configured container CPU limit — the point at which the kernel's CFS quota starts throttling it. Computed per pod as k8s.pod.cpu.utilization ÷ k8s.container.cpu_limit × 100; both are CPU cores, so this is a true percentage (k8s.pod.cpu.utilization is a misnamed cores gauge, not a percent). A throttled pod gets slower, not louder — behind an HPA that reads CPU, throttling drives the replica count up while every pod stays equally starved.",
1408
+ "Alert when a pod is using more than 90% of its container CPU limit — the point at which the kernel's CFS quota starts throttling it. Read from the kubeletstats receiver's own k8s.pod.cpu_limit_utilization, which divides the pod's CPU by the SUM of its containers' limits, so a pod with a sidecar is not measured against the mean of its containers' limits. A throttled pod gets slower, not louder — behind an HPA that reads CPU, throttling drives the replica count up while every pod stays equally starved.",
1211
1409
  category: "Workload",
1212
1410
  severity: "Warning",
1213
1411
  getMonitorStep: (args: KubernetesAlertTemplateArgs): MonitorStep => {
1214
1412
  const metricAlias: string = "pod_cpu_limit_saturation";
1215
1413
 
1216
1414
  return buildKubernetesMonitorStep({
1217
- kubernetesMonitor: buildKubernetesRatioMonitorConfig({
1415
+ kubernetesMonitor: buildKubernetesMonitorConfig({
1218
1416
  clusterIdentifier: args.clusterIdentifier,
1219
- numeratorMetricName: "k8s.pod.cpu.utilization",
1220
- denominatorMetricName: "k8s.container.cpu_limit",
1221
- groupByAttributeKey: "resource.k8s.pod.name",
1222
- numeratorAlias: "used_cpu",
1223
- denominatorAlias: "limit_cpu",
1224
- resultAlias: metricAlias,
1225
- resultLegend: "Pod CPU vs Limit (%)",
1417
+ // See the memory template above for why this replaces the ratio.
1418
+ metricName: "k8s.pod.cpu_limit_utilization",
1419
+ metricAlias,
1420
+ legendUnit: "%",
1226
1421
  resourceScope: KubernetesResourceScope.Pod,
1227
1422
  rollingTime: RollingTime.Past5Minutes,
1228
- /*
1229
- * Avg, for the same reason as the memory template above: ONE
1230
- * numerator series per pod (kubeletstats) against a per-container
1231
- * denominator (k8s_cluster) on an independent scrape cycle. Exact
1232
- * for single-container pods; over-reports (fires early) for
1233
- * multi-container pods. See that template's note for the full
1234
- * trade-off.
1235
- */
1236
- aggregationType: MetricsAggregationType.Avg,
1423
+ aggregationType: MetricsAggregationType.Max,
1424
+ groupByAttributeKeys: [
1425
+ "resource.k8s.namespace.name",
1426
+ "resource.k8s.pod.name",
1427
+ ],
1237
1428
  }),
1238
1429
  offlineCriteriaInstance: buildOfflineCriteriaInstance({
1239
1430
  offlineMonitorStatusId: args.offlineMonitorStatusId,