@oneuptime/common 11.5.9 → 11.5.11
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/Index.ts +13 -0
- package/Models/AnalyticsModels/MetricItemAggMV1mByContainer.ts +178 -0
- package/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.ts +179 -0
- package/Models/AnalyticsModels/MetricItemAggMV1mByService.ts +179 -0
- package/Models/AnalyticsModels/NetworkFlow.ts +397 -0
- package/Models/DatabaseModels/EnterpriseLicenseInstance.ts +18 -0
- package/Models/DatabaseModels/GlobalConfig.ts +36 -0
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/MarketingConversion.ts +198 -0
- package/Models/DatabaseModels/MetricSavedView.ts +34 -0
- package/Models/DatabaseModels/MetricType.ts +74 -0
- package/Models/DatabaseModels/NetworkDevice.ts +332 -0
- package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +113 -0
- package/Models/DatabaseModels/NetworkInterface.ts +58 -0
- package/Models/DatabaseModels/Project.ts +37 -0
- package/Models/DatabaseModels/User.ts +37 -0
- package/Server/API/BaseAnalyticsAPI.ts +23 -0
- package/Server/API/EnterpriseLicenseAPI.ts +14 -0
- package/Server/EnvironmentConfig.ts +84 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784191414522-AddCounterSemanticsToMetricType.ts +38 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784191414600-AddViewTypeToMetricSavedView.ts +28 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784211212164-AddNetworkDeviceInventoryAndDiscoverySchedule.ts +108 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784218257664-AddEnterpriseLicenseNotificationColumns.ts +31 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784293516000-AddAttributionColumnsToUserAndProject.ts +29 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784298000000-AddMarketingConversionTable.ts +35 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784401962564-MigrationName.ts +101 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +14 -0
- package/Server/Services/AnalyticsDatabaseService.ts +70 -1
- package/Server/Services/IncidentService.ts +13 -0
- package/Server/Services/Index.ts +10 -0
- package/Server/Services/MarketingConversionService.ts +10 -0
- package/Server/Services/MetricItemAggMV1mByContainerService.ts +31 -0
- package/Server/Services/MetricItemAggMV1mByK8sClusterService.ts +31 -0
- package/Server/Services/MetricItemAggMV1mByServiceService.ts +31 -0
- package/Server/Services/MetricService.ts +970 -122
- package/Server/Services/MonitorService.ts +14 -0
- package/Server/Services/NetworkDeviceOwnerTeamService.ts +42 -0
- package/Server/Services/NetworkDeviceOwnerUserService.ts +106 -0
- package/Server/Services/NetworkFlowService.ts +11 -0
- package/Server/Services/OnCallDutyPolicyService.ts +11 -1
- package/Server/Services/ProjectService.ts +136 -0
- package/Server/Services/SpanService.ts +13 -9
- package/Server/Services/StatusPageService.ts +10 -0
- package/Server/Services/TeamMemberService.ts +11 -0
- package/Server/Services/UserService.ts +59 -0
- package/Server/Types/AnalyticsDatabase/AggregateBy.ts +37 -7
- package/Server/Utils/Attribution.ts +99 -0
- package/Server/Utils/Marketing/ConversionUploadProvider.ts +103 -0
- package/Server/Utils/Marketing/ConversionUploadProviders.ts +22 -0
- package/Server/Utils/Marketing/Providers/GoogleAds.ts +270 -0
- package/Server/Utils/Marketing/Providers/LinkedIn.ts +147 -0
- package/Server/Utils/Marketing/Providers/Meta.ts +148 -0
- package/Server/Utils/Marketing/Providers/MicrosoftAds.ts +196 -0
- package/Server/Utils/Marketing/Providers/Reddit.ts +178 -0
- package/Server/Utils/Monitor/MonitorAlert.ts +71 -7
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +31 -19
- package/Server/Utils/Monitor/MonitorIncident.ts +71 -7
- package/Server/Utils/Monitor/MonitorMetricUtil.ts +57 -0
- package/Server/Utils/Monitor/MonitorTemplateUtil.ts +94 -0
- package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +15 -0
- package/Server/Utils/Monitor/NetworkInventoryUtil.ts +125 -14
- package/Server/Utils/ProductAnalytics.ts +133 -0
- package/Server/Utils/Telemetry/Telemetry.ts +39 -0
- package/Server/Utils/Telemetry/TelemetryEntity.ts +21 -0
- package/Tests/Server/API/BaseAnalyticsAPI.test.ts +72 -0
- package/Tests/Server/Infrastructure/SemaphorePermit.test.ts +9 -1
- package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +21 -2
- package/Tests/Server/Services/MetricEntityMVKeyParity.test.ts +173 -0
- package/Tests/Server/Services/MetricServiceAggregate.test.ts +1391 -0
- package/Tests/Server/Services/NetworkDeviceOwnerServices.test.ts +260 -0
- package/Tests/Server/Utils/Monitor/MonitorTemplateUtilNetworkDevice.test.ts +389 -0
- package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +764 -0
- package/Tests/Types/BaseDatabase/AggregationIntervalUtil.test.ts +111 -2
- package/Tests/Types/Database/EndsWith.test.ts +64 -0
- package/Tests/Types/Database/GreaterThan.test.ts +62 -0
- package/Tests/Types/Database/GreaterThanOrEqual.test.ts +65 -0
- package/Tests/Types/Database/GreaterThanOrNull.test.ts +63 -0
- package/Tests/Types/Database/Includes.test.ts +65 -0
- package/Tests/Types/Database/IncludesAll.test.ts +65 -0
- package/Tests/Types/Database/IncludesNone.test.ts +65 -0
- package/Tests/Types/Database/IsNull.test.ts +44 -0
- package/Tests/Types/Database/LessThan.test.ts +62 -0
- package/Tests/Types/Database/LessThanOrEqual.test.ts +62 -0
- package/Tests/Types/Database/LessThanOrNull.test.ts +62 -0
- package/Tests/Types/Database/MultiSearch.test.ts +81 -0
- package/Tests/Types/Database/NotContains.test.ts +64 -0
- package/Tests/Types/Database/NotNull.test.ts +44 -0
- package/Tests/Types/Database/StartsWith.test.ts +64 -0
- package/Tests/Types/Monitor/MonitorStepSqlMonitor.test.ts +83 -1
- package/Tests/Types/Monitor/SnmpV3EnumParsing.test.ts +247 -0
- package/Tests/Types/Monitor/SnmpVendorTemplate.test.ts +263 -0
- package/Tests/UI/Components/XAxis.test.ts +5 -3
- package/Tests/Utils/EnterpriseLicenseUsage.test.ts +76 -0
- package/Tests/Utils/Metrics/MetricExplorerUrl.test.ts +622 -0
- package/Tests/Utils/Metrics/MetricFormulaEvaluator.test.ts +474 -0
- package/Tests/Utils/Telemetry/HeartbeatAvailability.test.ts +52 -4
- package/Types/AnalyticsDatabase/AnalyticsTableName.ts +11 -0
- package/Types/BaseDatabase/AggregateBy.ts +31 -2
- package/Types/BaseDatabase/AggregatedResult.ts +22 -0
- package/Types/BaseDatabase/AggregationInterval.ts +11 -0
- package/Types/BaseDatabase/AggregationIntervalUtil.ts +30 -5
- package/Types/Dashboard/DashboardComponents/DashboardTraceChartComponent.ts +16 -0
- package/Types/Email/EmailTemplateType.ts +3 -0
- package/Types/Marketing/MarketingConversion.ts +11 -0
- package/Types/Metrics/MetricQueryConfigData.ts +21 -0
- package/Types/Metrics/MetricQueryData.ts +8 -0
- package/Types/Metrics/MetricViewData.ts +8 -0
- package/Types/Monitor/MonitorMetricType.ts +8 -0
- package/Types/Monitor/MonitorStep.ts +9 -0
- package/Types/Monitor/MonitorStepSqlMonitor.ts +12 -0
- package/Types/Monitor/MonitorType.ts +2 -1
- package/Types/Monitor/SSLMonitor/SslMonitorResponse.ts +17 -12
- package/Types/Monitor/SnmpMonitor/CdpNeighbor.ts +13 -0
- package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +37 -3
- package/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.ts +46 -0
- package/Types/Monitor/SnmpMonitor/SnmpEntityInfo.ts +15 -0
- package/Types/Monitor/SnmpMonitor/SnmpInterface.ts +8 -0
- package/Types/Monitor/SnmpMonitor/SnmpMonitorResponse.ts +17 -8
- package/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.ts +53 -0
- package/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.ts +43 -0
- package/Types/Monitor/SnmpMonitor/SnmpSystemInfo.ts +16 -0
- package/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.ts +119 -3
- package/Types/NetFlow/NetworkFlowRecord.ts +25 -0
- package/Types/Syslog/SyslogMessage.ts +18 -0
- package/Types/Telemetry/TelemetrySavedViewState.ts +9 -0
- package/Types/Telemetry/TelemetrySavedViewType.ts +12 -0
- package/UI/Components/Charts/Area/AreaChart.tsx +51 -0
- package/UI/Components/Charts/Bar/BarChart.tsx +51 -1
- package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +97 -26
- package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +328 -1
- package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +115 -0
- package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +328 -1
- package/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.ts +7 -0
- package/UI/Components/Charts/ChartLibrary/Types/FormattedReferenceRegion.ts +15 -0
- package/UI/Components/Charts/ChartLibrary/Types/FormattedTimeReferenceLine.ts +13 -0
- package/UI/Components/Charts/Line/LineChart.tsx +51 -0
- package/UI/Components/Charts/Types/ReferenceRegionProps.ts +12 -0
- package/UI/Components/Charts/Types/TimeReferenceLineProps.ts +12 -0
- package/UI/Components/Charts/Types/XAxis/XAxisPrecision.ts +1 -0
- package/UI/Components/Charts/Utils/DataPoint.ts +0 -0
- package/UI/Components/Charts/Utils/TimeAnnotation.ts +169 -0
- package/UI/Components/Charts/Utils/XAxis.ts +28 -4
- package/UI/Components/Icon/Icon.tsx +33 -13
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +9 -0
- package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +67 -0
- package/UI/Components/Page/ModelPage.tsx +6 -1
- package/UI/Components/TelemetryViewer/components/SavedViewsDropdown.tsx +33 -4
- package/UI/Styles/Theme.css +10 -0
- package/UI/Utils/User.ts +41 -2
- package/Utils/Analytics.ts +8 -6
- package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +74 -0
- package/Utils/Metrics/MetricExplorerUrl.ts +771 -0
- package/Utils/Metrics/MetricFormulaEvaluator.ts +410 -46
- package/Utils/Monitor/NetworkTopologyUtil.ts +261 -49
- package/Utils/ValueFormatter.ts +22 -1
- package/build/dist/Models/AnalyticsModels/Index.js +13 -0
- package/build/dist/Models/AnalyticsModels/Index.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByContainer.js +159 -0
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByContainer.js.map +1 -0
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.js +158 -0
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.js.map +1 -0
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByService.js +160 -0
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByService.js.map +1 -0
- package/build/dist/Models/AnalyticsModels/NetworkFlow.js +351 -0
- package/build/dist/Models/AnalyticsModels/NetworkFlow.js.map +1 -0
- package/build/dist/Models/DatabaseModels/EnterpriseLicenseInstance.js +19 -0
- package/build/dist/Models/DatabaseModels/EnterpriseLicenseInstance.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js +38 -0
- package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MarketingConversion.js +219 -0
- package/build/dist/Models/DatabaseModels/MarketingConversion.js.map +1 -0
- package/build/dist/Models/DatabaseModels/MetricSavedView.js +35 -0
- package/build/dist/Models/DatabaseModels/MetricSavedView.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MetricType.js +76 -0
- package/build/dist/Models/DatabaseModels/MetricType.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +341 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +116 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkInterface.js +60 -0
- package/build/dist/Models/DatabaseModels/NetworkInterface.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +38 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/User.js +38 -0
- package/build/dist/Models/DatabaseModels/User.js.map +1 -1
- package/build/dist/Server/API/BaseAnalyticsAPI.js +19 -0
- package/build/dist/Server/API/BaseAnalyticsAPI.js.map +1 -1
- package/build/dist/Server/API/EnterpriseLicenseAPI.js +8 -0
- package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +51 -0
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784191414522-AddCounterSemanticsToMetricType.js +27 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784191414522-AddCounterSemanticsToMetricType.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784191414600-AddViewTypeToMetricSavedView.js +21 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784191414600-AddViewTypeToMetricSavedView.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784211212164-AddNetworkDeviceInventoryAndDiscoverySchedule.js +47 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784211212164-AddNetworkDeviceInventoryAndDiscoverySchedule.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784218257664-AddEnterpriseLicenseNotificationColumns.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784218257664-AddEnterpriseLicenseNotificationColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784293516000-AddAttributionColumnsToUserAndProject.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784293516000-AddAttributionColumnsToUserAndProject.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784298000000-AddMarketingConversionTable.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784298000000-AddMarketingConversionTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784401962564-MigrationName.js +40 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784401962564-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +58 -4
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +12 -0
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +10 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/MarketingConversionService.js +9 -0
- package/build/dist/Server/Services/MarketingConversionService.js.map +1 -0
- package/build/dist/Server/Services/MetricItemAggMV1mByContainerService.js +29 -0
- package/build/dist/Server/Services/MetricItemAggMV1mByContainerService.js.map +1 -0
- package/build/dist/Server/Services/MetricItemAggMV1mByK8sClusterService.js +29 -0
- package/build/dist/Server/Services/MetricItemAggMV1mByK8sClusterService.js.map +1 -0
- package/build/dist/Server/Services/MetricItemAggMV1mByServiceService.js +29 -0
- package/build/dist/Server/Services/MetricItemAggMV1mByServiceService.js.map +1 -0
- package/build/dist/Server/Services/MetricService.js +761 -125
- package/build/dist/Server/Services/MetricService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +18 -5
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceOwnerTeamService.js +44 -0
- package/build/dist/Server/Services/NetworkDeviceOwnerTeamService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceOwnerUserService.js +88 -0
- package/build/dist/Server/Services/NetworkDeviceOwnerUserService.js.map +1 -1
- package/build/dist/Server/Services/NetworkFlowService.js +9 -0
- package/build/dist/Server/Services/NetworkFlowService.js.map +1 -0
- package/build/dist/Server/Services/OnCallDutyPolicyService.js +15 -6
- package/build/dist/Server/Services/OnCallDutyPolicyService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +107 -6
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/SpanService.js +8 -6
- package/build/dist/Server/Services/SpanService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +10 -0
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +11 -0
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +52 -0
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js +33 -7
- package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js.map +1 -1
- package/build/dist/Server/Utils/Attribution.js +74 -0
- package/build/dist/Server/Utils/Attribution.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js +40 -0
- package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/ConversionUploadProviders.js +20 -0
- package/build/dist/Server/Utils/Marketing/ConversionUploadProviders.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js +177 -0
- package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js +113 -0
- package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/Providers/Meta.js +109 -0
- package/build/dist/Server/Utils/Marketing/Providers/Meta.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js +130 -0
- package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/Providers/Reddit.js +126 -0
- package/build/dist/Server/Utils/Marketing/Providers/Reddit.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +53 -9
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +21 -10
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +54 -11
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +43 -3
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +68 -0
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +15 -0
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +100 -15
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
- package/build/dist/Server/Utils/ProductAnalytics.js +111 -0
- package/build/dist/Server/Utils/ProductAnalytics.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/Telemetry.js +32 -5
- package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +17 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
- package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +11 -0
- package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -1
- package/build/dist/Types/BaseDatabase/AggregationInterval.js +11 -0
- package/build/dist/Types/BaseDatabase/AggregationInterval.js.map +1 -1
- package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js +33 -5
- package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js.map +1 -1
- package/build/dist/Types/Email/EmailTemplateType.js +2 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/Marketing/MarketingConversion.js +13 -0
- package/build/dist/Types/Marketing/MarketingConversion.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorMetricType.js +7 -0
- package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +6 -0
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js +3 -0
- package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorType.js +2 -1
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/CdpNeighbor.js +2 -0
- package/build/dist/Types/Monitor/SnmpMonitor/CdpNeighbor.js.map +1 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.js +41 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpEntityInfo.js +2 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpEntityInfo.js.map +1 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.js +48 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.js +38 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpSystemInfo.js +2 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpSystemInfo.js.map +1 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js +96 -3
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js.map +1 -1
- package/build/dist/Types/NetFlow/NetworkFlowRecord.js +2 -0
- package/build/dist/Types/NetFlow/NetworkFlowRecord.js.map +1 -0
- package/build/dist/Types/Syslog/SyslogMessage.js +2 -0
- package/build/dist/Types/Syslog/SyslogMessage.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetrySavedViewState.js +0 -7
- package/build/dist/Types/Telemetry/TelemetrySavedViewState.js.map +1 -1
- package/build/dist/Types/Telemetry/TelemetrySavedViewType.js +13 -0
- package/build/dist/Types/Telemetry/TelemetrySavedViewType.js.map +1 -0
- package/build/dist/UI/Components/Charts/Area/AreaChart.js +25 -1
- package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js +26 -2
- package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +36 -12
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +208 -6
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +52 -3
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +208 -6
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.js +6 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Types/FormattedReferenceRegion.js +2 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Types/FormattedReferenceRegion.js.map +1 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Types/FormattedTimeReferenceLine.js +2 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Types/FormattedTimeReferenceLine.js.map +1 -0
- package/build/dist/UI/Components/Charts/Line/LineChart.js +25 -1
- package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Types/ReferenceRegionProps.js +2 -0
- package/build/dist/UI/Components/Charts/Types/ReferenceRegionProps.js.map +1 -0
- package/build/dist/UI/Components/Charts/Types/TimeReferenceLineProps.js +2 -0
- package/build/dist/UI/Components/Charts/Types/TimeReferenceLineProps.js.map +1 -0
- package/build/dist/UI/Components/Charts/Types/XAxis/XAxisPrecision.js +1 -0
- package/build/dist/UI/Components/Charts/Types/XAxis/XAxisPrecision.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js +0 -0
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js +121 -0
- package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js.map +1 -0
- package/build/dist/UI/Components/Charts/Utils/XAxis.js +27 -4
- package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +15 -8
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +58 -0
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
- package/build/dist/UI/Components/Page/ModelPage.js +7 -1
- package/build/dist/UI/Components/Page/ModelPage.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/SavedViewsDropdown.js +10 -4
- package/build/dist/UI/Components/TelemetryViewer/components/SavedViewsDropdown.js.map +1 -1
- package/build/dist/UI/Utils/User.js +35 -2
- package/build/dist/UI/Utils/User.js.map +1 -1
- package/build/dist/Utils/Analytics.js +8 -5
- package/build/dist/Utils/Analytics.js.map +1 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +57 -0
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js.map +1 -1
- package/build/dist/Utils/Metrics/MetricExplorerUrl.js +418 -0
- package/build/dist/Utils/Metrics/MetricExplorerUrl.js.map +1 -0
- package/build/dist/Utils/Metrics/MetricFormulaEvaluator.js +296 -37
- package/build/dist/Utils/Metrics/MetricFormulaEvaluator.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +176 -40
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/ValueFormatter.js +20 -1
- package/build/dist/Utils/ValueFormatter.js.map +1 -1
- package/package.json +4 -3
|
@@ -3,6 +3,7 @@ import AggregatedModel from "../../Types/BaseDatabase/AggregatedModel";
|
|
|
3
3
|
import AggregatedResult from "../../Types/BaseDatabase/AggregatedResult";
|
|
4
4
|
import MetricFormulaConfigData from "../../Types/Metrics/MetricFormulaConfigData";
|
|
5
5
|
import MetricQueryConfigData from "../../Types/Metrics/MetricQueryConfigData";
|
|
6
|
+
import { JSONObject, JSONValue } from "../../Types/JSON";
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Shunting-yard based evaluator for metric formulas such as
|
|
@@ -10,6 +11,17 @@ import MetricQueryConfigData from "../../Types/Metrics/MetricQueryConfigData";
|
|
|
10
11
|
* alias (case-insensitive, with or without a leading "$"). Evaluates
|
|
11
12
|
* the formula point-by-point against a time-aligned series from the
|
|
12
13
|
* referenced queries/formulas.
|
|
14
|
+
*
|
|
15
|
+
* Group-aware: when a referenced query is grouped (e.g. by "host.name")
|
|
16
|
+
* and its result carries multiple series, the formula is evaluated once
|
|
17
|
+
* per group present in ALL grouped variables (Datadog-style), and the
|
|
18
|
+
* group's attributes are stamped onto the output rows so chart layers
|
|
19
|
+
* can split them back into one line per group. Ungrouped variables
|
|
20
|
+
* broadcast across groups; a variable whose QUERY was grouped is joined
|
|
21
|
+
* by group key even when it happens to return a single series (see
|
|
22
|
+
* isGroupedVariable). When every referenced variable has a single
|
|
23
|
+
* series the evaluator behaves exactly like the original timestamp-only
|
|
24
|
+
* join — no stamping, identical output.
|
|
13
25
|
*/
|
|
14
26
|
|
|
15
27
|
enum TokenType {
|
|
@@ -47,11 +59,27 @@ export interface FormulaPoint {
|
|
|
47
59
|
value: number;
|
|
48
60
|
}
|
|
49
61
|
|
|
62
|
+
interface VariableSeriesData {
|
|
63
|
+
result: AggregatedResult;
|
|
64
|
+
groupByAttributeKeys: Array<string>;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
interface SeriesGroupBucket {
|
|
68
|
+
labels: JSONObject;
|
|
69
|
+
samples: Array<AggregatedModel>;
|
|
70
|
+
}
|
|
71
|
+
|
|
50
72
|
export default class MetricFormulaEvaluator {
|
|
51
73
|
/**
|
|
52
74
|
* Evaluate a formula against the provided query/formula results and
|
|
53
75
|
* return a synthetic AggregatedResult whose timestamps are the union
|
|
54
|
-
* of all referenced series.
|
|
76
|
+
* of all referenced series. Grouped inputs produce one output series
|
|
77
|
+
* per common group, with the group attributes stamped on each row.
|
|
78
|
+
*
|
|
79
|
+
* Throws for STRUCTURAL problems (invalid formula syntax/arity,
|
|
80
|
+
* unknown variable, grouped variables with no groups in common).
|
|
81
|
+
* Per-point data gaps (a timestamp missing from one variable) are
|
|
82
|
+
* skipped silently, as before.
|
|
55
83
|
*/
|
|
56
84
|
public static evaluateFormula(input: {
|
|
57
85
|
formula: string;
|
|
@@ -64,9 +92,10 @@ export default class MetricFormulaEvaluator {
|
|
|
64
92
|
return { data: [] };
|
|
65
93
|
}
|
|
66
94
|
|
|
95
|
+
// Throws a descriptive BadDataException for syntax and arity errors.
|
|
67
96
|
const rpn: Array<Token> = MetricFormulaEvaluator.toRpn(trimmedFormula);
|
|
68
97
|
|
|
69
|
-
const
|
|
98
|
+
const variableData: Record<string, VariableSeriesData> =
|
|
70
99
|
MetricFormulaEvaluator.buildVariableResultMap({
|
|
71
100
|
queryConfigs: input.queryConfigs,
|
|
72
101
|
formulaConfigs: input.formulaConfigs,
|
|
@@ -82,61 +111,132 @@ export default class MetricFormulaEvaluator {
|
|
|
82
111
|
MetricFormulaEvaluator.collectVariableNames(rpn);
|
|
83
112
|
|
|
84
113
|
for (const variableName of referencedVariables) {
|
|
85
|
-
if (!
|
|
114
|
+
if (!variableData[variableName]) {
|
|
86
115
|
throw new BadDataException(
|
|
87
116
|
`Formula references unknown variable "$${variableName}". Define a metric query with that alias first.`,
|
|
88
117
|
);
|
|
89
118
|
}
|
|
90
119
|
}
|
|
91
120
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
121
|
+
/*
|
|
122
|
+
* Bucket each variable's rows into series groups.
|
|
123
|
+
*/
|
|
124
|
+
const seriesBuckets: Record<string, Map<string, SeriesGroupBucket>> = {};
|
|
125
|
+
|
|
126
|
+
for (const variableName of referencedVariables) {
|
|
127
|
+
seriesBuckets[variableName] = MetricFormulaEvaluator.bucketSeriesByGroup(
|
|
128
|
+
variableData[variableName]!,
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/*
|
|
133
|
+
* The grouped path only ENGAGES when some variable factually carries
|
|
134
|
+
* two or more series. Callers like the metric-monitor worker
|
|
135
|
+
* pre-bucket per series fingerprint and pass one series per variable
|
|
136
|
+
* (with grouped query configs still attached), and those inputs must
|
|
137
|
+
* remain an exact — byte-identical — passthrough of the original
|
|
138
|
+
* single-series behavior.
|
|
139
|
+
*/
|
|
140
|
+
const hasMultiSeriesVariable: boolean = referencedVariables.some(
|
|
141
|
+
(variableName: string) => {
|
|
142
|
+
return (seriesBuckets[variableName]?.size || 0) >= 2;
|
|
143
|
+
},
|
|
98
144
|
);
|
|
99
145
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
146
|
+
if (!hasMultiSeriesVariable) {
|
|
147
|
+
// Single-series inputs: exact passthrough of the original behavior.
|
|
148
|
+
const seriesByVariable: Record<string, Array<AggregatedModel>> = {};
|
|
149
|
+
for (const variableName of referencedVariables) {
|
|
150
|
+
seriesByVariable[variableName] =
|
|
151
|
+
variableData[variableName]!.result.data;
|
|
152
|
+
}
|
|
103
153
|
|
|
104
|
-
|
|
154
|
+
return {
|
|
155
|
+
data: MetricFormulaEvaluator.evaluatePointwise({
|
|
156
|
+
rpn,
|
|
157
|
+
referencedVariables,
|
|
158
|
+
seriesByVariable,
|
|
159
|
+
}),
|
|
160
|
+
};
|
|
161
|
+
}
|
|
105
162
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
163
|
+
/*
|
|
164
|
+
* Once in the grouped path, classification switches from observed
|
|
165
|
+
* series count to query intent where available: a variable whose
|
|
166
|
+
* query was grouped joins by group key even when it returned a
|
|
167
|
+
* single series. Every multi-series variable satisfies the
|
|
168
|
+
* predicate too, so groupedVariables is never empty here.
|
|
169
|
+
*/
|
|
170
|
+
const groupedVariables: Array<string> = referencedVariables.filter(
|
|
171
|
+
(variableName: string) => {
|
|
172
|
+
return MetricFormulaEvaluator.isGroupedVariable(
|
|
173
|
+
seriesBuckets[variableName],
|
|
174
|
+
variableData[variableName]!,
|
|
175
|
+
);
|
|
176
|
+
},
|
|
177
|
+
);
|
|
109
178
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
179
|
+
/*
|
|
180
|
+
* Groups the formula is evaluated for = groups present in EVERY
|
|
181
|
+
* grouped variable. Ungrouped variables broadcast, so they don't
|
|
182
|
+
* constrain the set.
|
|
183
|
+
*/
|
|
184
|
+
let commonGroupKeys: Array<string> = Array.from(
|
|
185
|
+
seriesBuckets[groupedVariables[0]!]!.keys(),
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
for (let index: number = 1; index < groupedVariables.length; index++) {
|
|
189
|
+
const buckets: Map<string, SeriesGroupBucket> =
|
|
190
|
+
seriesBuckets[groupedVariables[index]!]!;
|
|
191
|
+
commonGroupKeys = commonGroupKeys.filter((groupKey: string) => {
|
|
192
|
+
return buckets.has(groupKey);
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (commonGroupKeys.length === 0) {
|
|
197
|
+
throw new BadDataException(
|
|
198
|
+
`Formula "${trimmedFormula}" references grouped queries that have no series groups in common. Make sure every grouped query used by the formula is grouped by the same attributes.`,
|
|
119
199
|
);
|
|
200
|
+
}
|
|
120
201
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
202
|
+
/*
|
|
203
|
+
* Group keys are canonical "key=value|key2=value2" strings, so a
|
|
204
|
+
* lexicographic sort yields a stable, human-sensible series order.
|
|
205
|
+
*/
|
|
206
|
+
commonGroupKeys.sort();
|
|
124
207
|
|
|
125
|
-
|
|
126
|
-
try {
|
|
127
|
-
evaluated = MetricFormulaEvaluator.evaluateRpn(rpn, values);
|
|
128
|
-
} catch {
|
|
129
|
-
continue;
|
|
130
|
-
}
|
|
208
|
+
const resultData: Array<AggregatedModel> = [];
|
|
131
209
|
|
|
132
|
-
|
|
133
|
-
|
|
210
|
+
for (const groupKey of commonGroupKeys) {
|
|
211
|
+
const groupLabels: JSONObject =
|
|
212
|
+
seriesBuckets[groupedVariables[0]!]!.get(groupKey)!.labels;
|
|
213
|
+
|
|
214
|
+
const seriesByVariable: Record<string, Array<AggregatedModel>> = {};
|
|
215
|
+
for (const variableName of referencedVariables) {
|
|
216
|
+
const buckets: Map<string, SeriesGroupBucket> =
|
|
217
|
+
seriesBuckets[variableName]!;
|
|
218
|
+
if (
|
|
219
|
+
MetricFormulaEvaluator.isGroupedVariable(
|
|
220
|
+
buckets,
|
|
221
|
+
variableData[variableName]!,
|
|
222
|
+
)
|
|
223
|
+
) {
|
|
224
|
+
seriesByVariable[variableName] = buckets.get(groupKey)?.samples || [];
|
|
225
|
+
} else {
|
|
226
|
+
// Ungrouped variable: broadcast to every group.
|
|
227
|
+
seriesByVariable[variableName] =
|
|
228
|
+
variableData[variableName]!.result.data;
|
|
229
|
+
}
|
|
134
230
|
}
|
|
135
231
|
|
|
136
|
-
resultData.push(
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
232
|
+
resultData.push(
|
|
233
|
+
...MetricFormulaEvaluator.evaluatePointwise({
|
|
234
|
+
rpn,
|
|
235
|
+
referencedVariables,
|
|
236
|
+
seriesByVariable,
|
|
237
|
+
groupAttributes: groupLabels,
|
|
238
|
+
}),
|
|
239
|
+
);
|
|
140
240
|
}
|
|
141
241
|
|
|
142
242
|
return { data: resultData };
|
|
@@ -203,8 +303,8 @@ export default class MetricFormulaEvaluator {
|
|
|
203
303
|
queryConfigs: Array<MetricQueryConfigData>;
|
|
204
304
|
formulaConfigs: Array<MetricFormulaConfigData>;
|
|
205
305
|
results: Array<AggregatedResult>;
|
|
206
|
-
}): Record<string,
|
|
207
|
-
const variableMap: Record<string,
|
|
306
|
+
}): Record<string, VariableSeriesData> {
|
|
307
|
+
const variableMap: Record<string, VariableSeriesData> = {};
|
|
208
308
|
|
|
209
309
|
const totalSeries: number =
|
|
210
310
|
input.queryConfigs.length + input.formulaConfigs.length;
|
|
@@ -216,10 +316,17 @@ export default class MetricFormulaEvaluator {
|
|
|
216
316
|
}
|
|
217
317
|
|
|
218
318
|
let alias: string | undefined;
|
|
319
|
+
let groupByAttributeKeys: Array<string> = [];
|
|
320
|
+
|
|
219
321
|
if (index < input.queryConfigs.length) {
|
|
220
322
|
alias =
|
|
221
323
|
input.queryConfigs[index]?.metricAliasData?.metricVariable ||
|
|
222
324
|
undefined;
|
|
325
|
+
groupByAttributeKeys = (
|
|
326
|
+
input.queryConfigs[index]?.metricQueryData?.groupByAttributeKeys || []
|
|
327
|
+
).filter((key: string) => {
|
|
328
|
+
return Boolean(key);
|
|
329
|
+
});
|
|
223
330
|
} else {
|
|
224
331
|
const formulaIndex: number = index - input.queryConfigs.length;
|
|
225
332
|
alias =
|
|
@@ -231,25 +338,230 @@ export default class MetricFormulaEvaluator {
|
|
|
231
338
|
continue;
|
|
232
339
|
}
|
|
233
340
|
|
|
234
|
-
variableMap[alias.toLowerCase()] =
|
|
341
|
+
variableMap[alias.toLowerCase()] = {
|
|
342
|
+
result,
|
|
343
|
+
groupByAttributeKeys,
|
|
344
|
+
};
|
|
235
345
|
}
|
|
236
346
|
|
|
237
347
|
return variableMap;
|
|
238
348
|
}
|
|
239
349
|
|
|
350
|
+
/**
|
|
351
|
+
* Whether a variable participates in per-group evaluation (joined by
|
|
352
|
+
* group key) rather than broadcasting across every group. True when
|
|
353
|
+
* it factually carries two or more series, OR when its QUERY was
|
|
354
|
+
* grouped (groupByAttributeKeys) and it returned at least one series:
|
|
355
|
+
* a grouped query that collapsed to a single series (e.g. only one
|
|
356
|
+
* host reported the denominator metric in the window) must still be
|
|
357
|
+
* matched group-by-group — broadcasting it would silently compute
|
|
358
|
+
* cross-group math stamped with another group's labels. Formula
|
|
359
|
+
* variables and ungrouped queries carry no grouping config, so they
|
|
360
|
+
* keep the observed >=2 heuristic. A config-grouped variable with an
|
|
361
|
+
* EMPTY result intentionally classifies as ungrouped: it degrades to
|
|
362
|
+
* per-point gaps (empty output) instead of a structural
|
|
363
|
+
* no-groups-in-common error.
|
|
364
|
+
*
|
|
365
|
+
* Only consulted once the grouped path has engaged — the passthrough
|
|
366
|
+
* gate in evaluateFormula deliberately does NOT use this predicate,
|
|
367
|
+
* so single-series inputs (the metric-monitor worker's per-fingerprint
|
|
368
|
+
* shape) stay a byte-identical passthrough.
|
|
369
|
+
*/
|
|
370
|
+
private static isGroupedVariable(
|
|
371
|
+
buckets: Map<string, SeriesGroupBucket> | undefined,
|
|
372
|
+
variable: VariableSeriesData,
|
|
373
|
+
): boolean {
|
|
374
|
+
const bucketCount: number = buckets?.size || 0;
|
|
375
|
+
if (bucketCount >= 2) {
|
|
376
|
+
return true;
|
|
377
|
+
}
|
|
378
|
+
return bucketCount >= 1 && variable.groupByAttributeKeys.length > 0;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Bucket a variable's rows by series group. Query variables group by
|
|
383
|
+
* their configured group-by attribute keys (read from each row's
|
|
384
|
+
* `attributes` map — the shape both the aggregation API and the
|
|
385
|
+
* metric-monitor worker produce). Formula variables (and queries
|
|
386
|
+
* without configured keys) group by whatever scalar `attributes`
|
|
387
|
+
* entries their rows carry — formula outputs are stamped with exactly
|
|
388
|
+
* the group attributes by this evaluator, so this round-trips
|
|
389
|
+
* formula-of-formula references. Rows without attributes fall into a
|
|
390
|
+
* single ungrouped bucket.
|
|
391
|
+
*/
|
|
392
|
+
private static bucketSeriesByGroup(
|
|
393
|
+
variable: VariableSeriesData,
|
|
394
|
+
): Map<string, SeriesGroupBucket> {
|
|
395
|
+
const buckets: Map<string, SeriesGroupBucket> = new Map();
|
|
396
|
+
|
|
397
|
+
for (const sample of variable.result.data) {
|
|
398
|
+
const labels: JSONObject = MetricFormulaEvaluator.extractGroupLabels({
|
|
399
|
+
sample,
|
|
400
|
+
groupByAttributeKeys: variable.groupByAttributeKeys,
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
const groupKey: string = MetricFormulaEvaluator.computeGroupKey(labels);
|
|
404
|
+
|
|
405
|
+
const existing: SeriesGroupBucket | undefined = buckets.get(groupKey);
|
|
406
|
+
if (existing) {
|
|
407
|
+
existing.samples.push(sample);
|
|
408
|
+
} else {
|
|
409
|
+
buckets.set(groupKey, { labels, samples: [sample] });
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
return buckets;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Mirror of MetricSeriesFingerprint.extractSeriesLabels semantics
|
|
418
|
+
* (missing keys preserved as "" so groups stay stable when a series
|
|
419
|
+
* occasionally drops an attribute). Not imported from that module
|
|
420
|
+
* because it pulls in node's "crypto", which the browser bundles that
|
|
421
|
+
* ship this evaluator cannot resolve.
|
|
422
|
+
*/
|
|
423
|
+
private static extractGroupLabels(input: {
|
|
424
|
+
sample: AggregatedModel;
|
|
425
|
+
groupByAttributeKeys: Array<string>;
|
|
426
|
+
}): JSONObject {
|
|
427
|
+
const labels: JSONObject = {};
|
|
428
|
+
|
|
429
|
+
const sampleAttributes: JSONObject =
|
|
430
|
+
((input.sample as unknown as JSONObject)["attributes"] as
|
|
431
|
+
| JSONObject
|
|
432
|
+
| undefined) || {};
|
|
433
|
+
|
|
434
|
+
if (input.groupByAttributeKeys.length > 0) {
|
|
435
|
+
for (const key of input.groupByAttributeKeys) {
|
|
436
|
+
const value: JSONValue | undefined = sampleAttributes[key];
|
|
437
|
+
labels[key] = value === undefined || value === null ? "" : value;
|
|
438
|
+
}
|
|
439
|
+
return labels;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
for (const key of Object.keys(sampleAttributes)) {
|
|
443
|
+
const value: JSONValue | undefined = sampleAttributes[key];
|
|
444
|
+
if (value === undefined || value === null) {
|
|
445
|
+
labels[key] = "";
|
|
446
|
+
continue;
|
|
447
|
+
}
|
|
448
|
+
// Nested objects/arrays can't canonicalize into a stable label.
|
|
449
|
+
if (typeof value === "object") {
|
|
450
|
+
continue;
|
|
451
|
+
}
|
|
452
|
+
labels[key] = value;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
return labels;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Canonical in-memory series key: sorted "key=value" pairs. Same
|
|
460
|
+
* equivalence classes as MetricSeriesFingerprint.computeFingerprint
|
|
461
|
+
* (which hashes this exact string), without the crypto dependency.
|
|
462
|
+
* Empty labels — an ungrouped series — map to "".
|
|
463
|
+
*/
|
|
464
|
+
private static computeGroupKey(labels: JSONObject): string {
|
|
465
|
+
const keys: Array<string> = Object.keys(labels).sort();
|
|
466
|
+
|
|
467
|
+
if (keys.length === 0) {
|
|
468
|
+
return "";
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
const parts: Array<string> = [];
|
|
472
|
+
for (const key of keys) {
|
|
473
|
+
const raw: JSONValue | undefined = labels[key];
|
|
474
|
+
const value: string =
|
|
475
|
+
raw === undefined || raw === null ? "" : String(raw);
|
|
476
|
+
parts.push(`${key}=${value}`);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
return parts.join("|");
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Join the given series on timestamp and evaluate the formula per
|
|
484
|
+
* point. Points missing a value for any referenced variable are
|
|
485
|
+
* skipped (a partial join would produce misleading numbers — e.g.
|
|
486
|
+
* treating a gap as zero silently when using subtraction), as are
|
|
487
|
+
* non-finite results like divide-by-zero. Structural formula errors
|
|
488
|
+
* are impossible here: the RPN's arity is validated at parse time.
|
|
489
|
+
*/
|
|
490
|
+
private static evaluatePointwise(input: {
|
|
491
|
+
rpn: Array<Token>;
|
|
492
|
+
referencedVariables: Array<string>;
|
|
493
|
+
seriesByVariable: Record<string, Array<AggregatedModel>>;
|
|
494
|
+
groupAttributes?: JSONObject | undefined;
|
|
495
|
+
}): Array<AggregatedModel> {
|
|
496
|
+
const timestampIndex: Map<
|
|
497
|
+
string,
|
|
498
|
+
Record<string, number>
|
|
499
|
+
> = MetricFormulaEvaluator.buildTimestampIndex(
|
|
500
|
+
input.referencedVariables,
|
|
501
|
+
input.seriesByVariable,
|
|
502
|
+
);
|
|
503
|
+
|
|
504
|
+
const sortedTimestamps: Array<string> = Array.from(
|
|
505
|
+
timestampIndex.keys(),
|
|
506
|
+
).sort();
|
|
507
|
+
|
|
508
|
+
const resultData: Array<AggregatedModel> = [];
|
|
509
|
+
|
|
510
|
+
for (const timestampString of sortedTimestamps) {
|
|
511
|
+
const values: Record<string, number> =
|
|
512
|
+
timestampIndex.get(timestampString) || {};
|
|
513
|
+
|
|
514
|
+
const hasAllValues: boolean = input.referencedVariables.every(
|
|
515
|
+
(variable: string) => {
|
|
516
|
+
return typeof values[variable] === "number";
|
|
517
|
+
},
|
|
518
|
+
);
|
|
519
|
+
|
|
520
|
+
if (!hasAllValues) {
|
|
521
|
+
continue;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
const evaluated: number = MetricFormulaEvaluator.evaluateRpn(
|
|
525
|
+
input.rpn,
|
|
526
|
+
values,
|
|
527
|
+
);
|
|
528
|
+
|
|
529
|
+
if (!Number.isFinite(evaluated)) {
|
|
530
|
+
continue;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
const row: AggregatedModel = {
|
|
534
|
+
timestamp: new Date(timestampString),
|
|
535
|
+
value: evaluated,
|
|
536
|
+
};
|
|
537
|
+
|
|
538
|
+
if (
|
|
539
|
+
input.groupAttributes &&
|
|
540
|
+
Object.keys(input.groupAttributes).length > 0
|
|
541
|
+
) {
|
|
542
|
+
row["attributes"] = input.groupAttributes;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
resultData.push(row);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
return resultData;
|
|
549
|
+
}
|
|
550
|
+
|
|
240
551
|
private static buildTimestampIndex(
|
|
241
552
|
variables: Array<string>,
|
|
242
|
-
|
|
553
|
+
seriesByVariable: Record<string, Array<AggregatedModel>>,
|
|
243
554
|
): Map<string, Record<string, number>> {
|
|
244
555
|
const index: Map<string, Record<string, number>> = new Map();
|
|
245
556
|
|
|
246
557
|
for (const variable of variables) {
|
|
247
|
-
const series:
|
|
558
|
+
const series: Array<AggregatedModel> | undefined =
|
|
559
|
+
seriesByVariable[variable];
|
|
248
560
|
if (!series) {
|
|
249
561
|
continue;
|
|
250
562
|
}
|
|
251
563
|
|
|
252
|
-
for (const sample of series
|
|
564
|
+
for (const sample of series) {
|
|
253
565
|
const timestampKey: string = MetricFormulaEvaluator.normalizeTimestamp(
|
|
254
566
|
sample.timestamp,
|
|
255
567
|
);
|
|
@@ -524,9 +836,61 @@ export default class MetricFormulaEvaluator {
|
|
|
524
836
|
output.push(top);
|
|
525
837
|
}
|
|
526
838
|
|
|
839
|
+
MetricFormulaEvaluator.assertValidRpn(output);
|
|
840
|
+
|
|
527
841
|
return output;
|
|
528
842
|
}
|
|
529
843
|
|
|
844
|
+
/**
|
|
845
|
+
* Verify operator arity by simulating stack depth over the RPN. This
|
|
846
|
+
* turns malformed expressions like "a**b", "a+" or "()" into
|
|
847
|
+
* descriptive parse-time errors instead of silent per-point failures
|
|
848
|
+
* that render as "no data".
|
|
849
|
+
*/
|
|
850
|
+
private static assertValidRpn(rpn: Array<Token>): void {
|
|
851
|
+
let depth: number = 0;
|
|
852
|
+
|
|
853
|
+
for (const token of rpn) {
|
|
854
|
+
if (
|
|
855
|
+
token.type === TokenType.Number ||
|
|
856
|
+
token.type === TokenType.Variable
|
|
857
|
+
) {
|
|
858
|
+
depth++;
|
|
859
|
+
continue;
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
if (token.type === TokenType.Operator) {
|
|
863
|
+
const operatorValue: Operator = token.value as Operator;
|
|
864
|
+
|
|
865
|
+
if (operatorValue === "u-" || operatorValue === "u+") {
|
|
866
|
+
if (depth < 1) {
|
|
867
|
+
throw new BadDataException(
|
|
868
|
+
`Invalid formula: unary "${operatorValue.charAt(1)}" is missing its operand.`,
|
|
869
|
+
);
|
|
870
|
+
}
|
|
871
|
+
continue;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
if (depth < 2) {
|
|
875
|
+
throw new BadDataException(
|
|
876
|
+
`Invalid formula: operator "${operatorValue}" is missing an operand.`,
|
|
877
|
+
);
|
|
878
|
+
}
|
|
879
|
+
depth--;
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
if (depth === 0) {
|
|
884
|
+
throw new BadDataException("Invalid formula: expression is empty.");
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
if (depth !== 1) {
|
|
888
|
+
throw new BadDataException(
|
|
889
|
+
"Invalid formula: expression does not reduce to a single value. Did you forget an operator between two values?",
|
|
890
|
+
);
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
|
|
530
894
|
private static evaluateRpn(
|
|
531
895
|
rpn: Array<Token>,
|
|
532
896
|
variableValues: Record<string, number>,
|