@oneuptime/common 11.6.1 → 11.6.2

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 (397) hide show
  1. package/Models/AnalyticsModels/Index.ts +4 -0
  2. package/Models/AnalyticsModels/KubernetesCostAllocation.ts +842 -0
  3. package/Models/AnalyticsModels/NetworkFlow.ts +54 -0
  4. package/Models/AnalyticsModels/SloHistory.ts +240 -0
  5. package/Models/DatabaseModels/Index.ts +20 -0
  6. package/Models/DatabaseModels/NetworkDevice.ts +453 -6
  7. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +7 -6
  8. package/Models/DatabaseModels/NetworkEndpoint.ts +753 -0
  9. package/Models/DatabaseModels/NetworkSite.ts +1155 -0
  10. package/Models/DatabaseModels/NetworkSiteAssignmentRule.ts +517 -0
  11. package/Models/DatabaseModels/NetworkSiteLink.ts +611 -0
  12. package/Models/DatabaseModels/NetworkSiteStatusTimeline.ts +520 -0
  13. package/Models/DatabaseModels/NetworkSiteType.ts +499 -0
  14. package/Models/DatabaseModels/ServiceLevelObjective.ts +1106 -0
  15. package/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.ts +762 -0
  16. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.ts +444 -0
  17. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.ts +443 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.ts +359 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.ts +48 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.ts +65 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.ts +88 -0
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.ts +391 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
  24. package/Server/Services/AnalyticsDatabaseService.ts +25 -9
  25. package/Server/Services/Index.ts +24 -0
  26. package/Server/Services/KubernetesCostAllocationService.ts +14 -0
  27. package/Server/Services/MetricService.ts +21 -2
  28. package/Server/Services/MonitorService.ts +22 -0
  29. package/Server/Services/NetworkDeviceService.ts +438 -2
  30. package/Server/Services/NetworkEndpointService.ts +414 -0
  31. package/Server/Services/NetworkSiteAssignmentRuleService.ts +98 -0
  32. package/Server/Services/NetworkSiteLinkService.ts +10 -0
  33. package/Server/Services/NetworkSiteService.ts +1254 -0
  34. package/Server/Services/NetworkSiteStatusTimelineService.ts +10 -0
  35. package/Server/Services/NetworkSiteTypeService.ts +10 -0
  36. package/Server/Services/ProjectService.ts +122 -2
  37. package/Server/Services/ServiceLevelObjectiveBurnRateRuleService.ts +457 -0
  38. package/Server/Services/ServiceLevelObjectiveOwnerTeamService.ts +10 -0
  39. package/Server/Services/ServiceLevelObjectiveOwnerUserService.ts +10 -0
  40. package/Server/Services/ServiceLevelObjectiveService.ts +677 -0
  41. package/Server/Services/SloHistoryService.ts +101 -0
  42. package/Server/Services/UserNotificationSettingService.ts +37 -0
  43. package/Server/Types/AnalyticsDatabase/AggregateBy.ts +9 -0
  44. package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +15 -0
  45. package/Server/Utils/AnalyticsDatabase/Statement.ts +39 -3
  46. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +87 -48
  47. package/Server/Utils/Memory.ts +9 -1
  48. package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +190 -12
  49. package/Server/Utils/Monitor/Data/OuiVendors.json +6920 -0
  50. package/Server/Utils/Monitor/DnsResolutionCache.ts +129 -0
  51. package/Server/Utils/Monitor/MonitorResource.ts +4 -30
  52. package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +214 -39
  53. package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +343 -0
  54. package/Server/Utils/Monitor/NetworkDeviceWalkUtil.ts +251 -0
  55. package/Server/Utils/Monitor/NetworkInventoryUtil.ts +176 -142
  56. package/Server/Utils/Monitor/OuiLookupUtil.ts +49 -0
  57. package/Server/Utils/Monitor/SnmpInterfaceRateUtil.ts +17 -13
  58. package/Server/Utils/WhatsAppTemplateUtil.ts +7 -3
  59. package/Tests/Models/AnalyticsModels/KubernetesCostAllocation.test.ts +135 -0
  60. package/Tests/Models/NetworkSiteHierarchy.test.ts +134 -0
  61. package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +239 -0
  62. package/Tests/Server/Services/KubernetesCostAllocationAggregate.test.ts +338 -0
  63. package/Tests/Server/Services/MetricServiceAggregate.test.ts +142 -0
  64. package/Tests/Server/Services/NetworkDeviceSiteAssignment.test.ts +484 -0
  65. package/Tests/Server/Services/NetworkEndpointServiceUpsert.test.ts +686 -0
  66. package/Tests/Server/Services/NetworkSiteAssignmentRuleService.test.ts +185 -0
  67. package/Tests/Server/Services/NetworkSiteService.test.ts +1354 -0
  68. package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleService.test.ts +1313 -0
  69. package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +1988 -0
  70. package/Tests/Server/Utils/AnalyticsDatabase/Statement.test.ts +22 -0
  71. package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +404 -0
  72. package/Tests/Server/Utils/Encryption.test.ts +70 -0
  73. package/Tests/Server/Utils/FileAttachmentMarkdownUtil.test.ts +225 -0
  74. package/Tests/Server/Utils/JsonWebToken.test.ts +175 -0
  75. package/Tests/Server/Utils/LocalFile.test.ts +258 -0
  76. package/Tests/Server/Utils/Memory.test.ts +213 -0
  77. package/Tests/Server/Utils/Monitor/Criteria/LogMonitorCriteria.test.ts +30 -0
  78. package/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.ts +385 -0
  79. package/Tests/Server/Utils/Monitor/DnsResolutionCache.test.ts +194 -0
  80. package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +155 -0
  81. package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +600 -0
  82. package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +151 -124
  83. package/Tests/Server/Utils/Monitor/SnmpInterfaceRateUtil.test.ts +496 -0
  84. package/Tests/Server/Utils/MonitorCriteriaDataExtractor.test.ts +175 -0
  85. package/Tests/Server/Utils/MonitorCriteriaMessageFormatter.test.ts +282 -0
  86. package/Tests/Server/Utils/OuiLookupUtil.test.ts +59 -0
  87. package/Tests/Server/Utils/SeriesResourceLabels.test.ts +117 -0
  88. package/Tests/Server/Utils/StackTraceParser.test.ts +370 -0
  89. package/Tests/Server/Utils/Stream.test.ts +87 -0
  90. package/Tests/Server/Utils/ValidateGlobalProviderProjectTeams.test.ts +221 -0
  91. package/Tests/Server/Utils/WhatsAppTemplateUtil.test.ts +199 -0
  92. package/Tests/Types/Database/CompareOperatorWireSerialization.test.ts +33 -0
  93. package/Tests/Types/Email.test.ts +198 -0
  94. package/Tests/Types/Kubernetes/KubernetesObjectParser.test.ts +177 -0
  95. package/Tests/Types/Log/LogQueryToFilter.test.ts +111 -0
  96. package/Tests/Types/Monitor/MonitorStepNetworkDeviceMonitor.test.ts +141 -1
  97. package/Tests/Types/Monitor/MonitorType.test.ts +59 -1
  98. package/Tests/Types/Monitor/NetworkDeviceAlertPack.test.ts +97 -0
  99. package/Tests/Types/Monitor/SnmpEndpointDiscovery.test.ts +151 -0
  100. package/Tests/Types/Monitor/SnmpVendorTemplate.test.ts +110 -6
  101. package/Tests/Types/NetworkSite/DefaultNetworkSiteType.test.ts +129 -0
  102. package/Tests/Types/SerializableObjectDictionary.test.ts +166 -0
  103. package/Tests/Types/Time/RangeStartAndEndDateTime.test.ts +98 -0
  104. package/Tests/Types/WebsiteRequest.test.ts +230 -0
  105. package/Tests/UI/Components/EntityFilterRoundTrip.test.tsx +103 -0
  106. package/Tests/UI/Components/ModelTable/BaseModelTableUrlState.test.tsx +612 -0
  107. package/Tests/UI/Components/ModelTable/FilterDataToQuery.test.ts +275 -0
  108. package/Tests/UI/Utils/LogExport.test.ts +159 -0
  109. package/Tests/UI/Utils/Navigation.test.ts +183 -0
  110. package/Tests/UI/Utils/TableFilterUrlState.test.ts +539 -0
  111. package/Tests/UI/Utils/TableViewUrlState.test.ts +272 -0
  112. package/Tests/Utils/Base64.test.ts +51 -0
  113. package/Tests/Utils/Boolean.test.ts +76 -0
  114. package/Tests/Utils/Crypto.test.ts +48 -0
  115. package/Tests/Utils/Dashboard/DashboardSloComponent.test.ts +259 -0
  116. package/Tests/Utils/Dashboard/ModelQueryVariableInterpolation.test.ts +162 -0
  117. package/Tests/Utils/Enum.test.ts +54 -0
  118. package/Tests/Utils/IpCanonicalUtil.test.ts +85 -0
  119. package/Tests/Utils/Metrics/MetricSeriesFingerprint.test.ts +160 -0
  120. package/Tests/Utils/Monitor/EndpointAttachmentUtil.test.ts +836 -0
  121. package/Tests/Utils/Monitor/MonitorMetricType.test.ts +218 -0
  122. package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +447 -0
  123. package/Tests/Utils/NetworkSite/CidrMatchUtil.test.ts +440 -0
  124. package/Tests/Utils/NetworkSite/MaterializedPathUtil.test.ts +205 -0
  125. package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +221 -0
  126. package/Tests/Utils/NetworkSite/SiteUptimeUtil.test.ts +283 -0
  127. package/Tests/Utils/ObjectUtil.test.ts +30 -0
  128. package/Tests/Utils/Slo/SloStatusColor.test.ts +89 -0
  129. package/Tests/Utils/Slo/SloUtil.test.ts +1980 -0
  130. package/Tests/Utils/Slo/SloWidgetFormat.test.ts +605 -0
  131. package/Tests/Utils/TechStack.test.ts +50 -0
  132. package/Tests/Utils/Traces/CriticalPath.test.ts +178 -0
  133. package/Types/AnalyticsDatabase/AnalyticsTableName.ts +10 -0
  134. package/Types/BaseDatabase/EqualTo.ts +9 -1
  135. package/Types/BaseDatabase/EqualToOrNull.ts +9 -1
  136. package/Types/BaseDatabase/NotEqual.ts +9 -1
  137. package/Types/Dashboard/DashboardComponentType.ts +1 -0
  138. package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +1 -0
  139. package/Types/Dashboard/DashboardComponents/DashboardSloComponent.ts +42 -0
  140. package/Types/Dashboard/DashboardTemplates.ts +214 -0
  141. package/Types/Email/EmailTemplateType.ts +2 -0
  142. package/Types/Kubernetes/KubernetesCostIngest.ts +79 -0
  143. package/Types/Monitor/CriteriaFilter.ts +9 -0
  144. package/Types/Monitor/MonitorStep.ts +5 -8
  145. package/Types/Monitor/MonitorStepNetworkDeviceMonitor.ts +27 -5
  146. package/Types/Monitor/MonitorType.ts +15 -5
  147. package/Types/Monitor/SnmpMonitor/ArpEntry.ts +14 -0
  148. package/Types/Monitor/SnmpMonitor/FdbEntry.ts +18 -0
  149. package/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.ts +10 -3
  150. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +31 -5
  151. package/Types/Monitor/SnmpMonitor/SnmpMonitorResponse.ts +12 -0
  152. package/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.ts +231 -3
  153. package/Types/NetworkSite/DefaultNetworkSiteType.ts +20 -0
  154. package/Types/NotificationSetting/NotificationSettingEventType.ts +4 -0
  155. package/Types/Permission.ts +449 -0
  156. package/Types/ServiceLevelObjective/SliType.ts +6 -0
  157. package/Types/ServiceLevelObjective/SloMultiMonitorMode.ts +6 -0
  158. package/Types/ServiceLevelObjective/SloStatus.ts +9 -0
  159. package/Types/ServiceLevelObjective/SloWindowType.ts +6 -0
  160. package/Types/Telemetry/ServiceType.ts +1 -0
  161. package/UI/Components/Filters/EntityFilter.tsx +16 -0
  162. package/UI/Components/Filters/FilterViewer.tsx +22 -5
  163. package/UI/Components/List/List.tsx +8 -0
  164. package/UI/Components/ModelTable/BaseModelTable.tsx +309 -106
  165. package/UI/Components/ModelTable/FilterDataToQuery.ts +172 -0
  166. package/UI/Components/Navbar/NavBar.tsx +16 -2
  167. package/UI/Components/Navbar/NavBarMenuModal.tsx +3 -3
  168. package/UI/Utils/Navigation.ts +10 -0
  169. package/UI/Utils/TableFilterUrlState.ts +204 -17
  170. package/UI/Utils/TableViewUrlState.ts +165 -0
  171. package/Utils/Dashboard/Components/DashboardSloComponent.ts +114 -0
  172. package/Utils/Dashboard/Components/Index.ts +7 -0
  173. package/Utils/IpCanonicalUtil.ts +134 -0
  174. package/Utils/Monitor/EndpointAttachmentUtil.ts +508 -0
  175. package/Utils/Monitor/NetworkTopologyUtil.ts +157 -5
  176. package/Utils/NetworkSite/CidrMatchUtil.ts +296 -0
  177. package/Utils/NetworkSite/MaterializedPathUtil.ts +115 -0
  178. package/Utils/NetworkSite/SiteStatusRollupUtil.ts +97 -0
  179. package/Utils/NetworkSite/SiteUptimeUtil.ts +111 -0
  180. package/Utils/Slo/SloStatusColor.ts +54 -0
  181. package/Utils/Slo/SloUtil.ts +637 -0
  182. package/Utils/Slo/SloWidgetFormat.ts +383 -0
  183. package/build/dist/Models/AnalyticsModels/Index.js +4 -0
  184. package/build/dist/Models/AnalyticsModels/Index.js.map +1 -1
  185. package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js +713 -0
  186. package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js.map +1 -0
  187. package/build/dist/Models/AnalyticsModels/NetworkFlow.js +44 -0
  188. package/build/dist/Models/AnalyticsModels/NetworkFlow.js.map +1 -1
  189. package/build/dist/Models/AnalyticsModels/SloHistory.js +215 -0
  190. package/build/dist/Models/AnalyticsModels/SloHistory.js.map +1 -0
  191. package/build/dist/Models/DatabaseModels/Index.js +20 -0
  192. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  193. package/build/dist/Models/DatabaseModels/NetworkDevice.js +458 -6
  194. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  195. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +0 -6
  196. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  197. package/build/dist/Models/DatabaseModels/NetworkEndpoint.js +779 -0
  198. package/build/dist/Models/DatabaseModels/NetworkEndpoint.js.map +1 -0
  199. package/build/dist/Models/DatabaseModels/NetworkSite.js +1180 -0
  200. package/build/dist/Models/DatabaseModels/NetworkSite.js.map +1 -0
  201. package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js +534 -0
  202. package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js.map +1 -0
  203. package/build/dist/Models/DatabaseModels/NetworkSiteLink.js +629 -0
  204. package/build/dist/Models/DatabaseModels/NetworkSiteLink.js.map +1 -0
  205. package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js +538 -0
  206. package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js.map +1 -0
  207. package/build/dist/Models/DatabaseModels/NetworkSiteType.js +522 -0
  208. package/build/dist/Models/DatabaseModels/NetworkSiteType.js.map +1 -0
  209. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js +1124 -0
  210. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js.map +1 -0
  211. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js +769 -0
  212. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js.map +1 -0
  213. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js +460 -0
  214. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js.map +1 -0
  215. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js +459 -0
  216. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js.map +1 -0
  217. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.js +130 -0
  218. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.js.map +1 -0
  219. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.js +31 -0
  220. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.js.map +1 -0
  221. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.js +36 -0
  222. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.js.map +1 -0
  223. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.js +49 -0
  224. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.js.map +1 -0
  225. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.js +140 -0
  226. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.js.map +1 -0
  227. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
  228. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  229. package/build/dist/Server/Services/AnalyticsDatabaseService.js +23 -6
  230. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  231. package/build/dist/Server/Services/Index.js +24 -0
  232. package/build/dist/Server/Services/Index.js.map +1 -1
  233. package/build/dist/Server/Services/KubernetesCostAllocationService.js +12 -0
  234. package/build/dist/Server/Services/KubernetesCostAllocationService.js.map +1 -0
  235. package/build/dist/Server/Services/MetricService.js +21 -3
  236. package/build/dist/Server/Services/MetricService.js.map +1 -1
  237. package/build/dist/Server/Services/MonitorService.js +19 -0
  238. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  239. package/build/dist/Server/Services/NetworkDeviceService.js +351 -1
  240. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  241. package/build/dist/Server/Services/NetworkEndpointService.js +319 -0
  242. package/build/dist/Server/Services/NetworkEndpointService.js.map +1 -0
  243. package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js +90 -0
  244. package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js.map +1 -0
  245. package/build/dist/Server/Services/NetworkSiteLinkService.js +9 -0
  246. package/build/dist/Server/Services/NetworkSiteLinkService.js.map +1 -0
  247. package/build/dist/Server/Services/NetworkSiteService.js +1038 -0
  248. package/build/dist/Server/Services/NetworkSiteService.js.map +1 -0
  249. package/build/dist/Server/Services/NetworkSiteStatusTimelineService.js +9 -0
  250. package/build/dist/Server/Services/NetworkSiteStatusTimelineService.js.map +1 -0
  251. package/build/dist/Server/Services/NetworkSiteTypeService.js +9 -0
  252. package/build/dist/Server/Services/NetworkSiteTypeService.js.map +1 -0
  253. package/build/dist/Server/Services/ProjectService.js +98 -2
  254. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  255. package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js +358 -0
  256. package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js.map +1 -0
  257. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js +9 -0
  258. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js.map +1 -0
  259. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js +9 -0
  260. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js.map +1 -0
  261. package/build/dist/Server/Services/ServiceLevelObjectiveService.js +582 -0
  262. package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -0
  263. package/build/dist/Server/Services/SloHistoryService.js +77 -0
  264. package/build/dist/Server/Services/SloHistoryService.js.map +1 -0
  265. package/build/dist/Server/Services/UserNotificationSettingService.js +20 -0
  266. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  267. package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js +9 -0
  268. package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js.map +1 -1
  269. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +15 -0
  270. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
  271. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js +31 -0
  272. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js.map +1 -1
  273. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +76 -48
  274. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  275. package/build/dist/Server/Utils/Memory.js +9 -1
  276. package/build/dist/Server/Utils/Memory.js.map +1 -1
  277. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +132 -10
  278. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
  279. package/build/dist/Server/Utils/Monitor/Data/OuiVendors.json +6920 -0
  280. package/build/dist/Server/Utils/Monitor/DnsResolutionCache.js +77 -0
  281. package/build/dist/Server/Utils/Monitor/DnsResolutionCache.js.map +1 -0
  282. package/build/dist/Server/Utils/Monitor/MonitorResource.js +21 -41
  283. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  284. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +152 -40
  285. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
  286. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +262 -0
  287. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -0
  288. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js +201 -0
  289. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js.map +1 -0
  290. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +152 -120
  291. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
  292. package/build/dist/Server/Utils/Monitor/OuiLookupUtil.js +44 -0
  293. package/build/dist/Server/Utils/Monitor/OuiLookupUtil.js.map +1 -0
  294. package/build/dist/Server/Utils/Monitor/SnmpInterfaceRateUtil.js +10 -10
  295. package/build/dist/Server/Utils/Monitor/SnmpInterfaceRateUtil.js.map +1 -1
  296. package/build/dist/Server/Utils/WhatsAppTemplateUtil.js +5 -0
  297. package/build/dist/Server/Utils/WhatsAppTemplateUtil.js.map +1 -1
  298. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +10 -0
  299. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -1
  300. package/build/dist/Types/BaseDatabase/EqualTo.js +9 -1
  301. package/build/dist/Types/BaseDatabase/EqualTo.js.map +1 -1
  302. package/build/dist/Types/BaseDatabase/EqualToOrNull.js +9 -1
  303. package/build/dist/Types/BaseDatabase/EqualToOrNull.js.map +1 -1
  304. package/build/dist/Types/BaseDatabase/NotEqual.js +9 -1
  305. package/build/dist/Types/BaseDatabase/NotEqual.js.map +1 -1
  306. package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
  307. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  308. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +1 -0
  309. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
  310. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloComponent.js +23 -0
  311. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloComponent.js.map +1 -0
  312. package/build/dist/Types/Dashboard/DashboardTemplates.js +205 -0
  313. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  314. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  315. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  316. package/build/dist/Types/Kubernetes/KubernetesCostIngest.js +21 -0
  317. package/build/dist/Types/Kubernetes/KubernetesCostIngest.js.map +1 -0
  318. package/build/dist/Types/Monitor/CriteriaFilter.js +1 -0
  319. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  320. package/build/dist/Types/Monitor/MonitorStep.js +5 -5
  321. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  322. package/build/dist/Types/Monitor/MonitorStepNetworkDeviceMonitor.js +8 -0
  323. package/build/dist/Types/Monitor/MonitorStepNetworkDeviceMonitor.js.map +1 -1
  324. package/build/dist/Types/Monitor/MonitorType.js +15 -5
  325. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  326. package/build/dist/Types/Monitor/SnmpMonitor/ArpEntry.js +2 -0
  327. package/build/dist/Types/Monitor/SnmpMonitor/ArpEntry.js.map +1 -0
  328. package/build/dist/Types/Monitor/SnmpMonitor/FdbEntry.js +2 -0
  329. package/build/dist/Types/Monitor/SnmpMonitor/FdbEntry.js.map +1 -0
  330. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js +9 -3
  331. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js.map +1 -1
  332. package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js +217 -3
  333. package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js.map +1 -1
  334. package/build/dist/Types/NetworkSite/DefaultNetworkSiteType.js +21 -0
  335. package/build/dist/Types/NetworkSite/DefaultNetworkSiteType.js.map +1 -0
  336. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js +3 -0
  337. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js.map +1 -1
  338. package/build/dist/Types/Permission.js +409 -0
  339. package/build/dist/Types/Permission.js.map +1 -1
  340. package/build/dist/Types/ServiceLevelObjective/SliType.js +7 -0
  341. package/build/dist/Types/ServiceLevelObjective/SliType.js.map +1 -0
  342. package/build/dist/Types/ServiceLevelObjective/SloMultiMonitorMode.js +7 -0
  343. package/build/dist/Types/ServiceLevelObjective/SloMultiMonitorMode.js.map +1 -0
  344. package/build/dist/Types/ServiceLevelObjective/SloStatus.js +10 -0
  345. package/build/dist/Types/ServiceLevelObjective/SloStatus.js.map +1 -0
  346. package/build/dist/Types/ServiceLevelObjective/SloWindowType.js +7 -0
  347. package/build/dist/Types/ServiceLevelObjective/SloWindowType.js.map +1 -0
  348. package/build/dist/Types/Telemetry/ServiceType.js +1 -0
  349. package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
  350. package/build/dist/UI/Components/Filters/EntityFilter.js +15 -0
  351. package/build/dist/UI/Components/Filters/EntityFilter.js.map +1 -1
  352. package/build/dist/UI/Components/Filters/FilterViewer.js +19 -4
  353. package/build/dist/UI/Components/Filters/FilterViewer.js.map +1 -1
  354. package/build/dist/UI/Components/List/List.js +1 -1
  355. package/build/dist/UI/Components/List/List.js.map +1 -1
  356. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +235 -89
  357. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  358. package/build/dist/UI/Components/ModelTable/FilterDataToQuery.js +96 -0
  359. package/build/dist/UI/Components/ModelTable/FilterDataToQuery.js.map +1 -0
  360. package/build/dist/UI/Components/Navbar/NavBar.js +14 -2
  361. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  362. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +3 -2
  363. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  364. package/build/dist/UI/Utils/Navigation.js +9 -0
  365. package/build/dist/UI/Utils/Navigation.js.map +1 -1
  366. package/build/dist/UI/Utils/TableFilterUrlState.js +159 -15
  367. package/build/dist/UI/Utils/TableFilterUrlState.js.map +1 -1
  368. package/build/dist/UI/Utils/TableViewUrlState.js +103 -0
  369. package/build/dist/UI/Utils/TableViewUrlState.js.map +1 -0
  370. package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js +93 -0
  371. package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js.map +1 -0
  372. package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
  373. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  374. package/build/dist/Utils/IpCanonicalUtil.js +110 -0
  375. package/build/dist/Utils/IpCanonicalUtil.js.map +1 -0
  376. package/build/dist/Utils/Monitor/EndpointAttachmentUtil.js +311 -0
  377. package/build/dist/Utils/Monitor/EndpointAttachmentUtil.js.map +1 -0
  378. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +98 -5
  379. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  380. package/build/dist/Utils/NetworkSite/CidrMatchUtil.js +222 -0
  381. package/build/dist/Utils/NetworkSite/CidrMatchUtil.js.map +1 -0
  382. package/build/dist/Utils/NetworkSite/MaterializedPathUtil.js +89 -0
  383. package/build/dist/Utils/NetworkSite/MaterializedPathUtil.js.map +1 -0
  384. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +60 -0
  385. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -0
  386. package/build/dist/Utils/NetworkSite/SiteUptimeUtil.js +76 -0
  387. package/build/dist/Utils/NetworkSite/SiteUptimeUtil.js.map +1 -0
  388. package/build/dist/Utils/Slo/SloStatusColor.js +18 -0
  389. package/build/dist/Utils/Slo/SloStatusColor.js.map +1 -0
  390. package/build/dist/Utils/Slo/SloUtil.js +393 -0
  391. package/build/dist/Utils/Slo/SloUtil.js.map +1 -0
  392. package/build/dist/Utils/Slo/SloWidgetFormat.js +174 -0
  393. package/build/dist/Utils/Slo/SloWidgetFormat.js.map +1 -0
  394. package/package.json +2 -2
  395. package/Types/Dashboard/DashboardComponents/Index.ts +0 -7
  396. package/build/dist/Types/Dashboard/DashboardComponents/Index.js +0 -8
  397. package/build/dist/Types/Dashboard/DashboardComponents/Index.js.map +0 -1
