@oneuptime/common 11.5.9 → 11.5.10
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/Index.ts +12 -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/Index.js +12 -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 +2 -2
|
@@ -68,6 +68,7 @@ import { MonitorFeedEventType } from "../../Models/DatabaseModels/MonitorFeed";
|
|
|
68
68
|
import { Gray500, Green500 } from "../../Types/BrandColors";
|
|
69
69
|
import LabelService from "./LabelService";
|
|
70
70
|
import logger, { LogAttributes } from "../Utils/Logger";
|
|
71
|
+
import ProductAnalytics from "../Utils/ProductAnalytics";
|
|
71
72
|
import PushNotificationUtil from "../Utils/PushNotificationUtil";
|
|
72
73
|
import ExceptionMessages from "../../Types/Exception/ExceptionMessages";
|
|
73
74
|
import Project from "../../Models/DatabaseModels/Project";
|
|
@@ -637,6 +638,19 @@ export class Service extends DatabaseService<Model> {
|
|
|
637
638
|
throw new BadDataException("currentMonitorStatusId is required");
|
|
638
639
|
}
|
|
639
640
|
|
|
641
|
+
/*
|
|
642
|
+
* Activation event for marketing funnels. Only fires for human-created
|
|
643
|
+
* monitors (captureForUser skips when there is no user).
|
|
644
|
+
*/
|
|
645
|
+
ProductAnalytics.captureForUser({
|
|
646
|
+
userId: onCreate.createBy.props.userId || createdItem.createdByUserId,
|
|
647
|
+
event: "server/monitor_created",
|
|
648
|
+
properties: {
|
|
649
|
+
project_id: createdItem.projectId.toString(),
|
|
650
|
+
monitor_type: createdItem.monitorType?.toString() || "",
|
|
651
|
+
},
|
|
652
|
+
});
|
|
653
|
+
|
|
640
654
|
const monitor: Model | null = await this.findOneById({
|
|
641
655
|
id: createdItem.id,
|
|
642
656
|
select: {
|
|
@@ -1,10 +1,52 @@
|
|
|
1
|
+
import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
|
|
2
|
+
import ObjectID from "../../Types/ObjectID";
|
|
1
3
|
import DatabaseService from "./DatabaseService";
|
|
2
4
|
import Model from "../../Models/DatabaseModels/NetworkDeviceOwnerTeam";
|
|
5
|
+
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
3
6
|
|
|
4
7
|
export class Service extends DatabaseService<Model> {
|
|
5
8
|
public constructor() {
|
|
6
9
|
super(Model);
|
|
7
10
|
}
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
* Returns the ids of all teams that own the given network device. Used to
|
|
14
|
+
* fan device ownership into monitor-created incidents/alerts and into the
|
|
15
|
+
* owner-added notification job.
|
|
16
|
+
*/
|
|
17
|
+
@CaptureSpan()
|
|
18
|
+
public async getOwnerTeamIdsForDevice(
|
|
19
|
+
networkDeviceId: ObjectID,
|
|
20
|
+
projectId?: ObjectID | undefined,
|
|
21
|
+
): Promise<Array<ObjectID>> {
|
|
22
|
+
const ownerTeams: Array<Model> = await this.findBy({
|
|
23
|
+
query: {
|
|
24
|
+
networkDeviceId: networkDeviceId,
|
|
25
|
+
/*
|
|
26
|
+
* Scope to the project when known so a monitor step referencing a
|
|
27
|
+
* device from another project can never fan out its owners.
|
|
28
|
+
*/
|
|
29
|
+
...(projectId ? { projectId: projectId } : {}),
|
|
30
|
+
},
|
|
31
|
+
select: {
|
|
32
|
+
_id: true,
|
|
33
|
+
teamId: true,
|
|
34
|
+
},
|
|
35
|
+
skip: 0,
|
|
36
|
+
limit: LIMIT_PER_PROJECT,
|
|
37
|
+
props: {
|
|
38
|
+
isRoot: true,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return ownerTeams
|
|
43
|
+
.map((ownerTeam: Model) => {
|
|
44
|
+
return ownerTeam.teamId!;
|
|
45
|
+
})
|
|
46
|
+
.filter((teamId: ObjectID) => {
|
|
47
|
+
return Boolean(teamId);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
8
50
|
}
|
|
9
51
|
|
|
10
52
|
export default new Service();
|
|
@@ -1,10 +1,116 @@
|
|
|
1
|
+
import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
|
|
2
|
+
import MonitorStep from "../../Types/Monitor/MonitorStep";
|
|
3
|
+
import ObjectID from "../../Types/ObjectID";
|
|
1
4
|
import DatabaseService from "./DatabaseService";
|
|
5
|
+
import NetworkDeviceOwnerTeamService from "./NetworkDeviceOwnerTeamService";
|
|
2
6
|
import Model from "../../Models/DatabaseModels/NetworkDeviceOwnerUser";
|
|
7
|
+
import Monitor from "../../Models/DatabaseModels/Monitor";
|
|
8
|
+
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
9
|
+
|
|
10
|
+
export interface NetworkDeviceOwners {
|
|
11
|
+
ownerUserIds: Array<ObjectID>;
|
|
12
|
+
ownerTeamIds: Array<ObjectID>;
|
|
13
|
+
}
|
|
3
14
|
|
|
4
15
|
export class Service extends DatabaseService<Model> {
|
|
5
16
|
public constructor() {
|
|
6
17
|
super(Model);
|
|
7
18
|
}
|
|
19
|
+
|
|
20
|
+
/*
|
|
21
|
+
* Returns the ids of all users that own the given network device. Used to
|
|
22
|
+
* fan device ownership into monitor-created incidents/alerts and into the
|
|
23
|
+
* owner-added notification job.
|
|
24
|
+
*/
|
|
25
|
+
@CaptureSpan()
|
|
26
|
+
public async getOwnerUserIdsForDevice(
|
|
27
|
+
networkDeviceId: ObjectID,
|
|
28
|
+
projectId?: ObjectID | undefined,
|
|
29
|
+
): Promise<Array<ObjectID>> {
|
|
30
|
+
const ownerUsers: Array<Model> = await this.findBy({
|
|
31
|
+
query: {
|
|
32
|
+
networkDeviceId: networkDeviceId,
|
|
33
|
+
/*
|
|
34
|
+
* Scope to the project when known so a monitor step referencing a
|
|
35
|
+
* device from another project can never fan out its owners.
|
|
36
|
+
*/
|
|
37
|
+
...(projectId ? { projectId: projectId } : {}),
|
|
38
|
+
},
|
|
39
|
+
select: {
|
|
40
|
+
_id: true,
|
|
41
|
+
userId: true,
|
|
42
|
+
},
|
|
43
|
+
skip: 0,
|
|
44
|
+
limit: LIMIT_PER_PROJECT,
|
|
45
|
+
props: {
|
|
46
|
+
isRoot: true,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
return ownerUsers
|
|
51
|
+
.map((ownerUser: Model) => {
|
|
52
|
+
return ownerUser.userId!;
|
|
53
|
+
})
|
|
54
|
+
.filter((userId: ObjectID) => {
|
|
55
|
+
return Boolean(userId);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/*
|
|
60
|
+
* Resolves the owner users/teams of the network device a monitor watches
|
|
61
|
+
* (if any). The device id lives on the monitor step config
|
|
62
|
+
* (step.data.networkDeviceMonitor.networkDeviceId). Prefer the step that
|
|
63
|
+
* produced the current probe response; fall back to the first step that
|
|
64
|
+
* references a device so callers without a step id still pick up owners.
|
|
65
|
+
* No-op (and no queries) for monitors that do not reference a device.
|
|
66
|
+
*/
|
|
67
|
+
@CaptureSpan()
|
|
68
|
+
public async getDeviceOwnersForMonitor(data: {
|
|
69
|
+
monitor: Monitor;
|
|
70
|
+
monitorStepId?: string | undefined;
|
|
71
|
+
}): Promise<NetworkDeviceOwners> {
|
|
72
|
+
const monitorSteps: Array<MonitorStep> =
|
|
73
|
+
data.monitor.monitorSteps?.data?.monitorStepsInstanceArray || [];
|
|
74
|
+
|
|
75
|
+
let monitorStep: MonitorStep | undefined = undefined;
|
|
76
|
+
|
|
77
|
+
if (data.monitorStepId) {
|
|
78
|
+
monitorStep = monitorSteps.find((step: MonitorStep) => {
|
|
79
|
+
return step.id.toString() === data.monitorStepId;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (!monitorStep?.data?.networkDeviceMonitor?.networkDeviceId) {
|
|
84
|
+
monitorStep = monitorSteps.find((step: MonitorStep) => {
|
|
85
|
+
return Boolean(step.data?.networkDeviceMonitor?.networkDeviceId);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const networkDeviceIdAsString: string | undefined =
|
|
90
|
+
monitorStep?.data?.networkDeviceMonitor?.networkDeviceId;
|
|
91
|
+
|
|
92
|
+
if (!networkDeviceIdAsString) {
|
|
93
|
+
return {
|
|
94
|
+
ownerUserIds: [],
|
|
95
|
+
ownerTeamIds: [],
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const networkDeviceId: ObjectID = new ObjectID(networkDeviceIdAsString);
|
|
100
|
+
const projectId: ObjectID | undefined = data.monitor.projectId;
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
ownerUserIds: await this.getOwnerUserIdsForDevice(
|
|
104
|
+
networkDeviceId,
|
|
105
|
+
projectId,
|
|
106
|
+
),
|
|
107
|
+
ownerTeamIds:
|
|
108
|
+
await NetworkDeviceOwnerTeamService.getOwnerTeamIdsForDevice(
|
|
109
|
+
networkDeviceId,
|
|
110
|
+
projectId,
|
|
111
|
+
),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
8
114
|
}
|
|
9
115
|
|
|
10
116
|
export default new Service();
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import ClickhouseDatabase from "../Infrastructure/ClickhouseDatabase";
|
|
2
|
+
import AnalyticsDatabaseService from "./AnalyticsDatabaseService";
|
|
3
|
+
import NetworkFlow from "../../Models/AnalyticsModels/NetworkFlow";
|
|
4
|
+
|
|
5
|
+
export class NetworkFlowService extends AnalyticsDatabaseService<NetworkFlow> {
|
|
6
|
+
public constructor(clickhouseDatabase?: ClickhouseDatabase | undefined) {
|
|
7
|
+
super({ modelType: NetworkFlow, database: clickhouseDatabase });
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default new NetworkFlowService();
|
|
@@ -31,6 +31,7 @@ import WorkspaceNotificationRuleService, {
|
|
|
31
31
|
MessageBlocksByWorkspaceType,
|
|
32
32
|
} from "./WorkspaceNotificationRuleService";
|
|
33
33
|
import logger, { LogAttributes } from "../Utils/Logger";
|
|
34
|
+
import ProductAnalytics from "../Utils/ProductAnalytics";
|
|
34
35
|
import OnCallDutyPolicyWorkspaceMessages from "../Utils/Workspace/WorkspaceMessages/OnCallDutyPolicy";
|
|
35
36
|
import OnCallDutyPolicyFeedService from "./OnCallDutyPolicyFeedService";
|
|
36
37
|
import { OnCallDutyPolicyFeedEventType } from "../../Models/DatabaseModels/OnCallDutyPolicyFeed";
|
|
@@ -44,13 +45,22 @@ export class Service extends DatabaseService<OnCallDutyPolicy> {
|
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
protected override async onCreateSuccess(
|
|
47
|
-
|
|
48
|
+
onCreate: OnCreate<OnCallDutyPolicy>,
|
|
48
49
|
createdItem: OnCallDutyPolicy,
|
|
49
50
|
): Promise<OnCallDutyPolicy> {
|
|
50
51
|
if (!createdItem.id) {
|
|
51
52
|
throw new BadDataException("On Call Policy id not found.");
|
|
52
53
|
}
|
|
53
54
|
|
|
55
|
+
// Activation event for marketing funnels.
|
|
56
|
+
ProductAnalytics.captureForUser({
|
|
57
|
+
userId: onCreate.createBy.props.userId || createdItem.createdByUserId,
|
|
58
|
+
event: "server/on_call_policy_created",
|
|
59
|
+
properties: {
|
|
60
|
+
project_id: createdItem.projectId?.toString() || "",
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
|
|
54
64
|
if (createdItem.projectId) {
|
|
55
65
|
try {
|
|
56
66
|
await OnCallDutyPolicyLabelRuleEngineService.applyRulesToOnCallDutyPolicy(
|
|
@@ -15,6 +15,7 @@ import QueryHelper from "../Types/Database/QueryHelper";
|
|
|
15
15
|
import UpdateBy from "../Types/Database/UpdateBy";
|
|
16
16
|
import logger, { LogAttributes } from "../Utils/Logger";
|
|
17
17
|
import Errors from "../Utils/Errors";
|
|
18
|
+
import ProductAnalytics from "../Utils/ProductAnalytics";
|
|
18
19
|
import AccessTokenService from "./AccessTokenService";
|
|
19
20
|
import BillingService from "./BillingService";
|
|
20
21
|
import DatabaseService from "./DatabaseService";
|
|
@@ -55,6 +56,7 @@ import EmailTemplateType from "../../Types/Email/EmailTemplateType";
|
|
|
55
56
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
56
57
|
import NotAuthorizedException from "../../Types/Exception/NotAuthorizedException";
|
|
57
58
|
import IconProp from "../../Types/Icon/IconProp";
|
|
59
|
+
import { JSONObject } from "../../Types/JSON";
|
|
58
60
|
import ObjectID from "../../Types/ObjectID";
|
|
59
61
|
import Permission from "../../Types/Permission";
|
|
60
62
|
import IncidentSeverity from "../../Models/DatabaseModels/IncidentSeverity";
|
|
@@ -169,6 +171,8 @@ export class ProjectService extends DatabaseService<Model> {
|
|
|
169
171
|
utmTerm: true,
|
|
170
172
|
utmContent: true,
|
|
171
173
|
utmUrl: true,
|
|
174
|
+
clickIds: true,
|
|
175
|
+
firstTouchAttribution: true,
|
|
172
176
|
},
|
|
173
177
|
props: {
|
|
174
178
|
isRoot: true,
|
|
@@ -324,6 +328,10 @@ export class ProjectService extends DatabaseService<Model> {
|
|
|
324
328
|
data.data.utmContent = user.utmContent!;
|
|
325
329
|
data.data.utmUrl = user.utmUrl!;
|
|
326
330
|
|
|
331
|
+
// Ad attribution info (click IDs + first touch).
|
|
332
|
+
data.data.clickIds = user.clickIds!;
|
|
333
|
+
data.data.firstTouchAttribution = user.firstTouchAttribution!;
|
|
334
|
+
|
|
327
335
|
// Set default number prefixes.
|
|
328
336
|
if (!data.data.incidentNumberPrefix) {
|
|
329
337
|
data.data.incidentNumberPrefix = "INC-";
|
|
@@ -477,6 +485,11 @@ export class ProjectService extends DatabaseService<Model> {
|
|
|
477
485
|
paymentProviderPlanId: true,
|
|
478
486
|
trialEndsAt: true,
|
|
479
487
|
paymentProviderCustomerId: true,
|
|
488
|
+
createdOwnerEmail: true,
|
|
489
|
+
utmSource: true,
|
|
490
|
+
utmMedium: true,
|
|
491
|
+
utmCampaign: true,
|
|
492
|
+
clickIds: true,
|
|
480
493
|
},
|
|
481
494
|
props: {
|
|
482
495
|
isRoot: true,
|
|
@@ -583,9 +596,116 @@ export class ProjectService extends DatabaseService<Model> {
|
|
|
583
596
|
},
|
|
584
597
|
});
|
|
585
598
|
|
|
599
|
+
this.capturePlanChangeAnalytics({
|
|
600
|
+
project: project,
|
|
601
|
+
newPlan: plan,
|
|
602
|
+
newPlanId: params.paymentProviderPlanId,
|
|
603
|
+
seats: seats,
|
|
604
|
+
});
|
|
605
|
+
|
|
586
606
|
await this.sendSubscriptionChangeWebhookSlackNotification(project.id!);
|
|
587
607
|
}
|
|
588
608
|
|
|
609
|
+
/*
|
|
610
|
+
* The paid-conversion event for ad platforms: fires server-side (immune to
|
|
611
|
+
* ad blockers) whenever a project's subscription plan changes, with enough
|
|
612
|
+
* detail (plan amounts, attribution) for revenue reporting and offline
|
|
613
|
+
* conversion uploads.
|
|
614
|
+
*
|
|
615
|
+
* Upgrade/downgrade is classified by plan tier (getPlanOrder), not price:
|
|
616
|
+
* monthly<->yearly switches of the same tier and custom-pricing plans
|
|
617
|
+
* (amount sentinel -1) would misclassify on price comparison.
|
|
618
|
+
*/
|
|
619
|
+
private capturePlanChangeAnalytics(data: {
|
|
620
|
+
project: Model;
|
|
621
|
+
newPlan: SubscriptionPlan;
|
|
622
|
+
newPlanId: string;
|
|
623
|
+
seats: number;
|
|
624
|
+
}): void {
|
|
625
|
+
if (!data.project.createdOwnerEmail) {
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
const oldPlanId: string | undefined =
|
|
630
|
+
data.project.paymentProviderPlanId || undefined;
|
|
631
|
+
|
|
632
|
+
// Re-submitting the currently active plan is a no-op, not a plan change.
|
|
633
|
+
if (oldPlanId === data.newPlanId) {
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
const oldPlan: SubscriptionPlan | undefined = oldPlanId
|
|
638
|
+
? SubscriptionPlan.getSubscriptionPlanById(oldPlanId, getAllEnvVars())
|
|
639
|
+
: undefined;
|
|
640
|
+
|
|
641
|
+
// Per-month amount, or null when unknown (custom pricing / unknown plan).
|
|
642
|
+
const getMonthlyAmountInUSD: (
|
|
643
|
+
plan: SubscriptionPlan | undefined,
|
|
644
|
+
planId: string | undefined,
|
|
645
|
+
) => number | null = (
|
|
646
|
+
plan: SubscriptionPlan | undefined,
|
|
647
|
+
planId: string | undefined,
|
|
648
|
+
): number | null => {
|
|
649
|
+
if (!plan || !planId || plan.isCustomPricing()) {
|
|
650
|
+
return null;
|
|
651
|
+
}
|
|
652
|
+
return plan.getYearlyPlanId() === planId
|
|
653
|
+
? plan.getYearlySubscriptionAmountInUSD()
|
|
654
|
+
: plan.getMonthlySubscriptionAmountInUSD();
|
|
655
|
+
};
|
|
656
|
+
|
|
657
|
+
const oldMonthlyAmountInUSD: number | null = getMonthlyAmountInUSD(
|
|
658
|
+
oldPlan,
|
|
659
|
+
oldPlanId,
|
|
660
|
+
);
|
|
661
|
+
const newMonthlyAmountInUSD: number | null = getMonthlyAmountInUSD(
|
|
662
|
+
data.newPlan,
|
|
663
|
+
data.newPlanId,
|
|
664
|
+
);
|
|
665
|
+
|
|
666
|
+
const oldPlanOrder: number | null = oldPlan ? oldPlan.getPlanOrder() : null;
|
|
667
|
+
const newPlanOrder: number = data.newPlan.getPlanOrder();
|
|
668
|
+
|
|
669
|
+
const newPlanIsPaid: boolean =
|
|
670
|
+
data.newPlan.isCustomPricing() ||
|
|
671
|
+
(newMonthlyAmountInUSD !== null && newMonthlyAmountInUSD > 0);
|
|
672
|
+
|
|
673
|
+
const properties: JSONObject = {
|
|
674
|
+
project_id: data.project.id?.toString() || "",
|
|
675
|
+
old_plan: oldPlan?.getName() || "",
|
|
676
|
+
new_plan: data.newPlan.getName(),
|
|
677
|
+
seats: data.seats,
|
|
678
|
+
is_upgrade: oldPlanOrder !== null && newPlanOrder > oldPlanOrder,
|
|
679
|
+
is_downgrade: oldPlanOrder !== null && newPlanOrder < oldPlanOrder,
|
|
680
|
+
// Same tier, different plan id: monthly<->yearly billing switch.
|
|
681
|
+
is_interval_change:
|
|
682
|
+
oldPlanOrder !== null && newPlanOrder === oldPlanOrder,
|
|
683
|
+
is_paid_conversion: oldMonthlyAmountInUSD === 0 && newPlanIsPaid,
|
|
684
|
+
has_custom_pricing: data.newPlan.isCustomPricing(),
|
|
685
|
+
utm_source: data.project.utmSource || "",
|
|
686
|
+
utm_medium: data.project.utmMedium || "",
|
|
687
|
+
utm_campaign: data.project.utmCampaign || "",
|
|
688
|
+
click_ids: data.project.clickIds || {},
|
|
689
|
+
};
|
|
690
|
+
|
|
691
|
+
if (oldMonthlyAmountInUSD !== null) {
|
|
692
|
+
properties["old_monthly_amount_in_usd"] = oldMonthlyAmountInUSD;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
if (newMonthlyAmountInUSD !== null) {
|
|
696
|
+
properties["new_monthly_amount_in_usd"] = newMonthlyAmountInUSD;
|
|
697
|
+
// Value for ROAS reporting: monthly recurring revenue after the change.
|
|
698
|
+
properties["value"] = newMonthlyAmountInUSD * data.seats;
|
|
699
|
+
properties["currency"] = "USD";
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
ProductAnalytics.capture({
|
|
703
|
+
event: "server/subscription_plan_changed",
|
|
704
|
+
distinctId: data.project.createdOwnerEmail.toString(),
|
|
705
|
+
properties: properties,
|
|
706
|
+
});
|
|
707
|
+
}
|
|
708
|
+
|
|
589
709
|
private async sendSubscriptionChangeWebhookSlackNotification(
|
|
590
710
|
projectId: ObjectID,
|
|
591
711
|
): Promise<void> {
|
|
@@ -858,6 +978,22 @@ export class ProjectService extends DatabaseService<Model> {
|
|
|
858
978
|
this.addDefaultIncidentRoles(createdItem),
|
|
859
979
|
]);
|
|
860
980
|
|
|
981
|
+
if (createdItem.createdOwnerEmail) {
|
|
982
|
+
ProductAnalytics.capture({
|
|
983
|
+
event: "server/project_created",
|
|
984
|
+
distinctId: createdItem.createdOwnerEmail.toString(),
|
|
985
|
+
properties: {
|
|
986
|
+
project_id: createdItem.id?.toString() || "",
|
|
987
|
+
project_name: createdItem.name?.toString() || "",
|
|
988
|
+
plan: createdItem.planName?.toString() || "",
|
|
989
|
+
utm_source: createdItem.utmSource || "",
|
|
990
|
+
utm_medium: createdItem.utmMedium || "",
|
|
991
|
+
utm_campaign: createdItem.utmCampaign || "",
|
|
992
|
+
click_ids: createdItem.clickIds || {},
|
|
993
|
+
},
|
|
994
|
+
});
|
|
995
|
+
}
|
|
996
|
+
|
|
861
997
|
if (NotificationSlackWebhookOnCreateProject) {
|
|
862
998
|
// fetch project again.
|
|
863
999
|
const project: Model | null = await this.findOneById({
|
|
@@ -8,6 +8,7 @@ import AggregateBy, {
|
|
|
8
8
|
import { SQL, Statement } from "../Utils/AnalyticsDatabase/Statement";
|
|
9
9
|
import { getQuerySettings } from "../Utils/AnalyticsDatabase/QuerySettingsHelper";
|
|
10
10
|
import TableColumnType from "../../Types/AnalyticsDatabase/TableColumnType";
|
|
11
|
+
import AggregationInterval from "../../Types/BaseDatabase/AggregationInterval";
|
|
11
12
|
import AggregationType from "../../Types/BaseDatabase/AggregationType";
|
|
12
13
|
import SortOrder from "../../Types/BaseDatabase/SortOrder";
|
|
13
14
|
import InBetween from "../../Types/BaseDatabase/InBetween";
|
|
@@ -340,20 +341,23 @@ export class SpanService extends AnalyticsDatabaseService<Span> {
|
|
|
340
341
|
}
|
|
341
342
|
const databaseName: string = this.database.getDatasourceOptions().database!;
|
|
342
343
|
|
|
343
|
-
const aggregationInterval:
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
344
|
+
const aggregationInterval: AggregationInterval =
|
|
345
|
+
AggregateUtil.getAggregationInterval({
|
|
346
|
+
startDate: aggregateBy.startTimestamp,
|
|
347
|
+
endDate: aggregateBy.endTimestamp,
|
|
348
|
+
});
|
|
347
349
|
|
|
348
350
|
/*
|
|
349
|
-
* Bucket expression derived from the projection key
|
|
350
|
-
* interval
|
|
351
|
-
*
|
|
352
|
-
*
|
|
351
|
+
* Bucket expression derived from the projection key via the shared
|
|
352
|
+
* interval-expression map (the sub-hour tiers are not valid
|
|
353
|
+
* date_trunc units): bucketing the minute-truncated timestamp
|
|
354
|
+
* equals bucketing the raw timestamp for every interval >= 1
|
|
355
|
+
* minute. Aliased to the timestamp column name so the generic
|
|
356
|
+
* result parsing applies.
|
|
353
357
|
*/
|
|
354
358
|
const statement: Statement = new Statement();
|
|
355
359
|
statement.append(
|
|
356
|
-
`SELECT ${aggregateExpression} as durationUnixNano,
|
|
360
|
+
`SELECT ${aggregateExpression} as durationUnixNano, ${AggregateUtil.buildBucketTimestampExpression(aggregationInterval, "toStartOfMinute(startTime)")} as startTime`,
|
|
357
361
|
);
|
|
358
362
|
statement.append(
|
|
359
363
|
SQL` FROM ${databaseName}.${this.model.tableName} WHERE projectId = ${{
|
|
@@ -7,6 +7,7 @@ import CookieUtil from "../Utils/Cookie";
|
|
|
7
7
|
import { ExpressRequest } from "../Utils/Express";
|
|
8
8
|
import JSONWebToken from "../Utils/JsonWebToken";
|
|
9
9
|
import logger, { LogAttributes } from "../Utils/Logger";
|
|
10
|
+
import ProductAnalytics from "../Utils/ProductAnalytics";
|
|
10
11
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
11
12
|
import DatabaseService from "./DatabaseService";
|
|
12
13
|
import MonitorStatusService from "./MonitorStatusService";
|
|
@@ -314,6 +315,15 @@ export class Service extends DatabaseService<StatusPage> {
|
|
|
314
315
|
onCreate: OnCreate<StatusPage>,
|
|
315
316
|
createdItem: StatusPage,
|
|
316
317
|
): Promise<StatusPage> {
|
|
318
|
+
// Activation event for marketing funnels.
|
|
319
|
+
ProductAnalytics.captureForUser({
|
|
320
|
+
userId: onCreate.createBy.props.userId || createdItem.createdByUserId,
|
|
321
|
+
event: "server/status_page_created",
|
|
322
|
+
properties: {
|
|
323
|
+
project_id: createdItem.projectId?.toString() || "",
|
|
324
|
+
},
|
|
325
|
+
});
|
|
326
|
+
|
|
317
327
|
// Execute owner assignment asynchronously
|
|
318
328
|
if (
|
|
319
329
|
createdItem.projectId &&
|
|
@@ -9,6 +9,7 @@ import Select from "../Types/Database/Select";
|
|
|
9
9
|
import UpdateBy from "../Types/Database/UpdateBy";
|
|
10
10
|
import Errors from "../Utils/Errors";
|
|
11
11
|
import logger, { LogAttributes } from "../Utils/Logger";
|
|
12
|
+
import ProductAnalytics from "../Utils/ProductAnalytics";
|
|
12
13
|
import AccessTokenService from "./AccessTokenService";
|
|
13
14
|
import BillingService from "./BillingService";
|
|
14
15
|
import DatabaseService from "./DatabaseService";
|
|
@@ -296,6 +297,16 @@ export class TeamMemberService extends DatabaseService<TeamMember> {
|
|
|
296
297
|
onCreate.createBy.data.projectId!,
|
|
297
298
|
);
|
|
298
299
|
|
|
300
|
+
// Activation event for marketing funnels, attributed to the inviter.
|
|
301
|
+
ProductAnalytics.captureForUser({
|
|
302
|
+
userId: onCreate.createBy.props.userId,
|
|
303
|
+
event: "server/team_member_invited",
|
|
304
|
+
properties: {
|
|
305
|
+
project_id: onCreate.createBy.data.projectId?.toString() || "",
|
|
306
|
+
has_accepted_invitation: Boolean(createdItem.hasAcceptedInvitation),
|
|
307
|
+
},
|
|
308
|
+
});
|
|
309
|
+
|
|
299
310
|
return createdItem;
|
|
300
311
|
}
|
|
301
312
|
|
|
@@ -4,8 +4,10 @@ import {
|
|
|
4
4
|
NotificationSlackWebhookOnCreateUser,
|
|
5
5
|
} from "../EnvironmentConfig";
|
|
6
6
|
import { OnCreate, OnDelete, OnUpdate } from "../Types/Database/Hooks";
|
|
7
|
+
import CreateBy from "../Types/Database/CreateBy";
|
|
7
8
|
import UpdateBy from "../Types/Database/UpdateBy";
|
|
8
9
|
import DeleteBy from "../Types/Database/DeleteBy";
|
|
10
|
+
import Attribution from "../Utils/Attribution";
|
|
9
11
|
import logger, { LogAttributes } from "../Utils/Logger";
|
|
10
12
|
import DatabaseService from "./DatabaseService";
|
|
11
13
|
import EmailVerificationTokenService from "./EmailVerificationTokenService";
|
|
@@ -25,12 +27,14 @@ import OneUptimeDate from "../../Types/Date";
|
|
|
25
27
|
import Email from "../../Types/Email";
|
|
26
28
|
import EmailTemplateType from "../../Types/Email/EmailTemplateType";
|
|
27
29
|
import HashedString from "../../Types/HashedString";
|
|
30
|
+
import { JSONObject, JSONValue } from "../../Types/JSON";
|
|
28
31
|
import ObjectID from "../../Types/ObjectID";
|
|
29
32
|
import Text from "../../Types/Text";
|
|
30
33
|
import EmailVerificationToken from "../../Models/DatabaseModels/EmailVerificationToken";
|
|
31
34
|
import TeamMember from "../../Models/DatabaseModels/TeamMember";
|
|
32
35
|
import Model from "../../Models/DatabaseModels/User";
|
|
33
36
|
import SlackUtil from "../Utils/Workspace/Slack/Slack";
|
|
37
|
+
import ProductAnalytics from "../Utils/ProductAnalytics";
|
|
34
38
|
import UserTotpAuth from "../../Models/DatabaseModels/UserTotpAuth";
|
|
35
39
|
import UserTotpAuthService from "./UserTotpAuthService";
|
|
36
40
|
import UserWebAuthn from "../../Models/DatabaseModels/UserWebAuthn";
|
|
@@ -120,6 +124,38 @@ export class Service extends DatabaseService<Model> {
|
|
|
120
124
|
);
|
|
121
125
|
}
|
|
122
126
|
|
|
127
|
+
@CaptureSpan()
|
|
128
|
+
protected override async onBeforeCreate(
|
|
129
|
+
createBy: CreateBy<Model>,
|
|
130
|
+
): Promise<OnCreate<Model>> {
|
|
131
|
+
/*
|
|
132
|
+
* clickIds / firstTouchAttribution are publicly creatable jsonb columns
|
|
133
|
+
* (set during signup). Unlike the varchar(500) utm columns they have no
|
|
134
|
+
* DB-level size bound, so whitelist keys and cap value lengths here.
|
|
135
|
+
*/
|
|
136
|
+
const sanitizedClickIds: JSONObject | undefined =
|
|
137
|
+
Attribution.sanitizeClickIds(createBy.data.clickIds as JSONValue);
|
|
138
|
+
|
|
139
|
+
if (sanitizedClickIds) {
|
|
140
|
+
createBy.data.clickIds = sanitizedClickIds;
|
|
141
|
+
} else {
|
|
142
|
+
delete createBy.data.clickIds;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const sanitizedFirstTouchAttribution: JSONObject | undefined =
|
|
146
|
+
Attribution.sanitizeFirstTouchAttribution(
|
|
147
|
+
createBy.data.firstTouchAttribution as JSONValue,
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
if (sanitizedFirstTouchAttribution) {
|
|
151
|
+
createBy.data.firstTouchAttribution = sanitizedFirstTouchAttribution;
|
|
152
|
+
} else {
|
|
153
|
+
delete createBy.data.firstTouchAttribution;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return { createBy, carryForward: null };
|
|
157
|
+
}
|
|
158
|
+
|
|
123
159
|
@CaptureSpan()
|
|
124
160
|
protected override async onCreateSuccess(
|
|
125
161
|
_onCreate: OnCreate<Model>,
|
|
@@ -141,6 +177,29 @@ export class Service extends DatabaseService<Model> {
|
|
|
141
177
|
});
|
|
142
178
|
}
|
|
143
179
|
|
|
180
|
+
/*
|
|
181
|
+
* Server-side signup event (ad blockers eat the client-side one). Also
|
|
182
|
+
* fires for users created via team invites — has_password separates
|
|
183
|
+
* direct signups (true) from invited users (false).
|
|
184
|
+
*/
|
|
185
|
+
if (createdItem.email) {
|
|
186
|
+
ProductAnalytics.capture({
|
|
187
|
+
event: "server/user_created",
|
|
188
|
+
distinctId: createdItem.email.toString(),
|
|
189
|
+
properties: {
|
|
190
|
+
has_password: Boolean(createdItem.password),
|
|
191
|
+
utm_source: createdItem.utmSource || "",
|
|
192
|
+
utm_medium: createdItem.utmMedium || "",
|
|
193
|
+
utm_campaign: createdItem.utmCampaign || "",
|
|
194
|
+
utm_term: createdItem.utmTerm || "",
|
|
195
|
+
utm_content: createdItem.utmContent || "",
|
|
196
|
+
utm_url: createdItem.utmUrl || "",
|
|
197
|
+
click_ids: createdItem.clickIds || {},
|
|
198
|
+
first_touch: createdItem.firstTouchAttribution || {},
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
|
|
144
203
|
// A place holder method used for overriding.
|
|
145
204
|
return Promise.resolve(createdItem);
|
|
146
205
|
}
|
|
@@ -38,19 +38,50 @@ export class AggregateUtil {
|
|
|
38
38
|
return interval === AggregationInterval.Total;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* The single source of truth for "which ClickHouse expression buckets
|
|
43
|
+
* a timestamp at this interval". Every aggregate SQL builder (raw
|
|
44
|
+
* table, minute MV, per-host MV, span projections) must go through
|
|
45
|
+
* this instead of lowercasing the enum value into the statement:
|
|
46
|
+
* the calendar units happen to double as SQL unit names
|
|
47
|
+
* (`date_trunc('hour', ...)`), but the sub-hour tiers
|
|
48
|
+
* (FiveMinutes/...) are not valid units and compile to
|
|
49
|
+
* `toStartOfInterval(col, INTERVAL 5 MINUTE)` instead — which
|
|
50
|
+
* ClickHouse counts in whole intervals since the epoch, so the
|
|
51
|
+
* 5/15/30-minute grids are exact on the client's epoch-ms grid too.
|
|
52
|
+
*
|
|
53
|
+
* `timestampExpression` is a model-validated identifier or a builder-
|
|
54
|
+
* owned expression, so raw interpolation here is consistent with the
|
|
55
|
+
* surrounding builders. `Total` has no bucket expression (the window
|
|
56
|
+
* collapses into `min(col)` — see buildBucketTimestampSelect).
|
|
57
|
+
*/
|
|
58
|
+
public static buildBucketTimestampExpression(
|
|
59
|
+
resolvedInterval: AggregationInterval,
|
|
60
|
+
timestampExpression: string,
|
|
61
|
+
): string {
|
|
62
|
+
switch (resolvedInterval) {
|
|
63
|
+
case AggregationInterval.FiveMinutes:
|
|
64
|
+
return `toStartOfInterval(${timestampExpression}, INTERVAL 5 MINUTE)`;
|
|
65
|
+
case AggregationInterval.FifteenMinutes:
|
|
66
|
+
return `toStartOfInterval(${timestampExpression}, INTERVAL 15 MINUTE)`;
|
|
67
|
+
case AggregationInterval.ThirtyMinutes:
|
|
68
|
+
return `toStartOfInterval(${timestampExpression}, INTERVAL 30 MINUTE)`;
|
|
69
|
+
default: {
|
|
70
|
+
const interval: string = resolvedInterval.toLowerCase();
|
|
71
|
+
return `date_trunc('${interval}', toStartOfInterval(${timestampExpression}, INTERVAL 1 ${interval}))`;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
41
76
|
/**
|
|
42
77
|
* The SELECT fragment that produces the bucket timestamp column,
|
|
43
78
|
* already aliased to `timestampColumn`. Shared by every aggregate SQL
|
|
44
79
|
* builder so the `Total` (whole-window) shape stays identical across
|
|
45
80
|
* paths:
|
|
46
81
|
*
|
|
47
|
-
* - normal interval →
|
|
82
|
+
* - normal interval → buildBucketTimestampExpression(...) `as col`
|
|
48
83
|
* - Total → `min(col) as col` (one row per group; the
|
|
49
84
|
* earliest sample timestamp in the window is the bucket label)
|
|
50
|
-
*
|
|
51
|
-
* `timestampColumn` is a model-validated identifier (see
|
|
52
|
-
* AnalyticsDatabaseService._aggregateBy), so raw interpolation here is
|
|
53
|
-
* consistent with the surrounding builders.
|
|
54
85
|
*/
|
|
55
86
|
public static buildBucketTimestampSelect(
|
|
56
87
|
resolvedInterval: AggregationInterval,
|
|
@@ -60,7 +91,6 @@ export class AggregateUtil {
|
|
|
60
91
|
return `min(${timestampColumn}) as ${timestampColumn}`;
|
|
61
92
|
}
|
|
62
93
|
|
|
63
|
-
|
|
64
|
-
return `date_trunc('${interval}', toStartOfInterval(${timestampColumn}, INTERVAL 1 ${interval})) as ${timestampColumn}`;
|
|
94
|
+
return `${AggregateUtil.buildBucketTimestampExpression(resolvedInterval, timestampColumn)} as ${timestampColumn}`;
|
|
65
95
|
}
|
|
66
96
|
}
|