@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.
- package/Models/DatabaseModels/Index.ts +4 -0
- package/Models/DatabaseModels/RumApplication.ts +1 -1
- package/Models/DatabaseModels/SecurityEventConnection.ts +457 -0
- package/Models/DatabaseModels/SecurityEventConnectionRun.ts +263 -0
- package/Models/DatabaseModels/TelemetryIngestionKey.ts +2 -2
- package/Server/API/AIInvestigationAPI.ts +484 -24
- package/Server/API/GoogleSecOpsConnectionAPI.ts +249 -8
- package/Server/API/SecurityEventConnectionAPI.ts +250 -0
- package/Server/API/TelemetryAPI.ts +402 -265
- package/Server/Infrastructure/Postgres/SchemaMigrations/1792700000000-AddSecurityEventConnections.ts +99 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
- package/Server/Middleware/TelemetryIngest.ts +101 -6
- package/Server/Services/ExceptionAggregationService.ts +7 -16
- package/Server/Services/GoogleSecOpsConnectionService.ts +15 -0
- package/Server/Services/Index.ts +4 -0
- package/Server/Services/InventoryItemService.ts +28 -0
- package/Server/Services/LogAggregationService.ts +17 -23
- package/Server/Services/MetricAggregationService.ts +4 -14
- package/Server/Services/SecurityEventConnectionRunService.ts +10 -0
- package/Server/Services/SecurityEventConnectionService.ts +538 -0
- package/Server/Services/TraceAggregationService.ts +77 -28
- package/Server/Types/AnalyticsDatabase/ModelPermission.ts +9 -0
- package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +13 -1
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +15 -1
- package/Server/Utils/AI/SRE/InvestigationEvidence.ts +658 -0
- package/Server/Utils/AI/SRE/InvestigationReferences.ts +324 -0
- package/Server/Utils/AI/Toolbox/Index.ts +38 -0
- package/Server/Utils/AI/Toolbox/TimelineTools.ts +9 -2
- package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +80 -0
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +5 -3
- package/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.ts +1108 -0
- package/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubConnector.ts +732 -0
- package/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.ts +495 -0
- package/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconClient.ts +689 -0
- package/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconConnector.ts +767 -0
- package/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityClient.ts +571 -0
- package/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityConnector.ts +827 -0
- package/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrClient.ts +610 -0
- package/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrConnector.ts +549 -0
- package/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelClient.ts +830 -0
- package/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelConnector.ts +684 -0
- package/Server/Utils/SecurityEvent/Connectors/Okta/OktaClient.ts +487 -0
- package/Server/Utils/SecurityEvent/Connectors/Okta/OktaConnector.ts +778 -0
- package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.ts +1002 -0
- package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.ts +556 -0
- package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.ts +275 -0
- package/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry.ts +53 -0
- package/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkClient.ts +709 -0
- package/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkConnector.ts +596 -0
- package/Server/Utils/SecurityEvent/Connectors/Types.ts +191 -0
- package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.ts +353 -65
- package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsConnectionTester.ts +777 -0
- package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.ts +747 -148
- package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.ts +48 -2
- package/Server/Utils/SecurityEvent/SecurityEventDedupe.ts +81 -0
- package/Server/Utils/SessionReplay/SessionReplayReadService.ts +741 -40
- package/Server/Utils/StartServer.ts +10 -0
- package/Server/Utils/Telemetry/EntityRegistry.ts +8 -0
- package/Server/Utils/Telemetry/KubernetesResourceAttributes.ts +108 -0
- package/Server/Utils/Telemetry/ResourceEntityFilter.ts +174 -93
- package/Server/Utils/Telemetry/ResourceFacetPlanner.ts +251 -0
- package/Server/Utils/Telemetry/ResourceFacetResolver.ts +248 -413
- package/Server/Utils/Telemetry/ServiceDependencyDiscovery.ts +668 -0
- package/Server/Utils/Telemetry/TraceContextPropagation.ts +348 -0
- package/Server/Utils/Telemetry.ts +18 -0
- package/Tests/App/Dashboard/AIInvestigationHeaderStatus.test.tsx +413 -0
- package/Tests/App/Dashboard/AIRootCauseFeedItem.test.tsx +285 -0
- package/Tests/App/Dashboard/AffectedResourcesDisplay.test.tsx +242 -0
- package/Tests/App/Dashboard/AlertEpisodeViewFields.test.tsx +601 -15
- package/Tests/App/Dashboard/ChangeAlertStateAIHeader.test.tsx +835 -0
- package/Tests/App/Dashboard/CloudResourceTelemetryScope.test.ts +41 -0
- package/Tests/App/Dashboard/ConnectionTestModal.test.tsx +604 -0
- package/Tests/App/Dashboard/ConnectorTestReportView.test.tsx +738 -0
- package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +153 -6
- package/Tests/App/Dashboard/EntityDetailPanel.test.tsx +165 -0
- package/Tests/App/Dashboard/EpisodeChangeState.test.tsx +1069 -0
- package/Tests/App/Dashboard/EpisodeMembersCard.test.tsx +772 -0
- package/Tests/App/Dashboard/EventOverviewPages.test.tsx +2354 -0
- package/Tests/App/Dashboard/EventOverviewSkeleton.test.tsx +210 -0
- package/Tests/App/Dashboard/EventStatBar.test.tsx +392 -0
- package/Tests/App/Dashboard/EventStatusPanel.test.tsx +247 -0
- package/Tests/App/Dashboard/ExceptionAIAssistance.test.tsx +606 -0
- package/Tests/App/Dashboard/ExceptionBreadcrumbTimeline.test.tsx +273 -0
- package/Tests/App/Dashboard/ExceptionDetailSideMenu.test.tsx +176 -0
- package/Tests/App/Dashboard/ExceptionOverviewCards.test.tsx +366 -0
- package/Tests/App/Dashboard/ExceptionSignalPages.test.tsx +371 -0
- package/Tests/App/Dashboard/ExceptionStackFrameViewer.test.tsx +440 -0
- package/Tests/App/Dashboard/ExceptionSummary.test.tsx +381 -0
- package/Tests/App/Dashboard/ExceptionTriage.test.tsx +306 -0
- package/Tests/App/Dashboard/ExceptionsResourceFacets.test.tsx +604 -0
- package/Tests/App/Dashboard/ExceptionsViewerEntityChips.test.tsx +706 -0
- package/Tests/App/Dashboard/FeedOrdering.test.ts +32 -0
- package/Tests/App/Dashboard/GoogleSecOpsConnectionForm.test.tsx +838 -0
- package/Tests/App/Dashboard/GoogleSecOpsConnectionsErrors.test.tsx +18 -0
- package/Tests/App/Dashboard/GoogleSecOpsDiagnostics.test.tsx +297 -20
- package/Tests/App/Dashboard/IncidentEpisodeViewFields.test.tsx +618 -13
- package/Tests/App/Dashboard/InfrastructureExplorer.test.tsx +254 -207
- package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +303 -135
- package/Tests/App/Dashboard/InvestigationEvidenceList.test.tsx +1251 -0
- package/Tests/App/Dashboard/InvestigationFeedRefresh.test.tsx +303 -0
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +876 -8
- package/Tests/App/Dashboard/InvestigationPanelStatus.test.tsx +35 -0
- package/Tests/App/Dashboard/InvestigationReferenceLink.test.tsx +177 -0
- package/Tests/App/Dashboard/InvestigationReportView.test.tsx +1295 -0
- package/Tests/App/Dashboard/KubernetesImageReferenceView.test.tsx +114 -0
- package/Tests/App/Dashboard/KubernetesLogsTabChips.test.tsx +285 -0
- package/Tests/App/Dashboard/LogsEntityChipNames.test.tsx +316 -0
- package/Tests/App/Dashboard/LogsResourceFacetChips.test.tsx +361 -0
- package/Tests/App/Dashboard/ProfileTableEntityNames.test.tsx +432 -0
- package/Tests/App/Dashboard/ProfileViewEntityName.test.tsx +250 -0
- package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +10 -0
- package/Tests/App/Dashboard/ResourceLogsTabsBareLayout.test.tsx +700 -0
- package/Tests/App/Dashboard/ResourcePageEntityNameProps.test.tsx +803 -0
- package/Tests/App/Dashboard/RumSessionReplaySideMenu.test.tsx +11 -1
- package/Tests/App/Dashboard/ScheduledMaintenanceChangeState.test.tsx +1026 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceFeedRefresh.test.tsx +436 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +1195 -0
- package/Tests/App/Dashboard/SecurityEventConnectionFormModal.test.tsx +1022 -0
- package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +905 -0
- package/Tests/App/Dashboard/SecurityEventsSideMenu.test.tsx +247 -0
- package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +375 -274
- package/Tests/App/Dashboard/SessionReplayAuditTable.test.tsx +410 -0
- package/Tests/App/Dashboard/TelemetryResourceRetentionSettings.test.tsx +774 -0
- package/Tests/App/Dashboard/TopErrorsPanelResourceNames.test.tsx +316 -0
- package/Tests/App/Dashboard/TopologyDataLoading.test.tsx +30 -0
- package/Tests/App/Dashboard/TopologyPageNavigation.test.tsx +88 -24
- package/Tests/App/Dashboard/TraceExplorer.test.tsx +1590 -0
- package/Tests/App/Dashboard/TraceWaterfall.test.tsx +488 -0
- package/Tests/App/Dashboard/TracesAnalyticsSeriesLabels.test.tsx +367 -0
- package/Tests/App/Dashboard/TracesEntityNames.test.tsx +585 -0
- package/Tests/App/Dashboard/TracesResourceFacets.test.tsx +613 -0
- package/Tests/App/Dashboard/UseServiceNames.test.tsx +359 -0
- package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +7 -0
- package/Tests/Models/InventoryItemNaming.test.ts +132 -16
- package/Tests/Models/SecurityDomainAccessControl.test.ts +61 -17
- package/Tests/Server/API/AIInvestigationAPI.test.ts +611 -2
- package/Tests/Server/API/AIInvestigationEvidenceAPI.test.ts +1098 -0
- package/Tests/Server/API/GoogleSecOpsConnectionAPI.test.ts +409 -0
- package/Tests/Server/API/SecurityEventConnectionAPI.test.ts +856 -0
- package/Tests/Server/API/SessionReplayAPI.test.ts +528 -1
- package/Tests/Server/API/TelemetryFacetsAPI.test.ts +810 -0
- package/Tests/Server/Infrastructure/E2EClickHouseFixtureAccess.test.ts +240 -0
- package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +229 -0
- package/Tests/Server/Services/InventoryItemDisplayName.test.ts +66 -0
- package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +28 -1
- package/Tests/Server/Services/SecurityEventConnectionService.test.ts +1233 -0
- package/Tests/Server/Services/TelemetryIngestionKeyValidation.test.ts +53 -0
- package/Tests/Server/Services/TelemetryResourceFacetCounting.test.ts +218 -0
- package/Tests/Server/Services/TelemetryResourceFacetFilters.test.ts +155 -1
- package/Tests/Server/Services/TraceAggregationExceptionScope.test.ts +142 -0
- package/Tests/Server/Services/TraceAnalyticsResourceDisplayNames.test.ts +85 -24
- package/Tests/Server/Types/Database/Permissions/SecurityRoleAccess.test.ts +33 -0
- package/Tests/Server/Utils/AI/InvestigationEvidence.test.ts +1395 -0
- package/Tests/Server/Utils/AI/InvestigationReferences.test.ts +616 -0
- package/Tests/Server/Utils/AI/TimelineTools.test.ts +119 -0
- package/Tests/Server/Utils/AI/Toolbox/AIToolbox.test.ts +151 -0
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +65 -0
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGeneratorExceptionScope.test.ts +224 -0
- package/Tests/Server/Utils/LoggerCore.test.ts +597 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPerSeriesFanout.test.ts +55 -2
- package/Tests/Server/Utils/Monitor/MonitorTemplateUtil.test.ts +1109 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.test.ts +1240 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubConnector.test.ts +1853 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.test.ts +1129 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconClient.test.ts +1066 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconConnector.test.ts +1568 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityClient.test.ts +930 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityConnector.test.ts +1409 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrClient.test.ts +763 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrConnector.test.ts +1296 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelClient.test.ts +1102 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelConnector.test.ts +1174 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/Okta/OktaClient.test.ts +1032 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/Okta/OktaConnector.test.ts +1558 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.test.ts +3041 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.test.ts +1168 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.test.ts +906 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkClient.test.ts +1068 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkConnector.test.ts +1004 -0
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsConnectionTester.test.ts +784 -0
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.test.ts +113 -1
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsClient.test.ts +5 -1
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsDiagnostics.test.ts +93 -13
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsHttpIntegration.test.ts +23 -1
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPoller.test.ts +25 -3
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerFailureTaxonomy.test.ts +22 -8
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerHardening.test.ts +82 -16
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsSearchDetections.test.ts +730 -0
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsThreePassPoller.test.ts +1577 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayOriginAllowlist.test.ts +41 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +1453 -18
- package/Tests/Server/Utils/Telemetry/EntityRegistry.test.ts +711 -0
- package/Tests/Server/Utils/Telemetry/KubernetesResourceAttributes.test.ts +162 -0
- package/Tests/Server/Utils/Telemetry/ResourceEntityFilter.test.ts +460 -13
- package/Tests/Server/Utils/Telemetry/ResourceFacetPlanner.test.ts +678 -0
- package/Tests/Server/Utils/Telemetry/ResourceFacetResolver.test.ts +868 -0
- package/Tests/Server/Utils/Telemetry/ServiceDependencyDiscovery.test.ts +525 -0
- package/Tests/Server/Utils/Telemetry/TraceContextPropagation.test.ts +420 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilCorePaths.test.ts +1014 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveRotation.test.ts +9 -6
- package/Tests/Types/Rules/RuleCriteriaFieldRegistry.test.ts +276 -0
- package/Tests/Types/Rum/SessionReplayApiContracts.test.ts +73 -0
- package/Tests/Types/Rum/SessionReplayTransportContracts.test.ts +95 -0
- package/Tests/Types/SecurityEvent/Connectors/ConnectorDiagnostics.test.ts +82 -0
- package/Tests/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.test.ts +314 -0
- package/Tests/Types/Telemetry/ExceptionSpanScope.test.ts +89 -0
- package/Tests/Types/Telemetry/LlmConventions.test.ts +495 -0
- package/Tests/Types/Telemetry/ResourceEntityFacet.test.ts +96 -0
- package/Tests/Types/Telemetry/ResourceFacetCatalog.test.ts +304 -0
- package/Tests/UI/Components/ActiveFilterChipsLockedFilters.test.tsx +357 -0
- package/Tests/UI/Components/Card.test.tsx +312 -1
- package/Tests/UI/Components/CardModelDetailHeaderLayout.test.tsx +253 -0
- package/Tests/UI/Components/CardModelDetailRefresher.test.tsx +342 -0
- package/Tests/UI/Components/Checkbox.test.tsx +79 -0
- package/Tests/UI/Components/CopyTextButton.test.tsx +142 -0
- package/Tests/UI/Components/DetailCompactStyle.test.tsx +621 -0
- package/Tests/UI/Components/ErrorBoundary.test.tsx +60 -0
- package/Tests/UI/Components/FacetSections.test.tsx +581 -0
- package/Tests/UI/Components/FacetSidebarControls.test.tsx +812 -0
- package/Tests/UI/Components/FacetVisibility.test.ts +429 -0
- package/Tests/UI/Components/LockedFilterActions.test.tsx +396 -0
- package/Tests/UI/Components/LockedFilterChip.test.tsx +651 -0
- package/Tests/UI/Components/LogsEntityNames.test.ts +1769 -0
- package/Tests/UI/Components/LogsEntityNamesComponents.test.tsx +696 -0
- package/Tests/UI/Components/LogsFacetSidebarHiddenFacets.test.tsx +600 -0
- package/Tests/UI/Components/LogsViewerEntityNames.test.tsx +713 -0
- package/Tests/UI/Components/MarkdownInlineReferences.test.tsx +2079 -0
- package/Tests/UI/Components/MemberRoleAssignment.test.tsx +446 -0
- package/Tests/UI/Components/ModelDetailRefetch.test.tsx +397 -0
- package/Tests/UI/Components/ModelListRefetch.test.tsx +233 -0
- package/Tests/UI/Components/ModelPageModelChange.test.tsx +409 -0
- package/Tests/UI/Components/PaginationIntegration.test.tsx +25 -0
- package/Tests/UI/Components/ResourceFacetConfigs.test.ts +172 -0
- package/Tests/UI/Components/SavedViewsSidebarIntegration.test.tsx +32 -14
- package/Tests/UI/Components/TableSortAndMobileColumns.test.tsx +44 -1
- package/Tests/UI/Components/TelemetryActiveFilterChipsLockedFilters.test.tsx +304 -0
- package/Tests/UI/Components/TelemetryFacetSidebarHiddenFacets.test.tsx +718 -0
- package/Tests/UI/Monitor/EvaluationLogList.test.tsx +303 -0
- package/Tests/UI/Monitor/MonitorSummarySnapshotRender.test.tsx +55 -1
- package/Tests/UI/Rum/FidelityNotices.test.ts +22 -0
- package/Tests/UI/Rum/RecordingHealthCard.test.tsx +120 -136
- package/Tests/UI/Rum/RecordingHealthDashboard.test.tsx +988 -0
- package/Tests/UI/Rum/ReplayCard.test.tsx +32 -0
- package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +709 -12
- package/Tests/UI/Rum/ReplayHeader.test.tsx +50 -1
- package/Tests/UI/Rum/ReplayPinControl.test.tsx +67 -10
- package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +41 -12
- package/Tests/UI/Rum/ReplayStage.test.tsx +663 -1
- package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +173 -0
- package/Tests/UI/Rum/ReplayUi.test.tsx +189 -2
- package/Tests/UI/Rum/ReplayUserSessionsMenu.test.tsx +91 -0
- package/Tests/UI/Rum/SessionReplayEmptyState.test.tsx +1 -1
- package/Tests/UI/Rum/SessionReplaySettingsPolicyLoading.test.tsx +585 -0
- package/Tests/UI/Rum/SessionReplayTable.test.tsx +844 -51
- package/Tests/UI/Rum/SessionReplayUsersTable.test.tsx +29 -1
- package/Tests/UI/Telemetry/TelemetryDetailPanel.test.tsx +288 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +31 -1
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +6 -0
- package/Tests/UI/Utils/Clipboard.test.ts +154 -0
- package/Tests/UI/Utils/Navigation.test.ts +24 -0
- package/Tests/UI/Utils/Telemetry/TelemetryEntityNames.test.ts +2205 -0
- package/Tests/UI/Utils/Telemetry/UseTelemetryEntityNames.test.tsx +844 -0
- package/Tests/Utils/AI/InvestigationReport.test.ts +2430 -0
- package/Tests/Utils/APIOutgoingRequestTracer.test.ts +137 -0
- package/Tests/Utils/Rum/SessionReplayHealth.test.ts +884 -0
- package/Tests/Utils/Rum/SessionReplayHealthDiagnosis.test.ts +40 -0
- package/Tests/Utils/Rum/SessionReplayRecordingEnded.test.ts +619 -0
- package/Tests/Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer.test.ts +631 -0
- package/Tests/Utils/SecurityEvent/Connectors/CrowdStrikeFalconNormalizer.test.ts +479 -0
- package/Tests/Utils/SecurityEvent/Connectors/ElasticSecurityNormalizer.test.ts +507 -0
- package/Tests/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdrNormalizer.test.ts +686 -0
- package/Tests/Utils/SecurityEvent/Connectors/MicrosoftSentinelNormalizer.test.ts +474 -0
- package/Tests/Utils/SecurityEvent/Connectors/OktaNormalizer.test.ts +736 -0
- package/Tests/Utils/SecurityEvent/Connectors/SplunkNormalizer.test.ts +407 -0
- package/Tests/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.test.ts +129 -0
- package/Tests/Utils/Telemetry/CrossSignalScope.test.ts +57 -1
- package/Tests/Utils/Telemetry/EntityRelationship.test.ts +36 -0
- package/Tests/Utils/Telemetry/LockedFilterSearch.test.ts +600 -0
- package/Tests/Utils/Telemetry/NetworkHost.test.ts +48 -0
- package/Tests/Utils/Telemetry/OriginAllowList.test.ts +154 -0
- package/Tests/Utils/Traces/CriticalPath.test.ts +25 -0
- package/Types/AI/AIChatTypes.ts +8 -0
- package/Types/AI/InvestigationEvidence.ts +96 -0
- package/Types/Monitor/MonitorEvaluationSummary.ts +5 -0
- package/Types/OnCallDutyPolicy/Layer.ts +12 -0
- package/Types/Permission.ts +2 -2
- package/Types/Rules/RuleCriteriaFieldRegistry.ts +12 -0
- package/Types/Rum/SessionReplay.ts +109 -0
- package/Types/Rum/SessionReplayApi.ts +31 -0
- package/Types/SecurityEvent/Connectors/ConnectorDiagnostics.ts +111 -0
- package/Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics.ts +87 -0
- package/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.ts +492 -0
- package/Types/SecurityEvent/Connectors/SecurityEventConnectorProvider.ts +41 -0
- package/Types/SecurityEvent/GoogleSecOpsDiagnostics.ts +56 -1
- package/Types/SecurityEvent/GoogleSecOpsRegion.ts +34 -0
- package/Types/Telemetry/EntityType.ts +14 -0
- package/Types/Telemetry/ExceptionSpanScope.ts +83 -0
- package/Types/Telemetry/LockedFilterDetail.ts +46 -0
- package/Types/Telemetry/ResourceEntityFacet.ts +17 -10
- package/Types/Telemetry/ResourceFacetCatalog.ts +171 -0
- package/UI/Components/Card/Card.tsx +118 -83
- package/UI/Components/Checkbox/Checkbox.tsx +8 -5
- package/UI/Components/CopyTextButton/CopyTextButton.tsx +7 -1
- package/UI/Components/CustomFields/CustomFieldsDetail.tsx +4 -1
- package/UI/Components/Detail/Detail.tsx +137 -22
- package/UI/Components/ErrorBoundary.tsx +38 -0
- package/UI/Components/LogsViewer/LogsEntityNames.ts +912 -0
- package/UI/Components/LogsViewer/LogsViewer.tsx +156 -77
- package/UI/Components/LogsViewer/components/ActiveFilterChips.tsx +28 -11
- package/UI/Components/LogsViewer/components/FacetSection.tsx +66 -79
- package/UI/Components/LogsViewer/components/FacetValueRow.tsx +17 -2
- package/UI/Components/LogsViewer/components/LogDetailsPanel.tsx +45 -5
- package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +100 -19
- package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +156 -39
- package/UI/Components/LogsViewer/components/LogsTable.tsx +30 -8
- package/UI/Components/LogsViewer/types.ts +6 -0
- package/UI/Components/Markdown.tsx/InlineReferences.tsx +628 -0
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +385 -312
- package/UI/Components/MemberRoleAssignment/MemberRoleAssignment.tsx +50 -22
- package/UI/Components/ModelDetail/CardModelDetail.tsx +15 -0
- package/UI/Components/ModelDetail/ModelDetail.tsx +64 -19
- package/UI/Components/ModelList/ModelList.tsx +33 -8
- package/UI/Components/Page/ModelPage.tsx +119 -54
- package/UI/Components/Table/Table.tsx +8 -0
- package/UI/Components/Table/TableRow.tsx +13 -5
- package/UI/Components/TelemetryViewer/FacetVisibility.ts +229 -0
- package/UI/Components/TelemetryViewer/ResourceFacetConfigs.ts +46 -0
- package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +11 -0
- package/UI/Components/TelemetryViewer/components/FacetSearchInput.tsx +79 -0
- package/UI/Components/TelemetryViewer/components/FacetSectionHeader.tsx +69 -0
- package/UI/Components/TelemetryViewer/components/FacetShowMoreButton.tsx +36 -0
- package/UI/Components/TelemetryViewer/components/HiddenFacetsFooter.tsx +88 -0
- package/UI/Components/TelemetryViewer/components/LockedFilterActions.tsx +205 -0
- package/UI/Components/TelemetryViewer/components/LockedFilterChip.tsx +496 -0
- package/UI/Components/TelemetryViewer/components/TelemetryActiveFilterChips.tsx +30 -10
- package/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.tsx +203 -10
- package/UI/Components/TelemetryViewer/components/TelemetryFacetSection.tsx +60 -73
- package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +94 -7
- package/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.tsx +17 -2
- package/UI/Components/TelemetryViewer/types.ts +19 -0
- package/UI/Components/TelemetryViewer/useFacetSearchExemptions.ts +158 -0
- package/UI/Components/TelemetryViewer/useFacetSectionSearch.ts +102 -0
- package/UI/Utils/Clipboard.ts +68 -2
- package/UI/Utils/Navigation.ts +17 -2
- package/UI/Utils/Telemetry/TelemetryEntityNames.ts +620 -0
- package/UI/Utils/Telemetry/UseTelemetryEntityNames.ts +151 -0
- package/Utils/AI/InvestigationReport.ts +1789 -0
- package/Utils/API.ts +90 -1
- package/Utils/Rum/SessionReplayHealth.ts +11 -0
- package/Utils/Rum/SessionReplayRecordingEnded.ts +134 -0
- package/Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer.ts +427 -0
- package/Utils/SecurityEvent/Connectors/CrowdStrikeFalconNormalizer.ts +197 -0
- package/Utils/SecurityEvent/Connectors/ElasticSecurityNormalizer.ts +464 -0
- package/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdrNormalizer.ts +567 -0
- package/Utils/SecurityEvent/Connectors/MicrosoftSentinelNormalizer.ts +299 -0
- package/Utils/SecurityEvent/Connectors/OktaNormalizer.ts +467 -0
- package/Utils/SecurityEvent/Connectors/SplunkNormalizer.ts +439 -0
- package/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.ts +124 -12
- package/Utils/Telemetry/CrossSignalScope.ts +22 -8
- package/Utils/Telemetry/EntityRelationship.ts +8 -0
- package/Utils/Telemetry/LockedFilterSearch.ts +412 -0
- package/Utils/Telemetry/NetworkHost.ts +43 -0
- package/Utils/Telemetry/OriginAllowList.ts +139 -4
- package/Utils/Traces/CriticalPath.ts +10 -4
- package/build/dist/Models/DatabaseModels/Index.js +4 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js +1 -1
- package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
- package/build/dist/Models/DatabaseModels/SecurityEventConnection.js +490 -0
- package/build/dist/Models/DatabaseModels/SecurityEventConnection.js.map +1 -0
- package/build/dist/Models/DatabaseModels/SecurityEventConnectionRun.js +287 -0
- package/build/dist/Models/DatabaseModels/SecurityEventConnectionRun.js.map +1 -0
- package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js +2 -2
- package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +336 -27
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/GoogleSecOpsConnectionAPI.js +182 -7
- package/build/dist/Server/API/GoogleSecOpsConnectionAPI.js.map +1 -1
- package/build/dist/Server/API/SecurityEventConnectionAPI.js +171 -0
- package/build/dist/Server/API/SecurityEventConnectionAPI.js.map +1 -0
- package/build/dist/Server/API/TelemetryAPI.js +248 -170
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792700000000-AddSecurityEventConnections.js +40 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792700000000-AddSecurityEventConnections.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +57 -4
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/ExceptionAggregationService.js +7 -16
- package/build/dist/Server/Services/ExceptionAggregationService.js.map +1 -1
- package/build/dist/Server/Services/GoogleSecOpsConnectionService.js +8 -0
- package/build/dist/Server/Services/GoogleSecOpsConnectionService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +4 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/InventoryItemService.js +22 -0
- package/build/dist/Server/Services/InventoryItemService.js.map +1 -1
- package/build/dist/Server/Services/LogAggregationService.js +8 -17
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/MetricAggregationService.js +4 -14
- package/build/dist/Server/Services/MetricAggregationService.js.map +1 -1
- package/build/dist/Server/Services/SecurityEventConnectionRunService.js +9 -0
- package/build/dist/Server/Services/SecurityEventConnectionRunService.js.map +1 -0
- package/build/dist/Server/Services/SecurityEventConnectionService.js +356 -0
- package/build/dist/Server/Services/SecurityEventConnectionService.js.map +1 -0
- package/build/dist/Server/Services/TraceAggregationService.js +51 -25
- package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
- package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js +9 -0
- package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +3 -0
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +14 -7
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationEvidence.js +468 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationEvidence.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationReferences.js +230 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationReferences.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/Index.js +32 -0
- package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js +6 -2
- package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +59 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +5 -3
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.js +752 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubClient.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubConnector.js +493 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/AwsSecurityHub/AwsSecurityHubConnector.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.js +352 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/ConnectorPlatformHealth.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconClient.js +405 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconClient.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconConnector.js +466 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/CrowdStrikeFalcon/CrowdStrikeFalconConnector.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityClient.js +344 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityClient.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityConnector.js +511 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/ElasticSecurity/ElasticSecurityConnector.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrClient.js +406 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrClient.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrConnector.js +336 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdr/MicrosoftDefenderXdrConnector.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelClient.js +474 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelClient.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelConnector.js +417 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/MicrosoftSentinel/MicrosoftSentinelConnector.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Okta/OktaClient.js +314 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Okta/OktaClient.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Okta/OktaConnector.js +494 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Okta/OktaConnector.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.js +719 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionPoller.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.js +404 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionRunExecutor.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.js +209 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectionTester.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry.js +40 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/SecurityEventConnectorRegistry.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkClient.js +494 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkClient.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkConnector.js +379 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Splunk/SplunkConnector.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Types.js +27 -0
- package/build/dist/Server/Utils/SecurityEvent/Connectors/Types.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js +234 -61
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsConnectionTester.js +537 -0
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsConnectionTester.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js +572 -115
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.js +35 -1
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/SecurityEventDedupe.js +52 -0
- package/build/dist/Server/Utils/SecurityEvent/SecurityEventDedupe.js.map +1 -0
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +521 -32
- package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +10 -0
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +8 -0
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/KubernetesResourceAttributes.js +80 -0
- package/build/dist/Server/Utils/Telemetry/KubernetesResourceAttributes.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +122 -67
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ResourceFacetPlanner.js +146 -0
- package/build/dist/Server/Utils/Telemetry/ResourceFacetPlanner.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js +174 -248
- package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js +492 -0
- package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/TraceContextPropagation.js +259 -0
- package/build/dist/Server/Utils/Telemetry/TraceContextPropagation.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry.js +11 -5
- package/build/dist/Server/Utils/Telemetry.js.map +1 -1
- package/build/dist/Types/AI/InvestigationEvidence.js +2 -0
- package/build/dist/Types/AI/InvestigationEvidence.js.map +1 -0
- package/build/dist/Types/OnCallDutyPolicy/Layer.js +11 -0
- package/build/dist/Types/OnCallDutyPolicy/Layer.js.map +1 -1
- package/build/dist/Types/Permission.js +2 -2
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +9 -0
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplay.js +95 -0
- package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -1
- package/build/dist/Types/SecurityEvent/Connectors/ConnectorDiagnostics.js +18 -0
- package/build/dist/Types/SecurityEvent/Connectors/ConnectorDiagnostics.js.map +1 -0
- package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics.js +2 -0
- package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectionDiagnostics.js.map +1 -0
- package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js +374 -0
- package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorCatalog.js.map +1 -0
- package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorProvider.js +35 -0
- package/build/dist/Types/SecurityEvent/Connectors/SecurityEventConnectorProvider.js.map +1 -0
- package/build/dist/Types/SecurityEvent/GoogleSecOpsRegion.js +35 -0
- package/build/dist/Types/SecurityEvent/GoogleSecOpsRegion.js.map +1 -0
- package/build/dist/Types/Telemetry/EntityType.js +14 -0
- package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
- package/build/dist/Types/Telemetry/ExceptionSpanScope.js +59 -0
- package/build/dist/Types/Telemetry/ExceptionSpanScope.js.map +1 -0
- package/build/dist/Types/Telemetry/LockedFilterDetail.js +16 -0
- package/build/dist/Types/Telemetry/LockedFilterDetail.js.map +1 -0
- package/build/dist/Types/Telemetry/ResourceEntityFacet.js +16 -10
- package/build/dist/Types/Telemetry/ResourceEntityFacet.js.map +1 -1
- package/build/dist/Types/Telemetry/ResourceFacetCatalog.js +119 -0
- package/build/dist/Types/Telemetry/ResourceFacetCatalog.js.map +1 -0
- package/build/dist/UI/Components/Card/Card.js +34 -17
- package/build/dist/UI/Components/Card/Card.js.map +1 -1
- package/build/dist/UI/Components/Checkbox/Checkbox.js +6 -4
- package/build/dist/UI/Components/Checkbox/Checkbox.js.map +1 -1
- package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js +5 -1
- package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js.map +1 -1
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +1 -1
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
- package/build/dist/UI/Components/Detail/Detail.js +63 -13
- package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
- package/build/dist/UI/Components/ErrorBoundary.js +34 -0
- package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/LogsEntityNames.js +535 -0
- package/build/dist/UI/Components/LogsViewer/LogsEntityNames.js.map +1 -0
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js +117 -57
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js +5 -7
- package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/FacetSection.js +31 -44
- package/build/dist/UI/Components/LogsViewer/components/FacetSection.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js +17 -3
- package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js +19 -3
- package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +64 -18
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +100 -41
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsTable.js +13 -5
- package/build/dist/UI/Components/LogsViewer/components/LogsTable.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/types.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/InlineReferences.js +403 -0
- package/build/dist/UI/Components/Markdown.tsx/InlineReferences.js.map +1 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +197 -179
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/MemberRoleAssignment/MemberRoleAssignment.js +30 -21
- package/build/dist/UI/Components/MemberRoleAssignment/MemberRoleAssignment.js.map +1 -1
- package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +12 -0
- package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
- package/build/dist/UI/Components/ModelDetail/ModelDetail.js +46 -12
- package/build/dist/UI/Components/ModelDetail/ModelDetail.js.map +1 -1
- package/build/dist/UI/Components/ModelList/ModelList.js +26 -7
- package/build/dist/UI/Components/ModelList/ModelList.js.map +1 -1
- package/build/dist/UI/Components/Page/ModelPage.js +62 -34
- package/build/dist/UI/Components/Page/ModelPage.js.map +1 -1
- package/build/dist/UI/Components/Table/Table.js +3 -1
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +8 -1
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js +111 -0
- package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/ResourceFacetConfigs.js +22 -0
- package/build/dist/UI/Components/TelemetryViewer/ResourceFacetConfigs.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +1 -1
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/FacetSearchInput.js +36 -0
- package/build/dist/UI/Components/TelemetryViewer/components/FacetSearchInput.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/components/FacetSectionHeader.js +21 -0
- package/build/dist/UI/Components/TelemetryViewer/components/FacetSectionHeader.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/components/FacetShowMoreButton.js +14 -0
- package/build/dist/UI/Components/TelemetryViewer/components/FacetShowMoreButton.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/components/HiddenFacetsFooter.js +27 -0
- package/build/dist/UI/Components/TelemetryViewer/components/HiddenFacetsFooter.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterActions.js +88 -0
- package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterActions.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js +228 -0
- package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryActiveFilterChips.js +6 -6
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryActiveFilterChips.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.js +111 -12
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryDetailPanel.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSection.js +27 -40
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSection.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +70 -10
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js +17 -3
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/types.js +0 -4
- package/build/dist/UI/Components/TelemetryViewer/types.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/useFacetSearchExemptions.js +70 -0
- package/build/dist/UI/Components/TelemetryViewer/useFacetSearchExemptions.js.map +1 -0
- package/build/dist/UI/Components/TelemetryViewer/useFacetSectionSearch.js +52 -0
- package/build/dist/UI/Components/TelemetryViewer/useFacetSectionSearch.js.map +1 -0
- package/build/dist/UI/Utils/Clipboard.js +59 -2
- package/build/dist/UI/Utils/Clipboard.js.map +1 -1
- package/build/dist/UI/Utils/Navigation.js +11 -2
- package/build/dist/UI/Utils/Navigation.js.map +1 -1
- package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js +471 -0
- package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js.map +1 -0
- package/build/dist/UI/Utils/Telemetry/UseTelemetryEntityNames.js +113 -0
- package/build/dist/UI/Utils/Telemetry/UseTelemetryEntityNames.js.map +1 -0
- package/build/dist/Utils/AI/InvestigationReport.js +1241 -0
- package/build/dist/Utils/AI/InvestigationReport.js.map +1 -0
- package/build/dist/Utils/API.js +25 -0
- package/build/dist/Utils/API.js.map +1 -1
- package/build/dist/Utils/Rum/SessionReplayHealth.js +10 -0
- package/build/dist/Utils/Rum/SessionReplayHealth.js.map +1 -1
- package/build/dist/Utils/Rum/SessionReplayRecordingEnded.js +54 -0
- package/build/dist/Utils/Rum/SessionReplayRecordingEnded.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer.js +311 -0
- package/build/dist/Utils/SecurityEvent/Connectors/AwsSecurityHubNormalizer.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/Connectors/CrowdStrikeFalconNormalizer.js +150 -0
- package/build/dist/Utils/SecurityEvent/Connectors/CrowdStrikeFalconNormalizer.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/Connectors/ElasticSecurityNormalizer.js +328 -0
- package/build/dist/Utils/SecurityEvent/Connectors/ElasticSecurityNormalizer.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdrNormalizer.js +405 -0
- package/build/dist/Utils/SecurityEvent/Connectors/MicrosoftDefenderXdrNormalizer.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/Connectors/MicrosoftSentinelNormalizer.js +212 -0
- package/build/dist/Utils/SecurityEvent/Connectors/MicrosoftSentinelNormalizer.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/Connectors/OktaNormalizer.js +351 -0
- package/build/dist/Utils/SecurityEvent/Connectors/OktaNormalizer.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/Connectors/SplunkNormalizer.js +348 -0
- package/build/dist/Utils/SecurityEvent/Connectors/SplunkNormalizer.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js +103 -10
- package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js.map +1 -1
- package/build/dist/Utils/Telemetry/CrossSignalScope.js +16 -5
- package/build/dist/Utils/Telemetry/CrossSignalScope.js.map +1 -1
- package/build/dist/Utils/Telemetry/EntityRelationship.js +7 -0
- package/build/dist/Utils/Telemetry/EntityRelationship.js.map +1 -1
- package/build/dist/Utils/Telemetry/LockedFilterSearch.js +277 -0
- package/build/dist/Utils/Telemetry/LockedFilterSearch.js.map +1 -0
- package/build/dist/Utils/Telemetry/NetworkHost.js +39 -0
- package/build/dist/Utils/Telemetry/NetworkHost.js.map +1 -0
- package/build/dist/Utils/Telemetry/OriginAllowList.js +105 -4
- package/build/dist/Utils/Telemetry/OriginAllowList.js.map +1 -1
- package/build/dist/Utils/Traces/CriticalPath.js +9 -4
- package/build/dist/Utils/Traces/CriticalPath.js.map +1 -1
- package/package.json +1 -1
- package/Tests/UI/Rum/RecordingHealthStrip.test.tsx +0 -600
- package/UI/Components/GanttChart/Bar/BarLabel.tsx +0 -17
- package/UI/Components/GanttChart/Bar/Index.tsx +0 -149
- package/UI/Components/GanttChart/ChartContainer.tsx +0 -50
- package/UI/Components/GanttChart/Index.tsx +0 -90
- package/UI/Components/GanttChart/Row/Index.tsx +0 -22
- package/UI/Components/GanttChart/Row/Row.tsx +0 -231
- package/UI/Components/GanttChart/Row/RowLabel.tsx +0 -30
- package/UI/Components/GanttChart/Rows.tsx +0 -59
- package/UI/Components/GanttChart/Timeline/Index.tsx +0 -46
- package/UI/Components/GanttChart/Timeline/TimelineInterval.tsx +0 -33
- package/UI/Components/GanttChart/Timeline/TimelineIntervalMarks.tsx +0 -43
- package/build/dist/UI/Components/GanttChart/Bar/BarLabel.js +0 -8
- package/build/dist/UI/Components/GanttChart/Bar/BarLabel.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Bar/Index.js +0 -77
- package/build/dist/UI/Components/GanttChart/Bar/Index.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/ChartContainer.js +0 -33
- package/build/dist/UI/Components/GanttChart/ChartContainer.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Index.js +0 -39
- package/build/dist/UI/Components/GanttChart/Index.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Row/Index.js +0 -7
- package/build/dist/UI/Components/GanttChart/Row/Index.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Row/Row.js +0 -106
- package/build/dist/UI/Components/GanttChart/Row/Row.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Row/RowLabel.js +0 -10
- package/build/dist/UI/Components/GanttChart/Row/RowLabel.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Rows.js +0 -19
- package/build/dist/UI/Components/GanttChart/Rows.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Timeline/Index.js +0 -16
- package/build/dist/UI/Components/GanttChart/Timeline/Index.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Timeline/TimelineInterval.js +0 -13
- package/build/dist/UI/Components/GanttChart/Timeline/TimelineInterval.js.map +0 -1
- package/build/dist/UI/Components/GanttChart/Timeline/TimelineIntervalMarks.js +0 -13
- 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
|
+
};
|