@@ -0,0 +1,213 @@
1
+ import MemoryUtil from "../../../Server/Utils/Memory";
2
+ import fs from "fs";
3
+ import os from "os";
4
+
5
+ /*
6
+ * MemoryUtil decides how much memory a process may assume it has. On a host
7
+ * it is os.freemem(); inside a container it must be the cgroup headroom,
8
+ * because os.freemem() reports the whole node and would happily let a
9
+ * container allocate its way to an OOM kill.
10
+ *
11
+ * The cgroup files do not exist on the dev machines these tests run on, so
12
+ * fs.readFileSync is stubbed per-path. That is the only way to exercise the
13
+ * v2 -> v1 -> null fallback chain and the "max"/unlimited handling at all.
14
+ */
15
+
16
+ const CGROUP_V2_LIMIT: string = "/sys/fs/cgroup/memory.max";
17
+ const CGROUP_V2_USAGE: string = "/sys/fs/cgroup/memory.current";
18
+ const CGROUP_V1_LIMIT: string = "/sys/fs/cgroup/memory/memory.limit_in_bytes";
19
+ const CGROUP_V1_USAGE: string = "/sys/fs/cgroup/memory/memory.usage_in_bytes";
20
+
21
+ type StubCgroupFilesFunction = (files: Record<string, string>) => void;
22
+
23
+ /*
24
+ * Makes readFileSync answer only for the given paths and throw ENOENT for
25
+ * everything else, which is what the real filesystem does when a cgroup
26
+ * version is not in use.
27
+ */
28
+ const stubCgroupFiles: StubCgroupFilesFunction = (
29
+ files: Record<string, string>,
30
+ ): void => {
31
+ jest
32
+ .spyOn(fs, "readFileSync")
33
+ .mockImplementation((path: fs.PathOrFileDescriptor): string => {
34
+ const value: string | undefined = files[String(path)];
35
+
36
+ if (value === undefined) {
37
+ throw Object.assign(new Error("ENOENT"), { code: "ENOENT" });
38
+ }
39
+
40
+ return value;
41
+ });
42
+ };
43
+
44
+ describe("MemoryUtil", () => {
45
+ const hostFreeMemory: number = 8 * 1024 * 1024 * 1024;
46
+
47
+ beforeEach(() => {
48
+ jest.spyOn(os, "freemem").mockReturnValue(hostFreeMemory);
49
+ });
50
+
51
+ afterEach(() => {
52
+ jest.restoreAllMocks();
53
+ });
54
+
55
+ describe("getHostFreeMemoryInBytes", () => {
56
+ test("should report what the os reports", () => {
57
+ expect(MemoryUtil.getHostFreeMemoryInBytes()).toEqual(hostFreeMemory);
58
+ });
59
+ });
60
+
61
+ describe("getCgroupAvailableMemoryInBytes", () => {
62
+ test("should return null when no cgroup files exist", () => {
63
+ stubCgroupFiles({});
64
+
65
+ expect(MemoryUtil.getCgroupAvailableMemoryInBytes()).toBeNull();
66
+ });
67
+
68
+ test("should return limit minus usage for cgroup v2", () => {
69
+ stubCgroupFiles({
70
+ [CGROUP_V2_LIMIT]: "1000",
71
+ [CGROUP_V2_USAGE]: "400",
72
+ });
73
+
74
+ expect(MemoryUtil.getCgroupAvailableMemoryInBytes()).toEqual(600);
75
+ });
76
+
77
+ test("should tolerate trailing whitespace in the cgroup files", () => {
78
+ stubCgroupFiles({
79
+ [CGROUP_V2_LIMIT]: "1000\n",
80
+ [CGROUP_V2_USAGE]: " 400 \n",
81
+ });
82
+
83
+ expect(MemoryUtil.getCgroupAvailableMemoryInBytes()).toEqual(600);
84
+ });
85
+
86
+ test("should never report negative headroom", () => {
87
+ // Usage above the limit happens transiently; clamp at zero.
88
+ stubCgroupFiles({
89
+ [CGROUP_V2_LIMIT]: "1000",
90
+ [CGROUP_V2_USAGE]: "1500",
91
+ });
92
+
93
+ expect(MemoryUtil.getCgroupAvailableMemoryInBytes()).toEqual(0);
94
+ });
95
+
96
+ test("should fall back to cgroup v1 when v2 says 'max'", () => {
97
+ /*
98
+ * "max" is how cgroup v2 spells "no limit", so it must not be read as a
99
+ * number and must not stop the v1 lookup.
100
+ */
101
+ stubCgroupFiles({
102
+ [CGROUP_V2_LIMIT]: "max",
103
+ [CGROUP_V2_USAGE]: "400",
104
+ [CGROUP_V1_LIMIT]: "2000",
105
+ [CGROUP_V1_USAGE]: "500",
106
+ });
107
+
108
+ expect(MemoryUtil.getCgroupAvailableMemoryInBytes()).toEqual(1500);
109
+ });
110
+
111
+ test("should fall back to cgroup v1 when v2 files are absent", () => {
112
+ stubCgroupFiles({
113
+ [CGROUP_V1_LIMIT]: "2000",
114
+ [CGROUP_V1_USAGE]: "500",
115
+ });
116
+
117
+ expect(MemoryUtil.getCgroupAvailableMemoryInBytes()).toEqual(1500);
118
+ });
119
+
120
+ test("should ignore an absurdly large limit as 'unlimited'", () => {
121
+ /*
122
+ * This is the literal sentinel an unconstrained cgroup v1 reports
123
+ * (PAGE_COUNTER_MAX, just under 2^63). It means "no limit", not "you
124
+ * have exabytes free".
125
+ */
126
+ const unlimited: string = "9223372036854771712";
127
+
128
+ stubCgroupFiles({
129
+ [CGROUP_V1_LIMIT]: unlimited,
130
+ [CGROUP_V1_USAGE]: "500",
131
+ });
132
+
133
+ expect(MemoryUtil.getCgroupAvailableMemoryInBytes()).toBeNull();
134
+ });
135
+
136
+ test("should honour a realistic multi-gigabyte container limit", () => {
137
+ /*
138
+ * Regression guard for the unlimited threshold. It must be large enough
139
+ * that ordinary container limits fall below it — a 2 GiB limit is a
140
+ * real limit, not the "no limit" sentinel, and treating it as unlimited
141
+ * silently disables container awareness for essentially every
142
+ * deployment.
143
+ */
144
+ const twoGiB: number = 2 * 1024 * 1024 * 1024;
145
+ const oneGiB: number = 1 * 1024 * 1024 * 1024;
146
+
147
+ stubCgroupFiles({
148
+ [CGROUP_V2_LIMIT]: String(twoGiB),
149
+ [CGROUP_V2_USAGE]: String(oneGiB),
150
+ });
151
+
152
+ expect(MemoryUtil.getCgroupAvailableMemoryInBytes()).toEqual(oneGiB);
153
+ });
154
+
155
+ test("should return null when the limit is present but usage is not", () => {
156
+ stubCgroupFiles({ [CGROUP_V2_LIMIT]: "1000" });
157
+
158
+ expect(MemoryUtil.getCgroupAvailableMemoryInBytes()).toBeNull();
159
+ });
160
+
161
+ test("should return null for a non-numeric limit", () => {
162
+ stubCgroupFiles({
163
+ [CGROUP_V2_LIMIT]: "not-a-number",
164
+ [CGROUP_V2_USAGE]: "400",
165
+ });
166
+
167
+ expect(MemoryUtil.getCgroupAvailableMemoryInBytes()).toBeNull();
168
+ });
169
+
170
+ test("should return null for a zero or negative limit", () => {
171
+ stubCgroupFiles({
172
+ [CGROUP_V2_LIMIT]: "0",
173
+ [CGROUP_V2_USAGE]: "0",
174
+ });
175
+
176
+ expect(MemoryUtil.getCgroupAvailableMemoryInBytes()).toBeNull();
177
+ });
178
+ });
179
+
180
+ describe("getContainerAwareAvailableMemoryInBytes", () => {
181
+ test("should use host free memory when there is no cgroup limit", () => {
182
+ stubCgroupFiles({});
183
+
184
+ expect(MemoryUtil.getContainerAwareAvailableMemoryInBytes()).toEqual(
185
+ hostFreeMemory,
186
+ );
187
+ });
188
+
189
+ test("should never exceed the container's headroom", () => {
190
+ /*
191
+ * This is the whole point of the helper: the host has 8GB free but the
192
+ * container may only use 600 bytes more.
193
+ */
194
+ stubCgroupFiles({
195
+ [CGROUP_V2_LIMIT]: "1000",
196
+ [CGROUP_V2_USAGE]: "400",
197
+ });
198
+
199
+ expect(MemoryUtil.getContainerAwareAvailableMemoryInBytes()).toEqual(600);
200
+ });
201
+
202
+ test("should use host free memory when it is the smaller of the two", () => {
203
+ jest.spyOn(os, "freemem").mockReturnValue(100);
204
+
205
+ stubCgroupFiles({
206
+ [CGROUP_V2_LIMIT]: "1000",
207
+ [CGROUP_V2_USAGE]: "0",
208
+ });
209
+
210
+ expect(MemoryUtil.getContainerAwareAvailableMemoryInBytes()).toEqual(100);
211
+ });
212
+ });
213
+ });
@@ -130,6 +130,36 @@ describe("LogMonitorCriteria.isMonitorInstanceCriteriaFilterMet", () => {
130
130
  });
