@oneuptime/common 14.0.2 → 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 (765) hide show
  1. package/Models/DatabaseModels/Alert.ts +55 -0
  2. package/Models/DatabaseModels/AlertFeed.ts +2 -0
  3. package/Models/DatabaseModels/DatabaseServer.ts +1650 -0
  4. package/Models/DatabaseModels/DatabaseServerEndpoint.ts +540 -0
  5. package/Models/DatabaseModels/DatabaseServerFeed.ts +625 -0
  6. package/Models/DatabaseModels/DatabaseServerLabelRule.ts +514 -0
  7. package/Models/DatabaseModels/DatabaseServerOwnerRule.ts +596 -0
  8. package/Models/DatabaseModels/DatabaseServerOwnerTeam.ts +491 -0
  9. package/Models/DatabaseModels/DatabaseServerOwnerUser.ts +490 -0
  10. package/Models/DatabaseModels/Incident.ts +55 -0
  11. package/Models/DatabaseModels/IncidentAlert.ts +540 -0
  12. package/Models/DatabaseModels/IncidentFeed.ts +2 -0
  13. package/Models/DatabaseModels/Index.ts +18 -0
  14. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +26 -0
  15. package/Models/DatabaseModels/Project.ts +60 -0
  16. package/Models/DatabaseModels/RumApplication.ts +52 -1
  17. package/Models/DatabaseModels/ScheduledMaintenance.ts +55 -0
  18. package/Models/DatabaseModels/TelemetryException.ts +2 -0
  19. package/Models/DatabaseModels/UserProjectSsoConsent.ts +146 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.ts +28 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.ts +89 -0
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.ts +673 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.ts +51 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  25. package/Server/Middleware/MultipartFormData.ts +1 -1
  26. package/Server/Middleware/TelemetryIngest.ts +15 -8
  27. package/Server/Services/AlertReminderRuleService.ts +100 -24
  28. package/Server/Services/DatabaseServerEndpointService.ts +895 -0
  29. package/Server/Services/DatabaseServerFeedService.ts +128 -0
  30. package/Server/Services/DatabaseServerLabelRuleEngineService.ts +340 -0
  31. package/Server/Services/DatabaseServerLabelRuleService.ts +14 -0
  32. package/Server/Services/DatabaseServerOwnerRuleEngineService.ts +425 -0
  33. package/Server/Services/DatabaseServerOwnerRuleService.ts +14 -0
  34. package/Server/Services/DatabaseServerOwnerTeamService.ts +180 -0
  35. package/Server/Services/DatabaseServerOwnerUserService.ts +173 -0
  36. package/Server/Services/DatabaseServerService.ts +4546 -0
  37. package/Server/Services/DatabaseService.ts +14 -8
  38. package/Server/Services/DockerResourceService.ts +43 -2
  39. package/Server/Services/IncidentAlertService.ts +1811 -0
  40. package/Server/Services/IncidentReminderRuleService.ts +103 -23
  41. package/Server/Services/IncidentService.ts +210 -10
  42. package/Server/Services/IncidentStateTimelineService.ts +24 -0
  43. package/Server/Services/Index.ts +18 -0
  44. package/Server/Services/InventoryItemService.ts +113 -5
  45. package/Server/Services/IoTDeviceService.ts +145 -37
  46. package/Server/Services/OpenTelemetryIngestService.ts +19 -0
  47. package/Server/Services/PodmanResourceService.ts +43 -2
  48. package/Server/Services/ScheduledMaintenanceReminderRuleService.ts +107 -23
  49. package/Server/Services/ServiceService.ts +1 -1
  50. package/Server/Services/TelemetryUsageBillingService.ts +29 -2
  51. package/Server/Services/UserProjectSsoConsentService.ts +74 -0
  52. package/Server/Services/UserService.ts +14 -1
  53. package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +18 -0
  54. package/Server/Types/Database/QueryHelper.ts +30 -1
  55. package/Server/Utils/AI/Toolbox/ResourceTools.ts +69 -1
  56. package/Server/Utils/Database/AffectedResourceRelations.ts +6 -0
  57. package/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.ts +188 -6
  58. package/Server/Utils/Monitor/MonitorAlert.ts +28 -1
  59. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +2262 -755
  60. package/Server/Utils/Monitor/MonitorIncident.ts +28 -1
  61. package/Server/Utils/Monitor/MonitorMaintenanceSuppression.ts +268 -6
  62. package/Server/Utils/Monitor/MonitorResource.ts +47 -11
  63. package/Server/Utils/Monitor/MonitorResourceContext.ts +1 -0
  64. package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +239 -21
  65. package/Server/Utils/Monitor/PerSeriesResolutionRootCause.ts +43 -0
  66. package/Server/Utils/Monitor/SeriesResourceLabels.ts +291 -0
  67. package/Server/Utils/Monitor/SeriesResourceLinker.ts +111 -12
  68. package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +25 -0
  69. package/Server/Utils/SessionReplay/SessionReplayGateCache.ts +24 -2
  70. package/Server/Utils/StartServer.ts +26 -6
  71. package/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.ts +2 -0
  72. package/Server/Utils/Telemetry/DatabaseEndpointDiscovery.ts +688 -0
  73. package/Server/Utils/Telemetry/EntityRegistry.ts +5 -1
  74. package/Server/Utils/Telemetry/LogExceptionExtractor.ts +18 -1
  75. package/Server/Utils/Telemetry/ResourceEntityFilter.ts +175 -12
  76. package/Server/Utils/Telemetry/ResourceFacetResolver.ts +12 -0
  77. package/Server/Utils/Telemetry/ServiceDependencyDiscovery.ts +606 -36
  78. package/Server/Utils/Telemetry/Telemetry.ts +16 -0
  79. package/Server/Utils/Telemetry/TelemetryEntity.ts +22 -22
  80. package/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.ts +16 -10
  81. package/Tests/App/Accounts/SignedInRedirect.test.tsx +241 -0
  82. package/Tests/App/AdminDashboard/AdminHeaderSmallScreens.test.tsx +221 -4
  83. package/Tests/App/Dashboard/AIInsightsResourcePageContext.test.ts +42 -0
  84. package/Tests/App/Dashboard/AffectedResourcesDisplay.test.tsx +100 -0
  85. package/Tests/App/Dashboard/AffectedResourcesPicker.test.tsx +86 -0
  86. package/Tests/App/Dashboard/AffectedResourcesPickerHiddenTypes.test.tsx +2 -0
  87. package/Tests/App/Dashboard/AffectedResourcesSummaryStep.test.tsx +19 -0
  88. package/Tests/App/Dashboard/BreadcrumbCoverage.test.tsx +14 -0
  89. package/Tests/App/Dashboard/BulkIncidentLinkActions.test.tsx +869 -0
  90. package/Tests/App/Dashboard/CephMetricTooltips.test.tsx +1777 -0
  91. package/Tests/App/Dashboard/CloudFleetSummary.test.ts +8 -0
  92. package/Tests/App/Dashboard/CloudMetricTooltips.test.tsx +887 -0
  93. package/Tests/App/Dashboard/ContainerHostMetricTooltips.test.tsx +1309 -0
  94. package/Tests/App/Dashboard/CorrelateFilterBuilder.test.tsx +26 -1
  95. package/Tests/App/Dashboard/DashboardAppSsoError.test.tsx +501 -0
  96. package/Tests/App/Dashboard/DashboardHeaderRequests.test.tsx +64 -1
  97. package/Tests/App/Dashboard/DashboardHeaderSmallScreens.test.tsx +178 -18
  98. package/Tests/App/Dashboard/DashboardMasterPageSsoRedirect.test.tsx +444 -0
  99. package/Tests/App/Dashboard/DashboardNavBarForeignHiddenRule.test.tsx +573 -0
  100. package/Tests/App/Dashboard/DatabaseChartAxes.test.tsx +431 -0
  101. package/Tests/App/Dashboard/DatabaseContainerDetailBadge.test.tsx +249 -0
  102. package/Tests/App/Dashboard/DatabaseDashboardE2EFixes.test.ts +681 -0
  103. package/Tests/App/Dashboard/DatabaseDocumentationMarkdown.test.ts +1801 -0
  104. package/Tests/App/Dashboard/DatabaseFleetSummaryRefresh.test.tsx +280 -0
  105. package/Tests/App/Dashboard/DatabaseFormHelpers.test.tsx +321 -0
  106. package/Tests/App/Dashboard/DatabaseMetricMonitorLink.test.tsx +795 -0
  107. package/Tests/App/Dashboard/DatabaseOverviewHeader.test.tsx +580 -0
  108. package/Tests/App/Dashboard/DatabaseRecommendationsEngineMetrics.test.ts +270 -0
  109. package/Tests/App/Dashboard/DatabaseServerComponents.test.tsx +1486 -0
  110. package/Tests/App/Dashboard/DatabaseServerEngineMetricsFilter.test.ts +223 -0
  111. package/Tests/App/Dashboard/DatabaseServerPresentation.test.ts +435 -0
  112. package/Tests/App/Dashboard/DatabaseServerSummary.test.ts +186 -0
  113. package/Tests/App/Dashboard/DatabaseServerTelemetryQueries.test.ts +1553 -0
  114. package/Tests/App/Dashboard/DatabaseTableTruncation.test.tsx +326 -0
  115. package/Tests/App/Dashboard/DatabaseTelemetryScope.test.ts +512 -0
  116. package/Tests/App/Dashboard/DatabaseTelemetryTabs.test.tsx +774 -0
  117. package/Tests/App/Dashboard/DatabaseViewLayout.test.tsx +233 -0
  118. package/Tests/App/Dashboard/DatabaseWorkloadBadge.test.tsx +972 -0
  119. package/Tests/App/Dashboard/DiscoveryReviewInventoryRefresh.test.tsx +5 -0
  120. package/Tests/App/Dashboard/DiscoveryReviewUnnamedHostHint.test.tsx +1061 -0
  121. package/Tests/App/Dashboard/DiscoveryScanLivePage.test.tsx +39 -0
  122. package/Tests/App/Dashboard/DockerSwarmClustersListTooltips.test.tsx +414 -0
  123. package/Tests/App/Dashboard/DockerSwarmMetricTooltips.test.ts +796 -0
  124. package/Tests/App/Dashboard/DockerSwarmOverviewTooltips.test.tsx +747 -0
  125. package/Tests/App/Dashboard/EventOverlayScope.test.ts +147 -0
  126. package/Tests/App/Dashboard/EventOverlayScopeHook.test.tsx +1 -0
  127. package/Tests/App/Dashboard/ExceptionMonitorEnvironmentFilter.test.tsx +38 -18
  128. package/Tests/App/Dashboard/HostDetailViewTooltips.test.tsx +725 -0
  129. package/Tests/App/Dashboard/HostListColumnTooltips.test.tsx +472 -0
  130. package/Tests/App/Dashboard/HostMetricTooltips.test.ts +709 -0
  131. package/Tests/App/Dashboard/HostOverviewTooltips.test.tsx +698 -0
  132. package/Tests/App/Dashboard/HostTooltipHarness.ts +124 -0
  133. package/Tests/App/Dashboard/HostsListTooltips.test.tsx +395 -0
  134. package/Tests/App/Dashboard/IncidentAlertLinkDialog.test.tsx +691 -0
  135. package/Tests/App/Dashboard/IncidentAlertLinkHelpers.test.ts +458 -0
  136. package/Tests/App/Dashboard/IncidentAlertLinkPages.test.tsx +828 -0
  137. package/Tests/App/Dashboard/IncidentAlertLinkSideMenus.test.tsx +231 -0
  138. package/Tests/App/Dashboard/IncidentCreateFromAlerts.test.tsx +689 -0
  139. package/Tests/App/Dashboard/IoTMetricTooltips.test.tsx +1123 -0
  140. package/Tests/App/Dashboard/KubernetesClusterMetricTooltips.test.ts +837 -0
  141. package/Tests/App/Dashboard/KubernetesClusterOverviewTooltips.test.tsx +699 -0
  142. package/Tests/App/Dashboard/KubernetesContainersTabTooltips.test.tsx +320 -0
  143. package/Tests/App/Dashboard/KubernetesCostTooltips.test.tsx +502 -0
  144. package/Tests/App/Dashboard/KubernetesInsightsTooltips.test.tsx +222 -0
  145. package/Tests/App/Dashboard/KubernetesResourceMetricTooltips.test.ts +561 -0
  146. package/Tests/App/Dashboard/KubernetesResourcePagesTooltips.test.tsx +1168 -0
  147. package/Tests/App/Dashboard/LinkIncidentAlertModal.test.tsx +154 -0
  148. package/Tests/App/Dashboard/LogsResourceFacetChips.test.tsx +1 -0
  149. package/Tests/App/Dashboard/MetricDescriptionRules.ts +170 -0
  150. package/Tests/App/Dashboard/MetricDescriptionsCatalog.test.ts +206 -0
  151. package/Tests/App/Dashboard/MetricDescriptionsConsistency.test.ts +275 -0
  152. package/Tests/App/Dashboard/MetricsViewerDrillDown.test.tsx +310 -0
  153. package/Tests/App/Dashboard/MetricsViewerEntityScopedRows.test.tsx +495 -0
  154. package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +132 -1
  155. package/Tests/App/Dashboard/NavigationSearchKeywords.test.tsx +5 -0
  156. package/Tests/App/Dashboard/NetworkDeviceTooltips.test.tsx +852 -0
  157. package/Tests/App/Dashboard/NetworkDiagnosticsTooltips.test.tsx +556 -0
  158. package/Tests/App/Dashboard/NetworkMetricTooltips.test.ts +1348 -0
  159. package/Tests/App/Dashboard/NetworkSiteTooltips.test.tsx +679 -0
  160. package/Tests/App/Dashboard/ProductOrientation.test.tsx +4 -3
  161. package/Tests/App/Dashboard/ProxmoxMetricTooltips.test.ts +592 -0
  162. package/Tests/App/Dashboard/ProxmoxOverviewTooltips.test.tsx +1002 -0
  163. package/Tests/App/Dashboard/ProxmoxResourcePageTooltips.test.tsx +923 -0
  164. package/Tests/App/Dashboard/RecommendationsLoadedContext.test.tsx +349 -0
  165. package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +62 -0
  166. package/Tests/App/Dashboard/ResourceFeedPageWiring.test.ts +8 -1
  167. package/Tests/App/Dashboard/ResourceFeedPagesFilterSort.test.tsx +14 -0
  168. package/Tests/App/Dashboard/ResourceOverviewTileTooltips.test.tsx +1066 -0
  169. package/Tests/App/Dashboard/RumOverviewPage.test.tsx +1195 -0
  170. package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +2 -0
  171. package/Tests/App/Dashboard/ServerlessMetricTooltips.test.tsx +474 -0
  172. package/Tests/App/Dashboard/ServiceMapDatabaseLink.test.tsx +1085 -0
  173. package/Tests/App/Dashboard/ServiceMetricTooltips.test.tsx +772 -0
  174. package/Tests/App/Dashboard/SessionReplayAuditTable.test.tsx +56 -1
  175. package/Tests/App/Dashboard/TelemetryMetricsSignals.test.ts +1207 -0
  176. package/Tests/App/Dashboard/TelemetryResourceRetentionSettings.test.tsx +10 -0
  177. package/Tests/App/Dashboard/TelemetryResourceTabTooltips.test.tsx +437 -0
  178. package/Tests/App/Dashboard/TracesResourceFacets.test.tsx +2 -1
  179. package/Tests/App/Dashboard/VMwareMetricTooltips.test.ts +801 -0
  180. package/Tests/App/Dashboard/VMwareOverviewTooltips.test.tsx +601 -0
  181. package/Tests/App/Dashboard/VMwareResourcePagesTooltips.test.tsx +646 -0
  182. package/Tests/App/Dashboard/VMwareTooltipHarness.ts +145 -0
  183. package/Tests/App/StatusPage/StatusPageHeaderForeignHiddenRule.test.tsx +284 -0
  184. package/Tests/ClassStrings.ts +178 -0
  185. package/Tests/Fixtures/MobilePasskeyUser.json +1 -2
  186. package/Tests/ForeignHiddenRuleGuard.ts +2152 -0
  187. package/Tests/Models/DatabaseModels/DatabaseServerModels.test.ts +2250 -0
  188. package/Tests/Models/DatabaseModels/IncidentAlertModel.test.ts +554 -0
  189. package/Tests/Models/DatabaseModels/ResourceFeedModels.test.ts +24 -5
  190. package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +117 -0
  191. package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +4 -2
  192. package/Tests/RenderedMarkup.ts +518 -0
  193. package/Tests/ResponsiveVisibility.test.ts +490 -4
  194. package/Tests/ResponsiveVisibility.ts +505 -52
  195. package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +3 -0
  196. package/Tests/Server/Infrastructure/Postgres/AddDatabaseServerTablesMigration.test.ts +541 -0
  197. package/Tests/Server/Infrastructure/Postgres/AddIncidentAlertMigration.test.ts +341 -0
  198. package/Tests/Server/Infrastructure/Postgres/AddSessionReplaySameOriginTracePropagationMigration.test.ts +247 -0
  199. package/Tests/Server/Infrastructure/Postgres/AddUserProjectSsoConsentMigration.test.ts +234 -0
  200. package/Tests/Server/Services/ContainerSnapshotUpsertPostgres.test.ts +319 -0
  201. package/Tests/Server/Services/CrossProjectRelationWriteGuard.test.ts +13 -0
  202. package/Tests/Server/Services/DatabaseServerEndpointService.test.ts +2033 -0
  203. package/Tests/Server/Services/DatabaseServerFeedAndOwnerServices.test.ts +529 -0
  204. package/Tests/Server/Services/DatabaseServerLifecycle.test.ts +3302 -0
  205. package/Tests/Server/Services/DatabaseServerRegistries.test.ts +603 -0
  206. package/Tests/Server/Services/DatabaseServerRuleEngines.test.ts +754 -0
  207. package/Tests/Server/Services/DatabaseServerService.test.ts +3558 -0
  208. package/Tests/Server/Services/DatabaseServerSqlPostgres.test.ts +2045 -0
  209. package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlockedPostgres.test.ts +362 -0
  210. package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlockedReply.test.ts +210 -0
  211. package/Tests/Server/Services/HookFreeWriteLengthClamp.test.ts +18 -0
  212. package/Tests/Server/Services/IncidentAlertPostgres.test.ts +903 -0
  213. package/Tests/Server/Services/IncidentAlertRegistration.test.ts +96 -0
  214. package/Tests/Server/Services/IncidentAlertService.test.ts +2225 -0
  215. package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +2 -0
  216. package/Tests/Server/Services/IncidentAlertStateCascade.test.ts +970 -0
  217. package/Tests/Server/Services/IncidentCreateFromAlerts.test.ts +1284 -0
  218. package/Tests/Server/Services/IncomingCallPolicyEscalationRuleTarget.test.ts +225 -0
  219. package/Tests/Server/Services/InventoryItemDisplayName.test.ts +280 -2
  220. package/Tests/Server/Services/InventoryUpsertSchemaParity.test.ts +8 -2
  221. package/Tests/Server/Services/IoTDeviceLatestMetricsPostgres.test.ts +689 -0
  222. package/Tests/Server/Services/IoTDeviceService.test.ts +379 -0
  223. package/Tests/Server/Services/LatestMetricsValuesShape.test.ts +360 -0
  224. package/Tests/Server/Services/LlmModelPriceService.test.ts +402 -0
  225. package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +7 -1
  226. package/Tests/Server/Services/OwnerRowUniqueness.test.ts +61 -9
  227. package/Tests/Server/Services/ReminderRuleLookupPostgres.test.ts +2250 -0
  228. package/Tests/Server/Services/ReminderRuleRefreshOpenSubjectsPaging.test.ts +653 -0
  229. package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +68 -20
  230. package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +3 -3
  231. package/Tests/Server/Services/TelemetryResourceFacetCounting.test.ts +9 -0
  232. package/Tests/Server/Services/UserProjectSsoConsentPostgres.test.ts +153 -0
  233. package/Tests/Server/Services/UserProjectSsoConsentService.test.ts +192 -0
  234. package/Tests/Server/Services/UserServiceFirstMasterAdminElection.test.ts +71 -0
  235. package/Tests/Server/Services/UserSignupIdTakeoverPostgres.test.ts +238 -0
  236. package/Tests/Server/Services/WorkspaceNotificationSummaryHelpers.test.ts +592 -0
  237. package/Tests/Server/Types/Billing/PayAsYouGoMeteredAuthorization.test.ts +3 -0
  238. package/Tests/Server/Types/Database/EventOverlayScopePostgres.test.ts +1 -0
  239. package/Tests/Server/Types/Database/FeedEventTypeFilterQuery.test.ts +11 -0
  240. package/Tests/Server/Types/Database/Permissions/InfrastructureOwnershipScope.test.ts +8 -0
  241. package/Tests/Server/Types/Database/QueryHelperBooleanForCriteriaBackedRule.test.ts +1094 -0
  242. package/Tests/Server/Utils/AI/ResourceTools.test.ts +134 -0
  243. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.ts +41 -0
  244. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaAnomalyUnits.test.ts +279 -9
  245. package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaDisplayContext.test.ts +933 -0
  246. package/Tests/Server/Utils/Monitor/DatabaseMaintenanceSuppression.test.ts +582 -0
  247. package/Tests/Server/Utils/Monitor/DatabaseServerMonitorLinking.test.ts +753 -0
  248. package/Tests/Server/Utils/Monitor/MonitorActionTimestamps.test.ts +1 -0
  249. package/Tests/Server/Utils/Monitor/MonitorAlertCriteriaReferences.test.ts +1 -0
  250. package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +119 -0
  251. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +60 -25
  252. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorAffectedResourceEdgeCases.test.ts +1719 -0
  253. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorKubernetesAffectedResources.test.ts +1447 -0
  254. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorKubernetesRatioEmail.test.ts +352 -0
  255. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformMetricUnits.test.ts +717 -0
  256. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformRawScan.test.ts +2125 -0
  257. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformSeriesAffectedResources.test.ts +1288 -0
  258. package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +1 -0
  259. package/Tests/Server/Utils/Monitor/MonitorIncidentCriteriaReferences.test.ts +1 -0
  260. package/Tests/Server/Utils/Monitor/MonitorIncidentMemberRoleMembership.test.ts +1 -0
  261. package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +88 -0
  262. package/Tests/Server/Utils/Monitor/MonitorMaintenanceSuppression.test.ts +205 -0
  263. package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +62 -0
  264. package/Tests/Server/Utils/Monitor/MonitorResourceDatabaseMaintenance.test.ts +803 -0
  265. package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +133 -3
  266. package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +1 -0
  267. package/Tests/Server/Utils/Monitor/PerSeriesRecoveryResolution.test.ts +472 -1
  268. package/Tests/Server/Utils/Monitor/PerSeriesSecondEntityAlerting.test.ts +1 -0
  269. package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +236 -2
  270. package/Tests/Server/Utils/SeriesResourceLabels.test.ts +70 -0
  271. package/Tests/Server/Utils/SessionReplay/SessionReplayGateCachePolicy.test.ts +103 -0
  272. package/Tests/Server/Utils/StartServerProtobufContentType.test.ts +54 -0
  273. package/Tests/Server/Utils/Telemetry/DatabaseEndpointDiscovery.test.ts +1895 -0
  274. package/Tests/Server/Utils/Telemetry/EntityRegistry.test.ts +7 -0
  275. package/Tests/Server/Utils/Telemetry/LogExceptionExtractorSeverityGate.test.ts +90 -0
  276. package/Tests/Server/Utils/Telemetry/ResourceEntityFilter.test.ts +570 -0
  277. package/Tests/Server/Utils/Telemetry/ResourceFacetResolver.test.ts +97 -2
  278. package/Tests/Server/Utils/Telemetry/ServiceDependencyDiscovery.test.ts +1337 -0
  279. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +295 -0
  280. package/Tests/Types/AI/AIResourceContext.test.ts +30 -0
  281. package/Tests/Types/DatabaseServer/DatabaseContainerClassifier.test.ts +3644 -0
  282. package/Tests/Types/DatabaseServer/DatabaseContainerCommand.test.ts +340 -0
  283. package/Tests/Types/DatabaseServer/DatabaseContainerCommandCorpus.ts +826 -0
  284. package/Tests/Types/DatabaseServer/DatabaseContainerCommandPostgres.test.ts +150 -0
  285. package/Tests/Types/DatabaseServer/DatabaseEndpoint.test.ts +2657 -0
  286. package/Tests/Types/DatabaseServer/DatabaseServerDiscoverySource.test.ts +64 -0
  287. package/Tests/Types/DatabaseServer/DatabaseServerEntityKeys.test.ts +952 -0
  288. package/Tests/Types/DatabaseServer/DatabaseServerMetricCatalog.test.ts +1161 -0
  289. package/Tests/Types/DatabaseServer/DatabaseSystem.test.ts +1514 -0
  290. package/Tests/Types/DatabaseServer/DatabaseTelemetryResolver.test.ts +1558 -0
  291. package/Tests/Types/Monitor/CephAlertTemplates.test.ts +255 -6
  292. package/Tests/Types/Monitor/DatabaseAlertTemplates.test.ts +2254 -0
  293. package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +298 -0
  294. package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +271 -0
  295. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +253 -9
  296. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +13 -5
  297. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +4 -2
  298. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +111 -2
  299. package/Tests/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.test.ts +61 -0
  300. package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +114 -0
  301. package/Tests/Types/Monitor/Utils/KubernetesAgentEmittedMetrics.ts +181 -0
  302. package/Tests/Types/NetworkDevice/DiscoveredHostNamingStatus.test.ts +401 -0
  303. package/Tests/Types/Rum/WebVitals.test.ts +173 -0
  304. package/Tests/Types/Telemetry/ResourceEntityFacet.test.ts +4 -1
  305. package/Tests/Types/Telemetry/ResourceFacetCatalog.test.ts +24 -2
  306. package/Tests/UI/Components/Card.test.tsx +93 -2
  307. package/Tests/UI/Components/FeedOptions.test.ts +6 -0
  308. package/Tests/UI/Components/FeedOptionsButton.test.tsx +8 -1
  309. package/Tests/UI/Components/FieldLabelInfoCardTooltip.test.tsx +413 -0
  310. package/Tests/UI/Components/ForeignHiddenRuleResilience.test.tsx +1147 -0
  311. package/Tests/UI/Components/HeaderRightRail.test.tsx +41 -1
  312. package/Tests/UI/Components/InfoTooltip.test.tsx +242 -0
  313. package/Tests/UI/Components/LogsEntityNames.test.ts +16 -1
  314. package/Tests/UI/Components/LogsFacetSidebarHiddenFacets.test.tsx +7 -3
  315. package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +207 -3
  316. package/Tests/UI/Components/ModelTable/BaseModelTableBulkDeleteVerb.test.tsx +367 -0
  317. package/Tests/UI/Components/ModelTable/BaseModelTableCreateButtonTitle.test.tsx +275 -0
  318. package/Tests/UI/Components/ResourceFacetConfigs.test.ts +2 -1
  319. package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
  320. package/Tests/UI/Components/SrOnlyForeignRule.test.tsx +994 -0
  321. package/Tests/UI/Components/StatusPage/ResourceListSelection.test.tsx +34 -1
  322. package/Tests/UI/Components/TableHeaderTooltip.test.tsx +662 -0
  323. package/Tests/UI/Components/TelemetryFacetSidebarHiddenFacets.test.tsx +4 -1
  324. package/Tests/UI/ForeignHiddenRuleGuard.test.ts +1951 -0
  325. package/Tests/UI/Rum/PrivacySummaryCard.test.tsx +166 -9
  326. package/Tests/UI/Rum/RecordingHealthTooltips.test.tsx +447 -0
  327. package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +164 -0
  328. package/Tests/UI/Rum/ReplayFrameCapture.test.ts +6750 -0
  329. package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +19 -1
  330. package/Tests/UI/Rum/ReplayRail.test.tsx +723 -12
  331. package/Tests/UI/Rum/ReplayRailDetail.test.tsx +86 -0
  332. package/Tests/UI/Rum/ReplayScreenshot.test.ts +2124 -0
  333. package/Tests/UI/Rum/ReplayScreenshotActions.test.tsx +3288 -0
  334. package/Tests/UI/Rum/ReplayStage.test.tsx +62 -0
  335. package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +983 -2
  336. package/Tests/UI/Rum/ReplayTabSwitcher.test.tsx +19 -1
  337. package/Tests/UI/Rum/SessionReplaySettingsPolicyLoading.test.tsx +149 -0
  338. package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +107 -6
  339. package/Tests/UI/Rum/SessionReplayUsersTableTooltips.test.tsx +330 -0
  340. package/Tests/UI/Rum/UserFlowTooltips.test.tsx +886 -0
  341. package/Tests/UI/TailwindPlayCdnForeignHiddenRule.test.ts +1005 -0
  342. package/Tests/UI/ThemeGroupHoverReveal.test.ts +847 -0
  343. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +80 -0
  344. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +23 -0
  345. package/Tests/UI/Utils/ModelAPISsoRedirect.test.ts +127 -0
  346. package/Tests/UI/Utils/Navigation.test.ts +102 -0
  347. package/Tests/UI/Utils/PermissionGate.test.ts +76 -0
  348. package/Tests/UI/Utils/Telemetry/TelemetryEntityNames.test.ts +23 -0
  349. package/Tests/Utils/Incident/IncidentFromAlerts.test.ts +696 -0
  350. package/Tests/Utils/LabelRuleImportExport.test.ts +5 -0
  351. package/Tests/Utils/MetricUnitUtil.test.ts +227 -2
  352. package/Tests/Utils/Monitor/MetricValueFormatter.test.ts +288 -2
  353. package/Tests/Utils/Monitor/PlatformResourceIdentityAndUnits.test.ts +1559 -0
  354. package/Tests/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.test.ts +2546 -0
  355. package/Tests/Utils/NetworkDiscovery/DiscoveredHostUtil.test.ts +315 -0
  356. package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +336 -1
  357. package/Tests/Utils/NetworkDiscovery/NetbiosNameUtil.test.ts +244 -0
  358. package/Tests/Utils/Rum/SessionTraceState.test.ts +239 -0
  359. package/Tests/Utils/ValueFormatter.test.ts +50 -0
  360. package/Tests/tsconfig.json +16 -0
  361. package/Types/AI/AIResourceContext.ts +7 -0
  362. package/Types/Dashboard/DashboardTemplates.ts +2 -1
  363. package/Types/DatabaseServer/DatabaseConnectionSpan.ts +77 -0
  364. package/Types/DatabaseServer/DatabaseContainerClassifier.ts +2068 -0
  365. package/Types/DatabaseServer/DatabaseContainerCommand.ts +801 -0
  366. package/Types/DatabaseServer/DatabaseEndpoint.ts +1943 -0
  367. package/Types/DatabaseServer/DatabaseServerDiscoverySource.ts +68 -0
  368. package/Types/DatabaseServer/DatabaseServerMetricCatalog.ts +966 -0
  369. package/Types/DatabaseServer/DatabaseSystem.ts +2124 -0
  370. package/Types/DatabaseServer/DatabaseTelemetryResolver.ts +555 -0
  371. package/Types/Email/EmailTemplateType.ts +1 -0
  372. package/Types/Incident/IncidentAlertLink.ts +38 -0
  373. package/Types/Monitor/CephAlertTemplates.ts +18 -0
  374. package/Types/Monitor/DatabaseAlertTemplates.ts +2020 -0
  375. package/Types/Monitor/KubernetesAlertTemplates.ts +64 -24
  376. package/Types/Monitor/KubernetesMetricCatalog.ts +118 -19
  377. package/Types/Monitor/MetricMonitor/MetricCriteriaContext.ts +14 -0
  378. package/Types/Monitor/MetricMonitor/MetricMonitorResponse.ts +93 -10
  379. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +109 -8
  380. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +36 -7
  381. package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +43 -2
  382. package/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.ts +41 -6
  383. package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +26 -0
  384. package/Types/NetworkDevice/DiscoveredHostNamingStatus.ts +147 -0
  385. package/Types/Permission.ts +315 -0
  386. package/Types/Probe/ProbeApiIngestResponse.ts +8 -0
  387. package/Types/Rules/RuleCriteriaFieldRegistry.ts +10 -0
  388. package/Types/Rules/RuleRun.ts +12 -0
  389. package/Types/Rum/SessionReplay.ts +25 -6
  390. package/Types/Rum/WebVitals.ts +52 -0
  391. package/Types/Telemetry/EntityType.ts +23 -0
  392. package/Types/Telemetry/ResourceFacetCatalog.ts +14 -0
  393. package/Types/Telemetry/ServiceType.ts +8 -0
  394. package/UI/Components/Banner/Banner.tsx +1 -1
  395. package/UI/Components/Card/Card.tsx +1 -1
  396. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +2 -2
  397. package/UI/Components/Charts/Line/LineChart.tsx +7 -0
  398. package/UI/Components/CommandPalette/CommandPalette.tsx +1 -1
  399. package/UI/Components/Date/StartAndEndDate.tsx +5 -5
  400. package/UI/Components/Detail/FieldLabel.tsx +8 -0
  401. package/UI/Components/Diagram/HorizontalStepChain.tsx +1 -1
  402. package/UI/Components/Feed/FeedOptionsButton.tsx +1 -1
  403. package/UI/Components/Forms/BasicForm.tsx +1 -1
  404. package/UI/Components/Header/Header.tsx +1 -1
  405. package/UI/Components/Header/HeaderIconDropdownButton.tsx +1 -1
  406. package/UI/Components/HeaderAlert/HeaderAlert.tsx +1 -1
  407. package/UI/Components/InfoCard/InfoCard.tsx +47 -1
  408. package/UI/Components/LogsViewer/components/FacetValueRow.tsx +1 -1
  409. package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +1 -1
  410. package/UI/Components/Modal/ModalFooter.tsx +1 -1
  411. package/UI/Components/ModelDetail/CardModelDetail.tsx +2 -2
  412. package/UI/Components/ModelTable/BaseModelTable.tsx +99 -21
  413. package/UI/Components/ModelTable/Column.ts +5 -0
  414. package/UI/Components/Navbar/NavBar.tsx +9 -2
  415. package/UI/Components/Navbar/NavBarMenuModal.tsx +2 -2
  416. package/UI/Components/Page/Page.tsx +1 -1
  417. package/UI/Components/Pagination/Pagination.tsx +3 -3
  418. package/UI/Components/ProgressButtons/ProgressButtonItem.tsx +1 -1
  419. package/UI/Components/SideMenu/SideMenu.tsx +4 -1
  420. package/UI/Components/StatusPage/ResourceGroupNavigator.tsx +4 -2
  421. package/UI/Components/StatusPage/ResourceList.tsx +6 -6
  422. package/UI/Components/Table/TableHeader.tsx +47 -2
  423. package/UI/Components/Table/Types/Column.ts +7 -0
  424. package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +1 -1
  425. package/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.tsx +1 -1
  426. package/UI/Components/Tooltip/InfoTooltip.tsx +78 -0
  427. package/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.tsx +1 -1
  428. package/UI/Components/Workflow/ComponentsModal.tsx +2 -2
  429. package/UI/Components/Workflow/StepTraceViewer.tsx +1 -1
  430. package/UI/Styles/Theme.css +8 -1
  431. package/UI/Utils/Navigation.ts +89 -42
  432. package/UI/Utils/PermissionGate.ts +11 -2
  433. package/UI/Utils/Telemetry/TelemetryEntityNames.ts +7 -0
  434. package/UI/Utils/TelemetryService.ts +4 -3
  435. package/Utils/Incident/IncidentFromAlerts.ts +516 -0
  436. package/Utils/LabelRuleImportExport.ts +2 -0
  437. package/Utils/MetricUnitUtil.ts +103 -11
  438. package/Utils/Monitor/MetricValueFormatter.ts +66 -13
  439. package/Utils/Monitor/PlatformMetricUnitUtil.ts +215 -0
  440. package/Utils/Monitor/PlatformResourceIdentity.ts +514 -0
  441. package/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.ts +425 -0
  442. package/Utils/NetworkDiscovery/DiscoveredHostUtil.ts +32 -0
  443. package/Utils/NetworkDiscovery/NetbiosNameUtil.ts +73 -0
  444. package/Utils/Rum/SessionTraceState.ts +212 -0
  445. package/Utils/Telemetry/DatabaseServerEntityKeys.ts +275 -0
  446. package/Utils/Telemetry/EntityKey.ts +176 -0
  447. package/Utils/ValueFormatter.ts +16 -0
  448. package/build/dist/Models/DatabaseModels/Alert.js +54 -0
  449. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  450. package/build/dist/Models/DatabaseModels/AlertFeed.js +2 -0
  451. package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -1
  452. package/build/dist/Models/DatabaseModels/DatabaseServer.js +1683 -0
  453. package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -0
  454. package/build/dist/Models/DatabaseModels/DatabaseServerEndpoint.js +559 -0
  455. package/build/dist/Models/DatabaseModels/DatabaseServerEndpoint.js.map +1 -0
  456. package/build/dist/Models/DatabaseModels/DatabaseServerFeed.js +648 -0
  457. package/build/dist/Models/DatabaseModels/DatabaseServerFeed.js.map +1 -0
  458. package/build/dist/Models/DatabaseModels/DatabaseServerLabelRule.js +522 -0
  459. package/build/dist/Models/DatabaseModels/DatabaseServerLabelRule.js.map +1 -0
  460. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerRule.js +603 -0
  461. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerRule.js.map +1 -0
  462. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerTeam.js +506 -0
  463. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerTeam.js.map +1 -0
  464. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerUser.js +505 -0
  465. package/build/dist/Models/DatabaseModels/DatabaseServerOwnerUser.js.map +1 -0
  466. package/build/dist/Models/DatabaseModels/Incident.js +54 -0
  467. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  468. package/build/dist/Models/DatabaseModels/IncidentAlert.js +553 -0
  469. package/build/dist/Models/DatabaseModels/IncidentAlert.js.map +1 -0
  470. package/build/dist/Models/DatabaseModels/IncidentFeed.js +2 -0
  471. package/build/dist/Models/DatabaseModels/IncidentFeed.js.map +1 -1
  472. package/build/dist/Models/DatabaseModels/Index.js +18 -0
  473. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  474. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  475. package/build/dist/Models/DatabaseModels/Project.js +62 -0
  476. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  477. package/build/dist/Models/DatabaseModels/RumApplication.js +53 -1
  478. package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
  479. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +54 -0
  480. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  481. package/build/dist/Models/DatabaseModels/TelemetryException.js +2 -0
  482. package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -1
  483. package/build/dist/Models/DatabaseModels/UserProjectSsoConsent.js +162 -0
  484. package/build/dist/Models/DatabaseModels/UserProjectSsoConsent.js.map +1 -0
  485. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.js +20 -0
  486. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.js.map +1 -0
  487. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.js +42 -0
  488. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.js.map +1 -0
  489. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.js +240 -0
  490. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.js.map +1 -0
  491. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.js +26 -0
  492. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.js.map +1 -0
  493. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  494. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  495. package/build/dist/Server/Middleware/MultipartFormData.js +1 -1
  496. package/build/dist/Server/Middleware/TelemetryIngest.js +15 -8
  497. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  498. package/build/dist/Server/Services/AlertReminderRuleService.js +72 -23
  499. package/build/dist/Server/Services/AlertReminderRuleService.js.map +1 -1
  500. package/build/dist/Server/Services/DatabaseServerEndpointService.js +694 -0
  501. package/build/dist/Server/Services/DatabaseServerEndpointService.js.map +1 -0
  502. package/build/dist/Server/Services/DatabaseServerFeedService.js +110 -0
  503. package/build/dist/Server/Services/DatabaseServerFeedService.js.map +1 -0
  504. package/build/dist/Server/Services/DatabaseServerLabelRuleEngineService.js +272 -0
  505. package/build/dist/Server/Services/DatabaseServerLabelRuleEngineService.js.map +1 -0
  506. package/build/dist/Server/Services/DatabaseServerLabelRuleService.js +13 -0
  507. package/build/dist/Server/Services/DatabaseServerLabelRuleService.js.map +1 -0
  508. package/build/dist/Server/Services/DatabaseServerOwnerRuleEngineService.js +340 -0
  509. package/build/dist/Server/Services/DatabaseServerOwnerRuleEngineService.js.map +1 -0
  510. package/build/dist/Server/Services/DatabaseServerOwnerRuleService.js +13 -0
  511. package/build/dist/Server/Services/DatabaseServerOwnerRuleService.js.map +1 -0
  512. package/build/dist/Server/Services/DatabaseServerOwnerTeamService.js +160 -0
  513. package/build/dist/Server/Services/DatabaseServerOwnerTeamService.js.map +1 -0
  514. package/build/dist/Server/Services/DatabaseServerOwnerUserService.js +153 -0
  515. package/build/dist/Server/Services/DatabaseServerOwnerUserService.js.map +1 -0
  516. package/build/dist/Server/Services/DatabaseServerService.js +3272 -0
  517. package/build/dist/Server/Services/DatabaseServerService.js.map +1 -0
  518. package/build/dist/Server/Services/DatabaseService.js +8 -4
  519. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  520. package/build/dist/Server/Services/DockerResourceService.js +30 -3
  521. package/build/dist/Server/Services/DockerResourceService.js.map +1 -1
  522. package/build/dist/Server/Services/IncidentAlertService.js +1370 -0
  523. package/build/dist/Server/Services/IncidentAlertService.js.map +1 -0
  524. package/build/dist/Server/Services/IncidentReminderRuleService.js +73 -23
  525. package/build/dist/Server/Services/IncidentReminderRuleService.js.map +1 -1
  526. package/build/dist/Server/Services/IncidentService.js +164 -12
  527. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  528. package/build/dist/Server/Services/IncidentStateTimelineService.js +21 -0
  529. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  530. package/build/dist/Server/Services/Index.js +18 -0
  531. package/build/dist/Server/Services/Index.js.map +1 -1
  532. package/build/dist/Server/Services/InventoryItemService.js +88 -5
  533. package/build/dist/Server/Services/InventoryItemService.js.map +1 -1
  534. package/build/dist/Server/Services/IoTDeviceService.js +111 -24
  535. package/build/dist/Server/Services/IoTDeviceService.js.map +1 -1
  536. package/build/dist/Server/Services/OpenTelemetryIngestService.js +24 -9
  537. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  538. package/build/dist/Server/Services/PodmanResourceService.js +30 -3
  539. package/build/dist/Server/Services/PodmanResourceService.js.map +1 -1
  540. package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js +75 -23
  541. package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js.map +1 -1
  542. package/build/dist/Server/Services/ServiceService.js +1 -1
  543. package/build/dist/Server/Services/ServiceService.js.map +1 -1
  544. package/build/dist/Server/Services/TelemetryUsageBillingService.js +23 -2
  545. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  546. package/build/dist/Server/Services/UserProjectSsoConsentService.js +79 -0
  547. package/build/dist/Server/Services/UserProjectSsoConsentService.js.map +1 -0
  548. package/build/dist/Server/Services/UserService.js +13 -1
  549. package/build/dist/Server/Services/UserService.js.map +1 -1
  550. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +18 -0
  551. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
  552. package/build/dist/Server/Types/Database/QueryHelper.js +26 -1
  553. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  554. package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js +46 -0
  555. package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js.map +1 -1
  556. package/build/dist/Server/Utils/Database/AffectedResourceRelations.js +6 -0
  557. package/build/dist/Server/Utils/Database/AffectedResourceRelations.js.map +1 -1
  558. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js +134 -13
  559. package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js.map +1 -1
  560. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +22 -6
  561. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  562. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +1489 -524
  563. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  564. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +22 -6
  565. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  566. package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js +196 -6
  567. package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js.map +1 -1
  568. package/build/dist/Server/Utils/Monitor/MonitorResource.js +36 -9
  569. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  570. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +1 -0
  571. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -1
  572. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +175 -17
  573. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -1
  574. package/build/dist/Server/Utils/Monitor/PerSeriesResolutionRootCause.js +29 -0
  575. package/build/dist/Server/Utils/Monitor/PerSeriesResolutionRootCause.js.map +1 -0
  576. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +211 -0
  577. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js.map +1 -1
  578. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +82 -10
  579. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
  580. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +25 -0
  581. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -1
  582. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js +8 -0
  583. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js.map +1 -1
  584. package/build/dist/Server/Utils/StartServer.js +20 -4
  585. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  586. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js +2 -0
  587. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js.map +1 -1
  588. package/build/dist/Server/Utils/Telemetry/DatabaseEndpointDiscovery.js +442 -0
  589. package/build/dist/Server/Utils/Telemetry/DatabaseEndpointDiscovery.js.map +1 -0
  590. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +5 -1
  591. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
  592. package/build/dist/Server/Utils/Telemetry/LogExceptionExtractor.js +15 -1
  593. package/build/dist/Server/Utils/Telemetry/LogExceptionExtractor.js.map +1 -1
  594. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +121 -5
  595. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -1
  596. package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js +12 -0
  597. package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js.map +1 -1
  598. package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js +438 -36
  599. package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js.map +1 -1
  600. package/build/dist/Server/Utils/Telemetry/Telemetry.js +12 -0
  601. package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
  602. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +17 -18
  603. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
  604. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js +16 -10
  605. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js.map +1 -1
  606. package/build/dist/Types/AI/AIResourceContext.js +7 -0
  607. package/build/dist/Types/AI/AIResourceContext.js.map +1 -1
  608. package/build/dist/Types/Dashboard/DashboardTemplates.js +2 -1
  609. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  610. package/build/dist/Types/DatabaseServer/DatabaseConnectionSpan.js +71 -0
  611. package/build/dist/Types/DatabaseServer/DatabaseConnectionSpan.js.map +1 -0
  612. package/build/dist/Types/DatabaseServer/DatabaseContainerClassifier.js +1462 -0
  613. package/build/dist/Types/DatabaseServer/DatabaseContainerClassifier.js.map +1 -0
  614. package/build/dist/Types/DatabaseServer/DatabaseContainerCommand.js +691 -0
  615. package/build/dist/Types/DatabaseServer/DatabaseContainerCommand.js.map +1 -0
  616. package/build/dist/Types/DatabaseServer/DatabaseEndpoint.js +1407 -0
  617. package/build/dist/Types/DatabaseServer/DatabaseEndpoint.js.map +1 -0
  618. package/build/dist/Types/DatabaseServer/DatabaseServerDiscoverySource.js +60 -0
  619. package/build/dist/Types/DatabaseServer/DatabaseServerDiscoverySource.js.map +1 -0
  620. package/build/dist/Types/DatabaseServer/DatabaseServerMetricCatalog.js +804 -0
  621. package/build/dist/Types/DatabaseServer/DatabaseServerMetricCatalog.js.map +1 -0
  622. package/build/dist/Types/DatabaseServer/DatabaseSystem.js +1860 -0
  623. package/build/dist/Types/DatabaseServer/DatabaseSystem.js.map +1 -0
  624. package/build/dist/Types/DatabaseServer/DatabaseTelemetryResolver.js +406 -0
  625. package/build/dist/Types/DatabaseServer/DatabaseTelemetryResolver.js.map +1 -0
  626. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  627. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  628. package/build/dist/Types/Incident/IncidentAlertLink.js +34 -0
  629. package/build/dist/Types/Incident/IncidentAlertLink.js.map +1 -0
  630. package/build/dist/Types/Monitor/CephAlertTemplates.js +18 -0
  631. package/build/dist/Types/Monitor/CephAlertTemplates.js.map +1 -1
  632. package/build/dist/Types/Monitor/DatabaseAlertTemplates.js +1518 -0
  633. package/build/dist/Types/Monitor/DatabaseAlertTemplates.js.map +1 -0
  634. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +57 -24
  635. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
  636. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js +104 -18
  637. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js.map +1 -1
  638. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +80 -3
  639. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
  640. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +10 -3
  641. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
  642. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +29 -0
  643. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
  644. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js +21 -6
  645. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js.map +1 -1
  646. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +25 -0
  647. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -1
  648. package/build/dist/Types/NetworkDevice/DiscoveredHostNamingStatus.js +136 -0
  649. package/build/dist/Types/NetworkDevice/DiscoveredHostNamingStatus.js.map +1 -0
  650. package/build/dist/Types/Permission.js +276 -0
  651. package/build/dist/Types/Permission.js.map +1 -1
  652. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +10 -0
  653. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
  654. package/build/dist/Types/Rules/RuleRun.js +4 -0
  655. package/build/dist/Types/Rules/RuleRun.js.map +1 -1
  656. package/build/dist/Types/Rum/WebVitals.js +25 -0
  657. package/build/dist/Types/Rum/WebVitals.js.map +1 -1
  658. package/build/dist/Types/Telemetry/EntityType.js +23 -0
  659. package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
  660. package/build/dist/Types/Telemetry/ResourceFacetCatalog.js +14 -0
  661. package/build/dist/Types/Telemetry/ResourceFacetCatalog.js.map +1 -1
  662. package/build/dist/Types/Telemetry/ServiceType.js +8 -0
  663. package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
  664. package/build/dist/UI/Components/Banner/Banner.js +1 -1
  665. package/build/dist/UI/Components/Banner/Banner.js.map +1 -1
  666. package/build/dist/UI/Components/Card/Card.js +1 -1
  667. package/build/dist/UI/Components/Card/Card.js.map +1 -1
  668. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +2 -2
  669. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  670. package/build/dist/UI/Components/Charts/Line/LineChart.js +1 -1
  671. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  672. package/build/dist/UI/Components/CommandPalette/CommandPalette.js +1 -1
  673. package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -1
  674. package/build/dist/UI/Components/Date/StartAndEndDate.js +5 -5
  675. package/build/dist/UI/Components/Date/StartAndEndDate.js.map +1 -1
  676. package/build/dist/UI/Components/Detail/FieldLabel.js +2 -0
  677. package/build/dist/UI/Components/Detail/FieldLabel.js.map +1 -1
  678. package/build/dist/UI/Components/Diagram/HorizontalStepChain.js +1 -1
  679. package/build/dist/UI/Components/Diagram/HorizontalStepChain.js.map +1 -1
  680. package/build/dist/UI/Components/Feed/FeedOptionsButton.js +1 -1
  681. package/build/dist/UI/Components/Feed/FeedOptionsButton.js.map +1 -1
  682. package/build/dist/UI/Components/Forms/BasicForm.js +1 -1
  683. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  684. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js +1 -1
  685. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js.map +1 -1
  686. package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js +1 -1
  687. package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js.map +1 -1
  688. package/build/dist/UI/Components/InfoCard/InfoCard.js +22 -1
  689. package/build/dist/UI/Components/InfoCard/InfoCard.js.map +1 -1
  690. package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js +1 -1
  691. package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js.map +1 -1
  692. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +1 -1
  693. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
  694. package/build/dist/UI/Components/Modal/ModalFooter.js +1 -1
  695. package/build/dist/UI/Components/Modal/ModalFooter.js.map +1 -1
  696. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +2 -2
  697. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  698. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +70 -18
  699. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  700. package/build/dist/UI/Components/Navbar/NavBar.js +9 -2
  701. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  702. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +2 -2
  703. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  704. package/build/dist/UI/Components/Page/Page.js +1 -1
  705. package/build/dist/UI/Components/Page/Page.js.map +1 -1
  706. package/build/dist/UI/Components/Pagination/Pagination.js +3 -3
  707. package/build/dist/UI/Components/Pagination/Pagination.js.map +1 -1
  708. package/build/dist/UI/Components/ProgressButtons/ProgressButtonItem.js +1 -1
  709. package/build/dist/UI/Components/ProgressButtons/ProgressButtonItem.js.map +1 -1
  710. package/build/dist/UI/Components/SideMenu/SideMenu.js +4 -1
  711. package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
  712. package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js +3 -1
  713. package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js.map +1 -1
  714. package/build/dist/UI/Components/StatusPage/ResourceList.js +6 -6
  715. package/build/dist/UI/Components/StatusPage/ResourceList.js.map +1 -1
  716. package/build/dist/UI/Components/Table/TableHeader.js +18 -2
  717. package/build/dist/UI/Components/Table/TableHeader.js.map +1 -1
  718. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +1 -1
  719. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
  720. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js +1 -1
  721. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js.map +1 -1
  722. package/build/dist/UI/Components/Tooltip/InfoTooltip.js +28 -0
  723. package/build/dist/UI/Components/Tooltip/InfoTooltip.js.map +1 -0
  724. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js +1 -1
  725. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js.map +1 -1
  726. package/build/dist/UI/Components/Workflow/ComponentsModal.js +2 -2
  727. package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
  728. package/build/dist/UI/Components/Workflow/StepTraceViewer.js +1 -1
  729. package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -1
  730. package/build/dist/UI/Utils/Navigation.js +66 -33
  731. package/build/dist/UI/Utils/Navigation.js.map +1 -1
  732. package/build/dist/UI/Utils/PermissionGate.js +4 -2
  733. package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
  734. package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js +7 -0
  735. package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js.map +1 -1
  736. package/build/dist/UI/Utils/TelemetryService.js +3 -2
  737. package/build/dist/UI/Utils/TelemetryService.js.map +1 -1
  738. package/build/dist/Utils/Incident/IncidentFromAlerts.js +306 -0
  739. package/build/dist/Utils/Incident/IncidentFromAlerts.js.map +1 -0
  740. package/build/dist/Utils/LabelRuleImportExport.js +2 -0
  741. package/build/dist/Utils/LabelRuleImportExport.js.map +1 -1
  742. package/build/dist/Utils/MetricUnitUtil.js +77 -13
  743. package/build/dist/Utils/MetricUnitUtil.js.map +1 -1
  744. package/build/dist/Utils/Monitor/MetricValueFormatter.js +58 -13
  745. package/build/dist/Utils/Monitor/MetricValueFormatter.js.map +1 -1
  746. package/build/dist/Utils/Monitor/PlatformMetricUnitUtil.js +161 -0
  747. package/build/dist/Utils/Monitor/PlatformMetricUnitUtil.js.map +1 -0
  748. package/build/dist/Utils/Monitor/PlatformResourceIdentity.js +323 -0
  749. package/build/dist/Utils/Monitor/PlatformResourceIdentity.js.map +1 -0
  750. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.js +270 -0
  751. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.js.map +1 -0
  752. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js +23 -0
  753. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js.map +1 -1
  754. package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js +61 -0
  755. package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js.map +1 -1
  756. package/build/dist/Utils/Rum/SessionTraceState.js +154 -0
  757. package/build/dist/Utils/Rum/SessionTraceState.js.map +1 -0
  758. package/build/dist/Utils/Telemetry/DatabaseServerEntityKeys.js +178 -0
  759. package/build/dist/Utils/Telemetry/DatabaseServerEntityKeys.js.map +1 -0
  760. package/build/dist/Utils/Telemetry/EntityKey.js +133 -0
  761. package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
  762. package/build/dist/Utils/ValueFormatter.js +15 -0
  763. package/build/dist/Utils/ValueFormatter.js.map +1 -1
  764. package/package.json +1 -1
  765. package/tsconfig.tests.json +7 -5
