@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
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { AnalyticsHost, AnalyticsKey } from "../EnvironmentConfig";
|
|
2
|
+
import UserService from "../Services/UserService";
|
|
3
|
+
import HTTPErrorResponse from "../../Types/API/HTTPErrorResponse";
|
|
4
|
+
import HTTPResponse from "../../Types/API/HTTPResponse";
|
|
5
|
+
import URL from "../../Types/API/URL";
|
|
6
|
+
import { JSONObject } from "../../Types/JSON";
|
|
7
|
+
import ObjectID from "../../Types/ObjectID";
|
|
8
|
+
import User from "../../Models/DatabaseModels/User";
|
|
9
|
+
import API from "../../Utils/API";
|
|
10
|
+
import logger from "./Logger";
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
* Server-side product analytics (PostHog).
|
|
14
|
+
*
|
|
15
|
+
* Client-side events are lost to ad blockers — common with OneUptime's
|
|
16
|
+
* developer audience — so revenue and activation events are also captured
|
|
17
|
+
* here, where they cannot be blocked.
|
|
18
|
+
*
|
|
19
|
+
* Events are identified by the user's email (the same distinct id the
|
|
20
|
+
* frontends use via posthog.identify) so server and client events join into
|
|
21
|
+
* one person profile.
|
|
22
|
+
*
|
|
23
|
+
* No-ops when ANALYTICS_KEY / ANALYTICS_HOST are not configured (the default
|
|
24
|
+
* for self-hosted installs). Never throws — analytics must not break the
|
|
25
|
+
* product.
|
|
26
|
+
*/
|
|
27
|
+
export default class ProductAnalytics {
|
|
28
|
+
public static isConfigured(): boolean {
|
|
29
|
+
return Boolean(AnalyticsKey && AnalyticsHost);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public static capture(data: {
|
|
33
|
+
event: string;
|
|
34
|
+
distinctId: string;
|
|
35
|
+
properties?: JSONObject | undefined;
|
|
36
|
+
}): void {
|
|
37
|
+
try {
|
|
38
|
+
if (!this.isConfigured()) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!data.distinctId) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
API.post<JSONObject>({
|
|
47
|
+
url: URL.fromString(AnalyticsHost.toString()).addRoute("/capture/"),
|
|
48
|
+
data: {
|
|
49
|
+
api_key: AnalyticsKey,
|
|
50
|
+
event: data.event,
|
|
51
|
+
distinct_id: data.distinctId,
|
|
52
|
+
properties: {
|
|
53
|
+
source: "oneuptime-server",
|
|
54
|
+
...(data.properties || {}),
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
})
|
|
58
|
+
.then((result: HTTPResponse<JSONObject> | HTTPErrorResponse) => {
|
|
59
|
+
/*
|
|
60
|
+
* API.post resolves (does not reject) on HTTP error statuses, so a
|
|
61
|
+
* misconfigured ANALYTICS_KEY (401) or malformed body (400) must be
|
|
62
|
+
* surfaced here or events vanish with no log signal.
|
|
63
|
+
*/
|
|
64
|
+
if (result instanceof HTTPErrorResponse) {
|
|
65
|
+
logger.error(
|
|
66
|
+
`ProductAnalytics capture failed for event ${data.event}: HTTP ${result.statusCode} ${result.message}`,
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
})
|
|
70
|
+
.catch((err: Error) => {
|
|
71
|
+
logger.error("ProductAnalytics capture failed:");
|
|
72
|
+
logger.error(err);
|
|
73
|
+
});
|
|
74
|
+
} catch (err) {
|
|
75
|
+
/*
|
|
76
|
+
* e.g. URL.fromString throws on a malformed ANALYTICS_HOST. Analytics
|
|
77
|
+
* runs inside request-path hooks (signup, project create, plan change)
|
|
78
|
+
* and must never fail those requests.
|
|
79
|
+
*/
|
|
80
|
+
logger.error("ProductAnalytics capture failed:");
|
|
81
|
+
logger.error(err as Error);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/*
|
|
86
|
+
* Capture an event attributed to a user by id, resolving the user's email
|
|
87
|
+
* to use as the distinct id. Skips silently when the user cannot be
|
|
88
|
+
* resolved (e.g. records created by probes, workflows or API keys).
|
|
89
|
+
*/
|
|
90
|
+
public static captureForUser(data: {
|
|
91
|
+
userId: ObjectID | undefined | null;
|
|
92
|
+
event: string;
|
|
93
|
+
properties?: JSONObject | undefined;
|
|
94
|
+
}): void {
|
|
95
|
+
try {
|
|
96
|
+
if (!this.isConfigured()) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (!data.userId) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
UserService.findOneById({
|
|
105
|
+
id: data.userId,
|
|
106
|
+
select: {
|
|
107
|
+
email: true,
|
|
108
|
+
},
|
|
109
|
+
props: {
|
|
110
|
+
isRoot: true,
|
|
111
|
+
},
|
|
112
|
+
})
|
|
113
|
+
.then((user: User | null) => {
|
|
114
|
+
if (!user || !user.email) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
this.capture({
|
|
119
|
+
event: data.event,
|
|
120
|
+
distinctId: user.email.toString(),
|
|
121
|
+
properties: data.properties,
|
|
122
|
+
});
|
|
123
|
+
})
|
|
124
|
+
.catch((err: Error) => {
|
|
125
|
+
logger.error("ProductAnalytics captureForUser failed:");
|
|
126
|
+
logger.error(err);
|
|
127
|
+
});
|
|
128
|
+
} catch (err) {
|
|
129
|
+
logger.error("ProductAnalytics captureForUser failed:");
|
|
130
|
+
logger.error(err as Error);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -26,6 +26,8 @@ export default class TelemetryUtil {
|
|
|
26
26
|
name: true,
|
|
27
27
|
description: true,
|
|
28
28
|
unit: true,
|
|
29
|
+
isMonotonic: true,
|
|
30
|
+
aggregationTemporality: true,
|
|
29
31
|
},
|
|
30
32
|
props: {
|
|
31
33
|
isRoot: true,
|
|
@@ -66,6 +68,30 @@ export default class TelemetryUtil {
|
|
|
66
68
|
metricType.unit = metricTypeInMap.unit || "";
|
|
67
69
|
}
|
|
68
70
|
|
|
71
|
+
/*
|
|
72
|
+
* Counter semantics (isMonotonic / aggregationTemporality) are only
|
|
73
|
+
* known on OTel metric ingest paths — other callers (monitor
|
|
74
|
+
* metrics, heartbeat metrics) never set them, so an undefined
|
|
75
|
+
* incoming value means "unknown", not "clear the stored value".
|
|
76
|
+
*/
|
|
77
|
+
if (
|
|
78
|
+
metricTypeInMap.isMonotonic !== undefined &&
|
|
79
|
+
metricType.isMonotonic !== metricTypeInMap.isMonotonic
|
|
80
|
+
) {
|
|
81
|
+
isSame = false;
|
|
82
|
+
metricType.isMonotonic = metricTypeInMap.isMonotonic;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (
|
|
86
|
+
metricTypeInMap.aggregationTemporality !== undefined &&
|
|
87
|
+
metricType.aggregationTemporality !==
|
|
88
|
+
metricTypeInMap.aggregationTemporality
|
|
89
|
+
) {
|
|
90
|
+
isSame = false;
|
|
91
|
+
metricType.aggregationTemporality =
|
|
92
|
+
metricTypeInMap.aggregationTemporality;
|
|
93
|
+
}
|
|
94
|
+
|
|
69
95
|
// check if services are same
|
|
70
96
|
|
|
71
97
|
for (const serviceId of servicesInMap) {
|
|
@@ -92,6 +118,12 @@ export default class TelemetryUtil {
|
|
|
92
118
|
services: metricType.services || [],
|
|
93
119
|
description: metricTypeInMap.description || "",
|
|
94
120
|
unit: metricTypeInMap.unit || "",
|
|
121
|
+
...(metricType.isMonotonic !== undefined
|
|
122
|
+
? { isMonotonic: metricType.isMonotonic }
|
|
123
|
+
: {}),
|
|
124
|
+
...(metricType.aggregationTemporality !== undefined
|
|
125
|
+
? { aggregationTemporality: metricType.aggregationTemporality }
|
|
126
|
+
: {}),
|
|
95
127
|
},
|
|
96
128
|
props: {
|
|
97
129
|
isRoot: true,
|
|
@@ -104,6 +136,13 @@ export default class TelemetryUtil {
|
|
|
104
136
|
metricType.name = metricName;
|
|
105
137
|
metricType.description = metricTypeInMap.description || "";
|
|
106
138
|
metricType.unit = metricTypeInMap.unit || "";
|
|
139
|
+
if (metricTypeInMap.isMonotonic !== undefined) {
|
|
140
|
+
metricType.isMonotonic = metricTypeInMap.isMonotonic;
|
|
141
|
+
}
|
|
142
|
+
if (metricTypeInMap.aggregationTemporality !== undefined) {
|
|
143
|
+
metricType.aggregationTemporality =
|
|
144
|
+
metricTypeInMap.aggregationTemporality;
|
|
145
|
+
}
|
|
107
146
|
metricType.projectId = data.projectId;
|
|
108
147
|
metricType.services = [];
|
|
109
148
|
|
|
@@ -888,3 +888,24 @@ export default class TelemetryEntity {
|
|
|
888
888
|
return out;
|
|
889
889
|
}
|
|
890
890
|
}
|
|
891
|
+
|
|
892
|
+
/**
|
|
893
|
+
* `container.id` is the container identity (mirrors the container
|
|
894
|
+
* resolver above — id-only). Read-side helper in the mold of
|
|
895
|
+
* `EntityKey.keyForHost` & co.; it lives here rather than in the
|
|
896
|
+
* isomorphic EntityKey module because its only consumer today is the
|
|
897
|
+
* server-side container metric-rollup read path
|
|
898
|
+
* (`MetricService.tryBuildEntityAggregateMVStatement` against
|
|
899
|
+
* `MetricItemAggMV1mByContainer`), so there is no reason to widen the
|
|
900
|
+
* browser bundle. Pass the raw `container.id` attribute value.
|
|
901
|
+
*/
|
|
902
|
+
export function keyForContainer(
|
|
903
|
+
projectId: string,
|
|
904
|
+
containerId: string,
|
|
905
|
+
): string {
|
|
906
|
+
return computeEntityKeyShared({
|
|
907
|
+
projectId,
|
|
908
|
+
entityType: EntityType.Container,
|
|
909
|
+
identifyingAttributes: { "container.id": containerId },
|
|
910
|
+
});
|
|
911
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import "../TestingUtils/Init";
|
|
2
|
+
import BaseAnalyticsAPI from "../../../Server/API/BaseAnalyticsAPI";
|
|
3
|
+
import AnalyticsDataModel from "../../../Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel";
|
|
4
|
+
import AggregateBy from "../../../Types/BaseDatabase/AggregateBy";
|
|
5
|
+
import { LIMIT_PER_PROJECT } from "../../../Types/Database/LimitMax";
|
|
6
|
+
import { describe, expect, it } from "@jest/globals";
|
|
7
|
+
|
|
8
|
+
describe("BaseAnalyticsAPI.clampAggregateLimit", () => {
|
|
9
|
+
type MakeAggregateByFunction = (
|
|
10
|
+
limit: unknown,
|
|
11
|
+
) => AggregateBy<AnalyticsDataModel>;
|
|
12
|
+
|
|
13
|
+
const makeAggregateBy: MakeAggregateByFunction = (
|
|
14
|
+
limit: unknown,
|
|
15
|
+
): AggregateBy<AnalyticsDataModel> => {
|
|
16
|
+
return { limit } as unknown as AggregateBy<AnalyticsDataModel>;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
it("clamps a client-sent limit above LIMIT_PER_PROJECT down to LIMIT_PER_PROJECT", () => {
|
|
20
|
+
const aggregateBy: AggregateBy<AnalyticsDataModel> =
|
|
21
|
+
makeAggregateBy(999999999);
|
|
22
|
+
|
|
23
|
+
BaseAnalyticsAPI.clampAggregateLimit(aggregateBy);
|
|
24
|
+
|
|
25
|
+
expect(aggregateBy.limit).toBe(LIMIT_PER_PROJECT);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("clamps limit = LIMIT_PER_PROJECT + 1", () => {
|
|
29
|
+
const aggregateBy: AggregateBy<AnalyticsDataModel> = makeAggregateBy(
|
|
30
|
+
LIMIT_PER_PROJECT + 1,
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
BaseAnalyticsAPI.clampAggregateLimit(aggregateBy);
|
|
34
|
+
|
|
35
|
+
expect(aggregateBy.limit).toBe(LIMIT_PER_PROJECT);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("does NOT clamp down to 1000 — grouped charts legitimately use the full 10k", () => {
|
|
39
|
+
const aggregateBy: AggregateBy<AnalyticsDataModel> =
|
|
40
|
+
makeAggregateBy(LIMIT_PER_PROJECT);
|
|
41
|
+
|
|
42
|
+
BaseAnalyticsAPI.clampAggregateLimit(aggregateBy);
|
|
43
|
+
|
|
44
|
+
expect(aggregateBy.limit).toBe(LIMIT_PER_PROJECT);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("leaves an in-range limit untouched", () => {
|
|
48
|
+
const aggregateBy: AggregateBy<AnalyticsDataModel> = makeAggregateBy(500);
|
|
49
|
+
|
|
50
|
+
BaseAnalyticsAPI.clampAggregateLimit(aggregateBy);
|
|
51
|
+
|
|
52
|
+
expect(aggregateBy.limit).toBe(500);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("leaves an absent limit for the service layer's own defaulting", () => {
|
|
56
|
+
const aggregateBy: AggregateBy<AnalyticsDataModel> =
|
|
57
|
+
makeAggregateBy(undefined);
|
|
58
|
+
|
|
59
|
+
BaseAnalyticsAPI.clampAggregateLimit(aggregateBy);
|
|
60
|
+
|
|
61
|
+
expect(aggregateBy.limit).toBeUndefined();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("leaves a non-numeric limit untouched (existing validation handles it)", () => {
|
|
65
|
+
const aggregateBy: AggregateBy<AnalyticsDataModel> =
|
|
66
|
+
makeAggregateBy("not-a-number");
|
|
67
|
+
|
|
68
|
+
BaseAnalyticsAPI.clampAggregateLimit(aggregateBy);
|
|
69
|
+
|
|
70
|
+
expect(aggregateBy.limit).toBe("not-a-number" as unknown as number);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -36,7 +36,15 @@ function mockRedisClient(): ClientType {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
function lastMockPermit(): MockPermit {
|
|
39
|
-
|
|
39
|
+
/*
|
|
40
|
+
* Indexed rather than .at(-1): this project targets es2017, so
|
|
41
|
+
* Array.prototype.at is outside its lib. Older @types/node pulled in newer
|
|
42
|
+
* lib references that happened to declare it, which is why this compiled
|
|
43
|
+
* before the types were aligned with the Node 26 runtime.
|
|
44
|
+
*/
|
|
45
|
+
const results: Array<{ value: unknown }> =
|
|
46
|
+
redisSemaphoreConstructor.mock.results;
|
|
47
|
+
const result: unknown = results[results.length - 1]?.value;
|
|
40
48
|
return result as MockPermit;
|
|
41
49
|
}
|
|
42
50
|
|
|
@@ -364,14 +364,33 @@ describe("AnalyticsDatabaseService", () => {
|
|
|
364
364
|
const query: string = service.toAggregateStatement(makeBaseAggregateBy())
|
|
365
365
|
.statement.query;
|
|
366
366
|
|
|
367
|
-
|
|
367
|
+
/*
|
|
368
|
+
* 1-day window derives a FifteenMinutes bucket (see
|
|
369
|
+
* AggregationIntervalUtil), which compiles through the shared
|
|
370
|
+
* expression map — NOT via lowercasing the enum into date_trunc.
|
|
371
|
+
*/
|
|
368
372
|
expect(query).toContain(
|
|
369
|
-
"
|
|
373
|
+
"toStartOfInterval(column_ObjectID, INTERVAL 15 MINUTE) as column_ObjectID",
|
|
370
374
|
);
|
|
375
|
+
expect(query).not.toContain("date_trunc('fifteenminutes'");
|
|
371
376
|
expect(query).toContain("GROUP BY column_ObjectID");
|
|
372
377
|
expect(query).not.toContain("min(column_ObjectID)");
|
|
373
378
|
});
|
|
374
379
|
|
|
380
|
+
test("derives an Hour bucket for a 5-day window", () => {
|
|
381
|
+
const query: string = service.toAggregateStatement(
|
|
382
|
+
makeBaseAggregateBy({
|
|
383
|
+
startTimestamp: new Date("2024-01-01"),
|
|
384
|
+
endTimestamp: new Date("2024-01-06"),
|
|
385
|
+
}),
|
|
386
|
+
).statement.query;
|
|
387
|
+
|
|
388
|
+
expect(query).toContain(
|
|
389
|
+
"date_trunc('hour', toStartOfInterval(column_ObjectID, INTERVAL 1 hour))",
|
|
390
|
+
);
|
|
391
|
+
expect(query).toContain("GROUP BY column_ObjectID");
|
|
392
|
+
});
|
|
393
|
+
|
|
375
394
|
test("Total with no group-by drops the time bucket and guards empty windows", () => {
|
|
376
395
|
const query: string = service.toAggregateStatement(
|
|
377
396
|
makeBaseAggregateBy({ aggregationInterval: "Total" }),
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import TelemetryEntity, {
|
|
2
|
+
ExtractedEntity,
|
|
3
|
+
keyForContainer,
|
|
4
|
+
} from "../../../Server/Utils/Telemetry/TelemetryEntity";
|
|
5
|
+
import {
|
|
6
|
+
keyForHost,
|
|
7
|
+
keyForKubernetesCluster,
|
|
8
|
+
keyForService,
|
|
9
|
+
} from "../../../Utils/Telemetry/EntityKey";
|
|
10
|
+
import EntityType from "../../../Types/Telemetry/EntityType";
|
|
11
|
+
import { describe, expect, test } from "@jest/globals";
|
|
12
|
+
|
|
13
|
+
/*
|
|
14
|
+
* Pins the read-side key derivations MetricService's entity-MV routing
|
|
15
|
+
* uses (keyForHost / keyForKubernetesCluster / keyForContainer /
|
|
16
|
+
* keyForService) against the ingest side that stamps the scalar
|
|
17
|
+
* entity-key columns the per-entity rollup MVs group by
|
|
18
|
+
* (TelemetryEntity.extractEntities -> serviceEntityKey / hostEntityKey /
|
|
19
|
+
* k8sClusterEntityKey / containerEntityKey on MetricItemV3; the MVs copy
|
|
20
|
+
* the stamped column verbatim — `WHERE <key> != '' GROUP BY ... <key>`).
|
|
21
|
+
*
|
|
22
|
+
* Byte-equality between the two sides is what makes an MV lookup
|
|
23
|
+
* correct: a routed predicate whose key doesn't match the stamp finds
|
|
24
|
+
* nothing. This is the sibling of EntityKeySqlParity.test.ts (which pins
|
|
25
|
+
* keyForHost against ClickHouse's SQL SHA-256); the host vector below
|
|
26
|
+
* reuses that test's live-ClickHouse-verified literal so the ingest
|
|
27
|
+
* stamping stays anchored to the same externally computed value.
|
|
28
|
+
*/
|
|
29
|
+
describe("entity-MV routing keys — parity with ingest-stamped scalar entity keys", () => {
|
|
30
|
+
const projectId: string = "proj-123";
|
|
31
|
+
|
|
32
|
+
/*
|
|
33
|
+
* A resource carrying all four routable identities at once, with
|
|
34
|
+
* casing/whitespace drift to exercise canonicalization.
|
|
35
|
+
*/
|
|
36
|
+
const attributes: Record<string, string> = {
|
|
37
|
+
"host.name": "Web-Server-01 ",
|
|
38
|
+
"k8s.cluster.name": "Prod-EU-1",
|
|
39
|
+
"container.id": "ABC123def456",
|
|
40
|
+
"service.name": "Checkout",
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
type FirstOfTypeFunction = (
|
|
44
|
+
entities: Array<ExtractedEntity>,
|
|
45
|
+
entityType: EntityType,
|
|
46
|
+
) => string;
|
|
47
|
+
|
|
48
|
+
/*
|
|
49
|
+
* Mirrors OtelIngestBaseService.scalarEntityKeysFromEntities: the
|
|
50
|
+
* FIRST extracted entity of a type is what lands in the scalar column
|
|
51
|
+
* ('' when the type is absent).
|
|
52
|
+
*/
|
|
53
|
+
const firstOfType: FirstOfTypeFunction = (
|
|
54
|
+
entities: Array<ExtractedEntity>,
|
|
55
|
+
entityType: EntityType,
|
|
56
|
+
): string => {
|
|
57
|
+
return (
|
|
58
|
+
entities.find((entity: ExtractedEntity) => {
|
|
59
|
+
return entity.entityType === entityType;
|
|
60
|
+
})?.entityKey || ""
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
test("each routable read-side key byte-matches the stamped scalar column", () => {
|
|
65
|
+
const entities: Array<ExtractedEntity> = TelemetryEntity.extractEntities({
|
|
66
|
+
projectId,
|
|
67
|
+
attributes,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
expect(firstOfType(entities, EntityType.Host)).toBe(
|
|
71
|
+
keyForHost(projectId, "Web-Server-01 "),
|
|
72
|
+
);
|
|
73
|
+
expect(firstOfType(entities, EntityType.KubernetesCluster)).toBe(
|
|
74
|
+
keyForKubernetesCluster(projectId, "Prod-EU-1"),
|
|
75
|
+
);
|
|
76
|
+
expect(firstOfType(entities, EntityType.Container)).toBe(
|
|
77
|
+
keyForContainer(projectId, "ABC123def456"),
|
|
78
|
+
);
|
|
79
|
+
expect(firstOfType(entities, EntityType.Service)).toBe(
|
|
80
|
+
keyForService(projectId, "Checkout"),
|
|
81
|
+
);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test("read-side keys canonicalize exactly like ingest (spelling drift lands on one rollup stream)", () => {
|
|
85
|
+
const drifted: Array<ExtractedEntity> = TelemetryEntity.extractEntities({
|
|
86
|
+
projectId,
|
|
87
|
+
attributes: {
|
|
88
|
+
"host.name": "web-server-01",
|
|
89
|
+
"k8s.cluster.name": " prod-eu-1 ",
|
|
90
|
+
"container.id": "abc123DEF456",
|
|
91
|
+
"service.name": " checkout",
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
expect(firstOfType(drifted, EntityType.Host)).toBe(
|
|
96
|
+
keyForHost(projectId, "Web-Server-01 "),
|
|
97
|
+
);
|
|
98
|
+
expect(firstOfType(drifted, EntityType.KubernetesCluster)).toBe(
|
|
99
|
+
keyForKubernetesCluster(projectId, "Prod-EU-1"),
|
|
100
|
+
);
|
|
101
|
+
expect(firstOfType(drifted, EntityType.Container)).toBe(
|
|
102
|
+
keyForContainer(projectId, "ABC123def456"),
|
|
103
|
+
);
|
|
104
|
+
expect(firstOfType(drifted, EntityType.Service)).toBe(
|
|
105
|
+
keyForService(projectId, "Checkout"),
|
|
106
|
+
);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test("host stamping matches the live-ClickHouse-verified vector from EntityKeySqlParity", () => {
|
|
110
|
+
const entities: Array<ExtractedEntity> = TelemetryEntity.extractEntities({
|
|
111
|
+
projectId: "proj-123",
|
|
112
|
+
attributes: { "host.name": "Web-Server-01 " },
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Literal output of ClickHouse 25.7's SHA-256 SQL for this identity.
|
|
116
|
+
expect(firstOfType(entities, EntityType.Host)).toBe("dba90fb9cca1242e");
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
test("service.namespace forks the stamped key — the bare-name key MUST NOT be assumed (registry required)", () => {
|
|
120
|
+
const namespaced: Array<ExtractedEntity> = TelemetryEntity.extractEntities({
|
|
121
|
+
projectId,
|
|
122
|
+
attributes: {
|
|
123
|
+
"service.name": "checkout",
|
|
124
|
+
"service.namespace": "prod",
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
const stampedKey: string = firstOfType(namespaced, EntityType.Service);
|
|
129
|
+
|
|
130
|
+
// Ingest folds the namespace in ...
|
|
131
|
+
expect(stampedKey).toBe(keyForService(projectId, "checkout", "prod"));
|
|
132
|
+
/*
|
|
133
|
+
* ... so the bare-name derivation finds NOTHING for these rows. This
|
|
134
|
+
* is why MetricService resolves service key SETS from the registry
|
|
135
|
+
* and falls back to raw on a miss, instead of computing one key.
|
|
136
|
+
*/
|
|
137
|
+
expect(stampedKey).not.toBe(keyForService(projectId, "checkout"));
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
test("a blank namespace is not identity-bearing on either side", () => {
|
|
141
|
+
const blankNamespace: Array<ExtractedEntity> =
|
|
142
|
+
TelemetryEntity.extractEntities({
|
|
143
|
+
projectId,
|
|
144
|
+
attributes: {
|
|
145
|
+
"service.name": "checkout",
|
|
146
|
+
"service.namespace": " ",
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
expect(firstOfType(blankNamespace, EntityType.Service)).toBe(
|
|
151
|
+
keyForService(projectId, "checkout"),
|
|
152
|
+
);
|
|
153
|
+
expect(keyForService(projectId, "checkout", " ")).toBe(
|
|
154
|
+
keyForService(projectId, "checkout"),
|
|
155
|
+
);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
test("entityKeys membership (the entityScope raw predicate) contains every routable key", () => {
|
|
159
|
+
const membershipKeys: Array<string> = TelemetryEntity.extractEntityKeys({
|
|
160
|
+
projectId,
|
|
161
|
+
attributes,
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
for (const key of [
|
|
165
|
+
keyForHost(projectId, "Web-Server-01 "),
|
|
166
|
+
keyForKubernetesCluster(projectId, "Prod-EU-1"),
|
|
167
|
+
keyForContainer(projectId, "ABC123def456"),
|
|
168
|
+
keyForService(projectId, "Checkout"),
|
|
169
|
+
]) {
|
|
170
|
+
expect(membershipKeys).toContain(key);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
});
|