131
131
  });
132
132
 
133
+ /*
134
+ * The exact production shape of a "log presence" alert: criteria
135
+ * "Log Count >= 1" flips the monitor Offline the moment a matching log
136
+ * line is ingested. Documents the comparator behavior downstream of
137
+ * countBy — the countBy parsing regression itself (ClickHouse >= 25.x
138
+ * returning count() as a JSON number) is pinned in
139
+ * AnalyticsDatabaseService.test.ts.
140
+ */
141
+ describe("log-presence offline criteria (Log Count >= 1)", () => {
142
+ const offlineCriteria: CriteriaFilter = {
143
+ checkOn: CheckOn.LogCount,
144
+ filterType: FilterType.GreaterThanOrEqualTo,
145
+ value: 1,
146
+ };
147
+
148
+ test("one matching log → met (monitor goes offline)", async () => {
149
+ const result: string | null = await evaluate(1, offlineCriteria);
150
+ expect(result).toBeTruthy();
151
+ expect(result).toContain("Log Count");
152
+ });
153
+
154
+ test("many matching logs → met", async () => {
155
+ expect(await evaluate(6718284, offlineCriteria)).toBeTruthy();
156
+ });
157
+
158
+ test("zero matching logs → not met (monitor stays operational)", async () => {
159
+ expect(await evaluate(0, offlineCriteria)).toBeNull();
160
+ });
161
+ });
162
+
133
163
  describe("edge cases", () => {
134
164
  test("a missing logCount is treated as 0", async () => {
135
165
  // undefined logCount → 0; "equal to 0" is therefore met.
@@ -1,10 +1,16 @@
1
1
  import SnmpMonitorCriteria from "../../../../../Server/Utils/Monitor/Criteria/SnmpMonitorCriteria";
2
+ import MetricBaselineService, {
3
+ BaselineSummary,
4
+ } from "../../../../../Server/Services/MetricBaselineService";
2
5
  import {
6
+ AnomalyDetectionSensitivity,
3
7
  CheckOn,
4
8
  CriteriaFilter,
5
9
  FilterType,
6
10
  } from "../../../../../Types/Monitor/CriteriaFilter";
11
+ import MonitorMetricType from "../../../../../Types/Monitor/MonitorMetricType";
7
12
  import SnmpDataType from "../../../../../Types/Monitor/SnmpMonitor/SnmpDataType";
13
+ import SnmpInterface from "../../../../../Types/Monitor/SnmpMonitor/SnmpInterface";
8
14
  import SnmpMonitorResponse, {
9
15
  SnmpOidResponse,
10
16
  } from "../../../../../Types/Monitor/SnmpMonitor/SnmpMonitorResponse";
@@ -15,6 +21,7 @@ const PSU_OID: string = "1.3.6.1.4.1.674.10892.5.4.600.12.1.5.1.2";
15
21
 
16
22
  function buildDataToProcess(input: {
17
23
  oidResponses: Array<SnmpOidResponse>;
24
+ interfaces?: Array<SnmpInterface>;
18
25
  isOnline?: boolean;
19
26
  responseTimeInMs?: number;
20
27
  }): ProbeMonitorResponse {
@@ -23,6 +30,7 @@ function buildDataToProcess(input: {
23
30
  responseTimeInMs: input.responseTimeInMs ?? 42,
24
31
  failureCause: "",
25
32
  oidResponses: input.oidResponses,
33
+ ...(input.interfaces ? { interfaces: input.interfaces } : {}),
26
34
  };
27
35
 
28
36
  return {
@@ -36,6 +44,41 @@ function buildDataToProcess(input: {
36
44
  };
37
45
  }
38
46
 
47
+ function buildInterface(input: {
48
+ name: string;
49
+ utilizationPercent?: number | undefined;
50
+ alias?: string | undefined;
51
+ }): SnmpInterface {
52
+ return {
53
+ interfaceIndex: 1,
54
+ name: input.name,
55
+ alias: input.alias,
56
+ isOperationallyUp: true,
57
+ isAdministrativelyUp: true,
58
+ utilizationPercent: input.utilizationPercent,
59
+ };
60
+ }
61
+
62
+ function buildBaseline(input: {
63
+ mean: number;
64
+ stddev: number;
65
+ sampleCount?: number;
66
+ isReliable?: boolean;
67
+ }): BaselineSummary {
68
+ return {
69
+ sampleCount: input.sampleCount ?? 100,
70
+ mean: input.mean,
71
+ stddev: input.stddev,
72
+ median: input.mean,
73
+ p95: input.mean + 2 * input.stddev,
74
+ minObserved: input.mean - 2 * input.stddev,
75
+ maxObserved: input.mean + 2 * input.stddev,
76
+ isReliable: input.isReliable ?? true,
77
+ windowDays: 14,
78
+ hourOfWeek: 10,
79
+ };
80
+ }
81
+
39
82
  describe("SnmpMonitorCriteria.isMonitorInstanceCriteriaFilterMet", () => {
40
83
  describe("SnmpOidValue with Integer values (regression for issue #2439)", () => {
41
84
  test("Integer 3 equals 3 → criteria is met", async () => {
@@ -374,4 +417,346 @@ describe("SnmpMonitorCriteria.isMonitorInstanceCriteriaFilterMet", () => {
374
417
  expect(result).toContain("does not exist");
375
418
  });
376
419
  });
420
+
421
+ describe("SnmpInterfaceUtilizationPercent anomaly filters", () => {
422
+ let getBaselineSpy: jest.SpyInstance;
423
+
424
+ beforeEach(() => {
425
+ getBaselineSpy = jest.spyOn(MetricBaselineService, "getBaseline");
426
+ });
427
+
428
+ afterEach(() => {
429
+ getBaselineSpy.mockRestore();
430
+ });
431
+
432
+ test("AnomalouslyHigh fires when utilization exceeds mean + 3σ (Medium default)", async () => {
433
+ // mean 20, σ 5 → 3σ band is [5, 35]; observed 90 breaches high.
434
+ getBaselineSpy.mockResolvedValue(buildBaseline({ mean: 20, stddev: 5 }));
435
+
436
+ const criteriaFilter: CriteriaFilter = {
437
+ checkOn: CheckOn.SnmpInterfaceUtilizationPercent,
438
+ filterType: FilterType.AnomalouslyHigh,
439
+ value: undefined,
440
+ };
441
+
442
+ const dataToProcess: ProbeMonitorResponse = buildDataToProcess({
443
+ oidResponses: [],
444
+ interfaces: [buildInterface({ name: "Gi0/1", utilizationPercent: 90 })],
445
+ });
446
+
447
+ const result: string | null =
448
+ await SnmpMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
449
+ dataToProcess,
450
+ criteriaFilter,
451
+ });
452
+
453
+ expect(result).toBeTruthy();
454
+ expect(result).toContain("above the same-hour baseline");
455
+ expect(result).toContain("90.00%");
456
+ });
457
+
458
+ test("baseline lookup is keyed by monitorId and the utilization metric name", async () => {
459
+ getBaselineSpy.mockResolvedValue(buildBaseline({ mean: 20, stddev: 5 }));
460
+
461
+ const criteriaFilter: CriteriaFilter = {
462
+ checkOn: CheckOn.SnmpInterfaceUtilizationPercent,
463
+ filterType: FilterType.AnomalouslyHigh,
464
+ value: undefined,
465
+ };
466
+
467
+ const dataToProcess: ProbeMonitorResponse = buildDataToProcess({
468
+ oidResponses: [],
469
+ interfaces: [buildInterface({ name: "Gi0/1", utilizationPercent: 90 })],
470
+ });
471
+
472
+ await SnmpMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
473
+ dataToProcess,
474
+ criteriaFilter,
475
+ });
476
+
477
+ expect(getBaselineSpy).toHaveBeenCalledWith(
478
+ expect.objectContaining({
479
+ projectId: dataToProcess.projectId.toString(),
480
+ primaryEntityId: dataToProcess.monitorId.toString(),
481
+ metricName: MonitorMetricType.SnmpInterfaceUtilizationPercent,
482
+ }),
483
+ );
484
+ });
485
+
486
+ test("no fire when utilization is inside the expected band", async () => {
487
+ getBaselineSpy.mockResolvedValue(buildBaseline({ mean: 20, stddev: 5 }));
488
+
489
+ const criteriaFilter: CriteriaFilter = {
490
+ checkOn: CheckOn.SnmpInterfaceUtilizationPercent,
491
+ filterType: FilterType.AnomalouslyHigh,
492
+ value: undefined,
493
+ };
494
+
495
+ const dataToProcess: ProbeMonitorResponse = buildDataToProcess({
496
+ oidResponses: [],
497
+ interfaces: [buildInterface({ name: "Gi0/1", utilizationPercent: 25 })],
498
+ });
499
+
500
+ const result: string | null =
501
+ await SnmpMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
502
+ dataToProcess,
503
+ criteriaFilter,
504
+ });
505
+
506
+ expect(result).toBeNull();
507
+ });
508
+
509
+ test("AnomalouslyLow fires when utilization drops below mean - 3σ", async () => {
510
+ // mean 50, σ 10 → 3σ band is [20, 80]; observed 2 breaches low.
511
+ getBaselineSpy.mockResolvedValue(buildBaseline({ mean: 50, stddev: 10 }));
512
+
513
+ const criteriaFilter: CriteriaFilter = {
514
+ checkOn: CheckOn.SnmpInterfaceUtilizationPercent,
515
+ filterType: FilterType.AnomalouslyLow,
516
+ value: undefined,
517
+ };
518
+
519
+ const dataToProcess: ProbeMonitorResponse = buildDataToProcess({
520
+ oidResponses: [],
521
+ interfaces: [buildInterface({ name: "Gi0/1", utilizationPercent: 2 })],
522
+ });
523
+
524
+ const result: string | null =
525
+ await SnmpMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
526
+ dataToProcess,
527
+ criteriaFilter,
528
+ });
529
+
530
+ expect(result).toBeTruthy();
531
+ expect(result).toContain("below the same-hour baseline");
532
+ });
533
+
534
+ test("Anomalous (either direction) fires on a high breach", async () => {
535
+ getBaselineSpy.mockResolvedValue(buildBaseline({ mean: 20, stddev: 5 }));
536
+
537
+ const criteriaFilter: CriteriaFilter = {
538
+ checkOn: CheckOn.SnmpInterfaceUtilizationPercent,
539
+ filterType: FilterType.Anomalous,
540
+ value: undefined,
541
+ };
542
+
543
+ const dataToProcess: ProbeMonitorResponse = buildDataToProcess({
544
+ oidResponses: [],
545
+ interfaces: [buildInterface({ name: "Gi0/1", utilizationPercent: 99 })],
546
+ });
547
+
548
+ const result: string | null =
549
+ await SnmpMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
550
+ dataToProcess,
551
+ criteriaFilter,
552
+ });
553
+
554
+ expect(result).toBeTruthy();
555
+ });
556
+
557
+ test("High sensitivity (2σ) fires where Medium (3σ) would not", async () => {
558
+ // mean 20, σ 5 → 2σ band tops out at 30; observed 32 breaches at 2σ only.
559
+ getBaselineSpy.mockResolvedValue(buildBaseline({ mean: 20, stddev: 5 }));
560
+
561
+ const criteriaFilter: CriteriaFilter = {
562
+ checkOn: CheckOn.SnmpInterfaceUtilizationPercent,
563
+ filterType: FilterType.AnomalouslyHigh,
564
+ value: undefined,
565
+ metricMonitorOptions: {
566
+ anomalyDetection: {
567
+ sensitivity: AnomalyDetectionSensitivity.High,
568
+ },
569
+ },
570
+ };
571
+
572
+ const dataToProcess: ProbeMonitorResponse = buildDataToProcess({
573
+ oidResponses: [],
574
+ interfaces: [buildInterface({ name: "Gi0/1", utilizationPercent: 32 })],
575
+ });
576
+
577
+ const result: string | null =
578
+ await SnmpMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
579
+ dataToProcess,
580
+ criteriaFilter,
581
+ });
582
+
583
+ expect(result).toBeTruthy();
584
+ expect(result).toContain("sensitivity High");
585
+ });
586
+
587
+ test("no baseline yet (learning) → never fires", async () => {
588
+ getBaselineSpy.mockResolvedValue(null);
589
+
590
+ const criteriaFilter: CriteriaFilter = {
591
+ checkOn: CheckOn.SnmpInterfaceUtilizationPercent,
592
+ filterType: FilterType.AnomalouslyHigh,
593
+ value: undefined,
594
+ };
595
+
596
+ const dataToProcess: ProbeMonitorResponse = buildDataToProcess({
597
+ oidResponses: [],
598
+ interfaces: [
599
+ buildInterface({ name: "Gi0/1", utilizationPercent: 100 }),
600
+ ],
601
+ });
602
+
603
+ const result: string | null =
604
+ await SnmpMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
605
+ dataToProcess,
606
+ criteriaFilter,
607
+ });
608
+
609
+ expect(result).toBeNull();
610
+ });
611
+
612
+ test("unreliable (thin) baseline → never fires", async () => {
613
+ getBaselineSpy.mockResolvedValue(
614
+ buildBaseline({ mean: 20, stddev: 5, isReliable: false }),
615
+ );
616
+
617
+ const criteriaFilter: CriteriaFilter = {
618
+ checkOn: CheckOn.SnmpInterfaceUtilizationPercent,
619
+ filterType: FilterType.AnomalouslyHigh,
620
+ value: undefined,
621
+ };
622
+
623
+ const dataToProcess: ProbeMonitorResponse = buildDataToProcess({
624
+ oidResponses: [],
625
+ interfaces: [
626
+ buildInterface({ name: "Gi0/1", utilizationPercent: 100 }),
627
+ ],
628
+ });
629
+
630
+ const result: string | null =
631
+ await SnmpMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
632
+ dataToProcess,
633
+ criteriaFilter,
634
+ });
635
+
636
+ expect(result).toBeNull();
637
+ });
638
+
639
+ test("zero-variance baseline → never fires", async () => {
640
+ getBaselineSpy.mockResolvedValue(buildBaseline({ mean: 20, stddev: 0 }));
641
+
642
+ const criteriaFilter: CriteriaFilter = {
643
+ checkOn: CheckOn.SnmpInterfaceUtilizationPercent,
644
+ filterType: FilterType.AnomalouslyHigh,
645
+ value: undefined,
646
+ };
647
+
648
+ const dataToProcess: ProbeMonitorResponse = buildDataToProcess({
649
+ oidResponses: [],
650
+ interfaces: [
651
+ buildInterface({ name: "Gi0/1", utilizationPercent: 100 }),
652
+ ],
653
+ });
654
+
655
+ const result: string | null =
656
+ await SnmpMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
657
+ dataToProcess,
658
+ criteriaFilter,
659
+ });
660
+
661
+ expect(result).toBeNull();
662
+ });
663
+
664
+ test("interface scope applies: only the scoped interface's utilization is observed", async () => {
665
+ getBaselineSpy.mockResolvedValue(buildBaseline({ mean: 20, stddev: 5 }));
666
+
667
+ const criteriaFilter: CriteriaFilter = {
668
+ checkOn: CheckOn.SnmpInterfaceUtilizationPercent,
669
+ filterType: FilterType.AnomalouslyHigh,
670
+ value: undefined,
671
+ snmpMonitorOptions: { interfaceName: "Gi0/2" },
672
+ };
673
+
674
+ // Out-of-scope Gi0/1 is anomalous; in-scope Gi0/2 is normal.
675
+ const dataToProcess: ProbeMonitorResponse = buildDataToProcess({
676
+ oidResponses: [],
677
+ interfaces: [
678
+ buildInterface({ name: "Gi0/1", utilizationPercent: 99 }),
679
+ buildInterface({ name: "Gi0/2", utilizationPercent: 22 }),
680
+ ],
681
+ });
682
+
683
+ const result: string | null =
684
+ await SnmpMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
685
+ dataToProcess,
686
+ criteriaFilter,
687
+ });
688
+
689
+ expect(result).toBeNull();
690
+ });
691
+
692
+ test("no interfaces in the response → no baseline lookup, no fire", async () => {
693
+ getBaselineSpy.mockResolvedValue(buildBaseline({ mean: 20, stddev: 5 }));
694
+
695
+ const criteriaFilter: CriteriaFilter = {
696
+ checkOn: CheckOn.SnmpInterfaceUtilizationPercent,
697
+ filterType: FilterType.AnomalouslyHigh,
698
+ value: undefined,
699
+ };
700
+
701
+ const dataToProcess: ProbeMonitorResponse = buildDataToProcess({
702
+ oidResponses: [],
703
+ });
704
+
705
+ const result: string | null =
706
+ await SnmpMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
707
+ dataToProcess,
708
+ criteriaFilter,
709
+ });
710
+
711
+ expect(result).toBeNull();
712
+ expect(getBaselineSpy).not.toHaveBeenCalled();
713
+ });
714
+
715
+ test("baseline lookup failure is swallowed (no fire, no throw)", async () => {
716
+ getBaselineSpy.mockRejectedValue(new Error("clickhouse down"));
717
+
718
+ const criteriaFilter: CriteriaFilter = {
719
+ checkOn: CheckOn.SnmpInterfaceUtilizationPercent,
720
+ filterType: FilterType.AnomalouslyHigh,
721
+ value: undefined,
722
+ };
723
+
724
+ const dataToProcess: ProbeMonitorResponse = buildDataToProcess({
725
+ oidResponses: [],
726
+ interfaces: [
727
+ buildInterface({ name: "Gi0/1", utilizationPercent: 100 }),
728
+ ],
729
+ });
730
+
731
+ const result: string | null =
732
+ await SnmpMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
733
+ dataToProcess,
734
+ criteriaFilter,
735
+ });
736
+
737
+ expect(result).toBeNull();
738
+ });
739
+
740
+ test("static threshold path is untouched: GreaterThan still compares numerically", async () => {
741
+ const criteriaFilter: CriteriaFilter = {
742
+ checkOn: CheckOn.SnmpInterfaceUtilizationPercent,
743
+ filterType: FilterType.GreaterThan,
744
+ value: 80,
745
+ };
746
+
747
+ const dataToProcess: ProbeMonitorResponse = buildDataToProcess({
748
+ oidResponses: [],
749
+ interfaces: [buildInterface({ name: "Gi0/1", utilizationPercent: 90 })],
750
+ });
751
+
752
+ const result: string | null =
753
+ await SnmpMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
754
+ dataToProcess,
755
+ criteriaFilter,
756
+ });
757
+
758
+ expect(result).toBeTruthy();
759
+ expect(getBaselineSpy).not.toHaveBeenCalled();
760
+ });
761
+ });
377
762
  });