@oneuptime/common 10.0.39 → 10.0.41
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 +4 -0
- package/Models/AnalyticsModels/Profile.ts +687 -0
- package/Models/AnalyticsModels/ProfileSample.ts +547 -0
- package/Models/DatabaseModels/Dashboard.ts +357 -0
- package/Models/DatabaseModels/DashboardDomain.ts +658 -0
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/StatusPage.ts +41 -0
- package/Server/API/DashboardAPI.ts +408 -0
- package/Server/API/DashboardDomainAPI.ts +235 -0
- package/Server/API/StatusPageAPI.ts +36 -2
- package/Server/API/TelemetryAPI.ts +393 -0
- package/Server/EnvironmentConfig.ts +12 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1774524742177-MigrationName.ts +97 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1774524742178-MigrationName.ts +17 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1774524742179-MigrationName.ts +50 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1774559064919-MigrationName.ts +59 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
- package/Server/Middleware/UserAuthorization.ts +96 -1
- package/Server/Services/DashboardDomainService.ts +647 -0
- package/Server/Services/DashboardService.ts +174 -3
- package/Server/Services/IncidentService.ts +295 -50
- package/Server/Services/IncidentStateTimelineService.ts +1 -0
- package/Server/Services/Index.ts +6 -0
- package/Server/Services/MonitorService.ts +5 -0
- package/Server/Services/ProfileAggregationService.ts +559 -0
- package/Server/Services/ProfileSampleService.ts +11 -0
- package/Server/Services/ProfileService.ts +11 -0
- package/Server/Services/TelemetryUsageBillingService.ts +77 -3
- package/Server/Services/WorkspaceNotificationSummaryService.ts +15 -1
- package/Server/Types/Billing/MeteredPlan/AllMeteredPlans.ts +9 -0
- package/Server/Utils/Cookie.ts +48 -0
- package/Server/Utils/Monitor/Criteria/ProfileMonitorCriteria.ts +34 -0
- package/Server/Utils/Monitor/DataToProcess.ts +3 -1
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +299 -0
- package/Server/Utils/Profile/PprofEncoder.ts +225 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +53 -16
- package/Server/Utils/Workspace/Slack/Slack.ts +26 -6
- package/ServiceRoute.ts +2 -0
- package/Tests/UI/Components/ComponentsModal.test.tsx +19 -15
- package/Types/AnalyticsDatabase/AnalyticsTableName.ts +2 -0
- package/Types/CookieName.ts +1 -0
- package/Types/Dashboard/Chart/ChartType.ts +5 -0
- package/Types/Dashboard/DashboardComponentType.ts +4 -0
- package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +10 -0
- package/Types/Dashboard/DashboardComponents/DashboardChartComponent.ts +1 -2
- package/Types/Dashboard/DashboardComponents/DashboardGaugeComponent.ts +17 -0
- package/Types/Dashboard/DashboardComponents/DashboardLogStreamComponent.ts +15 -0
- package/Types/Dashboard/DashboardComponents/DashboardTableComponent.ts +14 -0
- package/Types/Dashboard/DashboardComponents/DashboardTextComponent.ts +1 -0
- package/Types/Dashboard/DashboardComponents/DashboardTraceListComponent.ts +13 -0
- package/Types/Dashboard/DashboardComponents/DashboardValueComponent.ts +2 -0
- package/Types/Dashboard/DashboardTemplates.ts +964 -0
- package/Types/Dashboard/DashboardVariable.ts +23 -0
- package/Types/Dashboard/DashboardViewConfig.ts +59 -0
- package/Types/Dashboard/MasterPassword.ts +10 -0
- package/Types/Icon/IconProp.ts +1 -0
- package/Types/Incident/IncidentMetricType.ts +3 -0
- package/Types/MeteredPlan/ProductType.ts +1 -0
- package/Types/Metrics/MetricQueryConfigData.ts +3 -0
- package/Types/Monitor/CriteriaFilter.ts +3 -0
- package/Types/Monitor/KubernetesAlertTemplates.ts +78 -7
- package/Types/Monitor/MetricMonitor/MetricMonitorResponse.ts +20 -0
- package/Types/Monitor/MonitorStep.ts +25 -0
- package/Types/Monitor/MonitorStepProfileMonitor.ts +96 -0
- package/Types/Monitor/MonitorType.ts +11 -0
- package/Types/Monitor/ProfileMonitor/ProfileMonitorResponse.ts +12 -0
- package/Types/Permission.ts +87 -0
- package/Types/Telemetry/TelemetryType.ts +1 -0
- package/Types/Workspace/NotificationSummary/WorkspaceNotificationSummaryItem.ts +1 -0
- package/UI/Components/Button/Button.tsx +1 -1
- package/UI/Components/Card/Card.tsx +8 -4
- package/UI/Components/Charts/Area/AreaChart.tsx +4 -0
- package/UI/Components/Charts/Bar/BarChart.tsx +4 -0
- package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +26 -0
- package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +26 -0
- package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +26 -0
- package/UI/Components/Charts/Line/LineChart.tsx +4 -0
- package/UI/Components/Charts/Types/ReferenceLineProps.ts +6 -0
- package/UI/Components/Icon/Icon.tsx +33 -0
- package/UI/Components/ModelTable/BaseModelTable.tsx +13 -10
- package/UI/Components/MoreMenu/MoreMenu.tsx +15 -2
- package/UI/Components/MoreMenu/MoreMenuItem.tsx +4 -4
- package/UI/Components/Workflow/Component.tsx +450 -209
- package/UI/Components/Workflow/ComponentPortViewer.tsx +57 -20
- package/UI/Components/Workflow/ComponentReturnValueViewer.tsx +65 -25
- package/UI/Components/Workflow/ComponentSettingsModal.tsx +202 -37
- package/UI/Components/Workflow/ComponentsModal.tsx +180 -93
- package/UI/Components/Workflow/Workflow.tsx +105 -9
- package/UI/Config.ts +9 -0
- package/Utils/Dashboard/Components/DashboardChartComponent.ts +53 -22
- package/Utils/Dashboard/Components/DashboardGaugeComponent.ts +124 -0
- package/Utils/Dashboard/Components/DashboardLogStreamComponent.ts +110 -0
- package/Utils/Dashboard/Components/DashboardTableComponent.ts +86 -0
- package/Utils/Dashboard/Components/DashboardTextComponent.ts +32 -7
- package/Utils/Dashboard/Components/DashboardTraceListComponent.ts +86 -0
- package/Utils/Dashboard/Components/DashboardValueComponent.ts +39 -3
- package/Utils/Dashboard/Components/Index.ts +28 -0
- package/Utils/ValueFormatter.ts +170 -0
- package/build/dist/Models/AnalyticsModels/Index.js +4 -0
- package/build/dist/Models/AnalyticsModels/Index.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/Profile.js +621 -0
- package/build/dist/Models/AnalyticsModels/Profile.js.map +1 -0
- package/build/dist/Models/AnalyticsModels/ProfileSample.js +497 -0
- package/build/dist/Models/AnalyticsModels/ProfileSample.js.map +1 -0
- package/build/dist/Models/DatabaseModels/Dashboard.js +365 -0
- package/build/dist/Models/DatabaseModels/Dashboard.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DashboardDomain.js +691 -0
- package/build/dist/Models/DatabaseModels/DashboardDomain.js.map +1 -0
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +42 -0
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Server/API/DashboardAPI.js +293 -0
- package/build/dist/Server/API/DashboardAPI.js.map +1 -0
- package/build/dist/Server/API/DashboardDomainAPI.js +124 -0
- package/build/dist/Server/API/DashboardDomainAPI.js.map +1 -0
- package/build/dist/Server/API/StatusPageAPI.js +26 -2
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +222 -0
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +4 -0
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1774524742177-MigrationName.js +40 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1774524742177-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1774524742178-MigrationName.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1774524742178-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1774524742179-MigrationName.js +23 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1774524742179-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1774559064919-MigrationName.js +26 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1774559064919-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +41 -0
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Services/DashboardDomainService.js +595 -0
- package/build/dist/Server/Services/DashboardDomainService.js.map +1 -0
- package/build/dist/Server/Services/DashboardService.js +117 -3
- package/build/dist/Server/Services/DashboardService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +231 -55
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentStateTimelineService.js +1 -1
- package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +6 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +5 -2
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/ProfileAggregationService.js +356 -0
- package/build/dist/Server/Services/ProfileAggregationService.js.map +1 -0
- package/build/dist/Server/Services/ProfileSampleService.js +9 -0
- package/build/dist/Server/Services/ProfileSampleService.js.map +1 -0
- package/build/dist/Server/Services/ProfileService.js +9 -0
- package/build/dist/Server/Services/ProfileService.js.map +1 -0
- package/build/dist/Server/Services/TelemetryUsageBillingService.js +61 -4
- package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js +13 -1
- package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js.map +1 -1
- package/build/dist/Server/Types/Billing/MeteredPlan/AllMeteredPlans.js +8 -0
- package/build/dist/Server/Types/Billing/MeteredPlan/AllMeteredPlans.js.map +1 -1
- package/build/dist/Server/Utils/Cookie.js +36 -0
- package/build/dist/Server/Utils/Cookie.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/ProfileMonitorCriteria.js +34 -0
- package/build/dist/Server/Utils/Monitor/Criteria/ProfileMonitorCriteria.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +173 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Profile/PprofEncoder.js +129 -0
- package/build/dist/Server/Utils/Profile/PprofEncoder.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +36 -14
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js +23 -6
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
- package/build/dist/ServiceRoute.js +1 -0
- package/build/dist/ServiceRoute.js.map +1 -1
- package/build/dist/Tests/UI/Components/ComponentsModal.test.js +15 -15
- package/build/dist/Tests/UI/Components/ComponentsModal.test.js.map +1 -1
- package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +2 -0
- package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -1
- package/build/dist/Types/CookieName.js +1 -0
- package/build/dist/Types/CookieName.js.map +1 -1
- package/build/dist/Types/Dashboard/Chart/ChartType.js +5 -0
- package/build/dist/Types/Dashboard/Chart/ChartType.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponentType.js +4 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardGaugeComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardGaugeComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardLogStreamComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardLogStreamComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardTableComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardTableComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardTraceListComponent.js +2 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardTraceListComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.js +853 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardVariable.js +7 -0
- package/build/dist/Types/Dashboard/DashboardVariable.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardViewConfig.js +50 -1
- package/build/dist/Types/Dashboard/DashboardViewConfig.js.map +1 -1
- package/build/dist/Types/Dashboard/MasterPassword.js +5 -0
- package/build/dist/Types/Dashboard/MasterPassword.js.map +1 -0
- package/build/dist/Types/Icon/IconProp.js +1 -0
- package/build/dist/Types/Icon/IconProp.js.map +1 -1
- package/build/dist/Types/Incident/IncidentMetricType.js +3 -0
- package/build/dist/Types/Incident/IncidentMetricType.js.map +1 -1
- package/build/dist/Types/MeteredPlan/ProductType.js +1 -0
- package/build/dist/Types/MeteredPlan/ProductType.js.map +1 -1
- package/build/dist/Types/Metrics/MetricQueryConfigData.js +1 -0
- package/build/dist/Types/Metrics/MetricQueryConfigData.js.map +1 -1
- package/build/dist/Types/Monitor/CriteriaFilter.js +2 -0
- package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +58 -7
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +15 -0
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepProfileMonitor.js +59 -0
- package/build/dist/Types/Monitor/MonitorStepProfileMonitor.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorType.js +10 -0
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/Monitor/ProfileMonitor/ProfileMonitorResponse.js +2 -0
- package/build/dist/Types/Monitor/ProfileMonitor/ProfileMonitorResponse.js.map +1 -0
- package/build/dist/Types/Permission.js +75 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Telemetry/TelemetryType.js +1 -0
- package/build/dist/Types/Telemetry/TelemetryType.js.map +1 -1
- package/build/dist/Types/Workspace/NotificationSummary/WorkspaceNotificationSummaryItem.js +1 -0
- package/build/dist/Types/Workspace/NotificationSummary/WorkspaceNotificationSummaryItem.js.map +1 -1
- package/build/dist/UI/Components/Button/Button.js +1 -1
- package/build/dist/UI/Components/Button/Button.js.map +1 -1
- package/build/dist/UI/Components/Card/Card.js +4 -4
- package/build/dist/UI/Components/Card/Card.js.map +1 -1
- package/build/dist/UI/Components/Charts/Area/AreaChart.js +1 -1
- package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js +1 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +5 -2
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +5 -2
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +6 -3
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Line/LineChart.js +1 -1
- package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Types/ReferenceLineProps.js +2 -0
- package/build/dist/UI/Components/Charts/Types/ReferenceLineProps.js.map +1 -0
- package/build/dist/UI/Components/Icon/Icon.js +11 -0
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +12 -9
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js +8 -2
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +4 -4
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
- package/build/dist/UI/Components/Workflow/Component.js +311 -143
- package/build/dist/UI/Components/Workflow/Component.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentPortViewer.js +44 -18
- package/build/dist/UI/Components/Workflow/ComponentPortViewer.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js +48 -22
- package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js +127 -21
- package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentsModal.js +107 -52
- package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/Workflow.js +87 -12
- package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
- package/build/dist/UI/Config.js +3 -1
- package/build/dist/UI/Config.js.map +1 -1
- package/build/dist/Utils/Dashboard/Components/DashboardChartComponent.js +50 -21
- package/build/dist/Utils/Dashboard/Components/DashboardChartComponent.js.map +1 -1
- package/build/dist/Utils/Dashboard/Components/DashboardGaugeComponent.js +104 -0
- package/build/dist/Utils/Dashboard/Components/DashboardGaugeComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardLogStreamComponent.js +91 -0
- package/build/dist/Utils/Dashboard/Components/DashboardLogStreamComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardTableComponent.js +70 -0
- package/build/dist/Utils/Dashboard/Components/DashboardTableComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardTextComponent.js +28 -7
- package/build/dist/Utils/Dashboard/Components/DashboardTextComponent.js.map +1 -1
- package/build/dist/Utils/Dashboard/Components/DashboardTraceListComponent.js +70 -0
- package/build/dist/Utils/Dashboard/Components/DashboardTraceListComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardValueComponent.js +34 -3
- package/build/dist/Utils/Dashboard/Components/DashboardValueComponent.js.map +1 -1
- package/build/dist/Utils/Dashboard/Components/Index.js +16 -0
- package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
- package/build/dist/Utils/ValueFormatter.js +132 -0
- package/build/dist/Utils/ValueFormatter.js.map +1 -0
- package/package.json +1 -1
|
@@ -16,6 +16,8 @@ import SpanService from "./SpanService";
|
|
|
16
16
|
import LogService from "./LogService";
|
|
17
17
|
import MetricService from "./MetricService";
|
|
18
18
|
import ExceptionInstanceService from "./ExceptionInstanceService";
|
|
19
|
+
import ProfileService from "./ProfileService";
|
|
20
|
+
import ProfileSampleService from "./ProfileSampleService";
|
|
19
21
|
import AnalyticsQueryHelper from "../Types/AnalyticsDatabase/QueryHelper";
|
|
20
22
|
import DiskSize from "../../Types/DiskSize";
|
|
21
23
|
import logger from "../Utils/Logger";
|
|
@@ -26,6 +28,8 @@ import {
|
|
|
26
28
|
AverageLogRowSizeInBytes,
|
|
27
29
|
AverageMetricRowSizeInBytes,
|
|
28
30
|
AverageExceptionRowSizeInBytes,
|
|
31
|
+
AverageProfileRowSizeInBytes,
|
|
32
|
+
AverageProfileSampleRowSizeInBytes,
|
|
29
33
|
IsBillingEnabled,
|
|
30
34
|
} from "../EnvironmentConfig";
|
|
31
35
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
@@ -81,7 +85,14 @@ export class Service extends DatabaseService<Model> {
|
|
|
81
85
|
const averageExceptionRowSizeInBytes: number =
|
|
82
86
|
this.getAverageExceptionRowSize();
|
|
83
87
|
|
|
84
|
-
|
|
88
|
+
const averageProfileSampleRowSizeInBytes: number =
|
|
89
|
+
this.getAverageProfileSampleRowSize();
|
|
90
|
+
|
|
91
|
+
if (
|
|
92
|
+
data.productType !== ProductType.Traces &&
|
|
93
|
+
data.productType !== ProductType.Profiles &&
|
|
94
|
+
averageRowSizeInBytes <= 0
|
|
95
|
+
) {
|
|
85
96
|
return;
|
|
86
97
|
}
|
|
87
98
|
|
|
@@ -93,6 +104,14 @@ export class Service extends DatabaseService<Model> {
|
|
|
93
104
|
return;
|
|
94
105
|
}
|
|
95
106
|
|
|
107
|
+
if (
|
|
108
|
+
data.productType === ProductType.Profiles &&
|
|
109
|
+
averageRowSizeInBytes <= 0 &&
|
|
110
|
+
averageProfileSampleRowSizeInBytes <= 0
|
|
111
|
+
) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
96
115
|
const usageDayString: string = OneUptimeDate.getDateString(usageDate);
|
|
97
116
|
const startOfDay: Date = OneUptimeDate.getStartOfDay(usageDate);
|
|
98
117
|
const endOfDay: Date = OneUptimeDate.getEndOfDay(usageDate);
|
|
@@ -223,6 +242,44 @@ export class Service extends DatabaseService<Model> {
|
|
|
223
242
|
}
|
|
224
243
|
|
|
225
244
|
estimatedBytes = totalRowCount * averageRowSizeInBytes;
|
|
245
|
+
} else if (data.productType === ProductType.Profiles) {
|
|
246
|
+
const profileCount: PositiveNumber = await ProfileService.countBy({
|
|
247
|
+
query: {
|
|
248
|
+
projectId: data.projectId,
|
|
249
|
+
serviceId: service.id,
|
|
250
|
+
startTime: AnalyticsQueryHelper.inBetween(startOfDay, endOfDay),
|
|
251
|
+
},
|
|
252
|
+
skip: 0,
|
|
253
|
+
limit: LIMIT_INFINITY,
|
|
254
|
+
props: {
|
|
255
|
+
isRoot: true,
|
|
256
|
+
},
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
const profileSampleCount: PositiveNumber =
|
|
260
|
+
await ProfileSampleService.countBy({
|
|
261
|
+
query: {
|
|
262
|
+
projectId: data.projectId,
|
|
263
|
+
serviceId: service.id,
|
|
264
|
+
time: AnalyticsQueryHelper.inBetween(startOfDay, endOfDay),
|
|
265
|
+
},
|
|
266
|
+
skip: 0,
|
|
267
|
+
limit: LIMIT_INFINITY,
|
|
268
|
+
props: {
|
|
269
|
+
isRoot: true,
|
|
270
|
+
},
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
const totalProfileCount: number = profileCount.toNumber();
|
|
274
|
+
const totalProfileSampleCount: number = profileSampleCount.toNumber();
|
|
275
|
+
|
|
276
|
+
if (totalProfileCount <= 0 && totalProfileSampleCount <= 0) {
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
estimatedBytes =
|
|
281
|
+
totalProfileCount * averageRowSizeInBytes +
|
|
282
|
+
totalProfileSampleCount * averageProfileSampleRowSizeInBytes;
|
|
226
283
|
}
|
|
227
284
|
} catch (error) {
|
|
228
285
|
logger.error(
|
|
@@ -268,7 +325,8 @@ export class Service extends DatabaseService<Model> {
|
|
|
268
325
|
if (
|
|
269
326
|
data.productType !== ProductType.Traces &&
|
|
270
327
|
data.productType !== ProductType.Metrics &&
|
|
271
|
-
data.productType !== ProductType.Logs
|
|
328
|
+
data.productType !== ProductType.Logs &&
|
|
329
|
+
data.productType !== ProductType.Profiles
|
|
272
330
|
) {
|
|
273
331
|
throw new BadDataException(
|
|
274
332
|
"This product type is not a telemetry product type.",
|
|
@@ -370,7 +428,8 @@ export class Service extends DatabaseService<Model> {
|
|
|
370
428
|
if (
|
|
371
429
|
productType !== ProductType.Traces &&
|
|
372
430
|
productType !== ProductType.Logs &&
|
|
373
|
-
productType !== ProductType.Metrics
|
|
431
|
+
productType !== ProductType.Metrics &&
|
|
432
|
+
productType !== ProductType.Profiles
|
|
374
433
|
) {
|
|
375
434
|
return fallbackSize;
|
|
376
435
|
}
|
|
@@ -380,6 +439,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
380
439
|
[ProductType.Traces]: AverageSpanRowSizeInBytes,
|
|
381
440
|
[ProductType.Logs]: AverageLogRowSizeInBytes,
|
|
382
441
|
[ProductType.Metrics]: AverageMetricRowSizeInBytes,
|
|
442
|
+
[ProductType.Profiles]: AverageProfileRowSizeInBytes,
|
|
383
443
|
}[productType] ?? fallbackSize;
|
|
384
444
|
|
|
385
445
|
if (!Number.isFinite(value) || value <= 0) {
|
|
@@ -402,6 +462,20 @@ export class Service extends DatabaseService<Model> {
|
|
|
402
462
|
|
|
403
463
|
return AverageExceptionRowSizeInBytes;
|
|
404
464
|
}
|
|
465
|
+
|
|
466
|
+
private getAverageProfileSampleRowSize(): number {
|
|
467
|
+
const fallbackSize: number = 512;
|
|
468
|
+
|
|
469
|
+
if (!Number.isFinite(AverageProfileSampleRowSizeInBytes)) {
|
|
470
|
+
return fallbackSize;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
if (AverageProfileSampleRowSizeInBytes <= 0) {
|
|
474
|
+
return fallbackSize;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
return AverageProfileSampleRowSizeInBytes;
|
|
478
|
+
}
|
|
405
479
|
}
|
|
406
480
|
|
|
407
481
|
export default new Service();
|
|
@@ -241,6 +241,9 @@ export class Service extends DatabaseService<WorkspaceNotificationSummary> {
|
|
|
241
241
|
items: Array<WorkspaceNotificationSummaryItem>,
|
|
242
242
|
item: WorkspaceNotificationSummaryItem,
|
|
243
243
|
): boolean {
|
|
244
|
+
if (items.includes(WorkspaceNotificationSummaryItem.All)) {
|
|
245
|
+
return true;
|
|
246
|
+
}
|
|
244
247
|
return items.includes(item);
|
|
245
248
|
}
|
|
246
249
|
|
|
@@ -822,6 +825,11 @@ export class Service extends DatabaseService<WorkspaceNotificationSummary> {
|
|
|
822
825
|
ackResolve.push(
|
|
823
826
|
`Ack: ${Service.bold(td.ackBy)} in ${Service.formatDuration(OneUptimeDate.getMinutesBetweenTwoDates(td.declaredAt || inc.createdAt!, td.ackAt))}`,
|
|
824
827
|
);
|
|
828
|
+
} else if (td?.resolvedBy && td?.resolvedAt) {
|
|
829
|
+
// If not explicitly acknowledged but resolved, ack time = resolve time
|
|
830
|
+
ackResolve.push(
|
|
831
|
+
`Ack: ${Service.bold(td.resolvedBy)} in ${Service.formatDuration(OneUptimeDate.getMinutesBetweenTwoDates(td.declaredAt || inc.createdAt!, td.resolvedAt))}`,
|
|
832
|
+
);
|
|
825
833
|
} else {
|
|
826
834
|
ackResolve.push(`_Not yet acknowledged_`);
|
|
827
835
|
}
|
|
@@ -1251,6 +1259,11 @@ export class Service extends DatabaseService<WorkspaceNotificationSummary> {
|
|
|
1251
1259
|
ackResolve.push(
|
|
1252
1260
|
`Ack: ${Service.bold(td.ackBy)} in ${Service.formatDuration(OneUptimeDate.getMinutesBetweenTwoDates(td.declaredAt || a.createdAt!, td.ackAt))}`,
|
|
1253
1261
|
);
|
|
1262
|
+
} else if (td?.resolvedBy && td?.resolvedAt) {
|
|
1263
|
+
// If not explicitly acknowledged but resolved, ack time = resolve time
|
|
1264
|
+
ackResolve.push(
|
|
1265
|
+
`Ack: ${Service.bold(td.resolvedBy)} in ${Service.formatDuration(OneUptimeDate.getMinutesBetweenTwoDates(td.declaredAt || a.createdAt!, td.resolvedAt))}`,
|
|
1266
|
+
);
|
|
1254
1267
|
} else {
|
|
1255
1268
|
ackResolve.push(`_Not yet acknowledged_`);
|
|
1256
1269
|
}
|
|
@@ -1433,8 +1446,9 @@ export class Service extends DatabaseService<WorkspaceNotificationSummary> {
|
|
|
1433
1446
|
let total: number = 0;
|
|
1434
1447
|
let count: number = 0;
|
|
1435
1448
|
for (const [, td] of tlMap) {
|
|
1449
|
+
// For ack: if not explicitly acknowledged but resolved, use resolve time as ack time
|
|
1436
1450
|
const eventTime: Date | undefined =
|
|
1437
|
-
kind === "ack" ? td.ackAt : td.resolvedAt;
|
|
1451
|
+
kind === "ack" ? td.ackAt || td.resolvedAt : td.resolvedAt;
|
|
1438
1452
|
if (eventTime && td.declaredAt) {
|
|
1439
1453
|
total += OneUptimeDate.getMinutesBetweenTwoDates(
|
|
1440
1454
|
td.declaredAt,
|
|
@@ -26,11 +26,18 @@ export const TracesDataIngestMetredPlan: TelemetryMeteredPlanType =
|
|
|
26
26
|
unitCostInUSD: 0.1 / 15, // 0.10 per 15 days per GB
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
+
export const ProfilesDataIngestMeteredPlan: TelemetryMeteredPlanType =
|
|
30
|
+
new TelemetryMeteredPlanType({
|
|
31
|
+
productType: ProductType.Profiles,
|
|
32
|
+
unitCostInUSD: 0.1 / 15, // 0.10 per 15 days per GB
|
|
33
|
+
});
|
|
34
|
+
|
|
29
35
|
const AllMeteredPlans: Array<ServerMeteredPlan> = [
|
|
30
36
|
ActiveMonitoringMeteredPlan,
|
|
31
37
|
LogDataIngestMeteredPlan,
|
|
32
38
|
MetricsDataIngestMeteredPlan,
|
|
33
39
|
TracesDataIngestMetredPlan,
|
|
40
|
+
ProfilesDataIngestMeteredPlan,
|
|
34
41
|
];
|
|
35
42
|
|
|
36
43
|
export class MeteredPlanUtil {
|
|
@@ -44,6 +51,8 @@ export class MeteredPlanUtil {
|
|
|
44
51
|
return MetricsDataIngestMeteredPlan;
|
|
45
52
|
} else if (productType === ProductType.Traces) {
|
|
46
53
|
return TracesDataIngestMetredPlan;
|
|
54
|
+
} else if (productType === ProductType.Profiles) {
|
|
55
|
+
return ProfilesDataIngestMeteredPlan;
|
|
47
56
|
} else if (productType === ProductType.ActiveMonitoring) {
|
|
48
57
|
return ActiveMonitoringMeteredPlan;
|
|
49
58
|
}
|
package/Server/Utils/Cookie.ts
CHANGED
|
@@ -12,6 +12,10 @@ import {
|
|
|
12
12
|
MASTER_PASSWORD_COOKIE_IDENTIFIER,
|
|
13
13
|
MASTER_PASSWORD_COOKIE_MAX_AGE_IN_DAYS,
|
|
14
14
|
} from "../../Types/StatusPage/MasterPassword";
|
|
15
|
+
import {
|
|
16
|
+
DASHBOARD_MASTER_PASSWORD_COOKIE_IDENTIFIER,
|
|
17
|
+
DASHBOARD_MASTER_PASSWORD_COOKIE_MAX_AGE_IN_DAYS,
|
|
18
|
+
} from "../../Types/Dashboard/MasterPassword";
|
|
15
19
|
import CaptureSpan from "./Telemetry/CaptureSpan";
|
|
16
20
|
|
|
17
21
|
export default class CookieUtil {
|
|
@@ -323,6 +327,50 @@ export default class CookieUtil {
|
|
|
323
327
|
);
|
|
324
328
|
}
|
|
325
329
|
|
|
330
|
+
@CaptureSpan()
|
|
331
|
+
public static setDashboardMasterPasswordCookie(data: {
|
|
332
|
+
expressResponse: ExpressResponse;
|
|
333
|
+
dashboardId: ObjectID;
|
|
334
|
+
}): void {
|
|
335
|
+
const expiresInDays: PositiveNumber = new PositiveNumber(
|
|
336
|
+
DASHBOARD_MASTER_PASSWORD_COOKIE_MAX_AGE_IN_DAYS,
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
const token: string = JSONWebToken.signJsonPayload(
|
|
340
|
+
{
|
|
341
|
+
dashboardId: data.dashboardId.toString(),
|
|
342
|
+
type: DASHBOARD_MASTER_PASSWORD_COOKIE_IDENTIFIER,
|
|
343
|
+
},
|
|
344
|
+
OneUptimeDate.getSecondsInDays(expiresInDays),
|
|
345
|
+
);
|
|
346
|
+
|
|
347
|
+
CookieUtil.setCookie(
|
|
348
|
+
data.expressResponse,
|
|
349
|
+
CookieUtil.getDashboardMasterPasswordKey(data.dashboardId),
|
|
350
|
+
token,
|
|
351
|
+
{
|
|
352
|
+
maxAge: OneUptimeDate.getMillisecondsInDays(expiresInDays),
|
|
353
|
+
httpOnly: true,
|
|
354
|
+
},
|
|
355
|
+
);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
@CaptureSpan()
|
|
359
|
+
public static removeDashboardMasterPasswordCookie(
|
|
360
|
+
res: ExpressResponse,
|
|
361
|
+
dashboardId: ObjectID,
|
|
362
|
+
): void {
|
|
363
|
+
CookieUtil.removeCookie(
|
|
364
|
+
res,
|
|
365
|
+
CookieUtil.getDashboardMasterPasswordKey(dashboardId),
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
@CaptureSpan()
|
|
370
|
+
public static getDashboardMasterPasswordKey(id: ObjectID): string {
|
|
371
|
+
return `${CookieName.DashboardMasterPassword}-${id.toString()}`;
|
|
372
|
+
}
|
|
373
|
+
|
|
326
374
|
// get all cookies with express request
|
|
327
375
|
@CaptureSpan()
|
|
328
376
|
public static getAllCookies(req: ExpressRequest): Dictionary<string> {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import ProfileMonitorResponse from "../../../../Types/Monitor/ProfileMonitor/ProfileMonitorResponse";
|
|
2
|
+
import CaptureSpan from "../../Telemetry/CaptureSpan";
|
|
3
|
+
import DataToProcess from "../DataToProcess";
|
|
4
|
+
import CompareCriteria from "./CompareCriteria";
|
|
5
|
+
import {
|
|
6
|
+
CheckOn,
|
|
7
|
+
CriteriaFilter,
|
|
8
|
+
} from "../../../../Types/Monitor/CriteriaFilter";
|
|
9
|
+
|
|
10
|
+
export default class ProfileMonitorCriteria {
|
|
11
|
+
@CaptureSpan()
|
|
12
|
+
public static async isMonitorInstanceCriteriaFilterMet(input: {
|
|
13
|
+
dataToProcess: DataToProcess;
|
|
14
|
+
criteriaFilter: CriteriaFilter;
|
|
15
|
+
}): Promise<string | null> {
|
|
16
|
+
let threshold: number | string | undefined | null =
|
|
17
|
+
input.criteriaFilter.value;
|
|
18
|
+
|
|
19
|
+
if (input.criteriaFilter.checkOn === CheckOn.ProfileCount) {
|
|
20
|
+
threshold = CompareCriteria.convertToNumber(threshold);
|
|
21
|
+
|
|
22
|
+
const currentProfileCount: number =
|
|
23
|
+
(input.dataToProcess as ProfileMonitorResponse).profileCount || 0;
|
|
24
|
+
|
|
25
|
+
return CompareCriteria.compareCriteriaNumbers({
|
|
26
|
+
value: currentProfileCount,
|
|
27
|
+
threshold: threshold as number,
|
|
28
|
+
criteriaFilter: input.criteriaFilter,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -6,6 +6,7 @@ import LogMonitorResponse from "../../../Types/Monitor/LogMonitor/LogMonitorResp
|
|
|
6
6
|
import TraceMonitorResponse from "../../../Types/Monitor/TraceMonitor/TraceMonitorResponse";
|
|
7
7
|
import MetricMonitorResponse from "../../../Types/Monitor/MetricMonitor/MetricMonitorResponse";
|
|
8
8
|
import ExceptionMonitorResponse from "../../../Types/Monitor/ExceptionMonitor/ExceptionMonitorResponse";
|
|
9
|
+
import ProfileMonitorResponse from "../../../Types/Monitor/ProfileMonitor/ProfileMonitorResponse";
|
|
9
10
|
|
|
10
11
|
type DataToProcess =
|
|
11
12
|
| ProbeMonitorResponse
|
|
@@ -15,6 +16,7 @@ type DataToProcess =
|
|
|
15
16
|
| LogMonitorResponse
|
|
16
17
|
| TraceMonitorResponse
|
|
17
18
|
| MetricMonitorResponse
|
|
18
|
-
| ExceptionMonitorResponse
|
|
19
|
+
| ExceptionMonitorResponse
|
|
20
|
+
| ProfileMonitorResponse;
|
|
19
21
|
|
|
20
22
|
export default DataToProcess;
|
|
@@ -11,6 +11,7 @@ import LogMonitorCriteria from "./Criteria/LogMonitorCriteria";
|
|
|
11
11
|
import MetricMonitorCriteria from "./Criteria/MetricMonitorCriteria";
|
|
12
12
|
import TraceMonitorCriteria from "./Criteria/TraceMonitorCriteria";
|
|
13
13
|
import ExceptionMonitorCriteria from "./Criteria/ExceptionMonitorCriteria";
|
|
14
|
+
import ProfileMonitorCriteria from "./Criteria/ProfileMonitorCriteria";
|
|
14
15
|
import SnmpMonitorCriteria from "./Criteria/SnmpMonitorCriteria";
|
|
15
16
|
import DnsMonitorCriteria from "./Criteria/DnsMonitorCriteria";
|
|
16
17
|
import DomainMonitorCriteria from "./Criteria/DomainMonitorCriteria";
|
|
@@ -43,6 +44,10 @@ import URL from "../../../Types/API/URL";
|
|
|
43
44
|
import IP from "../../../Types/IP/IP";
|
|
44
45
|
import Hostname from "../../../Types/API/Hostname";
|
|
45
46
|
import Port from "../../../Types/Port";
|
|
47
|
+
import MetricMonitorResponse, {
|
|
48
|
+
KubernetesAffectedResource,
|
|
49
|
+
KubernetesResourceBreakdown,
|
|
50
|
+
} from "../../../Types/Monitor/MetricMonitor/MetricMonitorResponse";
|
|
46
51
|
|
|
47
52
|
export default class MonitorCriteriaEvaluator {
|
|
48
53
|
public static async processMonitorStep(input: {
|
|
@@ -487,6 +492,18 @@ ${contextBlock}
|
|
|
487
492
|
}
|
|
488
493
|
}
|
|
489
494
|
|
|
495
|
+
if (input.monitor.monitorType === MonitorType.Profiles) {
|
|
496
|
+
const profileMonitorResult: string | null =
|
|
497
|
+
await ProfileMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
|
|
498
|
+
dataToProcess: input.dataToProcess,
|
|
499
|
+
criteriaFilter: input.criteriaFilter,
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
if (profileMonitorResult) {
|
|
503
|
+
return profileMonitorResult;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
|
|
490
507
|
if (input.monitor.monitorType === MonitorType.SNMP) {
|
|
491
508
|
const snmpMonitorResult: string | null =
|
|
492
509
|
await SnmpMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
|
|
@@ -545,6 +562,11 @@ ${contextBlock}
|
|
|
545
562
|
monitorStep: MonitorStep;
|
|
546
563
|
monitor: Monitor;
|
|
547
564
|
}): string | null {
|
|
565
|
+
// Handle Kubernetes monitors with rich resource context
|
|
566
|
+
if (input.monitor.monitorType === MonitorType.Kubernetes) {
|
|
567
|
+
return MonitorCriteriaEvaluator.buildKubernetesRootCauseContext(input);
|
|
568
|
+
}
|
|
569
|
+
|
|
548
570
|
const requestDetails: Array<string> = [];
|
|
549
571
|
const responseDetails: Array<string> = [];
|
|
550
572
|
const failureDetails: Array<string> = [];
|
|
@@ -653,6 +675,283 @@ ${contextBlock}
|
|
|
653
675
|
return sections.join("\n");
|
|
654
676
|
}
|
|
655
677
|
|
|
678
|
+
private static buildKubernetesRootCauseContext(input: {
|
|
679
|
+
dataToProcess: DataToProcess;
|
|
680
|
+
monitorStep: MonitorStep;
|
|
681
|
+
monitor: Monitor;
|
|
682
|
+
}): string | null {
|
|
683
|
+
const metricResponse: MetricMonitorResponse =
|
|
684
|
+
input.dataToProcess as MetricMonitorResponse;
|
|
685
|
+
|
|
686
|
+
const breakdown: KubernetesResourceBreakdown | undefined =
|
|
687
|
+
metricResponse.kubernetesResourceBreakdown;
|
|
688
|
+
|
|
689
|
+
if (!breakdown) {
|
|
690
|
+
return null;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
const sections: Array<string> = [];
|
|
694
|
+
|
|
695
|
+
// Cluster context
|
|
696
|
+
const clusterDetails: Array<string> = [];
|
|
697
|
+
clusterDetails.push(`- Cluster: ${breakdown.clusterName}`);
|
|
698
|
+
clusterDetails.push(
|
|
699
|
+
`- Metric: ${breakdown.metricFriendlyName} (\`${breakdown.metricName}\`)`,
|
|
700
|
+
);
|
|
701
|
+
|
|
702
|
+
if (breakdown.attributes["k8s.namespace.name"]) {
|
|
703
|
+
clusterDetails.push(
|
|
704
|
+
`- Namespace: ${breakdown.attributes["k8s.namespace.name"]}`,
|
|
705
|
+
);
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
sections.push(
|
|
709
|
+
`**Kubernetes Cluster Details**\n${clusterDetails.join("\n")}`,
|
|
710
|
+
);
|
|
711
|
+
|
|
712
|
+
// Affected resources
|
|
713
|
+
if (breakdown.affectedResources && breakdown.affectedResources.length > 0) {
|
|
714
|
+
const resourceLines: Array<string> = [];
|
|
715
|
+
|
|
716
|
+
// Sort by metric value descending (worst first)
|
|
717
|
+
const sortedResources: Array<KubernetesAffectedResource> = [
|
|
718
|
+
...breakdown.affectedResources,
|
|
719
|
+
].sort((a: KubernetesAffectedResource, b: KubernetesAffectedResource) => {
|
|
720
|
+
return b.metricValue - a.metricValue;
|
|
721
|
+
});
|
|
722
|
+
|
|
723
|
+
// Show top 10 affected resources
|
|
724
|
+
const resourcesToShow: Array<KubernetesAffectedResource> =
|
|
725
|
+
sortedResources.slice(0, 10);
|
|
726
|
+
|
|
727
|
+
for (const resource of resourcesToShow) {
|
|
728
|
+
const details: Array<string> = [];
|
|
729
|
+
|
|
730
|
+
if (resource.namespace) {
|
|
731
|
+
details.push(`Namespace: \`${resource.namespace}\``);
|
|
732
|
+
}
|
|
733
|
+
if (resource.workloadType && resource.workloadName) {
|
|
734
|
+
details.push(
|
|
735
|
+
`${resource.workloadType}: \`${resource.workloadName}\``,
|
|
736
|
+
);
|
|
737
|
+
}
|
|
738
|
+
if (resource.podName) {
|
|
739
|
+
details.push(`Pod: \`${resource.podName}\``);
|
|
740
|
+
}
|
|
741
|
+
if (resource.containerName) {
|
|
742
|
+
details.push(`Container: \`${resource.containerName}\``);
|
|
743
|
+
}
|
|
744
|
+
if (resource.nodeName) {
|
|
745
|
+
details.push(`Node: \`${resource.nodeName}\``);
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
details.push(`Value: **${resource.metricValue}**`);
|
|
749
|
+
|
|
750
|
+
resourceLines.push(`- ${details.join(" | ")}`);
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
if (sortedResources.length > 10) {
|
|
754
|
+
resourceLines.push(
|
|
755
|
+
`- ... and ${sortedResources.length - 10} more affected resources`,
|
|
756
|
+
);
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
sections.push(
|
|
760
|
+
`\n\n**Affected Resources** (${sortedResources.length} total)\n${resourceLines.join("\n")}`,
|
|
761
|
+
);
|
|
762
|
+
|
|
763
|
+
// Add root cause analysis based on metric type
|
|
764
|
+
const analysis: string | null =
|
|
765
|
+
MonitorCriteriaEvaluator.buildKubernetesRootCauseAnalysis({
|
|
766
|
+
breakdown: breakdown,
|
|
767
|
+
topResource: resourcesToShow[0]!,
|
|
768
|
+
});
|
|
769
|
+
|
|
770
|
+
if (analysis) {
|
|
771
|
+
sections.push(`\n\n**Root Cause Analysis**\n${analysis}`);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
return sections.join("\n");
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
private static buildKubernetesRootCauseAnalysis(input: {
|
|
779
|
+
breakdown: KubernetesResourceBreakdown;
|
|
780
|
+
topResource: KubernetesAffectedResource;
|
|
781
|
+
}): string | null {
|
|
782
|
+
const { breakdown, topResource } = input;
|
|
783
|
+
const metricName: string = breakdown.metricName;
|
|
784
|
+
const lines: Array<string> = [];
|
|
785
|
+
|
|
786
|
+
if (
|
|
787
|
+
metricName === "k8s.container.restarts" ||
|
|
788
|
+
metricName.includes("restart")
|
|
789
|
+
) {
|
|
790
|
+
lines.push(
|
|
791
|
+
`Container restart count is elevated, indicating a potential CrashLoopBackOff condition.`,
|
|
792
|
+
);
|
|
793
|
+
if (topResource.containerName) {
|
|
794
|
+
lines.push(
|
|
795
|
+
`The container \`${topResource.containerName}\` in pod \`${topResource.podName || "unknown"}\` has restarted **${topResource.metricValue}** times.`,
|
|
796
|
+
);
|
|
797
|
+
}
|
|
798
|
+
lines.push(
|
|
799
|
+
`Common causes: application crash on startup, misconfigured environment variables, missing dependencies, OOM (Out of Memory) kills, failed health checks, or missing config maps/secrets.`,
|
|
800
|
+
);
|
|
801
|
+
lines.push(
|
|
802
|
+
`Recommended actions: Check container logs with \`kubectl logs ${topResource.podName || "<pod-name>"} -c ${topResource.containerName || "<container>"} --previous\` and inspect events with \`kubectl describe pod ${topResource.podName || "<pod-name>"}\`.`,
|
|
803
|
+
);
|
|
804
|
+
} else if (
|
|
805
|
+
metricName === "k8s.pod.phase" &&
|
|
806
|
+
breakdown.attributes["k8s.pod.phase"] === "Pending"
|
|
807
|
+
) {
|
|
808
|
+
lines.push(`Pods are stuck in Pending phase and unable to be scheduled.`);
|
|
809
|
+
lines.push(
|
|
810
|
+
`Common causes: insufficient CPU/memory resources on nodes, node affinity/taint restrictions preventing scheduling, PersistentVolumeClaim pending, or resource quota exceeded.`,
|
|
811
|
+
);
|
|
812
|
+
if (topResource.podName) {
|
|
813
|
+
lines.push(
|
|
814
|
+
`Recommended actions: Check scheduling events with \`kubectl describe pod ${topResource.podName}\` and verify node resources with \`kubectl describe nodes\`.`,
|
|
815
|
+
);
|
|
816
|
+
}
|
|
817
|
+
} else if (
|
|
818
|
+
metricName === "k8s.node.condition_ready" ||
|
|
819
|
+
(metricName.includes("node") && metricName.includes("condition"))
|
|
820
|
+
) {
|
|
821
|
+
lines.push(`One or more nodes have transitioned to a NotReady state.`);
|
|
822
|
+
if (topResource.nodeName) {
|
|
823
|
+
lines.push(
|
|
824
|
+
`Node \`${topResource.nodeName}\` is reporting NotReady (value: ${topResource.metricValue}).`,
|
|
825
|
+
);
|
|
826
|
+
}
|
|
827
|
+
lines.push(
|
|
828
|
+
`Common causes: kubelet process failure, node resource exhaustion (disk pressure, memory pressure, PID pressure), network connectivity issues, or underlying VM/hardware failure.`,
|
|
829
|
+
);
|
|
830
|
+
lines.push(
|
|
831
|
+
`Recommended actions: Check node conditions with \`kubectl describe node ${topResource.nodeName || "<node-name>"}\` and verify kubelet status on the node.`,
|
|
832
|
+
);
|
|
833
|
+
} else if (
|
|
834
|
+
metricName === "k8s.node.cpu.utilization" ||
|
|
835
|
+
(metricName.includes("cpu") && metricName.includes("utilization"))
|
|
836
|
+
) {
|
|
837
|
+
lines.push(`Node CPU utilization has exceeded the configured threshold.`);
|
|
838
|
+
if (topResource.nodeName) {
|
|
839
|
+
lines.push(
|
|
840
|
+
`Node \`${topResource.nodeName}\` is at **${topResource.metricValue.toFixed(1)}%** CPU utilization.`,
|
|
841
|
+
);
|
|
842
|
+
}
|
|
843
|
+
lines.push(
|
|
844
|
+
`Common causes: resource-intensive workloads, insufficient resource limits on pods, noisy neighbor pods consuming excessive CPU, or insufficient cluster capacity.`,
|
|
845
|
+
);
|
|
846
|
+
lines.push(
|
|
847
|
+
`Recommended actions: Identify top CPU consumers with \`kubectl top pods --all-namespaces --sort-by=cpu\` and consider scaling the cluster or adjusting pod resource limits.`,
|
|
848
|
+
);
|
|
849
|
+
} else if (
|
|
850
|
+
metricName === "k8s.node.memory.usage" ||
|
|
851
|
+
(metricName.includes("memory") && metricName.includes("usage"))
|
|
852
|
+
) {
|
|
853
|
+
lines.push(
|
|
854
|
+
`Node memory utilization has exceeded the configured threshold.`,
|
|
855
|
+
);
|
|
856
|
+
if (topResource.nodeName) {
|
|
857
|
+
lines.push(
|
|
858
|
+
`Node \`${topResource.nodeName}\` memory usage is at **${topResource.metricValue.toFixed(1)}%**.`,
|
|
859
|
+
);
|
|
860
|
+
}
|
|
861
|
+
lines.push(
|
|
862
|
+
`Common causes: memory leaks in applications, insufficient memory limits on pods, too many pods scheduled on the node, or growing dataset sizes.`,
|
|
863
|
+
);
|
|
864
|
+
lines.push(
|
|
865
|
+
`Recommended actions: Check memory consumers with \`kubectl top pods --all-namespaces --sort-by=memory\` and review pod memory limits. Consider scaling the cluster or adding nodes with more memory.`,
|
|
866
|
+
);
|
|
867
|
+
} else if (
|
|
868
|
+
metricName === "k8s.deployment.unavailable_replicas" ||
|
|
869
|
+
metricName.includes("unavailable")
|
|
870
|
+
) {
|
|
871
|
+
lines.push(
|
|
872
|
+
`Deployment has unavailable replicas, indicating a mismatch between desired and available replicas.`,
|
|
873
|
+
);
|
|
874
|
+
if (topResource.workloadName) {
|
|
875
|
+
lines.push(
|
|
876
|
+
`${topResource.workloadType || "Deployment"} \`${topResource.workloadName}\` has **${topResource.metricValue}** unavailable replica(s).`,
|
|
877
|
+
);
|
|
878
|
+
}
|
|
879
|
+
lines.push(
|
|
880
|
+
`Common causes: failed rolling update, image pull errors (wrong image tag or missing registry credentials), pod crash loops, insufficient cluster resources to schedule new pods, or PodDisruptionBudget blocking updates.`,
|
|
881
|
+
);
|
|
882
|
+
lines.push(
|
|
883
|
+
`Recommended actions: Check deployment rollout status with \`kubectl rollout status deployment/${topResource.workloadName || "<deployment>"}\` and inspect pod events.`,
|
|
884
|
+
);
|
|
885
|
+
} else if (
|
|
886
|
+
metricName === "k8s.job.failed_pods" ||
|
|
887
|
+
(metricName.includes("job") && metricName.includes("fail"))
|
|
888
|
+
) {
|
|
889
|
+
lines.push(`Kubernetes Job has failed pods.`);
|
|
890
|
+
if (topResource.workloadName) {
|
|
891
|
+
lines.push(
|
|
892
|
+
`Job \`${topResource.workloadName}\` has **${topResource.metricValue}** failed pod(s).`,
|
|
893
|
+
);
|
|
894
|
+
}
|
|
895
|
+
lines.push(
|
|
896
|
+
`Common causes: application error or non-zero exit code, resource limits exceeded (OOMKilled), misconfigured command or arguments, missing environment variables, or timeout exceeded.`,
|
|
897
|
+
);
|
|
898
|
+
lines.push(
|
|
899
|
+
`Recommended actions: Check job status with \`kubectl describe job ${topResource.workloadName || "<job-name>"}\` and review pod logs for the failed pod(s).`,
|
|
900
|
+
);
|
|
901
|
+
} else if (
|
|
902
|
+
metricName === "k8s.node.filesystem.usage" ||
|
|
903
|
+
metricName.includes("disk") ||
|
|
904
|
+
metricName.includes("filesystem")
|
|
905
|
+
) {
|
|
906
|
+
lines.push(
|
|
907
|
+
`Node disk/filesystem usage has exceeded the configured threshold.`,
|
|
908
|
+
);
|
|
909
|
+
if (topResource.nodeName) {
|
|
910
|
+
lines.push(
|
|
911
|
+
`Node \`${topResource.nodeName}\` filesystem usage is at **${topResource.metricValue.toFixed(1)}%**.`,
|
|
912
|
+
);
|
|
913
|
+
}
|
|
914
|
+
lines.push(
|
|
915
|
+
`Common causes: container image layers consuming disk space, excessive logging, large emptyDir volumes, or accumulation of unused container images.`,
|
|
916
|
+
);
|
|
917
|
+
lines.push(
|
|
918
|
+
`Recommended actions: Clean up unused images with \`docker system prune\` or \`crictl rmi --prune\`, check for large log files, and review PersistentVolumeClaim usage.`,
|
|
919
|
+
);
|
|
920
|
+
} else if (
|
|
921
|
+
metricName === "k8s.daemonset.misscheduled_nodes" ||
|
|
922
|
+
metricName.includes("daemonset")
|
|
923
|
+
) {
|
|
924
|
+
lines.push(`DaemonSet has misscheduled or unavailable nodes.`);
|
|
925
|
+
if (topResource.workloadName) {
|
|
926
|
+
lines.push(
|
|
927
|
+
`DaemonSet \`${topResource.workloadName}\` has **${topResource.metricValue}** misscheduled node(s).`,
|
|
928
|
+
);
|
|
929
|
+
}
|
|
930
|
+
lines.push(
|
|
931
|
+
`Common causes: node taints preventing scheduling, incorrect node selectors, or node affinity rules excluding certain nodes.`,
|
|
932
|
+
);
|
|
933
|
+
lines.push(
|
|
934
|
+
`Recommended actions: Check DaemonSet status with \`kubectl describe daemonset ${topResource.workloadName || "<daemonset>"}\` and verify node labels and taints.`,
|
|
935
|
+
);
|
|
936
|
+
} else {
|
|
937
|
+
// Generic Kubernetes context
|
|
938
|
+
lines.push(
|
|
939
|
+
`Kubernetes metric \`${metricName}\` (${breakdown.metricFriendlyName}) has breached the configured threshold.`,
|
|
940
|
+
);
|
|
941
|
+
if (topResource.podName) {
|
|
942
|
+
lines.push(`Most affected pod: \`${topResource.podName}\``);
|
|
943
|
+
}
|
|
944
|
+
if (topResource.nodeName) {
|
|
945
|
+
lines.push(`Most affected node: \`${topResource.nodeName}\``);
|
|
946
|
+
}
|
|
947
|
+
lines.push(
|
|
948
|
+
`Recommended actions: Investigate the affected resources using \`kubectl describe\` and \`kubectl logs\` commands.`,
|
|
949
|
+
);
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
return lines.join("\n");
|
|
953
|
+
}
|
|
954
|
+
|
|
656
955
|
private static getMonitorDestinationString(input: {
|
|
657
956
|
monitorStep: MonitorStep;
|
|
658
957
|
probeResponse: ProbeMonitorResponse | null;
|