@oneuptime/common 13.0.3 → 13.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 (687) hide show
  1. package/Models/DatabaseModels/Index.ts +4 -0
  2. package/Models/DatabaseModels/RumApplication.ts +1 -1
  3. package/Models/DatabaseModels/SecurityEventConnection.ts +457 -0
  4. package/Models/DatabaseModels/SecurityEventConnectionRun.ts +263 -0
  5. package/Models/DatabaseModels/TelemetryIngestionKey.ts +2 -2
  6. package/Server/API/AIInvestigationAPI.ts +484 -24
  7. package/Server/API/GoogleSecOpsConnectionAPI.ts +249 -8
  8. package/Server/API/SecurityEventConnectionAPI.ts +250 -0
  9. package/Server/API/TelemetryAPI.ts +402 -265
  10. package/Server/Infrastructure/Postgres/SchemaMigrations/1792700000000-AddSecurityEventConnections.ts +99 -0
  11. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
  12. package/Server/Middleware/TelemetryIngest.ts +101 -6
  13. package/Server/Services/ExceptionAggregationService.ts +7 -16
  14. package/Server/Services/GoogleSecOpsConnectionService.ts +15 -0
  15. package/Server/Services/Index.ts +4 -0
  16. package/Server/Services/InventoryItemService.ts +28 -0
  17. package/Server/Services/LogAggregationService.ts +17 -23
  18. package/Server/Services/MetricAggregationService.ts +4 -14
  19. package/Server/Services/SecurityEventConnectionRunService.ts +10 -0
  20. package/Server/Services/SecurityEventConnectionService.ts +538 -0
  21. package/Server/Services/TraceAggregationService.ts +77 -28
  22. package/Server/Types/AnalyticsDatabase/ModelPermission.ts +9 -0
  23. package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +13 -1
  24. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +15 -1
  25. package/Server/Utils/AI/SRE/InvestigationEvidence.ts +658 -0
  26. package/Server/Utils/AI/SRE/InvestigationReferences.ts +324 -0
  27. package/Server/Utils/AI/Toolbox/Index.ts +38 -0
  28. package/Server/Utils/AI/Toolbox/TimelineTools.ts +9 -2
  29. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +80 -0
  30. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +5 -3
  31. package/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.ts +1108 -0
  32. package/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubConnector.ts +732 -0
  33. package/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.ts +495 -0
  34. package/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconClient.ts +689 -0
  35. package/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconConnector.ts +767 -0
  36. package/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityClient.ts +571 -0
  37. package/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityConnector.ts +827 -0
  38. package/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrClient.ts +610 -0
  39. package/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrConnector.ts +549 -0
  40. package/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelClient.ts +830 -0
  41. package/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelConnector.ts +684 -0
  42. package/Server/Utils/SecurityEvent/Connectors/Okta/OktaClient.ts +487 -0
  43. package/Server/Utils/SecurityEvent/Connectors/Okta/OktaConnector.ts +778 -0
  44. package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.ts +1002 -0
  45. package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.ts +556 -0
  46. package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.ts +275 -0
  47. package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry.ts +53 -0
  48. package/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkClient.ts +709 -0
  49. package/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkConnector.ts +596 -0
  50. package/Server/Utils/SecurityEvent/Connectors/Types.ts +191 -0
  51. package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.ts +353 -65
  52. package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsConnectionTester.ts +777 -0
  53. package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.ts +747 -148
  54. package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.ts +48 -2
  55. package/Server/Utils/SecurityEvent/SecurityEventDedupe.ts +81 -0
  56. package/Server/Utils/SessionReplay/SessionReplayReadService.ts +741 -40
  57. package/Server/Utils/StartServer.ts +10 -0
  58. package/Server/Utils/Telemetry/EntityRegistry.ts +8 -0
  59. package/Server/Utils/Telemetry/KubernetesResourceAttributes.ts +108 -0
  60. package/Server/Utils/Telemetry/ResourceEntityFilter.ts +174 -93
  61. package/Server/Utils/Telemetry/ResourceFacetPlanner.ts +251 -0
  62. package/Server/Utils/Telemetry/ResourceFacetResolver.ts +248 -413
  63. package/Server/Utils/Telemetry/ServiceDependencyDiscovery.ts +668 -0
  64. package/Server/Utils/Telemetry/TraceContextPropagation.ts +348 -0
  65. package/Server/Utils/Telemetry.ts +18 -0
  66. package/Tests/App/Dashboard/AIInvestigationHeaderStatus.test.tsx +413 -0
  67. package/Tests/App/Dashboard/AIRootCauseFeedItem.test.tsx +285 -0
  68. package/Tests/App/Dashboard/AffectedResourcesDisplay.test.tsx +242 -0
  69. package/Tests/App/Dashboard/AlertEpisodeViewFields.test.tsx +601 -15
  70. package/Tests/App/Dashboard/ChangeAlertStateAIHeader.test.tsx +835 -0
  71. package/Tests/App/Dashboard/CloudResourceTelemetryScope.test.ts +41 -0
  72. package/Tests/App/Dashboard/ConnectionTestModal.test.tsx +604 -0
  73. package/Tests/App/Dashboard/ConnectorTestReportView.test.tsx +738 -0
  74. package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +153 -6
  75. package/Tests/App/Dashboard/EntityDetailPanel.test.tsx +165 -0
  76. package/Tests/App/Dashboard/EpisodeChangeState.test.tsx +1069 -0
  77. package/Tests/App/Dashboard/EpisodeMembersCard.test.tsx +772 -0
  78. package/Tests/App/Dashboard/EventOverviewPages.test.tsx +2354 -0
  79. package/Tests/App/Dashboard/EventOverviewSkeleton.test.tsx +210 -0
  80. package/Tests/App/Dashboard/EventStatBar.test.tsx +392 -0
  81. package/Tests/App/Dashboard/EventStatusPanel.test.tsx +247 -0
  82. package/Tests/App/Dashboard/ExceptionAIAssistance.test.tsx +606 -0
  83. package/Tests/App/Dashboard/ExceptionBreadcrumbTimeline.test.tsx +273 -0
  84. package/Tests/App/Dashboard/ExceptionDetailSideMenu.test.tsx +176 -0
  85. package/Tests/App/Dashboard/ExceptionOverviewCards.test.tsx +366 -0
  86. package/Tests/App/Dashboard/ExceptionSignalPages.test.tsx +371 -0
  87. package/Tests/App/Dashboard/ExceptionStackFrameViewer.test.tsx +440 -0
  88. package/Tests/App/Dashboard/ExceptionSummary.test.tsx +381 -0
  89. package/Tests/App/Dashboard/ExceptionTriage.test.tsx +306 -0
  90. package/Tests/App/Dashboard/ExceptionsResourceFacets.test.tsx +604 -0
  91. package/Tests/App/Dashboard/ExceptionsViewerEntityChips.test.tsx +706 -0
  92. package/Tests/App/Dashboard/FeedOrdering.test.ts +32 -0
  93. package/Tests/App/Dashboard/GoogleSecOpsConnectionForm.test.tsx +838 -0
  94. package/Tests/App/Dashboard/GoogleSecOpsConnectionsErrors.test.tsx +18 -0
  95. package/Tests/App/Dashboard/GoogleSecOpsDiagnostics.test.tsx +297 -20
  96. package/Tests/App/Dashboard/IncidentEpisodeViewFields.test.tsx +618 -13
  97. package/Tests/App/Dashboard/InfrastructureExplorer.test.tsx +254 -207
  98. package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +303 -135
  99. package/Tests/App/Dashboard/InvestigationEvidenceList.test.tsx +1251 -0
  100. package/Tests/App/Dashboard/InvestigationFeedRefresh.test.tsx +303 -0
  101. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +876 -8
  102. package/Tests/App/Dashboard/InvestigationPanelStatus.test.tsx +35 -0
  103. package/Tests/App/Dashboard/InvestigationReferenceLink.test.tsx +177 -0
  104. package/Tests/App/Dashboard/InvestigationReportView.test.tsx +1295 -0
  105. package/Tests/App/Dashboard/KubernetesImageReferenceView.test.tsx +114 -0
  106. package/Tests/App/Dashboard/KubernetesLogsTabChips.test.tsx +285 -0
  107. package/Tests/App/Dashboard/LogsEntityChipNames.test.tsx +316 -0
  108. package/Tests/App/Dashboard/LogsResourceFacetChips.test.tsx +361 -0
  109. package/Tests/App/Dashboard/ProfileTableEntityNames.test.tsx +432 -0
  110. package/Tests/App/Dashboard/ProfileViewEntityName.test.tsx +250 -0
  111. package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +10 -0
  112. package/Tests/App/Dashboard/ResourceLogsTabsBareLayout.test.tsx +700 -0
  113. package/Tests/App/Dashboard/ResourcePageEntityNameProps.test.tsx +803 -0
  114. package/Tests/App/Dashboard/RumSessionReplaySideMenu.test.tsx +11 -1
  115. package/Tests/App/Dashboard/ScheduledMaintenanceChangeState.test.tsx +1026 -0
  116. package/Tests/App/Dashboard/ScheduledMaintenanceFeedRefresh.test.tsx +436 -0
  117. package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +1195 -0
  118. package/Tests/App/Dashboard/SecurityEventConnectionFormModal.test.tsx +1022 -0
  119. package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +905 -0
  120. package/Tests/App/Dashboard/SecurityEventsSideMenu.test.tsx +247 -0
  121. package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +375 -274
  122. package/Tests/App/Dashboard/SessionReplayAuditTable.test.tsx +410 -0
  123. package/Tests/App/Dashboard/TelemetryResourceRetentionSettings.test.tsx +774 -0
  124. package/Tests/App/Dashboard/TopErrorsPanelResourceNames.test.tsx +316 -0
  125. package/Tests/App/Dashboard/TopologyDataLoading.test.tsx +30 -0
  126. package/Tests/App/Dashboard/TopologyPageNavigation.test.tsx +88 -24
  127. package/Tests/App/Dashboard/TraceExplorer.test.tsx +1590 -0
  128. package/Tests/App/Dashboard/TraceWaterfall.test.tsx +488 -0
  129. package/Tests/App/Dashboard/TracesAnalyticsSeriesLabels.test.tsx +367 -0
  130. package/Tests/App/Dashboard/TracesEntityNames.test.tsx +585 -0
  131. package/Tests/App/Dashboard/TracesResourceFacets.test.tsx +613 -0
  132. package/Tests/App/Dashboard/UseServiceNames.test.tsx +359 -0
  133. package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +7 -0
  134. package/Tests/Models/InventoryItemNaming.test.ts +132 -16
  135. package/Tests/Models/SecurityDomainAccessControl.test.ts +61 -17
  136. package/Tests/Server/API/AIInvestigationAPI.test.ts +611 -2
  137. package/Tests/Server/API/AIInvestigationEvidenceAPI.test.ts +1098 -0
  138. package/Tests/Server/API/GoogleSecOpsConnectionAPI.test.ts +409 -0
  139. package/Tests/Server/API/SecurityEventConnectionAPI.test.ts +856 -0
  140. package/Tests/Server/API/SessionReplayAPI.test.ts +528 -1
  141. package/Tests/Server/API/TelemetryFacetsAPI.test.ts +810 -0
  142. package/Tests/Server/Infrastructure/E2EClickHouseFixtureAccess.test.ts +240 -0
  143. package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +229 -0
  144. package/Tests/Server/Services/InventoryItemDisplayName.test.ts +66 -0
  145. package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +28 -1
  146. package/Tests/Server/Services/SecurityEventConnectionService.test.ts +1233 -0
  147. package/Tests/Server/Services/TelemetryIngestionKeyValidation.test.ts +53 -0
  148. package/Tests/Server/Services/TelemetryResourceFacetCounting.test.ts +218 -0
  149. package/Tests/Server/Services/TelemetryResourceFacetFilters.test.ts +155 -1
  150. package/Tests/Server/Services/TraceAggregationExceptionScope.test.ts +142 -0
  151. package/Tests/Server/Services/TraceAnalyticsResourceDisplayNames.test.ts +85 -24
  152. package/Tests/Server/Types/Database/Permissions/SecurityRoleAccess.test.ts +33 -0
  153. package/Tests/Server/Utils/AI/InvestigationEvidence.test.ts +1395 -0
  154. package/Tests/Server/Utils/AI/InvestigationReferences.test.ts +616 -0
  155. package/Tests/Server/Utils/AI/TimelineTools.test.ts +119 -0
  156. package/Tests/Server/Utils/AI/Toolbox/AIToolbox.test.ts +151 -0
  157. package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +65 -0
  158. package/Tests/Server/Utils/AnalyticsDatabase/StatementGeneratorExceptionScope.test.ts +224 -0
  159. package/Tests/Server/Utils/LoggerCore.test.ts +597 -0
  160. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPerSeriesFanout.test.ts +55 -2
  161. package/Tests/Server/Utils/Monitor/MonitorTemplateUtil.test.ts +1109 -0
  162. package/Tests/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.test.ts +1240 -0
  163. package/Tests/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubConnector.test.ts +1853 -0
  164. package/Tests/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.test.ts +1129 -0
  165. package/Tests/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconClient.test.ts +1066 -0
  166. package/Tests/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconConnector.test.ts +1568 -0
  167. package/Tests/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityClient.test.ts +930 -0
  168. package/Tests/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityConnector.test.ts +1409 -0
  169. package/Tests/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrClient.test.ts +763 -0
  170. package/Tests/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrConnector.test.ts +1296 -0
  171. package/Tests/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelClient.test.ts +1102 -0
  172. package/Tests/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelConnector.test.ts +1174 -0
  173. package/Tests/Server/Utils/SecurityEvent/Connectors/Okta/OktaClient.test.ts +1032 -0
  174. package/Tests/Server/Utils/SecurityEvent/Connectors/Okta/OktaConnector.test.ts +1558 -0
  175. package/Tests/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.test.ts +3041 -0
  176. package/Tests/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.test.ts +1168 -0
  177. package/Tests/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.test.ts +906 -0
  178. package/Tests/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkClient.test.ts +1068 -0
  179. package/Tests/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkConnector.test.ts +1004 -0
  180. package/Tests/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsConnectionTester.test.ts +784 -0
  181. package/Tests/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.test.ts +113 -1
  182. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsClient.test.ts +5 -1
  183. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsDiagnostics.test.ts +93 -13
  184. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsHttpIntegration.test.ts +23 -1
  185. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPoller.test.ts +25 -3
  186. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerFailureTaxonomy.test.ts +22 -8
  187. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerHardening.test.ts +82 -16
  188. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsSearchDetections.test.ts +730 -0
  189. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsThreePassPoller.test.ts +1577 -0
  190. package/Tests/Server/Utils/SessionReplay/SessionReplayOriginAllowlist.test.ts +41 -0
  191. package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +1453 -18
  192. package/Tests/Server/Utils/Telemetry/EntityRegistry.test.ts +711 -0
  193. package/Tests/Server/Utils/Telemetry/KubernetesResourceAttributes.test.ts +162 -0
  194. package/Tests/Server/Utils/Telemetry/ResourceEntityFilter.test.ts +460 -13
  195. package/Tests/Server/Utils/Telemetry/ResourceFacetPlanner.test.ts +678 -0
  196. package/Tests/Server/Utils/Telemetry/ResourceFacetResolver.test.ts +868 -0
  197. package/Tests/Server/Utils/Telemetry/ServiceDependencyDiscovery.test.ts +525 -0
  198. package/Tests/Server/Utils/Telemetry/TraceContextPropagation.test.ts +420 -0
  199. package/Tests/Types/OnCallDutyPolicy/LayerUtilCorePaths.test.ts +1014 -0
  200. package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveRotation.test.ts +9 -6
  201. package/Tests/Types/Rules/RuleCriteriaFieldRegistry.test.ts +276 -0
  202. package/Tests/Types/Rum/SessionReplayApiContracts.test.ts +73 -0
  203. package/Tests/Types/Rum/SessionReplayTransportContracts.test.ts +95 -0
  204. package/Tests/Types/SecurityEvent/Connectors/ConnectorDiagnostics.test.ts +82 -0
  205. package/Tests/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.test.ts +314 -0
  206. package/Tests/Types/Telemetry/ExceptionSpanScope.test.ts +89 -0
  207. package/Tests/Types/Telemetry/LlmConventions.test.ts +495 -0
  208. package/Tests/Types/Telemetry/ResourceEntityFacet.test.ts +96 -0
  209. package/Tests/Types/Telemetry/ResourceFacetCatalog.test.ts +304 -0
  210. package/Tests/UI/Components/ActiveFilterChipsLockedFilters.test.tsx +357 -0
  211. package/Tests/UI/Components/Card.test.tsx +312 -1
  212. package/Tests/UI/Components/CardModelDetailHeaderLayout.test.tsx +253 -0
  213. package/Tests/UI/Components/CardModelDetailRefresher.test.tsx +342 -0
  214. package/Tests/UI/Components/Checkbox.test.tsx +79 -0
  215. package/Tests/UI/Components/CopyTextButton.test.tsx +142 -0
  216. package/Tests/UI/Components/DetailCompactStyle.test.tsx +621 -0
  217. package/Tests/UI/Components/ErrorBoundary.test.tsx +60 -0
  218. package/Tests/UI/Components/FacetSections.test.tsx +581 -0
  219. package/Tests/UI/Components/FacetSidebarControls.test.tsx +812 -0
  220. package/Tests/UI/Components/FacetVisibility.test.ts +429 -0
  221. package/Tests/UI/Components/LockedFilterActions.test.tsx +396 -0
  222. package/Tests/UI/Components/LockedFilterChip.test.tsx +651 -0
  223. package/Tests/UI/Components/LogsEntityNames.test.ts +1769 -0
  224. package/Tests/UI/Components/LogsEntityNamesComponents.test.tsx +696 -0
  225. package/Tests/UI/Components/LogsFacetSidebarHiddenFacets.test.tsx +600 -0
  226. package/Tests/UI/Components/LogsViewerEntityNames.test.tsx +713 -0
  227. package/Tests/UI/Components/MarkdownInlineReferences.test.tsx +2079 -0
  228. package/Tests/UI/Components/MemberRoleAssignment.test.tsx +446 -0
  229. package/Tests/UI/Components/ModelDetailRefetch.test.tsx +397 -0
  230. package/Tests/UI/Components/ModelListRefetch.test.tsx +233 -0
  231. package/Tests/UI/Components/ModelPageModelChange.test.tsx +409 -0
  232. package/Tests/UI/Components/PaginationIntegration.test.tsx +25 -0
  233. package/Tests/UI/Components/ResourceFacetConfigs.test.ts +172 -0
  234. package/Tests/UI/Components/SavedViewsSidebarIntegration.test.tsx +32 -14
  235. package/Tests/UI/Components/TableSortAndMobileColumns.test.tsx +44 -1
  236. package/Tests/UI/Components/TelemetryActiveFilterChipsLockedFilters.test.tsx +304 -0
  237. package/Tests/UI/Components/TelemetryFacetSidebarHiddenFacets.test.tsx +718 -0
  238. package/Tests/UI/Monitor/EvaluationLogList.test.tsx +303 -0
  239. package/Tests/UI/Monitor/MonitorSummarySnapshotRender.test.tsx +55 -1
  240. package/Tests/UI/Rum/FidelityNotices.test.ts +22 -0
  241. package/Tests/UI/Rum/RecordingHealthCard.test.tsx +120 -136
  242. package/Tests/UI/Rum/RecordingHealthDashboard.test.tsx +988 -0
  243. package/Tests/UI/Rum/ReplayCard.test.tsx +32 -0
  244. package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +709 -12
  245. package/Tests/UI/Rum/ReplayHeader.test.tsx +50 -1
  246. package/Tests/UI/Rum/ReplayPinControl.test.tsx +67 -10
  247. package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +41 -12
  248. package/Tests/UI/Rum/ReplayStage.test.tsx +663 -1
  249. package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +173 -0
  250. package/Tests/UI/Rum/ReplayUi.test.tsx +189 -2
  251. package/Tests/UI/Rum/ReplayUserSessionsMenu.test.tsx +91 -0
  252. package/Tests/UI/Rum/SessionReplayEmptyState.test.tsx +1 -1
  253. package/Tests/UI/Rum/SessionReplaySettingsPolicyLoading.test.tsx +585 -0
  254. package/Tests/UI/Rum/SessionReplayTable.test.tsx +844 -51
  255. package/Tests/UI/Rum/SessionReplayUsersTable.test.tsx +29 -1
  256. package/Tests/UI/Telemetry/TelemetryDetailPanel.test.tsx +288 -0
  257. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +31 -1
  258. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +6 -0
  259. package/Tests/UI/Utils/Clipboard.test.ts +154 -0
  260. package/Tests/UI/Utils/Navigation.test.ts +24 -0
  261. package/Tests/UI/Utils/Telemetry/TelemetryEntityNames.test.ts +2205 -0
  262. package/Tests/UI/Utils/Telemetry/UseTelemetryEntityNames.test.tsx +844 -0
  263. package/Tests/Utils/AI/InvestigationReport.test.ts +2430 -0
  264. package/Tests/Utils/APIOutgoingRequestTracer.test.ts +137 -0
  265. package/Tests/Utils/Rum/SessionReplayHealth.test.ts +884 -0
  266. package/Tests/Utils/Rum/SessionReplayHealthDiagnosis.test.ts +40 -0
  267. package/Tests/Utils/Rum/SessionReplayRecordingEnded.test.ts +619 -0
  268. package/Tests/Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer.test.ts +631 -0
  269. package/Tests/Utils/SecurityEvent/Connectors/CrowdStrikeFalconNormalizer.test.ts +479 -0
  270. package/Tests/Utils/SecurityEvent/Connectors/ElasticSecurityNormalizer.test.ts +507 -0
  271. package/Tests/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdrNormalizer.test.ts +686 -0
  272. package/Tests/Utils/SecurityEvent/Connectors/MicrosoftSentinelNormalizer.test.ts +474 -0
  273. package/Tests/Utils/SecurityEvent/Connectors/OktaNormalizer.test.ts +736 -0
  274. package/Tests/Utils/SecurityEvent/Connectors/SplunkNormalizer.test.ts +407 -0
  275. package/Tests/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.test.ts +129 -0
  276. package/Tests/Utils/Telemetry/CrossSignalScope.test.ts +57 -1
  277. package/Tests/Utils/Telemetry/EntityRelationship.test.ts +36 -0
  278. package/Tests/Utils/Telemetry/LockedFilterSearch.test.ts +600 -0
  279. package/Tests/Utils/Telemetry/NetworkHost.test.ts +48 -0
  280. package/Tests/Utils/Telemetry/OriginAllowList.test.ts +154 -0
  281. package/Tests/Utils/Traces/CriticalPath.test.ts +25 -0
  282. package/Types/AI/AIChatTypes.ts +8 -0
  283. package/Types/AI/InvestigationEvidence.ts +96 -0
  284. package/Types/Monitor/MonitorEvaluationSummary.ts +5 -0
  285. package/Types/OnCallDutyPolicy/Layer.ts +12 -0
  286. package/Types/Permission.ts +2 -2
  287. package/Types/Rules/RuleCriteriaFieldRegistry.ts +12 -0
  288. package/Types/Rum/SessionReplay.ts +109 -0
  289. package/Types/Rum/SessionReplayApi.ts +31 -0
  290. package/Types/SecurityEvent/Connectors/ConnectorDiagnostics.ts +111 -0
  291. package/Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics.ts +87 -0
  292. package/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.ts +492 -0
  293. package/Types/SecurityEvent/Connectors/SecurityEventConnectorProvider.ts +41 -0
  294. package/Types/SecurityEvent/GoogleSecOpsDiagnostics.ts +56 -1
  295. package/Types/SecurityEvent/GoogleSecOpsRegion.ts +34 -0
  296. package/Types/Telemetry/EntityType.ts +14 -0
  297. package/Types/Telemetry/ExceptionSpanScope.ts +83 -0
  298. package/Types/Telemetry/LockedFilterDetail.ts +46 -0
  299. package/Types/Telemetry/ResourceEntityFacet.ts +17 -10
  300. package/Types/Telemetry/ResourceFacetCatalog.ts +171 -0
  301. package/UI/Components/Card/Card.tsx +118 -83
  302. package/UI/Components/Checkbox/Checkbox.tsx +8 -5
  303. package/UI/Components/CopyTextButton/CopyTextButton.tsx +7 -1
  304. package/UI/Components/CustomFields/CustomFieldsDetail.tsx +4 -1
  305. package/UI/Components/Detail/Detail.tsx +137 -22
  306. package/UI/Components/ErrorBoundary.tsx +38 -0
  307. package/UI/Components/LogsViewer/LogsEntityNames.ts +912 -0
  308. package/UI/Components/LogsViewer/LogsViewer.tsx +156 -77
  309. package/UI/Components/LogsViewer/components/ActiveFilterChips.tsx +28 -11
  310. package/UI/Components/LogsViewer/components/FacetSection.tsx +66 -79
  311. package/UI/Components/LogsViewer/components/FacetValueRow.tsx +17 -2
  312. package/UI/Components/LogsViewer/components/LogDetailsPanel.tsx +45 -5
  313. package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +100 -19
  314. package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +156 -39
  315. package/UI/Components/LogsViewer/components/LogsTable.tsx +30 -8
  316. package/UI/Components/LogsViewer/types.ts +6 -0
  317. package/UI/Components/Markdown.tsx/InlineReferences.tsx +628 -0
  318. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +385 -312
  319. package/UI/Components/MemberRoleAssignment/MemberRoleAssignment.tsx +50 -22
  320. package/UI/Components/ModelDetail/CardModelDetail.tsx +15 -0
  321. package/UI/Components/ModelDetail/ModelDetail.tsx +64 -19
  322. package/UI/Components/ModelList/ModelList.tsx +33 -8
  323. package/UI/Components/Page/ModelPage.tsx +119 -54
  324. package/UI/Components/Table/Table.tsx +8 -0
  325. package/UI/Components/Table/TableRow.tsx +13 -5
  326. package/UI/Components/TelemetryViewer/FacetVisibility.ts +229 -0
  327. package/UI/Components/TelemetryViewer/ResourceFacetConfigs.ts +46 -0
  328. package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +11 -0
  329. package/UI/Components/TelemetryViewer/components/FacetSearchInput.tsx +79 -0
  330. package/UI/Components/TelemetryViewer/components/FacetSectionHeader.tsx +69 -0
  331. package/UI/Components/TelemetryViewer/components/FacetShowMoreButton.tsx +36 -0
  332. package/UI/Components/TelemetryViewer/components/HiddenFacetsFooter.tsx +88 -0
  333. package/UI/Components/TelemetryViewer/components/LockedFilterActions.tsx +205 -0
  334. package/UI/Components/TelemetryViewer/components/LockedFilterChip.tsx +496 -0
  335. package/UI/Components/TelemetryViewer/components/TelemetryActiveFilterChips.tsx +30 -10
  336. package/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.tsx +203 -10
  337. package/UI/Components/TelemetryViewer/components/TelemetryFacetSection.tsx +60 -73
  338. package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +94 -7
  339. package/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.tsx +17 -2
  340. package/UI/Components/TelemetryViewer/types.ts +19 -0
  341. package/UI/Components/TelemetryViewer/useFacetSearchExemptions.ts +158 -0
  342. package/UI/Components/TelemetryViewer/useFacetSectionSearch.ts +102 -0
  343. package/UI/Utils/Clipboard.ts +68 -2
  344. package/UI/Utils/Navigation.ts +17 -2
  345. package/UI/Utils/Telemetry/TelemetryEntityNames.ts +620 -0
  346. package/UI/Utils/Telemetry/UseTelemetryEntityNames.ts +151 -0
  347. package/Utils/AI/InvestigationReport.ts +1789 -0
  348. package/Utils/API.ts +90 -1
  349. package/Utils/Rum/SessionReplayHealth.ts +11 -0
  350. package/Utils/Rum/SessionReplayRecordingEnded.ts +134 -0
  351. package/Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer.ts +427 -0
  352. package/Utils/SecurityEvent/Connectors/CrowdStrikeFalconNormalizer.ts +197 -0
  353. package/Utils/SecurityEvent/Connectors/ElasticSecurityNormalizer.ts +464 -0
  354. package/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdrNormalizer.ts +567 -0
  355. package/Utils/SecurityEvent/Connectors/MicrosoftSentinelNormalizer.ts +299 -0
  356. package/Utils/SecurityEvent/Connectors/OktaNormalizer.ts +467 -0
  357. package/Utils/SecurityEvent/Connectors/SplunkNormalizer.ts +439 -0
  358. package/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.ts +124 -12
  359. package/Utils/Telemetry/CrossSignalScope.ts +22 -8
  360. package/Utils/Telemetry/EntityRelationship.ts +8 -0
  361. package/Utils/Telemetry/LockedFilterSearch.ts +412 -0
  362. package/Utils/Telemetry/NetworkHost.ts +43 -0
  363. package/Utils/Telemetry/OriginAllowList.ts +139 -4
  364. package/Utils/Traces/CriticalPath.ts +10 -4
  365. package/build/dist/Models/DatabaseModels/Index.js +4 -0
  366. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  367. package/build/dist/Models/DatabaseModels/RumApplication.js +1 -1
  368. package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
  369. package/build/dist/Models/DatabaseModels/SecurityEventConnection.js +490 -0
  370. package/build/dist/Models/DatabaseModels/SecurityEventConnection.js.map +1 -0
  371. package/build/dist/Models/DatabaseModels/SecurityEventConnectionRun.js +287 -0
  372. package/build/dist/Models/DatabaseModels/SecurityEventConnectionRun.js.map +1 -0
  373. package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js +2 -2
  374. package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js.map +1 -1
  375. package/build/dist/Server/API/AIInvestigationAPI.js +336 -27
  376. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  377. package/build/dist/Server/API/GoogleSecOpsConnectionAPI.js +182 -7
  378. package/build/dist/Server/API/GoogleSecOpsConnectionAPI.js.map +1 -1
  379. package/build/dist/Server/API/SecurityEventConnectionAPI.js +171 -0
  380. package/build/dist/Server/API/SecurityEventConnectionAPI.js.map +1 -0
  381. package/build/dist/Server/API/TelemetryAPI.js +248 -170
  382. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  383. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792700000000-AddSecurityEventConnections.js +40 -0
  384. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792700000000-AddSecurityEventConnections.js.map +1 -0
  385. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
  386. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  387. package/build/dist/Server/Middleware/TelemetryIngest.js +57 -4
  388. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  389. package/build/dist/Server/Services/ExceptionAggregationService.js +7 -16
  390. package/build/dist/Server/Services/ExceptionAggregationService.js.map +1 -1
  391. package/build/dist/Server/Services/GoogleSecOpsConnectionService.js +8 -0
  392. package/build/dist/Server/Services/GoogleSecOpsConnectionService.js.map +1 -1
  393. package/build/dist/Server/Services/Index.js +4 -0
  394. package/build/dist/Server/Services/Index.js.map +1 -1
  395. package/build/dist/Server/Services/InventoryItemService.js +22 -0
  396. package/build/dist/Server/Services/InventoryItemService.js.map +1 -1
  397. package/build/dist/Server/Services/LogAggregationService.js +8 -17
  398. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  399. package/build/dist/Server/Services/MetricAggregationService.js +4 -14
  400. package/build/dist/Server/Services/MetricAggregationService.js.map +1 -1
  401. package/build/dist/Server/Services/SecurityEventConnectionRunService.js +9 -0
  402. package/build/dist/Server/Services/SecurityEventConnectionRunService.js.map +1 -0
  403. package/build/dist/Server/Services/SecurityEventConnectionService.js +356 -0
  404. package/build/dist/Server/Services/SecurityEventConnectionService.js.map +1 -0
  405. package/build/dist/Server/Services/TraceAggregationService.js +51 -25
  406. package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
  407. package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js +9 -0
  408. package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js.map +1 -1
  409. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +3 -0
  410. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
  411. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +14 -7
  412. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  413. package/build/dist/Server/Utils/AI/SRE/InvestigationEvidence.js +468 -0
  414. package/build/dist/Server/Utils/AI/SRE/InvestigationEvidence.js.map +1 -0
  415. package/build/dist/Server/Utils/AI/SRE/InvestigationReferences.js +230 -0
  416. package/build/dist/Server/Utils/AI/SRE/InvestigationReferences.js.map +1 -0
  417. package/build/dist/Server/Utils/AI/Toolbox/Index.js +32 -0
  418. package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
  419. package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js +6 -2
  420. package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js.map +1 -1
  421. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +59 -0
  422. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  423. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +5 -3
  424. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  425. package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.js +752 -0
  426. package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.js.map +1 -0
  427. package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubConnector.js +493 -0
  428. package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubConnector.js.map +1 -0
  429. package/build/dist/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.js +352 -0
  430. package/build/dist/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.js.map +1 -0
  431. package/build/dist/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconClient.js +405 -0
  432. package/build/dist/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconClient.js.map +1 -0
  433. package/build/dist/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconConnector.js +466 -0
  434. package/build/dist/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconConnector.js.map +1 -0
  435. package/build/dist/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityClient.js +344 -0
  436. package/build/dist/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityClient.js.map +1 -0
  437. package/build/dist/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityConnector.js +511 -0
  438. package/build/dist/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityConnector.js.map +1 -0
  439. package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrClient.js +406 -0
  440. package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrClient.js.map +1 -0
  441. package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrConnector.js +336 -0
  442. package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrConnector.js.map +1 -0
  443. package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelClient.js +474 -0
  444. package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelClient.js.map +1 -0
  445. package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelConnector.js +417 -0
  446. package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelConnector.js.map +1 -0
  447. package/build/dist/Server/Utils/SecurityEvent/Connectors/Okta/OktaClient.js +314 -0
  448. package/build/dist/Server/Utils/SecurityEvent/Connectors/Okta/OktaClient.js.map +1 -0
  449. package/build/dist/Server/Utils/SecurityEvent/Connectors/Okta/OktaConnector.js +494 -0
  450. package/build/dist/Server/Utils/SecurityEvent/Connectors/Okta/OktaConnector.js.map +1 -0
  451. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.js +719 -0
  452. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.js.map +1 -0
  453. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.js +404 -0
  454. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.js.map +1 -0
  455. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.js +209 -0
  456. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.js.map +1 -0
  457. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry.js +40 -0
  458. package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry.js.map +1 -0
  459. package/build/dist/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkClient.js +494 -0
  460. package/build/dist/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkClient.js.map +1 -0
  461. package/build/dist/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkConnector.js +379 -0
  462. package/build/dist/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkConnector.js.map +1 -0
  463. package/build/dist/Server/Utils/SecurityEvent/Connectors/Types.js +27 -0
  464. package/build/dist/Server/Utils/SecurityEvent/Connectors/Types.js.map +1 -0
  465. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js +234 -61
  466. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js.map +1 -1
  467. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsConnectionTester.js +537 -0
  468. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsConnectionTester.js.map +1 -0
  469. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js +572 -115
  470. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js.map +1 -1
  471. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.js +35 -1
  472. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.js.map +1 -1
  473. package/build/dist/Server/Utils/SecurityEvent/SecurityEventDedupe.js +52 -0
  474. package/build/dist/Server/Utils/SecurityEvent/SecurityEventDedupe.js.map +1 -0
  475. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +521 -32
  476. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
  477. package/build/dist/Server/Utils/StartServer.js +10 -0
  478. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  479. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +8 -0
  480. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
  481. package/build/dist/Server/Utils/Telemetry/KubernetesResourceAttributes.js +80 -0
  482. package/build/dist/Server/Utils/Telemetry/KubernetesResourceAttributes.js.map +1 -0
  483. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +122 -67
  484. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -1
  485. package/build/dist/Server/Utils/Telemetry/ResourceFacetPlanner.js +146 -0
  486. package/build/dist/Server/Utils/Telemetry/ResourceFacetPlanner.js.map +1 -0
  487. package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js +174 -248
  488. package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js.map +1 -1
  489. package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js +492 -0
  490. package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js.map +1 -0
  491. package/build/dist/Server/Utils/Telemetry/TraceContextPropagation.js +259 -0
  492. package/build/dist/Server/Utils/Telemetry/TraceContextPropagation.js.map +1 -0
  493. package/build/dist/Server/Utils/Telemetry.js +11 -5
  494. package/build/dist/Server/Utils/Telemetry.js.map +1 -1
  495. package/build/dist/Types/AI/InvestigationEvidence.js +2 -0
  496. package/build/dist/Types/AI/InvestigationEvidence.js.map +1 -0
  497. package/build/dist/Types/OnCallDutyPolicy/Layer.js +11 -0
  498. package/build/dist/Types/OnCallDutyPolicy/Layer.js.map +1 -1
  499. package/build/dist/Types/Permission.js +2 -2
  500. package/build/dist/Types/Permission.js.map +1 -1
  501. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +9 -0
  502. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
  503. package/build/dist/Types/Rum/SessionReplay.js +95 -0
  504. package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
  505. package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -1
  506. package/build/dist/Types/SecurityEvent/Connectors/ConnectorDiagnostics.js +18 -0
  507. package/build/dist/Types/SecurityEvent/Connectors/ConnectorDiagnostics.js.map +1 -0
  508. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics.js +2 -0
  509. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics.js.map +1 -0
  510. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js +374 -0
  511. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js.map +1 -0
  512. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorProvider.js +35 -0
  513. package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorProvider.js.map +1 -0
  514. package/build/dist/Types/SecurityEvent/GoogleSecOpsRegion.js +35 -0
  515. package/build/dist/Types/SecurityEvent/GoogleSecOpsRegion.js.map +1 -0
  516. package/build/dist/Types/Telemetry/EntityType.js +14 -0
  517. package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
  518. package/build/dist/Types/Telemetry/ExceptionSpanScope.js +59 -0
  519. package/build/dist/Types/Telemetry/ExceptionSpanScope.js.map +1 -0
  520. package/build/dist/Types/Telemetry/LockedFilterDetail.js +16 -0
  521. package/build/dist/Types/Telemetry/LockedFilterDetail.js.map +1 -0
  522. package/build/dist/Types/Telemetry/ResourceEntityFacet.js +16 -10
  523. package/build/dist/Types/Telemetry/ResourceEntityFacet.js.map +1 -1
  524. package/build/dist/Types/Telemetry/ResourceFacetCatalog.js +119 -0
  525. package/build/dist/Types/Telemetry/ResourceFacetCatalog.js.map +1 -0
  526. package/build/dist/UI/Components/Card/Card.js +34 -17
  527. package/build/dist/UI/Components/Card/Card.js.map +1 -1
  528. package/build/dist/UI/Components/Checkbox/Checkbox.js +6 -4
  529. package/build/dist/UI/Components/Checkbox/Checkbox.js.map +1 -1
  530. package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js +5 -1
  531. package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js.map +1 -1
  532. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +1 -1
  533. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
  534. package/build/dist/UI/Components/Detail/Detail.js +63 -13
  535. package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
  536. package/build/dist/UI/Components/ErrorBoundary.js +34 -0
  537. package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
  538. package/build/dist/UI/Components/LogsViewer/LogsEntityNames.js +535 -0
  539. package/build/dist/UI/Components/LogsViewer/LogsEntityNames.js.map +1 -0
  540. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +117 -57
  541. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  542. package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js +5 -7
  543. package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js.map +1 -1
  544. package/build/dist/UI/Components/LogsViewer/components/FacetSection.js +31 -44
  545. package/build/dist/UI/Components/LogsViewer/components/FacetSection.js.map +1 -1
  546. package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js +17 -3
  547. package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js.map +1 -1
  548. package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js +19 -3
  549. package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js.map +1 -1
  550. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +64 -18
  551. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
  552. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +100 -41
  553. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
  554. package/build/dist/UI/Components/LogsViewer/components/LogsTable.js +13 -5
  555. package/build/dist/UI/Components/LogsViewer/components/LogsTable.js.map +1 -1
  556. package/build/dist/UI/Components/LogsViewer/types.js.map +1 -1
  557. package/build/dist/UI/Components/Markdown.tsx/InlineReferences.js +403 -0
  558. package/build/dist/UI/Components/Markdown.tsx/InlineReferences.js.map +1 -0
  559. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +197 -179
  560. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  561. package/build/dist/UI/Components/MemberRoleAssignment/MemberRoleAssignment.js +30 -21
  562. package/build/dist/UI/Components/MemberRoleAssignment/MemberRoleAssignment.js.map +1 -1
  563. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +12 -0
  564. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  565. package/build/dist/UI/Components/ModelDetail/ModelDetail.js +46 -12
  566. package/build/dist/UI/Components/ModelDetail/ModelDetail.js.map +1 -1
  567. package/build/dist/UI/Components/ModelList/ModelList.js +26 -7
  568. package/build/dist/UI/Components/ModelList/ModelList.js.map +1 -1
  569. package/build/dist/UI/Components/Page/ModelPage.js +62 -34
  570. package/build/dist/UI/Components/Page/ModelPage.js.map +1 -1
  571. package/build/dist/UI/Components/Table/Table.js +3 -1
  572. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  573. package/build/dist/UI/Components/Table/TableRow.js +8 -1
  574. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  575. package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js +111 -0
  576. package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js.map +1 -0
  577. package/build/dist/UI/Components/TelemetryViewer/ResourceFacetConfigs.js +22 -0
  578. package/build/dist/UI/Components/TelemetryViewer/ResourceFacetConfigs.js.map +1 -0
  579. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +1 -1
  580. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
  581. package/build/dist/UI/Components/TelemetryViewer/components/FacetSearchInput.js +36 -0
  582. package/build/dist/UI/Components/TelemetryViewer/components/FacetSearchInput.js.map +1 -0
  583. package/build/dist/UI/Components/TelemetryViewer/components/FacetSectionHeader.js +21 -0
  584. package/build/dist/UI/Components/TelemetryViewer/components/FacetSectionHeader.js.map +1 -0
  585. package/build/dist/UI/Components/TelemetryViewer/components/FacetShowMoreButton.js +14 -0
  586. package/build/dist/UI/Components/TelemetryViewer/components/FacetShowMoreButton.js.map +1 -0
  587. package/build/dist/UI/Components/TelemetryViewer/components/HiddenFacetsFooter.js +27 -0
  588. package/build/dist/UI/Components/TelemetryViewer/components/HiddenFacetsFooter.js.map +1 -0
  589. package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterActions.js +88 -0
  590. package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterActions.js.map +1 -0
  591. package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js +228 -0
  592. package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js.map +1 -0
  593. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryActiveFilterChips.js +6 -6
  594. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryActiveFilterChips.js.map +1 -1
  595. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.js +111 -12
  596. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.js.map +1 -1
  597. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSection.js +27 -40
  598. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSection.js.map +1 -1
  599. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +70 -10
  600. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
  601. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js +17 -3
  602. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js.map +1 -1
  603. package/build/dist/UI/Components/TelemetryViewer/types.js +0 -4
  604. package/build/dist/UI/Components/TelemetryViewer/types.js.map +1 -1
  605. package/build/dist/UI/Components/TelemetryViewer/useFacetSearchExemptions.js +70 -0
  606. package/build/dist/UI/Components/TelemetryViewer/useFacetSearchExemptions.js.map +1 -0
  607. package/build/dist/UI/Components/TelemetryViewer/useFacetSectionSearch.js +52 -0
  608. package/build/dist/UI/Components/TelemetryViewer/useFacetSectionSearch.js.map +1 -0
  609. package/build/dist/UI/Utils/Clipboard.js +59 -2
  610. package/build/dist/UI/Utils/Clipboard.js.map +1 -1
  611. package/build/dist/UI/Utils/Navigation.js +11 -2
  612. package/build/dist/UI/Utils/Navigation.js.map +1 -1
  613. package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js +471 -0
  614. package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js.map +1 -0
  615. package/build/dist/UI/Utils/Telemetry/UseTelemetryEntityNames.js +113 -0
  616. package/build/dist/UI/Utils/Telemetry/UseTelemetryEntityNames.js.map +1 -0
  617. package/build/dist/Utils/AI/InvestigationReport.js +1241 -0
  618. package/build/dist/Utils/AI/InvestigationReport.js.map +1 -0
  619. package/build/dist/Utils/API.js +25 -0
  620. package/build/dist/Utils/API.js.map +1 -1
  621. package/build/dist/Utils/Rum/SessionReplayHealth.js +10 -0
  622. package/build/dist/Utils/Rum/SessionReplayHealth.js.map +1 -1
  623. package/build/dist/Utils/Rum/SessionReplayRecordingEnded.js +54 -0
  624. package/build/dist/Utils/Rum/SessionReplayRecordingEnded.js.map +1 -0
  625. package/build/dist/Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer.js +311 -0
  626. package/build/dist/Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer.js.map +1 -0
  627. package/build/dist/Utils/SecurityEvent/Connectors/CrowdStrikeFalconNormalizer.js +150 -0
  628. package/build/dist/Utils/SecurityEvent/Connectors/CrowdStrikeFalconNormalizer.js.map +1 -0
  629. package/build/dist/Utils/SecurityEvent/Connectors/ElasticSecurityNormalizer.js +328 -0
  630. package/build/dist/Utils/SecurityEvent/Connectors/ElasticSecurityNormalizer.js.map +1 -0
  631. package/build/dist/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdrNormalizer.js +405 -0
  632. package/build/dist/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdrNormalizer.js.map +1 -0
  633. package/build/dist/Utils/SecurityEvent/Connectors/MicrosoftSentinelNormalizer.js +212 -0
  634. package/build/dist/Utils/SecurityEvent/Connectors/MicrosoftSentinelNormalizer.js.map +1 -0
  635. package/build/dist/Utils/SecurityEvent/Connectors/OktaNormalizer.js +351 -0
  636. package/build/dist/Utils/SecurityEvent/Connectors/OktaNormalizer.js.map +1 -0
  637. package/build/dist/Utils/SecurityEvent/Connectors/SplunkNormalizer.js +348 -0
  638. package/build/dist/Utils/SecurityEvent/Connectors/SplunkNormalizer.js.map +1 -0
  639. package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js +103 -10
  640. package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js.map +1 -1
  641. package/build/dist/Utils/Telemetry/CrossSignalScope.js +16 -5
  642. package/build/dist/Utils/Telemetry/CrossSignalScope.js.map +1 -1
  643. package/build/dist/Utils/Telemetry/EntityRelationship.js +7 -0
  644. package/build/dist/Utils/Telemetry/EntityRelationship.js.map +1 -1
  645. package/build/dist/Utils/Telemetry/LockedFilterSearch.js +277 -0
  646. package/build/dist/Utils/Telemetry/LockedFilterSearch.js.map +1 -0
  647. package/build/dist/Utils/Telemetry/NetworkHost.js +39 -0
  648. package/build/dist/Utils/Telemetry/NetworkHost.js.map +1 -0
  649. package/build/dist/Utils/Telemetry/OriginAllowList.js +105 -4
  650. package/build/dist/Utils/Telemetry/OriginAllowList.js.map +1 -1
  651. package/build/dist/Utils/Traces/CriticalPath.js +9 -4
  652. package/build/dist/Utils/Traces/CriticalPath.js.map +1 -1
  653. package/package.json +1 -1
  654. package/Tests/UI/Rum/RecordingHealthStrip.test.tsx +0 -600
  655. package/UI/Components/GanttChart/Bar/BarLabel.tsx +0 -17
  656. package/UI/Components/GanttChart/Bar/Index.tsx +0 -149
  657. package/UI/Components/GanttChart/ChartContainer.tsx +0 -50
  658. package/UI/Components/GanttChart/Index.tsx +0 -90
  659. package/UI/Components/GanttChart/Row/Index.tsx +0 -22
  660. package/UI/Components/GanttChart/Row/Row.tsx +0 -231
  661. package/UI/Components/GanttChart/Row/RowLabel.tsx +0 -30
  662. package/UI/Components/GanttChart/Rows.tsx +0 -59
  663. package/UI/Components/GanttChart/Timeline/Index.tsx +0 -46
  664. package/UI/Components/GanttChart/Timeline/TimelineInterval.tsx +0 -33
  665. package/UI/Components/GanttChart/Timeline/TimelineIntervalMarks.tsx +0 -43
  666. package/build/dist/UI/Components/GanttChart/Bar/BarLabel.js +0 -8
  667. package/build/dist/UI/Components/GanttChart/Bar/BarLabel.js.map +0 -1
  668. package/build/dist/UI/Components/GanttChart/Bar/Index.js +0 -77
  669. package/build/dist/UI/Components/GanttChart/Bar/Index.js.map +0 -1
  670. package/build/dist/UI/Components/GanttChart/ChartContainer.js +0 -33
  671. package/build/dist/UI/Components/GanttChart/ChartContainer.js.map +0 -1
  672. package/build/dist/UI/Components/GanttChart/Index.js +0 -39
  673. package/build/dist/UI/Components/GanttChart/Index.js.map +0 -1
  674. package/build/dist/UI/Components/GanttChart/Row/Index.js +0 -7
  675. package/build/dist/UI/Components/GanttChart/Row/Index.js.map +0 -1
  676. package/build/dist/UI/Components/GanttChart/Row/Row.js +0 -106
  677. package/build/dist/UI/Components/GanttChart/Row/Row.js.map +0 -1
  678. package/build/dist/UI/Components/GanttChart/Row/RowLabel.js +0 -10
  679. package/build/dist/UI/Components/GanttChart/Row/RowLabel.js.map +0 -1
  680. package/build/dist/UI/Components/GanttChart/Rows.js +0 -19
  681. package/build/dist/UI/Components/GanttChart/Rows.js.map +0 -1
  682. package/build/dist/UI/Components/GanttChart/Timeline/Index.js +0 -16
  683. package/build/dist/UI/Components/GanttChart/Timeline/Index.js.map +0 -1
  684. package/build/dist/UI/Components/GanttChart/Timeline/TimelineInterval.js +0 -13
  685. package/build/dist/UI/Components/GanttChart/Timeline/TimelineInterval.js.map +0 -1
  686. package/build/dist/UI/Components/GanttChart/Timeline/TimelineIntervalMarks.js +0 -13
  687. package/build/dist/UI/Components/GanttChart/Timeline/TimelineIntervalMarks.js.map +0 -1
