@oneuptime/common 10.8.2 → 11.0.0
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/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel.ts +16 -18
- package/Models/AnalyticsModels/AuditLog.ts +3 -1
- package/Models/AnalyticsModels/ExceptionInstance.ts +200 -82
- package/Models/AnalyticsModels/Index.ts +7 -2
- package/Models/AnalyticsModels/Log.ts +197 -81
- package/Models/AnalyticsModels/Metric.ts +199 -86
- package/Models/AnalyticsModels/MetricBaselineHourly.ts +44 -25
- package/Models/AnalyticsModels/MetricItemAggMV1m.ts +23 -20
- package/Models/AnalyticsModels/{MetricItemAggMV1mByHost.ts → MetricItemAggMV1mByHostV2.ts} +58 -47
- package/Models/AnalyticsModels/MonitorLog.ts +5 -1
- package/Models/AnalyticsModels/Profile.ts +206 -85
- package/Models/AnalyticsModels/ProfileSample.ts +196 -83
- package/Models/AnalyticsModels/Span.ts +218 -85
- package/Models/DatabaseModels/Index.ts +4 -0
- package/Models/DatabaseModels/Service.ts +29 -0
- package/Models/DatabaseModels/TelemetryEntity.ts +393 -0
- package/Models/DatabaseModels/TelemetryEntityRelationship.ts +294 -0
- package/Models/DatabaseModels/TelemetryException.ts +10 -10
- package/Models/DatabaseModels/TelemetryUsageBilling.ts +5 -5
- package/Server/API/AIAgentDataAPI.ts +13 -12
- package/Server/API/DashboardAPI.ts +2 -2
- package/Server/API/TelemetryAPI.ts +656 -141
- package/Server/API/TelemetryExceptionAPI.ts +2 -2
- package/Server/Infrastructure/ClickhouseConfig.ts +12 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1781100000001-RenameTelemetryServiceIdToPrimaryEntityId.ts +48 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1781200000000-AddTelemetryEntityTable.ts +70 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1781200000001-AddTelemetryEntityRelationshipTable.ts +57 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1781250074195-MigrationName.ts +207 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1781300000000-AddTelemetryEntityLabels.ts +24 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1781400000000-AddServiceTelemetrySdkLanguage.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +12 -0
- package/Server/Infrastructure/Queue.ts +36 -3
- package/Server/Middleware/TelemetryIngest.ts +27 -22
- package/Server/Services/AlertService.ts +9 -9
- package/Server/Services/AnalyticsDatabaseService.ts +204 -35
- package/Server/Services/ExceptionAggregationService.ts +41 -18
- package/Server/Services/HostService.ts +2 -1
- package/Server/Services/IncidentService.ts +19 -19
- package/Server/Services/Index.ts +6 -2
- package/Server/Services/LogAggregationService.ts +116 -43
- package/Server/Services/MetricAggregationService.ts +29 -14
- package/Server/Services/MetricBaselineService.ts +34 -34
- package/Server/Services/MetricItemAggMV1mByHostV2Service.ts +30 -0
- package/Server/Services/MetricService.ts +119 -31
- package/Server/Services/OpenTelemetryIngestService.ts +186 -50
- package/Server/Services/ProfileAggregationService.ts +904 -126
- package/Server/Services/ServiceService.ts +6 -0
- package/Server/Services/SpanService.ts +274 -14
- package/Server/Services/TelemetryEntityRelationshipService.ts +71 -0
- package/Server/Services/TelemetryEntityService.ts +246 -0
- package/Server/Services/TelemetryExceptionService.ts +27 -23
- package/Server/Services/TelemetryUsageBillingService.ts +38 -31
- package/Server/Services/TraceAggregationService.ts +875 -43
- package/Server/Types/AnalyticsDatabase/ModelPermission.ts +43 -2
- package/Server/Types/Database/Permissions/AccessControlPermission.ts +47 -2
- package/Server/Types/Database/Permissions/BasePermission.ts +37 -1
- package/Server/Types/Database/Permissions/OwnedScopePermission.ts +21 -3
- package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +1 -0
- package/Server/Types/Database/QueryHelper.ts +41 -0
- package/Server/Utils/Alert/AlertPrivacyFilter.ts +9 -2
- package/Server/Utils/AlertEpisode/AlertEpisodePrivacyFilter.ts +9 -2
- package/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.ts +95 -0
- package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +133 -0
- package/Server/Utils/Incident/IncidentPrivacyFilter.ts +9 -2
- package/Server/Utils/IncidentEpisode/IncidentEpisodePrivacyFilter.ts +9 -2
- package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +1 -1
- package/Server/Utils/Monitor/MonitorLogUtil.ts +1 -2
- package/Server/Utils/Monitor/MonitorMetricUtil.ts +3 -4
- package/Server/Utils/PrivacyFilterUtil.ts +72 -0
- package/Server/Utils/Profile/PprofEncoder.ts +135 -11
- package/Server/Utils/Telemetry/EntityRegistry.ts +316 -0
- package/Server/Utils/Telemetry/ResourceFacetResolver.ts +5 -0
- package/Server/Utils/Telemetry/TelemetryEntity.ts +783 -0
- package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +79 -4
- package/Tests/Server/Services/LogAggregationService.test.ts +7 -2
- package/Tests/Server/Services/ProfileAggregationService.test.ts +280 -0
- package/Tests/Server/Services/ProfileBreakdown.test.ts +161 -0
- package/Tests/Server/Services/ProfileFunctionFocus.test.ts +349 -0
- package/Tests/Server/Services/TelemetryAttributeService.test.ts +1 -1
- package/Tests/Server/Services/TraceAggregationService.test.ts +403 -0
- package/Tests/Server/Types/AnalyticsDatabase/ModelPermissionOwnedScope.test.ts +114 -0
- package/Tests/Server/Types/Database/Permissions/AccessControlPermission.test.ts +189 -0
- package/Tests/Server/Types/Database/Permissions/BasePermission.test.ts +118 -0
- package/Tests/Server/Types/Database/Permissions/OwnedScopePermission.test.ts +159 -0
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +275 -8
- package/Tests/Server/Utils/PrivacyFilterUtil.test.ts +177 -0
- package/Tests/Server/Utils/Profile/PprofEncoder.test.ts +276 -0
- package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +761 -0
- package/Tests/Types/Monitor/MonitorStepEntityScope.test.ts +275 -0
- package/Tests/Types/Text.test.ts +52 -0
- package/Tests/Utils/Telemetry/EntityKey.test.ts +150 -0
- package/Tests/Utils/Telemetry/EntityKeySqlParity.test.ts +40 -0
- package/Tests/Utils/Telemetry/EntityRelationship.test.ts +150 -0
- package/Tests/Utils/UUID.test.ts +47 -0
- package/Types/AnalyticsDatabase/AnalyticsTableName.ts +14 -9
- package/Types/AnalyticsDatabase/TableColumnType.ts +1 -0
- package/Types/Dashboard/DashboardComponentType.ts +1 -0
- package/Types/Dashboard/DashboardComponents/DashboardTraceChartComponent.ts +37 -0
- package/Types/Dashboard/DashboardTemplates.ts +4 -5
- package/Types/Log/LogQueryParser.ts +2 -2
- package/Types/Log/LogQueryToFilter.ts +2 -2
- package/Types/Monitor/MonitorStepExceptionMonitor.ts +19 -1
- package/Types/Monitor/MonitorStepLogMonitor.ts +20 -1
- package/Types/Monitor/MonitorStepMetricMonitor.ts +27 -0
- package/Types/Monitor/MonitorStepProfileMonitor.ts +19 -1
- package/Types/Monitor/MonitorStepTraceMonitor.ts +18 -1
- package/Types/Monitor/MonitorType.ts +8 -1
- package/Types/ObjectID.ts +10 -0
- package/Types/Telemetry/EntityRelationshipType.ts +31 -0
- package/Types/Telemetry/EntityType.ts +33 -0
- package/Types/Telemetry/TelemetrySavedViewState.ts +2 -0
- package/Types/Text.ts +34 -0
- package/Types/Trace/TraceAggregationType.ts +1 -0
- package/Types/Trace/TraceRecordingRuleDefinition.ts +74 -0
- package/UI/Components/LogsViewer/LogsViewer.tsx +12 -9
- package/UI/Components/LogsViewer/components/LogDetailsPanel.tsx +10 -9
- package/UI/Components/LogsViewer/components/LogSearchBar.tsx +1 -1
- package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +2 -2
- package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +4 -4
- package/UI/Components/LogsViewer/components/LogsTable.tsx +5 -3
- package/UI/Components/Navbar/NavBarMenuModal.tsx +81 -44
- package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +33 -10
- package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +18 -3
- package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +91 -68
- package/UI/Components/TelemetryViewer/components/TelemetryHistogramTooltip.tsx +9 -2
- package/UI/Utils/LogExport.ts +2 -2
- package/UI/Utils/TelemetryService.ts +20 -20
- package/Utils/Dashboard/Components/DashboardTraceChartComponent.ts +134 -0
- package/Utils/Dashboard/Components/Index.ts +7 -0
- package/Utils/Telemetry/EntityKey.ts +151 -0
- package/Utils/Telemetry/EntityRelationship.ts +113 -0
- package/Utils/Traces/CriticalPath.ts +7 -7
- package/Utils/UUID.ts +57 -0
- package/build/dist/Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel.js +14 -13
- package/build/dist/Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/AuditLog.js +2 -1
- package/build/dist/Models/AnalyticsModels/AuditLog.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/ExceptionInstance.js +125 -22
- package/build/dist/Models/AnalyticsModels/ExceptionInstance.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/Index.js +7 -2
- package/build/dist/Models/AnalyticsModels/Index.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/Log.js +123 -22
- package/build/dist/Models/AnalyticsModels/Log.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/Metric.js +125 -27
- package/build/dist/Models/AnalyticsModels/Metric.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/MetricBaselineHourly.js +38 -21
- package/build/dist/Models/AnalyticsModels/MetricBaselineHourly.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1m.js +17 -16
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1m.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/{MetricItemAggMV1mByHost.js → MetricItemAggMV1mByHostV2.js} +54 -42
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByHostV2.js.map +1 -0
- package/build/dist/Models/AnalyticsModels/MonitorLog.js +4 -1
- package/build/dist/Models/AnalyticsModels/MonitorLog.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/Profile.js +132 -26
- package/build/dist/Models/AnalyticsModels/Profile.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/ProfileSample.js +121 -23
- package/build/dist/Models/AnalyticsModels/ProfileSample.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/Span.js +144 -26
- package/build/dist/Models/AnalyticsModels/Span.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +4 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Service.js +30 -0
- package/build/dist/Models/DatabaseModels/Service.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TelemetryEntity.js +419 -0
- package/build/dist/Models/DatabaseModels/TelemetryEntity.js.map +1 -0
- package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js +317 -0
- package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js.map +1 -0
- package/build/dist/Models/DatabaseModels/TelemetryException.js +12 -12
- package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TelemetryUsageBilling.js +7 -7
- package/build/dist/Models/DatabaseModels/TelemetryUsageBilling.js.map +1 -1
- package/build/dist/Server/API/AIAgentDataAPI.js +14 -13
- package/build/dist/Server/API/AIAgentDataAPI.js.map +1 -1
- package/build/dist/Server/API/DashboardAPI.js +2 -2
- package/build/dist/Server/API/DashboardAPI.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +425 -129
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/API/TelemetryExceptionAPI.js +2 -2
- package/build/dist/Server/API/TelemetryExceptionAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/ClickhouseConfig.js +12 -0
- package/build/dist/Server/Infrastructure/ClickhouseConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781100000001-RenameTelemetryServiceIdToPrimaryEntityId.js +29 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781100000001-RenameTelemetryServiceIdToPrimaryEntityId.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781200000000-AddTelemetryEntityTable.js +38 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781200000000-AddTelemetryEntityTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781200000001-AddTelemetryEntityRelationshipTable.js +33 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781200000001-AddTelemetryEntityRelationshipTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781250074195-MigrationName.js +78 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781250074195-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781300000000-AddTelemetryEntityLabels.js +19 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781300000000-AddTelemetryEntityLabels.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781400000000-AddServiceTelemetrySdkLanguage.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1781400000000-AddServiceTelemetrySdkLanguage.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/Queue.js +14 -3
- package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +16 -18
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +9 -9
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +115 -40
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/ExceptionAggregationService.js +38 -18
- package/build/dist/Server/Services/ExceptionAggregationService.js.map +1 -1
- package/build/dist/Server/Services/HostService.js +2 -1
- package/build/dist/Server/Services/HostService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +19 -19
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +6 -2
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/LogAggregationService.js +100 -42
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/MetricAggregationService.js +27 -14
- package/build/dist/Server/Services/MetricAggregationService.js.map +1 -1
- package/build/dist/Server/Services/MetricBaselineService.js +28 -28
- package/build/dist/Server/Services/MetricBaselineService.js.map +1 -1
- package/build/dist/Server/Services/MetricItemAggMV1mByHostV2Service.js +28 -0
- package/build/dist/Server/Services/MetricItemAggMV1mByHostV2Service.js.map +1 -0
- package/build/dist/Server/Services/MetricService.js +116 -31
- package/build/dist/Server/Services/MetricService.js.map +1 -1
- package/build/dist/Server/Services/OpenTelemetryIngestService.js +103 -36
- package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
- package/build/dist/Server/Services/ProfileAggregationService.js +613 -105
- package/build/dist/Server/Services/ProfileAggregationService.js.map +1 -1
- package/build/dist/Server/Services/ServiceService.js +9 -5
- package/build/dist/Server/Services/ServiceService.js.map +1 -1
- package/build/dist/Server/Services/SpanService.js +217 -15
- package/build/dist/Server/Services/SpanService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryEntityRelationshipService.js +72 -0
- package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +1 -0
- package/build/dist/Server/Services/TelemetryEntityService.js +201 -0
- package/build/dist/Server/Services/TelemetryEntityService.js.map +1 -0
- package/build/dist/Server/Services/TelemetryExceptionService.js +18 -18
- package/build/dist/Server/Services/TelemetryExceptionService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryUsageBillingService.js +27 -21
- package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
- package/build/dist/Server/Services/TraceAggregationService.js +568 -43
- package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
- package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js +38 -2
- package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/AccessControlPermission.js +36 -2
- package/build/dist/Server/Types/Database/Permissions/AccessControlPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/BasePermission.js +25 -1
- package/build/dist/Server/Types/Database/Permissions/BasePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/OwnedScopePermission.js +17 -3
- package/build/dist/Server/Types/Database/Permissions/OwnedScopePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +1 -0
- package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js +31 -0
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Utils/Alert/AlertPrivacyFilter.js +3 -2
- package/build/dist/Server/Utils/Alert/AlertPrivacyFilter.js.map +1 -1
- package/build/dist/Server/Utils/AlertEpisode/AlertEpisodePrivacyFilter.js +3 -2
- package/build/dist/Server/Utils/AlertEpisode/AlertEpisodePrivacyFilter.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js +46 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js.map +1 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +97 -3
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
- package/build/dist/Server/Utils/Incident/IncidentPrivacyFilter.js +3 -2
- package/build/dist/Server/Utils/Incident/IncidentPrivacyFilter.js.map +1 -1
- package/build/dist/Server/Utils/IncidentEpisode/IncidentEpisodePrivacyFilter.js +3 -2
- package/build/dist/Server/Utils/IncidentEpisode/IncidentEpisodePrivacyFilter.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorLogUtil.js +1 -2
- package/build/dist/Server/Utils/Monitor/MonitorLogUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +3 -4
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
- package/build/dist/Server/Utils/PrivacyFilterUtil.js +47 -0
- package/build/dist/Server/Utils/PrivacyFilterUtil.js.map +1 -0
- package/build/dist/Server/Utils/Profile/PprofEncoder.js +132 -4
- package/build/dist/Server/Utils/Profile/PprofEncoder.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +228 -0
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js +5 -0
- package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +569 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -0
- package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +14 -9
- package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -1
- package/build/dist/Types/AnalyticsDatabase/TableColumnType.js +1 -0
- package/build/dist/Types/AnalyticsDatabase/TableColumnType.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardTraceChartComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardTraceChartComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.js +4 -5
- package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
- package/build/dist/Types/Log/LogQueryParser.js +2 -2
- package/build/dist/Types/Log/LogQueryParser.js.map +1 -1
- package/build/dist/Types/Log/LogQueryToFilter.js +1 -1
- package/build/dist/Types/Log/LogQueryToFilter.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepExceptionMonitor.js +9 -1
- package/build/dist/Types/Monitor/MonitorStepExceptionMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepLogMonitor.js +9 -1
- package/build/dist/Types/Monitor/MonitorStepLogMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepMetricMonitor.js +13 -0
- package/build/dist/Types/Monitor/MonitorStepMetricMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepProfileMonitor.js +9 -1
- package/build/dist/Types/Monitor/MonitorStepProfileMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepTraceMonitor.js +9 -1
- package/build/dist/Types/Monitor/MonitorStepTraceMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorType.js +8 -1
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/ObjectID.js +9 -0
- package/build/dist/Types/ObjectID.js.map +1 -1
- package/build/dist/Types/Telemetry/EntityRelationshipType.js +32 -0
- package/build/dist/Types/Telemetry/EntityRelationshipType.js.map +1 -0
- package/build/dist/Types/Telemetry/EntityType.js +34 -0
- package/build/dist/Types/Telemetry/EntityType.js.map +1 -0
- package/build/dist/Types/Text.js +32 -1
- package/build/dist/Types/Text.js.map +1 -1
- package/build/dist/Types/Trace/TraceAggregationType.js +1 -0
- package/build/dist/Types/Trace/TraceAggregationType.js.map +1 -1
- package/build/dist/Types/Trace/TraceRecordingRuleDefinition.js +50 -1
- package/build/dist/Types/Trace/TraceRecordingRuleDefinition.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js +10 -9
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js +8 -8
- package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogSearchBar.js +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogSearchBar.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +2 -2
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +4 -4
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsTable.js +3 -3
- package/build/dist/UI/Components/LogsViewer/components/LogsTable.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +43 -30
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +6 -2
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +14 -3
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +18 -10
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogramTooltip.js +4 -2
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogramTooltip.js.map +1 -1
- package/build/dist/UI/Utils/LogExport.js +2 -2
- package/build/dist/UI/Utils/LogExport.js.map +1 -1
- package/build/dist/UI/Utils/TelemetryService.js +16 -16
- package/build/dist/UI/Utils/TelemetryService.js.map +1 -1
- package/build/dist/Utils/Dashboard/Components/DashboardTraceChartComponent.js +110 -0
- package/build/dist/Utils/Dashboard/Components/DashboardTraceChartComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
- package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
- package/build/dist/Utils/Telemetry/EntityKey.js +115 -0
- package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -0
- package/build/dist/Utils/Telemetry/EntityRelationship.js +71 -0
- package/build/dist/Utils/Telemetry/EntityRelationship.js.map +1 -0
- package/build/dist/Utils/Traces/CriticalPath.js +5 -5
- package/build/dist/Utils/Traces/CriticalPath.js.map +1 -1
- package/build/dist/Utils/UUID.js +50 -0
- package/build/dist/Utils/UUID.js.map +1 -1
- package/package.json +2 -1
- package/tsconfig.json +10 -1
- package/Server/Services/MetricItemAggMV1mByHostService.ts +0 -30
- package/Types/Profile/ProfileMetricType.ts +0 -16
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByHost.js.map +0 -1
- package/build/dist/Server/Services/MetricItemAggMV1mByHostService.js +0 -28
- package/build/dist/Server/Services/MetricItemAggMV1mByHostService.js.map +0 -1
- package/build/dist/Tests/MockType.js +0 -5
- package/build/dist/Tests/MockType.js.map +0 -1
- package/build/dist/Tests/Models/AnalyticsModels/Log.test.js +0 -12
- package/build/dist/Tests/Models/AnalyticsModels/Log.test.js.map +0 -1
- package/build/dist/Tests/Models/File.test.js +0 -10
- package/build/dist/Tests/Models/File.test.js.map +0 -1
- package/build/dist/Tests/Server/API/BaseAPI.test.js +0 -590
- package/build/dist/Tests/Server/API/BaseAPI.test.js.map +0 -1
- package/build/dist/Tests/Server/API/Helpers.js +0 -27
- package/build/dist/Tests/Server/API/Helpers.js.map +0 -1
- package/build/dist/Tests/Server/API/ProbeAPI.test.js +0 -84
- package/build/dist/Tests/Server/API/ProbeAPI.test.js.map +0 -1
- package/build/dist/Tests/Server/API/ProjectAPI.test.js +0 -170
- package/build/dist/Tests/Server/API/ProjectAPI.test.js.map +0 -1
- package/build/dist/Tests/Server/API/UserSmsApi.test.js +0 -177
- package/build/dist/Tests/Server/API/UserSmsApi.test.js.map +0 -1
- package/build/dist/Tests/Server/Middleware/BearerTokenAuthorization.test.js +0 -63
- package/build/dist/Tests/Server/Middleware/BearerTokenAuthorization.test.js.map +0 -1
- package/build/dist/Tests/Server/Middleware/ClusterKeyAuthorization.test.js +0 -58
- package/build/dist/Tests/Server/Middleware/ClusterKeyAuthorization.test.js.map +0 -1
- package/build/dist/Tests/Server/Middleware/NotificationMiddleware.test.js +0 -101
- package/build/dist/Tests/Server/Middleware/NotificationMiddleware.test.js.map +0 -1
- package/build/dist/Tests/Server/Middleware/ProjectAuthorization.test.js +0 -160
- package/build/dist/Tests/Server/Middleware/ProjectAuthorization.test.js.map +0 -1
- package/build/dist/Tests/Server/Middleware/UserAuthorization.test.js +0 -410
- package/build/dist/Tests/Server/Middleware/UserAuthorization.test.js.map +0 -1
- package/build/dist/Tests/Server/Services/AlertEpisodeMemberService.test.js +0 -165
- package/build/dist/Tests/Server/Services/AlertEpisodeMemberService.test.js.map +0 -1
- package/build/dist/Tests/Server/Services/AlertEpisodeService.test.js +0 -193
- package/build/dist/Tests/Server/Services/AlertEpisodeService.test.js.map +0 -1
- package/build/dist/Tests/Server/Services/AlertGroupingEngineService.test.js +0 -435
- package/build/dist/Tests/Server/Services/AlertGroupingEngineService.test.js.map +0 -1
- package/build/dist/Tests/Server/Services/AlertGroupingRuleService.test.js +0 -320
- package/build/dist/Tests/Server/Services/AlertGroupingRuleService.test.js.map +0 -1
- package/build/dist/Tests/Server/Services/AnalyticsDatabaseService.test.js +0 -266
- package/build/dist/Tests/Server/Services/AnalyticsDatabaseService.test.js.map +0 -1
- package/build/dist/Tests/Server/Services/BillingService.test.js +0 -910
- package/build/dist/Tests/Server/Services/BillingService.test.js.map +0 -1
- package/build/dist/Tests/Server/Services/LogAggregationService.test.js +0 -75
- package/build/dist/Tests/Server/Services/LogAggregationService.test.js.map +0 -1
- package/build/dist/Tests/Server/Services/ProbeService.test.js +0 -127
- package/build/dist/Tests/Server/Services/ProbeService.test.js.map +0 -1
- package/build/dist/Tests/Server/Services/ScheduledMaintenanceService.test.js +0 -114
- package/build/dist/Tests/Server/Services/ScheduledMaintenanceService.test.js.map +0 -1
- package/build/dist/Tests/Server/Services/TeamMemberService.test.js +0 -106
- package/build/dist/Tests/Server/Services/TeamMemberService.test.js.map +0 -1
- package/build/dist/Tests/Server/Services/TelemetryAttributeService.test.js +0 -50
- package/build/dist/Tests/Server/Services/TelemetryAttributeService.test.js.map +0 -1
- package/build/dist/Tests/Server/TestingUtils/Init.js +0 -4
- package/build/dist/Tests/Server/TestingUtils/Init.js.map +0 -1
- package/build/dist/Tests/Server/TestingUtils/Postgres/TestDataSourceOptions.js +0 -9
- package/build/dist/Tests/Server/TestingUtils/Postgres/TestDataSourceOptions.js.map +0 -1
- package/build/dist/Tests/Server/TestingUtils/Redis/TestRedisOptions.js +0 -16
- package/build/dist/Tests/Server/TestingUtils/Redis/TestRedisOptions.js.map +0 -1
- package/build/dist/Tests/Server/TestingUtils/Services/BillingServiceHelper.js +0 -125
- package/build/dist/Tests/Server/TestingUtils/Services/BillingServiceHelper.js.map +0 -1
- package/build/dist/Tests/Server/TestingUtils/Services/ProjectServiceHelper.js +0 -39
- package/build/dist/Tests/Server/TestingUtils/Services/ProjectServiceHelper.js.map +0 -1
- package/build/dist/Tests/Server/TestingUtils/Services/ScheduledMaintenanceServiceHelper.js +0 -20
- package/build/dist/Tests/Server/TestingUtils/Services/ScheduledMaintenanceServiceHelper.js.map +0 -1
- package/build/dist/Tests/Server/TestingUtils/Services/ScheduledMaintenanceStateServiceHelper.js +0 -31
- package/build/dist/Tests/Server/TestingUtils/Services/ScheduledMaintenanceStateServiceHelper.js.map +0 -1
- package/build/dist/Tests/Server/TestingUtils/Services/TeamMemberServiceHelper.js +0 -14
- package/build/dist/Tests/Server/TestingUtils/Services/TeamMemberServiceHelper.js.map +0 -1
- package/build/dist/Tests/Server/TestingUtils/Services/TeamServiceHelper.js +0 -21
- package/build/dist/Tests/Server/TestingUtils/Services/TeamServiceHelper.js.map +0 -1
- package/build/dist/Tests/Server/TestingUtils/Services/Types.js +0 -2
- package/build/dist/Tests/Server/TestingUtils/Services/Types.js.map +0 -1
- package/build/dist/Tests/Server/TestingUtils/Services/UserServiceHelper.js +0 -37
- package/build/dist/Tests/Server/TestingUtils/Services/UserServiceHelper.js.map +0 -1
- package/build/dist/Tests/Server/TestingUtils/__mocks__/Stripe.mock.js +0 -13
- package/build/dist/Tests/Server/TestingUtils/__mocks__/Stripe.mock.js.map +0 -1
- package/build/dist/Tests/Server/TestingUtils/__mocks__/TestDatabase.mock.js +0 -22
- package/build/dist/Tests/Server/TestingUtils/__mocks__/TestDatabase.mock.js.map +0 -1
- package/build/dist/Tests/Server/Types/Domain.test.js +0 -78
- package/build/dist/Tests/Server/Types/Domain.test.js.map +0 -1
- package/build/dist/Tests/Server/Utils/AnalyticsDatabase/Statement.test.js +0 -94
- package/build/dist/Tests/Server/Utils/AnalyticsDatabase/Statement.test.js.map +0 -1
- package/build/dist/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.js +0 -459
- package/build/dist/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.js.map +0 -1
- package/build/dist/Tests/Server/Utils/Cookie.test.js +0 -83
- package/build/dist/Tests/Server/Utils/Cookie.test.js.map +0 -1
- package/build/dist/Tests/Server/Utils/CronTab.test.js +0 -29
- package/build/dist/Tests/Server/Utils/CronTab.test.js.map +0 -1
- package/build/dist/Tests/Server/Utils/JsonToCsv.test.js +0 -114
- package/build/dist/Tests/Server/Utils/JsonToCsv.test.js.map +0 -1
- package/build/dist/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.js +0 -606
- package/build/dist/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.js.map +0 -1
- package/build/dist/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.js +0 -255
- package/build/dist/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.js.map +0 -1
- package/build/dist/Tests/Server/Utils/Monitor/MonitorMaintenanceSuppression.test.js +0 -142
- package/build/dist/Tests/Server/Utils/Monitor/MonitorMaintenanceSuppression.test.js.map +0 -1
- package/build/dist/Tests/Server/Utils/StatusPageResource.test.js +0 -122
- package/build/dist/Tests/Server/Utils/StatusPageResource.test.js.map +0 -1
- package/build/dist/Tests/Server/Utils/Telemetry/LogExceptionExtractor.test.js +0 -0
- package/build/dist/Tests/Server/Utils/Telemetry/LogExceptionExtractor.test.js.map +0 -1
- package/build/dist/Tests/Server/Utils/VM/VMAPI.test.js +0 -205
- package/build/dist/Tests/Server/Utils/VM/VMAPI.test.js.map +0 -1
- package/build/dist/Tests/Spy.js +0 -4
- package/build/dist/Tests/Spy.js.map +0 -1
- package/build/dist/Tests/Types/API/ErrorResponse.test.js +0 -13
- package/build/dist/Tests/Types/API/ErrorResponse.test.js.map +0 -1
- package/build/dist/Tests/Types/API/HTTPErrorResponse.test.js +0 -33
- package/build/dist/Tests/Types/API/HTTPErrorResponse.test.js.map +0 -1
- package/build/dist/Tests/Types/API/HTTPMethod.test.js +0 -16
- package/build/dist/Tests/Types/API/HTTPMethod.test.js.map +0 -1
- package/build/dist/Tests/Types/API/Headers.test.js +0 -14
- package/build/dist/Tests/Types/API/Headers.test.js.map +0 -1
- package/build/dist/Tests/Types/API/Hostname.test.js +0 -22
- package/build/dist/Tests/Types/API/Hostname.test.js.map +0 -1
- package/build/dist/Tests/Types/API/Protocal.test.js +0 -19
- package/build/dist/Tests/Types/API/Protocal.test.js.map +0 -1
- package/build/dist/Tests/Types/API/Response.test.js +0 -14
- package/build/dist/Tests/Types/API/Response.test.js.map +0 -1
- package/build/dist/Tests/Types/API/ResponseType.test.js +0 -13
- package/build/dist/Tests/Types/API/ResponseType.test.js.map +0 -1
- package/build/dist/Tests/Types/API/Route.test.js +0 -30
- package/build/dist/Tests/Types/API/Route.test.js.map +0 -1
- package/build/dist/Tests/Types/API/StatusCode.test.js +0 -26
- package/build/dist/Tests/Types/API/StatusCode.test.js.map +0 -1
- package/build/dist/Tests/Types/API/URL.test.js +0 -33
- package/build/dist/Tests/Types/API/URL.test.js.map +0 -1
- package/build/dist/Tests/Types/Alerts/AlertEventType.test.js +0 -34
- package/build/dist/Tests/Types/Alerts/AlertEventType.test.js.map +0 -1
- package/build/dist/Tests/Types/Alerts/AlertType.test.js +0 -19
- package/build/dist/Tests/Types/Alerts/AlertType.test.js.map +0 -1
- package/build/dist/Tests/Types/AppEnvironment.test.js +0 -13
- package/build/dist/Tests/Types/AppEnvironment.test.js.map +0 -1
- package/build/dist/Tests/Types/ApplicationLog/ApplicationLogType.test.js +0 -13
- package/build/dist/Tests/Types/ApplicationLog/ApplicationLogType.test.js.map +0 -1
- package/build/dist/Tests/Types/ArrayUtil.test.js +0 -71
- package/build/dist/Tests/Types/ArrayUtil.test.js.map +0 -1
- package/build/dist/Tests/Types/Billing/SubscriptionPlan.test.js +0 -181
- package/build/dist/Tests/Types/Billing/SubscriptionPlan.test.js.map +0 -1
- package/build/dist/Tests/Types/BrandColors.test.js +0 -124
- package/build/dist/Tests/Types/BrandColors.test.js.map +0 -1
- package/build/dist/Tests/Types/Char.test.js +0 -82
- package/build/dist/Tests/Types/Char.test.js.map +0 -1
- package/build/dist/Tests/Types/Code/CodeType.test.js +0 -13
- package/build/dist/Tests/Types/Code/CodeType.test.js.map +0 -1
- package/build/dist/Tests/Types/Color.test.js +0 -44
- package/build/dist/Tests/Types/Color.test.js.map +0 -1
- package/build/dist/Tests/Types/Company/CompanySize.test.js +0 -20
- package/build/dist/Tests/Types/Company/CompanySize.test.js.map +0 -1
- package/build/dist/Tests/Types/Company/JobRole.test.js +0 -22
- package/build/dist/Tests/Types/Company/JobRole.test.js.map +0 -1
- package/build/dist/Tests/Types/Countries.test.js +0 -249
- package/build/dist/Tests/Types/Countries.test.js.map +0 -1
- package/build/dist/Tests/Types/Database/ColumnLength.test.js +0 -43
- package/build/dist/Tests/Types/Database/ColumnLength.test.js.map +0 -1
- package/build/dist/Tests/Types/Database/ColumnType.test.js +0 -79
- package/build/dist/Tests/Types/Database/ColumnType.test.js.map +0 -1
- package/build/dist/Tests/Types/Database/Columns.test.js +0 -20
- package/build/dist/Tests/Types/Database/Columns.test.js.map +0 -1
- package/build/dist/Tests/Types/Database/CompareBase.test.js +0 -37
- package/build/dist/Tests/Types/Database/CompareBase.test.js.map +0 -1
- package/build/dist/Tests/Types/Database/Date.test.js +0 -62
- package/build/dist/Tests/Types/Database/Date.test.js.map +0 -1
- package/build/dist/Tests/Types/Database/EqualTo.test.js +0 -65
- package/build/dist/Tests/Types/Database/EqualTo.test.js.map +0 -1
- package/build/dist/Tests/Types/Database/EqualToOrNull.test.js +0 -62
- package/build/dist/Tests/Types/Database/EqualToOrNull.test.js.map +0 -1
- package/build/dist/Tests/Types/Database/InBetween.test.js +0 -72
- package/build/dist/Tests/Types/Database/InBetween.test.js.map +0 -1
- package/build/dist/Tests/Types/Database/LimitMax.test.js +0 -18
- package/build/dist/Tests/Types/Database/LimitMax.test.js.map +0 -1
- package/build/dist/Tests/Types/Database/NotEqual.test.js +0 -19
- package/build/dist/Tests/Types/Database/NotEqual.test.js.map +0 -1
- package/build/dist/Tests/Types/Database/Search.test.js +0 -10
- package/build/dist/Tests/Types/Database/Search.test.js.map +0 -1
- package/build/dist/Tests/Types/DatabaseType.test.js +0 -7
- package/build/dist/Tests/Types/DatabaseType.test.js.map +0 -1
- package/build/dist/Tests/Types/Date.test.js +0 -194
- package/build/dist/Tests/Types/Date.test.js.map +0 -1
- package/build/dist/Tests/Types/Dictionary.test.js +0 -25
- package/build/dist/Tests/Types/Dictionary.test.js.map +0 -1
- package/build/dist/Tests/Types/Domain.test.js +0 -54
- package/build/dist/Tests/Types/Domain.test.js.map +0 -1
- package/build/dist/Tests/Types/Email/Email.test.js +0 -51
- package/build/dist/Tests/Types/Email/Email.test.js.map +0 -1
- package/build/dist/Tests/Types/EmailWithName.test.js +0 -36
- package/build/dist/Tests/Types/EmailWithName.test.js.map +0 -1
- package/build/dist/Tests/Types/EncryptionAlgorithm.test.js +0 -7
- package/build/dist/Tests/Types/EncryptionAlgorithm.test.js.map +0 -1
- package/build/dist/Tests/Types/Exception/ApiException.test.js +0 -10
- package/build/dist/Tests/Types/Exception/ApiException.test.js.map +0 -1
- package/build/dist/Tests/Types/Exception/BadDataException.test.js +0 -12
- package/build/dist/Tests/Types/Exception/BadDataException.test.js.map +0 -1
- package/build/dist/Tests/Types/Exception/BadOperationException.test.js +0 -10
- package/build/dist/Tests/Types/Exception/BadOperationException.test.js.map +0 -1
- package/build/dist/Tests/Types/Exception/BadRequestException.test.js +0 -12
- package/build/dist/Tests/Types/Exception/BadRequestException.test.js.map +0 -1
- package/build/dist/Tests/Types/Exception/DatabaseNotConnectedException.test.js +0 -10
- package/build/dist/Tests/Types/Exception/DatabaseNotConnectedException.test.js.map +0 -1
- package/build/dist/Tests/Types/Exception/Exception.test.js +0 -15
- package/build/dist/Tests/Types/Exception/Exception.test.js.map +0 -1
- package/build/dist/Tests/Types/Exception/NotImplementedException.test.js +0 -12
- package/build/dist/Tests/Types/Exception/NotImplementedException.test.js.map +0 -1
- package/build/dist/Tests/Types/File.test.js +0 -22
- package/build/dist/Tests/Types/File.test.js.map +0 -1
- package/build/dist/Tests/Types/HashedString.test.js +0 -51
- package/build/dist/Tests/Types/HashedString.test.js.map +0 -1
- package/build/dist/Tests/Types/Html.test.js +0 -8
- package/build/dist/Tests/Types/Html.test.js.map +0 -1
- package/build/dist/Tests/Types/IP/IP.test.js +0 -65
- package/build/dist/Tests/Types/IP/IP.test.js.map +0 -1
- package/build/dist/Tests/Types/IP/IPType.test.js +0 -10
- package/build/dist/Tests/Types/IP/IPType.test.js.map +0 -1
- package/build/dist/Tests/Types/IP/IPv4.test.js +0 -17
- package/build/dist/Tests/Types/IP/IPv4.test.js.map +0 -1
- package/build/dist/Tests/Types/IP/IPv6.test.js +0 -17
- package/build/dist/Tests/Types/IP/IPv6.test.js.map +0 -1
- package/build/dist/Tests/Types/JSON.test.js +0 -37
- package/build/dist/Tests/Types/JSON.test.js.map +0 -1
- package/build/dist/Tests/Types/JSONFunctions.test.js +0 -38
- package/build/dist/Tests/Types/JSONFunctions.test.js.map +0 -1
- package/build/dist/Tests/Types/ListData.test.js +0 -34
- package/build/dist/Tests/Types/ListData.test.js.map +0 -1
- package/build/dist/Tests/Types/Monitor/KubernetesAlertTemplates.test.js +0 -121
- package/build/dist/Tests/Types/Monitor/KubernetesAlertTemplates.test.js.map +0 -1
- package/build/dist/Tests/Types/Name.test.js +0 -26
- package/build/dist/Tests/Types/Name.test.js.map +0 -1
- package/build/dist/Tests/Types/ObjectID.test.js +0 -12
- package/build/dist/Tests/Types/ObjectID.test.js.map +0 -1
- package/build/dist/Tests/Types/OnCallDutyPolicy/LayerUtil.test.js +0 -530
- package/build/dist/Tests/Types/OnCallDutyPolicy/LayerUtil.test.js.map +0 -1
- package/build/dist/Tests/Types/Permission.test.js +0 -99
- package/build/dist/Tests/Types/Permission.test.js.map +0 -1
- package/build/dist/Tests/Types/Phone.test.js +0 -37
- package/build/dist/Tests/Types/Phone.test.js.map +0 -1
- package/build/dist/Tests/Types/Port.test.js +0 -35
- package/build/dist/Tests/Types/Port.test.js.map +0 -1
- package/build/dist/Tests/Types/PositiveNumber.test.js +0 -101
- package/build/dist/Tests/Types/PositiveNumber.test.js.map +0 -1
- package/build/dist/Tests/Types/SecuritySeverity.test.js +0 -16
- package/build/dist/Tests/Types/SecuritySeverity.test.js.map +0 -1
- package/build/dist/Tests/Types/SerializableObject.test.js +0 -37
- package/build/dist/Tests/Types/SerializableObject.test.js.map +0 -1
- package/build/dist/Tests/Types/Sleep.test.js +0 -14
- package/build/dist/Tests/Types/Sleep.test.js.map +0 -1
- package/build/dist/Tests/Types/Text.test.js +0 -8
- package/build/dist/Tests/Types/Text.test.js.map +0 -1
- package/build/dist/Tests/Types/Timezone.test.js +0 -596
- package/build/dist/Tests/Types/Timezone.test.js.map +0 -1
- package/build/dist/Tests/Types/Typeof.test.js +0 -16
- package/build/dist/Tests/Types/Typeof.test.js.map +0 -1
- package/build/dist/Tests/Types/UserType.test.js +0 -16
- package/build/dist/Tests/Types/UserType.test.js.map +0 -1
- package/build/dist/Tests/Types/Version.test.js +0 -35
- package/build/dist/Tests/Types/Version.test.js.map +0 -1
- package/build/dist/Tests/Types/XML.test.js +0 -35
- package/build/dist/Tests/Types/XML.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/404.test.js +0 -59
- package/build/dist/Tests/UI/Components/404.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/Alert.test.js +0 -83
- package/build/dist/Tests/UI/Components/Alert.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/Badge.test.js +0 -59
- package/build/dist/Tests/UI/Components/Badge.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/BasicForm.test.js +0 -92
- package/build/dist/Tests/UI/Components/BasicForm.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/Breadcrumbs.test.js +0 -69
- package/build/dist/Tests/UI/Components/Breadcrumbs.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/Button.test.js +0 -104
- package/build/dist/Tests/UI/Components/Button.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/Card.test.js +0 -81
- package/build/dist/Tests/UI/Components/Card.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/ColorViewer.test.js +0 -42
- package/build/dist/Tests/UI/Components/ColorViewer.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/ComponentsModal.test.js +0 -233
- package/build/dist/Tests/UI/Components/ComponentsModal.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/ConfirmModal.test.js +0 -57
- package/build/dist/Tests/UI/Components/ConfirmModal.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/DictionaryOfStrings.test.js +0 -84
- package/build/dist/Tests/UI/Components/DictionaryOfStrings.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/Dropdown.test.js +0 -146
- package/build/dist/Tests/UI/Components/Dropdown.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/DuplicateModel.test.js +0 -229
- package/build/dist/Tests/UI/Components/DuplicateModel.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/EmptyState/EmptyState.test.js +0 -26
- package/build/dist/Tests/UI/Components/EmptyState/EmptyState.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/ErrorBoundary.test.js +0 -32
- package/build/dist/Tests/UI/Components/ErrorBoundary.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/FilePicker.test.js +0 -342
- package/build/dist/Tests/UI/Components/FilePicker.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/HiddenText.test.js +0 -50
- package/build/dist/Tests/UI/Components/HiddenText.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/Input.test.js +0 -223
- package/build/dist/Tests/UI/Components/Input.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/Item.test.js +0 -58
- package/build/dist/Tests/UI/Components/Item.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/List.test.js +0 -83
- package/build/dist/Tests/UI/Components/List.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/Loader.test.js +0 -19
- package/build/dist/Tests/UI/Components/Loader.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/MarkdownEditor.test.js +0 -85
- package/build/dist/Tests/UI/Components/MarkdownEditor.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/MasterPage.test.js +0 -46
- package/build/dist/Tests/UI/Components/MasterPage.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/Modal.test.js +0 -127
- package/build/dist/Tests/UI/Components/Modal.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/NavBar.test.js +0 -52
- package/build/dist/Tests/UI/Components/NavBar.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/OrderedStatesList.test.js +0 -86
- package/build/dist/Tests/UI/Components/OrderedStatesList.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/Pagination.test.js +0 -137
- package/build/dist/Tests/UI/Components/Pagination.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/Pill.test.js +0 -55
- package/build/dist/Tests/UI/Components/Pill.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/Probe.test.js +0 -52
- package/build/dist/Tests/UI/Components/Probe.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/ProgressBar.test.js +0 -41
- package/build/dist/Tests/UI/Components/ProgressBar.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/RadioButtons.test.js +0 -66
- package/build/dist/Tests/UI/Components/RadioButtons.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/SideMenuItem.test.js +0 -99
- package/build/dist/Tests/UI/Components/SideMenuItem.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/SideOver.test.js +0 -77
- package/build/dist/Tests/UI/Components/SideOver.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/Tabs.test.js +0 -56
- package/build/dist/Tests/UI/Components/Tabs.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/Template/Template.test.js +0 -15
- package/build/dist/Tests/UI/Components/Template/Template.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/TextArea.test.js +0 -112
- package/build/dist/Tests/UI/Components/TextArea.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/TimePicker/TimePicker.test.js +0 -352
- package/build/dist/Tests/UI/Components/TimePicker/TimePicker.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/Toast.test.js +0 -48
- package/build/dist/Tests/UI/Components/Toast.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/Toggle.test.js +0 -95
- package/build/dist/Tests/UI/Components/Toggle.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/TopSection.test.js +0 -33
- package/build/dist/Tests/UI/Components/TopSection.test.js.map +0 -1
- package/build/dist/Tests/UI/Components/XAxis.test.js +0 -21
- package/build/dist/Tests/UI/Components/XAxis.test.js.map +0 -1
- package/build/dist/Tests/UI/Index.js +0 -2
- package/build/dist/Tests/UI/Index.js.map +0 -1
- package/build/dist/Tests/UI/Mocks/FileMock.js +0 -3
- package/build/dist/Tests/UI/Mocks/FileMock.js.map +0 -1
- package/build/dist/Tests/Utils/API.test.js +0 -399
- package/build/dist/Tests/Utils/API.test.js.map +0 -1
- package/build/dist/Tests/Utils/Analytics.test.js +0 -67
- package/build/dist/Tests/Utils/Analytics.test.js.map +0 -1
- package/build/dist/Tests/Utils/CronTime.test.js +0 -22
- package/build/dist/Tests/Utils/CronTime.test.js.map +0 -1
- package/build/dist/Tests/Utils/Faker.test.js +0 -27
- package/build/dist/Tests/Utils/Faker.test.js.map +0 -1
- package/build/dist/Tests/Utils/MetricUnitUtil.test.js +0 -187
- package/build/dist/Tests/Utils/MetricUnitUtil.test.js.map +0 -1
- package/build/dist/Tests/Utils/Metrics/MetricFormulaEvaluator.test.js +0 -224
- package/build/dist/Tests/Utils/Metrics/MetricFormulaEvaluator.test.js.map +0 -1
- package/build/dist/Tests/Utils/Metrics/MetricResultUnitConverter.test.js +0 -180
- package/build/dist/Tests/Utils/Metrics/MetricResultUnitConverter.test.js.map +0 -1
- package/build/dist/Tests/Utils/RecordingRuleExpression.test.js +0 -142
- package/build/dist/Tests/Utils/RecordingRuleExpression.test.js.map +0 -1
- package/build/dist/Tests/Utils/Slug.test.js +0 -20
- package/build/dist/Tests/Utils/Slug.test.js.map +0 -1
- package/build/dist/Tests/Utils/UUID.test.js +0 -48
- package/build/dist/Tests/Utils/UUID.test.js.map +0 -1
- package/build/dist/Tests/jest.setup.js +0 -30
- package/build/dist/Tests/jest.setup.js.map +0 -1
- package/build/dist/Types/Profile/ProfileMetricType.js +0 -17
- package/build/dist/Types/Profile/ProfileMetricType.js.map +0 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SQL, Statement } from "../Utils/AnalyticsDatabase/Statement";
|
|
2
|
+
import { getQuerySettings } from "../Utils/AnalyticsDatabase/QuerySettingsHelper";
|
|
2
3
|
import SpanService from "./SpanService";
|
|
3
4
|
import TableColumnType from "../../Types/AnalyticsDatabase/TableColumnType";
|
|
4
5
|
import { JSONObject } from "../../Types/JSON";
|
|
@@ -19,13 +20,39 @@ export interface HistogramBucket {
|
|
|
19
20
|
|
|
20
21
|
export interface TraceFilters {
|
|
21
22
|
serviceIds?: Array<ObjectID> | undefined;
|
|
23
|
+
entityKeys?: Array<string> | undefined;
|
|
22
24
|
statusCodes?: Array<number> | undefined;
|
|
23
25
|
spanKinds?: Array<string> | undefined;
|
|
24
26
|
spanNames?: Array<string> | undefined;
|
|
27
|
+
/*
|
|
28
|
+
* Substring name matches (ANDed). The span list compiles a single `name`
|
|
29
|
+
* filter to `name ILIKE '%v%'` (Search) — aggregations must use the same
|
|
30
|
+
* semantics or the histogram/facets disagree with the list. `spanNames`
|
|
31
|
+
* stays exact-match for multi-value filters (list-side `Includes`).
|
|
32
|
+
*/
|
|
33
|
+
spanNameSearches?: Array<string> | undefined;
|
|
34
|
+
spanIds?: Array<string> | undefined;
|
|
25
35
|
traceIds?: Array<string> | undefined;
|
|
26
36
|
nameSearchText?: string | undefined;
|
|
37
|
+
statusMessageSearchText?: string | undefined;
|
|
38
|
+
// Exact-match for multi-value statusMessage filters (list-side `Includes`).
|
|
39
|
+
statusMessages?: Array<string> | undefined;
|
|
40
|
+
hasException?: boolean | undefined;
|
|
41
|
+
/*
|
|
42
|
+
* Strict bounds (`>` / `<`) — the list compiles duration:>N / duration:<N
|
|
43
|
+
* to GreaterThan / LessThan, which are strict comparisons. `duration:N`
|
|
44
|
+
* (no operator) is exact equality, carried by exactDurationNano.
|
|
45
|
+
*/
|
|
46
|
+
minDurationNano?: number | undefined;
|
|
47
|
+
maxDurationNano?: number | undefined;
|
|
48
|
+
exactDurationNano?: number | undefined;
|
|
27
49
|
rootOnly?: boolean | undefined;
|
|
28
50
|
attributes?: Record<string, string> | undefined;
|
|
51
|
+
/*
|
|
52
|
+
* Substring (contains) attribute matches — `@key:~value` in the explorer.
|
|
53
|
+
* Same case-insensitive key matching as `attributes`, value via ILIKE.
|
|
54
|
+
*/
|
|
55
|
+
attributeSearches?: Record<string, string> | undefined;
|
|
29
56
|
}
|
|
30
57
|
|
|
31
58
|
export interface HistogramRequest extends TraceFilters {
|
|
@@ -35,6 +62,57 @@ export interface HistogramRequest extends TraceFilters {
|
|
|
35
62
|
bucketSizeInMinutes: number;
|
|
36
63
|
}
|
|
37
64
|
|
|
65
|
+
export type TraceAnalyticsChartType = "timeseries" | "toplist" | "table";
|
|
66
|
+
|
|
67
|
+
export type TraceAnalyticsMetric =
|
|
68
|
+
| "count"
|
|
69
|
+
| "errorCount"
|
|
70
|
+
| "avgDuration"
|
|
71
|
+
| "minDuration"
|
|
72
|
+
| "maxDuration"
|
|
73
|
+
| "p50Duration"
|
|
74
|
+
| "p90Duration"
|
|
75
|
+
| "p95Duration"
|
|
76
|
+
| "p99Duration";
|
|
77
|
+
|
|
78
|
+
export interface TraceAnalyticsRequest extends TraceFilters {
|
|
79
|
+
projectId: ObjectID;
|
|
80
|
+
startTime: Date;
|
|
81
|
+
endTime: Date;
|
|
82
|
+
bucketSizeInMinutes: number;
|
|
83
|
+
chartType: TraceAnalyticsChartType;
|
|
84
|
+
metric: TraceAnalyticsMetric;
|
|
85
|
+
/*
|
|
86
|
+
* Up to two dimensions: top-level Span columns (name, primaryEntityId,
|
|
87
|
+
* kind, statusCode, ...) or span attribute keys (e.g. url.host).
|
|
88
|
+
*/
|
|
89
|
+
groupBy?: Array<string> | undefined;
|
|
90
|
+
limit?: number | undefined;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface TraceAnalyticsTimeseriesRow {
|
|
94
|
+
time: string;
|
|
95
|
+
// Metric value — a count, or milliseconds for duration metrics.
|
|
96
|
+
value: number;
|
|
97
|
+
groupValues: Record<string, string>;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface TraceAnalyticsTopItem {
|
|
101
|
+
value: string;
|
|
102
|
+
// The selected metric for this dimension value.
|
|
103
|
+
metricValue: number;
|
|
104
|
+
count: number;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface TraceAnalyticsTableRow {
|
|
108
|
+
groupValues: Record<string, string>;
|
|
109
|
+
count: number;
|
|
110
|
+
avgDurationMs: number;
|
|
111
|
+
p50DurationMs: number;
|
|
112
|
+
minDurationMs: number;
|
|
113
|
+
maxDurationMs: number;
|
|
114
|
+
}
|
|
115
|
+
|
|
38
116
|
export interface FacetValue {
|
|
39
117
|
value: string;
|
|
40
118
|
count: number;
|
|
@@ -62,7 +140,7 @@ export class TraceAggregationService {
|
|
|
62
140
|
private static readonly DEFAULT_FACET_LIMIT: number = 500;
|
|
63
141
|
private static readonly TABLE_NAME: string = AnalyticsTableName.Span;
|
|
64
142
|
private static readonly TOP_LEVEL_COLUMNS: Set<string> = new Set([
|
|
65
|
-
"
|
|
143
|
+
"primaryEntityId",
|
|
66
144
|
"traceId",
|
|
67
145
|
"spanId",
|
|
68
146
|
"parentSpanId",
|
|
@@ -73,8 +151,8 @@ export class TraceAggregationService {
|
|
|
73
151
|
]);
|
|
74
152
|
/*
|
|
75
153
|
* Virtual facet keys — same scheme as LogAggregationService. The
|
|
76
|
-
* `
|
|
77
|
-
* disambiguated by the `
|
|
154
|
+
* `primaryEntityId` slot is reused for host / docker host / k8s cluster
|
|
155
|
+
* ids, disambiguated by the `primaryEntityType` discriminator.
|
|
78
156
|
*/
|
|
79
157
|
private static readonly RESOURCE_FACET_KEYS: Map<string, ServiceType> =
|
|
80
158
|
new Map([
|
|
@@ -87,6 +165,17 @@ export class TraceAggregationService {
|
|
|
87
165
|
]);
|
|
88
166
|
private static readonly ATTRIBUTE_KEY_PATTERN: RegExp = /^[a-zA-Z0-9._:/-]+$/;
|
|
89
167
|
private static readonly MAX_FACET_KEY_LENGTH: number = 256;
|
|
168
|
+
/*
|
|
169
|
+
* Read-side retention filter for raw-table queries (rows past their
|
|
170
|
+
* per-service retention stay in their part until the whole part drops
|
|
171
|
+
* — ttl_only_drop_parts). Deliberately NOT applied to the
|
|
172
|
+
* projection-shaped queries (histogram / resource facet counts): the
|
|
173
|
+
* proj_hist_by_minute aggregate projection does not store
|
|
174
|
+
* retentionDate, so the predicate would silently force a full
|
|
175
|
+
* base-table scan.
|
|
176
|
+
*/
|
|
177
|
+
private static readonly RETENTION_FILTER: string =
|
|
178
|
+
" AND retentionDate >= now()";
|
|
90
179
|
|
|
91
180
|
@CaptureSpan()
|
|
92
181
|
public static async getHistogram(
|
|
@@ -199,11 +288,14 @@ export class TraceAggregationService {
|
|
|
199
288
|
selectColumns.push(...topLevelKeys);
|
|
200
289
|
}
|
|
201
290
|
if (resourceKeys.length > 0) {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
291
|
+
/*
|
|
292
|
+
* Virtual facets read out of primaryEntityId disambiguated by
|
|
293
|
+
* primaryEntityType.
|
|
294
|
+
*/
|
|
295
|
+
if (!selectColumns.includes("primaryEntityId")) {
|
|
296
|
+
selectColumns.push("primaryEntityId");
|
|
205
297
|
}
|
|
206
|
-
selectColumns.push("
|
|
298
|
+
selectColumns.push("primaryEntityType");
|
|
207
299
|
}
|
|
208
300
|
if (attributeKeys.length > 0) {
|
|
209
301
|
selectColumns.push("attributes");
|
|
@@ -234,6 +326,8 @@ export class TraceAggregationService {
|
|
|
234
326
|
}}`,
|
|
235
327
|
);
|
|
236
328
|
|
|
329
|
+
statement.append(TraceAggregationService.RETENTION_FILTER);
|
|
330
|
+
|
|
237
331
|
TraceAggregationService.appendCommonFilters(statement, request);
|
|
238
332
|
|
|
239
333
|
statement.append(
|
|
@@ -249,7 +343,10 @@ export class TraceAggregationService {
|
|
|
249
343
|
* proxy_read_timeout regardless.
|
|
250
344
|
*/
|
|
251
345
|
statement.append(
|
|
252
|
-
|
|
346
|
+
getQuerySettings({
|
|
347
|
+
maxExecutionTimeInSeconds: 45,
|
|
348
|
+
timeoutOverflowMode: "break",
|
|
349
|
+
}),
|
|
253
350
|
);
|
|
254
351
|
|
|
255
352
|
const dbResult: Results = await SpanService.executeQuery(statement);
|
|
@@ -280,10 +377,11 @@ export class TraceAggregationService {
|
|
|
280
377
|
|
|
281
378
|
if (resourceKeys.length > 0) {
|
|
282
379
|
const rowServiceType: string =
|
|
283
|
-
row["
|
|
380
|
+
row["primaryEntityType"] === undefined ||
|
|
381
|
+
row["primaryEntityType"] === null
|
|
284
382
|
? ""
|
|
285
|
-
: String(row["
|
|
286
|
-
const rowServiceId: unknown = row["
|
|
383
|
+
: String(row["primaryEntityType"]);
|
|
384
|
+
const rowServiceId: unknown = row["primaryEntityId"];
|
|
287
385
|
if (rowServiceId !== undefined && rowServiceId !== null) {
|
|
288
386
|
const value: string = String(rowServiceId);
|
|
289
387
|
if (value.length > 0) {
|
|
@@ -354,27 +452,30 @@ export class TraceAggregationService {
|
|
|
354
452
|
* exact regardless of skew.
|
|
355
453
|
*
|
|
356
454
|
* It is cheap because it rides the proj_hist_by_minute aggregate projection
|
|
357
|
-
* (projectId, minute,
|
|
358
|
-
* window reads a few thousand pre-aggregated minute rows in
|
|
359
|
-
* instead of scanning tens of millions of raw spans. Two
|
|
360
|
-
* for ClickHouse to actually pick that projection, both
|
|
455
|
+
* (projectId, minute, primaryEntityId, statusCode, isRootSpan -> count): a
|
|
456
|
+
* 1-month window reads a few thousand pre-aggregated minute rows in
|
|
457
|
+
* single-digit ms instead of scanning tens of millions of raw spans. Two
|
|
458
|
+
* things are required for ClickHouse to actually pick that projection, both
|
|
459
|
+
* load-bearing:
|
|
361
460
|
* 1. The time predicate must be on toStartOfMinute(startTime) — the
|
|
362
461
|
* projection's key expression — NOT raw startTime. A raw startTime
|
|
363
462
|
* filter references a column the aggregate projection does not store, so
|
|
364
463
|
* ClickHouse rejects the projection and full-scans. (Window edges land
|
|
365
464
|
* on minute boundaries, consistent with the minute-bucketed histogram.)
|
|
366
465
|
* 2. Every other predicate must be on a projection column. isRootSpan,
|
|
367
|
-
*
|
|
368
|
-
* drill-down-by-service stay on the projection. A non-projection
|
|
369
|
-
* (kind / name / traceId / attributes)
|
|
370
|
-
* base-table scan — still correct, still
|
|
466
|
+
* primaryEntityId and statusCode all are, so the default sidebar load
|
|
467
|
+
* and drill-down-by-service stay on the projection. A non-projection
|
|
468
|
+
* filter (kind / name / traceId / entityKeys / attributes)
|
|
469
|
+
* transparently falls back to a base-table scan — still correct, still
|
|
470
|
+
* bounded by max_execution_time.
|
|
371
471
|
*
|
|
372
|
-
*
|
|
373
|
-
* IDs are globally unique, so a single
|
|
374
|
-
* serves the service / host / docker host / k8s cluster
|
|
375
|
-
* against each Postgres source-of-truth list (a host id
|
|
376
|
-
* a service id, so an unrelated entry is simply never
|
|
377
|
-
* the
|
|
472
|
+
* primaryEntityId is intentionally NOT disambiguated by primaryEntityType
|
|
473
|
+
* here. Resource IDs are globally unique, so a single primaryEntityId ->
|
|
474
|
+
* count map correctly serves the service / host / docker host / k8s cluster
|
|
475
|
+
* facets once merged against each Postgres source-of-truth list (a host id
|
|
476
|
+
* never collides with a service id, so an unrelated entry is simply never
|
|
477
|
+
* looked up). Omitting the primaryEntityType predicate keeps the query
|
|
478
|
+
* projection-eligible.
|
|
378
479
|
*/
|
|
379
480
|
@CaptureSpan()
|
|
380
481
|
public static async getResourceFacetCounts(
|
|
@@ -385,7 +486,7 @@ export class TraceAggregationService {
|
|
|
385
486
|
}> {
|
|
386
487
|
const statement: Statement = new Statement();
|
|
387
488
|
statement.append(
|
|
388
|
-
`SELECT
|
|
489
|
+
`SELECT primaryEntityId, statusCode, count() AS cnt FROM ${TraceAggregationService.TABLE_NAME}`,
|
|
389
490
|
);
|
|
390
491
|
statement.append(
|
|
391
492
|
SQL` WHERE projectId = ${{
|
|
@@ -402,7 +503,7 @@ export class TraceAggregationService {
|
|
|
402
503
|
|
|
403
504
|
TraceAggregationService.appendCommonFilters(statement, request);
|
|
404
505
|
|
|
405
|
-
statement.append(" GROUP BY
|
|
506
|
+
statement.append(" GROUP BY primaryEntityId, statusCode");
|
|
406
507
|
|
|
407
508
|
/*
|
|
408
509
|
* Cap runtime below nginx's 60s proxy_read_timeout and explicitly allow
|
|
@@ -410,7 +511,11 @@ export class TraceAggregationService {
|
|
|
410
511
|
* toStartOfMinute note above).
|
|
411
512
|
*/
|
|
412
513
|
statement.append(
|
|
413
|
-
|
|
514
|
+
getQuerySettings({
|
|
515
|
+
maxExecutionTimeInSeconds: 45,
|
|
516
|
+
timeoutOverflowMode: "break",
|
|
517
|
+
additionalSettings: { optimize_use_projections: 1 },
|
|
518
|
+
}),
|
|
414
519
|
);
|
|
415
520
|
|
|
416
521
|
const serviceCounts: Map<string, number> = new Map<string, number>();
|
|
@@ -439,7 +544,7 @@ export class TraceAggregationService {
|
|
|
439
544
|
for (const row of rows) {
|
|
440
545
|
const cnt: number = Number(row["cnt"] || 0);
|
|
441
546
|
|
|
442
|
-
const rawServiceId: unknown = row["
|
|
547
|
+
const rawServiceId: unknown = row["primaryEntityId"];
|
|
443
548
|
if (rawServiceId !== undefined && rawServiceId !== null) {
|
|
444
549
|
const serviceId: string = String(rawServiceId);
|
|
445
550
|
if (serviceId.length > 0) {
|
|
@@ -490,9 +595,13 @@ export class TraceAggregationService {
|
|
|
490
595
|
* minute-bucketed output and only shifts the first/last bucket by the
|
|
491
596
|
* partial boundary minute when the range is not minute-aligned.
|
|
492
597
|
*
|
|
493
|
-
* If any non-projection filter (kind, name, traceId,
|
|
494
|
-
*
|
|
495
|
-
*
|
|
598
|
+
* If any non-projection filter (kind, name, traceId, spanId,
|
|
599
|
+
* nameSearchText, spanNameSearches, statusMessageSearchText,
|
|
600
|
+
* hasException, duration bounds, entityKeys, attributes) is active,
|
|
601
|
+
* ClickHouse transparently falls back to scanning the main table for the
|
|
602
|
+
* inner query — same cost as before.
|
|
603
|
+
* The retention read-filter is omitted for the same reason (see
|
|
604
|
+
* RETENTION_FILTER).
|
|
496
605
|
*/
|
|
497
606
|
const statement: Statement = SQL`
|
|
498
607
|
SELECT
|
|
@@ -535,13 +644,22 @@ export class TraceAggregationService {
|
|
|
535
644
|
* a density visualization. Explicitly enable projection use.
|
|
536
645
|
*/
|
|
537
646
|
statement.append(
|
|
538
|
-
|
|
647
|
+
getQuerySettings({
|
|
648
|
+
maxExecutionTimeInSeconds: 45,
|
|
649
|
+
timeoutOverflowMode: "break",
|
|
650
|
+
additionalSettings: { optimize_use_projections: 1 },
|
|
651
|
+
}),
|
|
539
652
|
);
|
|
540
653
|
|
|
541
654
|
return statement;
|
|
542
655
|
}
|
|
543
656
|
|
|
544
657
|
private static buildFacetStatement(request: FacetRequest): Statement {
|
|
658
|
+
// Pre-rename alias from stale clients; the V3 column is primaryEntityId.
|
|
659
|
+
if (request.facetKey === "serviceId") {
|
|
660
|
+
request.facetKey = "primaryEntityId";
|
|
661
|
+
}
|
|
662
|
+
|
|
545
663
|
const limit: number =
|
|
546
664
|
request.limit ?? TraceAggregationService.DEFAULT_FACET_LIMIT;
|
|
547
665
|
|
|
@@ -558,7 +676,7 @@ export class TraceAggregationService {
|
|
|
558
676
|
|
|
559
677
|
if (isResourceFacet) {
|
|
560
678
|
statement.append(
|
|
561
|
-
SQL`SELECT toString(
|
|
679
|
+
SQL`SELECT toString(primaryEntityId) AS val, count() AS cnt FROM ${TraceAggregationService.TABLE_NAME}`,
|
|
562
680
|
);
|
|
563
681
|
} else if (isTopLevelColumn) {
|
|
564
682
|
statement.append(
|
|
@@ -566,10 +684,10 @@ export class TraceAggregationService {
|
|
|
566
684
|
);
|
|
567
685
|
} else {
|
|
568
686
|
statement.append(
|
|
569
|
-
SQL`SELECT
|
|
687
|
+
SQL`SELECT attributes[${{
|
|
570
688
|
type: TableColumnType.Text,
|
|
571
689
|
value: request.facetKey,
|
|
572
|
-
}}
|
|
690
|
+
}}] AS val, count() AS cnt FROM ${TraceAggregationService.TABLE_NAME}`,
|
|
573
691
|
);
|
|
574
692
|
}
|
|
575
693
|
|
|
@@ -588,27 +706,29 @@ export class TraceAggregationService {
|
|
|
588
706
|
|
|
589
707
|
if (isResourceFacet) {
|
|
590
708
|
statement.append(
|
|
591
|
-
SQL` AND
|
|
709
|
+
SQL` AND primaryEntityType = ${{
|
|
592
710
|
type: TableColumnType.Text,
|
|
593
711
|
value: resourceServiceType as string,
|
|
594
712
|
}}`,
|
|
595
713
|
);
|
|
596
|
-
} else if (request.facetKey === "
|
|
714
|
+
} else if (request.facetKey === "primaryEntityId") {
|
|
597
715
|
statement.append(
|
|
598
|
-
SQL` AND (
|
|
716
|
+
SQL` AND (primaryEntityType = '' OR primaryEntityType = ${{
|
|
599
717
|
type: TableColumnType.Text,
|
|
600
718
|
value: ServiceType.OpenTelemetry as string,
|
|
601
719
|
}})`,
|
|
602
720
|
);
|
|
603
721
|
} else if (!isTopLevelColumn) {
|
|
604
722
|
statement.append(
|
|
605
|
-
SQL` AND
|
|
723
|
+
SQL` AND mapContains(attributes, ${{
|
|
606
724
|
type: TableColumnType.Text,
|
|
607
725
|
value: request.facetKey,
|
|
608
|
-
}})
|
|
726
|
+
}})`,
|
|
609
727
|
);
|
|
610
728
|
}
|
|
611
729
|
|
|
730
|
+
statement.append(TraceAggregationService.RETENTION_FILTER);
|
|
731
|
+
|
|
612
732
|
TraceAggregationService.appendCommonFilters(statement, request);
|
|
613
733
|
|
|
614
734
|
statement.append(
|
|
@@ -623,7 +743,10 @@ export class TraceAggregationService {
|
|
|
623
743
|
* 60s proxy_read_timeout so a slow facet never starves the endpoint.
|
|
624
744
|
*/
|
|
625
745
|
statement.append(
|
|
626
|
-
|
|
746
|
+
getQuerySettings({
|
|
747
|
+
maxExecutionTimeInSeconds: 45,
|
|
748
|
+
timeoutOverflowMode: "break",
|
|
749
|
+
}),
|
|
627
750
|
);
|
|
628
751
|
|
|
629
752
|
return statement;
|
|
@@ -639,7 +762,7 @@ export class TraceAggregationService {
|
|
|
639
762
|
|
|
640
763
|
if (request.serviceIds && request.serviceIds.length > 0) {
|
|
641
764
|
statement.append(
|
|
642
|
-
SQL` AND
|
|
765
|
+
SQL` AND primaryEntityId IN (${{
|
|
643
766
|
type: TableColumnType.ObjectID,
|
|
644
767
|
value: new Includes(
|
|
645
768
|
request.serviceIds.map((id: ObjectID) => {
|
|
@@ -650,6 +773,15 @@ export class TraceAggregationService {
|
|
|
650
773
|
);
|
|
651
774
|
}
|
|
652
775
|
|
|
776
|
+
if (request.entityKeys && request.entityKeys.length > 0) {
|
|
777
|
+
statement.append(
|
|
778
|
+
SQL` AND hasAny(entityKeys, ${{
|
|
779
|
+
type: TableColumnType.ArrayText,
|
|
780
|
+
value: request.entityKeys,
|
|
781
|
+
}})`,
|
|
782
|
+
);
|
|
783
|
+
}
|
|
784
|
+
|
|
653
785
|
if (request.statusCodes && request.statusCodes.length > 0) {
|
|
654
786
|
statement.append(
|
|
655
787
|
SQL` AND statusCode IN (${{
|
|
@@ -681,6 +813,34 @@ export class TraceAggregationService {
|
|
|
681
813
|
);
|
|
682
814
|
}
|
|
683
815
|
|
|
816
|
+
/*
|
|
817
|
+
* Values are kept verbatim (no trim) — the list-side Search serialization
|
|
818
|
+
* wraps the raw value in %...%, and quoted search values deliberately
|
|
819
|
+
* preserve whitespace. Only blank entries are skipped.
|
|
820
|
+
*/
|
|
821
|
+
if (request.spanNameSearches && request.spanNameSearches.length > 0) {
|
|
822
|
+
for (const search of request.spanNameSearches) {
|
|
823
|
+
if (search.trim().length === 0) {
|
|
824
|
+
continue;
|
|
825
|
+
}
|
|
826
|
+
statement.append(
|
|
827
|
+
SQL` AND name ILIKE ${{
|
|
828
|
+
type: TableColumnType.Text,
|
|
829
|
+
value: `%${search}%`,
|
|
830
|
+
}}`,
|
|
831
|
+
);
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
if (request.spanIds && request.spanIds.length > 0) {
|
|
836
|
+
statement.append(
|
|
837
|
+
SQL` AND spanId IN (${{
|
|
838
|
+
type: TableColumnType.Text,
|
|
839
|
+
value: new Includes(request.spanIds),
|
|
840
|
+
}})`,
|
|
841
|
+
);
|
|
842
|
+
}
|
|
843
|
+
|
|
684
844
|
if (request.traceIds && request.traceIds.length > 0) {
|
|
685
845
|
statement.append(
|
|
686
846
|
SQL` AND traceId IN (${{
|
|
@@ -699,6 +859,75 @@ export class TraceAggregationService {
|
|
|
699
859
|
);
|
|
700
860
|
}
|
|
701
861
|
|
|
862
|
+
if (
|
|
863
|
+
request.statusMessageSearchText &&
|
|
864
|
+
request.statusMessageSearchText.trim().length > 0
|
|
865
|
+
) {
|
|
866
|
+
statement.append(
|
|
867
|
+
SQL` AND statusMessage ILIKE ${{
|
|
868
|
+
type: TableColumnType.Text,
|
|
869
|
+
value: `%${request.statusMessageSearchText}%`,
|
|
870
|
+
}}`,
|
|
871
|
+
);
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
if (request.statusMessages && request.statusMessages.length > 0) {
|
|
875
|
+
statement.append(
|
|
876
|
+
SQL` AND statusMessage IN (${{
|
|
877
|
+
type: TableColumnType.Text,
|
|
878
|
+
value: new Includes(request.statusMessages),
|
|
879
|
+
}})`,
|
|
880
|
+
);
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
if (request.hasException !== undefined) {
|
|
884
|
+
statement.append(
|
|
885
|
+
request.hasException
|
|
886
|
+
? " AND hasException = 1"
|
|
887
|
+
: " AND hasException = 0",
|
|
888
|
+
);
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
/*
|
|
892
|
+
* durationUnixNano is LongNumber (Int128) — a Number (Int32) param would
|
|
893
|
+
* overflow for spans longer than ~2.1 seconds.
|
|
894
|
+
*/
|
|
895
|
+
if (
|
|
896
|
+
request.minDurationNano !== undefined &&
|
|
897
|
+
!isNaN(request.minDurationNano)
|
|
898
|
+
) {
|
|
899
|
+
statement.append(
|
|
900
|
+
SQL` AND durationUnixNano > ${{
|
|
901
|
+
type: TableColumnType.LongNumber,
|
|
902
|
+
value: request.minDurationNano,
|
|
903
|
+
}}`,
|
|
904
|
+
);
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
if (
|
|
908
|
+
request.maxDurationNano !== undefined &&
|
|
909
|
+
!isNaN(request.maxDurationNano)
|
|
910
|
+
) {
|
|
911
|
+
statement.append(
|
|
912
|
+
SQL` AND durationUnixNano < ${{
|
|
913
|
+
type: TableColumnType.LongNumber,
|
|
914
|
+
value: request.maxDurationNano,
|
|
915
|
+
}}`,
|
|
916
|
+
);
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
if (
|
|
920
|
+
request.exactDurationNano !== undefined &&
|
|
921
|
+
!isNaN(request.exactDurationNano)
|
|
922
|
+
) {
|
|
923
|
+
statement.append(
|
|
924
|
+
SQL` AND durationUnixNano = ${{
|
|
925
|
+
type: TableColumnType.LongNumber,
|
|
926
|
+
value: request.exactDurationNano,
|
|
927
|
+
}}`,
|
|
928
|
+
);
|
|
929
|
+
}
|
|
930
|
+
|
|
702
931
|
if (request.attributes && Object.keys(request.attributes).length > 0) {
|
|
703
932
|
for (const [attrKey, attrValue] of Object.entries(request.attributes)) {
|
|
704
933
|
TraceAggregationService.validateFacetKey(attrKey);
|
|
@@ -719,6 +948,609 @@ export class TraceAggregationService {
|
|
|
719
948
|
);
|
|
720
949
|
}
|
|
721
950
|
}
|
|
951
|
+
|
|
952
|
+
if (
|
|
953
|
+
request.attributeSearches &&
|
|
954
|
+
Object.keys(request.attributeSearches).length > 0
|
|
955
|
+
) {
|
|
956
|
+
for (const [attrKey, attrValue] of Object.entries(
|
|
957
|
+
request.attributeSearches,
|
|
958
|
+
)) {
|
|
959
|
+
TraceAggregationService.validateFacetKey(attrKey);
|
|
960
|
+
|
|
961
|
+
if (attrValue.trim().length === 0) {
|
|
962
|
+
continue;
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
// Same key matching as `attributes`, contains-match on the value.
|
|
966
|
+
statement.append(
|
|
967
|
+
SQL` AND arrayExists((k, v) -> lowerUTF8(k) = lowerUTF8(${{
|
|
968
|
+
type: TableColumnType.Text,
|
|
969
|
+
value: attrKey,
|
|
970
|
+
}}) AND v ILIKE ${{
|
|
971
|
+
type: TableColumnType.Text,
|
|
972
|
+
value: `%${attrValue}%`,
|
|
973
|
+
}}, mapKeys(attributes), mapValues(attributes))`,
|
|
974
|
+
);
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
private static readonly DEFAULT_ANALYTICS_LIMIT: number = 10;
|
|
980
|
+
private static readonly MAX_GROUP_BY_DIMENSIONS: number = 2;
|
|
981
|
+
|
|
982
|
+
/*
|
|
983
|
+
* Metric → ClickHouse aggregate expression. Values are an allowlist — the
|
|
984
|
+
* expression is interpolated into SQL, so it must never come from user
|
|
985
|
+
* input directly. Durations are converted to milliseconds.
|
|
986
|
+
*/
|
|
987
|
+
private static readonly METRIC_EXPRESSIONS: Record<
|
|
988
|
+
TraceAnalyticsMetric,
|
|
989
|
+
string
|
|
990
|
+
> = {
|
|
991
|
+
count: "count()",
|
|
992
|
+
errorCount: "countIf(statusCode = 2)",
|
|
993
|
+
avgDuration: "avg(durationUnixNano) / 1000000",
|
|
994
|
+
minDuration: "min(durationUnixNano) / 1000000",
|
|
995
|
+
maxDuration: "max(durationUnixNano) / 1000000",
|
|
996
|
+
p50Duration: "quantile(0.5)(durationUnixNano) / 1000000",
|
|
997
|
+
p90Duration: "quantile(0.9)(durationUnixNano) / 1000000",
|
|
998
|
+
p95Duration: "quantile(0.95)(durationUnixNano) / 1000000",
|
|
999
|
+
p99Duration: "quantile(0.99)(durationUnixNano) / 1000000",
|
|
1000
|
+
};
|
|
1001
|
+
|
|
1002
|
+
public static isValidAnalyticsMetric(
|
|
1003
|
+
metric: string,
|
|
1004
|
+
): metric is TraceAnalyticsMetric {
|
|
1005
|
+
return Object.prototype.hasOwnProperty.call(
|
|
1006
|
+
TraceAggregationService.METRIC_EXPRESSIONS,
|
|
1007
|
+
metric,
|
|
1008
|
+
);
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
/*
|
|
1012
|
+
* Multidimensional span analytics — the interactive "split by dimension"
|
|
1013
|
+
* path (count / duration percentiles grouped by a span column or
|
|
1014
|
+
* attribute). Mirrors the logs analytics architecture
|
|
1015
|
+
* (LogAggregationService.getAnalyticsTimeseries and friends) and shares
|
|
1016
|
+
* appendCommonFilters with the histogram/facets, so every explorer filter
|
|
1017
|
+
* applies identically.
|
|
1018
|
+
*/
|
|
1019
|
+
@CaptureSpan()
|
|
1020
|
+
public static async getAnalyticsTimeseries(
|
|
1021
|
+
request: TraceAnalyticsRequest,
|
|
1022
|
+
): Promise<Array<TraceAnalyticsTimeseriesRow>> {
|
|
1023
|
+
const groupByKeys: Array<string> = request.groupBy || [];
|
|
1024
|
+
|
|
1025
|
+
/*
|
|
1026
|
+
* Cap the series count: a high-cardinality dimension (e.g. url.host
|
|
1027
|
+
* across hundreds of tenants) would otherwise return one series per
|
|
1028
|
+
* value. Pre-resolve the top values of the first dimension — ranked by
|
|
1029
|
+
* the SELECTED metric (so duration metrics chart the slowest dimension
|
|
1030
|
+
* values, counts chart the busiest) — and constrain the timeseries to
|
|
1031
|
+
* them. The full groupBy is passed so the ranking applies the same
|
|
1032
|
+
* dimension-implied predicates (e.g. mapContains on the second
|
|
1033
|
+
* dimension) as the final query.
|
|
1034
|
+
*/
|
|
1035
|
+
let topValues: Array<string> | undefined = undefined;
|
|
1036
|
+
if (groupByKeys.length > 0) {
|
|
1037
|
+
const topItems: Array<TraceAnalyticsTopItem> =
|
|
1038
|
+
await TraceAggregationService.getAnalyticsTopList(request);
|
|
1039
|
+
|
|
1040
|
+
topValues = topItems.map((item: TraceAnalyticsTopItem): string => {
|
|
1041
|
+
return item.value;
|
|
1042
|
+
});
|
|
1043
|
+
|
|
1044
|
+
/*
|
|
1045
|
+
* No non-empty values → skip the cap rather than returning nothing:
|
|
1046
|
+
* spans whose dimension value is an empty string still chart (as one
|
|
1047
|
+
* "(empty)" series), consistent with the table view.
|
|
1048
|
+
*/
|
|
1049
|
+
if (topValues.length === 0) {
|
|
1050
|
+
topValues = undefined;
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
const statement: Statement =
|
|
1055
|
+
TraceAggregationService.buildAnalyticsTimeseriesStatement(
|
|
1056
|
+
request,
|
|
1057
|
+
topValues,
|
|
1058
|
+
);
|
|
1059
|
+
|
|
1060
|
+
const dbResult: Results = await SpanService.executeQuery(statement);
|
|
1061
|
+
|
|
1062
|
+
let rows: Array<JSONObject> = [];
|
|
1063
|
+
try {
|
|
1064
|
+
const response: DbJSONResponse = await dbResult.json<{
|
|
1065
|
+
data?: Array<JSONObject>;
|
|
1066
|
+
}>();
|
|
1067
|
+
rows = response.data || [];
|
|
1068
|
+
} catch {
|
|
1069
|
+
logger.warn(
|
|
1070
|
+
"Trace analytics timeseries query returned unparseable response, returning empty result",
|
|
1071
|
+
);
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
return rows.map((row: JSONObject): TraceAnalyticsTimeseriesRow => {
|
|
1075
|
+
const groupValues: Record<string, string> = {};
|
|
1076
|
+
|
|
1077
|
+
for (const [index, key] of groupByKeys.entries()) {
|
|
1078
|
+
const alias: string = TraceAggregationService.groupByAlias(key, index);
|
|
1079
|
+
groupValues[key] = String(row[alias] ?? "");
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
return {
|
|
1083
|
+
time: String(row["bucket"] || ""),
|
|
1084
|
+
value: Number(row["val"] || 0),
|
|
1085
|
+
groupValues,
|
|
1086
|
+
};
|
|
1087
|
+
});
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
@CaptureSpan()
|
|
1091
|
+
public static async getAnalyticsTopList(
|
|
1092
|
+
request: TraceAnalyticsRequest,
|
|
1093
|
+
): Promise<Array<TraceAnalyticsTopItem>> {
|
|
1094
|
+
if (!request.groupBy || request.groupBy.length === 0) {
|
|
1095
|
+
throw new BadDataException(
|
|
1096
|
+
"groupBy with at least one dimension is required for top list",
|
|
1097
|
+
);
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
const statement: Statement =
|
|
1101
|
+
TraceAggregationService.buildAnalyticsTopListStatement(request);
|
|
1102
|
+
|
|
1103
|
+
const dbResult: Results = await SpanService.executeQuery(statement);
|
|
1104
|
+
|
|
1105
|
+
let rows: Array<JSONObject> = [];
|
|
1106
|
+
try {
|
|
1107
|
+
const response: DbJSONResponse = await dbResult.json<{
|
|
1108
|
+
data?: Array<JSONObject>;
|
|
1109
|
+
}>();
|
|
1110
|
+
rows = response.data || [];
|
|
1111
|
+
} catch {
|
|
1112
|
+
logger.warn(
|
|
1113
|
+
"Trace analytics top list query returned unparseable response, returning empty result",
|
|
1114
|
+
);
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
return rows
|
|
1118
|
+
.map((row: JSONObject): TraceAnalyticsTopItem => {
|
|
1119
|
+
return {
|
|
1120
|
+
value: String(row["dim"] ?? ""),
|
|
1121
|
+
metricValue: Number(row["val"] || 0),
|
|
1122
|
+
count: Number(row["cnt"] || 0),
|
|
1123
|
+
};
|
|
1124
|
+
})
|
|
1125
|
+
.filter((item: TraceAnalyticsTopItem): boolean => {
|
|
1126
|
+
return item.value.length > 0;
|
|
1127
|
+
});
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
@CaptureSpan()
|
|
1131
|
+
public static async getAnalyticsTable(
|
|
1132
|
+
request: TraceAnalyticsRequest,
|
|
1133
|
+
): Promise<Array<TraceAnalyticsTableRow>> {
|
|
1134
|
+
if (!request.groupBy || request.groupBy.length === 0) {
|
|
1135
|
+
throw new BadDataException(
|
|
1136
|
+
"groupBy with at least one dimension is required for table",
|
|
1137
|
+
);
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
const statement: Statement =
|
|
1141
|
+
TraceAggregationService.buildAnalyticsTableStatement(request);
|
|
1142
|
+
|
|
1143
|
+
const dbResult: Results = await SpanService.executeQuery(statement);
|
|
1144
|
+
|
|
1145
|
+
let rows: Array<JSONObject> = [];
|
|
1146
|
+
try {
|
|
1147
|
+
const response: DbJSONResponse = await dbResult.json<{
|
|
1148
|
+
data?: Array<JSONObject>;
|
|
1149
|
+
}>();
|
|
1150
|
+
rows = response.data || [];
|
|
1151
|
+
} catch {
|
|
1152
|
+
logger.warn(
|
|
1153
|
+
"Trace analytics table query returned unparseable response, returning empty result",
|
|
1154
|
+
);
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
const groupByKeys: Array<string> = request.groupBy;
|
|
1158
|
+
|
|
1159
|
+
return rows.map((row: JSONObject): TraceAnalyticsTableRow => {
|
|
1160
|
+
const groupValues: Record<string, string> = {};
|
|
1161
|
+
|
|
1162
|
+
for (const [index, key] of groupByKeys.entries()) {
|
|
1163
|
+
const alias: string = TraceAggregationService.groupByAlias(key, index);
|
|
1164
|
+
groupValues[key] = String(row[alias] ?? "");
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
return {
|
|
1168
|
+
groupValues,
|
|
1169
|
+
count: Number(row["cnt"] || 0),
|
|
1170
|
+
avgDurationMs: Number(row["avg_ms"] || 0),
|
|
1171
|
+
p50DurationMs: Number(row["p50_ms"] || 0),
|
|
1172
|
+
minDurationMs: Number(row["min_ms"] || 0),
|
|
1173
|
+
maxDurationMs: Number(row["max_ms"] || 0),
|
|
1174
|
+
};
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
private static groupByAlias(key: string, index: number): string {
|
|
1179
|
+
if (
|
|
1180
|
+
TraceAggregationService.isTopLevelColumn(key) ||
|
|
1181
|
+
TraceAggregationService.RESOURCE_FACET_KEYS.has(key)
|
|
1182
|
+
) {
|
|
1183
|
+
return key;
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
/*
|
|
1187
|
+
* Attribute keys get a sanitized alias. The dimension index is included
|
|
1188
|
+
* so two distinct keys that sanitize identically (url.host vs url:host)
|
|
1189
|
+
* never collide into one alias (ClickHouse rejects duplicate aliases).
|
|
1190
|
+
*/
|
|
1191
|
+
return `attr_${index}_${key.replace(/[^a-zA-Z0-9_]/g, "_")}`;
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
/*
|
|
1195
|
+
* Append the SELECT expression for one group-by dimension. Resource facet
|
|
1196
|
+
* keys (hostId / dockerHostId / ...) read out of primaryEntityId — the
|
|
1197
|
+
* matching primaryEntityType predicate is added by
|
|
1198
|
+
* appendGroupByDimensionFilters.
|
|
1199
|
+
*/
|
|
1200
|
+
private static appendGroupBySelect(
|
|
1201
|
+
statement: Statement,
|
|
1202
|
+
groupByKeys: Array<string>,
|
|
1203
|
+
): void {
|
|
1204
|
+
for (const [index, key] of groupByKeys.entries()) {
|
|
1205
|
+
TraceAggregationService.validateFacetKey(key);
|
|
1206
|
+
|
|
1207
|
+
if (TraceAggregationService.RESOURCE_FACET_KEYS.has(key)) {
|
|
1208
|
+
statement.append(`, toString(primaryEntityId) AS ${key}`);
|
|
1209
|
+
} else if (TraceAggregationService.isTopLevelColumn(key)) {
|
|
1210
|
+
statement.append(`, toString(${key}) AS ${key}`);
|
|
1211
|
+
} else {
|
|
1212
|
+
const alias: string = TraceAggregationService.groupByAlias(key, index);
|
|
1213
|
+
statement.append(
|
|
1214
|
+
SQL`, attributes[${{
|
|
1215
|
+
type: TableColumnType.Text,
|
|
1216
|
+
value: key,
|
|
1217
|
+
}}] AS ${alias}`,
|
|
1218
|
+
);
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
private static appendGroupByClause(
|
|
1224
|
+
statement: Statement,
|
|
1225
|
+
groupByKeys: Array<string>,
|
|
1226
|
+
): void {
|
|
1227
|
+
for (const [index, key] of groupByKeys.entries()) {
|
|
1228
|
+
statement.append(`, ${TraceAggregationService.groupByAlias(key, index)}`);
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
/*
|
|
1233
|
+
* Dimension-implied WHERE predicates: attribute dimensions only count
|
|
1234
|
+
* spans that carry the attribute (matching buildFacetStatement); resource
|
|
1235
|
+
* dimensions constrain primaryEntityType to the matching resource type.
|
|
1236
|
+
*/
|
|
1237
|
+
private static appendGroupByDimensionFilters(
|
|
1238
|
+
statement: Statement,
|
|
1239
|
+
groupByKeys: Array<string>,
|
|
1240
|
+
): void {
|
|
1241
|
+
for (const key of groupByKeys) {
|
|
1242
|
+
const resourceType: ServiceType | undefined =
|
|
1243
|
+
TraceAggregationService.RESOURCE_FACET_KEYS.get(key);
|
|
1244
|
+
|
|
1245
|
+
if (resourceType !== undefined) {
|
|
1246
|
+
statement.append(
|
|
1247
|
+
SQL` AND primaryEntityType = ${{
|
|
1248
|
+
type: TableColumnType.Text,
|
|
1249
|
+
value: resourceType as string,
|
|
1250
|
+
}}`,
|
|
1251
|
+
);
|
|
1252
|
+
continue;
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
if (key === "primaryEntityId") {
|
|
1256
|
+
/*
|
|
1257
|
+
* Same restriction as the Service facet: keep host/docker/k8s
|
|
1258
|
+
* entity ids out of the "Service" dimension (they reuse the
|
|
1259
|
+
* primaryEntityId slot, disambiguated by primaryEntityType).
|
|
1260
|
+
*/
|
|
1261
|
+
statement.append(
|
|
1262
|
+
SQL` AND (primaryEntityType = '' OR primaryEntityType = ${{
|
|
1263
|
+
type: TableColumnType.Text,
|
|
1264
|
+
value: ServiceType.OpenTelemetry as string,
|
|
1265
|
+
}})`,
|
|
1266
|
+
);
|
|
1267
|
+
continue;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
if (TraceAggregationService.isTopLevelColumn(key)) {
|
|
1271
|
+
continue;
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
statement.append(
|
|
1275
|
+
SQL` AND mapContains(attributes, ${{
|
|
1276
|
+
type: TableColumnType.Text,
|
|
1277
|
+
value: key,
|
|
1278
|
+
}})`,
|
|
1279
|
+
);
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
private static validateGroupBy(groupBy: Array<string> | undefined): void {
|
|
1284
|
+
if (!groupBy) {
|
|
1285
|
+
return;
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
if (groupBy.length > TraceAggregationService.MAX_GROUP_BY_DIMENSIONS) {
|
|
1289
|
+
throw new BadDataException(
|
|
1290
|
+
`groupBy supports at most ${TraceAggregationService.MAX_GROUP_BY_DIMENSIONS} dimensions`,
|
|
1291
|
+
);
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
for (const key of groupBy) {
|
|
1295
|
+
TraceAggregationService.validateFacetKey(key);
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
private static getMetricExpression(metric: TraceAnalyticsMetric): string {
|
|
1300
|
+
const expression: string | undefined =
|
|
1301
|
+
TraceAggregationService.METRIC_EXPRESSIONS[metric];
|
|
1302
|
+
|
|
1303
|
+
if (!expression) {
|
|
1304
|
+
throw new BadDataException("Invalid analytics metric");
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
return expression;
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
private static appendAnalyticsTimeWindow(
|
|
1311
|
+
statement: Statement,
|
|
1312
|
+
request: TraceAnalyticsRequest,
|
|
1313
|
+
): void {
|
|
1314
|
+
statement.append(
|
|
1315
|
+
SQL` WHERE projectId = ${{
|
|
1316
|
+
type: TableColumnType.ObjectID,
|
|
1317
|
+
value: request.projectId,
|
|
1318
|
+
}} AND startTime >= ${{
|
|
1319
|
+
type: TableColumnType.Date,
|
|
1320
|
+
value: request.startTime,
|
|
1321
|
+
}} AND startTime <= ${{
|
|
1322
|
+
type: TableColumnType.Date,
|
|
1323
|
+
value: request.endTime,
|
|
1324
|
+
}}`,
|
|
1325
|
+
);
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
private static buildAnalyticsTimeseriesStatement(
|
|
1329
|
+
request: TraceAnalyticsRequest,
|
|
1330
|
+
topDimensionValues?: Array<string> | undefined,
|
|
1331
|
+
): Statement {
|
|
1332
|
+
TraceAggregationService.validateGroupBy(request.groupBy);
|
|
1333
|
+
|
|
1334
|
+
const groupByKeys: Array<string> = request.groupBy || [];
|
|
1335
|
+
const intervalSeconds: number = request.bucketSizeInMinutes * 60;
|
|
1336
|
+
const metricExpr: string = TraceAggregationService.getMetricExpression(
|
|
1337
|
+
request.metric,
|
|
1338
|
+
);
|
|
1339
|
+
|
|
1340
|
+
const statement: Statement = SQL`SELECT toStartOfInterval(startTime, INTERVAL ${{
|
|
1341
|
+
type: TableColumnType.Number,
|
|
1342
|
+
value: intervalSeconds,
|
|
1343
|
+
}} SECOND) AS bucket`;
|
|
1344
|
+
|
|
1345
|
+
statement.append(`, ${metricExpr} AS val`);
|
|
1346
|
+
|
|
1347
|
+
TraceAggregationService.appendGroupBySelect(statement, groupByKeys);
|
|
1348
|
+
|
|
1349
|
+
statement.append(` FROM ${TraceAggregationService.TABLE_NAME}`);
|
|
1350
|
+
|
|
1351
|
+
TraceAggregationService.appendAnalyticsTimeWindow(statement, request);
|
|
1352
|
+
|
|
1353
|
+
statement.append(TraceAggregationService.RETENTION_FILTER);
|
|
1354
|
+
|
|
1355
|
+
TraceAggregationService.appendGroupByDimensionFilters(
|
|
1356
|
+
statement,
|
|
1357
|
+
groupByKeys,
|
|
1358
|
+
);
|
|
1359
|
+
|
|
1360
|
+
/*
|
|
1361
|
+
* Series cap: constrain the first dimension to the pre-resolved top
|
|
1362
|
+
* values (see getAnalyticsTimeseries).
|
|
1363
|
+
*/
|
|
1364
|
+
if (
|
|
1365
|
+
topDimensionValues &&
|
|
1366
|
+
topDimensionValues.length > 0 &&
|
|
1367
|
+
groupByKeys.length > 0
|
|
1368
|
+
) {
|
|
1369
|
+
TraceAggregationService.appendDimensionExpression(
|
|
1370
|
+
statement,
|
|
1371
|
+
groupByKeys[0]!,
|
|
1372
|
+
" AND ",
|
|
1373
|
+
);
|
|
1374
|
+
statement.append(
|
|
1375
|
+
SQL` IN (${{
|
|
1376
|
+
type: TableColumnType.Text,
|
|
1377
|
+
value: new Includes(topDimensionValues),
|
|
1378
|
+
}})`,
|
|
1379
|
+
);
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
TraceAggregationService.appendCommonFilters(statement, request);
|
|
1383
|
+
|
|
1384
|
+
statement.append(" GROUP BY bucket");
|
|
1385
|
+
TraceAggregationService.appendGroupByClause(statement, groupByKeys);
|
|
1386
|
+
statement.append(" ORDER BY bucket ASC");
|
|
1387
|
+
|
|
1388
|
+
statement.append(
|
|
1389
|
+
getQuerySettings({
|
|
1390
|
+
maxExecutionTimeInSeconds: 45,
|
|
1391
|
+
timeoutOverflowMode: "break",
|
|
1392
|
+
}),
|
|
1393
|
+
);
|
|
1394
|
+
|
|
1395
|
+
return statement;
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
/*
|
|
1399
|
+
* Append the bare dimension expression (no alias) prefixed by `prefix` —
|
|
1400
|
+
* used in WHERE clauses where SELECT aliases are not yet visible.
|
|
1401
|
+
*/
|
|
1402
|
+
private static appendDimensionExpression(
|
|
1403
|
+
statement: Statement,
|
|
1404
|
+
key: string,
|
|
1405
|
+
prefix: string,
|
|
1406
|
+
): void {
|
|
1407
|
+
TraceAggregationService.validateFacetKey(key);
|
|
1408
|
+
|
|
1409
|
+
if (
|
|
1410
|
+
TraceAggregationService.RESOURCE_FACET_KEYS.has(key) ||
|
|
1411
|
+
key === "primaryEntityId"
|
|
1412
|
+
) {
|
|
1413
|
+
statement.append(`${prefix}toString(primaryEntityId)`);
|
|
1414
|
+
return;
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
if (TraceAggregationService.isTopLevelColumn(key)) {
|
|
1418
|
+
statement.append(`${prefix}toString(${key})`);
|
|
1419
|
+
return;
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
statement.append(`${prefix}attributes[`);
|
|
1423
|
+
statement.append(
|
|
1424
|
+
SQL`${{
|
|
1425
|
+
type: TableColumnType.Text,
|
|
1426
|
+
value: key,
|
|
1427
|
+
}}`,
|
|
1428
|
+
);
|
|
1429
|
+
statement.append("]");
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1432
|
+
private static buildAnalyticsTopListStatement(
|
|
1433
|
+
request: TraceAnalyticsRequest,
|
|
1434
|
+
): Statement {
|
|
1435
|
+
const groupByKey: string = request.groupBy![0]!;
|
|
1436
|
+
TraceAggregationService.validateFacetKey(groupByKey);
|
|
1437
|
+
|
|
1438
|
+
const limit: number =
|
|
1439
|
+
request.limit ?? TraceAggregationService.DEFAULT_ANALYTICS_LIMIT;
|
|
1440
|
+
const metricExpr: string = TraceAggregationService.getMetricExpression(
|
|
1441
|
+
request.metric,
|
|
1442
|
+
);
|
|
1443
|
+
|
|
1444
|
+
const statement: Statement = new Statement();
|
|
1445
|
+
statement.append("SELECT");
|
|
1446
|
+
TraceAggregationService.appendDimensionExpression(
|
|
1447
|
+
statement,
|
|
1448
|
+
groupByKey,
|
|
1449
|
+
" ",
|
|
1450
|
+
);
|
|
1451
|
+
statement.append(
|
|
1452
|
+
` AS dim, ${metricExpr} AS val, count() AS cnt FROM ${TraceAggregationService.TABLE_NAME}`,
|
|
1453
|
+
);
|
|
1454
|
+
|
|
1455
|
+
TraceAggregationService.appendAnalyticsTimeWindow(statement, request);
|
|
1456
|
+
|
|
1457
|
+
statement.append(TraceAggregationService.RETENTION_FILTER);
|
|
1458
|
+
|
|
1459
|
+
/*
|
|
1460
|
+
* Dimension-implied predicates for EVERY groupBy key — when this query
|
|
1461
|
+
* pre-resolves the series cap for a two-dimension timeseries, the
|
|
1462
|
+
* ranking must count the same span set the final chart counts.
|
|
1463
|
+
*/
|
|
1464
|
+
TraceAggregationService.appendGroupByDimensionFilters(
|
|
1465
|
+
statement,
|
|
1466
|
+
request.groupBy!,
|
|
1467
|
+
);
|
|
1468
|
+
|
|
1469
|
+
TraceAggregationService.appendCommonFilters(statement, request);
|
|
1470
|
+
|
|
1471
|
+
/*
|
|
1472
|
+
* Duration metrics rank by the metric itself (slowest first); count-like
|
|
1473
|
+
* metrics rank by volume. Either way `cnt` is returned for context.
|
|
1474
|
+
*/
|
|
1475
|
+
statement.append(
|
|
1476
|
+
SQL` GROUP BY dim ORDER BY val DESC LIMIT ${{
|
|
1477
|
+
type: TableColumnType.Number,
|
|
1478
|
+
value: limit,
|
|
1479
|
+
}}`,
|
|
1480
|
+
);
|
|
1481
|
+
|
|
1482
|
+
statement.append(
|
|
1483
|
+
getQuerySettings({
|
|
1484
|
+
maxExecutionTimeInSeconds: 45,
|
|
1485
|
+
timeoutOverflowMode: "break",
|
|
1486
|
+
}),
|
|
1487
|
+
);
|
|
1488
|
+
|
|
1489
|
+
return statement;
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1492
|
+
private static buildAnalyticsTableStatement(
|
|
1493
|
+
request: TraceAnalyticsRequest,
|
|
1494
|
+
): Statement {
|
|
1495
|
+
TraceAggregationService.validateGroupBy(request.groupBy);
|
|
1496
|
+
|
|
1497
|
+
const groupByKeys: Array<string> = request.groupBy!;
|
|
1498
|
+
const limit: number =
|
|
1499
|
+
request.limit ?? TraceAggregationService.DEFAULT_ANALYTICS_LIMIT;
|
|
1500
|
+
|
|
1501
|
+
/*
|
|
1502
|
+
* The "top dimensions" table always carries the full duration stat set
|
|
1503
|
+
* (count, avg, median, min, max) — one query answers "requests and
|
|
1504
|
+
* median response time per tenant" without a follow-up.
|
|
1505
|
+
*/
|
|
1506
|
+
const statement: Statement = new Statement();
|
|
1507
|
+
statement.append(
|
|
1508
|
+
"SELECT count() AS cnt" +
|
|
1509
|
+
", avg(durationUnixNano) / 1000000 AS avg_ms" +
|
|
1510
|
+
", quantile(0.5)(durationUnixNano) / 1000000 AS p50_ms" +
|
|
1511
|
+
", min(durationUnixNano) / 1000000 AS min_ms" +
|
|
1512
|
+
", max(durationUnixNano) / 1000000 AS max_ms",
|
|
1513
|
+
);
|
|
1514
|
+
|
|
1515
|
+
TraceAggregationService.appendGroupBySelect(statement, groupByKeys);
|
|
1516
|
+
|
|
1517
|
+
statement.append(` FROM ${TraceAggregationService.TABLE_NAME}`);
|
|
1518
|
+
|
|
1519
|
+
TraceAggregationService.appendAnalyticsTimeWindow(statement, request);
|
|
1520
|
+
|
|
1521
|
+
statement.append(TraceAggregationService.RETENTION_FILTER);
|
|
1522
|
+
|
|
1523
|
+
TraceAggregationService.appendGroupByDimensionFilters(
|
|
1524
|
+
statement,
|
|
1525
|
+
groupByKeys,
|
|
1526
|
+
);
|
|
1527
|
+
|
|
1528
|
+
TraceAggregationService.appendCommonFilters(statement, request);
|
|
1529
|
+
|
|
1530
|
+
statement.append(" GROUP BY");
|
|
1531
|
+
let first: boolean = true;
|
|
1532
|
+
for (const [index, key] of groupByKeys.entries()) {
|
|
1533
|
+
statement.append(
|
|
1534
|
+
`${first ? " " : ", "}${TraceAggregationService.groupByAlias(key, index)}`,
|
|
1535
|
+
);
|
|
1536
|
+
first = false;
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1539
|
+
statement.append(
|
|
1540
|
+
SQL` ORDER BY cnt DESC LIMIT ${{
|
|
1541
|
+
type: TableColumnType.Number,
|
|
1542
|
+
value: limit,
|
|
1543
|
+
}}`,
|
|
1544
|
+
);
|
|
1545
|
+
|
|
1546
|
+
statement.append(
|
|
1547
|
+
getQuerySettings({
|
|
1548
|
+
maxExecutionTimeInSeconds: 45,
|
|
1549
|
+
timeoutOverflowMode: "break",
|
|
1550
|
+
}),
|
|
1551
|
+
);
|
|
1552
|
+
|
|
1553
|
+
return statement;
|
|
722
1554
|
}
|
|
723
1555
|
|
|
724
1556
|
private static isTopLevelColumn(key: string): boolean {
|