@@ -0,0 +1,1514 @@
1
+ import {
2
+ DATABASE_SYSTEMS,
3
+ DatabaseSystemDescriptor,
4
+ getCollectorReceiverComponentName,
5
+ getDatabaseReceiverSystemHint,
6
+ getDatabaseSystemDescriptor,
7
+ getDatabaseSystemDisplayName,
8
+ getDatabaseSystemFamily,
9
+ getDatabaseSystemFromReceiverScopeName,
10
+ getDatabaseSystemMetricsEngine,
11
+ getDatabaseEngineMetricsSource,
12
+ getDefaultDatabasePort,
13
+ getMoreSpecificDatabaseSystem,
14
+ isAutoCreatableDatabaseSystem,
15
+ isCompatibilityVersionAttribute,
16
+ isKnownDatabaseSystem,
17
+ isSameDatabaseFamily,
18
+ normalizeDatabaseSystem,
19
+ refineDatabaseSystemFromVersion,
20
+ trimTrailingCharacter,
21
+ } from "../../../Types/DatabaseServer/DatabaseSystem";
22
+ import {
23
+ classifyImage,
24
+ ImageClassification,
25
+ } from "../../../Types/DatabaseServer/DatabaseContainerClassifier";
26
+ import { describe, expect, test } from "@jest/globals";
27
+
28
+ const CONTRIB_PREFIX: string =
29
+ "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/";
30
+
31
+ /*
32
+ * The semconv registry's well-known `db.system.name` values
33
+ * (model/db/registry.yaml), and the values of the deprecated `db.system`
34
+ * attribute it replaced (model/db/deprecated/registry-deprecated.yaml).
35
+ * Every one of them is what some instrumentation puts on a span, so each
36
+ * must land on a catalog engine — or be one of the deliberate exceptions
37
+ * below.
38
+ */
39
+ const SEMCONV_DB_SYSTEM_NAMES: ReadonlyArray<string> = [
40
+ "other_sql",
41
+ "softwareag.adabas",
42
+ "actian.ingres",
43
+ "aws.dynamodb",
44
+ "aws.redshift",
45
+ "azure.cosmosdb",
46
+ "intersystems.cache",
47
+ "cassandra",
48
+ "clickhouse",
49
+ "cockroachdb",
50
+ "couchbase",
51
+ "couchdb",
52
+ "derby",
53
+ "elasticsearch",
54
+ "firebirdsql",
55
+ "gcp.spanner",
56
+ "geode",
57
+ "h2database",
58
+ "hbase",
59
+ "hive",
60
+ "hsqldb",
61
+ "ibm.db2",
62
+ "ibm.informix",
63
+ "ibm.netezza",
64
+ "influxdb",
65
+ "instantdb",
66
+ "mariadb",
67
+ "memcached",
68
+ "mongodb",
69
+ "microsoft.sql_server",
70
+ "mysql",
71
+ "neo4j",
72
+ "opensearch",
73
+ "oracle.db",
74
+ "postgresql",
75
+ "redis",
76
+ "sap.hana",
77
+ "sap.maxdb",
78
+ "sqlite",
79
+ "teradata",
80
+ "trino",
81
+ ];
82
+
83
+ const SEMCONV_DEPRECATED_DB_SYSTEMS: ReadonlyArray<string> = [
84
+ "other_sql",
85
+ "adabas",
86
+ "cache",
87
+ "intersystems_cache",
88
+ "cassandra",
89
+ "clickhouse",
90
+ "cloudscape",
91
+ "cockroachdb",
92
+ "coldfusion",
93
+ "cosmosdb",
94
+ "couchbase",
95
+ "couchdb",
96
+ "db2",
97
+ "derby",
98
+ "dynamodb",
99
+ "edb",
100
+ "elasticsearch",
101
+ "filemaker",
102
+ "firebird",
103
+ "firstsql",
104
+ "geode",
105
+ "h2",
106
+ "hanadb",
107
+ "hbase",
108
+ "hive",
109
+ "hsqldb",
110
+ "influxdb",
111
+ "informix",
112
+ "ingres",
113
+ "instantdb",
114
+ "interbase",
115
+ "mariadb",
116
+ "maxdb",
117
+ "memcached",
118
+ "mongodb",
119
+ "mssql",
120
+ "mssqlcompact",
121
+ "mysql",
122
+ "neo4j",
123
+ "netezza",
124
+ "opensearch",
125
+ "oracle",
126
+ "pervasive",
127
+ "pointbase",
128
+ "postgresql",
129
+ "progress",
130
+ "redis",
131
+ "redshift",
132
+ "spanner",
133
+ "sqlite",
134
+ "sybase",
135
+ "teradata",
136
+ "trino",
137
+ "vertica",
138
+ ];
139
+
140
+ /*
141
+ * Values that deliberately stay unknown (normalized to themselves, never
142
+ * shown as an engine they are not):
143
+ * - other_sql: "some SQL database the instrumentation could not name";
144
+ * - coldfusion: a web application server, not a database;
145
+ * - firstsql, pointbase: products discontinued two decades ago;
146
+ * - mssqlcompact: SQL Server Compact, an in-process library Microsoft
147
+ * retired in 2016 — never SQL Server itself.
148
+ */
149
+ const DELIBERATELY_UNKNOWN: ReadonlyArray<string> = [
150
+ "other_sql",
151
+ "coldfusion",
152
+ "firstsql",
153
+ "pointbase",
154
+ "mssqlcompact",
155
+ ];
156
+
157
+ /*
158
+ * The receivers of the collector the Database Agent pins
159
+ * (`otel/opentelemetry-collector-contrib:0.161.0 components`). Every
160
+ * receiver the catalog names must exist there under that name.
161
+ */
162
+ const PINNED_COLLECTOR_RECEIVERS: ReadonlySet<string> = new Set<string>([
163
+ "active_directory_ds",
164
+ "aerospike",
165
+ "apache",
166
+ "apache_spark",
167
+ "aws_cloudwatch",
168
+ "aws_lambda",
169
+ "awscontainerinsightreceiver",
170
+ "awsecscontainermetrics",
171
+ "awsfirehose",
172
+ "awss3",
173
+ "awsxray",
174
+ "azure_blob",
175
+ "azure_event_hub",
176
+ "azure_monitor",
177
+ "carbon",
178
+ "chrony",
179
+ "cisco_os",
180
+ "cloud_foundry",
181
+ "cloudflare",
182
+ "collectd",
183
+ "couchdb",
184
+ "datadog",
185
+ "docker_stats",
186
+ "elasticsearch",
187
+ "envoy_als",
188
+ "expvar",
189
+ "faro",
190
+ "file_log",
191
+ "file_stats",
192
+ "flink_metrics",
193
+ "fluent_forward",
194
+ "github",
195
+ "gitlab",
196
+ "google_cloud_spanner",
197
+ "googlecloudmonitoring",
198
+ "googlecloudpubsub",
199
+ "haproxy",
200
+ "host_metrics",
201
+ "http_check",
202
+ "icmp_check",
203
+ "iis",
204
+ "influxdb",
205
+ "jaeger",
206
+ "journald",
207
+ "k8s_cluster",
208
+ "k8s_events",
209
+ "k8s_objects",
210
+ "kafka",
211
+ "kafka_metrics",
212
+ "kubelet_stats",
213
+ "libhoney",
214
+ "loki",
215
+ "macos_unified_logging",
216
+ "memcached",
217
+ "mongodb",
218
+ "mongodb_atlas",
219
+ "mysql",
220
+ "named_pipe",
221
+ "netflow",
222
+ "nginx",
223
+ "nop",
224
+ "nsxt",
225
+ "ntp",
226
+ "obi",
227
+ "oracledb",
228
+ "otelarrow",
229
+ "otlp",
230
+ "otlp_json_file",
231
+ "podman_stats",
232
+ "postgresql",
233
+ "pprof",
234
+ "prometheus",
235
+ "prometheus_remote_write",
236
+ "prometheus_simple",
237
+ "pulsar",
238
+ "purefa",
239
+ "purefb",
240
+ "rabbitmq",
241
+ "receiver_creator",
242
+ "redis",
243
+ "riak",
244
+ "saphana",
245
+ "skywalking",
246
+ "snmp",
247
+ "snowflake",
248
+ "solace",
249
+ "splunk_enterprise",
250
+ "splunk_hec",
251
+ "sql_query",
252
+ "sqlserver",
253
+ "ssh_check",
254
+ "statsd",
255
+ "stef",
256
+ "syslog",
257
+ "systemd",
258
+ "tcp_check",
259
+ "tcp_log",
260
+ "tls_check",
261
+ "udp_log",
262
+ "vcenter",
263
+ "wavefront",
264
+ "webhook_event",
265
+ "windows_event_log",
266
+ "windows_perf_counters",
267
+ "windows_service",
268
+ "yang_grpc",
269
+ "zipkin",
270
+ "zookeeper",
271
+ ]);
272
+
273
+ function descriptorOf(system: string): DatabaseSystemDescriptor {
274
+ const descriptor: DatabaseSystemDescriptor | null =
275
+ getDatabaseSystemDescriptor(system);
276
+ expect({ system, known: descriptor !== null }).toEqual({
277
+ system,
278
+ known: true,
279
+ });
280
+ return descriptor as DatabaseSystemDescriptor;
281
+ }
282
+
283
+ function isForkOf(descriptor: DatabaseSystemDescriptor): boolean {
284
+ return Boolean(descriptor.family);
285
+ }
286
+
287
+ describe("DATABASE_SYSTEMS registry integrity", () => {
288
+ test("covers the widely used engines (a floor, so an entry is never dropped by accident)", () => {
289
+ expect(DATABASE_SYSTEMS.length).toBeGreaterThanOrEqual(80);
290
+ });
291
+
292
+ test("systems are unique, lowercase and trimmed", () => {
293
+ const systems: Array<string> = DATABASE_SYSTEMS.map(
294
+ (descriptor: DatabaseSystemDescriptor): string => {
295
+ return descriptor.system;
296
+ },
297
+ );
298
+ expect(new Set(systems).size).toBe(systems.length);
299
+ for (const system of systems) {
300
+ expect(system).toBe(system.trim().toLowerCase());
301
+ expect(system).toMatch(/^[a-z0-9][a-z0-9._]*$/);
302
+ }
303
+ });
304
+
305
+ test("display names are non-empty and unique", () => {
306
+ const names: Array<string> = DATABASE_SYSTEMS.map(
307
+ (descriptor: DatabaseSystemDescriptor): string => {
308
+ return descriptor.displayName;
309
+ },
310
+ );
311
+ for (const name of names) {
312
+ expect(name.trim().length).toBeGreaterThan(0);
313
+ expect(name).toBe(name.trim());
314
+ }
315
+ expect(new Set(names).size).toBe(names.length);
316
+ });
317
+
318
+ test("no alias is claimed by two engines or shadows a system", () => {
319
+ const owners: Map<string, string> = new Map<string, string>();
320
+ for (const descriptor of DATABASE_SYSTEMS) {
321
+ owners.set(descriptor.system, descriptor.system);
322
+ }
323
+ for (const descriptor of DATABASE_SYSTEMS) {
324
+ for (const alias of descriptor.aliases) {
325
+ expect(alias).toBe(alias.trim().toLowerCase());
326
+ expect({ alias, claimedBy: owners.get(alias) }).toEqual({
327
+ alias,
328
+ claimedBy: undefined,
329
+ });
330
+ owners.set(alias, descriptor.system);
331
+ }
332
+ }
333
+ });
334
+
335
+ test("every family is a known engine that is its own family (no chains, no self-reference)", () => {
336
+ for (const descriptor of DATABASE_SYSTEMS) {
337
+ if (!descriptor.family) {
338
+ continue;
339
+ }
340
+ const family: DatabaseSystemDescriptor = descriptorOf(descriptor.family);
341
+ expect({
342
+ system: descriptor.system,
343
+ family: descriptor.family,
344
+ canonical: family.system,
345
+ chained: Boolean(family.family),
346
+ }).toEqual({
347
+ system: descriptor.system,
348
+ family: descriptor.family,
349
+ canonical: descriptor.family,
350
+ chained: false,
351
+ });
352
+ expect(descriptor.family).not.toBe(descriptor.system);
353
+ }
354
+ });
355
+
356
+ test("every receiver type is owned by exactly one engine that is its own family", () => {
357
+ const owners: Map<string, string> = new Map<string, string>();
358
+ for (const descriptor of DATABASE_SYSTEMS) {
359
+ if (isForkOf(descriptor)) {
360
+ continue;
361
+ }
362
+ for (const receiverType of descriptor.receiverTypes) {
363
+ expect({ receiverType, owner: owners.get(receiverType) }).toEqual({
364
+ receiverType,
365
+ owner: undefined,
366
+ });
367
+ owners.set(receiverType, descriptor.system);
368
+ }
369
+ }
370
+ // Everything a fork lists belongs to its own family's engine.
371
+ for (const descriptor of DATABASE_SYSTEMS) {
372
+ if (!isForkOf(descriptor)) {
373
+ continue;
374
+ }
375
+ for (const receiverType of descriptor.receiverTypes) {
376
+ expect({
377
+ fork: descriptor.system,
378
+ receiverType,
379
+ owner: owners.get(receiverType),
380
+ }).toEqual({
381
+ fork: descriptor.system,
382
+ receiverType,
383
+ owner: descriptor.family,
384
+ });
385
+ }
386
+ const family: DatabaseSystemDescriptor = descriptorOf(
387
+ descriptor.family as string,
388
+ );
389
+ for (const prefix of descriptor.receiverMetricPrefixes) {
390
+ expect(family.receiverMetricPrefixes).toContain(prefix);
391
+ }
392
+ }
393
+ });
394
+
395
+ test("hasCollectorReceiver agrees with receiverTypes, prefixes and engineMetrics", () => {
396
+ for (const descriptor of DATABASE_SYSTEMS) {
397
+ const context: { system: string } = { system: descriptor.system };
398
+ expect({
399
+ ...context,
400
+ has: descriptor.hasCollectorReceiver,
401
+ }).toEqual({ ...context, has: descriptor.receiverTypes.length > 0 });
402
+ expect({
403
+ ...context,
404
+ prefixes: descriptor.receiverMetricPrefixes.length > 0,
405
+ }).toEqual({ ...context, prefixes: descriptor.hasCollectorReceiver });
406
+ expect({
407
+ ...context,
408
+ receiverKind: descriptor.engineMetrics.kind === "receiver",
409
+ }).toEqual({ ...context, receiverKind: descriptor.hasCollectorReceiver });
410
+ for (const prefix of descriptor.receiverMetricPrefixes) {
411
+ // Stored metric names are lowercased at ingest.
412
+ expect(prefix).toBe(prefix.toLowerCase());
413
+ // A whole name segment: `redis.` never matches `redisearch_…`.
414
+ expect(prefix.endsWith(".") || prefix.endsWith("/")).toBe(true);
415
+ }
416
+ }
417
+ });
418
+
419
+ test("every receiver is configured under a name the pinned collector ships", () => {
420
+ for (const descriptor of DATABASE_SYSTEMS) {
421
+ for (const receiverType of descriptor.receiverTypes) {
422
+ const component: string =
423
+ getCollectorReceiverComponentName(receiverType);
424
+ expect({
425
+ receiverType,
426
+ component,
427
+ shipped: PINNED_COLLECTOR_RECEIVERS.has(component),
428
+ }).toEqual({ receiverType, component, shipped: true });
429
+ }
430
+ if (descriptor.engineMetrics.kind === "cloud-monitoring") {
431
+ expect(
432
+ PINNED_COLLECTOR_RECEIVERS.has(descriptor.engineMetrics.receiver),
433
+ ).toBe(true);
434
+ }
435
+ }
436
+ // The Prometheus recipes run the pinned prometheus receiver.
437
+ expect(PINNED_COLLECTOR_RECEIVERS.has("prometheus")).toBe(true);
438
+ });
439
+
440
+ test("engineMetrics recipes are complete", () => {
441
+ for (const descriptor of DATABASE_SYSTEMS) {
442
+ const source: DatabaseSystemDescriptor["engineMetrics"] =
443
+ descriptor.engineMetrics;
444
+ // Only an in-process engine has nothing to collect from.
445
+ expect({
446
+ system: descriptor.system,
447
+ embedded: source.kind === "embedded",
448
+ }).toEqual({
449
+ system: descriptor.system,
450
+ embedded: descriptor.deployment === "embedded",
451
+ });
452
+ if (source.kind === "prometheus") {
453
+ expect(Number.isInteger(source.port)).toBe(true);
454
+ expect(source.port).toBeGreaterThanOrEqual(1);
455
+ expect(source.port).toBeLessThanOrEqual(65535);
456
+ expect(source.path.startsWith("/")).toBe(true);
457
+ expect(source.path).not.toMatch(/\s/);
458
+ }
459
+ if (source.kind === "none" || source.kind === "cloud-monitoring") {
460
+ const text: string =
461
+ source.kind === "none" ? source.reason : source.note;
462
+ expect(text.trim().length).toBeGreaterThan(20);
463
+ expect(text.endsWith(".")).toBe(true);
464
+ }
465
+ }
466
+ });
467
+
468
+ test("a versionPattern is only on a fork, and it names the fork", () => {
469
+ for (const descriptor of DATABASE_SYSTEMS) {
470
+ if (descriptor.versionPattern) {
471
+ expect({
472
+ system: descriptor.system,
473
+ fork: isForkOf(descriptor),
474
+ }).toEqual({ system: descriptor.system, fork: true });
475
+ expect(descriptor.versionPattern.global).toBe(false);
476
+ expect(descriptor.versionPattern.sticky).toBe(false);
477
+ }
478
+ }
479
+ });
480
+
481
+ /*
482
+ * A major version names a fork only when its family never released it:
483
+ * MySQL's releases stop at 9.x, so only MariaDB — 10.x, 11.x, 12.x — may
484
+ * claim the majors from 10 on, and only one fork of a family may claim
485
+ * them.
486
+ */
487
+ test("a versionMajorFrom is only on a fork, above every release of its family", () => {
488
+ const claimedFamilies: Array<string> = [];
489
+ for (const descriptor of DATABASE_SYSTEMS) {
490
+ if (descriptor.versionMajorFrom === undefined) {
491
+ continue;
492
+ }
493
+ expect({
494
+ system: descriptor.system,
495
+ fork: isForkOf(descriptor),
496
+ }).toEqual({ system: descriptor.system, fork: true });
497
+ expect(Number.isInteger(descriptor.versionMajorFrom)).toBe(true);
498
+ expect(descriptor.versionMajorFrom).toBeGreaterThanOrEqual(10);
499
+ claimedFamilies.push(descriptor.family!);
500
+ }
501
+ expect(claimedFamilies).toEqual(["mysql"]);
502
+ expect(getDatabaseSystemDescriptor("mariadb")?.versionMajorFrom).toBe(10);
503
+ });
504
+
505
+ test("a compatibility version attribute is only on a fork, and is its receiver's version attribute", () => {
506
+ for (const descriptor of DATABASE_SYSTEMS) {
507
+ for (const key of descriptor.compatibilityVersionAttributes || []) {
508
+ expect({
509
+ system: descriptor.system,
510
+ fork: isForkOf(descriptor),
511
+ }).toEqual({ system: descriptor.system, fork: true });
512
+ expect(key).toBe(`${descriptor.receiverTypes[0]}.version`);
513
+ }
514
+ }
515
+ });
516
+
517
+ test("image repositories are canonical, and no repository or chart name is claimed by two engines", () => {
518
+ const images: Map<string, string> = new Map<string, string>();
519
+ const charts: Map<string, string> = new Map<string, string>();
520
+ for (const descriptor of DATABASE_SYSTEMS) {
521
+ for (const image of descriptor.imageRepositories) {
522
+ expect(image).toMatch(/^[a-z0-9._-]+(?:\/[a-z0-9._-]+)*$/);
523
+ /*
524
+ * Canonical form: the registry host and `library/` are stripped
525
+ * before matching, so an entry must not carry them.
526
+ */
527
+ expect(image.split("/")[0]).not.toMatch(/[.:]/);
528
+ expect(image.startsWith("library/")).toBe(false);
529
+ expect({ image, claimedBy: images.get(image) }).toEqual({
530
+ image,
531
+ claimedBy: undefined,
532
+ });
533
+ images.set(image, descriptor.system);
534
+ }
535
+ for (const chart of descriptor.kubernetesChartNames) {
536
+ expect(chart).toBe(chart.toLowerCase());
537
+ expect({ chart, claimedBy: charts.get(chart) }).toEqual({
538
+ chart,
539
+ claimedBy: undefined,
540
+ });
541
+ charts.set(chart, descriptor.system);
542
+ }
543
+ }
544
+ });
545
+
546
+ test("every image repository classifies as its own engine, with or without a registry and tag", () => {
547
+ for (const descriptor of DATABASE_SYSTEMS) {
548
+ for (const image of descriptor.imageRepositories) {
549
+ for (const reference of [
550
+ image,
551
+ `${image}:1.2.3`,
552
+ `registry.example.com/${image}:latest`,
553
+ ]) {
554
+ const classification: ImageClassification = classifyImage(reference);
555
+ expect({ reference, classification }).toEqual({
556
+ reference,
557
+ classification: { kind: "database", system: descriptor.system },
558
+ });
559
+ }
560
+ }
561
+ }
562
+ });
563
+
564
+ /*
565
+ * Regression (image coverage): these references came out "unknown", so a
566
+ * Docker / Podman / OpenShift database running them never appeared —
567
+ * Bitnami's 2025 bitnamilegacy / bitnamisecure registries, Red Hat
568
+ * Software Collections images, and the official images of catalog
569
+ * engines that listed none. The catalog lists each engine's repositories
570
+ * canonically; the classifier folds the relocated and versioned names
571
+ * onto them.
572
+ */
573
+ test.each([
574
+ ["docker.io/bitnamilegacy/mongodb:7.0.14", "mongodb"],
575
+ ["bitnamisecure/mongodb:7.0", "mongodb"],
576
+ ["bitnamilegacy/redis-cluster:7.2", "redis"],
577
+ ["bitnamilegacy/valkey:8.0", "valkey"],
578
+ ["bitnamilegacy/mariadb-galera:11.4", "mariadb"],
579
+ ["bitnamilegacy/postgresql-repmgr:16", "postgresql"],
580
+ ["bitnamilegacy/clickhouse:24.8", "clickhouse"],
581
+ ["bitnamilegacy/opensearch:2.17", "opensearch"],
582
+ ["bitnamilegacy/mongodb-sharded:7.0", "mongodb"],
583
+ ["registry.redhat.io/rhel9/postgresql-16", "postgresql"],
584
+ ["quay.io/fedora/postgresql-16", "postgresql"],
585
+ ["registry.redhat.io/rhel9/mysql-80", "mysql"],
586
+ ["registry.redhat.io/rhel9/mariadb-1011", "mariadb"],
587
+ ["registry.redhat.io/rhel9/redis-7", "redis"],
588
+ ["registry.redhat.io/rhel10/valkey-8", "valkey"],
589
+ ["citusdata/citus:12.1", "postgresql"],
590
+ ["icr.io/db2_community/db2", "ibm.db2"],
591
+ ["ibmcom/db2:11.5", "ibm.db2"],
592
+ ["saplabs/hanaexpress:2.00.072", "sap.hana"],
593
+ ["firebirdsql/firebird:5", "firebirdsql"],
594
+ ["jacobalberty/firebird:v4.0", "firebirdsql"],
595
+ ["trinodb/trino:450", "trino"],
596
+ ["mariadb:11.4", "mariadb"],
597
+ ["valkey/valkey:8", "valkey"],
598
+ ["docker.dragonflydb.io/dragonflydb/dragonfly:v1.21.0", "dragonfly"],
599
+ ["scylladb/scylla:2025.1", "scylladb"],
600
+ ["pingcap/tidb:v7.5.0", "tidb"],
601
+ ["yugabytedb/yugabyte:2.20", "yugabytedb"],
602
+ ["quay.io/coreos/etcd:v3.5.15", "etcd"],
603
+ ["qdrant/qdrant:v1.12.0", "qdrant"],
604
+ [
605
+ "docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2",
606
+ "elasticsearch",
607
+ ],
608
+ ["quay.io/mongodb/mongodb-enterprise-database-ubi:2.0", "mongodb"],
609
+ ])("%s is %s", (image: string, system: string) => {
610
+ expect(classifyImage(image)).toEqual({ kind: "database", system });
611
+ });
612
+
613
+ /*
614
+ * Regression (Software Collections basenames): the classifier reduces a
615
+ * Red Hat / CentOS / sclorg image name to the engine's bare basename
616
+ * (`centos/mongodb-36-centos7` → `centos/mongodb`,
617
+ * `quay.io/sclorg/valkey-8-c10s` → `sclorg/valkey`), so an engine is only
618
+ * recognised there when its catalog entry lists that bare basename.
619
+ * MongoDB listed only `mongo` and namespaced repositories, so every
620
+ * CentOS / sclorg MongoDB container came out "unknown" and never became
621
+ * a database.
622
+ */
623
+ test.each([
624
+ ["centos/mongodb-36-centos7", "mongodb"],
625
+ ["docker.io/centos/mongodb-36-centos7:latest", "mongodb"],
626
+ ["registry.access.redhat.com/rhscl/mongodb-36-rhel7:1-60", "mongodb"],
627
+ ["quay.io/sclorg/mongodb-36-c8s", "mongodb"],
628
+ ["quay.io/sclorg/valkey-8-c10s", "valkey"],
629
+ ["registry.redhat.io/rhel10/valkey-8:10.0", "valkey"],
630
+ ["quay.io/fedora/valkey-8", "valkey"],
631
+ ["quay.io/sclorg/postgresql-16-c9s", "postgresql"],
632
+ ["quay.io/sclorg/mariadb-1011-c9s", "mariadb"],
633
+ ["quay.io/sclorg/redis-7-c9s", "redis"],
634
+ ["registry.redhat.io/rhel9/memcached:1-80", "memcached"],
635
+ ])(
636
+ "the Software Collections image %s is %s",
637
+ (image: string, system: string) => {
638
+ expect(classifyImage(image)).toEqual({ kind: "database", system });
639
+ },
640
+ );
641
+
642
+ test("each engine a Software Collections image is published for lists its bare basename", () => {
643
+ // The engines Red Hat, CentOS and sclorg publish as `<engine>-<version>`.
644
+ for (const system of [
645
+ "postgresql",
646
+ "mysql",
647
+ "mariadb",
648
+ "redis",
649
+ "valkey",
650
+ "mongodb",
651
+ "memcached",
652
+ ]) {
653
+ const descriptor: DatabaseSystemDescriptor | null =
654
+ getDatabaseSystemDescriptor(system);
655
+
656
+ expect({
657
+ system,
658
+ listsBasename: descriptor?.imageRepositories.includes(system),
659
+ }).toEqual({ system, listsBasename: true });
660
+ }
661
+ });
662
+
663
+ /*
664
+ * Not a basename that means MongoDB: the exporters, operators and admin
665
+ * UIs built around it keep their own names, so the bare entry does not
666
+ * pull them in.
667
+ */
668
+ test.each([
669
+ "percona/mongodb_exporter:0.40",
670
+ "bitnami/mongodb-exporter:0.40",
671
+ "mongodb/mongodb-kubernetes-operator:0.9.0",
672
+ "mongo-express:1.0",
673
+ ])("%s is not a MongoDB database", (image: string) => {
674
+ expect(classifyImage(image)).not.toEqual({
675
+ kind: "database",
676
+ system: "mongodb",
677
+ });
678
+ });
679
+
680
+ test("the control plane's own etcd is not a database of the project", () => {
681
+ // Only the etcd distributions people run as a database are listed.
682
+ expect(classifyImage("registry.k8s.io/etcd:3.5.15-0")).not.toEqual({
683
+ kind: "database",
684
+ system: "etcd",
685
+ });
686
+ });
687
+
688
+ test("engines with no container of their own list no images or charts", () => {
689
+ for (const descriptor of DATABASE_SYSTEMS) {
690
+ if (descriptor.deployment !== "server") {
691
+ expect({
692
+ system: descriptor.system,
693
+ images: descriptor.imageRepositories,
694
+ charts: descriptor.kubernetesChartNames,
695
+ }).toEqual({
696
+ system: descriptor.system,
697
+ images: [],
698
+ charts: [],
699
+ });
700
+ }
701
+ }
702
+ });
703
+
704
+ test("default ports are valid TCP ports or null", () => {
705
+ for (const descriptor of DATABASE_SYSTEMS) {
706
+ if (descriptor.defaultPort !== null) {
707
+ expect(Number.isInteger(descriptor.defaultPort)).toBe(true);
708
+ expect(descriptor.defaultPort).toBeGreaterThanOrEqual(1);
709
+ expect(descriptor.defaultPort).toBeLessThanOrEqual(65535);
710
+ }
711
+ }
712
+ });
713
+
714
+ test("a cloud API is reached over HTTPS, so its default port is 443", () => {
715
+ for (const descriptor of DATABASE_SYSTEMS) {
716
+ if (descriptor.deployment === "cloud-api") {
717
+ expect({
718
+ system: descriptor.system,
719
+ port: descriptor.defaultPort,
720
+ }).toEqual({ system: descriptor.system, port: 443 });
721
+ }
722
+ }
723
+ });
724
+ });
725
+
726
+ describe("semconv coverage", () => {
727
+ test.each(
728
+ SEMCONV_DB_SYSTEM_NAMES.filter((value: string): boolean => {
729
+ return !DELIBERATELY_UNKNOWN.includes(value);
730
+ }),
731
+ )(
732
+ "the stable db.system.name value %s is a catalog engine",
733
+ (value: string) => {
734
+ expect(isKnownDatabaseSystem(value)).toBe(true);
735
+ // A stable value is the engine's own `system`, never an alias of another.
736
+ expect(normalizeDatabaseSystem(value)).toBe(value);
737
+ },
738
+ );
739
+
740
+ test.each(
741
+ SEMCONV_DEPRECATED_DB_SYSTEMS.filter((value: string): boolean => {
742
+ return !DELIBERATELY_UNKNOWN.includes(value);
743
+ }),
744
+ )(
745
+ "the deprecated db.system value %s lands on a catalog engine",
746
+ (value: string) => {
747
+ expect(isKnownDatabaseSystem(value)).toBe(true);
748
+ },
749
+ );
750
+
751
+ test.each([...DELIBERATELY_UNKNOWN])(
752
+ "%s deliberately stays unknown and is never created from traces",
753
+ (value: string) => {
754
+ expect(isKnownDatabaseSystem(value)).toBe(false);
755
+ expect(normalizeDatabaseSystem(value)).toBe(value);
756
+ expect(isAutoCreatableDatabaseSystem(value)).toBe(false);
757
+ },
758
+ );
759
+
760
+ test("the deprecated values rename to their stable successors", () => {
761
+ const renames: Record<string, string> = {
762
+ adabas: "softwareag.adabas",
763
+ cache: "intersystems.cache",
764
+ intersystems_cache: "intersystems.cache",
765
+ cosmosdb: "azure.cosmosdb",
766
+ db2: "ibm.db2",
767
+ dynamodb: "aws.dynamodb",
768
+ firebird: "firebirdsql",
769
+ h2: "h2database",
770
+ hanadb: "sap.hana",
771
+ informix: "ibm.informix",
772
+ ingres: "actian.ingres",
773
+ maxdb: "sap.maxdb",
774
+ mssql: "microsoft.sql_server",
775
+ netezza: "ibm.netezza",
776
+ oracle: "oracle.db",
777
+ redshift: "aws.redshift",
778
+ spanner: "gcp.spanner",
779
+ // Predecessors and distributions.
780
+ cloudscape: "derby",
781
+ edb: "postgresql",
782
+ // No stable successor: the legacy value is the engine.
783
+ vertica: "vertica",
784
+ sybase: "sybase",
785
+ progress: "progress",
786
+ pervasive: "pervasive",
787
+ filemaker: "filemaker",
788
+ interbase: "interbase",
789
+ };
790
+ for (const [legacy, stable] of Object.entries(renames)) {
791
+ expect({ legacy, system: normalizeDatabaseSystem(legacy) }).toEqual({
792
+ legacy,
793
+ system: stable,
794
+ });
795
+ }
796
+ });
797
+ });
798
+
799
+ describe("normalizeDatabaseSystem", () => {
800
+ test.each([
801
+ ["postgresql", "postgresql"],
802
+ ["postgres", "postgresql"],
803
+ ["pg", "postgresql"],
804
+ ["pgsql", "postgresql"],
805
+ ["edb", "postgresql"],
806
+ ["percona", "mysql"],
807
+ ["mssql", "microsoft.sql_server"],
808
+ ["sqlserver", "microsoft.sql_server"],
809
+ ["sql_server", "microsoft.sql_server"],
810
+ ["microsoft.sql_server", "microsoft.sql_server"],
811
+ ["oracle", "oracle.db"],
812
+ ["oracledb", "oracle.db"],
813
+ ["mongo", "mongodb"],
814
+ ["elastic", "elasticsearch"],
815
+ ["cockroach", "cockroachdb"],
816
+ ["saphana", "sap.hana"],
817
+ ["yugabyte", "yugabytedb"],
818
+ ["memsql", "singlestore"],
819
+ ["documentdb", "aws.documentdb"],
820
+ ["neptune", "aws.neptune"],
821
+ ["gcp.bigquery", "bigquery"],
822
+ ["firestore", "gcp.firestore"],
823
+ ["bigtable", "gcp.bigtable"],
824
+ ["chromadb", "chroma"],
825
+ ["sqlite3", "sqlite"],
826
+ ["sap.ase", "sybase"],
827
+ // The semconv legacy → stable renames.
828
+ ["db2", "ibm.db2"],
829
+ ["hanadb", "sap.hana"],
830
+ ["h2", "h2database"],
831
+ ["firebird", "firebirdsql"],
832
+ ["redshift", "aws.redshift"],
833
+ ["cosmosdb", "azure.cosmosdb"],
834
+ ["dynamodb", "aws.dynamodb"],
835
+ ["spanner", "gcp.spanner"],
836
+ ])("%s → %s", (raw: string, system: string) => {
837
+ expect(normalizeDatabaseSystem(raw)).toBe(system);
838
+ });
839
+
840
+ /*
841
+ * Regression: forks used to be folded into the engine they fork, so a
842
+ * MariaDB 11.4 read "MySQL 11.4", Dragonfly 1.21 read "Redis 1.21.0" and
843
+ * a `^MariaDB` owner rule never matched.
844
+ */
845
+ test.each([
846
+ ["mariadb", "mariadb", "MariaDB", "mysql"],
847
+ ["valkey", "valkey", "Valkey", "redis"],
848
+ ["keydb", "keydb", "KeyDB", "redis"],
849
+ ["dragonfly", "dragonfly", "Dragonfly", "redis"],
850
+ ["dragonflydb", "dragonfly", "Dragonfly", "redis"],
851
+ ["scylladb", "scylladb", "ScyllaDB", "cassandra"],
852
+ ["scylla", "scylladb", "ScyllaDB", "cassandra"],
853
+ ["tidb", "tidb", "TiDB", "mysql"],
854
+ ["opensearch", "opensearch", "OpenSearch", "elasticsearch"],
855
+ ])(
856
+ "the fork %s is its own engine %s (%s), in the %s family",
857
+ (raw: string, system: string, display: string, family: string) => {
858
+ expect(normalizeDatabaseSystem(raw)).toBe(system);
859
+ expect(getDatabaseSystemDisplayName(raw)).toBe(display);
860
+ expect(getDatabaseSystemFamily(raw)).toBe(family);
861
+ },
862
+ );
863
+
864
+ test("casing and whitespace do not matter", () => {
865
+ expect(normalizeDatabaseSystem(" PostgreSQL ")).toBe("postgresql");
866
+ expect(normalizeDatabaseSystem("MSSQL")).toBe("microsoft.sql_server");
867
+ expect(normalizeDatabaseSystem(" MariaDB ")).toBe("mariadb");
868
+ });
869
+
870
+ test("an unknown non-empty value is returned canonicalized", () => {
871
+ expect(normalizeDatabaseSystem(" AcmeDB ")).toBe("acmedb");
872
+ expect(normalizeDatabaseSystem("other_sql")).toBe("other_sql");
873
+ });
874
+
875
+ test("empty and non-string values are null", () => {
876
+ expect(normalizeDatabaseSystem("")).toBeNull();
877
+ expect(normalizeDatabaseSystem(" ")).toBeNull();
878
+ expect(normalizeDatabaseSystem(null)).toBeNull();
879
+ expect(normalizeDatabaseSystem(undefined)).toBeNull();
880
+ expect(normalizeDatabaseSystem(5432)).toBeNull();
881
+ expect(normalizeDatabaseSystem({ system: "postgresql" })).toBeNull();
882
+ });
883
+
884
+ test("Object.prototype member names are not engines", () => {
885
+ expect(normalizeDatabaseSystem("constructor")).toBe("constructor");
886
+ expect(isKnownDatabaseSystem("constructor")).toBe(false);
887
+ expect(getDatabaseSystemDescriptor("__proto__")).toBeNull();
888
+ expect(getDatabaseSystemFamily("hasOwnProperty")).toBe("hasownproperty");
889
+ });
890
+ });
891
+
892
+ describe("engine families", () => {
893
+ test.each([
894
+ ["mariadb", "mysql"],
895
+ ["tidb", "mysql"],
896
+ ["vitess", "mysql"],
897
+ ["singlestore", "mysql"],
898
+ ["oceanbase", "mysql"],
899
+ ["starrocks", "mysql"],
900
+ ["doris", "mysql"],
901
+ ["cockroachdb", "postgresql"],
902
+ ["yugabytedb", "postgresql"],
903
+ ["aws.redshift", "postgresql"],
904
+ ["greenplum", "postgresql"],
905
+ ["questdb", "postgresql"],
906
+ ["valkey", "redis"],
907
+ ["keydb", "redis"],
908
+ ["dragonfly", "redis"],
909
+ ["scylladb", "cassandra"],
910
+ ["opensearch", "elasticsearch"],
911
+ ["ferretdb", "mongodb"],
912
+ ["aws.documentdb", "mongodb"],
913
+ ["interbase", "firebirdsql"],
914
+ ])("%s belongs to the %s family", (fork: string, family: string) => {
915
+ expect(getDatabaseSystemFamily(fork)).toBe(family);
916
+ expect(isSameDatabaseFamily(fork, family)).toBe(true);
917
+ expect(isSameDatabaseFamily(family, fork)).toBe(true);
918
+ });
919
+
920
+ test("an engine that is its own family, an alias and an unknown value", () => {
921
+ expect(getDatabaseSystemFamily("postgresql")).toBe("postgresql");
922
+ expect(getDatabaseSystemFamily("pg")).toBe("postgresql");
923
+ expect(getDatabaseSystemFamily("dragonflydb")).toBe("redis");
924
+ expect(getDatabaseSystemFamily(" AcmeDB ")).toBe("acmedb");
925
+ expect(getDatabaseSystemFamily("")).toBeNull();
926
+ expect(getDatabaseSystemFamily(null)).toBeNull();
927
+ expect(getDatabaseSystemFamily(42)).toBeNull();
928
+ });
929
+
930
+ test("two forks of one family are one family; different families are not", () => {
931
+ expect(isSameDatabaseFamily("valkey", "dragonfly")).toBe(true);
932
+ expect(isSameDatabaseFamily("mariadb", "tidb")).toBe(true);
933
+ expect(isSameDatabaseFamily("mysql", "postgresql")).toBe(false);
934
+ expect(isSameDatabaseFamily("mariadb", "cockroachdb")).toBe(false);
935
+ expect(isSameDatabaseFamily("redis", "memcached")).toBe(false);
936
+ expect(isSameDatabaseFamily("acmedb", " AcmeDB ")).toBe(true);
937
+ expect(isSameDatabaseFamily("", "")).toBe(false);
938
+ expect(isSameDatabaseFamily(null, "redis")).toBe(false);
939
+ });
940
+ });
941
+
942
+ describe("getDatabaseSystemMetricsEngine", () => {
943
+ test.each([
944
+ // Forks their family's receiver monitors chart the family's metrics.
945
+ ["mariadb", "mysql"],
946
+ ["valkey", "redis"],
947
+ ["keydb", "redis"],
948
+ ["dragonflydb", "redis"],
949
+ // Verified against OpenSearch 2.17 with the pinned collector.
950
+ ["opensearch", "elasticsearch"],
951
+ // Forks the family's receiver does NOT monitor keep their own.
952
+ ["tidb", "tidb"],
953
+ ["cockroachdb", "cockroachdb"],
954
+ ["scylladb", "scylladb"],
955
+ ["ferretdb", "ferretdb"],
956
+ // Engines that are their own family, aliases and unknown values.
957
+ ["mysql", "mysql"],
958
+ ["postgres", "postgresql"],
959
+ ["MSSQL", "microsoft.sql_server"],
960
+ [" AcmeDB ", "acmedb"],
961
+ ])("%s → %s", (system: string, expected: string) => {
962
+ expect(getDatabaseSystemMetricsEngine(system)).toBe(expected);
963
+ });
964
+
965
+ test("agrees with the receivers each engine lists", () => {
966
+ for (const descriptor of DATABASE_SYSTEMS) {
967
+ const engine: string = getDatabaseSystemMetricsEngine(
968
+ descriptor.system,
969
+ ) as string;
970
+ if (descriptor.receiverTypes.length > 0) {
971
+ expect(descriptorOf(engine).receiverTypes).toEqual(
972
+ expect.arrayContaining([...descriptor.receiverTypes]),
973
+ );
974
+ } else {
975
+ expect(engine).toBe(descriptor.system);
976
+ }
977
+ }
978
+ });
979
+
980
+ test("empty and non-string input is null", () => {
981
+ expect(getDatabaseSystemMetricsEngine("")).toBeNull();
982
+ expect(getDatabaseSystemMetricsEngine(null)).toBeNull();
983
+ expect(getDatabaseSystemMetricsEngine(3306)).toBeNull();
984
+ });
985
+ });
986
+
987
+ describe("getMoreSpecificDatabaseSystem", () => {
988
+ test.each([
989
+ // A fork refines its family.
990
+ ["mysql", "mariadb", "mariadb"],
991
+ ["redis", "valkey", "valkey"],
992
+ ["postgresql", "cockroachdb", "cockroachdb"],
993
+ ["cassandra", "scylla", "scylladb"],
994
+ ["postgres", "yugabyte", "yugabytedb"],
995
+ // The family never undoes a fork (the client cannot tell them apart).
996
+ ["mariadb", "mysql", "mariadb"],
997
+ ["valkey", "redis", "valkey"],
998
+ ["cockroachdb", "postgresql", "cockroachdb"],
999
+ // A different fork of the same family is not "more specific".
1000
+ ["valkey", "dragonfly", "valkey"],
1001
+ ["tidb", "mariadb", "tidb"],
1002
+ // Unrelated or unknown sightings keep the current engine.
1003
+ ["postgresql", "mysql", "postgresql"],
1004
+ ["mysql", "acmedb", "mysql"],
1005
+ ["acmedb", "mariadb", "acmedb"],
1006
+ // Same engine, aliases and casing.
1007
+ ["mysql", "MySQL", "mysql"],
1008
+ ["mssql", "sqlserver", "microsoft.sql_server"],
1009
+ ])(
1010
+ "current %s, seen as %s → %s",
1011
+ (current: string, observed: string, expected: string) => {
1012
+ expect(getMoreSpecificDatabaseSystem(current, observed)).toBe(expected);
1013
+ },
1014
+ );
1015
+
1016
+ test("an empty side yields the other, both empty is null", () => {
1017
+ expect(getMoreSpecificDatabaseSystem("", "mariadb")).toBe("mariadb");
1018
+ expect(getMoreSpecificDatabaseSystem(null, "Postgres")).toBe("postgresql");
1019
+ expect(getMoreSpecificDatabaseSystem("mysql", "")).toBe("mysql");
1020
+ expect(getMoreSpecificDatabaseSystem("mysql", undefined)).toBe("mysql");
1021
+ expect(getMoreSpecificDatabaseSystem(null, null)).toBeNull();
1022
+ });
1023
+ });
1024
+
1025
+ describe("refineDatabaseSystemFromVersion", () => {
1026
+ test.each([
1027
+ ["mysql", "10.11.7-MariaDB-1:10.11.7+maria~ubu2204", "mariadb"],
1028
+ ["mysql", "11.4.2-MariaDB", "mariadb"],
1029
+ ["mysql", "8.0.11-TiDB-v7.5.1", "tidb"],
1030
+ ["mysql", "8.0.30-Vitess", "vitess"],
1031
+ ["mysql", "5.7.25-OceanBase_CE-v4.2.1.2", "oceanbase"],
1032
+ // Percona Server and plain MySQL stay MySQL.
1033
+ ["mysql", "8.0.36-28", "mysql"],
1034
+ ["mysql", "8.4.0", "mysql"],
1035
+ ["percona", "8.0.36-28", "mysql"],
1036
+ // No fork of these families declares a version pattern.
1037
+ ["redis", "7.2.4", "redis"],
1038
+ ["postgresql", "16.2", "postgresql"],
1039
+ // A fork already names itself.
1040
+ ["mariadb", "8.0.11-TiDB-v7.5.1", "mariadb"],
1041
+ // A version that names a fork of ANOTHER family is ignored.
1042
+ ["postgresql", "10.11.7-MariaDB", "postgresql"],
1043
+ ])(
1044
+ "%s reporting %s is %s",
1045
+ (system: string, version: string, expected: string) => {
1046
+ expect(refineDatabaseSystemFromVersion(system, version)).toBe(expected);
1047
+ },
1048
+ );
1049
+
1050
+ /*
1051
+ * Regression (e2e, collector-contrib 0.161.0): an agent installed with
1052
+ * DATABASE_SYSTEM=mysql against MariaDB 11.4 — whose SELECT VERSION() is
1053
+ * "11.4.13-MariaDB-ubu2404" — reported db.system.version "11.4.13", the
1054
+ * bare number the mysql receiver keeps, and the database stayed "MySQL"
1055
+ * for good. MySQL has never released a 10.x or 11.x, so the major alone
1056
+ * names MariaDB.
1057
+ */
1058
+ test.each([
1059
+ ["mysql", "11.4.13", "mariadb"],
1060
+ ["mysql", "10.11.7", "mariadb"],
1061
+ ["mysql", "10.5.9", "mariadb"],
1062
+ ["mysql", "12.0.2", "mariadb"],
1063
+ ["mysql", " 11.8.2 ", "mariadb"],
1064
+ ["percona", "11.4.13", "mariadb"],
1065
+ // MySQL's own releases, 5.x to the 9.x innovation line, stay MySQL.
1066
+ ["mysql", "8.4.11", "mysql"],
1067
+ ["mysql", "9.4.0", "mysql"],
1068
+ ["mysql", "5.7.44-log", "mysql"],
1069
+ ["mysql", "8.0.mysql_aurora.3.05.2", "mysql"],
1070
+ // A MariaDB older than 10 whose suffix was stripped cannot be told apart.
1071
+ ["mysql", "5.5.68", "mysql"],
1072
+ // A fork's name beats the major: TiDB answers with MySQL's version.
1073
+ ["mysql", "8.0.11-TiDB-v7.5.1", "tidb"],
1074
+ // Only the mysql family has such a fork; other families keep theirs.
1075
+ ["postgresql", "16.2", "postgresql"],
1076
+ ["redis", "11.0.0", "redis"],
1077
+ ["mongodb", "10.0.1", "mongodb"],
1078
+ // A fork already names itself.
1079
+ ["tidb", "11.4.13", "tidb"],
1080
+ // Not a version's leading number: a date, a word.
1081
+ ["mysql", "20240101", "mysql"],
1082
+ ["mysql", "latest", "mysql"],
1083
+ ])(
1084
+ "the bare version: %s reporting %s is %s",
1085
+ (system: string, version: string, expected: string) => {
1086
+ expect(refineDatabaseSystemFromVersion(system, version)).toBe(expected);
1087
+ },
1088
+ );
1089
+
1090
+ test("no version, or a non-string one, keeps the engine; no engine is null", () => {
1091
+ expect(refineDatabaseSystemFromVersion("mysql", null)).toBe("mysql");
1092
+ expect(refineDatabaseSystemFromVersion("mysql", "")).toBe("mysql");
1093
+ expect(refineDatabaseSystemFromVersion("mysql", " ")).toBe("mysql");
1094
+ expect(refineDatabaseSystemFromVersion("mysql", 10)).toBe("mysql");
1095
+ expect(refineDatabaseSystemFromVersion("", "10.11.7-MariaDB")).toBeNull();
1096
+ expect(refineDatabaseSystemFromVersion(null, "10.11.7-MariaDB")).toBeNull();
1097
+ expect(refineDatabaseSystemFromVersion("AcmeDB", "1.0-MariaDB")).toBe(
1098
+ "acmedb",
1099
+ );
1100
+ });
1101
+
1102
+ test("reads the major of a pathological version string in linear time", () => {
1103
+ const hostile: string = " ".repeat(100_000) + "x";
1104
+ const started: number = performance.now();
1105
+ expect(refineDatabaseSystemFromVersion("mysql", hostile)).toBe("mysql");
1106
+ expect(performance.now() - started).toBeLessThan(1000);
1107
+ });
1108
+
1109
+ test("only reads the head of a pathological version string", () => {
1110
+ const hostile: string = "9".repeat(100_000) + "-MariaDB";
1111
+ const started: number = performance.now();
1112
+ expect(refineDatabaseSystemFromVersion("mysql", hostile)).toBe("mysql");
1113
+ expect(performance.now() - started).toBeLessThan(1000);
1114
+ });
1115
+ });
1116
+
1117
+ describe("descriptor lookups", () => {
1118
+ test("isKnownDatabaseSystem accepts systems and aliases only", () => {
1119
+ expect(isKnownDatabaseSystem("postgresql")).toBe(true);
1120
+ expect(isKnownDatabaseSystem("postgres")).toBe(true);
1121
+ expect(isKnownDatabaseSystem("tidb")).toBe(true);
1122
+ expect(isKnownDatabaseSystem("snowflake")).toBe(true);
1123
+ expect(isKnownDatabaseSystem("acmedb")).toBe(false);
1124
+ expect(isKnownDatabaseSystem("")).toBe(false);
1125
+ expect(isKnownDatabaseSystem(null)).toBe(false);
1126
+ });
1127
+
1128
+ test("getDatabaseSystemDescriptor resolves an alias to its engine", () => {
1129
+ expect(getDatabaseSystemDescriptor("pg")?.system).toBe("postgresql");
1130
+ expect(getDatabaseSystemDescriptor("scylla")?.system).toBe("scylladb");
1131
+ expect(getDatabaseSystemDescriptor("nope")).toBeNull();
1132
+ });
1133
+
1134
+ test.each([
1135
+ ["postgresql", 5432],
1136
+ ["mysql", 3306],
1137
+ ["mariadb", 3306],
1138
+ ["microsoft.sql_server", 1433],
1139
+ ["oracle.db", 1521],
1140
+ ["redis", 6379],
1141
+ ["valkey", 6379],
1142
+ ["mongodb", 27017],
1143
+ ["elasticsearch", 9200],
1144
+ ["opensearch", 9200],
1145
+ ["memcached", 11211],
1146
+ ["couchdb", 5984],
1147
+ ["cassandra", 9042],
1148
+ ["scylladb", 9042],
1149
+ ["clickhouse", 9000],
1150
+ ["cockroachdb", 26257],
1151
+ ["yugabytedb", 5433],
1152
+ ["tidb", 4000],
1153
+ ["neo4j", 7687],
1154
+ ["influxdb", 8086],
1155
+ ["couchbase", 11210],
1156
+ ["ibm.db2", 50000],
1157
+ ["sap.hana", 30015],
1158
+ ["firebirdsql", 3050],
1159
+ ["aws.redshift", 5439],
1160
+ ["trino", 8080],
1161
+ ["hive", 10000],
1162
+ ["teradata", 1025],
1163
+ ["vertica", 5433],
1164
+ ["snowflake", 443],
1165
+ ["etcd", 2379],
1166
+ ["aerospike", 3000],
1167
+ ["riak", 8087],
1168
+ ["arangodb", 8529],
1169
+ ["milvus", 19530],
1170
+ ["qdrant", 6333],
1171
+ ["solr", 8983],
1172
+ ["intersystems.cache", 1972],
1173
+ ["aws.dynamodb", 443],
1174
+ ["azure.cosmosdb", 443],
1175
+ ["gcp.spanner", 443],
1176
+ ["h2database", 9092],
1177
+ ["derby", 1527],
1178
+ ])("default port of %s is %d", (system: string, port: number) => {
1179
+ expect(getDefaultDatabasePort(system)).toBe(port);
1180
+ });
1181
+
1182
+ test("engines without a network port, and unknown engines, have none", () => {
1183
+ for (const system of [
1184
+ "sqlite",
1185
+ "duckdb",
1186
+ "instantdb",
1187
+ "hbase",
1188
+ "actian.ingres",
1189
+ "acmedb",
1190
+ "",
1191
+ ]) {
1192
+ expect(getDefaultDatabasePort(system)).toBeNull();
1193
+ }
1194
+ });
1195
+
1196
+ test("display names: engine, alias, unknown raw, empty", () => {
1197
+ expect(getDatabaseSystemDisplayName("postgresql")).toBe("PostgreSQL");
1198
+ expect(getDatabaseSystemDisplayName("postgres")).toBe("PostgreSQL");
1199
+ expect(getDatabaseSystemDisplayName("microsoft.sql_server")).toBe(
1200
+ "SQL Server",
1201
+ );
1202
+ expect(getDatabaseSystemDisplayName("snowflake")).toBe("Snowflake");
1203
+ expect(getDatabaseSystemDisplayName(" AcmeDB ")).toBe("AcmeDB");
1204
+ expect(getDatabaseSystemDisplayName("")).toBe("Database");
1205
+ expect(getDatabaseSystemDisplayName(" ")).toBe("Database");
1206
+ expect(getDatabaseSystemDisplayName(null)).toBe("Database");
1207
+ });
1208
+ });
1209
+
1210
+ describe("isAutoCreatableDatabaseSystem", () => {
1211
+ test("server engines may auto-create, managed ones with a per-cluster or per-account endpoint included", () => {
1212
+ for (const system of [
1213
+ "postgresql",
1214
+ "mysql",
1215
+ "mariadb",
1216
+ "redis",
1217
+ "valkey",
1218
+ "mongodb",
1219
+ "microsoft.sql_server",
1220
+ "oracle.db",
1221
+ "cockroachdb",
1222
+ "tidb",
1223
+ "clickhouse",
1224
+ "cassandra",
1225
+ "scylladb",
1226
+ "hive",
1227
+ "teradata",
1228
+ "vertica",
1229
+ "qdrant",
1230
+ "postgres",
1231
+ // `orders.abc.us-east-1.redshift.amazonaws.com` is one warehouse.
1232
+ "aws.redshift",
1233
+ "aws.documentdb",
1234
+ "aws.neptune",
1235
+ // `acme.snowflakecomputing.com` is one account.
1236
+ "snowflake",
1237
+ "databricks",
1238
+ ]) {
1239
+ expect({ system, auto: isAutoCreatableDatabaseSystem(system) }).toEqual({
1240
+ system,
1241
+ auto: true,
1242
+ });
1243
+ }
1244
+ });
1245
+
1246
+ test("cloud-API, in-process and unknown engines never auto-create", () => {
1247
+ for (const system of [
1248
+ "aws.dynamodb",
1249
+ "dynamodb",
1250
+ "azure.cosmosdb",
1251
+ "gcp.spanner",
1252
+ "bigquery",
1253
+ "gcp.firestore",
1254
+ "gcp.bigtable",
1255
+ "pinecone",
1256
+ "sqlite",
1257
+ "h2database",
1258
+ "h2",
1259
+ "hsqldb",
1260
+ "derby",
1261
+ "duckdb",
1262
+ "instantdb",
1263
+ "other_sql",
1264
+ "acmedb",
1265
+ "",
1266
+ ]) {
1267
+ expect({ system, auto: isAutoCreatableDatabaseSystem(system) }).toEqual({
1268
+ system,
1269
+ auto: false,
1270
+ });
1271
+ }
1272
+ });
1273
+ });
1274
+
1275
+ describe("getDatabaseSystemFromReceiverScopeName", () => {
1276
+ test.each([
1277
+ ["postgresqlreceiver", "postgresql"],
1278
+ ["mysqlreceiver", "mysql"],
1279
+ ["sqlserverreceiver", "microsoft.sql_server"],
1280
+ ["oracledbreceiver", "oracle.db"],
1281
+ ["redisreceiver", "redis"],
1282
+ ["mongodbreceiver", "mongodb"],
1283
+ ["mongodbatlasreceiver", "mongodb"],
1284
+ ["elasticsearchreceiver", "elasticsearch"],
1285
+ ["memcachedreceiver", "memcached"],
1286
+ ["couchdbreceiver", "couchdb"],
1287
+ // Regression: these ship in the pinned collector and were not recognised.
1288
+ ["saphanareceiver", "sap.hana"],
1289
+ ["snowflakereceiver", "snowflake"],
1290
+ ["riakreceiver", "riak"],
1291
+ ["aerospikereceiver", "aerospike"],
1292
+ ["googlecloudspannerreceiver", "gcp.spanner"],
1293
+ ])("current Go-module form of %s → %s", (segment: string, system: string) => {
1294
+ expect(
1295
+ getDatabaseSystemFromReceiverScopeName(`${CONTRIB_PREFIX}${segment}`),
1296
+ ).toBe(system);
1297
+ });
1298
+
1299
+ test("a receiver that also monitors forks reports its family, never a fork", () => {
1300
+ // MariaDB, Valkey, KeyDB and Dragonfly list these receivers too.
1301
+ expect(
1302
+ getDatabaseSystemFromReceiverScopeName(`${CONTRIB_PREFIX}mysqlreceiver`),
1303
+ ).toBe("mysql");
1304
+ expect(
1305
+ getDatabaseSystemFromReceiverScopeName(`${CONTRIB_PREFIX}redisreceiver`),
1306
+ ).toBe("redis");
1307
+ });
1308
+
1309
+ test("every receiver the catalog lists is recognised, as its family's engine", () => {
1310
+ for (const descriptor of DATABASE_SYSTEMS) {
1311
+ for (const receiverType of descriptor.receiverTypes) {
1312
+ expect({
1313
+ receiverType,
1314
+ system: getDatabaseSystemFromReceiverScopeName(
1315
+ `${CONTRIB_PREFIX}${receiverType}receiver`,
1316
+ ),
1317
+ }).toEqual({
1318
+ receiverType,
1319
+ system: descriptor.family || descriptor.system,
1320
+ });
1321
+ }
1322
+ }
1323
+ });
1324
+
1325
+ test("the legacy otelcol/<type>receiver form is recognised too", () => {
1326
+ expect(
1327
+ getDatabaseSystemFromReceiverScopeName("otelcol/postgresqlreceiver"),
1328
+ ).toBe("postgresql");
1329
+ expect(
1330
+ getDatabaseSystemFromReceiverScopeName("otelcol/redisreceiver"),
1331
+ ).toBe("redis");
1332
+ });
1333
+
1334
+ test("casing, padding and a trailing slash are tolerated", () => {
1335
+ expect(
1336
+ getDatabaseSystemFromReceiverScopeName(
1337
+ ` ${CONTRIB_PREFIX.toUpperCase()}PostgreSQLReceiver/ `,
1338
+ ),
1339
+ ).toBe("postgresql");
1340
+ });
1341
+
1342
+ test("non-DB receivers, the generic sql_query receiver and SDK scopes are null", () => {
1343
+ for (const scope of [
1344
+ `${CONTRIB_PREFIX}hostmetricsreceiver`,
1345
+ `${CONTRIB_PREFIX}kafkareceiver`,
1346
+ `${CONTRIB_PREFIX}zookeeperreceiver`,
1347
+ // It runs whatever SQL it is given against whatever driver: no engine.
1348
+ `${CONTRIB_PREFIX}sqlqueryreceiver`,
1349
+ `${CONTRIB_PREFIX}prometheusreceiver`,
1350
+ "otelcol/receiver",
1351
+ "receiver",
1352
+ "@opentelemetry/instrumentation-pg",
1353
+ "io.opentelemetry.jdbc",
1354
+ "postgresql",
1355
+ "",
1356
+ ]) {
1357
+ expect(getDatabaseSystemFromReceiverScopeName(scope)).toBeNull();
1358
+ }
1359
+ expect(getDatabaseSystemFromReceiverScopeName(null)).toBeNull();
1360
+ expect(getDatabaseSystemFromReceiverScopeName(undefined)).toBeNull();
1361
+ });
1362
+
1363
+ test("only the LAST path segment counts", () => {
1364
+ expect(
1365
+ getDatabaseSystemFromReceiverScopeName(
1366
+ `${CONTRIB_PREFIX}postgresqlreceiver/internal/metadata`,
1367
+ ),
1368
+ ).toBeNull();
1369
+ });
1370
+ });
1371
+
1372
+ describe("getDatabaseEngineMetricsSource", () => {
1373
+ test.each([
1374
+ ["postgres", "receiver"],
1375
+ ["mariadb", "receiver"],
1376
+ ["sap.hana", "receiver"],
1377
+ ["spanner", "receiver"],
1378
+ ["clickhouse", "prometheus"],
1379
+ ["cockroachdb", "prometheus"],
1380
+ ["scylla", "prometheus"],
1381
+ ["dynamodb", "cloud-monitoring"],
1382
+ ["bigquery", "cloud-monitoring"],
1383
+ ["db2", "none"],
1384
+ ["cassandra", "none"],
1385
+ ["sqlite", "embedded"],
1386
+ ["h2", "embedded"],
1387
+ ])("%s → %s", (system: string, kind: string) => {
1388
+ expect(getDatabaseEngineMetricsSource(system).kind).toBe(kind);
1389
+ });
1390
+
1391
+ test("an unknown engine has no known path — never 'embedded', which would claim it has no metrics at all", () => {
1392
+ for (const system of ["acmedb", "", null, undefined, 42]) {
1393
+ const source: ReturnType<typeof getDatabaseEngineMetricsSource> =
1394
+ getDatabaseEngineMetricsSource(system);
1395
+ expect(source.kind).toBe("none");
1396
+ }
1397
+ });
1398
+
1399
+ test("a Prometheus recipe carries the port and path to scrape", () => {
1400
+ expect(getDatabaseEngineMetricsSource("clickhouse")).toEqual({
1401
+ kind: "prometheus",
1402
+ port: 9363,
1403
+ path: "/metrics",
1404
+ note: "Enable the `<prometheus>` section of the server config.",
1405
+ });
1406
+ });
1407
+ });
1408
+
1409
+ describe("getCollectorReceiverComponentName", () => {
1410
+ test("renamed receivers are configured under their new names", () => {
1411
+ expect(getCollectorReceiverComponentName("googlecloudspanner")).toBe(
1412
+ "google_cloud_spanner",
1413
+ );
1414
+ expect(getCollectorReceiverComponentName("mongodbatlas")).toBe(
1415
+ "mongodb_atlas",
1416
+ );
1417
+ });
1418
+
1419
+ test("the rest are configured under their type", () => {
1420
+ for (const type of ["postgresql", "sqlserver", "saphana", "snowflake"]) {
1421
+ expect(getCollectorReceiverComponentName(type)).toBe(type);
1422
+ }
1423
+ });
1424
+ });
1425
+
1426
+ describe("getDatabaseReceiverSystemHint", () => {
1427
+ test("the first DB receiver among the block's scopes wins", () => {
1428
+ expect(
1429
+ getDatabaseReceiverSystemHint([
1430
+ null,
1431
+ undefined,
1432
+ "",
1433
+ `${CONTRIB_PREFIX}hostmetricsreceiver`,
1434
+ `${CONTRIB_PREFIX}redisreceiver`,
1435
+ `${CONTRIB_PREFIX}postgresqlreceiver`,
1436
+ ]),
1437
+ ).toBe("redis");
1438
+ expect(
1439
+ getDatabaseReceiverSystemHint([
1440
+ `${CONTRIB_PREFIX}saphanareceiver`,
1441
+ `${CONTRIB_PREFIX}redisreceiver`,
1442
+ ]),
1443
+ ).toBe("sap.hana");
1444
+ });
1445
+
1446
+ test("no DB receiver → null", () => {
1447
+ expect(getDatabaseReceiverSystemHint([])).toBeNull();
1448
+ expect(
1449
+ getDatabaseReceiverSystemHint([`${CONTRIB_PREFIX}filelogreceiver`]),
1450
+ ).toBeNull();
1451
+ });
1452
+
1453
+ test("a non-array input is null rather than a throw", () => {
1454
+ expect(
1455
+ getDatabaseReceiverSystemHint(
1456
+ "otelcol/redisreceiver" as unknown as Array<string>,
1457
+ ),
1458
+ ).toBeNull();
1459
+ });
1460
+ });
1461
+
1462
+ describe("trimTrailingCharacter", () => {
1463
+ test("drops every trailing copy of the character and nothing else", () => {
1464
+ expect(trimTrailingCharacter("db.prod.", ".")).toBe("db.prod");
1465
+ expect(trimTrailingCharacter("db.prod...", ".")).toBe("db.prod");
1466
+ expect(trimTrailingCharacter("db.prod", ".")).toBe("db.prod");
1467
+ expect(trimTrailingCharacter("...", ".")).toBe("");
1468
+ expect(trimTrailingCharacter("", ".")).toBe("");
1469
+ expect(trimTrailingCharacter("a/b//", "/")).toBe("a/b");
1470
+ expect(trimTrailingCharacter(".a.", ".")).toBe(".a");
1471
+ });
1472
+
1473
+ test("stays linear on long runs that do not end the string", () => {
1474
+ // The regex it replaced (/\.+$/) backtracks quadratically on this input.
1475
+ const hostile: string = "a" + ".".repeat(200_000) + "b";
1476
+ const started: number = performance.now();
1477
+ expect(trimTrailingCharacter(hostile, ".")).toBe(hostile);
1478
+ expect(
1479
+ getDatabaseSystemFromReceiverScopeName("x" + "/".repeat(200_000) + "y"),
1480
+ ).toBeNull();
1481
+ expect(performance.now() - started).toBeLessThan(1000);
1482
+ });
1483
+ });
1484
+
1485
+ /*
1486
+ * Regression (e2e): Valkey 8.1.10 showed "Version 7.2.4". Its INFO keeps
1487
+ * redis_version at 7.2.4 — the Redis release it forked from — next to
1488
+ * valkey_version:8.1.10, and the redis receiver reports only the former, as
1489
+ * redis.version.
1490
+ */
1491
+ describe("isCompatibilityVersionAttribute", () => {
1492
+ test.each([
1493
+ ["valkey", "redis.version", true],
1494
+ ["valkey", "resource.redis.version", true],
1495
+ ["Valkey", " redis.version ", true],
1496
+ ["dragonfly", "redis.version", true],
1497
+ ["dragonflydb", "redis.version", true],
1498
+ // Redis's is its own; so is KeyDB's (redis_version:6.3.4 is KeyDB 6.3.4).
1499
+ ["redis", "redis.version", false],
1500
+ ["keydb", "redis.version", false],
1501
+ // Another attribute, or an engine that declares none.
1502
+ ["valkey", "db.system.version", false],
1503
+ ["mariadb", "db.system.version", false],
1504
+ ["opensearch", "elasticsearch.node.version", false],
1505
+ ["acmedb", "redis.version", false],
1506
+ ["", "redis.version", false],
1507
+ [null, "redis.version", false],
1508
+ ])(
1509
+ "%s + %s is a compatibility version: %s",
1510
+ (system: string | null, key: string, expected: boolean) => {
1511
+ expect(isCompatibilityVersionAttribute(system, key)).toBe(expected);
1512
+ },
1513
+ );
1514
+ });