@@ -0,0 +1,912 @@
1
+ import Log from "../../../Models/AnalyticsModels/Log";
2
+ import DockerHost from "../../../Models/DatabaseModels/DockerHost";
3
+ import Host from "../../../Models/DatabaseModels/Host";
4
+ import KubernetesCluster from "../../../Models/DatabaseModels/KubernetesCluster";
5
+ import PodmanHost from "../../../Models/DatabaseModels/PodmanHost";
6
+ import Service from "../../../Models/DatabaseModels/Service";
7
+ import Dictionary from "../../../Types/Dictionary";
8
+ import {
9
+ isResourceEntityFacetKey,
10
+ isResourceFacetKey,
11
+ isServiceFacetKey,
12
+ } from "../../../Types/Telemetry/ResourceEntityFacet";
13
+ import {
14
+ getResourceFacetLabelMap,
15
+ getResourceFacetServiceTypeMap,
16
+ } from "../../../Types/Telemetry/ResourceFacetCatalog";
17
+ import ServiceType from "../../../Types/Telemetry/ServiceType";
18
+ import {
19
+ DEFAULT_TELEMETRY_ENTITY_LABEL,
20
+ getTelemetryEntityDisplay,
21
+ ResolvedTelemetryEntity,
22
+ TELEMETRY_ENTITY_TYPES,
23
+ TelemetryEntityNameMap,
24
+ } from "../../Utils/Telemetry/TelemetryEntityNames";
25
+ import { ActiveFilter, FacetData, FacetValue } from "./types";
26
+
27
+ /*
28
+ * Display-only name resolution for the shared logs viewer.
29
+ *
30
+ * A log's `primaryEntityId` is polymorphic — a Service id for most rows, but
31
+ * a RumApplication id for browser logs, a Host id for agent-ingested host
32
+ * logs, and so on. The viewer only preloads Services / Hosts / Docker hosts /
33
+ * Podman hosts / Kubernetes clusters, so anything else (a RUM application, a
34
+ * serverless function, …) used to render as a raw UUID in the chips, the
35
+ * Service column, the details header and the analytics legend.
36
+ *
37
+ * These helpers decide which ids still need the generic resolver
38
+ * (TelemetryEntityNameResolver) and how its answer is folded into what the
39
+ * user sees. They are pure so the precedence rules can be pinned without
40
+ * rendering the viewer. Queries, URL state and saved views keep the ids.
41
+ */
42
+
43
+ // The preloaded non-Service resource maps.
44
+ export interface LogsResourceEntityMaps {
45
+ hostMap?: Dictionary<Host> | undefined;
46
+ dockerHostMap?: Dictionary<DockerHost> | undefined;
47
+ podmanHostMap?: Dictionary<PodmanHost> | undefined;
48
+ kubernetesClusterMap?: Dictionary<KubernetesCluster> | undefined;
49
+ }
50
+
51
+ export interface LogsEntityLookupMaps extends LogsResourceEntityMaps {
52
+ serviceMap: Dictionary<Service>;
53
+ }
54
+
55
+ export interface LogsEntityResolutionRequest {
56
+ // Sorted, de-duplicated ids that still need the generic resolver.
57
+ ids: Array<string>;
58
+ // id -> table, for ids whose table the viewer already knows.
59
+ typeHints: Record<string, ServiceType>;
60
+ }
61
+
62
+ /*
63
+ * Non-Service resource facets name one specific table, so their ids can
64
+ * skip the Service-first probe and go straight to it. Every catalog resource
65
+ * type is listed — not only the four the viewer preloads — so a Proxmox
66
+ * cluster or IoT fleet facet value / chip is still sent to its own table.
67
+ * Catalog order is kept: findLoadedLogsResourceEntity probes the preloaded
68
+ * maps in this order.
69
+ */
70
+ export const LOGS_RESOURCE_FACET_ENTITY_TYPES: Record<string, ServiceType> =
71
+ Object.fromEntries(getResourceFacetServiceTypeMap());
72
+
73
+ /*
74
+ * Telemetry entity ids are Postgres UUIDs. A chip value that is not one (a
75
+ * service name typed into the search bar that did not match a loaded
76
+ * Service) would only make every entity table answer "not found", so it is
77
+ * never sent to the resolver.
78
+ */
79
+ const ENTITY_ID_PATTERN: RegExp =
80
+ /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
81
+
82
+ export const isLogsEntityIdValue: (value: unknown) => value is string = (
83
+ value: unknown,
84
+ ): value is string => {
85
+ return typeof value === "string" && ENTITY_ID_PATTERN.test(value.trim());
86
+ };
87
+
88
+ const nonEmpty: (value: string | null | undefined) => string | undefined = (
89
+ value: string | null | undefined,
90
+ ): string | undefined => {
91
+ if (value === null || value === undefined) {
92
+ return undefined;
93
+ }
94
+ const text: string = `${value}`.trim();
95
+ return text.length > 0 ? text : undefined;
96
+ };
97
+
98
+ /*
99
+ * The name the viewer's preloaded maps already know for a resource facet
100
+ * value, or undefined. These win over the generic resolver: they are loaded
101
+ * anyway and carry extras (a Service's colour) the resolver does not.
102
+ */
103
+ export const getLoadedLogsEntityName: (
104
+ facetKey: string,
105
+ id: string,
106
+ maps: LogsEntityLookupMaps,
107
+ ) => string | undefined = (
108
+ facetKey: string,
109
+ id: string,
110
+ maps: LogsEntityLookupMaps,
111
+ ): string | undefined => {
112
+ if (isServiceFacetKey(facetKey)) {
113
+ return nonEmpty(maps.serviceMap[id]?.name);
114
+ }
115
+ if (facetKey === "hostId") {
116
+ const host: Host | undefined = maps.hostMap?.[id];
117
+ return nonEmpty(host?.name) || nonEmpty(host?.hostIdentifier);
118
+ }
119
+ if (facetKey === "dockerHostId") {
120
+ const dockerHost: DockerHost | undefined = maps.dockerHostMap?.[id];
121
+ return nonEmpty(dockerHost?.name) || nonEmpty(dockerHost?.hostIdentifier);
122
+ }
123
+ if (facetKey === "podmanHostId") {
124
+ const podmanHost: PodmanHost | undefined = maps.podmanHostMap?.[id];
125
+ return nonEmpty(podmanHost?.name) || nonEmpty(podmanHost?.hostIdentifier);
126
+ }
127
+ if (facetKey === "kubernetesClusterId") {
128
+ const cluster: KubernetesCluster | undefined =
129
+ maps.kubernetesClusterMap?.[id];
130
+ return nonEmpty(cluster?.name) || nonEmpty(cluster?.clusterIdentifier);
131
+ }
132
+ return undefined;
133
+ };
134
+
135
+ export interface LoadedLogsResourceEntity {
136
+ name: string;
137
+ entityType: ServiceType;
138
+ // e.g. "Host", "Kubernetes Cluster".
139
+ typeLabel: string;
140
+ }
141
+
142
+ /*
143
+ * A primaryEntityId is polymorphic: agent-ingested host / container /
144
+ * cluster telemetry carries the Host / DockerHost / PodmanHost /
145
+ * KubernetesCluster id. Production log rows are not guaranteed to carry
146
+ * primaryEntityType, so the only way to tell such an id apart from a
147
+ * Service id without a network round trip is to look it up in the
148
+ * non-Service maps the viewer has already preloaded. Returns the name
149
+ * (name, else the machine identifier) and the table it was found in.
150
+ */
151
+ export const findLoadedLogsResourceEntity: (
152
+ id: string,
153
+ maps: LogsResourceEntityMaps | undefined,
154
+ ) => LoadedLogsResourceEntity | undefined = (
155
+ id: string,
156
+ maps: LogsResourceEntityMaps | undefined,
157
+ ): LoadedLogsResourceEntity | undefined => {
158
+ if (!id || !maps) {
159
+ return undefined;
160
+ }
161
+
162
+ for (const [facetKey, entityType] of Object.entries(
163
+ LOGS_RESOURCE_FACET_ENTITY_TYPES,
164
+ )) {
165
+ const name: string | undefined = getLoadedLogsEntityName(facetKey, id, {
166
+ ...maps,
167
+ serviceMap: {},
168
+ });
169
+ if (name) {
170
+ return {
171
+ name,
172
+ entityType,
173
+ typeLabel: TELEMETRY_ENTITY_TYPES[entityType].label,
174
+ };
175
+ }
176
+ }
177
+
178
+ return undefined;
179
+ };
180
+
181
+ /*
182
+ * A parent (the Dashboard logs explorer) may hand chips over already named
183
+ * — e.g. "RUM Application: checkout-web". Its displayValue then differs from
184
+ * the id and must not be overwritten with anything less specific.
185
+ */
186
+ const hasParentResolvedDisplay: (filter: ActiveFilter) => boolean = (
187
+ filter: ActiveFilter,
188
+ ): boolean => {
189
+ return (
190
+ typeof filter.displayValue === "string" &&
191
+ filter.displayValue.length > 0 &&
192
+ filter.displayValue !== filter.value
193
+ );
194
+ };
195
+
196
+ /*
197
+ * Name one chip. Precedence for primaryEntityId / serviceId / hostId / … :
198
+ * 1. the preloaded map (existing behaviour, keeps the key as given);
199
+ * 2. a name the parent already supplied (left untouched);
200
+ * 3. for Service-keyed chips, a preloaded host / cluster with that id —
201
+ * the key becomes its type ("Host");
202
+ * 4. the generic resolver — for Service-keyed chips the key becomes the
203
+ * entity's type ("RUM Application"), for the typed resource facets the
204
+ * key ("Host") is already right and only the value changes;
205
+ * 5. otherwise the chip is returned as it came in.
206
+ * Non-resource chips are never touched.
207
+ */
208
+ export const enrichLogsActiveFilter: (
209
+ filter: ActiveFilter,
210
+ maps: LogsEntityLookupMaps,
211
+ entityNameMap: TelemetryEntityNameMap | undefined,
212
+ ) => ActiveFilter = (
213
+ filter: ActiveFilter,
214
+ maps: LogsEntityLookupMaps,
215
+ entityNameMap: TelemetryEntityNameMap | undefined,
216
+ ): ActiveFilter => {
217
+ if (
218
+ !isResourceFacetKey(filter.facetKey) ||
219
+ typeof filter.value !== "string"
220
+ ) {
221
+ return filter;
222
+ }
223
+
224
+ const loadedName: string | undefined = getLoadedLogsEntityName(
225
+ filter.facetKey,
226
+ filter.value,
227
+ maps,
228
+ );
229
+ if (loadedName) {
230
+ return { ...filter, displayValue: loadedName };
231
+ }
232
+
233
+ if (hasParentResolvedDisplay(filter)) {
234
+ return filter;
235
+ }
236
+
237
+ /*
238
+ * A Service-keyed chip whose id is a preloaded host / cluster is named
239
+ * from that map, keyed by its type like a resolver answer would be. The
240
+ * id is then never sent to the resolver (collectLogsEntityIdsToResolve
241
+ * skips it), so this is the only place it gets named.
242
+ */
243
+ if (isServiceFacetKey(filter.facetKey)) {
244
+ const loadedResource: LoadedLogsResourceEntity | undefined =
245
+ findLoadedLogsResourceEntity(filter.value, maps);
246
+ if (loadedResource) {
247
+ return {
248
+ ...filter,
249
+ displayKey: loadedResource.typeLabel,
250
+ displayValue: loadedResource.name,
251
+ };
252
+ }
253
+ }
254
+
255
+ const resolved: ResolvedTelemetryEntity | undefined =
256
+ entityNameMap?.[filter.value];
257
+ if (!resolved) {
258
+ return filter;
259
+ }
260
+
261
+ if (isServiceFacetKey(filter.facetKey)) {
262
+ const display: { key: string; value: string } = getTelemetryEntityDisplay({
263
+ id: filter.value,
264
+ nameMap: entityNameMap,
265
+ fallbackKey: filter.displayKey,
266
+ });
267
+ return { ...filter, displayKey: display.key, displayValue: display.value };
268
+ }
269
+
270
+ return { ...filter, displayValue: resolved.name };
271
+ };
272
+
273
+ export const enrichLogsActiveFilters: (
274
+ filters: Array<ActiveFilter> | undefined,
275
+ maps: LogsEntityLookupMaps,
276
+ entityNameMap: TelemetryEntityNameMap | undefined,
277
+ ) => Array<ActiveFilter> = (
278
+ filters: Array<ActiveFilter> | undefined,
279
+ maps: LogsEntityLookupMaps,
280
+ entityNameMap: TelemetryEntityNameMap | undefined,
281
+ ): Array<ActiveFilter> => {
282
+ return (filters || []).map((filter: ActiveFilter): ActiveFilter => {
283
+ return enrichLogsActiveFilter(filter, maps, entityNameMap);
284
+ });
285
+ };
286
+
287
+ /*
288
+ * A parent that knows what its scope ids are (a RUM page) labels the chip
289
+ * with the entity's type ("RUM Application") before the name has landed.
290
+ * Reading that label back as a type hint sends the id straight to its own
291
+ * table; unhinted, a non-Service id misses the Service probe and then fans
292
+ * out to every other entity table. "Service" is ambiguous (a Service or the
293
+ * project-level Unknown bucket) and is the generic default, so it is never
294
+ * read as a hint.
295
+ */
296
+ export const getTelemetryEntityTypeForChipKey: (
297
+ displayKey: string | undefined,
298
+ ) => ServiceType | undefined = (
299
+ displayKey: string | undefined,
300
+ ): ServiceType | undefined => {
301
+ const label: string | undefined = nonEmpty(displayKey);
302
+ if (!label || label === DEFAULT_TELEMETRY_ENTITY_LABEL) {
303
+ return undefined;
304
+ }
305
+
306
+ const matches: Array<ServiceType> = (
307
+ Object.keys(TELEMETRY_ENTITY_TYPES) as Array<ServiceType>
308
+ ).filter((type: ServiceType): boolean => {
309
+ return TELEMETRY_ENTITY_TYPES[type].label === label;
310
+ });
311
+
312
+ return matches.length === 1 ? matches[0] : undefined;
313
+ };
314
+
315
+ /*
316
+ * The server's name for a facet value, or undefined. A blank displayName, or
317
+ * one that merely echoes the value (an id the server could not name), is
318
+ * not a name: it must neither suppress the client-side resolver nor win
319
+ * over a name the viewer does have.
320
+ */
321
+ export const getServerFacetDisplayName: (
322
+ facetValue: FacetValue | undefined,
323
+ ) => string | undefined = (
324
+ facetValue: FacetValue | undefined,
325
+ ): string | undefined => {
326
+ const displayName: string | undefined = nonEmpty(facetValue?.displayName);
327
+ if (!displayName || displayName === `${facetValue?.value ?? ""}`.trim()) {
328
+ return undefined;
329
+ }
330
+ return displayName;
331
+ };
332
+
333
+ /*
334
+ * What a sidebar facet row prints: the server's name, then the viewer's
335
+ * display map (preloaded resources + resolver names), then undefined so the
336
+ * row falls back to the raw value.
337
+ */
338
+ export const getFacetValueDisplayLabel: (
339
+ facetValue: FacetValue,
340
+ valueDisplayMap: Record<string, string> | undefined,
341
+ ) => string | undefined = (
342
+ facetValue: FacetValue,
343
+ valueDisplayMap: Record<string, string> | undefined,
344
+ ): string | undefined => {
345
+ return (
346
+ getServerFacetDisplayName(facetValue) ||
347
+ nonEmpty(valueDisplayMap?.[facetValue.value]) ||
348
+ undefined
349
+ );
350
+ };
351
+
352
+ const getFacetDisplayNames: (
353
+ facetData: FacetData | undefined,
354
+ facetKey: string,
355
+ ) => Record<string, string> = (
356
+ facetData: FacetData | undefined,
357
+ facetKey: string,
358
+ ): Record<string, string> => {
359
+ const map: Record<string, string> = {};
360
+ for (const facetValue of facetData?.[facetKey] || []) {
361
+ const displayName: string | undefined =
362
+ getServerFacetDisplayName(facetValue);
363
+ if (displayName) {
364
+ map[facetValue.value] = displayName;
365
+ }
366
+ }
367
+ return map;
368
+ };
369
+
370
+ /*
371
+ * Everything the viewer shows that can name an entity by id and that the
372
+ * preloaded maps / server / parent have not named yet, gathered into ONE
373
+ * resolver request:
374
+ * - resource chips (base + user), unless already named;
375
+ * - the primaryEntityId of every displayed log missing from the
376
+ * preloaded maps (hinted by the row's primaryEntityType when the row
377
+ * carries it);
378
+ * - primaryEntityId search suggestions without a server displayName;
379
+ * - resource facet values in the sidebar without a server displayName.
380
+ *
381
+ * A Service-keyed id (chip, log row, suggestion) found in a preloaded
382
+ * non-Service map is named from that map by enrichLogsActiveFilter /
383
+ * getLogEntityDisplay / resolvePrimaryEntitySuggestions, so it is not
384
+ * requested. The sidebar's primaryEntityId rows only read serviceMap and
385
+ * the resolver, so such an id is still requested there, but hinted to the
386
+ * table it was found in rather than probing Services and fanning out.
387
+ */
388
+ export const collectLogsEntityIdsToResolve: (data: {
389
+ filters?: Array<ActiveFilter> | undefined;
390
+ logs?: Array<Log> | undefined;
391
+ facetData?: FacetData | undefined;
392
+ suggestionIds?: Array<string> | undefined;
393
+ maps: LogsEntityLookupMaps;
394
+ }) => LogsEntityResolutionRequest = (data: {
395
+ filters?: Array<ActiveFilter> | undefined;
396
+ logs?: Array<Log> | undefined;
397
+ facetData?: FacetData | undefined;
398
+ suggestionIds?: Array<string> | undefined;
399
+ maps: LogsEntityLookupMaps;
400
+ }): LogsEntityResolutionRequest => {
401
+ const ids: Set<string> = new Set<string>();
402
+ const typeHints: Record<string, ServiceType> = {};
403
+
404
+ const add: (
405
+ facetKey: string,
406
+ rawId: unknown,
407
+ hint?: ServiceType | string | undefined,
408
+ loadedResourceIds?: "skip" | "hint" | undefined,
409
+ ) => void = (
410
+ facetKey: string,
411
+ rawId: unknown,
412
+ hint?: ServiceType | string | undefined,
413
+ loadedResourceIds?: "skip" | "hint" | undefined,
414
+ ): void => {
415
+ if (!isLogsEntityIdValue(rawId)) {
416
+ return;
417
+ }
418
+ const id: string = rawId.trim();
419
+ if (getLoadedLogsEntityName(facetKey, id, data.maps)) {
420
+ return;
421
+ }
422
+ const loadedResource: LoadedLogsResourceEntity | undefined =
423
+ isServiceFacetKey(facetKey)
424
+ ? findLoadedLogsResourceEntity(id, data.maps)
425
+ : undefined;
426
+ // Default "skip": the caller names it from the preloaded map.
427
+ if (loadedResource && loadedResourceIds !== "hint") {
428
+ return;
429
+ }
430
+ ids.add(id);
431
+ const typeHint: ServiceType | undefined =
432
+ LOGS_RESOURCE_FACET_ENTITY_TYPES[facetKey] ||
433
+ loadedResource?.entityType ||
434
+ (hint &&
435
+ Object.prototype.hasOwnProperty.call(TELEMETRY_ENTITY_TYPES, `${hint}`)
436
+ ? (`${hint}` as ServiceType)
437
+ : undefined);
438
+ if (typeHint && !typeHints[id]) {
439
+ typeHints[id] = typeHint;
440
+ }
441
+ };
442
+
443
+ for (const filter of data.filters || []) {
444
+ if (!isResourceFacetKey(filter.facetKey)) {
445
+ continue;
446
+ }
447
+ if (hasParentResolvedDisplay(filter)) {
448
+ continue;
449
+ }
450
+ add(
451
+ filter.facetKey,
452
+ filter.value,
453
+ getTelemetryEntityTypeForChipKey(filter.displayKey),
454
+ );
455
+ }
456
+
457
+ for (const log of data.logs || []) {
458
+ add(
459
+ "primaryEntityId",
460
+ log.primaryEntityId?.toString(),
461
+ log.primaryEntityType,
462
+ );
463
+ }
464
+
465
+ const serviceFacetDisplayNames: Record<string, string> = getFacetDisplayNames(
466
+ data.facetData,
467
+ "primaryEntityId",
468
+ );
469
+ for (const id of data.suggestionIds || []) {
470
+ if (serviceFacetDisplayNames[id]) {
471
+ continue;
472
+ }
473
+ add("primaryEntityId", id);
474
+ }
475
+
476
+ for (const [facetKey, values] of Object.entries(data.facetData || {})) {
477
+ if (!isResourceFacetKey(facetKey)) {
478
+ continue;
479
+ }
480
+ for (const facetValue of values || []) {
481
+ if (getServerFacetDisplayName(facetValue)) {
482
+ continue;
483
+ }
484
+ add(facetKey, facetValue.value, undefined, "hint");
485
+ }
486
+ }
487
+
488
+ return {
489
+ ids: Array.from(ids).sort(),
490
+ typeHints,
491
+ };
492
+ };
493
+
494
+ export interface LogEntityDisplay {
495
+ // Name to render; undefined when nothing (not even an id) is known.
496
+ name: string | undefined;
497
+ // A real Service's colour; undefined for other entities.
498
+ color: string | undefined;
499
+ /*
500
+ * Type label when the entity was named by the generic resolver (e.g.
501
+ * "RUM Application") or a preloaded host / cluster map (e.g. "Host");
502
+ * undefined for preloaded Services.
503
+ */
504
+ typeLabel: string | undefined;
505
+ }
506
+
507
+ /*
508
+ * What a log row / details header shows for the log's primary entity:
509
+ * a preloaded Service (name + colour) first, then a preloaded host /
510
+ * cluster (agent-ingested telemetry is primary-keyed on it, and those ids
511
+ * are not sent to the resolver), then the generic resolver's name, then the
512
+ * raw id so the row is never blank.
513
+ */
514
+ export const getLogEntityDisplay: (data: {
515
+ primaryEntityId: string | undefined;
516
+ serviceMap: Dictionary<Service>;
517
+ resourceMaps?: LogsResourceEntityMaps | undefined;
518
+ entityNameMap?: TelemetryEntityNameMap | undefined;
519
+ }) => LogEntityDisplay = (data: {
520
+ primaryEntityId: string | undefined;
521
+ serviceMap: Dictionary<Service>;
522
+ resourceMaps?: LogsResourceEntityMaps | undefined;
523
+ entityNameMap?: TelemetryEntityNameMap | undefined;
524
+ }): LogEntityDisplay => {
525
+ const id: string = data.primaryEntityId || "";
526
+ const service: Service | undefined = id ? data.serviceMap[id] : undefined;
527
+ const serviceName: string | undefined = nonEmpty(service?.name);
528
+ const color: string | undefined = service?.serviceColor
529
+ ? service.serviceColor.toString()
530
+ : undefined;
531
+
532
+ if (serviceName) {
533
+ return { name: serviceName, color, typeLabel: undefined };
534
+ }
535
+
536
+ const loadedResource: LoadedLogsResourceEntity | undefined =
537
+ findLoadedLogsResourceEntity(id, data.resourceMaps);
538
+ if (loadedResource) {
539
+ return {
540
+ name: loadedResource.name,
541
+ color,
542
+ typeLabel: loadedResource.typeLabel,
543
+ };
544
+ }
545
+
546
+ const resolved: ResolvedTelemetryEntity | undefined = id
547
+ ? data.entityNameMap?.[id]
548
+ : undefined;
549
+ if (resolved) {
550
+ return { name: resolved.name, color, typeLabel: resolved.typeLabel };
551
+ }
552
+
553
+ return { name: id || undefined, color, typeLabel: undefined };
554
+ };
555
+
556
+ // id -> name for every entity the resolver named.
557
+ export const buildEntityNameDisplayMap: (
558
+ entityNameMap: TelemetryEntityNameMap | undefined,
559
+ ) => Record<string, string> = (
560
+ entityNameMap: TelemetryEntityNameMap | undefined,
561
+ ): Record<string, string> => {
562
+ const map: Record<string, string> = {};
563
+ for (const [id, entity] of Object.entries(entityNameMap || {})) {
564
+ if (entity?.name) {
565
+ map[id] = entity.name;
566
+ }
567
+ }
568
+ return map;
569
+ };
570
+
571
+ /*
572
+ * Sidebar facet row labels: resolver names underneath, the preloaded map on
573
+ * top (server displayName still wins inside FacetSection).
574
+ */
575
+ export const mergeFacetValueDisplayMap: (
576
+ loadedDisplayMap: Record<string, string> | undefined,
577
+ entityNameMap: TelemetryEntityNameMap | undefined,
578
+ ) => Record<string, string> = (
579
+ loadedDisplayMap: Record<string, string> | undefined,
580
+ entityNameMap: TelemetryEntityNameMap | undefined,
581
+ ): Record<string, string> => {
582
+ return {
583
+ ...buildEntityNameDisplayMap(entityNameMap),
584
+ ...(loadedDisplayMap || {}),
585
+ };
586
+ };
587
+
588
+ export interface PrimaryEntitySuggestions {
589
+ /*
590
+ * Labels shown in the search bar dropdown, one per distinct id, in input
591
+ * order. No two are equal, even ignoring case.
592
+ */
593
+ labels: Array<string>;
594
+ /*
595
+ * Lower-cased label -> id for every label, to turn a picked label back
596
+ * into the filter id.
597
+ */
598
+ labelToId: Record<string, string>;
599
+ }
600
+
601
+ interface PrimaryEntitySuggestionCandidate {
602
+ id: string;
603
+ name: string;
604
+ typeLabel: string | undefined;
605
+ }
606
+
607
+ /*
608
+ * The `service:` value dropdown lists primaryEntityId ids. Show names —
609
+ * server facet displayName first (it covers every entity type), then the
610
+ * preloaded Service, then a preloaded host / cluster, then the generic
611
+ * resolver, then the id — and remember how to map the picked label back
612
+ * to the id the filter needs.
613
+ *
614
+ * The filter needs the id, and picking is by label, so every label must
615
+ * name exactly one id. Names are not unique across entity types (a Service
616
+ * and a RUM application can both be "checkout") or across case, and a
617
+ * shared label used to silently filter by whichever id came first. Every
618
+ * entity in a case-insensitive name clash is shown as "name (Type)"; if
619
+ * that is still ambiguous (same type) or the type is unknown, the id itself
620
+ * is shown. A plain typed "checkout" then misses the suggestions and falls
621
+ * back to the preloaded Service scan, as before.
622
+ */
623
+ export const resolvePrimaryEntitySuggestions: (data: {
624
+ ids: Array<string>;
625
+ facetValues?: Array<FacetValue> | undefined;
626
+ serviceMap: Dictionary<Service>;
627
+ resourceMaps?: LogsResourceEntityMaps | undefined;
628
+ entityNameMap?: TelemetryEntityNameMap | undefined;
629
+ }) => PrimaryEntitySuggestions = (data: {
630
+ ids: Array<string>;
631
+ facetValues?: Array<FacetValue> | undefined;
632
+ serviceMap: Dictionary<Service>;
633
+ resourceMaps?: LogsResourceEntityMaps | undefined;
634
+ entityNameMap?: TelemetryEntityNameMap | undefined;
635
+ }): PrimaryEntitySuggestions => {
636
+ const displayNames: Record<string, string> = getFacetDisplayNames(
637
+ { primaryEntityId: data.facetValues || [] },
638
+ "primaryEntityId",
639
+ );
640
+
641
+ const candidates: Array<PrimaryEntitySuggestionCandidate> = [];
642
+ const seenIds: Set<string> = new Set<string>();
643
+ for (const id of data.ids) {
644
+ if (!id || seenIds.has(id)) {
645
+ continue;
646
+ }
647
+ seenIds.add(id);
648
+
649
+ const serviceName: string | undefined = nonEmpty(data.serviceMap[id]?.name);
650
+ const loadedResource: LoadedLogsResourceEntity | undefined = serviceName
651
+ ? undefined
652
+ : findLoadedLogsResourceEntity(id, data.resourceMaps);
653
+ const resolved: ResolvedTelemetryEntity | undefined =
654
+ data.entityNameMap?.[id];
655
+
656
+ candidates.push({
657
+ id,
658
+ name:
659
+ displayNames[id] ||
660
+ serviceName ||
661
+ loadedResource?.name ||
662
+ nonEmpty(resolved?.name) ||
663
+ id,
664
+ typeLabel: serviceName
665
+ ? TELEMETRY_ENTITY_TYPES[ServiceType.OpenTelemetry].label
666
+ : loadedResource?.typeLabel || nonEmpty(resolved?.typeLabel),
667
+ });
668
+ }
669
+
670
+ const countByLower: (values: Array<string>) => Map<string, number> = (
671
+ values: Array<string>,
672
+ ): Map<string, number> => {
673
+ const counts: Map<string, number> = new Map<string, number>();
674
+ for (const value of values) {
675
+ const lower: string = value.toLowerCase();
676
+ counts.set(lower, (counts.get(lower) || 0) + 1);
677
+ }
678
+ return counts;
679
+ };
680
+
681
+ const nameCounts: Map<string, number> = countByLower(
682
+ candidates.map((candidate: PrimaryEntitySuggestionCandidate): string => {
683
+ return candidate.name;
684
+ }),
685
+ );
686
+ const isClashing: (candidate: PrimaryEntitySuggestionCandidate) => boolean = (
687
+ candidate: PrimaryEntitySuggestionCandidate,
688
+ ): boolean => {
689
+ // An unnamed id is its own label and ids are unique.
690
+ return (
691
+ candidate.name !== candidate.id &&
692
+ (nameCounts.get(candidate.name.toLowerCase()) || 0) > 1
693
+ );
694
+ };
695
+
696
+ /*
697
+ * Labels that need no qualifying are reserved first, so "checkout
698
+ * (Service)" made up for a clash never takes the label of an entity that
699
+ * is really called that.
700
+ */
701
+ const reserved: Set<string> = new Set<string>();
702
+ for (const candidate of candidates) {
703
+ if (!isClashing(candidate)) {
704
+ reserved.add(candidate.name.toLowerCase());
705
+ }
706
+ }
707
+
708
+ const qualifiedLabelFor: (
709
+ candidate: PrimaryEntitySuggestionCandidate,
710
+ ) => string | undefined = (
711
+ candidate: PrimaryEntitySuggestionCandidate,
712
+ ): string | undefined => {
713
+ return candidate.typeLabel
714
+ ? `${candidate.name} (${candidate.typeLabel})`
715
+ : undefined;
716
+ };
717
+
718
+ const qualifiedCounts: Map<string, number> = countByLower(
719
+ candidates
720
+ .filter(isClashing)
721
+ .map((candidate: PrimaryEntitySuggestionCandidate): string => {
722
+ return qualifiedLabelFor(candidate) || candidate.id;
723
+ }),
724
+ );
725
+
726
+ const labels: Array<string> = [];
727
+ const labelToId: Record<string, string> = {};
728
+ for (const candidate of candidates) {
729
+ let label: string = candidate.name;
730
+
731
+ if (isClashing(candidate)) {
732
+ const qualified: string | undefined = qualifiedLabelFor(candidate);
733
+ const lowerQualified: string = (qualified || "").toLowerCase();
734
+ label =
735
+ qualified &&
736
+ !reserved.has(lowerQualified) &&
737
+ (qualifiedCounts.get(lowerQualified) || 0) === 1
738
+ ? qualified
739
+ : candidate.id;
740
+ }
741
+
742
+ labels.push(label);
743
+ labelToId[label.toLowerCase()] = candidate.id;
744
+ }
745
+
746
+ return { labels, labelToId };
747
+ };
748
+
749
+ /*
750
+ * ---- Analytics view ----
751
+ *
752
+ * Group-by values for an entity dimension (primaryEntityId, or a typed
753
+ * resource id key) are ids; the chart keeps them as series keys (two
754
+ * entities with the same name must stay two series) and only the labels
755
+ * change.
756
+ */
757
+
758
+ export const ANALYTICS_DIMENSION_LABELS: Record<string, string> = {
759
+ severityText: "Severity",
760
+ primaryEntityId: "Service",
761
+ serviceId: "Service",
762
+ ...getResourceFacetLabelMap(),
763
+ traceId: "Trace ID",
764
+ spanId: "Span ID",
765
+ };
766
+
767
+ export const isAnalyticsEntityDimension: (key: string) => boolean = (
768
+ key: string,
769
+ ): boolean => {
770
+ return isResourceFacetKey(key);
771
+ };
772
+
773
+ export interface AnalyticsGroupedRow {
774
+ groupValues: Record<string, string>;
775
+ }
776
+
777
+ export interface AnalyticsTopListValue {
778
+ value: string;
779
+ }
780
+
781
+ /*
782
+ * Ids to name for the analytics result on screen.
783
+ *
784
+ * Grouped rows (timeseries / table) are read by their own groupValues keys
785
+ * — the same keys the legend and table cells label them by. The group-by
786
+ * of the last fetch is not a safe guide: it belongs to whichever chart type
787
+ * fetched last, so after switching chart type the leftover rows of the
788
+ * other type (grouped differently) had their ids dropped from the request
789
+ * and their names fell back to UUIDs until the refetch landed.
790
+ *
791
+ * A top list item carries only a value, so it is read against
792
+ * `groupByFields[0]`, the dimension its label is rendered with.
793
+ */
794
+ export const collectAnalyticsEntityIds: (data: {
795
+ groupByFields: Array<string>;
796
+ groupedRows?: Array<AnalyticsGroupedRow> | undefined;
797
+ topListItems?: Array<AnalyticsTopListValue> | undefined;
798
+ }) => LogsEntityResolutionRequest = (data: {
799
+ groupByFields: Array<string>;
800
+ groupedRows?: Array<AnalyticsGroupedRow> | undefined;
801
+ topListItems?: Array<AnalyticsTopListValue> | undefined;
802
+ }): LogsEntityResolutionRequest => {
803
+ const ids: Set<string> = new Set<string>();
804
+ const typeHints: Record<string, ServiceType> = {};
805
+
806
+ const add: (key: string, value: unknown) => void = (
807
+ key: string,
808
+ value: unknown,
809
+ ): void => {
810
+ if (!isAnalyticsEntityDimension(key) || !isLogsEntityIdValue(value)) {
811
+ return;
812
+ }
813
+ const id: string = value.trim();
814
+ ids.add(id);
815
+ const hint: ServiceType | undefined = LOGS_RESOURCE_FACET_ENTITY_TYPES[key];
816
+ if (hint && !typeHints[id]) {
817
+ typeHints[id] = hint;
818
+ }
819
+ };
820
+
821
+ for (const row of data.groupedRows || []) {
822
+ for (const [key, value] of Object.entries(row?.groupValues || {})) {
823
+ add(key, value);
824
+ }
825
+ }
826
+
827
+ const topListKey: string | undefined = data.groupByFields[0];
828
+ if (topListKey) {
829
+ for (const item of data.topListItems || []) {
830
+ add(topListKey, item.value);
831
+ }
832
+ }
833
+
834
+ return { ids: Array.from(ids).sort(), typeHints };
835
+ };
836
+
837
+ // Label for one group-by value: the entity name for entity dimensions.
838
+ export const getAnalyticsGroupValueLabel: (
839
+ key: string | undefined,
840
+ value: string,
841
+ entityNameMap: TelemetryEntityNameMap | undefined,
842
+ ) => string = (
843
+ key: string | undefined,
844
+ value: string,
845
+ entityNameMap: TelemetryEntityNameMap | undefined,
846
+ ): string => {
847
+ if (!key || !isAnalyticsEntityDimension(key) || !value) {
848
+ return value;
849
+ }
850
+ return entityNameMap?.[value]?.name || value;
851
+ };
852
+
853
+ /*
854
+ * Column header for a group-by dimension. Entity dimensions use the type of
855
+ * the values when they all resolved to the same one (a RUM application's
856
+ * logs grouped by entity read "RUM Application"); a mixed or unresolved set
857
+ * keeps the generic label. Other known dimensions get their friendly label;
858
+ * attribute keys stay as typed.
859
+ */
860
+ export const getAnalyticsDimensionLabel: (
861
+ key: string,
862
+ values: Array<string>,
863
+ entityNameMap: TelemetryEntityNameMap | undefined,
864
+ ) => string = (
865
+ key: string,
866
+ values: Array<string>,
867
+ entityNameMap: TelemetryEntityNameMap | undefined,
868
+ ): string => {
869
+ const fallback: string = ANALYTICS_DIMENSION_LABELS[key] || key;
870
+
871
+ if (!isAnalyticsEntityDimension(key) || isResourceEntityFacetKey(key)) {
872
+ return fallback;
873
+ }
874
+
875
+ const nonEmptyValues: Array<string> = values.filter((value: string) => {
876
+ return Boolean(value);
877
+ });
878
+ if (nonEmptyValues.length === 0) {
879
+ return fallback;
880
+ }
881
+
882
+ const labels: Set<string> = new Set<string>();
883
+ for (const value of nonEmptyValues) {
884
+ const resolved: ResolvedTelemetryEntity | undefined =
885
+ entityNameMap?.[value];
886
+ if (!resolved) {
887
+ return fallback;
888
+ }
889
+ labels.add(resolved.typeLabel);
890
+ }
891
+
892
+ return labels.size === 1 ? Array.from(labels)[0]! : fallback;
893
+ };
894
+
895
+ /*
896
+ * Legend / tooltip label for a timeseries series. The series key joins the
897
+ * row's group values with " / " (see pivotTimeseriesData); the label joins
898
+ * the same values after naming them.
899
+ */
900
+ export const getAnalyticsSeriesLabel: (
901
+ groupValues: Record<string, string>,
902
+ entityNameMap: TelemetryEntityNameMap | undefined,
903
+ ) => string = (
904
+ groupValues: Record<string, string>,
905
+ entityNameMap: TelemetryEntityNameMap | undefined,
906
+ ): string => {
907
+ return Object.entries(groupValues)
908
+ .map(([key, value]: [string, string]): string => {
909
+ return getAnalyticsGroupValueLabel(key, value, entityNameMap);
910
+ })
911
+ .join(" / ");
912
+ };