@oneuptime/common 14.0.3 → 14.0.5

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 (617) hide show
  1. package/Models/DatabaseModels/Alert.ts +55 -0
  2. package/Models/DatabaseModels/DatabaseServer.ts +1650 -0
  3. package/Models/DatabaseModels/DatabaseServerEndpoint.ts +540 -0
  4. package/Models/DatabaseModels/DatabaseServerFeed.ts +625 -0
  5. package/Models/DatabaseModels/DatabaseServerLabelRule.ts +514 -0
  6. package/Models/DatabaseModels/DatabaseServerOwnerRule.ts +596 -0
  7. package/Models/DatabaseModels/DatabaseServerOwnerTeam.ts +491 -0
  8. package/Models/DatabaseModels/DatabaseServerOwnerUser.ts +490 -0
  9. package/Models/DatabaseModels/Incident.ts +55 -0
  10. package/Models/DatabaseModels/Index.ts +16 -0
  11. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +26 -0
  12. package/Models/DatabaseModels/ScheduledMaintenance.ts +55 -0
  13. package/Models/DatabaseModels/TelemetryException.ts +2 -0
  14. package/Models/DatabaseModels/UserProjectSsoConsent.ts +146 -0
  15. package/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.ts +673 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.ts +51 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
  18. package/Server/Middleware/MultipartFormData.ts +1 -1
  19. package/Server/Middleware/TelemetryIngest.ts +15 -8
  20. package/Server/Services/AlertReminderRuleService.ts +100 -24
  21. package/Server/Services/DatabaseServerEndpointService.ts +895 -0
  22. package/Server/Services/DatabaseServerFeedService.ts +128 -0
  23. package/Server/Services/DatabaseServerLabelRuleEngineService.ts +340 -0
  24. package/Server/Services/DatabaseServerLabelRuleService.ts +14 -0
  25. package/Server/Services/DatabaseServerOwnerRuleEngineService.ts +425 -0
  26. package/Server/Services/DatabaseServerOwnerRuleService.ts +14 -0
  27. package/Server/Services/DatabaseServerOwnerTeamService.ts +180 -0
  28. package/Server/Services/DatabaseServerOwnerUserService.ts +173 -0
  29. package/Server/Services/DatabaseServerService.ts +4546 -0
  30. package/Server/Services/DatabaseService.ts +14 -8
  31. package/Server/Services/DockerResourceService.ts +43 -2
  32. package/Server/Services/IncidentReminderRuleService.ts +103 -23
  33. package/Server/Services/Index.ts +16 -0
  34. package/Server/Services/InventoryItemService.ts +113 -5
  35. package/Server/Services/IoTDeviceService.ts +145 -37
  36. package/Server/Services/OpenTelemetryIngestService.ts +19 -0
  37. package/Server/Services/PodmanResourceService.ts +43 -2
  38. package/Server/Services/ScheduledMaintenanceReminderRuleService.ts +107 -23
  39. package/Server/Services/ServiceService.ts +1 -1
  40. package/Server/Services/TelemetryUsageBillingService.ts +29 -2
  41. package/Server/Services/UserProjectSsoConsentService.ts +74 -0
  42. package/Server/Services/UserService.ts +14 -1
  43. package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +18 -0
  44. package/Server/Types/Database/QueryHelper.ts +30 -1
  45. package/Server/Utils/AI/Toolbox/ResourceTools.ts +69 -1
  46. package/Server/Utils/Database/AffectedResourceRelations.ts +6 -0
  47. package/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.ts +188 -6
  48. package/Server/Utils/Monitor/MonitorAlert.ts +28 -1
  49. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +2262 -755
  50. package/Server/Utils/Monitor/MonitorIncident.ts +28 -1
  51. package/Server/Utils/Monitor/MonitorMaintenanceSuppression.ts +268 -6
  52. package/Server/Utils/Monitor/MonitorResource.ts +47 -11
  53. package/Server/Utils/Monitor/MonitorResourceContext.ts +1 -0
  54. package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +239 -21
  55. package/Server/Utils/Monitor/PerSeriesResolutionRootCause.ts +43 -0
  56. package/Server/Utils/Monitor/SeriesResourceLabels.ts +291 -0
  57. package/Server/Utils/Monitor/SeriesResourceLinker.ts +111 -12
  58. package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +25 -0
  59. package/Server/Utils/StartServer.ts +26 -6
  60. package/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.ts +2 -0
  61. package/Server/Utils/Telemetry/DatabaseEndpointDiscovery.ts +688 -0
  62. package/Server/Utils/Telemetry/EntityRegistry.ts +5 -1
  63. package/Server/Utils/Telemetry/LogExceptionExtractor.ts +18 -1
  64. package/Server/Utils/Telemetry/ResourceEntityFilter.ts +175 -12
  65. package/Server/Utils/Telemetry/ResourceFacetResolver.ts +12 -0
  66. package/Server/Utils/Telemetry/ServiceDependencyDiscovery.ts +606 -36
  67. package/Server/Utils/Telemetry/Telemetry.ts +16 -0
  68. package/Server/Utils/Telemetry/TelemetryEntity.ts +22 -22
  69. package/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.ts +16 -10
  70. package/Tests/App/Accounts/SignedInRedirect.test.tsx +241 -0
  71. package/Tests/App/AdminDashboard/AdminHeaderSmallScreens.test.tsx +221 -4
  72. package/Tests/App/Dashboard/AIInsightsResourcePageContext.test.ts +42 -0
  73. package/Tests/App/Dashboard/AffectedResourcesDisplay.test.tsx +100 -0
  74. package/Tests/App/Dashboard/AffectedResourcesPicker.test.tsx +86 -0
  75. package/Tests/App/Dashboard/AffectedResourcesPickerHiddenTypes.test.tsx +2 -0
  76. package/Tests/App/Dashboard/AffectedResourcesSummaryStep.test.tsx +19 -0
  77. package/Tests/App/Dashboard/BreadcrumbCoverage.test.tsx +14 -0
  78. package/Tests/App/Dashboard/CorrelateFilterBuilder.test.tsx +26 -1
  79. package/Tests/App/Dashboard/DashboardAppSsoError.test.tsx +501 -0
  80. package/Tests/App/Dashboard/DashboardHeaderRequests.test.tsx +64 -1
  81. package/Tests/App/Dashboard/DashboardHeaderSmallScreens.test.tsx +178 -18
  82. package/Tests/App/Dashboard/DashboardMasterPageSsoRedirect.test.tsx +444 -0
  83. package/Tests/App/Dashboard/DashboardNavBarForeignHiddenRule.test.tsx +573 -0
  84. package/Tests/App/Dashboard/DatabaseChartAxes.test.tsx +431 -0
  85. package/Tests/App/Dashboard/DatabaseContainerDetailBadge.test.tsx +249 -0
  86. package/Tests/App/Dashboard/DatabaseDashboardE2EFixes.test.ts +681 -0
  87. package/Tests/App/Dashboard/DatabaseDocumentationMarkdown.test.ts +1801 -0
  88. package/Tests/App/Dashboard/DatabaseFleetSummaryRefresh.test.tsx +280 -0
  89. package/Tests/App/Dashboard/DatabaseFormHelpers.test.tsx +321 -0
  90. package/Tests/App/Dashboard/DatabaseMetricMonitorLink.test.tsx +795 -0
  91. package/Tests/App/Dashboard/DatabaseOverviewHeader.test.tsx +580 -0
  92. package/Tests/App/Dashboard/DatabaseRecommendationsEngineMetrics.test.ts +270 -0
  93. package/Tests/App/Dashboard/DatabaseServerComponents.test.tsx +1486 -0
  94. package/Tests/App/Dashboard/DatabaseServerEngineMetricsFilter.test.ts +223 -0
  95. package/Tests/App/Dashboard/DatabaseServerPresentation.test.ts +435 -0
  96. package/Tests/App/Dashboard/DatabaseServerSummary.test.ts +186 -0
  97. package/Tests/App/Dashboard/DatabaseServerTelemetryQueries.test.ts +1553 -0
  98. package/Tests/App/Dashboard/DatabaseTableTruncation.test.tsx +326 -0
  99. package/Tests/App/Dashboard/DatabaseTelemetryScope.test.ts +512 -0
  100. package/Tests/App/Dashboard/DatabaseTelemetryTabs.test.tsx +774 -0
  101. package/Tests/App/Dashboard/DatabaseViewLayout.test.tsx +233 -0
  102. package/Tests/App/Dashboard/DatabaseWorkloadBadge.test.tsx +972 -0
  103. package/Tests/App/Dashboard/DiscoveryReviewInventoryRefresh.test.tsx +5 -0
  104. package/Tests/App/Dashboard/DiscoveryReviewUnnamedHostHint.test.tsx +1061 -0
  105. package/Tests/App/Dashboard/EventOverlayScope.test.ts +147 -0
  106. package/Tests/App/Dashboard/EventOverlayScopeHook.test.tsx +1 -0
  107. package/Tests/App/Dashboard/LogsResourceFacetChips.test.tsx +1 -0
  108. package/Tests/App/Dashboard/MetricsViewerDrillDown.test.tsx +310 -0
  109. package/Tests/App/Dashboard/MetricsViewerEntityScopedRows.test.tsx +495 -0
  110. package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +132 -1
  111. package/Tests/App/Dashboard/NavigationSearchKeywords.test.tsx +5 -0
  112. package/Tests/App/Dashboard/ProductOrientation.test.tsx +4 -3
  113. package/Tests/App/Dashboard/RecommendationsLoadedContext.test.tsx +349 -0
  114. package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +62 -0
  115. package/Tests/App/Dashboard/ResourceFeedPageWiring.test.ts +8 -1
  116. package/Tests/App/Dashboard/ResourceFeedPagesFilterSort.test.tsx +14 -0
  117. package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +2 -0
  118. package/Tests/App/Dashboard/ServiceMapDatabaseLink.test.tsx +1085 -0
  119. package/Tests/App/Dashboard/TelemetryResourceRetentionSettings.test.tsx +10 -0
  120. package/Tests/App/Dashboard/TracesResourceFacets.test.tsx +2 -1
  121. package/Tests/App/StatusPage/StatusPageHeaderForeignHiddenRule.test.tsx +284 -0
  122. package/Tests/ClassStrings.ts +178 -0
  123. package/Tests/Fixtures/MobilePasskeyUser.json +1 -2
  124. package/Tests/ForeignHiddenRuleGuard.ts +2152 -0
  125. package/Tests/Models/DatabaseModels/DatabaseServerModels.test.ts +2250 -0
  126. package/Tests/Models/DatabaseModels/ResourceFeedModels.test.ts +24 -5
  127. package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +4 -2
  128. package/Tests/RenderedMarkup.ts +518 -0
  129. package/Tests/ResponsiveVisibility.test.ts +490 -4
  130. package/Tests/ResponsiveVisibility.ts +505 -52
  131. package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +3 -0
  132. package/Tests/Server/Infrastructure/Postgres/AddDatabaseServerTablesMigration.test.ts +541 -0
  133. package/Tests/Server/Infrastructure/Postgres/AddUserProjectSsoConsentMigration.test.ts +234 -0
  134. package/Tests/Server/Services/ContainerSnapshotUpsertPostgres.test.ts +319 -0
  135. package/Tests/Server/Services/CrossProjectRelationWriteGuard.test.ts +13 -0
  136. package/Tests/Server/Services/DatabaseServerEndpointService.test.ts +2033 -0
  137. package/Tests/Server/Services/DatabaseServerFeedAndOwnerServices.test.ts +529 -0
  138. package/Tests/Server/Services/DatabaseServerLifecycle.test.ts +3302 -0
  139. package/Tests/Server/Services/DatabaseServerRegistries.test.ts +603 -0
  140. package/Tests/Server/Services/DatabaseServerRuleEngines.test.ts +754 -0
  141. package/Tests/Server/Services/DatabaseServerService.test.ts +3558 -0
  142. package/Tests/Server/Services/DatabaseServerSqlPostgres.test.ts +2045 -0
  143. package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlockedPostgres.test.ts +362 -0
  144. package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlockedReply.test.ts +210 -0
  145. package/Tests/Server/Services/HookFreeWriteLengthClamp.test.ts +18 -0
  146. package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +2 -0
  147. package/Tests/Server/Services/IncomingCallPolicyEscalationRuleTarget.test.ts +225 -0
  148. package/Tests/Server/Services/InventoryItemDisplayName.test.ts +280 -2
  149. package/Tests/Server/Services/InventoryUpsertSchemaParity.test.ts +8 -2
  150. package/Tests/Server/Services/IoTDeviceLatestMetricsPostgres.test.ts +689 -0
  151. package/Tests/Server/Services/IoTDeviceService.test.ts +379 -0
  152. package/Tests/Server/Services/LatestMetricsValuesShape.test.ts +360 -0
  153. package/Tests/Server/Services/LlmModelPriceService.test.ts +402 -0
  154. package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +7 -1
  155. package/Tests/Server/Services/OwnerRowUniqueness.test.ts +61 -9
  156. package/Tests/Server/Services/ReminderRuleLookupPostgres.test.ts +2250 -0
  157. package/Tests/Server/Services/ReminderRuleRefreshOpenSubjectsPaging.test.ts +653 -0
  158. package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +68 -20
  159. package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +3 -3
  160. package/Tests/Server/Services/TelemetryResourceFacetCounting.test.ts +9 -0
  161. package/Tests/Server/Services/UserProjectSsoConsentPostgres.test.ts +153 -0
  162. package/Tests/Server/Services/UserProjectSsoConsentService.test.ts +192 -0
  163. package/Tests/Server/Services/UserServiceFirstMasterAdminElection.test.ts +71 -0
  164. package/Tests/Server/Services/UserSignupIdTakeoverPostgres.test.ts +238 -0
  165. package/Tests/Server/Services/WorkspaceNotificationSummaryHelpers.test.ts +592 -0
  166. package/Tests/Server/Types/Billing/PayAsYouGoMeteredAuthorization.test.ts +3 -0
  167. package/Tests/Server/Types/Database/EventOverlayScopePostgres.test.ts +1 -0
  168. package/Tests/Server/Types/Database/FeedEventTypeFilterQuery.test.ts +11 -0
  169. package/Tests/Server/Types/Database/Permissions/InfrastructureOwnershipScope.test.ts +8 -0
  170. package/Tests/Server/Types/Database/QueryHelperBooleanForCriteriaBackedRule.test.ts +1094 -0
  171. package/Tests/Server/Utils/AI/ResourceTools.test.ts +134 -0
  172. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.ts +41 -0
  173. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaAnomalyUnits.test.ts +279 -9
  174. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaDisplayContext.test.ts +933 -0
  175. package/Tests/Server/Utils/Monitor/DatabaseMaintenanceSuppression.test.ts +582 -0
  176. package/Tests/Server/Utils/Monitor/DatabaseServerMonitorLinking.test.ts +753 -0
  177. package/Tests/Server/Utils/Monitor/MonitorActionTimestamps.test.ts +1 -0
  178. package/Tests/Server/Utils/Monitor/MonitorAlertCriteriaReferences.test.ts +1 -0
  179. package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +119 -0
  180. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +60 -25
  181. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorAffectedResourceEdgeCases.test.ts +1719 -0
  182. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorKubernetesAffectedResources.test.ts +1447 -0
  183. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorKubernetesRatioEmail.test.ts +352 -0
  184. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformMetricUnits.test.ts +717 -0
  185. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformRawScan.test.ts +2125 -0
  186. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformSeriesAffectedResources.test.ts +1288 -0
  187. package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +1 -0
  188. package/Tests/Server/Utils/Monitor/MonitorIncidentCriteriaReferences.test.ts +1 -0
  189. package/Tests/Server/Utils/Monitor/MonitorIncidentMemberRoleMembership.test.ts +1 -0
  190. package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +88 -0
  191. package/Tests/Server/Utils/Monitor/MonitorMaintenanceSuppression.test.ts +205 -0
  192. package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +62 -0
  193. package/Tests/Server/Utils/Monitor/MonitorResourceDatabaseMaintenance.test.ts +803 -0
  194. package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +133 -3
  195. package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +1 -0
  196. package/Tests/Server/Utils/Monitor/PerSeriesRecoveryResolution.test.ts +472 -1
  197. package/Tests/Server/Utils/Monitor/PerSeriesSecondEntityAlerting.test.ts +1 -0
  198. package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +236 -2
  199. package/Tests/Server/Utils/SeriesResourceLabels.test.ts +70 -0
  200. package/Tests/Server/Utils/StartServerProtobufContentType.test.ts +54 -0
  201. package/Tests/Server/Utils/Telemetry/DatabaseEndpointDiscovery.test.ts +1895 -0
  202. package/Tests/Server/Utils/Telemetry/EntityRegistry.test.ts +7 -0
  203. package/Tests/Server/Utils/Telemetry/LogExceptionExtractorSeverityGate.test.ts +90 -0
  204. package/Tests/Server/Utils/Telemetry/ResourceEntityFilter.test.ts +570 -0
  205. package/Tests/Server/Utils/Telemetry/ResourceFacetResolver.test.ts +97 -2
  206. package/Tests/Server/Utils/Telemetry/ServiceDependencyDiscovery.test.ts +1337 -0
  207. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +295 -0
  208. package/Tests/Types/AI/AIResourceContext.test.ts +30 -0
  209. package/Tests/Types/DatabaseServer/DatabaseContainerClassifier.test.ts +3644 -0
  210. package/Tests/Types/DatabaseServer/DatabaseContainerCommand.test.ts +340 -0
  211. package/Tests/Types/DatabaseServer/DatabaseContainerCommandCorpus.ts +826 -0
  212. package/Tests/Types/DatabaseServer/DatabaseContainerCommandPostgres.test.ts +150 -0
  213. package/Tests/Types/DatabaseServer/DatabaseEndpoint.test.ts +2657 -0
  214. package/Tests/Types/DatabaseServer/DatabaseServerDiscoverySource.test.ts +64 -0
  215. package/Tests/Types/DatabaseServer/DatabaseServerEntityKeys.test.ts +952 -0
  216. package/Tests/Types/DatabaseServer/DatabaseServerMetricCatalog.test.ts +1161 -0
  217. package/Tests/Types/DatabaseServer/DatabaseSystem.test.ts +1514 -0
  218. package/Tests/Types/DatabaseServer/DatabaseTelemetryResolver.test.ts +1558 -0
  219. package/Tests/Types/Monitor/CephAlertTemplates.test.ts +255 -6
  220. package/Tests/Types/Monitor/DatabaseAlertTemplates.test.ts +2254 -0
  221. package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +298 -0
  222. package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +271 -0
  223. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +253 -9
  224. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +13 -5
  225. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +4 -2
  226. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +111 -2
  227. package/Tests/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.test.ts +61 -0
  228. package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +114 -0
  229. package/Tests/Types/Monitor/Utils/KubernetesAgentEmittedMetrics.ts +181 -0
  230. package/Tests/Types/NetworkDevice/DiscoveredHostNamingStatus.test.ts +401 -0
  231. package/Tests/Types/Telemetry/ResourceEntityFacet.test.ts +4 -1
  232. package/Tests/Types/Telemetry/ResourceFacetCatalog.test.ts +24 -2
  233. package/Tests/UI/Components/Card.test.tsx +93 -2
  234. package/Tests/UI/Components/FeedOptions.test.ts +6 -0
  235. package/Tests/UI/Components/FeedOptionsButton.test.tsx +8 -1
  236. package/Tests/UI/Components/ForeignHiddenRuleResilience.test.tsx +1147 -0
  237. package/Tests/UI/Components/HeaderRightRail.test.tsx +41 -1
  238. package/Tests/UI/Components/LogsEntityNames.test.ts +16 -1
  239. package/Tests/UI/Components/LogsFacetSidebarHiddenFacets.test.tsx +7 -3
  240. package/Tests/UI/Components/ResourceFacetConfigs.test.ts +2 -1
  241. package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
  242. package/Tests/UI/Components/SrOnlyForeignRule.test.tsx +994 -0
  243. package/Tests/UI/Components/StatusPage/ResourceListSelection.test.tsx +34 -1
  244. package/Tests/UI/Components/TelemetryFacetSidebarHiddenFacets.test.tsx +4 -1
  245. package/Tests/UI/ForeignHiddenRuleGuard.test.ts +1951 -0
  246. package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +19 -1
  247. package/Tests/UI/Rum/ReplayTabSwitcher.test.tsx +19 -1
  248. package/Tests/UI/TailwindPlayCdnForeignHiddenRule.test.ts +1005 -0
  249. package/Tests/UI/ThemeGroupHoverReveal.test.ts +847 -0
  250. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +70 -0
  251. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +21 -0
  252. package/Tests/UI/Utils/ModelAPISsoRedirect.test.ts +127 -0
  253. package/Tests/UI/Utils/Navigation.test.ts +102 -0
  254. package/Tests/UI/Utils/Telemetry/TelemetryEntityNames.test.ts +23 -0
  255. package/Tests/Utils/LabelRuleImportExport.test.ts +5 -0
  256. package/Tests/Utils/MetricUnitUtil.test.ts +227 -2
  257. package/Tests/Utils/Monitor/MetricValueFormatter.test.ts +288 -2
  258. package/Tests/Utils/Monitor/PlatformResourceIdentityAndUnits.test.ts +1559 -0
  259. package/Tests/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.test.ts +2546 -0
  260. package/Tests/Utils/NetworkDiscovery/DiscoveredHostUtil.test.ts +315 -0
  261. package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +336 -1
  262. package/Tests/Utils/NetworkDiscovery/NetbiosNameUtil.test.ts +244 -0
  263. package/Tests/Utils/ValueFormatter.test.ts +50 -0
  264. package/Tests/tsconfig.json +16 -0
  265. package/Types/AI/AIResourceContext.ts +7 -0
  266. package/Types/Dashboard/DashboardTemplates.ts +2 -1
  267. package/Types/DatabaseServer/DatabaseConnectionSpan.ts +77 -0
  268. package/Types/DatabaseServer/DatabaseContainerClassifier.ts +2068 -0
  269. package/Types/DatabaseServer/DatabaseContainerCommand.ts +801 -0
  270. package/Types/DatabaseServer/DatabaseEndpoint.ts +1943 -0
  271. package/Types/DatabaseServer/DatabaseServerDiscoverySource.ts +68 -0
  272. package/Types/DatabaseServer/DatabaseServerMetricCatalog.ts +966 -0
  273. package/Types/DatabaseServer/DatabaseSystem.ts +2124 -0
  274. package/Types/DatabaseServer/DatabaseTelemetryResolver.ts +555 -0
  275. package/Types/Email/EmailTemplateType.ts +1 -0
  276. package/Types/Monitor/CephAlertTemplates.ts +18 -0
  277. package/Types/Monitor/DatabaseAlertTemplates.ts +2020 -0
  278. package/Types/Monitor/KubernetesAlertTemplates.ts +64 -24
  279. package/Types/Monitor/KubernetesMetricCatalog.ts +118 -19
  280. package/Types/Monitor/MetricMonitor/MetricCriteriaContext.ts +14 -0
  281. package/Types/Monitor/MetricMonitor/MetricMonitorResponse.ts +93 -10
  282. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +109 -8
  283. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +36 -7
  284. package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +43 -2
  285. package/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.ts +41 -6
  286. package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +26 -0
  287. package/Types/NetworkDevice/DiscoveredHostNamingStatus.ts +147 -0
  288. package/Types/Permission.ts +267 -0
  289. package/Types/Probe/ProbeApiIngestResponse.ts +8 -0
  290. package/Types/Rules/RuleCriteriaFieldRegistry.ts +10 -0
  291. package/Types/Rules/RuleRun.ts +12 -0
  292. package/Types/Telemetry/EntityType.ts +23 -0
  293. package/Types/Telemetry/ResourceFacetCatalog.ts +14 -0
  294. package/Types/Telemetry/ServiceType.ts +8 -0
  295. package/UI/Components/Banner/Banner.tsx +1 -1
  296. package/UI/Components/Card/Card.tsx +1 -1
  297. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +2 -2
  298. package/UI/Components/Charts/Line/LineChart.tsx +7 -0
  299. package/UI/Components/CommandPalette/CommandPalette.tsx +1 -1
  300. package/UI/Components/Date/StartAndEndDate.tsx +5 -5
  301. package/UI/Components/Diagram/HorizontalStepChain.tsx +1 -1
  302. package/UI/Components/Feed/FeedOptionsButton.tsx +1 -1
  303. package/UI/Components/Forms/BasicForm.tsx +1 -1
  304. package/UI/Components/Header/Header.tsx +1 -1
  305. package/UI/Components/Header/HeaderIconDropdownButton.tsx +1 -1
  306. package/UI/Components/HeaderAlert/HeaderAlert.tsx +1 -1
  307. package/UI/Components/LogsViewer/components/FacetValueRow.tsx +1 -1
  308. package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +1 -1
  309. package/UI/Components/Modal/ModalFooter.tsx +1 -1
  310. package/UI/Components/ModelDetail/CardModelDetail.tsx +2 -2
  311. package/UI/Components/ModelTable/BaseModelTable.tsx +4 -4
  312. package/UI/Components/Navbar/NavBar.tsx +9 -2
  313. package/UI/Components/Navbar/NavBarMenuModal.tsx +2 -2
  314. package/UI/Components/Page/Page.tsx +1 -1
  315. package/UI/Components/Pagination/Pagination.tsx +3 -3
  316. package/UI/Components/ProgressButtons/ProgressButtonItem.tsx +1 -1
  317. package/UI/Components/SideMenu/SideMenu.tsx +4 -1
  318. package/UI/Components/StatusPage/ResourceGroupNavigator.tsx +4 -2
  319. package/UI/Components/StatusPage/ResourceList.tsx +6 -6
  320. package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +1 -1
  321. package/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.tsx +1 -1
  322. package/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.tsx +1 -1
  323. package/UI/Components/Workflow/ComponentsModal.tsx +2 -2
  324. package/UI/Components/Workflow/StepTraceViewer.tsx +1 -1
  325. package/UI/Styles/Theme.css +8 -1
  326. package/UI/Utils/Navigation.ts +89 -42
  327. package/UI/Utils/Telemetry/TelemetryEntityNames.ts +7 -0
  328. package/UI/Utils/TelemetryService.ts +4 -3
  329. package/Utils/LabelRuleImportExport.ts +2 -0
  330. package/Utils/MetricUnitUtil.ts +103 -11
  331. package/Utils/Monitor/MetricValueFormatter.ts +66 -13
  332. package/Utils/Monitor/PlatformMetricUnitUtil.ts +215 -0
  333. package/Utils/Monitor/PlatformResourceIdentity.ts +514 -0
  334. package/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.ts +425 -0
  335. package/Utils/NetworkDiscovery/DiscoveredHostUtil.ts +32 -0
  336. package/Utils/NetworkDiscovery/NetbiosNameUtil.ts +73 -0
  337. package/Utils/Telemetry/DatabaseServerEntityKeys.ts +275 -0
  338. package/Utils/Telemetry/EntityKey.ts +176 -0
  339. package/Utils/ValueFormatter.ts +16 -0
  340. package/build/dist/Models/DatabaseModels/Alert.js +54 -0
  341. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  342. package/build/dist/Models/DatabaseModels/DatabaseServer.js +1683 -0
  343. package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -0
  344. package/build/dist/Models/DatabaseModels/DatabaseServerEndpoint.js +559 -0
  345. package/build/dist/Models/DatabaseModels/DatabaseServerEndpoint.js.map +1 -0
  346. package/build/dist/Models/DatabaseModels/DatabaseServerFeed.js +648 -0
  347. package/build/dist/Models/DatabaseModels/DatabaseServerFeed.js.map +1 -0
  348. package/build/dist/Models/DatabaseModels/DatabaseServerLabelRule.js +522 -0
  349. package/build/dist/Models/DatabaseModels/DatabaseServerLabelRule.js.map +1 -0
  350. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerRule.js +603 -0
  351. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerRule.js.map +1 -0
  352. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerTeam.js +506 -0
  353. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerTeam.js.map +1 -0
  354. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerUser.js +505 -0
  355. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerUser.js.map +1 -0
  356. package/build/dist/Models/DatabaseModels/Incident.js +54 -0
  357. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  358. package/build/dist/Models/DatabaseModels/Index.js +16 -0
  359. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  360. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  361. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +54 -0
  362. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  363. package/build/dist/Models/DatabaseModels/TelemetryException.js +2 -0
  364. package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -1
  365. package/build/dist/Models/DatabaseModels/UserProjectSsoConsent.js +162 -0
  366. package/build/dist/Models/DatabaseModels/UserProjectSsoConsent.js.map +1 -0
  367. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.js +240 -0
  368. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.js.map +1 -0
  369. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.js +26 -0
  370. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.js.map +1 -0
  371. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
  372. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  373. package/build/dist/Server/Middleware/MultipartFormData.js +1 -1
  374. package/build/dist/Server/Middleware/TelemetryIngest.js +15 -8
  375. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  376. package/build/dist/Server/Services/AlertReminderRuleService.js +72 -23
  377. package/build/dist/Server/Services/AlertReminderRuleService.js.map +1 -1
  378. package/build/dist/Server/Services/DatabaseServerEndpointService.js +694 -0
  379. package/build/dist/Server/Services/DatabaseServerEndpointService.js.map +1 -0
  380. package/build/dist/Server/Services/DatabaseServerFeedService.js +110 -0
  381. package/build/dist/Server/Services/DatabaseServerFeedService.js.map +1 -0
  382. package/build/dist/Server/Services/DatabaseServerLabelRuleEngineService.js +272 -0
  383. package/build/dist/Server/Services/DatabaseServerLabelRuleEngineService.js.map +1 -0
  384. package/build/dist/Server/Services/DatabaseServerLabelRuleService.js +13 -0
  385. package/build/dist/Server/Services/DatabaseServerLabelRuleService.js.map +1 -0
  386. package/build/dist/Server/Services/DatabaseServerOwnerRuleEngineService.js +340 -0
  387. package/build/dist/Server/Services/DatabaseServerOwnerRuleEngineService.js.map +1 -0
  388. package/build/dist/Server/Services/DatabaseServerOwnerRuleService.js +13 -0
  389. package/build/dist/Server/Services/DatabaseServerOwnerRuleService.js.map +1 -0
  390. package/build/dist/Server/Services/DatabaseServerOwnerTeamService.js +160 -0
  391. package/build/dist/Server/Services/DatabaseServerOwnerTeamService.js.map +1 -0
  392. package/build/dist/Server/Services/DatabaseServerOwnerUserService.js +153 -0
  393. package/build/dist/Server/Services/DatabaseServerOwnerUserService.js.map +1 -0
  394. package/build/dist/Server/Services/DatabaseServerService.js +3272 -0
  395. package/build/dist/Server/Services/DatabaseServerService.js.map +1 -0
  396. package/build/dist/Server/Services/DatabaseService.js +8 -4
  397. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  398. package/build/dist/Server/Services/DockerResourceService.js +30 -3
  399. package/build/dist/Server/Services/DockerResourceService.js.map +1 -1
  400. package/build/dist/Server/Services/IncidentReminderRuleService.js +73 -23
  401. package/build/dist/Server/Services/IncidentReminderRuleService.js.map +1 -1
  402. package/build/dist/Server/Services/Index.js +16 -0
  403. package/build/dist/Server/Services/Index.js.map +1 -1
  404. package/build/dist/Server/Services/InventoryItemService.js +88 -5
  405. package/build/dist/Server/Services/InventoryItemService.js.map +1 -1
  406. package/build/dist/Server/Services/IoTDeviceService.js +111 -24
  407. package/build/dist/Server/Services/IoTDeviceService.js.map +1 -1
  408. package/build/dist/Server/Services/OpenTelemetryIngestService.js +24 -9
  409. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  410. package/build/dist/Server/Services/PodmanResourceService.js +30 -3
  411. package/build/dist/Server/Services/PodmanResourceService.js.map +1 -1
  412. package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js +75 -23
  413. package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js.map +1 -1
  414. package/build/dist/Server/Services/ServiceService.js +1 -1
  415. package/build/dist/Server/Services/ServiceService.js.map +1 -1
  416. package/build/dist/Server/Services/TelemetryUsageBillingService.js +23 -2
  417. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  418. package/build/dist/Server/Services/UserProjectSsoConsentService.js +79 -0
  419. package/build/dist/Server/Services/UserProjectSsoConsentService.js.map +1 -0
  420. package/build/dist/Server/Services/UserService.js +13 -1
  421. package/build/dist/Server/Services/UserService.js.map +1 -1
  422. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +18 -0
  423. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
  424. package/build/dist/Server/Types/Database/QueryHelper.js +26 -1
  425. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  426. package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js +46 -0
  427. package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js.map +1 -1
  428. package/build/dist/Server/Utils/Database/AffectedResourceRelations.js +6 -0
  429. package/build/dist/Server/Utils/Database/AffectedResourceRelations.js.map +1 -1
  430. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js +134 -13
  431. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js.map +1 -1
  432. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +22 -6
  433. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  434. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +1489 -524
  435. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  436. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +22 -6
  437. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  438. package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js +196 -6
  439. package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js.map +1 -1
  440. package/build/dist/Server/Utils/Monitor/MonitorResource.js +36 -9
  441. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  442. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +1 -0
  443. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -1
  444. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +175 -17
  445. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -1
  446. package/build/dist/Server/Utils/Monitor/PerSeriesResolutionRootCause.js +29 -0
  447. package/build/dist/Server/Utils/Monitor/PerSeriesResolutionRootCause.js.map +1 -0
  448. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +211 -0
  449. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js.map +1 -1
  450. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +82 -10
  451. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
  452. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +25 -0
  453. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -1
  454. package/build/dist/Server/Utils/StartServer.js +20 -4
  455. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  456. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js +2 -0
  457. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js.map +1 -1
  458. package/build/dist/Server/Utils/Telemetry/DatabaseEndpointDiscovery.js +442 -0
  459. package/build/dist/Server/Utils/Telemetry/DatabaseEndpointDiscovery.js.map +1 -0
  460. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +5 -1
  461. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
  462. package/build/dist/Server/Utils/Telemetry/LogExceptionExtractor.js +15 -1
  463. package/build/dist/Server/Utils/Telemetry/LogExceptionExtractor.js.map +1 -1
  464. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +121 -5
  465. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -1
  466. package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js +12 -0
  467. package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js.map +1 -1
  468. package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js +438 -36
  469. package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js.map +1 -1
  470. package/build/dist/Server/Utils/Telemetry/Telemetry.js +12 -0
  471. package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
  472. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +17 -18
  473. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
  474. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js +16 -10
  475. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js.map +1 -1
  476. package/build/dist/Types/AI/AIResourceContext.js +7 -0
  477. package/build/dist/Types/AI/AIResourceContext.js.map +1 -1
  478. package/build/dist/Types/Dashboard/DashboardTemplates.js +2 -1
  479. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  480. package/build/dist/Types/DatabaseServer/DatabaseConnectionSpan.js +71 -0
  481. package/build/dist/Types/DatabaseServer/DatabaseConnectionSpan.js.map +1 -0
  482. package/build/dist/Types/DatabaseServer/DatabaseContainerClassifier.js +1462 -0
  483. package/build/dist/Types/DatabaseServer/DatabaseContainerClassifier.js.map +1 -0
  484. package/build/dist/Types/DatabaseServer/DatabaseContainerCommand.js +691 -0
  485. package/build/dist/Types/DatabaseServer/DatabaseContainerCommand.js.map +1 -0
  486. package/build/dist/Types/DatabaseServer/DatabaseEndpoint.js +1407 -0
  487. package/build/dist/Types/DatabaseServer/DatabaseEndpoint.js.map +1 -0
  488. package/build/dist/Types/DatabaseServer/DatabaseServerDiscoverySource.js +60 -0
  489. package/build/dist/Types/DatabaseServer/DatabaseServerDiscoverySource.js.map +1 -0
  490. package/build/dist/Types/DatabaseServer/DatabaseServerMetricCatalog.js +804 -0
  491. package/build/dist/Types/DatabaseServer/DatabaseServerMetricCatalog.js.map +1 -0
  492. package/build/dist/Types/DatabaseServer/DatabaseSystem.js +1860 -0
  493. package/build/dist/Types/DatabaseServer/DatabaseSystem.js.map +1 -0
  494. package/build/dist/Types/DatabaseServer/DatabaseTelemetryResolver.js +406 -0
  495. package/build/dist/Types/DatabaseServer/DatabaseTelemetryResolver.js.map +1 -0
  496. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  497. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  498. package/build/dist/Types/Monitor/CephAlertTemplates.js +18 -0
  499. package/build/dist/Types/Monitor/CephAlertTemplates.js.map +1 -1
  500. package/build/dist/Types/Monitor/DatabaseAlertTemplates.js +1518 -0
  501. package/build/dist/Types/Monitor/DatabaseAlertTemplates.js.map +1 -0
  502. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +57 -24
  503. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
  504. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js +104 -18
  505. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js.map +1 -1
  506. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +80 -3
  507. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
  508. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +10 -3
  509. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
  510. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +29 -0
  511. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
  512. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js +21 -6
  513. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js.map +1 -1
  514. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +25 -0
  515. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -1
  516. package/build/dist/Types/NetworkDevice/DiscoveredHostNamingStatus.js +136 -0
  517. package/build/dist/Types/NetworkDevice/DiscoveredHostNamingStatus.js.map +1 -0
  518. package/build/dist/Types/Permission.js +234 -0
  519. package/build/dist/Types/Permission.js.map +1 -1
  520. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +10 -0
  521. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
  522. package/build/dist/Types/Rules/RuleRun.js +4 -0
  523. package/build/dist/Types/Rules/RuleRun.js.map +1 -1
  524. package/build/dist/Types/Telemetry/EntityType.js +23 -0
  525. package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
  526. package/build/dist/Types/Telemetry/ResourceFacetCatalog.js +14 -0
  527. package/build/dist/Types/Telemetry/ResourceFacetCatalog.js.map +1 -1
  528. package/build/dist/Types/Telemetry/ServiceType.js +8 -0
  529. package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
  530. package/build/dist/UI/Components/Banner/Banner.js +1 -1
  531. package/build/dist/UI/Components/Banner/Banner.js.map +1 -1
  532. package/build/dist/UI/Components/Card/Card.js +1 -1
  533. package/build/dist/UI/Components/Card/Card.js.map +1 -1
  534. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +2 -2
  535. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  536. package/build/dist/UI/Components/Charts/Line/LineChart.js +1 -1
  537. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  538. package/build/dist/UI/Components/CommandPalette/CommandPalette.js +1 -1
  539. package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -1
  540. package/build/dist/UI/Components/Date/StartAndEndDate.js +5 -5
  541. package/build/dist/UI/Components/Date/StartAndEndDate.js.map +1 -1
  542. package/build/dist/UI/Components/Diagram/HorizontalStepChain.js +1 -1
  543. package/build/dist/UI/Components/Diagram/HorizontalStepChain.js.map +1 -1
  544. package/build/dist/UI/Components/Feed/FeedOptionsButton.js +1 -1
  545. package/build/dist/UI/Components/Feed/FeedOptionsButton.js.map +1 -1
  546. package/build/dist/UI/Components/Forms/BasicForm.js +1 -1
  547. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  548. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js +1 -1
  549. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js.map +1 -1
  550. package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js +1 -1
  551. package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js.map +1 -1
  552. package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js +1 -1
  553. package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js.map +1 -1
  554. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +1 -1
  555. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
  556. package/build/dist/UI/Components/Modal/ModalFooter.js +1 -1
  557. package/build/dist/UI/Components/Modal/ModalFooter.js.map +1 -1
  558. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +2 -2
  559. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  560. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +4 -4
  561. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  562. package/build/dist/UI/Components/Navbar/NavBar.js +9 -2
  563. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  564. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +2 -2
  565. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  566. package/build/dist/UI/Components/Page/Page.js +1 -1
  567. package/build/dist/UI/Components/Page/Page.js.map +1 -1
  568. package/build/dist/UI/Components/Pagination/Pagination.js +3 -3
  569. package/build/dist/UI/Components/Pagination/Pagination.js.map +1 -1
  570. package/build/dist/UI/Components/ProgressButtons/ProgressButtonItem.js +1 -1
  571. package/build/dist/UI/Components/ProgressButtons/ProgressButtonItem.js.map +1 -1
  572. package/build/dist/UI/Components/SideMenu/SideMenu.js +4 -1
  573. package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
  574. package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js +3 -1
  575. package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js.map +1 -1
  576. package/build/dist/UI/Components/StatusPage/ResourceList.js +6 -6
  577. package/build/dist/UI/Components/StatusPage/ResourceList.js.map +1 -1
  578. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +1 -1
  579. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
  580. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js +1 -1
  581. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js.map +1 -1
  582. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js +1 -1
  583. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js.map +1 -1
  584. package/build/dist/UI/Components/Workflow/ComponentsModal.js +2 -2
  585. package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
  586. package/build/dist/UI/Components/Workflow/StepTraceViewer.js +1 -1
  587. package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -1
  588. package/build/dist/UI/Utils/Navigation.js +66 -33
  589. package/build/dist/UI/Utils/Navigation.js.map +1 -1
  590. package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js +7 -0
  591. package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js.map +1 -1
  592. package/build/dist/UI/Utils/TelemetryService.js +3 -2
  593. package/build/dist/UI/Utils/TelemetryService.js.map +1 -1
  594. package/build/dist/Utils/LabelRuleImportExport.js +2 -0
  595. package/build/dist/Utils/LabelRuleImportExport.js.map +1 -1
  596. package/build/dist/Utils/MetricUnitUtil.js +77 -13
  597. package/build/dist/Utils/MetricUnitUtil.js.map +1 -1
  598. package/build/dist/Utils/Monitor/MetricValueFormatter.js +58 -13
  599. package/build/dist/Utils/Monitor/MetricValueFormatter.js.map +1 -1
  600. package/build/dist/Utils/Monitor/PlatformMetricUnitUtil.js +161 -0
  601. package/build/dist/Utils/Monitor/PlatformMetricUnitUtil.js.map +1 -0
  602. package/build/dist/Utils/Monitor/PlatformResourceIdentity.js +323 -0
  603. package/build/dist/Utils/Monitor/PlatformResourceIdentity.js.map +1 -0
  604. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.js +270 -0
  605. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.js.map +1 -0
  606. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js +23 -0
  607. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js.map +1 -1
  608. package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js +61 -0
  609. package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js.map +1 -1
  610. package/build/dist/Utils/Telemetry/DatabaseServerEntityKeys.js +178 -0
  611. package/build/dist/Utils/Telemetry/DatabaseServerEntityKeys.js.map +1 -0
  612. package/build/dist/Utils/Telemetry/EntityKey.js +133 -0
  613. package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
  614. package/build/dist/Utils/ValueFormatter.js +15 -0
  615. package/build/dist/Utils/ValueFormatter.js.map +1 -1
  616. package/package.json +1 -1
  617. package/tsconfig.tests.json +7 -5
@@ -0,0 +1,1161 @@
1
+ import {
2
+ DATABASE_SERVER_INSTANCE_ATTRIBUTE_KEYS,
3
+ DATABASE_SERVER_METRICS,
4
+ DatabaseServerMetricDefinition,
5
+ findDatabaseServerMetricByName,
6
+ getDatabaseServerMetricGroupKeys,
7
+ getDatabaseServerMetricId,
8
+ getDatabaseServerMetrics,
9
+ } from "../../../Types/DatabaseServer/DatabaseServerMetricCatalog";
10
+ import {
11
+ DatabaseSystemDescriptor,
12
+ getDatabaseSystemDescriptor,
13
+ } from "../../../Types/DatabaseServer/DatabaseSystem";
14
+ import AggregationType from "../../../Types/BaseDatabase/AggregationType";
15
+ import { describe, expect, test } from "@jest/globals";
16
+ import fs from "fs";
17
+ import path from "path";
18
+
19
+ const AGENT_CONFIG_DIR: string = path.join(
20
+ __dirname,
21
+ "..",
22
+ "..",
23
+ "..",
24
+ "..",
25
+ "..",
26
+ "agents",
27
+ "DatabaseAgent",
28
+ "configs",
29
+ );
30
+
31
+ // The Database Agent's config for a receiver (sqlserver.yaml, oracledb.yaml).
32
+ function readAgentConfig(receiver: string): string {
33
+ return fs.readFileSync(
34
+ path.join(AGENT_CONFIG_DIR, `${receiver}.yaml`),
35
+ "utf8",
36
+ );
37
+ }
38
+
39
+ const CURATED_SYSTEMS: Array<string> = [
40
+ "postgresql",
41
+ "mysql",
42
+ "redis",
43
+ "mongodb",
44
+ "microsoft.sql_server",
45
+ "oracle.db",
46
+ "elasticsearch",
47
+ "memcached",
48
+ ];
49
+
50
+ /*
51
+ * Cumulative monotonic sums per the receivers' metadata.yaml (research map
52
+ * otel-db-receivers.md §2). Each MUST be a "counter" — charting the raw value
53
+ * would draw an ever-rising line.
54
+ */
55
+ const KNOWN_CUMULATIVE_COUNTERS: Array<string> = [
56
+ "postgresql.commits",
57
+ "postgresql.rollbacks",
58
+ "mysql.handlers",
59
+ "mysql.row_operations",
60
+ "mysql.row_locks",
61
+ "redis.commands.processed",
62
+ "redis.keyspace.hits",
63
+ "redis.keyspace.misses",
64
+ "redis.keys.evicted",
65
+ "mongodb.operation.count",
66
+ "mongodb.operation.time",
67
+ "mongodb.cache.operations",
68
+ "oracledb.executions",
69
+ "oracledb.user_commits",
70
+ "oracledb.physical_reads",
71
+ "oracledb.db.time",
72
+ /*
73
+ * Named "*.rate", but over a direct connection the receiver passes SQL
74
+ * Server's cumulative cntr_value through: a live capture read
75
+ * batch.request.rate 8, 13, 18, 23, 28, 33 on consecutive 10 s scrapes of
76
+ * an idle server. Charted as a gauge they would show an ever-growing
77
+ * number labelled per second.
78
+ */
79
+ "sqlserver.batch.request.rate",
80
+ "sqlserver.batch.sql_compilation.rate",
81
+ "sqlserver.lock.wait.rate",
82
+ "sqlserver.deadlock.rate",
83
+ "elasticsearch.node.operations.completed",
84
+ "memcached.operations",
85
+ "memcached.commands",
86
+ "memcached.evictions",
87
+ ];
88
+
89
+ /*
90
+ * Receiver-computed per-second gauges and point-in-time values: never a
91
+ * counter (a rate of a rate is meaningless).
92
+ */
93
+ const KNOWN_GAUGES: Array<string> = [
94
+ "postgresql.backends",
95
+ "postgresql.connection.max",
96
+ "postgresql.db_size",
97
+ "redis.commands",
98
+ "redis.memory.used",
99
+ "sqlserver.processes.blocked",
100
+ "sqlserver.page.buffer_cache.hit_ratio",
101
+ "oracledb.sessions.usage",
102
+ "oracledb.sga.usage",
103
+ "oracledb.tablespace.utilization",
104
+ // Non-monotonic sums: a level, however the receiver types it.
105
+ "mysql.buffer_pool.pages",
106
+ "elasticsearch.cluster.health",
107
+ "elasticsearch.cluster.nodes",
108
+ "elasticsearch.cluster.shards",
109
+ "elasticsearch.cluster.pending_tasks",
110
+ "elasticsearch.node.fs.disk.available",
111
+ "jvm.memory.heap.utilization",
112
+ "memcached.connections.current",
113
+ "memcached.bytes",
114
+ "memcached.current_items",
115
+ ];
116
+
117
+ /*
118
+ * Off-by-default receiver metrics (otel-db-receivers.md §8.5) the Database
119
+ * Agent does NOT switch on. Nothing arrives for them on a default setup, so
120
+ * none of these may appear.
121
+ */
122
+ const OFF_BY_DEFAULT: Array<string> = [
123
+ "postgresql.deadlocks",
124
+ "postgresql.blks_hit",
125
+ "postgresql.blks_read",
126
+ "postgresql.database.locks",
127
+ "mysql.query.count",
128
+ "mysql.query.slow.count",
129
+ "mysql.commands",
130
+ "mysql.connection.count",
131
+ "mysql.replica.time_behind_source",
132
+ "redis.maxmemory",
133
+ "redis.cmd.latency",
134
+ "mongodb.replica_set.lag",
135
+ "mongodb.lock.deadlock.count",
136
+ "sqlserver.lock.timeout.rate",
137
+ "sqlserver.memory.usage",
138
+ "oracledb.logons",
139
+ "oracledb.transaction.rollbacks",
140
+ ];
141
+
142
+ /*
143
+ * Default-on in the receiver's metadata, yet measured never to arrive on
144
+ * the Database Agent's default setups (collector-contrib 0.161.0): SQL
145
+ * Server 2022 on Linux, connected directly, has no Windows performance
146
+ * counters behind the first two; Oracle Free 23 connected to its pluggable
147
+ * database (FREEPDB1) returned neither of the last two in 90 seconds. A
148
+ * tile for one of them would stay empty forever.
149
+ */
150
+ const NEVER_ARRIVE_ON_DEFAULT_SETUPS: Array<string> = [
151
+ "sqlserver.transaction.rate",
152
+ "sqlserver.transaction_log.usage",
153
+ "oracledb.processes.usage",
154
+ "oracledb.sessions.limit",
155
+ ];
156
+
157
+ /*
158
+ * The datapoint attributes each curated metric carries, from the v0.161.0
159
+ * receivers' metadata.yaml (with name_override applied, as ingest stores
160
+ * them). Every one of them splits the metric into several series, so each
161
+ * catalog entry has to say what happens to it: pinned by `attributes`,
162
+ * added up / maxed through `seriesKeys`, or pooled as a repeat through
163
+ * `duplicatedAcross`.
164
+ */
165
+ const RECEIVER_DATAPOINT_ATTRIBUTES: Record<string, Array<string>> = {
166
+ "postgresql.backends": ["db.namespace"],
167
+ "postgresql.commits": ["db.namespace"],
168
+ "postgresql.rollbacks": ["db.namespace"],
169
+ "postgresql.db_size": ["db.namespace"],
170
+ "postgresql.replication.data_delay": ["replication_client"],
171
+ "mysql.threads": ["kind"],
172
+ "mysql.buffer_pool.usage": ["status"],
173
+ "mysql.handlers": ["kind"],
174
+ "mysql.row_operations": ["operation"],
175
+ "mysql.row_locks": ["kind"],
176
+ "mongodb.connection.count": ["type", "db.namespace"],
177
+ "mongodb.memory.usage": ["type", "db.namespace"],
178
+ "mongodb.data.size": ["db.namespace"],
179
+ "mongodb.operation.count": ["operation"],
180
+ "mongodb.operation.time": ["operation"],
181
+ "mongodb.cache.operations": ["type"],
182
+ "sqlserver.page.life_expectancy": ["performance_counter.object_name"],
183
+ "oracledb.sessions.usage": [
184
+ "session_type",
185
+ "session_status",
186
+ "oracle.db.pdb",
187
+ ],
188
+ "oracledb.tablespace_size.usage": ["tablespace_name", "oracle.db.pdb"],
189
+ "oracledb.executions": ["oracle.db.pdb"],
190
+ "oracledb.user_commits": ["oracle.db.pdb"],
191
+ "oracledb.physical_reads": ["oracle.db.pdb"],
192
+ "oracledb.db.time": ["oracledb.session.type"],
193
+ "oracledb.sga.usage": ["oracledb.sga.component.name"],
194
+ "oracledb.tablespace.utilization": ["tablespace_name", "oracle.db.pdb"],
195
+ "mysql.buffer_pool.pages": ["kind"],
196
+ "elasticsearch.cluster.health": ["status"],
197
+ "elasticsearch.cluster.shards": ["state"],
198
+ "elasticsearch.node.operations.completed": ["operation"],
199
+ // Recorded once per node: the node is a resource attribute.
200
+ "elasticsearch.node.fs.disk.available": ["resource.elasticsearch.node.name"],
201
+ "jvm.memory.heap.utilization": ["resource.elasticsearch.node.name"],
202
+ "memcached.commands": ["command"],
203
+ "memcached.operations": ["type", "operation"],
204
+ };
205
+
206
+ /*
207
+ * Every metric the e2e run's Database Agents (collector-contrib 0.161.0)
208
+ * delivered for these engines, read back from ClickHouse: Elasticsearch
209
+ * 8.15.3, OpenSearch 2.17.1 (the same receiver), Memcached 1.6, MySQL
210
+ * 8.4.11 and MariaDB 11.4.13 (the same receiver). A curated tile for
211
+ * anything else would stay empty.
212
+ */
213
+ const SEEN_ARRIVING_FROM_AGENT: Record<string, Array<string>> = {
214
+ mysql: [
215
+ "mysql.buffer_pool.data_pages",
216
+ "mysql.buffer_pool.limit",
217
+ "mysql.buffer_pool.operations",
218
+ "mysql.buffer_pool.page_flushes",
219
+ "mysql.buffer_pool.pages",
220
+ "mysql.buffer_pool.usage",
221
+ "mysql.client.network.io",
222
+ "mysql.commands",
223
+ "mysql.connection.count",
224
+ "mysql.connection.errors",
225
+ "mysql.double_writes",
226
+ "mysql.handlers",
227
+ "mysql.locks",
228
+ "mysql.log_operations",
229
+ "mysql.max_used_connections",
230
+ "mysql.mysqlx_connections",
231
+ "mysql.opened_resources",
232
+ "mysql.operations",
233
+ "mysql.page_operations",
234
+ "mysql.prepared_statements",
235
+ "mysql.query.count",
236
+ "mysql.query.slow.count",
237
+ "mysql.row_locks",
238
+ "mysql.row_operations",
239
+ "mysql.sorts",
240
+ "mysql.threads",
241
+ "mysql.tmp_resources",
242
+ "mysql.uptime",
243
+ ],
244
+ // No mysql.row_operations: MariaDB has no Innodb_rows_* status counters.
245
+ mariadb: [
246
+ "mysql.buffer_pool.data_pages",
247
+ "mysql.buffer_pool.limit",
248
+ "mysql.buffer_pool.operations",
249
+ "mysql.buffer_pool.page_flushes",
250
+ "mysql.buffer_pool.pages",
251
+ "mysql.buffer_pool.usage",
252
+ "mysql.client.network.io",
253
+ "mysql.commands",
254
+ "mysql.connection.count",
255
+ "mysql.connection.errors",
256
+ "mysql.double_writes",
257
+ "mysql.handlers",
258
+ "mysql.locks",
259
+ "mysql.log_operations",
260
+ "mysql.max_used_connections",
261
+ "mysql.opened_resources",
262
+ "mysql.operations",
263
+ "mysql.page_operations",
264
+ "mysql.prepared_statements",
265
+ "mysql.query.count",
266
+ "mysql.query.slow.count",
267
+ "mysql.row_locks",
268
+ "mysql.sorts",
269
+ "mysql.threads",
270
+ "mysql.tmp_resources",
271
+ "mysql.uptime",
272
+ ],
273
+ elasticsearch: [
274
+ "elasticsearch.breaker.memory.estimated",
275
+ "elasticsearch.breaker.memory.limit",
276
+ "elasticsearch.breaker.tripped",
277
+ "elasticsearch.cluster.data_nodes",
278
+ "elasticsearch.cluster.health",
279
+ "elasticsearch.cluster.in_flight_fetch",
280
+ "elasticsearch.cluster.nodes",
281
+ "elasticsearch.cluster.pending_tasks",
282
+ "elasticsearch.cluster.shards",
283
+ "elasticsearch.cluster.state_queue",
284
+ "elasticsearch.index.documents",
285
+ "elasticsearch.index.operations.completed",
286
+ "elasticsearch.node.cache.evictions",
287
+ "elasticsearch.node.documents",
288
+ "elasticsearch.node.fs.disk.available",
289
+ "elasticsearch.node.fs.disk.total",
290
+ "elasticsearch.node.http.connections",
291
+ "elasticsearch.node.operations.completed",
292
+ "elasticsearch.node.operations.current",
293
+ "elasticsearch.node.thread_pool.tasks.finished",
294
+ "elasticsearch.node.thread_pool.tasks.queued",
295
+ "elasticsearch.os.cpu.usage",
296
+ "elasticsearch.process.cpu.usage",
297
+ "jvm.memory.heap.max",
298
+ "jvm.memory.heap.used",
299
+ "jvm.memory.heap.utilization",
300
+ ],
301
+ opensearch: [
302
+ "elasticsearch.breaker.tripped",
303
+ "elasticsearch.cluster.data_nodes",
304
+ "elasticsearch.cluster.health",
305
+ "elasticsearch.cluster.nodes",
306
+ "elasticsearch.cluster.pending_tasks",
307
+ "elasticsearch.cluster.shards",
308
+ "elasticsearch.index.documents",
309
+ "elasticsearch.node.documents",
310
+ "elasticsearch.node.fs.disk.available",
311
+ "elasticsearch.node.operations.completed",
312
+ "elasticsearch.node.operations.current",
313
+ "elasticsearch.node.thread_pool.tasks.finished",
314
+ "jvm.memory.heap.max",
315
+ "jvm.memory.heap.used",
316
+ "jvm.memory.heap.utilization",
317
+ ],
318
+ memcached: [
319
+ "memcached.bytes",
320
+ "memcached.commands",
321
+ "memcached.connections.current",
322
+ "memcached.connections.total",
323
+ "memcached.cpu.usage",
324
+ "memcached.current_items",
325
+ "memcached.evictions",
326
+ "memcached.network",
327
+ "memcached.operation_hit_ratio",
328
+ "memcached.operations",
329
+ "memcached.threads",
330
+ ],
331
+ };
332
+
333
+ function metricByName(name: string): DatabaseServerMetricDefinition {
334
+ const metric: DatabaseServerMetricDefinition | undefined =
335
+ DATABASE_SERVER_METRICS.find(
336
+ (candidate: DatabaseServerMetricDefinition): boolean => {
337
+ return candidate.metricName === name;
338
+ },
339
+ );
340
+ expect(metric).toBeDefined();
341
+ return metric!;
342
+ }
343
+
344
+ function entriesNamed(name: string): Array<DatabaseServerMetricDefinition> {
345
+ return DATABASE_SERVER_METRICS.filter(
346
+ (candidate: DatabaseServerMetricDefinition): boolean => {
347
+ return candidate.metricName === name;
348
+ },
349
+ );
350
+ }
351
+
352
+ describe("DATABASE_SERVER_METRICS", () => {
353
+ test.each(CURATED_SYSTEMS)("%s has 5-8 curated metrics", (system: string) => {
354
+ const count: number = getDatabaseServerMetrics(system).length;
355
+ expect(count).toBeGreaterThanOrEqual(5);
356
+ expect(count).toBeLessThanOrEqual(8);
357
+ });
358
+
359
+ test("only the curated engines have entries", () => {
360
+ const systems: Set<string> = new Set<string>(
361
+ DATABASE_SERVER_METRICS.map(
362
+ (metric: DatabaseServerMetricDefinition): string => {
363
+ return metric.system;
364
+ },
365
+ ),
366
+ );
367
+ expect(Array.from(systems).sort()).toEqual([...CURATED_SYSTEMS].sort());
368
+ });
369
+
370
+ test("entry ids are unique; names are lowercase, as ingest stores them", () => {
371
+ const ids: Array<string> = DATABASE_SERVER_METRICS.map(
372
+ (metric: DatabaseServerMetricDefinition): string => {
373
+ return getDatabaseServerMetricId(metric);
374
+ },
375
+ );
376
+ expect(new Set(ids).size).toBe(ids.length);
377
+ for (const metric of DATABASE_SERVER_METRICS) {
378
+ expect(metric.metricName).toBe(metric.metricName.toLowerCase());
379
+ expect(metric.metricName).toBe(metric.metricName.trim());
380
+ }
381
+ });
382
+
383
+ test("a metric backs several entries only when each pins a different value", () => {
384
+ const byName: Map<
385
+ string,
386
+ Array<DatabaseServerMetricDefinition>
387
+ > = new Map();
388
+ for (const metric of DATABASE_SERVER_METRICS) {
389
+ byName.set(metric.metricName, [
390
+ ...(byName.get(metric.metricName) || []),
391
+ metric,
392
+ ]);
393
+ }
394
+ for (const [, entries] of byName) {
395
+ if (entries.length < 2) {
396
+ continue;
397
+ }
398
+ for (const entry of entries) {
399
+ expect(Object.keys(entry.attributes || {}).length).toBeGreaterThan(0);
400
+ }
401
+ }
402
+ });
403
+
404
+ test("every metric carries its engine's receiver prefix", () => {
405
+ for (const metric of DATABASE_SERVER_METRICS) {
406
+ const descriptor: DatabaseSystemDescriptor | null =
407
+ getDatabaseSystemDescriptor(metric.system);
408
+ expect(descriptor).not.toBeNull();
409
+ /*
410
+ * The Elasticsearch receiver also emits the node JVM's `jvm.*`
411
+ * metrics in the same batch — the one sanctioned exception.
412
+ */
413
+ if (
414
+ metric.system === "elasticsearch" &&
415
+ metric.metricName.startsWith("jvm.")
416
+ ) {
417
+ continue;
418
+ }
419
+ expect(
420
+ descriptor!.receiverMetricPrefixes.some((prefix: string): boolean => {
421
+ return metric.metricName.startsWith(prefix);
422
+ }),
423
+ ).toBe(true);
424
+ }
425
+ });
426
+
427
+ test("every entry is fully described", () => {
428
+ for (const metric of DATABASE_SERVER_METRICS) {
429
+ expect(metric.title.trim().length).toBeGreaterThan(0);
430
+ expect(metric.description.trim().length).toBeGreaterThan(0);
431
+ expect(metric.unit.trim().length).toBeGreaterThan(0);
432
+ expect(Object.values(AggregationType)).toContain(metric.aggregation);
433
+ expect(["gauge", "counter"]).toContain(metric.kind);
434
+ expect(["sum", "max", "min", "avg"]).toContain(metric.seriesCombine);
435
+ }
436
+ });
437
+
438
+ test("titles are unique within an engine", () => {
439
+ for (const system of CURATED_SYSTEMS) {
440
+ const titles: Array<string> = getDatabaseServerMetrics(system).map(
441
+ (metric: DatabaseServerMetricDefinition): string => {
442
+ return metric.title;
443
+ },
444
+ );
445
+ expect(new Set(titles).size).toBe(titles.length);
446
+ }
447
+ });
448
+
449
+ test.each(KNOWN_CUMULATIVE_COUNTERS)(
450
+ "%s is a counter (charted as a rate)",
451
+ (name: string) => {
452
+ expect(metricByName(name).kind).toBe("counter");
453
+ },
454
+ );
455
+
456
+ test("counters read Max per series per bucket, and their rates add up", () => {
457
+ for (const metric of DATABASE_SERVER_METRICS) {
458
+ if (metric.kind === "counter") {
459
+ // The latest cumulative value of ONE series in the bucket.
460
+ expect(metric.aggregation).toBe(AggregationType.Max);
461
+ // Rates of separate series are parts of one total.
462
+ expect(metric.seriesCombine).toBe("sum");
463
+ // Counters are split by their whole attribute set, never by a list.
464
+ expect(metric.seriesKeys).toBeUndefined();
465
+ expect(metric.duplicatedAcross).toBeUndefined();
466
+ }
467
+ }
468
+ });
469
+
470
+ test.each(KNOWN_GAUGES)("%s is a gauge", (name: string) => {
471
+ expect(metricByName(name).kind).toBe("gauge");
472
+ });
473
+
474
+ test("SQL Server's *.rate metrics are charted as rates of running totals", () => {
475
+ /*
476
+ * The agent connects directly, where the receiver reports each
477
+ * "per second" counter as SQL Server's cumulative cntr_value.
478
+ */
479
+ const kinds: Record<string, string> = {};
480
+ for (const metric of getDatabaseServerMetrics("microsoft.sql_server")) {
481
+ kinds[metric.metricName] = metric.kind;
482
+ }
483
+ expect(kinds).toEqual({
484
+ "sqlserver.user.connection.count": "gauge",
485
+ "sqlserver.batch.request.rate": "counter",
486
+ "sqlserver.batch.sql_compilation.rate": "counter",
487
+ "sqlserver.page.buffer_cache.hit_ratio": "gauge",
488
+ "sqlserver.page.life_expectancy": "gauge",
489
+ "sqlserver.lock.wait.rate": "counter",
490
+ "sqlserver.deadlock.rate": "counter",
491
+ "sqlserver.processes.blocked": "gauge",
492
+ });
493
+ for (const metric of getDatabaseServerMetrics("microsoft.sql_server")) {
494
+ if (metric.kind === "counter") {
495
+ // A rate is computed from the latest total in each bucket.
496
+ expect(metric.aggregation).toBe(AggregationType.Max);
497
+ expect(metric.unit).not.toContain("/s");
498
+ }
499
+ }
500
+ });
501
+
502
+ test("every engine has at least one gauge for the Overview tiles", () => {
503
+ for (const system of CURATED_SYSTEMS) {
504
+ expect(
505
+ getDatabaseServerMetrics(system).some(
506
+ (metric: DatabaseServerMetricDefinition): boolean => {
507
+ return metric.kind === "gauge";
508
+ },
509
+ ),
510
+ ).toBe(true);
511
+ }
512
+ });
513
+
514
+ test.each(OFF_BY_DEFAULT)(
515
+ "%s (off by default, and left off by the agent) is not curated",
516
+ (name: string) => {
517
+ expect(
518
+ DATABASE_SERVER_METRICS.some(
519
+ (metric: DatabaseServerMetricDefinition): boolean => {
520
+ return metric.metricName === name;
521
+ },
522
+ ),
523
+ ).toBe(false);
524
+ },
525
+ );
526
+
527
+ test.each(NEVER_ARRIVE_ON_DEFAULT_SETUPS)(
528
+ "%s (never arrives on the agent's default setup) is not curated",
529
+ (name: string) => {
530
+ expect(entriesNamed(name)).toEqual([]);
531
+ },
532
+ );
533
+
534
+ /*
535
+ * An optional receiver metric is curated only because the Database Agent
536
+ * switches it on; if the agent's config stopped doing so, the tile would
537
+ * go empty. Every other entry must not be switched OFF by the agent.
538
+ */
539
+ test("every off-by-default entry is switched on by the agent's config for its receiver", () => {
540
+ const optional: Array<DatabaseServerMetricDefinition> =
541
+ DATABASE_SERVER_METRICS.filter(
542
+ (metric: DatabaseServerMetricDefinition): boolean => {
543
+ return metric.enabledByDefault === false;
544
+ },
545
+ );
546
+ expect(
547
+ optional
548
+ .map((metric: DatabaseServerMetricDefinition): string => {
549
+ return metric.metricName;
550
+ })
551
+ .sort(),
552
+ ).toEqual([
553
+ "jvm.memory.heap.utilization",
554
+ "oracledb.db.time",
555
+ "oracledb.sga.usage",
556
+ "oracledb.tablespace.utilization",
557
+ "sqlserver.deadlock.rate",
558
+ "sqlserver.processes.blocked",
559
+ ]);
560
+
561
+ for (const metric of optional) {
562
+ const receiver: string = getDatabaseSystemDescriptor(metric.system)!
563
+ .receiverTypes[0]!;
564
+ const config: string = readAgentConfig(receiver);
565
+ expect({
566
+ metric: metric.metricName,
567
+ enabledByAgent: config.includes(
568
+ ` ${metric.metricName}:\n enabled: true`,
569
+ ),
570
+ }).toEqual({ metric: metric.metricName, enabledByAgent: true });
571
+ // The tile's (i) tells a team with its own collector to switch it on.
572
+ expect(metric.description).toContain("Off by default");
573
+ expect(metric.description).toContain("Database Agent switches it on");
574
+ }
575
+ });
576
+
577
+ test("no default-on entry is switched off by the agent", () => {
578
+ for (const metric of DATABASE_SERVER_METRICS) {
579
+ const descriptor: DatabaseSystemDescriptor | null =
580
+ getDatabaseSystemDescriptor(metric.system);
581
+ const config: string = readAgentConfig(descriptor!.receiverTypes[0]!);
582
+ expect({
583
+ metric: metric.metricName,
584
+ disabled: config.includes(
585
+ ` ${metric.metricName}:\n enabled: false`,
586
+ ),
587
+ }).toEqual({ metric: metric.metricName, disabled: false });
588
+ if (metric.enabledByDefault !== false) {
589
+ expect(metric.description).not.toContain("Off by default");
590
+ }
591
+ }
592
+ });
593
+
594
+ test("SQL Server's tiles are the ones a directly connected server fills", () => {
595
+ expect(
596
+ getDatabaseServerMetrics("microsoft.sql_server").map(
597
+ (metric: DatabaseServerMetricDefinition): string => {
598
+ return metric.metricName;
599
+ },
600
+ ),
601
+ ).toEqual([
602
+ "sqlserver.user.connection.count",
603
+ "sqlserver.batch.request.rate",
604
+ "sqlserver.batch.sql_compilation.rate",
605
+ "sqlserver.page.buffer_cache.hit_ratio",
606
+ "sqlserver.page.life_expectancy",
607
+ "sqlserver.lock.wait.rate",
608
+ "sqlserver.deadlock.rate",
609
+ "sqlserver.processes.blocked",
610
+ ]);
611
+ });
612
+
613
+ test("Oracle's tiles are the ones a pluggable-database connection fills", () => {
614
+ expect(
615
+ getDatabaseServerMetrics("oracle.db").map(
616
+ (metric: DatabaseServerMetricDefinition): string => {
617
+ return metric.metricName;
618
+ },
619
+ ),
620
+ ).toEqual([
621
+ "oracledb.sessions.usage",
622
+ "oracledb.db.time",
623
+ "oracledb.sga.usage",
624
+ "oracledb.tablespace.utilization",
625
+ "oracledb.tablespace_size.usage",
626
+ "oracledb.executions",
627
+ "oracledb.user_commits",
628
+ "oracledb.physical_reads",
629
+ ]);
630
+ });
631
+ });
632
+
633
+ /*
634
+ * The audit's failure scenarios: a tile that averaged MongoDB's available
635
+ * connections into "Connections", averaged MySQL's lifetime Threads_created
636
+ * into "Threads", showed the per-database MEAN of PostgreSQL backends next
637
+ * to the server-wide max_connections, and took the Max of MySQL's row-lock
638
+ * waits and row-lock TIME counters.
639
+ */
640
+ describe("how each metric's series combine", () => {
641
+ test.each(Object.keys(RECEIVER_DATAPOINT_ATTRIBUTES))(
642
+ "%s declares what happens to every attribute that splits it",
643
+ (name: string) => {
644
+ const entries: Array<DatabaseServerMetricDefinition> = entriesNamed(name);
645
+ expect(entries.length).toBeGreaterThan(0);
646
+
647
+ for (const entry of entries) {
648
+ if (entry.kind === "counter") {
649
+ // Every distinct attribute set is its own series; nothing to list.
650
+ continue;
651
+ }
652
+ const maxOfMax: boolean =
653
+ entry.aggregation === AggregationType.Max &&
654
+ entry.seriesCombine === "max";
655
+ for (const attribute of RECEIVER_DATAPOINT_ATTRIBUTES[name]!) {
656
+ const declared: boolean =
657
+ Object.keys(entry.attributes || {}).includes(attribute) ||
658
+ (entry.seriesKeys || []).includes(attribute) ||
659
+ (entry.duplicatedAcross || []).includes(attribute) ||
660
+ maxOfMax;
661
+ expect({ metric: name, attribute, declared }).toEqual({
662
+ metric: name,
663
+ attribute,
664
+ declared: true,
665
+ });
666
+ }
667
+ }
668
+ },
669
+ );
670
+
671
+ test("MongoDB connections are the CURRENT ones, never averaged with available", () => {
672
+ const connections: DatabaseServerMetricDefinition = metricByName(
673
+ "mongodb.connection.count",
674
+ );
675
+ expect(connections.attributes).toEqual({ type: "current" });
676
+ // Repeated once per database by the receiver: pooled, not added up.
677
+ expect(connections.duplicatedAcross).toContain("db.namespace");
678
+ expect(connections.seriesKeys).toBeUndefined();
679
+ });
680
+
681
+ test("MongoDB memory is resident memory, not resident averaged with virtual", () => {
682
+ const memory: DatabaseServerMetricDefinition = metricByName(
683
+ "mongodb.memory.usage",
684
+ );
685
+ expect(memory.attributes).toEqual({ type: "resident" });
686
+ expect(memory.title).toBe("Resident memory");
687
+ });
688
+
689
+ test("MySQL threads are split into connected and running; created and cached never mix in", () => {
690
+ const threads: Array<DatabaseServerMetricDefinition> =
691
+ entriesNamed("mysql.threads");
692
+ expect(
693
+ threads.map((entry: DatabaseServerMetricDefinition) => {
694
+ return [entry.title, entry.attributes];
695
+ }),
696
+ ).toEqual([
697
+ ["Connected threads", { kind: "connected" }],
698
+ ["Running threads", { kind: "running" }],
699
+ ]);
700
+ });
701
+
702
+ test("PostgreSQL connections add up across databases", () => {
703
+ const backends: DatabaseServerMetricDefinition = metricByName(
704
+ "postgresql.backends",
705
+ );
706
+ expect(backends.seriesCombine).toBe("sum");
707
+ expect(backends.seriesKeys).toEqual([
708
+ "db.namespace",
709
+ "resource.postgresql.database.name",
710
+ ]);
711
+ });
712
+
713
+ test("the InnoDB buffer pool adds its clean and dirty pages", () => {
714
+ const pool: DatabaseServerMetricDefinition = metricByName(
715
+ "mysql.buffer_pool.usage",
716
+ );
717
+ expect(pool.seriesKeys).toEqual(["status"]);
718
+ expect(pool.seriesCombine).toBe("sum");
719
+ });
720
+
721
+ test("Oracle sessions add every type, status and PDB", () => {
722
+ const sessions: DatabaseServerMetricDefinition = metricByName(
723
+ "oracledb.sessions.usage",
724
+ );
725
+ expect(sessions.seriesKeys).toEqual([
726
+ "session_type",
727
+ "session_status",
728
+ "oracle.db.pdb",
729
+ ]);
730
+ expect(sessions.seriesCombine).toBe("sum");
731
+ });
732
+
733
+ test("row lock waits count waits, never the cumulative lock time", () => {
734
+ expect(metricByName("mysql.row_locks").attributes).toEqual({
735
+ kind: "waits",
736
+ });
737
+ });
738
+
739
+ test("worst-of metrics keep the worst series", () => {
740
+ for (const name of [
741
+ "postgresql.replication.data_delay",
742
+ "postgresql.db_size",
743
+ "postgresql.wal.age",
744
+ "oracledb.tablespace_size.usage",
745
+ "oracledb.tablespace.utilization",
746
+ ]) {
747
+ expect({ name, combine: metricByName(name).seriesCombine }).toEqual({
748
+ name,
749
+ combine: "max",
750
+ });
751
+ }
752
+ // The member that restarted last, not the longest-running one.
753
+ expect(metricByName("mysql.uptime").seriesCombine).toBe("min");
754
+ expect(metricByName("sqlserver.page.life_expectancy").seriesCombine).toBe(
755
+ "min",
756
+ );
757
+ });
758
+
759
+ test("ratios are averaged, never added", () => {
760
+ for (const name of [
761
+ "redis.memory.fragmentation_ratio",
762
+ "sqlserver.page.buffer_cache.hit_ratio",
763
+ ]) {
764
+ expect(metricByName(name).seriesCombine).toBe("avg");
765
+ }
766
+ });
767
+
768
+ test("settings are not added up across replicas", () => {
769
+ for (const name of [
770
+ "postgresql.connection.max",
771
+ "postgresql.database.count",
772
+ "mysql.buffer_pool.pages",
773
+ ]) {
774
+ expect(metricByName(name).seriesCombine).toBe("max");
775
+ }
776
+ });
777
+
778
+ test("Oracle DB time is the users' load: foreground sessions only, as a rate", () => {
779
+ const dbTime: DatabaseServerMetricDefinition =
780
+ metricByName("oracledb.db.time");
781
+ expect(dbTime.kind).toBe("counter");
782
+ expect(dbTime.attributes).toEqual({
783
+ "oracledb.session.type": "foreground",
784
+ });
785
+ expect(dbTime.unit).toBe("s");
786
+ });
787
+
788
+ test("the SGA adds its components; tablespace fullness is a 0..1 share", () => {
789
+ const sga: DatabaseServerMetricDefinition =
790
+ metricByName("oracledb.sga.usage");
791
+ expect(sga.seriesKeys).toEqual(["oracledb.sga.component.name"]);
792
+ expect(sga.seriesCombine).toBe("sum");
793
+ expect(sga.unit).toBe("bytes");
794
+
795
+ const fullest: DatabaseServerMetricDefinition = metricByName(
796
+ "oracledb.tablespace.utilization",
797
+ );
798
+ // The receiver reports 0..1 (unit "1"); the tile shows a percentage.
799
+ expect(fullest.unit).toBe("fraction");
800
+ expect(fullest.aggregation).toBe(AggregationType.Max);
801
+ });
802
+
803
+ test("SQL Server's blocked processes keep the peak of each interval", () => {
804
+ const blocked: DatabaseServerMetricDefinition = metricByName(
805
+ "sqlserver.processes.blocked",
806
+ );
807
+ expect(blocked.aggregation).toBe(AggregationType.Max);
808
+ expect(blocked.kind).toBe("gauge");
809
+ });
810
+ });
811
+
812
+ /*
813
+ * Regression (e2e, collector-contrib 0.161.0): MariaDB 11.4's Overview read
814
+ * "Buffer pool size 7.9 KiB". The mysql receiver fills
815
+ * mysql.buffer_pool.limit ("bytes") from information_schema.INNODB_METRICS,
816
+ * which on MariaDB holds the pool's page count: these are one scrape of
817
+ * each server as ClickHouse stored it (@@innodb_buffer_pool_size is
818
+ * 134217728 on both).
819
+ */
820
+ describe("the InnoDB buffer pool on MySQL and MariaDB alike", () => {
821
+ const MARIADB_11_4: Record<string, number> = {
822
+ "mysql.buffer_pool.limit": 8112,
823
+ "mysql.buffer_pool.pages{kind=total}": 8112,
824
+ "mysql.buffer_pool.pages{kind=data}": 1273,
825
+ "mysql.buffer_pool.pages{kind=free}": 6839,
826
+ "mysql.buffer_pool.pages{kind=misc}": 0,
827
+ };
828
+ const MYSQL_8_4: Record<string, number> = {
829
+ "mysql.buffer_pool.limit": 134217728,
830
+ "mysql.buffer_pool.pages{kind=total}": 8192,
831
+ "mysql.buffer_pool.pages{kind=data}": 1186,
832
+ "mysql.buffer_pool.pages{kind=free}": 7006,
833
+ "mysql.buffer_pool.pages{kind=misc}": 0,
834
+ };
835
+
836
+ test("no tile reads mysql.buffer_pool.limit, whose unit differs by engine", () => {
837
+ for (const system of ["mysql", "mariadb"]) {
838
+ expect(
839
+ getDatabaseServerMetrics(system).filter(
840
+ (metric: DatabaseServerMetricDefinition): boolean => {
841
+ return metric.metricName === "mysql.buffer_pool.limit";
842
+ },
843
+ ),
844
+ ).toEqual([]);
845
+ }
846
+ // The fixture holds the trap: the same setting, 16384x apart.
847
+ expect(
848
+ MYSQL_8_4["mysql.buffer_pool.limit"]! /
849
+ MARIADB_11_4["mysql.buffer_pool.limit"]!,
850
+ ).toBeGreaterThan(16000);
851
+ });
852
+
853
+ test("the size tile reads the total page count, the same measure on both", () => {
854
+ const size: DatabaseServerMetricDefinition = getDatabaseServerMetrics(
855
+ "mariadb",
856
+ ).find((metric: DatabaseServerMetricDefinition): boolean => {
857
+ return metric.title === "Buffer pool size";
858
+ })!;
859
+ expect(getDatabaseServerMetricId(size)).toBe(
860
+ "mysql.buffer_pool.pages{kind=total}",
861
+ );
862
+ expect(size.unit).toBe("pages");
863
+ expect(size.kind).toBe("gauge");
864
+ // Pinned: kind total is the sum of the other kinds, never added to them.
865
+ for (const scrape of [MARIADB_11_4, MYSQL_8_4]) {
866
+ const size16k: number = scrape[getDatabaseServerMetricId(size)]! * 16384;
867
+ expect(size16k).toBeGreaterThan(128 * 1024 * 1024 * 0.95);
868
+ expect(size16k).toBeLessThanOrEqual(128 * 1024 * 1024);
869
+ expect(
870
+ scrape["mysql.buffer_pool.pages{kind=data}"]! +
871
+ scrape["mysql.buffer_pool.pages{kind=free}"]! +
872
+ scrape["mysql.buffer_pool.pages{kind=misc}"]!,
873
+ ).toBe(scrape["mysql.buffer_pool.pages{kind=total}"]);
874
+ }
875
+ });
876
+
877
+ test("buffer pool usage stays in bytes: MariaDB reports those as bytes", () => {
878
+ const usage: DatabaseServerMetricDefinition = metricByName(
879
+ "mysql.buffer_pool.usage",
880
+ );
881
+ expect(usage.unit).toBe("bytes");
882
+ // MariaDB 11.4, same scrape: 16203776 dirty bytes = 989 dirty pages.
883
+ expect(16203776 / 16384).toBe(989);
884
+ });
885
+ });
886
+
887
+ /*
888
+ * Regression (e2e): Elasticsearch, OpenSearch and Memcached databases were
889
+ * connected, 69 to 76 metrics arriving every 30 s, and their Overview said
890
+ * there was no curated overview for the engine.
891
+ */
892
+ describe("Elasticsearch, OpenSearch and Memcached have a curated overview", () => {
893
+ test.each([
894
+ ["elasticsearch", "elasticsearch"],
895
+ ["opensearch", "opensearch"],
896
+ ["memcached", "memcached"],
897
+ ])(
898
+ "every %s tile reads a metric the agent delivered",
899
+ (system: string, arrivedFrom: string) => {
900
+ const metrics: Array<DatabaseServerMetricDefinition> =
901
+ getDatabaseServerMetrics(system);
902
+ expect(metrics.length).toBeGreaterThanOrEqual(5);
903
+ for (const metric of metrics) {
904
+ expect({
905
+ system,
906
+ metric: metric.metricName,
907
+ arrived: SEEN_ARRIVING_FROM_AGENT[arrivedFrom]!.includes(
908
+ metric.metricName,
909
+ ),
910
+ }).toEqual({ system, metric: metric.metricName, arrived: true });
911
+ }
912
+ },
913
+ );
914
+
915
+ test("OpenSearch gets Elasticsearch's set: the same receiver reads both", () => {
916
+ expect(getDatabaseServerMetrics("opensearch")).toEqual(
917
+ getDatabaseServerMetrics("elasticsearch"),
918
+ );
919
+ });
920
+
921
+ test("Elasticsearch's tiles, in display order", () => {
922
+ expect(
923
+ getDatabaseServerMetrics("elasticsearch").map(
924
+ (metric: DatabaseServerMetricDefinition): [string, string] => {
925
+ return [getDatabaseServerMetricId(metric), metric.kind];
926
+ },
927
+ ),
928
+ ).toEqual([
929
+ ["elasticsearch.cluster.health{status=green}", "gauge"],
930
+ ["elasticsearch.cluster.nodes", "gauge"],
931
+ ["elasticsearch.cluster.shards{state=unassigned}", "gauge"],
932
+ ["elasticsearch.cluster.pending_tasks", "gauge"],
933
+ ["jvm.memory.heap.utilization", "gauge"],
934
+ ["elasticsearch.node.fs.disk.available", "gauge"],
935
+ ["elasticsearch.node.operations.completed{operation=query}", "counter"],
936
+ ["elasticsearch.node.operations.completed{operation=index}", "counter"],
937
+ ]);
938
+ });
939
+
940
+ test("cluster health is the share of the interval spent green", () => {
941
+ /*
942
+ * The receiver records one 0/1 series per status (green 1, yellow 0,
943
+ * red 0 on a green cluster): the green series' average is the share,
944
+ * and the worst reporter decides.
945
+ */
946
+ const health: DatabaseServerMetricDefinition = metricByName(
947
+ "elasticsearch.cluster.health",
948
+ );
949
+ expect(health.attributes).toEqual({ status: "green" });
950
+ expect(health.aggregation).toBe(AggregationType.Avg);
951
+ expect(health.unit).toBe("fraction");
952
+ expect(health.seriesCombine).toBe("min");
953
+ });
954
+
955
+ test("node-level tiles keep the node closest to trouble", () => {
956
+ const heap: DatabaseServerMetricDefinition = metricByName(
957
+ "jvm.memory.heap.utilization",
958
+ );
959
+ // A 0..1 share (unit "1"), per node; the fullest one is shown.
960
+ expect(heap.unit).toBe("fraction");
961
+ expect(heap.seriesCombine).toBe("max");
962
+ expect(heap.seriesKeys).toEqual(["resource.elasticsearch.node.name"]);
963
+ expect(heap.enabledByDefault).toBe(false);
964
+
965
+ const disk: DatabaseServerMetricDefinition = metricByName(
966
+ "elasticsearch.node.fs.disk.available",
967
+ );
968
+ expect(disk.unit).toBe("bytes");
969
+ expect(disk.aggregation).toBe(AggregationType.Min);
970
+ expect(disk.seriesCombine).toBe("min");
971
+ expect(disk.seriesKeys).toEqual(["resource.elasticsearch.node.name"]);
972
+ });
973
+
974
+ test("Memcached's tiles, in display order", () => {
975
+ expect(
976
+ getDatabaseServerMetrics("memcached").map(
977
+ (metric: DatabaseServerMetricDefinition): [string, string] => {
978
+ return [getDatabaseServerMetricId(metric), metric.kind];
979
+ },
980
+ ),
981
+ ).toEqual([
982
+ ["memcached.connections.current", "gauge"],
983
+ ["memcached.bytes", "gauge"],
984
+ ["memcached.current_items", "gauge"],
985
+ ["memcached.operations{operation=get,type=hit}", "counter"],
986
+ ["memcached.operations{operation=get,type=miss}", "counter"],
987
+ ["memcached.commands", "counter"],
988
+ ["memcached.evictions", "counter"],
989
+ ]);
990
+ });
991
+
992
+ test("Memcached's hit ratio is not a tile: it reads 0% on an idle cache", () => {
993
+ /*
994
+ * Measured: a Memcached 1.6 nobody had read from reported
995
+ * memcached.operation_hit_ratio{operation=get} = 0 on all 239 scrapes.
996
+ */
997
+ expect(entriesNamed("memcached.operation_hit_ratio")).toEqual([]);
998
+ });
999
+ });
1000
+
1001
+ describe("getDatabaseServerMetrics", () => {
1002
+ test("aliases resolve to the engine's list", () => {
1003
+ expect(getDatabaseServerMetrics("postgres")).toEqual(
1004
+ getDatabaseServerMetrics("postgresql"),
1005
+ );
1006
+ expect(getDatabaseServerMetrics("MSSQL")).toEqual(
1007
+ getDatabaseServerMetrics("microsoft.sql_server"),
1008
+ );
1009
+ });
1010
+
1011
+ test("a fork its family's receiver monitors gets the family's set", () => {
1012
+ // The redis / mysql receivers report redis.* / mysql.* for these.
1013
+ expect(getDatabaseServerMetrics("valkey")).toEqual(
1014
+ getDatabaseServerMetrics("redis"),
1015
+ );
1016
+ // Less what the receiver never sends for the fork (see below).
1017
+ expect(getDatabaseServerMetrics("mariadb")).toEqual(
1018
+ getDatabaseServerMetrics("mysql").filter(
1019
+ (metric: DatabaseServerMetricDefinition): boolean => {
1020
+ return metric.metricName !== "mysql.row_operations";
1021
+ },
1022
+ ),
1023
+ );
1024
+ expect(getDatabaseServerMetrics("MariaDB")).toEqual(
1025
+ getDatabaseServerMetrics("mariadb"),
1026
+ );
1027
+ expect(getDatabaseServerMetrics("redis").length).toBeGreaterThan(0);
1028
+ });
1029
+
1030
+ /*
1031
+ * Regression (live re-verification): a MariaDB 11.4 Overview showed
1032
+ * "ROW OPERATIONS —" under ~960 handler ops/s. The tile reads
1033
+ * mysql.row_operations, from the Innodb_rows_* status counters, which
1034
+ * MariaDB does not have — `SHOW GLOBAL STATUS LIKE 'Innodb_rows%'` is
1035
+ * empty — so the receiver never sends it there and the tile could never
1036
+ * fill.
1037
+ */
1038
+ test.each([["mysql"], ["mariadb"]])(
1039
+ "every %s tile reads a metric the agent delivered",
1040
+ (system: string) => {
1041
+ const metrics: Array<DatabaseServerMetricDefinition> =
1042
+ getDatabaseServerMetrics(system);
1043
+ expect(metrics.length).toBeGreaterThanOrEqual(5);
1044
+ for (const metric of metrics) {
1045
+ expect({
1046
+ system,
1047
+ metric: metric.metricName,
1048
+ arrived: SEEN_ARRIVING_FROM_AGENT[system]!.includes(
1049
+ metric.metricName,
1050
+ ),
1051
+ }).toEqual({ system, metric: metric.metricName, arrived: true });
1052
+ }
1053
+ },
1054
+ );
1055
+
1056
+ test("notEmittedFor names only forks of the entry's own engine", () => {
1057
+ for (const metric of DATABASE_SERVER_METRICS) {
1058
+ for (const fork of metric.notEmittedFor || []) {
1059
+ const descriptor: DatabaseSystemDescriptor | null =
1060
+ getDatabaseSystemDescriptor(fork);
1061
+ expect({
1062
+ metric: metric.metricName,
1063
+ fork,
1064
+ family: descriptor?.family,
1065
+ isItself: descriptor?.system === metric.system,
1066
+ }).toEqual({
1067
+ metric: metric.metricName,
1068
+ fork,
1069
+ family: metric.system,
1070
+ isItself: false,
1071
+ });
1072
+ }
1073
+ }
1074
+ });
1075
+
1076
+ test("returns only that engine's metrics, in catalog order", () => {
1077
+ const metrics: Array<DatabaseServerMetricDefinition> =
1078
+ getDatabaseServerMetrics("redis");
1079
+ for (const metric of metrics) {
1080
+ expect(metric.system).toBe("redis");
1081
+ }
1082
+ expect(metrics[0]!.metricName).toBe("redis.clients.connected");
1083
+ });
1084
+
1085
+ test("engines without a curated set, and junk, give []", () => {
1086
+ expect(getDatabaseServerMetrics("cockroachdb")).toEqual([]);
1087
+ expect(getDatabaseServerMetrics("couchdb")).toEqual([]);
1088
+ expect(getDatabaseServerMetrics("tidb")).toEqual([]);
1089
+ expect(getDatabaseServerMetrics("")).toEqual([]);
1090
+ expect(getDatabaseServerMetrics(null)).toEqual([]);
1091
+ expect(getDatabaseServerMetrics(undefined)).toEqual([]);
1092
+ });
1093
+
1094
+ test("the returned array is a copy (callers may not mutate the catalog)", () => {
1095
+ const first: Array<DatabaseServerMetricDefinition> =
1096
+ getDatabaseServerMetrics("mysql");
1097
+ first.pop();
1098
+ expect(getDatabaseServerMetrics("mysql").length).toBe(first.length + 1);
1099
+ });
1100
+ });
1101
+
1102
+ describe("catalog helpers", () => {
1103
+ test("an entry's id is its name, plus its pins in key order", () => {
1104
+ expect(getDatabaseServerMetricId(metricByName("postgresql.backends"))).toBe(
1105
+ "postgresql.backends",
1106
+ );
1107
+ const [connected, running] = entriesNamed("mysql.threads");
1108
+ expect(getDatabaseServerMetricId(connected!)).toBe(
1109
+ "mysql.threads{kind=connected}",
1110
+ );
1111
+ expect(getDatabaseServerMetricId(running!)).toBe(
1112
+ "mysql.threads{kind=running}",
1113
+ );
1114
+ expect(
1115
+ getDatabaseServerMetricId({
1116
+ ...metricByName("postgresql.backends"),
1117
+ attributes: { z: "1", a: "2" },
1118
+ }),
1119
+ ).toBe("postgresql.backends{a=2,z=1}");
1120
+ });
1121
+
1122
+ test("gauges group by their series keys, then the reporting instance", () => {
1123
+ expect(
1124
+ getDatabaseServerMetricGroupKeys(metricByName("postgresql.backends")),
1125
+ ).toEqual([
1126
+ "db.namespace",
1127
+ "resource.postgresql.database.name",
1128
+ ...DATABASE_SERVER_INSTANCE_ATTRIBUTE_KEYS,
1129
+ ]);
1130
+ expect(
1131
+ getDatabaseServerMetricGroupKeys(metricByName("redis.memory.used")),
1132
+ ).toEqual(["resource.server.address", "resource.server.port"]);
1133
+ expect(
1134
+ getDatabaseServerMetricGroupKeys({
1135
+ ...metricByName("redis.memory.used"),
1136
+ seriesKeys: ["resource.server.address", "x"],
1137
+ }),
1138
+ ).toEqual(["resource.server.address", "x", "resource.server.port"]);
1139
+ });
1140
+
1141
+ test("group keys stay within the server's ten-key limit", () => {
1142
+ for (const metric of DATABASE_SERVER_METRICS) {
1143
+ expect(getDatabaseServerMetricGroupKeys(metric).length).toBeLessThan(10);
1144
+ }
1145
+ });
1146
+
1147
+ test("a metric name finds its entry, preferring one that pins nothing", () => {
1148
+ expect(
1149
+ findDatabaseServerMetricByName("postgres", " postgresql.commits ")?.title,
1150
+ ).toBe("Commits");
1151
+ // Every mysql.threads entry pins; the first one is used.
1152
+ expect(
1153
+ findDatabaseServerMetricByName("mysql", "mysql.threads")?.title,
1154
+ ).toBe("Connected threads");
1155
+ expect(
1156
+ findDatabaseServerMetricByName("mysql", "postgresql.commits"),
1157
+ ).toBeNull();
1158
+ expect(findDatabaseServerMetricByName(null, "mysql.threads")).toBeNull();
1159
+ expect(findDatabaseServerMetricByName("mysql", "")).toBeNull();
1160
+ });
1161
+ });