@oneuptime/common 14.0.3 → 14.0.5
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/DatabaseModels/Alert.ts +55 -0
- package/Models/DatabaseModels/DatabaseServer.ts +1650 -0
- package/Models/DatabaseModels/DatabaseServerEndpoint.ts +540 -0
- package/Models/DatabaseModels/DatabaseServerFeed.ts +625 -0
- package/Models/DatabaseModels/DatabaseServerLabelRule.ts +514 -0
- package/Models/DatabaseModels/DatabaseServerOwnerRule.ts +596 -0
- package/Models/DatabaseModels/DatabaseServerOwnerTeam.ts +491 -0
- package/Models/DatabaseModels/DatabaseServerOwnerUser.ts +490 -0
- package/Models/DatabaseModels/Incident.ts +55 -0
- package/Models/DatabaseModels/Index.ts +16 -0
- package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +26 -0
- package/Models/DatabaseModels/ScheduledMaintenance.ts +55 -0
- package/Models/DatabaseModels/TelemetryException.ts +2 -0
- package/Models/DatabaseModels/UserProjectSsoConsent.ts +146 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.ts +673 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.ts +51 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
- package/Server/Middleware/MultipartFormData.ts +1 -1
- package/Server/Middleware/TelemetryIngest.ts +15 -8
- package/Server/Services/AlertReminderRuleService.ts +100 -24
- package/Server/Services/DatabaseServerEndpointService.ts +895 -0
- package/Server/Services/DatabaseServerFeedService.ts +128 -0
- package/Server/Services/DatabaseServerLabelRuleEngineService.ts +340 -0
- package/Server/Services/DatabaseServerLabelRuleService.ts +14 -0
- package/Server/Services/DatabaseServerOwnerRuleEngineService.ts +425 -0
- package/Server/Services/DatabaseServerOwnerRuleService.ts +14 -0
- package/Server/Services/DatabaseServerOwnerTeamService.ts +180 -0
- package/Server/Services/DatabaseServerOwnerUserService.ts +173 -0
- package/Server/Services/DatabaseServerService.ts +4546 -0
- package/Server/Services/DatabaseService.ts +14 -8
- package/Server/Services/DockerResourceService.ts +43 -2
- package/Server/Services/IncidentReminderRuleService.ts +103 -23
- package/Server/Services/Index.ts +16 -0
- package/Server/Services/InventoryItemService.ts +113 -5
- package/Server/Services/IoTDeviceService.ts +145 -37
- package/Server/Services/OpenTelemetryIngestService.ts +19 -0
- package/Server/Services/PodmanResourceService.ts +43 -2
- package/Server/Services/ScheduledMaintenanceReminderRuleService.ts +107 -23
- package/Server/Services/ServiceService.ts +1 -1
- package/Server/Services/TelemetryUsageBillingService.ts +29 -2
- package/Server/Services/UserProjectSsoConsentService.ts +74 -0
- package/Server/Services/UserService.ts +14 -1
- package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +18 -0
- package/Server/Types/Database/QueryHelper.ts +30 -1
- package/Server/Utils/AI/Toolbox/ResourceTools.ts +69 -1
- package/Server/Utils/Database/AffectedResourceRelations.ts +6 -0
- package/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.ts +188 -6
- package/Server/Utils/Monitor/MonitorAlert.ts +28 -1
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +2262 -755
- package/Server/Utils/Monitor/MonitorIncident.ts +28 -1
- package/Server/Utils/Monitor/MonitorMaintenanceSuppression.ts +268 -6
- package/Server/Utils/Monitor/MonitorResource.ts +47 -11
- package/Server/Utils/Monitor/MonitorResourceContext.ts +1 -0
- package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +239 -21
- package/Server/Utils/Monitor/PerSeriesResolutionRootCause.ts +43 -0
- package/Server/Utils/Monitor/SeriesResourceLabels.ts +291 -0
- package/Server/Utils/Monitor/SeriesResourceLinker.ts +111 -12
- package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +25 -0
- package/Server/Utils/StartServer.ts +26 -6
- package/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.ts +2 -0
- package/Server/Utils/Telemetry/DatabaseEndpointDiscovery.ts +688 -0
- package/Server/Utils/Telemetry/EntityRegistry.ts +5 -1
- package/Server/Utils/Telemetry/LogExceptionExtractor.ts +18 -1
- package/Server/Utils/Telemetry/ResourceEntityFilter.ts +175 -12
- package/Server/Utils/Telemetry/ResourceFacetResolver.ts +12 -0
- package/Server/Utils/Telemetry/ServiceDependencyDiscovery.ts +606 -36
- package/Server/Utils/Telemetry/Telemetry.ts +16 -0
- package/Server/Utils/Telemetry/TelemetryEntity.ts +22 -22
- package/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.ts +16 -10
- package/Tests/App/Accounts/SignedInRedirect.test.tsx +241 -0
- package/Tests/App/AdminDashboard/AdminHeaderSmallScreens.test.tsx +221 -4
- package/Tests/App/Dashboard/AIInsightsResourcePageContext.test.ts +42 -0
- package/Tests/App/Dashboard/AffectedResourcesDisplay.test.tsx +100 -0
- package/Tests/App/Dashboard/AffectedResourcesPicker.test.tsx +86 -0
- package/Tests/App/Dashboard/AffectedResourcesPickerHiddenTypes.test.tsx +2 -0
- package/Tests/App/Dashboard/AffectedResourcesSummaryStep.test.tsx +19 -0
- package/Tests/App/Dashboard/BreadcrumbCoverage.test.tsx +14 -0
- package/Tests/App/Dashboard/CorrelateFilterBuilder.test.tsx +26 -1
- package/Tests/App/Dashboard/DashboardAppSsoError.test.tsx +501 -0
- package/Tests/App/Dashboard/DashboardHeaderRequests.test.tsx +64 -1
- package/Tests/App/Dashboard/DashboardHeaderSmallScreens.test.tsx +178 -18
- package/Tests/App/Dashboard/DashboardMasterPageSsoRedirect.test.tsx +444 -0
- package/Tests/App/Dashboard/DashboardNavBarForeignHiddenRule.test.tsx +573 -0
- package/Tests/App/Dashboard/DatabaseChartAxes.test.tsx +431 -0
- package/Tests/App/Dashboard/DatabaseContainerDetailBadge.test.tsx +249 -0
- package/Tests/App/Dashboard/DatabaseDashboardE2EFixes.test.ts +681 -0
- package/Tests/App/Dashboard/DatabaseDocumentationMarkdown.test.ts +1801 -0
- package/Tests/App/Dashboard/DatabaseFleetSummaryRefresh.test.tsx +280 -0
- package/Tests/App/Dashboard/DatabaseFormHelpers.test.tsx +321 -0
- package/Tests/App/Dashboard/DatabaseMetricMonitorLink.test.tsx +795 -0
- package/Tests/App/Dashboard/DatabaseOverviewHeader.test.tsx +580 -0
- package/Tests/App/Dashboard/DatabaseRecommendationsEngineMetrics.test.ts +270 -0
- package/Tests/App/Dashboard/DatabaseServerComponents.test.tsx +1486 -0
- package/Tests/App/Dashboard/DatabaseServerEngineMetricsFilter.test.ts +223 -0
- package/Tests/App/Dashboard/DatabaseServerPresentation.test.ts +435 -0
- package/Tests/App/Dashboard/DatabaseServerSummary.test.ts +186 -0
- package/Tests/App/Dashboard/DatabaseServerTelemetryQueries.test.ts +1553 -0
- package/Tests/App/Dashboard/DatabaseTableTruncation.test.tsx +326 -0
- package/Tests/App/Dashboard/DatabaseTelemetryScope.test.ts +512 -0
- package/Tests/App/Dashboard/DatabaseTelemetryTabs.test.tsx +774 -0
- package/Tests/App/Dashboard/DatabaseViewLayout.test.tsx +233 -0
- package/Tests/App/Dashboard/DatabaseWorkloadBadge.test.tsx +972 -0
- package/Tests/App/Dashboard/DiscoveryReviewInventoryRefresh.test.tsx +5 -0
- package/Tests/App/Dashboard/DiscoveryReviewUnnamedHostHint.test.tsx +1061 -0
- package/Tests/App/Dashboard/EventOverlayScope.test.ts +147 -0
- package/Tests/App/Dashboard/EventOverlayScopeHook.test.tsx +1 -0
- package/Tests/App/Dashboard/LogsResourceFacetChips.test.tsx +1 -0
- package/Tests/App/Dashboard/MetricsViewerDrillDown.test.tsx +310 -0
- package/Tests/App/Dashboard/MetricsViewerEntityScopedRows.test.tsx +495 -0
- package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +132 -1
- package/Tests/App/Dashboard/NavigationSearchKeywords.test.tsx +5 -0
- package/Tests/App/Dashboard/ProductOrientation.test.tsx +4 -3
- package/Tests/App/Dashboard/RecommendationsLoadedContext.test.tsx +349 -0
- package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +62 -0
- package/Tests/App/Dashboard/ResourceFeedPageWiring.test.ts +8 -1
- package/Tests/App/Dashboard/ResourceFeedPagesFilterSort.test.tsx +14 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +2 -0
- package/Tests/App/Dashboard/ServiceMapDatabaseLink.test.tsx +1085 -0
- package/Tests/App/Dashboard/TelemetryResourceRetentionSettings.test.tsx +10 -0
- package/Tests/App/Dashboard/TracesResourceFacets.test.tsx +2 -1
- package/Tests/App/StatusPage/StatusPageHeaderForeignHiddenRule.test.tsx +284 -0
- package/Tests/ClassStrings.ts +178 -0
- package/Tests/Fixtures/MobilePasskeyUser.json +1 -2
- package/Tests/ForeignHiddenRuleGuard.ts +2152 -0
- package/Tests/Models/DatabaseModels/DatabaseServerModels.test.ts +2250 -0
- package/Tests/Models/DatabaseModels/ResourceFeedModels.test.ts +24 -5
- package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +4 -2
- package/Tests/RenderedMarkup.ts +518 -0
- package/Tests/ResponsiveVisibility.test.ts +490 -4
- package/Tests/ResponsiveVisibility.ts +505 -52
- package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +3 -0
- package/Tests/Server/Infrastructure/Postgres/AddDatabaseServerTablesMigration.test.ts +541 -0
- package/Tests/Server/Infrastructure/Postgres/AddUserProjectSsoConsentMigration.test.ts +234 -0
- package/Tests/Server/Services/ContainerSnapshotUpsertPostgres.test.ts +319 -0
- package/Tests/Server/Services/CrossProjectRelationWriteGuard.test.ts +13 -0
- package/Tests/Server/Services/DatabaseServerEndpointService.test.ts +2033 -0
- package/Tests/Server/Services/DatabaseServerFeedAndOwnerServices.test.ts +529 -0
- package/Tests/Server/Services/DatabaseServerLifecycle.test.ts +3302 -0
- package/Tests/Server/Services/DatabaseServerRegistries.test.ts +603 -0
- package/Tests/Server/Services/DatabaseServerRuleEngines.test.ts +754 -0
- package/Tests/Server/Services/DatabaseServerService.test.ts +3558 -0
- package/Tests/Server/Services/DatabaseServerSqlPostgres.test.ts +2045 -0
- package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlockedPostgres.test.ts +362 -0
- package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlockedReply.test.ts +210 -0
- package/Tests/Server/Services/HookFreeWriteLengthClamp.test.ts +18 -0
- package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +2 -0
- package/Tests/Server/Services/IncomingCallPolicyEscalationRuleTarget.test.ts +225 -0
- package/Tests/Server/Services/InventoryItemDisplayName.test.ts +280 -2
- package/Tests/Server/Services/InventoryUpsertSchemaParity.test.ts +8 -2
- package/Tests/Server/Services/IoTDeviceLatestMetricsPostgres.test.ts +689 -0
- package/Tests/Server/Services/IoTDeviceService.test.ts +379 -0
- package/Tests/Server/Services/LatestMetricsValuesShape.test.ts +360 -0
- package/Tests/Server/Services/LlmModelPriceService.test.ts +402 -0
- package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +7 -1
- package/Tests/Server/Services/OwnerRowUniqueness.test.ts +61 -9
- package/Tests/Server/Services/ReminderRuleLookupPostgres.test.ts +2250 -0
- package/Tests/Server/Services/ReminderRuleRefreshOpenSubjectsPaging.test.ts +653 -0
- package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +68 -20
- package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +3 -3
- package/Tests/Server/Services/TelemetryResourceFacetCounting.test.ts +9 -0
- package/Tests/Server/Services/UserProjectSsoConsentPostgres.test.ts +153 -0
- package/Tests/Server/Services/UserProjectSsoConsentService.test.ts +192 -0
- package/Tests/Server/Services/UserServiceFirstMasterAdminElection.test.ts +71 -0
- package/Tests/Server/Services/UserSignupIdTakeoverPostgres.test.ts +238 -0
- package/Tests/Server/Services/WorkspaceNotificationSummaryHelpers.test.ts +592 -0
- package/Tests/Server/Types/Billing/PayAsYouGoMeteredAuthorization.test.ts +3 -0
- package/Tests/Server/Types/Database/EventOverlayScopePostgres.test.ts +1 -0
- package/Tests/Server/Types/Database/FeedEventTypeFilterQuery.test.ts +11 -0
- package/Tests/Server/Types/Database/Permissions/InfrastructureOwnershipScope.test.ts +8 -0
- package/Tests/Server/Types/Database/QueryHelperBooleanForCriteriaBackedRule.test.ts +1094 -0
- package/Tests/Server/Utils/AI/ResourceTools.test.ts +134 -0
- package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.test.ts +41 -0
- package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaAnomalyUnits.test.ts +279 -9
- package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaDisplayContext.test.ts +933 -0
- package/Tests/Server/Utils/Monitor/DatabaseMaintenanceSuppression.test.ts +582 -0
- package/Tests/Server/Utils/Monitor/DatabaseServerMonitorLinking.test.ts +753 -0
- package/Tests/Server/Utils/Monitor/MonitorActionTimestamps.test.ts +1 -0
- package/Tests/Server/Utils/Monitor/MonitorAlertCriteriaReferences.test.ts +1 -0
- package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +119 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +60 -25
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorAffectedResourceEdgeCases.test.ts +1719 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorKubernetesAffectedResources.test.ts +1447 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorKubernetesRatioEmail.test.ts +352 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformMetricUnits.test.ts +717 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformRawScan.test.ts +2125 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorPlatformSeriesAffectedResources.test.ts +1288 -0
- package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +1 -0
- package/Tests/Server/Utils/Monitor/MonitorIncidentCriteriaReferences.test.ts +1 -0
- package/Tests/Server/Utils/Monitor/MonitorIncidentMemberRoleMembership.test.ts +1 -0
- package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +88 -0
- package/Tests/Server/Utils/Monitor/MonitorMaintenanceSuppression.test.ts +205 -0
- package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +62 -0
- package/Tests/Server/Utils/Monitor/MonitorResourceDatabaseMaintenance.test.ts +803 -0
- package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +133 -3
- package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +1 -0
- package/Tests/Server/Utils/Monitor/PerSeriesRecoveryResolution.test.ts +472 -1
- package/Tests/Server/Utils/Monitor/PerSeriesSecondEntityAlerting.test.ts +1 -0
- package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +236 -2
- package/Tests/Server/Utils/SeriesResourceLabels.test.ts +70 -0
- package/Tests/Server/Utils/StartServerProtobufContentType.test.ts +54 -0
- package/Tests/Server/Utils/Telemetry/DatabaseEndpointDiscovery.test.ts +1895 -0
- package/Tests/Server/Utils/Telemetry/EntityRegistry.test.ts +7 -0
- package/Tests/Server/Utils/Telemetry/LogExceptionExtractorSeverityGate.test.ts +90 -0
- package/Tests/Server/Utils/Telemetry/ResourceEntityFilter.test.ts +570 -0
- package/Tests/Server/Utils/Telemetry/ResourceFacetResolver.test.ts +97 -2
- package/Tests/Server/Utils/Telemetry/ServiceDependencyDiscovery.test.ts +1337 -0
- package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +295 -0
- package/Tests/Types/AI/AIResourceContext.test.ts +30 -0
- package/Tests/Types/DatabaseServer/DatabaseContainerClassifier.test.ts +3644 -0
- package/Tests/Types/DatabaseServer/DatabaseContainerCommand.test.ts +340 -0
- package/Tests/Types/DatabaseServer/DatabaseContainerCommandCorpus.ts +826 -0
- package/Tests/Types/DatabaseServer/DatabaseContainerCommandPostgres.test.ts +150 -0
- package/Tests/Types/DatabaseServer/DatabaseEndpoint.test.ts +2657 -0
- package/Tests/Types/DatabaseServer/DatabaseServerDiscoverySource.test.ts +64 -0
- package/Tests/Types/DatabaseServer/DatabaseServerEntityKeys.test.ts +952 -0
- package/Tests/Types/DatabaseServer/DatabaseServerMetricCatalog.test.ts +1161 -0
- package/Tests/Types/DatabaseServer/DatabaseSystem.test.ts +1514 -0
- package/Tests/Types/DatabaseServer/DatabaseTelemetryResolver.test.ts +1558 -0
- package/Tests/Types/Monitor/CephAlertTemplates.test.ts +255 -6
- package/Tests/Types/Monitor/DatabaseAlertTemplates.test.ts +2254 -0
- package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +298 -0
- package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +271 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +253 -9
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +13 -5
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +4 -2
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +111 -2
- package/Tests/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.test.ts +61 -0
- package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +114 -0
- package/Tests/Types/Monitor/Utils/KubernetesAgentEmittedMetrics.ts +181 -0
- package/Tests/Types/NetworkDevice/DiscoveredHostNamingStatus.test.ts +401 -0
- package/Tests/Types/Telemetry/ResourceEntityFacet.test.ts +4 -1
- package/Tests/Types/Telemetry/ResourceFacetCatalog.test.ts +24 -2
- package/Tests/UI/Components/Card.test.tsx +93 -2
- package/Tests/UI/Components/FeedOptions.test.ts +6 -0
- package/Tests/UI/Components/FeedOptionsButton.test.tsx +8 -1
- package/Tests/UI/Components/ForeignHiddenRuleResilience.test.tsx +1147 -0
- package/Tests/UI/Components/HeaderRightRail.test.tsx +41 -1
- package/Tests/UI/Components/LogsEntityNames.test.ts +16 -1
- package/Tests/UI/Components/LogsFacetSidebarHiddenFacets.test.tsx +7 -3
- package/Tests/UI/Components/ResourceFacetConfigs.test.ts +2 -1
- package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
- package/Tests/UI/Components/SrOnlyForeignRule.test.tsx +994 -0
- package/Tests/UI/Components/StatusPage/ResourceListSelection.test.tsx +34 -1
- package/Tests/UI/Components/TelemetryFacetSidebarHiddenFacets.test.tsx +4 -1
- package/Tests/UI/ForeignHiddenRuleGuard.test.ts +1951 -0
- package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +19 -1
- package/Tests/UI/Rum/ReplayTabSwitcher.test.tsx +19 -1
- package/Tests/UI/TailwindPlayCdnForeignHiddenRule.test.ts +1005 -0
- package/Tests/UI/ThemeGroupHoverReveal.test.ts +847 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +70 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +21 -0
- package/Tests/UI/Utils/ModelAPISsoRedirect.test.ts +127 -0
- package/Tests/UI/Utils/Navigation.test.ts +102 -0
- package/Tests/UI/Utils/Telemetry/TelemetryEntityNames.test.ts +23 -0
- package/Tests/Utils/LabelRuleImportExport.test.ts +5 -0
- package/Tests/Utils/MetricUnitUtil.test.ts +227 -2
- package/Tests/Utils/Monitor/MetricValueFormatter.test.ts +288 -2
- package/Tests/Utils/Monitor/PlatformResourceIdentityAndUnits.test.ts +1559 -0
- package/Tests/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.test.ts +2546 -0
- package/Tests/Utils/NetworkDiscovery/DiscoveredHostUtil.test.ts +315 -0
- package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +336 -1
- package/Tests/Utils/NetworkDiscovery/NetbiosNameUtil.test.ts +244 -0
- package/Tests/Utils/ValueFormatter.test.ts +50 -0
- package/Tests/tsconfig.json +16 -0
- package/Types/AI/AIResourceContext.ts +7 -0
- package/Types/Dashboard/DashboardTemplates.ts +2 -1
- package/Types/DatabaseServer/DatabaseConnectionSpan.ts +77 -0
- package/Types/DatabaseServer/DatabaseContainerClassifier.ts +2068 -0
- package/Types/DatabaseServer/DatabaseContainerCommand.ts +801 -0
- package/Types/DatabaseServer/DatabaseEndpoint.ts +1943 -0
- package/Types/DatabaseServer/DatabaseServerDiscoverySource.ts +68 -0
- package/Types/DatabaseServer/DatabaseServerMetricCatalog.ts +966 -0
- package/Types/DatabaseServer/DatabaseSystem.ts +2124 -0
- package/Types/DatabaseServer/DatabaseTelemetryResolver.ts +555 -0
- package/Types/Email/EmailTemplateType.ts +1 -0
- package/Types/Monitor/CephAlertTemplates.ts +18 -0
- package/Types/Monitor/DatabaseAlertTemplates.ts +2020 -0
- package/Types/Monitor/KubernetesAlertTemplates.ts +64 -24
- package/Types/Monitor/KubernetesMetricCatalog.ts +118 -19
- package/Types/Monitor/MetricMonitor/MetricCriteriaContext.ts +14 -0
- package/Types/Monitor/MetricMonitor/MetricMonitorResponse.ts +93 -10
- package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +109 -8
- package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +36 -7
- package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +43 -2
- package/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.ts +41 -6
- package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +26 -0
- package/Types/NetworkDevice/DiscoveredHostNamingStatus.ts +147 -0
- package/Types/Permission.ts +267 -0
- package/Types/Probe/ProbeApiIngestResponse.ts +8 -0
- package/Types/Rules/RuleCriteriaFieldRegistry.ts +10 -0
- package/Types/Rules/RuleRun.ts +12 -0
- package/Types/Telemetry/EntityType.ts +23 -0
- package/Types/Telemetry/ResourceFacetCatalog.ts +14 -0
- package/Types/Telemetry/ServiceType.ts +8 -0
- package/UI/Components/Banner/Banner.tsx +1 -1
- package/UI/Components/Card/Card.tsx +1 -1
- package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +2 -2
- package/UI/Components/Charts/Line/LineChart.tsx +7 -0
- package/UI/Components/CommandPalette/CommandPalette.tsx +1 -1
- package/UI/Components/Date/StartAndEndDate.tsx +5 -5
- package/UI/Components/Diagram/HorizontalStepChain.tsx +1 -1
- package/UI/Components/Feed/FeedOptionsButton.tsx +1 -1
- package/UI/Components/Forms/BasicForm.tsx +1 -1
- package/UI/Components/Header/Header.tsx +1 -1
- package/UI/Components/Header/HeaderIconDropdownButton.tsx +1 -1
- package/UI/Components/HeaderAlert/HeaderAlert.tsx +1 -1
- package/UI/Components/LogsViewer/components/FacetValueRow.tsx +1 -1
- package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +1 -1
- package/UI/Components/Modal/ModalFooter.tsx +1 -1
- package/UI/Components/ModelDetail/CardModelDetail.tsx +2 -2
- package/UI/Components/ModelTable/BaseModelTable.tsx +4 -4
- package/UI/Components/Navbar/NavBar.tsx +9 -2
- package/UI/Components/Navbar/NavBarMenuModal.tsx +2 -2
- package/UI/Components/Page/Page.tsx +1 -1
- package/UI/Components/Pagination/Pagination.tsx +3 -3
- package/UI/Components/ProgressButtons/ProgressButtonItem.tsx +1 -1
- package/UI/Components/SideMenu/SideMenu.tsx +4 -1
- package/UI/Components/StatusPage/ResourceGroupNavigator.tsx +4 -2
- package/UI/Components/StatusPage/ResourceList.tsx +6 -6
- package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +1 -1
- package/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.tsx +1 -1
- package/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.tsx +1 -1
- package/UI/Components/Workflow/ComponentsModal.tsx +2 -2
- package/UI/Components/Workflow/StepTraceViewer.tsx +1 -1
- package/UI/Styles/Theme.css +8 -1
- package/UI/Utils/Navigation.ts +89 -42
- package/UI/Utils/Telemetry/TelemetryEntityNames.ts +7 -0
- package/UI/Utils/TelemetryService.ts +4 -3
- package/Utils/LabelRuleImportExport.ts +2 -0
- package/Utils/MetricUnitUtil.ts +103 -11
- package/Utils/Monitor/MetricValueFormatter.ts +66 -13
- package/Utils/Monitor/PlatformMetricUnitUtil.ts +215 -0
- package/Utils/Monitor/PlatformResourceIdentity.ts +514 -0
- package/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.ts +425 -0
- package/Utils/NetworkDiscovery/DiscoveredHostUtil.ts +32 -0
- package/Utils/NetworkDiscovery/NetbiosNameUtil.ts +73 -0
- package/Utils/Telemetry/DatabaseServerEntityKeys.ts +275 -0
- package/Utils/Telemetry/EntityKey.ts +176 -0
- package/Utils/ValueFormatter.ts +16 -0
- package/build/dist/Models/DatabaseModels/Alert.js +54 -0
- package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DatabaseServer.js +1683 -0
- package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -0
- package/build/dist/Models/DatabaseModels/DatabaseServerEndpoint.js +559 -0
- package/build/dist/Models/DatabaseModels/DatabaseServerEndpoint.js.map +1 -0
- package/build/dist/Models/DatabaseModels/DatabaseServerFeed.js +648 -0
- package/build/dist/Models/DatabaseModels/DatabaseServerFeed.js.map +1 -0
- package/build/dist/Models/DatabaseModels/DatabaseServerLabelRule.js +522 -0
- package/build/dist/Models/DatabaseModels/DatabaseServerLabelRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/DatabaseServerOwnerRule.js +603 -0
- package/build/dist/Models/DatabaseModels/DatabaseServerOwnerRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/DatabaseServerOwnerTeam.js +506 -0
- package/build/dist/Models/DatabaseModels/DatabaseServerOwnerTeam.js.map +1 -0
- package/build/dist/Models/DatabaseModels/DatabaseServerOwnerUser.js +505 -0
- package/build/dist/Models/DatabaseModels/DatabaseServerOwnerUser.js.map +1 -0
- package/build/dist/Models/DatabaseModels/Incident.js +54 -0
- package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +16 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +54 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TelemetryException.js +2 -0
- package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserProjectSsoConsent.js +162 -0
- package/build/dist/Models/DatabaseModels/UserProjectSsoConsent.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.js +240 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795000000000-AddDatabaseServerTables.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.js +26 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795100000000-AddUserProjectSsoConsent.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/MultipartFormData.js +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +15 -8
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/AlertReminderRuleService.js +72 -23
- package/build/dist/Server/Services/AlertReminderRuleService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseServerEndpointService.js +694 -0
- package/build/dist/Server/Services/DatabaseServerEndpointService.js.map +1 -0
- package/build/dist/Server/Services/DatabaseServerFeedService.js +110 -0
- package/build/dist/Server/Services/DatabaseServerFeedService.js.map +1 -0
- package/build/dist/Server/Services/DatabaseServerLabelRuleEngineService.js +272 -0
- package/build/dist/Server/Services/DatabaseServerLabelRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/DatabaseServerLabelRuleService.js +13 -0
- package/build/dist/Server/Services/DatabaseServerLabelRuleService.js.map +1 -0
- package/build/dist/Server/Services/DatabaseServerOwnerRuleEngineService.js +340 -0
- package/build/dist/Server/Services/DatabaseServerOwnerRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/DatabaseServerOwnerRuleService.js +13 -0
- package/build/dist/Server/Services/DatabaseServerOwnerRuleService.js.map +1 -0
- package/build/dist/Server/Services/DatabaseServerOwnerTeamService.js +160 -0
- package/build/dist/Server/Services/DatabaseServerOwnerTeamService.js.map +1 -0
- package/build/dist/Server/Services/DatabaseServerOwnerUserService.js +153 -0
- package/build/dist/Server/Services/DatabaseServerOwnerUserService.js.map +1 -0
- package/build/dist/Server/Services/DatabaseServerService.js +3272 -0
- package/build/dist/Server/Services/DatabaseServerService.js.map +1 -0
- package/build/dist/Server/Services/DatabaseService.js +8 -4
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DockerResourceService.js +30 -3
- package/build/dist/Server/Services/DockerResourceService.js.map +1 -1
- package/build/dist/Server/Services/IncidentReminderRuleService.js +73 -23
- package/build/dist/Server/Services/IncidentReminderRuleService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +16 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/InventoryItemService.js +88 -5
- package/build/dist/Server/Services/InventoryItemService.js.map +1 -1
- package/build/dist/Server/Services/IoTDeviceService.js +111 -24
- package/build/dist/Server/Services/IoTDeviceService.js.map +1 -1
- package/build/dist/Server/Services/OpenTelemetryIngestService.js +24 -9
- package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
- package/build/dist/Server/Services/PodmanResourceService.js +30 -3
- package/build/dist/Server/Services/PodmanResourceService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js +75 -23
- package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js.map +1 -1
- package/build/dist/Server/Services/ServiceService.js +1 -1
- package/build/dist/Server/Services/ServiceService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryUsageBillingService.js +23 -2
- package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
- package/build/dist/Server/Services/UserProjectSsoConsentService.js +79 -0
- package/build/dist/Server/Services/UserProjectSsoConsentService.js.map +1 -0
- package/build/dist/Server/Services/UserService.js +13 -1
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +18 -0
- package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js +26 -1
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js +46 -0
- package/build/dist/Server/Utils/AI/Toolbox/ResourceTools.js.map +1 -1
- package/build/dist/Server/Utils/Database/AffectedResourceRelations.js +6 -0
- package/build/dist/Server/Utils/Database/AffectedResourceRelations.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js +134 -13
- package/build/dist/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +22 -6
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +1489 -524
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +22 -6
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js +196 -6
- package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +36 -9
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +175 -17
- package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/PerSeriesResolutionRootCause.js +29 -0
- package/build/dist/Server/Utils/Monitor/PerSeriesResolutionRootCause.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +211 -0
- package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +82 -10
- package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
- package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +25 -0
- package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +20 -4
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js +2 -0
- package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/DatabaseEndpointDiscovery.js +442 -0
- package/build/dist/Server/Utils/Telemetry/DatabaseEndpointDiscovery.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +5 -1
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/LogExceptionExtractor.js +15 -1
- package/build/dist/Server/Utils/Telemetry/LogExceptionExtractor.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +121 -5
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js +12 -0
- package/build/dist/Server/Utils/Telemetry/ResourceFacetResolver.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js +438 -36
- package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/Telemetry.js +12 -0
- package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +17 -18
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js +16 -10
- package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js.map +1 -1
- package/build/dist/Types/AI/AIResourceContext.js +7 -0
- package/build/dist/Types/AI/AIResourceContext.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardTemplates.js +2 -1
- package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
- package/build/dist/Types/DatabaseServer/DatabaseConnectionSpan.js +71 -0
- package/build/dist/Types/DatabaseServer/DatabaseConnectionSpan.js.map +1 -0
- package/build/dist/Types/DatabaseServer/DatabaseContainerClassifier.js +1462 -0
- package/build/dist/Types/DatabaseServer/DatabaseContainerClassifier.js.map +1 -0
- package/build/dist/Types/DatabaseServer/DatabaseContainerCommand.js +691 -0
- package/build/dist/Types/DatabaseServer/DatabaseContainerCommand.js.map +1 -0
- package/build/dist/Types/DatabaseServer/DatabaseEndpoint.js +1407 -0
- package/build/dist/Types/DatabaseServer/DatabaseEndpoint.js.map +1 -0
- package/build/dist/Types/DatabaseServer/DatabaseServerDiscoverySource.js +60 -0
- package/build/dist/Types/DatabaseServer/DatabaseServerDiscoverySource.js.map +1 -0
- package/build/dist/Types/DatabaseServer/DatabaseServerMetricCatalog.js +804 -0
- package/build/dist/Types/DatabaseServer/DatabaseServerMetricCatalog.js.map +1 -0
- package/build/dist/Types/DatabaseServer/DatabaseSystem.js +1860 -0
- package/build/dist/Types/DatabaseServer/DatabaseSystem.js.map +1 -0
- package/build/dist/Types/DatabaseServer/DatabaseTelemetryResolver.js +406 -0
- package/build/dist/Types/DatabaseServer/DatabaseTelemetryResolver.js.map +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/Monitor/CephAlertTemplates.js +18 -0
- package/build/dist/Types/Monitor/CephAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/DatabaseAlertTemplates.js +1518 -0
- package/build/dist/Types/Monitor/DatabaseAlertTemplates.js.map +1 -0
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +57 -24
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/KubernetesMetricCatalog.js +104 -18
- package/build/dist/Types/Monitor/KubernetesMetricCatalog.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +80 -3
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +10 -3
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +29 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js +21 -6
- package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js.map +1 -1
- package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +25 -0
- package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -1
- package/build/dist/Types/NetworkDevice/DiscoveredHostNamingStatus.js +136 -0
- package/build/dist/Types/NetworkDevice/DiscoveredHostNamingStatus.js.map +1 -0
- package/build/dist/Types/Permission.js +234 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +10 -0
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
- package/build/dist/Types/Rules/RuleRun.js +4 -0
- package/build/dist/Types/Rules/RuleRun.js.map +1 -1
- package/build/dist/Types/Telemetry/EntityType.js +23 -0
- package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
- package/build/dist/Types/Telemetry/ResourceFacetCatalog.js +14 -0
- package/build/dist/Types/Telemetry/ResourceFacetCatalog.js.map +1 -1
- package/build/dist/Types/Telemetry/ServiceType.js +8 -0
- package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
- package/build/dist/UI/Components/Banner/Banner.js +1 -1
- package/build/dist/UI/Components/Banner/Banner.js.map +1 -1
- package/build/dist/UI/Components/Card/Card.js +1 -1
- package/build/dist/UI/Components/Card/Card.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +2 -2
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.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/CommandPalette/CommandPalette.js +1 -1
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -1
- package/build/dist/UI/Components/Date/StartAndEndDate.js +5 -5
- package/build/dist/UI/Components/Date/StartAndEndDate.js.map +1 -1
- package/build/dist/UI/Components/Diagram/HorizontalStepChain.js +1 -1
- package/build/dist/UI/Components/Diagram/HorizontalStepChain.js.map +1 -1
- package/build/dist/UI/Components/Feed/FeedOptionsButton.js +1 -1
- package/build/dist/UI/Components/Feed/FeedOptionsButton.js.map +1 -1
- package/build/dist/UI/Components/Forms/BasicForm.js +1 -1
- package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
- package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js +1 -1
- package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js.map +1 -1
- package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js +1 -1
- package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js +1 -1
- package/build/dist/UI/Components/LogsViewer/components/FacetValueRow.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/Modal/ModalFooter.js +1 -1
- package/build/dist/UI/Components/Modal/ModalFooter.js.map +1 -1
- package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +2 -2
- package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +4 -4
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBar.js +9 -2
- package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +2 -2
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
- package/build/dist/UI/Components/Page/Page.js +1 -1
- package/build/dist/UI/Components/Page/Page.js.map +1 -1
- package/build/dist/UI/Components/Pagination/Pagination.js +3 -3
- package/build/dist/UI/Components/Pagination/Pagination.js.map +1 -1
- package/build/dist/UI/Components/ProgressButtons/ProgressButtonItem.js +1 -1
- package/build/dist/UI/Components/ProgressButtons/ProgressButtonItem.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/SideMenu.js +4 -1
- package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js +3 -1
- package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceList.js +6 -6
- package/build/dist/UI/Components/StatusPage/ResourceList.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetValueRow.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js +1 -1
- package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentsModal.js +2 -2
- package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/StepTraceViewer.js +1 -1
- package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -1
- package/build/dist/UI/Utils/Navigation.js +66 -33
- package/build/dist/UI/Utils/Navigation.js.map +1 -1
- package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js +7 -0
- package/build/dist/UI/Utils/Telemetry/TelemetryEntityNames.js.map +1 -1
- package/build/dist/UI/Utils/TelemetryService.js +3 -2
- package/build/dist/UI/Utils/TelemetryService.js.map +1 -1
- package/build/dist/Utils/LabelRuleImportExport.js +2 -0
- package/build/dist/Utils/LabelRuleImportExport.js.map +1 -1
- package/build/dist/Utils/MetricUnitUtil.js +77 -13
- package/build/dist/Utils/MetricUnitUtil.js.map +1 -1
- package/build/dist/Utils/Monitor/MetricValueFormatter.js +58 -13
- package/build/dist/Utils/Monitor/MetricValueFormatter.js.map +1 -1
- package/build/dist/Utils/Monitor/PlatformMetricUnitUtil.js +161 -0
- package/build/dist/Utils/Monitor/PlatformMetricUnitUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/PlatformResourceIdentity.js +323 -0
- package/build/dist/Utils/Monitor/PlatformResourceIdentity.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.js +270 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveredHostNamingDiagnosis.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js +23 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js +61 -0
- package/build/dist/Utils/NetworkDiscovery/NetbiosNameUtil.js.map +1 -1
- package/build/dist/Utils/Telemetry/DatabaseServerEntityKeys.js +178 -0
- package/build/dist/Utils/Telemetry/DatabaseServerEntityKeys.js.map +1 -0
- package/build/dist/Utils/Telemetry/EntityKey.js +133 -0
- package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
- package/build/dist/Utils/ValueFormatter.js +15 -0
- package/build/dist/Utils/ValueFormatter.js.map +1 -1
- package/package.json +1 -1
- package/tsconfig.tests.json +7 -5
|
@@ -0,0 +1,1518 @@
|
|
|
1
|
+
import MonitorStep from "./MonitorStep";
|
|
2
|
+
import MonitorCriteria from "./MonitorCriteria";
|
|
3
|
+
import FilterCondition from "../Filter/FilterCondition";
|
|
4
|
+
import { EvaluateOverTimeType, FilterType } from "./CriteriaFilter";
|
|
5
|
+
import MonitorType from "./MonitorType";
|
|
6
|
+
import RollingTime from "../RollingTime/RollingTime";
|
|
7
|
+
import MetricsAggregationType from "../Metrics/MetricsAggregationType";
|
|
8
|
+
import { getDatabaseSystemDescriptor, } from "../DatabaseServer/DatabaseSystem";
|
|
9
|
+
import { buildHealthyCriteriaInstance, buildUnhealthyCriteriaInstance, getRecoveryFilterType, } from "./Recommendation/RecommendationCriteriaBuilder";
|
|
10
|
+
/*
|
|
11
|
+
* The attribute ingest stamps on every row of a database's own telemetry, and
|
|
12
|
+
* the one every template query filters on. Kept as a literal here rather than
|
|
13
|
+
* imported from the server-side ingest code: Types must stay isomorphic.
|
|
14
|
+
*/
|
|
15
|
+
export const DATABASE_SERVER_ID_SCOPE_ATTRIBUTE = "oneuptime.database.server.id";
|
|
16
|
+
/*
|
|
17
|
+
* Every metric a template reads, verified against the v0.161.0
|
|
18
|
+
* `metadata.yaml` of each receiver (name, instrument, monotonicity, unit,
|
|
19
|
+
* default enablement). The datapoint attribute filters the templates use are
|
|
20
|
+
* the receivers' stored attribute names (`kind`, `status`, `type`,
|
|
21
|
+
* `operation`), which is what ingest writes into the row's attribute map.
|
|
22
|
+
*/
|
|
23
|
+
export const DATABASE_ALERT_METRICS = [
|
|
24
|
+
// PostgreSQL — postgresqlreceiver.
|
|
25
|
+
{
|
|
26
|
+
engine: "postgresql",
|
|
27
|
+
receiver: "postgresql",
|
|
28
|
+
metricName: "postgresql.backends",
|
|
29
|
+
kind: "gauge",
|
|
30
|
+
unit: "1",
|
|
31
|
+
enabledByDefault: true,
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
engine: "postgresql",
|
|
35
|
+
receiver: "postgresql",
|
|
36
|
+
metricName: "postgresql.connection.max",
|
|
37
|
+
kind: "gauge",
|
|
38
|
+
unit: "{connections}",
|
|
39
|
+
enabledByDefault: true,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
engine: "postgresql",
|
|
43
|
+
receiver: "postgresql",
|
|
44
|
+
/*
|
|
45
|
+
* Not postgresql.wal.lag: the `postgresqlreceiver.preciselagmetrics`
|
|
46
|
+
* gate is beta (on by default) in 0.161.0, and under it the receiver
|
|
47
|
+
* records this metric INSTEAD — so wal.lag never arrives (see the
|
|
48
|
+
* module header).
|
|
49
|
+
*/
|
|
50
|
+
metricName: "postgresql.wal.delay",
|
|
51
|
+
kind: "gauge",
|
|
52
|
+
unit: "s",
|
|
53
|
+
enabledByDefault: false,
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
engine: "postgresql",
|
|
57
|
+
receiver: "postgresql",
|
|
58
|
+
metricName: "postgresql.replication.data_delay",
|
|
59
|
+
kind: "gauge",
|
|
60
|
+
unit: "By",
|
|
61
|
+
enabledByDefault: true,
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
engine: "postgresql",
|
|
65
|
+
receiver: "postgresql",
|
|
66
|
+
metricName: "postgresql.db_size",
|
|
67
|
+
kind: "gauge",
|
|
68
|
+
unit: "By",
|
|
69
|
+
enabledByDefault: true,
|
|
70
|
+
},
|
|
71
|
+
// MySQL / MariaDB — mysqlreceiver.
|
|
72
|
+
{
|
|
73
|
+
engine: "mysql",
|
|
74
|
+
receiver: "mysql",
|
|
75
|
+
metricName: "mysql.threads",
|
|
76
|
+
kind: "gauge",
|
|
77
|
+
unit: "1",
|
|
78
|
+
enabledByDefault: true,
|
|
79
|
+
},
|
|
80
|
+
/*
|
|
81
|
+
* Page counts, not the byte metrics mysql.buffer_pool.usage / .limit:
|
|
82
|
+
* MariaDB reports mysql.buffer_pool.limit as a page count (see the module
|
|
83
|
+
* header), while these two mean the same on MySQL and MariaDB.
|
|
84
|
+
*/
|
|
85
|
+
{
|
|
86
|
+
engine: "mysql",
|
|
87
|
+
receiver: "mysql",
|
|
88
|
+
metricName: "mysql.buffer_pool.data_pages",
|
|
89
|
+
kind: "gauge",
|
|
90
|
+
unit: "1",
|
|
91
|
+
enabledByDefault: true,
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
engine: "mysql",
|
|
95
|
+
receiver: "mysql",
|
|
96
|
+
metricName: "mysql.buffer_pool.pages",
|
|
97
|
+
kind: "gauge",
|
|
98
|
+
unit: "1",
|
|
99
|
+
enabledByDefault: true,
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
engine: "mysql",
|
|
103
|
+
receiver: "mysql",
|
|
104
|
+
metricName: "mysql.replica.time_behind_source",
|
|
105
|
+
kind: "gauge",
|
|
106
|
+
unit: "s",
|
|
107
|
+
enabledByDefault: false,
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
engine: "mysql",
|
|
111
|
+
receiver: "mysql",
|
|
112
|
+
metricName: "mysql.uptime",
|
|
113
|
+
kind: "elapsed",
|
|
114
|
+
unit: "s",
|
|
115
|
+
enabledByDefault: true,
|
|
116
|
+
},
|
|
117
|
+
// Redis / Valkey — redisreceiver.
|
|
118
|
+
{
|
|
119
|
+
engine: "redis",
|
|
120
|
+
receiver: "redis",
|
|
121
|
+
metricName: "redis.memory.used",
|
|
122
|
+
kind: "gauge",
|
|
123
|
+
unit: "By",
|
|
124
|
+
enabledByDefault: true,
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
engine: "redis",
|
|
128
|
+
receiver: "redis",
|
|
129
|
+
metricName: "redis.maxmemory",
|
|
130
|
+
kind: "gauge",
|
|
131
|
+
unit: "By",
|
|
132
|
+
enabledByDefault: false,
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
engine: "redis",
|
|
136
|
+
receiver: "redis",
|
|
137
|
+
metricName: "redis.memory.fragmentation_ratio",
|
|
138
|
+
kind: "gauge",
|
|
139
|
+
unit: "1",
|
|
140
|
+
enabledByDefault: true,
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
engine: "redis",
|
|
144
|
+
receiver: "redis",
|
|
145
|
+
metricName: "redis.clients.connected",
|
|
146
|
+
kind: "gauge",
|
|
147
|
+
unit: "{client}",
|
|
148
|
+
enabledByDefault: true,
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
engine: "redis",
|
|
152
|
+
receiver: "redis",
|
|
153
|
+
metricName: "redis.uptime",
|
|
154
|
+
kind: "elapsed",
|
|
155
|
+
unit: "s",
|
|
156
|
+
enabledByDefault: true,
|
|
157
|
+
},
|
|
158
|
+
// MongoDB — mongodbreceiver.
|
|
159
|
+
{
|
|
160
|
+
engine: "mongodb",
|
|
161
|
+
receiver: "mongodb",
|
|
162
|
+
metricName: "mongodb.connection.count",
|
|
163
|
+
kind: "gauge",
|
|
164
|
+
unit: "{connections}",
|
|
165
|
+
enabledByDefault: true,
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
engine: "mongodb",
|
|
169
|
+
receiver: "mongodb",
|
|
170
|
+
metricName: "mongodb.uptime",
|
|
171
|
+
kind: "elapsed",
|
|
172
|
+
unit: "ms",
|
|
173
|
+
enabledByDefault: false,
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
engine: "mongodb",
|
|
177
|
+
receiver: "mongodb",
|
|
178
|
+
metricName: "mongodb.database.count",
|
|
179
|
+
kind: "gauge",
|
|
180
|
+
unit: "{databases}",
|
|
181
|
+
enabledByDefault: true,
|
|
182
|
+
},
|
|
183
|
+
/*
|
|
184
|
+
* SQL Server — sqlserverreceiver, connected directly. Each of these is a
|
|
185
|
+
* point-in-time value in sys.dm_os_performance_counters (the hit ratio is
|
|
186
|
+
* computed against its base counter), unlike the "/sec" counters, which
|
|
187
|
+
* arrive as since-start totals (see the module header).
|
|
188
|
+
*/
|
|
189
|
+
{
|
|
190
|
+
engine: "microsoft.sql_server",
|
|
191
|
+
receiver: "sqlserver",
|
|
192
|
+
metricName: "sqlserver.page.buffer_cache.hit_ratio",
|
|
193
|
+
kind: "gauge",
|
|
194
|
+
unit: "%",
|
|
195
|
+
enabledByDefault: true,
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
engine: "microsoft.sql_server",
|
|
199
|
+
receiver: "sqlserver",
|
|
200
|
+
metricName: "sqlserver.page.life_expectancy",
|
|
201
|
+
kind: "gauge",
|
|
202
|
+
unit: "s",
|
|
203
|
+
enabledByDefault: true,
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
engine: "microsoft.sql_server",
|
|
207
|
+
receiver: "sqlserver",
|
|
208
|
+
metricName: "sqlserver.processes.blocked",
|
|
209
|
+
kind: "gauge",
|
|
210
|
+
unit: "{processes}",
|
|
211
|
+
enabledByDefault: false,
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
engine: "microsoft.sql_server",
|
|
215
|
+
receiver: "sqlserver",
|
|
216
|
+
// A non-monotonic sum: a gauge in all but name.
|
|
217
|
+
metricName: "sqlserver.memory.grants.pending.count",
|
|
218
|
+
kind: "gauge",
|
|
219
|
+
unit: "{grants}",
|
|
220
|
+
enabledByDefault: false,
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
engine: "microsoft.sql_server",
|
|
224
|
+
receiver: "sqlserver",
|
|
225
|
+
metricName: "sqlserver.user.connection.count",
|
|
226
|
+
kind: "gauge",
|
|
227
|
+
unit: "{connections}",
|
|
228
|
+
enabledByDefault: true,
|
|
229
|
+
},
|
|
230
|
+
// Oracle — oracledbreceiver.
|
|
231
|
+
{
|
|
232
|
+
engine: "oracle.db",
|
|
233
|
+
receiver: "oracledb",
|
|
234
|
+
metricName: "oracledb.sessions.usage",
|
|
235
|
+
kind: "gauge",
|
|
236
|
+
unit: "{sessions}",
|
|
237
|
+
enabledByDefault: true,
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
engine: "oracle.db",
|
|
241
|
+
receiver: "oracledb",
|
|
242
|
+
// A 0..1 share of the tablespace's maximum size.
|
|
243
|
+
metricName: "oracledb.tablespace.utilization",
|
|
244
|
+
kind: "gauge",
|
|
245
|
+
unit: "1",
|
|
246
|
+
enabledByDefault: false,
|
|
247
|
+
},
|
|
248
|
+
// Elasticsearch — elasticsearchreceiver.
|
|
249
|
+
{
|
|
250
|
+
engine: "elasticsearch",
|
|
251
|
+
receiver: "elasticsearch",
|
|
252
|
+
metricName: "elasticsearch.cluster.health",
|
|
253
|
+
kind: "gauge",
|
|
254
|
+
unit: "{status}",
|
|
255
|
+
enabledByDefault: true,
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
engine: "elasticsearch",
|
|
259
|
+
receiver: "elasticsearch",
|
|
260
|
+
metricName: "elasticsearch.cluster.pending_tasks",
|
|
261
|
+
kind: "gauge",
|
|
262
|
+
unit: "{tasks}",
|
|
263
|
+
enabledByDefault: true,
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
engine: "elasticsearch",
|
|
267
|
+
receiver: "elasticsearch",
|
|
268
|
+
/*
|
|
269
|
+
* A 0..1 share of the node's heap maximum, recorded per node only. Not
|
|
270
|
+
* jvm.memory.heap.used / heap.max: the receiver records heap.used a
|
|
271
|
+
* second time, for the whole cluster, in the same scrape (see the
|
|
272
|
+
* aggregation contract in the module header).
|
|
273
|
+
*/
|
|
274
|
+
metricName: "jvm.memory.heap.utilization",
|
|
275
|
+
kind: "gauge",
|
|
276
|
+
unit: "1",
|
|
277
|
+
enabledByDefault: false,
|
|
278
|
+
},
|
|
279
|
+
// Memcached — memcachedreceiver.
|
|
280
|
+
{
|
|
281
|
+
engine: "memcached",
|
|
282
|
+
receiver: "memcached",
|
|
283
|
+
metricName: "memcached.connections.current",
|
|
284
|
+
kind: "gauge",
|
|
285
|
+
unit: "{connections}",
|
|
286
|
+
enabledByDefault: true,
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
engine: "memcached",
|
|
290
|
+
receiver: "memcached",
|
|
291
|
+
metricName: "memcached.threads",
|
|
292
|
+
kind: "gauge",
|
|
293
|
+
unit: "{threads}",
|
|
294
|
+
enabledByDefault: true,
|
|
295
|
+
},
|
|
296
|
+
// CouchDB — couchdbreceiver.
|
|
297
|
+
{
|
|
298
|
+
engine: "couchdb",
|
|
299
|
+
receiver: "couchdb",
|
|
300
|
+
metricName: "couchdb.average_request_time",
|
|
301
|
+
kind: "gauge",
|
|
302
|
+
unit: "ms",
|
|
303
|
+
enabledByDefault: true,
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
engine: "couchdb",
|
|
307
|
+
receiver: "couchdb",
|
|
308
|
+
metricName: "couchdb.database.open",
|
|
309
|
+
kind: "gauge",
|
|
310
|
+
unit: "{databases}",
|
|
311
|
+
enabledByDefault: true,
|
|
312
|
+
},
|
|
313
|
+
];
|
|
314
|
+
/*
|
|
315
|
+
* The alert-worthy signals a team will ask for first, and why none of them is
|
|
316
|
+
* a template. Every one is a cumulative monotonic counter (verified against
|
|
317
|
+
* the v0.161.0 receiver metadata) — or, like SQL Server's deadlock "rate",
|
|
318
|
+
* a gauge whose value on the agent's direct connection is the since-start
|
|
319
|
+
* total — so the monitor path, which has no rate, can only compare its
|
|
320
|
+
* since-restart total against a threshold. They remain visible on the
|
|
321
|
+
* database's Metrics tab.
|
|
322
|
+
*
|
|
323
|
+
* The honest workaround for a team that needs one of these alerted today is
|
|
324
|
+
* a `cumulativetodelta` processor in its collector pipeline, which turns the
|
|
325
|
+
* counter into per-interval deltas that a Sum over the window does threshold
|
|
326
|
+
* correctly. That processor only converts sums, so it leaves SQL Server's
|
|
327
|
+
* deadlock total (typed a gauge) as it is.
|
|
328
|
+
*/
|
|
329
|
+
export const UNALERTABLE_DATABASE_COUNTERS = [
|
|
330
|
+
{
|
|
331
|
+
engine: "postgresql",
|
|
332
|
+
metricName: "postgresql.deadlocks",
|
|
333
|
+
wouldAlertOn: "deadlocks",
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
engine: "postgresql",
|
|
337
|
+
metricName: "postgresql.rollbacks",
|
|
338
|
+
wouldAlertOn: "a rollback spike",
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
engine: "mysql",
|
|
342
|
+
metricName: "mysql.query.slow.count",
|
|
343
|
+
wouldAlertOn: "slow queries",
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
engine: "mysql",
|
|
347
|
+
metricName: "mysql.connection.errors",
|
|
348
|
+
wouldAlertOn: "connections refused at max_connections",
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
engine: "redis",
|
|
352
|
+
metricName: "redis.connections.rejected",
|
|
353
|
+
wouldAlertOn: "connections rejected at maxclients",
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
engine: "redis",
|
|
357
|
+
metricName: "redis.keys.evicted",
|
|
358
|
+
wouldAlertOn: "evictions",
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
engine: "mongodb",
|
|
362
|
+
metricName: "mongodb.lock.deadlock.count",
|
|
363
|
+
wouldAlertOn: "lock deadlocks",
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
engine: "microsoft.sql_server",
|
|
367
|
+
metricName: "sqlserver.deadlock.rate",
|
|
368
|
+
wouldAlertOn: "deadlocks",
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
engine: "oracle.db",
|
|
372
|
+
metricName: "oracledb.enqueue_deadlocks",
|
|
373
|
+
wouldAlertOn: "enqueue deadlocks",
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
engine: "elasticsearch",
|
|
377
|
+
metricName: "elasticsearch.breaker.tripped",
|
|
378
|
+
wouldAlertOn: "circuit breakers tripping",
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
engine: "memcached",
|
|
382
|
+
metricName: "memcached.evictions",
|
|
383
|
+
wouldAlertOn: "evictions",
|
|
384
|
+
},
|
|
385
|
+
];
|
|
386
|
+
export function getDatabaseAlertMetric(metricName) {
|
|
387
|
+
return DATABASE_ALERT_METRICS.find((metric) => {
|
|
388
|
+
return metric.metricName === metricName;
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
/*
|
|
392
|
+
* "mysql.threads (kind = running)" — a query as the criteria description
|
|
393
|
+
* names it. The database scope is left out: every query carries it, and it
|
|
394
|
+
* is an id nobody reads.
|
|
395
|
+
*/
|
|
396
|
+
function describeQuery(query) {
|
|
397
|
+
const filters = Object.keys(query.attributes || {}).map((key) => {
|
|
398
|
+
return `${key} = ${(query.attributes || {})[key]}`;
|
|
399
|
+
});
|
|
400
|
+
return filters.length > 0
|
|
401
|
+
? `${query.metricName} (${filters.join(", ")})`
|
|
402
|
+
: query.metricName;
|
|
403
|
+
}
|
|
404
|
+
function describeCriteria(data) {
|
|
405
|
+
if (data.criteria.triggerOnNoData) {
|
|
406
|
+
return `Triggers when ${data.subject} reports no data for the whole evaluation window.`;
|
|
407
|
+
}
|
|
408
|
+
if (data.criteria.evaluation === EvaluateOverTimeType.AnyValue) {
|
|
409
|
+
return `Triggers when ${data.subject} reads ${data.criteria.thresholdLabel} at any point in the evaluation window.`;
|
|
410
|
+
}
|
|
411
|
+
const alsoRequired = data.criteria.additionalFilter
|
|
412
|
+
? `, while ${data.criteria.additionalFilter.label}`
|
|
413
|
+
: "";
|
|
414
|
+
return `Triggers when ${data.subject} stays ${data.criteria.thresholdLabel} for the whole evaluation window${alsoRequired}.`;
|
|
415
|
+
}
|
|
416
|
+
/*
|
|
417
|
+
* One query of a database template. The database scope is added HERE, to
|
|
418
|
+
* every query, rather than by each template — a template that forgot it would
|
|
419
|
+
* watch the whole project and attach its alerts to nothing.
|
|
420
|
+
*/
|
|
421
|
+
function buildDatabaseQuery(data) {
|
|
422
|
+
return {
|
|
423
|
+
metricAliasData: {
|
|
424
|
+
metricVariable: data.spec.alias,
|
|
425
|
+
title: data.title,
|
|
426
|
+
description: data.title,
|
|
427
|
+
legend: data.title,
|
|
428
|
+
legendUnit: data.spec.legendUnit,
|
|
429
|
+
},
|
|
430
|
+
metricQueryData: {
|
|
431
|
+
filterData: {
|
|
432
|
+
metricName: data.spec.metricName,
|
|
433
|
+
attributes: Object.assign(Object.assign({}, (data.spec.attributes || {})), { [DATABASE_SERVER_ID_SCOPE_ATTRIBUTE]: data.databaseServerId }),
|
|
434
|
+
aggegationType: data.spec.aggregationType,
|
|
435
|
+
aggregateBy: {},
|
|
436
|
+
},
|
|
437
|
+
},
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
function buildDatabaseCriteria(data) {
|
|
441
|
+
const criteria = data.criteria;
|
|
442
|
+
const incidentTitle = `[Database] ${data.templateName} - ${data.args.monitorName}`;
|
|
443
|
+
const additionalFilter = criteria.additionalFilter
|
|
444
|
+
? {
|
|
445
|
+
metricAlias: criteria.additionalFilter.metricAlias,
|
|
446
|
+
filterType: criteria.additionalFilter.filterType,
|
|
447
|
+
value: criteria.additionalFilter.value,
|
|
448
|
+
}
|
|
449
|
+
: undefined;
|
|
450
|
+
const unhealthy = buildUnhealthyCriteriaInstance({
|
|
451
|
+
offlineMonitorStatusId: data.args.offlineMonitorStatusId,
|
|
452
|
+
incidentSeverityId: data.args.defaultIncidentSeverityId,
|
|
453
|
+
alertSeverityId: data.args.defaultAlertSeverityId,
|
|
454
|
+
monitorName: data.args.monitorName,
|
|
455
|
+
metricAlias: criteria.metricAlias,
|
|
456
|
+
filterType: criteria.filterType,
|
|
457
|
+
value: criteria.threshold,
|
|
458
|
+
incidentTitle: incidentTitle,
|
|
459
|
+
incidentDescription: criteria.incidentDescription,
|
|
460
|
+
criteriaName: `${data.templateName} - ${criteria.thresholdLabel}`,
|
|
461
|
+
criteriaDescription: describeCriteria({
|
|
462
|
+
subject: data.subject,
|
|
463
|
+
criteria: criteria,
|
|
464
|
+
}),
|
|
465
|
+
resourceNoun: "database",
|
|
466
|
+
metricAggregationType: criteria.evaluation,
|
|
467
|
+
triggerOnNoData: criteria.triggerOnNoData,
|
|
468
|
+
additionalFilters: additionalFilter ? [additionalFilter] : undefined,
|
|
469
|
+
filterCondition: additionalFilter ? FilterCondition.All : undefined,
|
|
470
|
+
});
|
|
471
|
+
/*
|
|
472
|
+
* Recovery mirrors the breach: the complementary comparison, the same
|
|
473
|
+
* sustained evaluation, and — for a two-condition breach — Any, so the
|
|
474
|
+
* monitor is healthy again as soon as EITHER condition has cleared.
|
|
475
|
+
*/
|
|
476
|
+
const healthy = buildHealthyCriteriaInstance({
|
|
477
|
+
onlineMonitorStatusId: data.args.onlineMonitorStatusId,
|
|
478
|
+
metricAlias: criteria.metricAlias,
|
|
479
|
+
filterType: getRecoveryFilterType(criteria.filterType),
|
|
480
|
+
value: criteria.threshold,
|
|
481
|
+
isBinaryMetric: criteria.isBinaryMetric,
|
|
482
|
+
metricAggregationType: criteria.evaluation === EvaluateOverTimeType.AnyValue
|
|
483
|
+
? EvaluateOverTimeType.AllValues
|
|
484
|
+
: criteria.evaluation,
|
|
485
|
+
additionalFilters: additionalFilter
|
|
486
|
+
? [
|
|
487
|
+
{
|
|
488
|
+
metricAlias: additionalFilter.metricAlias,
|
|
489
|
+
filterType: getRecoveryFilterType(additionalFilter.filterType),
|
|
490
|
+
value: additionalFilter.value,
|
|
491
|
+
},
|
|
492
|
+
]
|
|
493
|
+
: undefined,
|
|
494
|
+
filterCondition: additionalFilter ? FilterCondition.Any : undefined,
|
|
495
|
+
});
|
|
496
|
+
const monitorCriteria = new MonitorCriteria();
|
|
497
|
+
monitorCriteria.data = {
|
|
498
|
+
monitorCriteriaInstanceArray: [unhealthy, healthy],
|
|
499
|
+
};
|
|
500
|
+
return monitorCriteria;
|
|
501
|
+
}
|
|
502
|
+
function buildDatabaseTemplate(spec) {
|
|
503
|
+
return {
|
|
504
|
+
id: spec.id,
|
|
505
|
+
name: spec.name,
|
|
506
|
+
description: spec.description,
|
|
507
|
+
category: spec.category,
|
|
508
|
+
severity: spec.severity,
|
|
509
|
+
monitorType: MonitorType.Metrics,
|
|
510
|
+
engine: spec.engine.engine,
|
|
511
|
+
receiver: spec.engine.receiver,
|
|
512
|
+
metricNames: spec.queries.map((query) => {
|
|
513
|
+
return query.metricName;
|
|
514
|
+
}),
|
|
515
|
+
getMonitorStep: (args) => {
|
|
516
|
+
const step = MonitorStep.getDefaultMonitorStep({
|
|
517
|
+
monitorName: args.monitorName,
|
|
518
|
+
monitorType: MonitorType.Metrics,
|
|
519
|
+
onlineMonitorStatusId: args.onlineMonitorStatusId,
|
|
520
|
+
offlineMonitorStatusId: args.offlineMonitorStatusId,
|
|
521
|
+
defaultIncidentSeverityId: args.defaultIncidentSeverityId,
|
|
522
|
+
defaultAlertSeverityId: args.defaultAlertSeverityId,
|
|
523
|
+
});
|
|
524
|
+
const formulaConfigs = spec.formula
|
|
525
|
+
? [
|
|
526
|
+
{
|
|
527
|
+
metricAliasData: {
|
|
528
|
+
metricVariable: spec.formula.alias,
|
|
529
|
+
title: spec.name,
|
|
530
|
+
description: spec.name,
|
|
531
|
+
legend: spec.name,
|
|
532
|
+
legendUnit: spec.formula.legendUnit,
|
|
533
|
+
},
|
|
534
|
+
metricFormulaData: {
|
|
535
|
+
metricFormula: spec.formula.expression,
|
|
536
|
+
},
|
|
537
|
+
},
|
|
538
|
+
]
|
|
539
|
+
: [];
|
|
540
|
+
step.setMetricMonitor({
|
|
541
|
+
rollingTime: spec.rollingTime || RollingTime.Past5Minutes,
|
|
542
|
+
metricViewConfig: {
|
|
543
|
+
queryConfigs: spec.queries.map((query) => {
|
|
544
|
+
return buildDatabaseQuery({
|
|
545
|
+
spec: query,
|
|
546
|
+
databaseServerId: args.databaseServerId,
|
|
547
|
+
title: spec.queries.length > 1
|
|
548
|
+
? `${spec.name} (${query.alias})`
|
|
549
|
+
: spec.name,
|
|
550
|
+
});
|
|
551
|
+
}),
|
|
552
|
+
formulaConfigs: formulaConfigs,
|
|
553
|
+
},
|
|
554
|
+
});
|
|
555
|
+
step.setMonitorCriteria(buildDatabaseCriteria({
|
|
556
|
+
args: args,
|
|
557
|
+
templateName: spec.name,
|
|
558
|
+
subject: getCriteriaSubject(spec),
|
|
559
|
+
criteria: spec.criteria,
|
|
560
|
+
}));
|
|
561
|
+
return step;
|
|
562
|
+
},
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
/*
|
|
566
|
+
* What the criteria compares, for its description: the explicit subject when
|
|
567
|
+
* the template gave one, else the query the criteria's alias names.
|
|
568
|
+
*/
|
|
569
|
+
function getCriteriaSubject(spec) {
|
|
570
|
+
if (spec.criteria.subject) {
|
|
571
|
+
return spec.criteria.subject;
|
|
572
|
+
}
|
|
573
|
+
const query = spec.queries.find((candidate) => {
|
|
574
|
+
return candidate.alias === spec.criteria.metricAlias;
|
|
575
|
+
});
|
|
576
|
+
return query ? describeQuery(query) : spec.name;
|
|
577
|
+
}
|
|
578
|
+
/*
|
|
579
|
+
* `(numerator / denominator) * 100` over two Sum queries — see the
|
|
580
|
+
* aggregation contract in the module header for why Sum is right for a
|
|
581
|
+
* same-scrape ratio.
|
|
582
|
+
*/
|
|
583
|
+
function buildPercentOfLimitTemplate(data) {
|
|
584
|
+
return buildDatabaseTemplate({
|
|
585
|
+
id: data.id,
|
|
586
|
+
name: data.name,
|
|
587
|
+
description: data.description,
|
|
588
|
+
category: data.category,
|
|
589
|
+
severity: data.severity,
|
|
590
|
+
engine: data.engine,
|
|
591
|
+
queries: [data.numerator, data.denominator],
|
|
592
|
+
formula: {
|
|
593
|
+
alias: data.resultAlias,
|
|
594
|
+
expression: `(${data.numerator.alias} / ${data.denominator.alias}) * 100`,
|
|
595
|
+
legendUnit: "%",
|
|
596
|
+
},
|
|
597
|
+
rollingTime: data.rollingTime,
|
|
598
|
+
criteria: {
|
|
599
|
+
metricAlias: data.resultAlias,
|
|
600
|
+
filterType: FilterType.GreaterThanOrEqualTo,
|
|
601
|
+
threshold: data.thresholdPercent,
|
|
602
|
+
thresholdLabel: `at or above ${data.thresholdPercent}%`,
|
|
603
|
+
subject: `${describeQuery(data.numerator)} as a percentage of ${describeQuery(data.denominator)}`,
|
|
604
|
+
incidentDescription: data.incidentDescription,
|
|
605
|
+
},
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
/*
|
|
609
|
+
* The engine's own metrics stopped arriving.
|
|
610
|
+
*
|
|
611
|
+
* A database receiver that cannot connect — the server is down, refusing
|
|
612
|
+
* logins, or out of connection slots — emits nothing at all, and so does a
|
|
613
|
+
* collector that stopped. The absence is the only telemetry-side signal of
|
|
614
|
+
* either, so this is the closest thing to "database down" engine metrics can
|
|
615
|
+
* express. `metricName` is a metric the receiver emits once per successful
|
|
616
|
+
* scrape; the threshold (`< 0`) is unreachable on purpose, so the criteria
|
|
617
|
+
* only ever fires through its no-data policy.
|
|
618
|
+
*
|
|
619
|
+
* Offered only to a database whose engine metrics have been seen at least
|
|
620
|
+
* once (see MonitorRecommendationContext.databaseEngineMetricsReported) —
|
|
621
|
+
* on a database that has never reported them it would fire the moment it was
|
|
622
|
+
* created.
|
|
623
|
+
*/
|
|
624
|
+
function buildEngineMetricsStoppedTemplate(data) {
|
|
625
|
+
return buildDatabaseTemplate({
|
|
626
|
+
id: data.id,
|
|
627
|
+
name: "Engine Metrics Stopped",
|
|
628
|
+
description: `Alert when no ${data.engine.displayName} engine metrics arrive for ten minutes — the server is down or refusing the collector's login, or the Database Agent / collector itself stopped. Reads ${data.metricName}, which the receiver emits on every successful scrape.`,
|
|
629
|
+
category: "Availability",
|
|
630
|
+
severity: "Critical",
|
|
631
|
+
engine: data.engine,
|
|
632
|
+
queries: [
|
|
633
|
+
{
|
|
634
|
+
alias: data.metricAlias,
|
|
635
|
+
metricName: data.metricName,
|
|
636
|
+
aggregationType: MetricsAggregationType.Count,
|
|
637
|
+
},
|
|
638
|
+
],
|
|
639
|
+
rollingTime: RollingTime.Past10Minutes,
|
|
640
|
+
criteria: {
|
|
641
|
+
metricAlias: data.metricAlias,
|
|
642
|
+
filterType: FilterType.LessThan,
|
|
643
|
+
threshold: 0,
|
|
644
|
+
thresholdLabel: "silent (no data)",
|
|
645
|
+
triggerOnNoData: true,
|
|
646
|
+
incidentDescription: `No ${data.engine.displayName} engine metrics have arrived for ten minutes. Check, in order: whether the database accepts connections at all, whether the collector's login still works (password rotation and connection limits are the usual causes — the collector log names the error), and whether the Database Agent or collector process is running.`,
|
|
647
|
+
},
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
/*
|
|
651
|
+
* A low uptime is a restart. `Min` per bucket, so a bucket spanning the
|
|
652
|
+
* restart reads the post-restart value rather than the pre-restart one.
|
|
653
|
+
*
|
|
654
|
+
* The one family here that overrides the sustained default: a restart is an
|
|
655
|
+
* EVENT, and requiring every sample of the window to be young would never be
|
|
656
|
+
* true once the window is longer than the restart is old. `AnyValue` fires on
|
|
657
|
+
* the first scrape after the restart and clears once the whole window has
|
|
658
|
+
* aged past the threshold.
|
|
659
|
+
*/
|
|
660
|
+
function buildRestartTemplate(data) {
|
|
661
|
+
return buildDatabaseTemplate({
|
|
662
|
+
id: data.id,
|
|
663
|
+
name: "Server Restarted",
|
|
664
|
+
description: `Alert when the ${data.engine.displayName} server has been up for less than ten minutes — it restarted, crashed and came back, or failed over. Reads ${data.metricName}${data.requiresEnabling
|
|
665
|
+
? ", which the receiver only emits once it is enabled (the Database Agent enables it)"
|
|
666
|
+
: ""}.`,
|
|
667
|
+
category: "Availability",
|
|
668
|
+
severity: "Warning",
|
|
669
|
+
engine: data.engine,
|
|
670
|
+
queries: [
|
|
671
|
+
{
|
|
672
|
+
alias: data.metricAlias,
|
|
673
|
+
metricName: data.metricName,
|
|
674
|
+
aggregationType: MetricsAggregationType.Min,
|
|
675
|
+
},
|
|
676
|
+
],
|
|
677
|
+
rollingTime: RollingTime.Past5Minutes,
|
|
678
|
+
criteria: {
|
|
679
|
+
metricAlias: data.metricAlias,
|
|
680
|
+
filterType: FilterType.LessThan,
|
|
681
|
+
threshold: data.threshold,
|
|
682
|
+
thresholdLabel: "below ten minutes",
|
|
683
|
+
evaluation: EvaluateOverTimeType.AnyValue,
|
|
684
|
+
incidentDescription: `The ${data.engine.displayName} server restarted in the last ten minutes. If nobody restarted it, look for an out-of-memory kill in the host or container logs, then for a crash in the server's own log. A restart empties caches, so expect slower queries until they warm up.`,
|
|
685
|
+
},
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
// --- PostgreSQL ---
|
|
689
|
+
const POSTGRESQL = {
|
|
690
|
+
engine: "postgresql",
|
|
691
|
+
receiver: "postgresql",
|
|
692
|
+
displayName: "PostgreSQL",
|
|
693
|
+
};
|
|
694
|
+
const postgresqlTemplates = [
|
|
695
|
+
buildEngineMetricsStoppedTemplate({
|
|
696
|
+
id: "database-postgresql-engine-metrics-stopped",
|
|
697
|
+
engine: POSTGRESQL,
|
|
698
|
+
metricName: "postgresql.connection.max",
|
|
699
|
+
metricAlias: "pg_heartbeat",
|
|
700
|
+
}),
|
|
701
|
+
buildPercentOfLimitTemplate({
|
|
702
|
+
id: "database-postgresql-connections-exhausted",
|
|
703
|
+
name: "Connections Nearly Exhausted",
|
|
704
|
+
description: 'Alert when backends reach 95% of max_connections. Past 100% PostgreSQL refuses every new connection with "too many clients already".',
|
|
705
|
+
category: "Connections",
|
|
706
|
+
severity: "Critical",
|
|
707
|
+
engine: POSTGRESQL,
|
|
708
|
+
numerator: {
|
|
709
|
+
alias: "pg_backends",
|
|
710
|
+
metricName: "postgresql.backends",
|
|
711
|
+
aggregationType: MetricsAggregationType.Sum,
|
|
712
|
+
},
|
|
713
|
+
denominator: {
|
|
714
|
+
alias: "pg_max_connections",
|
|
715
|
+
metricName: "postgresql.connection.max",
|
|
716
|
+
aggregationType: MetricsAggregationType.Sum,
|
|
717
|
+
},
|
|
718
|
+
resultAlias: "pg_connections_percent_critical",
|
|
719
|
+
thresholdPercent: 95,
|
|
720
|
+
incidentDescription: "PostgreSQL is about to refuse new connections. Look for idle-in-transaction sessions in pg_stat_activity and for an application whose pool grew; a connection pooler such as PgBouncer is the durable fix, raising max_connections the stopgap.",
|
|
721
|
+
}),
|
|
722
|
+
buildPercentOfLimitTemplate({
|
|
723
|
+
id: "database-postgresql-connections-high",
|
|
724
|
+
name: "Connections Above 80% of max_connections",
|
|
725
|
+
description: "Alert when backends stay at 80% of max_connections — the early warning before the connection limit. Backends include autovacuum and parallel workers.",
|
|
726
|
+
category: "Connections",
|
|
727
|
+
severity: "Warning",
|
|
728
|
+
engine: POSTGRESQL,
|
|
729
|
+
numerator: {
|
|
730
|
+
alias: "pg_backends",
|
|
731
|
+
metricName: "postgresql.backends",
|
|
732
|
+
aggregationType: MetricsAggregationType.Sum,
|
|
733
|
+
},
|
|
734
|
+
denominator: {
|
|
735
|
+
alias: "pg_max_connections",
|
|
736
|
+
metricName: "postgresql.connection.max",
|
|
737
|
+
aggregationType: MetricsAggregationType.Sum,
|
|
738
|
+
},
|
|
739
|
+
resultAlias: "pg_connections_percent_warning",
|
|
740
|
+
thresholdPercent: 80,
|
|
741
|
+
rollingTime: RollingTime.Past10Minutes,
|
|
742
|
+
incidentDescription: "PostgreSQL connections have stayed above 80% of max_connections. Find the database and client holding them in pg_stat_activity before the limit is reached.",
|
|
743
|
+
}),
|
|
744
|
+
buildDatabaseTemplate({
|
|
745
|
+
id: "database-postgresql-replica-replay-lag",
|
|
746
|
+
name: "Replica Replay Lag",
|
|
747
|
+
description: "Alert when the slowest replica stays 30 seconds or more behind this primary in replaying WAL. Reads postgresql.wal.delay (operation = replay), which the primary reports per connected replica and the receiver only emits once it is enabled (the Database Agent enables it).",
|
|
748
|
+
category: "Replication",
|
|
749
|
+
severity: "Warning",
|
|
750
|
+
engine: POSTGRESQL,
|
|
751
|
+
queries: [
|
|
752
|
+
{
|
|
753
|
+
alias: "pg_replay_lag",
|
|
754
|
+
metricName: "postgresql.wal.delay",
|
|
755
|
+
aggregationType: MetricsAggregationType.Max,
|
|
756
|
+
attributes: { operation: "replay" },
|
|
757
|
+
},
|
|
758
|
+
],
|
|
759
|
+
criteria: {
|
|
760
|
+
metricAlias: "pg_replay_lag",
|
|
761
|
+
filterType: FilterType.GreaterThanOrEqualTo,
|
|
762
|
+
threshold: 30,
|
|
763
|
+
thresholdLabel: "at or above 30 seconds",
|
|
764
|
+
incidentDescription: "A replica is 30 seconds or more behind the primary, so reads routed to it return stale data and a failover to it would lose those seconds. Check the replica's I/O and CPU, long-running queries on it that conflict with replay, and network throughput between the two.",
|
|
765
|
+
},
|
|
766
|
+
}),
|
|
767
|
+
buildDatabaseTemplate({
|
|
768
|
+
id: "database-postgresql-replication-byte-lag",
|
|
769
|
+
name: "Replication Falling Behind (bytes)",
|
|
770
|
+
description: "Alert when the slowest replica stays 1 GB or more of WAL behind this primary. Catches a replica that is streaming but not keeping up, even while the primary is too idle to report a time lag.",
|
|
771
|
+
category: "Replication",
|
|
772
|
+
severity: "Warning",
|
|
773
|
+
engine: POSTGRESQL,
|
|
774
|
+
queries: [
|
|
775
|
+
{
|
|
776
|
+
alias: "pg_replication_delay",
|
|
777
|
+
metricName: "postgresql.replication.data_delay",
|
|
778
|
+
aggregationType: MetricsAggregationType.Max,
|
|
779
|
+
},
|
|
780
|
+
],
|
|
781
|
+
criteria: {
|
|
782
|
+
metricAlias: "pg_replication_delay",
|
|
783
|
+
filterType: FilterType.GreaterThanOrEqualTo,
|
|
784
|
+
// Decimal, like the byte ladder the alert text formats with: "1 GB".
|
|
785
|
+
threshold: 1000000000,
|
|
786
|
+
thresholdLabel: "at or above 1 GB",
|
|
787
|
+
incidentDescription: "A replica has fallen 1 GB or more of WAL behind. The primary must keep that WAL until the replica catches up, so its disk fills as well; check the replica's disk throughput and the network link.",
|
|
788
|
+
},
|
|
789
|
+
}),
|
|
790
|
+
buildDatabaseTemplate({
|
|
791
|
+
id: "database-postgresql-database-size",
|
|
792
|
+
name: "Database Size Above Budget",
|
|
793
|
+
description: "Alert when the largest database on the server grows past 500 GB. An absolute budget — retune it to the disk the server actually has.",
|
|
794
|
+
category: "Storage",
|
|
795
|
+
severity: "Warning",
|
|
796
|
+
engine: POSTGRESQL,
|
|
797
|
+
queries: [
|
|
798
|
+
{
|
|
799
|
+
alias: "pg_database_size",
|
|
800
|
+
metricName: "postgresql.db_size",
|
|
801
|
+
aggregationType: MetricsAggregationType.Max,
|
|
802
|
+
},
|
|
803
|
+
],
|
|
804
|
+
rollingTime: RollingTime.Past15Minutes,
|
|
805
|
+
criteria: {
|
|
806
|
+
metricAlias: "pg_database_size",
|
|
807
|
+
filterType: FilterType.GreaterThanOrEqualTo,
|
|
808
|
+
// Decimal, like the byte ladder the alert text formats with: "500 GB".
|
|
809
|
+
threshold: 500000000000,
|
|
810
|
+
thresholdLabel: "at or above 500 GB",
|
|
811
|
+
incidentDescription: "A database has grown past its size budget. Check for table and index bloat (autovacuum keeping up?), unbounded tables such as event logs, and how much headroom the volume has left.",
|
|
812
|
+
},
|
|
813
|
+
}),
|
|
814
|
+
];
|
|
815
|
+
// --- MySQL / MariaDB ---
|
|
816
|
+
const MYSQL = {
|
|
817
|
+
engine: "mysql",
|
|
818
|
+
receiver: "mysql",
|
|
819
|
+
displayName: "MySQL",
|
|
820
|
+
};
|
|
821
|
+
const mysqlTemplates = [
|
|
822
|
+
buildEngineMetricsStoppedTemplate({
|
|
823
|
+
id: "database-mysql-engine-metrics-stopped",
|
|
824
|
+
engine: MYSQL,
|
|
825
|
+
metricName: "mysql.uptime",
|
|
826
|
+
metricAlias: "mysql_heartbeat",
|
|
827
|
+
}),
|
|
828
|
+
buildRestartTemplate({
|
|
829
|
+
id: "database-mysql-restarted",
|
|
830
|
+
engine: MYSQL,
|
|
831
|
+
metricName: "mysql.uptime",
|
|
832
|
+
metricAlias: "mysql_uptime",
|
|
833
|
+
threshold: 600,
|
|
834
|
+
}),
|
|
835
|
+
buildDatabaseTemplate({
|
|
836
|
+
id: "database-mysql-connections-high",
|
|
837
|
+
name: "Connections Near max_connections",
|
|
838
|
+
description: "Alert when connected threads stay at 136 or more — 90% of the default max_connections of 151. The receiver reports no max_connections value, so retune this to 90% of the server's own setting.",
|
|
839
|
+
category: "Connections",
|
|
840
|
+
severity: "Warning",
|
|
841
|
+
engine: MYSQL,
|
|
842
|
+
queries: [
|
|
843
|
+
{
|
|
844
|
+
alias: "mysql_threads_connected",
|
|
845
|
+
metricName: "mysql.threads",
|
|
846
|
+
aggregationType: MetricsAggregationType.Max,
|
|
847
|
+
attributes: { kind: "connected" },
|
|
848
|
+
},
|
|
849
|
+
],
|
|
850
|
+
criteria: {
|
|
851
|
+
metricAlias: "mysql_threads_connected",
|
|
852
|
+
filterType: FilterType.GreaterThanOrEqualTo,
|
|
853
|
+
threshold: 136,
|
|
854
|
+
thresholdLabel: "at or above 136 connections",
|
|
855
|
+
incidentDescription: 'MySQL connections are close to max_connections; past it the server answers every new client with "Too many connections". Look at SHOW PROCESSLIST for sleeping connections an application pool is holding.',
|
|
856
|
+
},
|
|
857
|
+
}),
|
|
858
|
+
buildDatabaseTemplate({
|
|
859
|
+
id: "database-mysql-threads-running-high",
|
|
860
|
+
name: "Too Many Running Threads",
|
|
861
|
+
description: "Alert when threads actively executing stay at 50 or more — CPU saturation or lock contention. Retune to about twice the server's vCPU count.",
|
|
862
|
+
category: "Performance",
|
|
863
|
+
severity: "Warning",
|
|
864
|
+
engine: MYSQL,
|
|
865
|
+
queries: [
|
|
866
|
+
{
|
|
867
|
+
alias: "mysql_threads_running",
|
|
868
|
+
metricName: "mysql.threads",
|
|
869
|
+
aggregationType: MetricsAggregationType.Max,
|
|
870
|
+
attributes: { kind: "running" },
|
|
871
|
+
},
|
|
872
|
+
],
|
|
873
|
+
criteria: {
|
|
874
|
+
metricAlias: "mysql_threads_running",
|
|
875
|
+
filterType: FilterType.GreaterThanOrEqualTo,
|
|
876
|
+
threshold: 50,
|
|
877
|
+
thresholdLabel: "at or above 50 threads",
|
|
878
|
+
incidentDescription: "More queries are executing at once than the server can run in parallel, so every one of them slows down. Check for a lock wait chain (SHOW ENGINE INNODB STATUS) and for a query that stopped using its index.",
|
|
879
|
+
},
|
|
880
|
+
}),
|
|
881
|
+
/*
|
|
882
|
+
* Pages over pages, both from the same SHOW GLOBAL STATUS read. Not
|
|
883
|
+
* mysql.buffer_pool.usage (bytes) over mysql.buffer_pool.limit: MariaDB
|
|
884
|
+
* reports limit as a page count, so on MariaDB that ratio read 199,750%
|
|
885
|
+
* for a pool 12% dirty and never cleared.
|
|
886
|
+
*/
|
|
887
|
+
buildPercentOfLimitTemplate({
|
|
888
|
+
id: "database-mysql-buffer-pool-dirty",
|
|
889
|
+
name: "InnoDB Dirty Pages High",
|
|
890
|
+
description: "Alert when dirty pages stay at 75% of the InnoDB buffer pool's pages — page flushing is not keeping up with writes, and a checkpoint stall is next. (A FULL buffer pool is normal; a DIRTY one is not.) Reads page counts, which MySQL and MariaDB report alike.",
|
|
891
|
+
category: "Performance",
|
|
892
|
+
severity: "Warning",
|
|
893
|
+
engine: MYSQL,
|
|
894
|
+
numerator: {
|
|
895
|
+
alias: "mysql_buffer_pool_dirty",
|
|
896
|
+
metricName: "mysql.buffer_pool.data_pages",
|
|
897
|
+
aggregationType: MetricsAggregationType.Sum,
|
|
898
|
+
attributes: { status: "dirty" },
|
|
899
|
+
},
|
|
900
|
+
denominator: {
|
|
901
|
+
alias: "mysql_buffer_pool_size",
|
|
902
|
+
metricName: "mysql.buffer_pool.pages",
|
|
903
|
+
aggregationType: MetricsAggregationType.Sum,
|
|
904
|
+
// The metric also carries kind data, free and misc: parts of total.
|
|
905
|
+
attributes: { kind: "total" },
|
|
906
|
+
},
|
|
907
|
+
resultAlias: "mysql_buffer_pool_dirty_percent",
|
|
908
|
+
thresholdPercent: 75,
|
|
909
|
+
rollingTime: RollingTime.Past10Minutes,
|
|
910
|
+
incidentDescription: "Most of the InnoDB buffer pool is dirty, so InnoDB will soon stall writes to force a checkpoint. Check disk write latency and innodb_io_capacity, and whether a bulk load is running.",
|
|
911
|
+
}),
|
|
912
|
+
buildDatabaseTemplate({
|
|
913
|
+
id: "database-mysql-replica-lag",
|
|
914
|
+
name: "Replica Lag",
|
|
915
|
+
description: "Alert when this replica stays 30 seconds or more behind its source. Reads mysql.replica.time_behind_source, which the receiver only emits once it is enabled (the Database Agent enables it).",
|
|
916
|
+
category: "Replication",
|
|
917
|
+
severity: "Warning",
|
|
918
|
+
engine: MYSQL,
|
|
919
|
+
queries: [
|
|
920
|
+
{
|
|
921
|
+
alias: "mysql_replica_lag",
|
|
922
|
+
metricName: "mysql.replica.time_behind_source",
|
|
923
|
+
aggregationType: MetricsAggregationType.Max,
|
|
924
|
+
},
|
|
925
|
+
],
|
|
926
|
+
criteria: {
|
|
927
|
+
metricAlias: "mysql_replica_lag",
|
|
928
|
+
filterType: FilterType.GreaterThanOrEqualTo,
|
|
929
|
+
threshold: 30,
|
|
930
|
+
thresholdLabel: "at or above 30 seconds",
|
|
931
|
+
incidentDescription: "This replica is 30 seconds or more behind its source, so reads from it are stale. Check SHOW REPLICA STATUS for a long-running statement on the SQL thread, and the replica's disk and CPU.",
|
|
932
|
+
},
|
|
933
|
+
}),
|
|
934
|
+
];
|
|
935
|
+
// --- Redis / Valkey ---
|
|
936
|
+
const REDIS = {
|
|
937
|
+
engine: "redis",
|
|
938
|
+
receiver: "redis",
|
|
939
|
+
displayName: "Redis",
|
|
940
|
+
};
|
|
941
|
+
const redisTemplates = [
|
|
942
|
+
buildEngineMetricsStoppedTemplate({
|
|
943
|
+
id: "database-redis-engine-metrics-stopped",
|
|
944
|
+
engine: REDIS,
|
|
945
|
+
metricName: "redis.uptime",
|
|
946
|
+
metricAlias: "redis_heartbeat",
|
|
947
|
+
}),
|
|
948
|
+
buildRestartTemplate({
|
|
949
|
+
id: "database-redis-restarted",
|
|
950
|
+
engine: REDIS,
|
|
951
|
+
metricName: "redis.uptime",
|
|
952
|
+
metricAlias: "redis_uptime",
|
|
953
|
+
threshold: 600,
|
|
954
|
+
}),
|
|
955
|
+
buildPercentOfLimitTemplate({
|
|
956
|
+
id: "database-redis-memory-near-maxmemory",
|
|
957
|
+
name: "Memory Near maxmemory",
|
|
958
|
+
description: "Alert when used memory stays at 90% of maxmemory. Reads redis.maxmemory, which the receiver only emits once it is enabled (the Database Agent enables it); a server with no maxmemory set never fires.",
|
|
959
|
+
category: "Memory",
|
|
960
|
+
severity: "Warning",
|
|
961
|
+
engine: REDIS,
|
|
962
|
+
numerator: {
|
|
963
|
+
alias: "redis_memory_used",
|
|
964
|
+
metricName: "redis.memory.used",
|
|
965
|
+
aggregationType: MetricsAggregationType.Sum,
|
|
966
|
+
},
|
|
967
|
+
denominator: {
|
|
968
|
+
alias: "redis_maxmemory",
|
|
969
|
+
metricName: "redis.maxmemory",
|
|
970
|
+
aggregationType: MetricsAggregationType.Sum,
|
|
971
|
+
},
|
|
972
|
+
resultAlias: "redis_memory_percent",
|
|
973
|
+
thresholdPercent: 90,
|
|
974
|
+
rollingTime: RollingTime.Past10Minutes,
|
|
975
|
+
incidentDescription: "Redis is close to maxmemory. With an eviction policy it is about to start evicting keys; with noeviction it is about to reject writes with OOM errors. Check which keys grew (redis-cli --bigkeys) and whether keys are missing a TTL.",
|
|
976
|
+
}),
|
|
977
|
+
buildDatabaseTemplate({
|
|
978
|
+
id: "database-redis-memory-fragmentation",
|
|
979
|
+
name: "Memory Fragmentation High",
|
|
980
|
+
description: "Alert when the memory fragmentation ratio stays at 1.5 or more while Redis uses at least 256 MB — the process holds far more RAM than its data needs. Small instances are exempt: their ratio is naturally high and meaningless.",
|
|
981
|
+
category: "Memory",
|
|
982
|
+
severity: "Warning",
|
|
983
|
+
engine: REDIS,
|
|
984
|
+
queries: [
|
|
985
|
+
{
|
|
986
|
+
alias: "redis_fragmentation_ratio",
|
|
987
|
+
metricName: "redis.memory.fragmentation_ratio",
|
|
988
|
+
aggregationType: MetricsAggregationType.Avg,
|
|
989
|
+
/*
|
|
990
|
+
* The receiver's unit is the dimensionless "1", which on a `_ratio`
|
|
991
|
+
* name the alert text reads as a 0..1 fraction and renders ×100
|
|
992
|
+
* ("162.00% ... 150.00%"). This ratio is no fraction — healthy is
|
|
993
|
+
* about 1.0 — so it is labelled with an annotation-only unit, which
|
|
994
|
+
* formats as the bare number.
|
|
995
|
+
*/
|
|
996
|
+
legendUnit: "{ratio}",
|
|
997
|
+
},
|
|
998
|
+
{
|
|
999
|
+
alias: "redis_fragmentation_memory_used",
|
|
1000
|
+
metricName: "redis.memory.used",
|
|
1001
|
+
aggregationType: MetricsAggregationType.Avg,
|
|
1002
|
+
},
|
|
1003
|
+
],
|
|
1004
|
+
rollingTime: RollingTime.Past15Minutes,
|
|
1005
|
+
criteria: {
|
|
1006
|
+
metricAlias: "redis_fragmentation_ratio",
|
|
1007
|
+
filterType: FilterType.GreaterThanOrEqualTo,
|
|
1008
|
+
threshold: 1.5,
|
|
1009
|
+
thresholdLabel: "at or above a ratio of 1.5",
|
|
1010
|
+
additionalFilter: {
|
|
1011
|
+
metricAlias: "redis_fragmentation_memory_used",
|
|
1012
|
+
filterType: FilterType.GreaterThanOrEqualTo,
|
|
1013
|
+
// Decimal, like the byte ladder the alert text formats with: "256 MB".
|
|
1014
|
+
value: 256000000,
|
|
1015
|
+
label: "redis.memory.used is at or above 256 MB",
|
|
1016
|
+
},
|
|
1017
|
+
incidentDescription: "Redis holds far more resident memory than its data needs. Enable active defragmentation (activedefrag yes) or plan a restart; if the ratio is BELOW 1 instead, the host is swapping, which is worse.",
|
|
1018
|
+
},
|
|
1019
|
+
}),
|
|
1020
|
+
buildDatabaseTemplate({
|
|
1021
|
+
id: "database-redis-clients-high",
|
|
1022
|
+
name: "Connected Clients Near maxclients",
|
|
1023
|
+
description: "Alert when connected clients stay at 9,000 or more — 90% of the default maxclients of 10,000. Retune to 90% of the server's own maxclients setting.",
|
|
1024
|
+
category: "Connections",
|
|
1025
|
+
severity: "Warning",
|
|
1026
|
+
engine: REDIS,
|
|
1027
|
+
queries: [
|
|
1028
|
+
{
|
|
1029
|
+
alias: "redis_clients_connected",
|
|
1030
|
+
metricName: "redis.clients.connected",
|
|
1031
|
+
aggregationType: MetricsAggregationType.Max,
|
|
1032
|
+
},
|
|
1033
|
+
],
|
|
1034
|
+
criteria: {
|
|
1035
|
+
metricAlias: "redis_clients_connected",
|
|
1036
|
+
filterType: FilterType.GreaterThanOrEqualTo,
|
|
1037
|
+
threshold: 9000,
|
|
1038
|
+
thresholdLabel: "at or above 9,000 clients",
|
|
1039
|
+
incidentDescription: 'Redis is close to maxclients; past it new connections are refused with "max number of clients reached". Look for a client that opens a connection per request instead of reusing a pool (CLIENT LIST, grouped by address).',
|
|
1040
|
+
},
|
|
1041
|
+
}),
|
|
1042
|
+
];
|
|
1043
|
+
// --- MongoDB ---
|
|
1044
|
+
const MONGODB = {
|
|
1045
|
+
engine: "mongodb",
|
|
1046
|
+
receiver: "mongodb",
|
|
1047
|
+
displayName: "MongoDB",
|
|
1048
|
+
};
|
|
1049
|
+
const mongodbTemplates = [
|
|
1050
|
+
buildEngineMetricsStoppedTemplate({
|
|
1051
|
+
id: "database-mongodb-engine-metrics-stopped",
|
|
1052
|
+
engine: MONGODB,
|
|
1053
|
+
metricName: "mongodb.database.count",
|
|
1054
|
+
metricAlias: "mongodb_heartbeat",
|
|
1055
|
+
}),
|
|
1056
|
+
buildRestartTemplate({
|
|
1057
|
+
id: "database-mongodb-restarted",
|
|
1058
|
+
engine: MONGODB,
|
|
1059
|
+
metricName: "mongodb.uptime",
|
|
1060
|
+
metricAlias: "mongodb_uptime",
|
|
1061
|
+
// mongodb.uptime is reported in milliseconds.
|
|
1062
|
+
threshold: 600000,
|
|
1063
|
+
requiresEnabling: true,
|
|
1064
|
+
}),
|
|
1065
|
+
buildDatabaseTemplate({
|
|
1066
|
+
id: "database-mongodb-connections-exhausted",
|
|
1067
|
+
name: "Connections Nearly Exhausted",
|
|
1068
|
+
description: "Alert when current connections reach 90% of the connections the server can accept (current + available). Past 100% mongod refuses new connections.",
|
|
1069
|
+
category: "Connections",
|
|
1070
|
+
severity: "Critical",
|
|
1071
|
+
engine: MONGODB,
|
|
1072
|
+
queries: [
|
|
1073
|
+
{
|
|
1074
|
+
alias: "mongodb_connections_current",
|
|
1075
|
+
metricName: "mongodb.connection.count",
|
|
1076
|
+
aggregationType: MetricsAggregationType.Sum,
|
|
1077
|
+
attributes: { type: "current" },
|
|
1078
|
+
},
|
|
1079
|
+
{
|
|
1080
|
+
alias: "mongodb_connections_available",
|
|
1081
|
+
metricName: "mongodb.connection.count",
|
|
1082
|
+
aggregationType: MetricsAggregationType.Sum,
|
|
1083
|
+
attributes: { type: "available" },
|
|
1084
|
+
},
|
|
1085
|
+
],
|
|
1086
|
+
formula: {
|
|
1087
|
+
alias: "mongodb_connections_percent",
|
|
1088
|
+
expression: "(mongodb_connections_current / (mongodb_connections_current + mongodb_connections_available)) * 100",
|
|
1089
|
+
legendUnit: "%",
|
|
1090
|
+
},
|
|
1091
|
+
criteria: {
|
|
1092
|
+
metricAlias: "mongodb_connections_percent",
|
|
1093
|
+
filterType: FilterType.GreaterThanOrEqualTo,
|
|
1094
|
+
threshold: 90,
|
|
1095
|
+
thresholdLabel: "at or above 90%",
|
|
1096
|
+
subject: "mongodb.connection.count (type = current) as a percentage of current + available",
|
|
1097
|
+
incidentDescription: "mongod is about to refuse new connections. Check which clients hold them (db.currentOp, $currentOp grouped by client) — usually a driver pool sized far above what the application needs, multiplied across every replica of it.",
|
|
1098
|
+
},
|
|
1099
|
+
}),
|
|
1100
|
+
/*
|
|
1101
|
+
* No "server reports unhealthy" template on mongodb.health: the receiver
|
|
1102
|
+
* records it from serverStatus's `ok` only after serverStatus succeeded,
|
|
1103
|
+
* so it can only ever read 1 — a server that is down emits nothing
|
|
1104
|
+
* (Engine Metrics Stopped covers that), and a replica-set member in
|
|
1105
|
+
* RECOVERING or ROLLBACK still answers ok:1.
|
|
1106
|
+
*/
|
|
1107
|
+
];
|
|
1108
|
+
// --- SQL Server ---
|
|
1109
|
+
const SQL_SERVER = {
|
|
1110
|
+
engine: "microsoft.sql_server",
|
|
1111
|
+
receiver: "sqlserver",
|
|
1112
|
+
displayName: "SQL Server",
|
|
1113
|
+
};
|
|
1114
|
+
const sqlServerTemplates = [
|
|
1115
|
+
buildEngineMetricsStoppedTemplate({
|
|
1116
|
+
id: "database-sqlserver-engine-metrics-stopped",
|
|
1117
|
+
engine: SQL_SERVER,
|
|
1118
|
+
metricName: "sqlserver.user.connection.count",
|
|
1119
|
+
metricAlias: "sqlserver_heartbeat",
|
|
1120
|
+
}),
|
|
1121
|
+
buildDatabaseTemplate({
|
|
1122
|
+
id: "database-sqlserver-buffer-cache-hit-ratio-low",
|
|
1123
|
+
name: "Buffer Cache Hit Ratio Low",
|
|
1124
|
+
description: "Alert when the buffer cache hit ratio stays below 90% — pages are being read from disk instead of memory.",
|
|
1125
|
+
category: "Performance",
|
|
1126
|
+
severity: "Warning",
|
|
1127
|
+
engine: SQL_SERVER,
|
|
1128
|
+
queries: [
|
|
1129
|
+
{
|
|
1130
|
+
alias: "sqlserver_buffer_cache_hit_ratio",
|
|
1131
|
+
metricName: "sqlserver.page.buffer_cache.hit_ratio",
|
|
1132
|
+
aggregationType: MetricsAggregationType.Min,
|
|
1133
|
+
},
|
|
1134
|
+
],
|
|
1135
|
+
rollingTime: RollingTime.Past10Minutes,
|
|
1136
|
+
criteria: {
|
|
1137
|
+
metricAlias: "sqlserver_buffer_cache_hit_ratio",
|
|
1138
|
+
filterType: FilterType.LessThan,
|
|
1139
|
+
threshold: 90,
|
|
1140
|
+
thresholdLabel: "below 90%",
|
|
1141
|
+
incidentDescription: "SQL Server is reading pages from disk rather than memory. Check whether max server memory is set too low and whether a scan-heavy query is flushing the buffer pool.",
|
|
1142
|
+
},
|
|
1143
|
+
}),
|
|
1144
|
+
buildDatabaseTemplate({
|
|
1145
|
+
id: "database-sqlserver-page-life-expectancy-low",
|
|
1146
|
+
name: "Page Life Expectancy Low",
|
|
1147
|
+
description: "Alert when page life expectancy stays below 300 seconds — the buffer pool is churning under memory pressure.",
|
|
1148
|
+
category: "Memory",
|
|
1149
|
+
severity: "Warning",
|
|
1150
|
+
engine: SQL_SERVER,
|
|
1151
|
+
queries: [
|
|
1152
|
+
{
|
|
1153
|
+
alias: "sqlserver_page_life_expectancy",
|
|
1154
|
+
metricName: "sqlserver.page.life_expectancy",
|
|
1155
|
+
aggregationType: MetricsAggregationType.Min,
|
|
1156
|
+
},
|
|
1157
|
+
],
|
|
1158
|
+
rollingTime: RollingTime.Past10Minutes,
|
|
1159
|
+
criteria: {
|
|
1160
|
+
metricAlias: "sqlserver_page_life_expectancy",
|
|
1161
|
+
filterType: FilterType.LessThan,
|
|
1162
|
+
threshold: 300,
|
|
1163
|
+
thresholdLabel: "below 300 seconds",
|
|
1164
|
+
incidentDescription: "Pages are leaving the buffer pool within five minutes of being read, so the server is short of memory for its working set. Check memory grants and large scans, then max server memory.",
|
|
1165
|
+
},
|
|
1166
|
+
}),
|
|
1167
|
+
buildDatabaseTemplate({
|
|
1168
|
+
id: "database-sqlserver-sessions-blocked",
|
|
1169
|
+
name: "Sessions Blocked",
|
|
1170
|
+
description: "Alert when sessions waiting on another session's lock are seen throughout ten minutes — a blocking chain that is not clearing. Reads sqlserver.processes.blocked, which the receiver only emits once it is enabled (the Database Agent enables it).",
|
|
1171
|
+
category: "Performance",
|
|
1172
|
+
severity: "Warning",
|
|
1173
|
+
engine: SQL_SERVER,
|
|
1174
|
+
queries: [
|
|
1175
|
+
{
|
|
1176
|
+
alias: "sqlserver_processes_blocked",
|
|
1177
|
+
metricName: "sqlserver.processes.blocked",
|
|
1178
|
+
// The worst scrape of each minute, across every agent reporting it.
|
|
1179
|
+
aggregationType: MetricsAggregationType.Max,
|
|
1180
|
+
},
|
|
1181
|
+
],
|
|
1182
|
+
rollingTime: RollingTime.Past10Minutes,
|
|
1183
|
+
criteria: {
|
|
1184
|
+
metricAlias: "sqlserver_processes_blocked",
|
|
1185
|
+
filterType: FilterType.GreaterThanOrEqualTo,
|
|
1186
|
+
threshold: 1,
|
|
1187
|
+
thresholdLabel: "at or above 1 blocked session",
|
|
1188
|
+
incidentDescription: "Sessions have been blocked on locks for ten minutes. Find the head of the blocking chain in sys.dm_exec_requests (blocking_session_id) and what it is waiting on — usually a transaction an application opened and never committed.",
|
|
1189
|
+
},
|
|
1190
|
+
}),
|
|
1191
|
+
buildDatabaseTemplate({
|
|
1192
|
+
id: "database-sqlserver-memory-grants-pending",
|
|
1193
|
+
name: "Queries Waiting for Memory",
|
|
1194
|
+
description: "Alert when queries stay queued for a memory grant for five minutes — they cannot start until workspace memory frees up. Reads sqlserver.memory.grants.pending.count, which the receiver only emits once it is enabled (the Database Agent enables it).",
|
|
1195
|
+
category: "Memory",
|
|
1196
|
+
severity: "Warning",
|
|
1197
|
+
engine: SQL_SERVER,
|
|
1198
|
+
queries: [
|
|
1199
|
+
{
|
|
1200
|
+
alias: "sqlserver_memory_grants_pending",
|
|
1201
|
+
metricName: "sqlserver.memory.grants.pending.count",
|
|
1202
|
+
aggregationType: MetricsAggregationType.Max,
|
|
1203
|
+
},
|
|
1204
|
+
],
|
|
1205
|
+
criteria: {
|
|
1206
|
+
metricAlias: "sqlserver_memory_grants_pending",
|
|
1207
|
+
filterType: FilterType.GreaterThanOrEqualTo,
|
|
1208
|
+
threshold: 1,
|
|
1209
|
+
thresholdLabel: "at or above 1 pending grant",
|
|
1210
|
+
incidentDescription: "Queries are waiting for workspace memory before they can run. sys.dm_exec_query_memory_grants lists them (grant_time is NULL for the waiters) next to the sorts and hashes holding the memory; then check max server memory.",
|
|
1211
|
+
},
|
|
1212
|
+
}),
|
|
1213
|
+
];
|
|
1214
|
+
// --- Oracle ---
|
|
1215
|
+
const ORACLE = {
|
|
1216
|
+
engine: "oracle.db",
|
|
1217
|
+
receiver: "oracledb",
|
|
1218
|
+
displayName: "Oracle",
|
|
1219
|
+
};
|
|
1220
|
+
/*
|
|
1221
|
+
* No "percent of the SESSIONS / PROCESSES limit" template: a connection to a
|
|
1222
|
+
* pluggable database, the usual setup, never returns either limit, so such a
|
|
1223
|
+
* monitor would watch nothing (see the module header).
|
|
1224
|
+
*/
|
|
1225
|
+
const oracleTemplates = [
|
|
1226
|
+
buildEngineMetricsStoppedTemplate({
|
|
1227
|
+
id: "database-oracle-engine-metrics-stopped",
|
|
1228
|
+
engine: ORACLE,
|
|
1229
|
+
// One row per session type and status on every scrape: never empty.
|
|
1230
|
+
metricName: "oracledb.sessions.usage",
|
|
1231
|
+
metricAlias: "oracle_heartbeat",
|
|
1232
|
+
}),
|
|
1233
|
+
buildDatabaseTemplate({
|
|
1234
|
+
id: "database-oracle-tablespace-nearly-full",
|
|
1235
|
+
name: "Tablespace Nearly Full",
|
|
1236
|
+
description: "Alert when the fullest tablespace stays at 90% or more of its maximum size. A full tablespace refuses to extend the segments in it (ORA-01653; ORA-01652 for TEMP). Reads oracledb.tablespace.utilization, which the receiver only emits once it is enabled (the Database Agent enables it).",
|
|
1237
|
+
category: "Storage",
|
|
1238
|
+
severity: "Critical",
|
|
1239
|
+
engine: ORACLE,
|
|
1240
|
+
queries: [
|
|
1241
|
+
{
|
|
1242
|
+
alias: "oracle_tablespace_utilization",
|
|
1243
|
+
metricName: "oracledb.tablespace.utilization",
|
|
1244
|
+
// The fullest tablespace, of any pluggable database.
|
|
1245
|
+
aggregationType: MetricsAggregationType.Max,
|
|
1246
|
+
},
|
|
1247
|
+
],
|
|
1248
|
+
// The receiver reports a 0..1 share; the monitor compares a percentage.
|
|
1249
|
+
formula: {
|
|
1250
|
+
alias: "oracle_tablespace_percent",
|
|
1251
|
+
expression: "oracle_tablespace_utilization * 100",
|
|
1252
|
+
legendUnit: "%",
|
|
1253
|
+
},
|
|
1254
|
+
rollingTime: RollingTime.Past10Minutes,
|
|
1255
|
+
criteria: {
|
|
1256
|
+
metricAlias: "oracle_tablespace_percent",
|
|
1257
|
+
filterType: FilterType.GreaterThanOrEqualTo,
|
|
1258
|
+
threshold: 90,
|
|
1259
|
+
thresholdLabel: "at or above 90%",
|
|
1260
|
+
subject: "oracledb.tablespace.utilization (the fullest tablespace) as a percentage",
|
|
1261
|
+
incidentDescription: "A tablespace is nearly full. DBA_TABLESPACE_USAGE_METRICS shows which one: add a datafile, raise its datafiles' MAXSIZE, or purge what grew. For TEMP, look for the sort or hash join spilling to disk.",
|
|
1262
|
+
},
|
|
1263
|
+
}),
|
|
1264
|
+
];
|
|
1265
|
+
// --- Elasticsearch ---
|
|
1266
|
+
const ELASTICSEARCH = {
|
|
1267
|
+
engine: "elasticsearch",
|
|
1268
|
+
receiver: "elasticsearch",
|
|
1269
|
+
displayName: "Elasticsearch",
|
|
1270
|
+
};
|
|
1271
|
+
const elasticsearchTemplates = [
|
|
1272
|
+
buildEngineMetricsStoppedTemplate({
|
|
1273
|
+
id: "database-elasticsearch-engine-metrics-stopped",
|
|
1274
|
+
engine: ELASTICSEARCH,
|
|
1275
|
+
metricName: "elasticsearch.cluster.health",
|
|
1276
|
+
metricAlias: "elasticsearch_heartbeat",
|
|
1277
|
+
}),
|
|
1278
|
+
buildDatabaseTemplate({
|
|
1279
|
+
id: "database-elasticsearch-cluster-red",
|
|
1280
|
+
name: "Cluster Health Red",
|
|
1281
|
+
description: "Alert when cluster health stays red — at least one primary shard is unassigned, so part of the data cannot be searched or written.",
|
|
1282
|
+
category: "Availability",
|
|
1283
|
+
severity: "Critical",
|
|
1284
|
+
engine: ELASTICSEARCH,
|
|
1285
|
+
queries: [
|
|
1286
|
+
{
|
|
1287
|
+
alias: "elasticsearch_health_red",
|
|
1288
|
+
metricName: "elasticsearch.cluster.health",
|
|
1289
|
+
aggregationType: MetricsAggregationType.Max,
|
|
1290
|
+
attributes: { status: "red" },
|
|
1291
|
+
},
|
|
1292
|
+
],
|
|
1293
|
+
criteria: {
|
|
1294
|
+
metricAlias: "elasticsearch_health_red",
|
|
1295
|
+
filterType: FilterType.GreaterThanOrEqualTo,
|
|
1296
|
+
threshold: 1,
|
|
1297
|
+
thresholdLabel: "at 1 (red)",
|
|
1298
|
+
isBinaryMetric: true,
|
|
1299
|
+
incidentDescription: "The cluster is red: a primary shard is unassigned. GET _cluster/allocation/explain says why — usually a lost node, a full disk past the flood-stage watermark, or a corrupted shard.",
|
|
1300
|
+
},
|
|
1301
|
+
}),
|
|
1302
|
+
buildDatabaseTemplate({
|
|
1303
|
+
id: "database-elasticsearch-cluster-yellow",
|
|
1304
|
+
name: "Cluster Health Yellow",
|
|
1305
|
+
description: "Alert when cluster health stays yellow for fifteen minutes — replica shards are unassigned, so one more node loss can lose data. Short yellow periods during a rolling restart are normal.",
|
|
1306
|
+
category: "Availability",
|
|
1307
|
+
severity: "Warning",
|
|
1308
|
+
engine: ELASTICSEARCH,
|
|
1309
|
+
queries: [
|
|
1310
|
+
{
|
|
1311
|
+
alias: "elasticsearch_health_yellow",
|
|
1312
|
+
metricName: "elasticsearch.cluster.health",
|
|
1313
|
+
aggregationType: MetricsAggregationType.Max,
|
|
1314
|
+
attributes: { status: "yellow" },
|
|
1315
|
+
},
|
|
1316
|
+
],
|
|
1317
|
+
rollingTime: RollingTime.Past15Minutes,
|
|
1318
|
+
criteria: {
|
|
1319
|
+
metricAlias: "elasticsearch_health_yellow",
|
|
1320
|
+
filterType: FilterType.GreaterThanOrEqualTo,
|
|
1321
|
+
threshold: 1,
|
|
1322
|
+
thresholdLabel: "at 1 (yellow)",
|
|
1323
|
+
isBinaryMetric: true,
|
|
1324
|
+
incidentDescription: "The cluster has been yellow for fifteen minutes: replica shards are unassigned. GET _cluster/allocation/explain says why — too few nodes for the replica count, or disk watermarks.",
|
|
1325
|
+
},
|
|
1326
|
+
}),
|
|
1327
|
+
buildDatabaseTemplate({
|
|
1328
|
+
id: "database-elasticsearch-pending-tasks",
|
|
1329
|
+
name: "Cluster Tasks Backing Up",
|
|
1330
|
+
description: "Alert when ten or more cluster-state tasks stay pending — the master node cannot keep up with mapping, shard and index changes.",
|
|
1331
|
+
category: "Performance",
|
|
1332
|
+
severity: "Warning",
|
|
1333
|
+
engine: ELASTICSEARCH,
|
|
1334
|
+
queries: [
|
|
1335
|
+
{
|
|
1336
|
+
alias: "elasticsearch_pending_tasks",
|
|
1337
|
+
metricName: "elasticsearch.cluster.pending_tasks",
|
|
1338
|
+
aggregationType: MetricsAggregationType.Max,
|
|
1339
|
+
},
|
|
1340
|
+
],
|
|
1341
|
+
rollingTime: RollingTime.Past10Minutes,
|
|
1342
|
+
criteria: {
|
|
1343
|
+
metricAlias: "elasticsearch_pending_tasks",
|
|
1344
|
+
filterType: FilterType.GreaterThanOrEqualTo,
|
|
1345
|
+
threshold: 10,
|
|
1346
|
+
thresholdLabel: "at or above 10 tasks",
|
|
1347
|
+
incidentDescription: "Cluster-state updates are queueing on the master. GET _cluster/pending_tasks shows what — dynamic mapping updates from a field explosion and mass index creation are the usual causes.",
|
|
1348
|
+
},
|
|
1349
|
+
}),
|
|
1350
|
+
buildDatabaseTemplate({
|
|
1351
|
+
id: "database-elasticsearch-jvm-heap-high",
|
|
1352
|
+
name: "JVM Heap Pressure",
|
|
1353
|
+
description: "Alert when a node's JVM heap stays at 85% of its maximum or more. Sustained pressure means long GC pauses and circuit breakers tripping next. Reads jvm.memory.heap.utilization, which the receiver only emits once it is enabled (the Database Agent enables it).",
|
|
1354
|
+
category: "Memory",
|
|
1355
|
+
severity: "Warning",
|
|
1356
|
+
engine: ELASTICSEARCH,
|
|
1357
|
+
queries: [
|
|
1358
|
+
{
|
|
1359
|
+
alias: "elasticsearch_heap_utilization",
|
|
1360
|
+
metricName: "jvm.memory.heap.utilization",
|
|
1361
|
+
/*
|
|
1362
|
+
* The hottest node: heap pressure is a per-node failure (that
|
|
1363
|
+
* node's breakers trip, its GC stalls), which a cluster-wide mean
|
|
1364
|
+
* hides. Not a Sum/Sum of jvm.memory.heap.used over heap.max —
|
|
1365
|
+
* the receiver records heap.used once per node AND once for the
|
|
1366
|
+
* whole cluster in the same scrape, so that ratio reads double.
|
|
1367
|
+
*/
|
|
1368
|
+
aggregationType: MetricsAggregationType.Max,
|
|
1369
|
+
},
|
|
1370
|
+
],
|
|
1371
|
+
// The receiver reports a 0..1 share; the monitor compares a percentage.
|
|
1372
|
+
formula: {
|
|
1373
|
+
alias: "elasticsearch_heap_percent",
|
|
1374
|
+
expression: "elasticsearch_heap_utilization * 100",
|
|
1375
|
+
legendUnit: "%",
|
|
1376
|
+
},
|
|
1377
|
+
rollingTime: RollingTime.Past10Minutes,
|
|
1378
|
+
criteria: {
|
|
1379
|
+
metricAlias: "elasticsearch_heap_percent",
|
|
1380
|
+
filterType: FilterType.GreaterThanOrEqualTo,
|
|
1381
|
+
threshold: 85,
|
|
1382
|
+
thresholdLabel: "at or above 85%",
|
|
1383
|
+
subject: "jvm.memory.heap.utilization (the fullest node's heap) as a percentage",
|
|
1384
|
+
incidentDescription: "A node's Elasticsearch heap has stayed above 85%. GET _nodes/stats/jvm,breaker shows which node and how close its breakers are; large aggregations, too many shards per node and unbounded fielddata are the usual causes.",
|
|
1385
|
+
},
|
|
1386
|
+
}),
|
|
1387
|
+
];
|
|
1388
|
+
// --- Memcached ---
|
|
1389
|
+
const MEMCACHED = {
|
|
1390
|
+
engine: "memcached",
|
|
1391
|
+
receiver: "memcached",
|
|
1392
|
+
displayName: "Memcached",
|
|
1393
|
+
};
|
|
1394
|
+
const memcachedTemplates = [
|
|
1395
|
+
buildEngineMetricsStoppedTemplate({
|
|
1396
|
+
id: "database-memcached-engine-metrics-stopped",
|
|
1397
|
+
engine: MEMCACHED,
|
|
1398
|
+
metricName: "memcached.threads",
|
|
1399
|
+
metricAlias: "memcached_heartbeat",
|
|
1400
|
+
}),
|
|
1401
|
+
buildDatabaseTemplate({
|
|
1402
|
+
id: "database-memcached-connections-high",
|
|
1403
|
+
name: "Connections Near Limit",
|
|
1404
|
+
description: "Alert when open connections stay at 900 or more — close to the default connection limit of 1,024 (-c). Retune to 90% of the server's own limit.",
|
|
1405
|
+
category: "Connections",
|
|
1406
|
+
severity: "Warning",
|
|
1407
|
+
engine: MEMCACHED,
|
|
1408
|
+
queries: [
|
|
1409
|
+
{
|
|
1410
|
+
alias: "memcached_connections",
|
|
1411
|
+
metricName: "memcached.connections.current",
|
|
1412
|
+
aggregationType: MetricsAggregationType.Max,
|
|
1413
|
+
},
|
|
1414
|
+
],
|
|
1415
|
+
criteria: {
|
|
1416
|
+
metricAlias: "memcached_connections",
|
|
1417
|
+
filterType: FilterType.GreaterThanOrEqualTo,
|
|
1418
|
+
threshold: 900,
|
|
1419
|
+
thresholdLabel: "at or above 900 connections",
|
|
1420
|
+
incidentDescription: "Memcached is close to its connection limit; past it new clients are refused. Look for a client that opens a connection per request instead of pooling.",
|
|
1421
|
+
},
|
|
1422
|
+
}),
|
|
1423
|
+
];
|
|
1424
|
+
// --- CouchDB ---
|
|
1425
|
+
const COUCHDB = {
|
|
1426
|
+
engine: "couchdb",
|
|
1427
|
+
receiver: "couchdb",
|
|
1428
|
+
displayName: "CouchDB",
|
|
1429
|
+
};
|
|
1430
|
+
const couchdbTemplates = [
|
|
1431
|
+
buildEngineMetricsStoppedTemplate({
|
|
1432
|
+
id: "database-couchdb-engine-metrics-stopped",
|
|
1433
|
+
engine: COUCHDB,
|
|
1434
|
+
metricName: "couchdb.database.open",
|
|
1435
|
+
metricAlias: "couchdb_heartbeat",
|
|
1436
|
+
}),
|
|
1437
|
+
buildDatabaseTemplate({
|
|
1438
|
+
id: "database-couchdb-request-time-high",
|
|
1439
|
+
name: "Slow Requests",
|
|
1440
|
+
description: "Alert when the average request time stays at one second or more.",
|
|
1441
|
+
category: "Performance",
|
|
1442
|
+
severity: "Warning",
|
|
1443
|
+
engine: COUCHDB,
|
|
1444
|
+
queries: [
|
|
1445
|
+
{
|
|
1446
|
+
alias: "couchdb_request_time",
|
|
1447
|
+
metricName: "couchdb.average_request_time",
|
|
1448
|
+
aggregationType: MetricsAggregationType.Max,
|
|
1449
|
+
},
|
|
1450
|
+
],
|
|
1451
|
+
criteria: {
|
|
1452
|
+
metricAlias: "couchdb_request_time",
|
|
1453
|
+
filterType: FilterType.GreaterThanOrEqualTo,
|
|
1454
|
+
threshold: 1000,
|
|
1455
|
+
thresholdLabel: "at or above 1,000 ms",
|
|
1456
|
+
incidentDescription: "CouchDB requests are averaging a second or more. Check view indexing (_active_tasks), compaction, and disk latency.",
|
|
1457
|
+
},
|
|
1458
|
+
}),
|
|
1459
|
+
];
|
|
1460
|
+
/*
|
|
1461
|
+
* Declaration order is display order within an engine: availability first,
|
|
1462
|
+
* because "the database is down" outranks everything else on the page.
|
|
1463
|
+
*/
|
|
1464
|
+
const ALL_DATABASE_ALERT_TEMPLATES = [
|
|
1465
|
+
...postgresqlTemplates,
|
|
1466
|
+
...mysqlTemplates,
|
|
1467
|
+
...redisTemplates,
|
|
1468
|
+
...mongodbTemplates,
|
|
1469
|
+
...sqlServerTemplates,
|
|
1470
|
+
...oracleTemplates,
|
|
1471
|
+
...elasticsearchTemplates,
|
|
1472
|
+
...memcachedTemplates,
|
|
1473
|
+
...couchdbTemplates,
|
|
1474
|
+
];
|
|
1475
|
+
export function getAllDatabaseAlertTemplates() {
|
|
1476
|
+
return [...ALL_DATABASE_ALERT_TEMPLATES];
|
|
1477
|
+
}
|
|
1478
|
+
/*
|
|
1479
|
+
* The templates to offer ONE database, given its engine (`dbSystem`, aliases
|
|
1480
|
+
* accepted).
|
|
1481
|
+
*
|
|
1482
|
+
* Matched by RECEIVER: the templates written against the collector receivers
|
|
1483
|
+
* that monitor this engine. A fork its family's receiver works against gets
|
|
1484
|
+
* that receiver's set (MariaDB → MySQL's, Valkey → Redis's); an engine no
|
|
1485
|
+
* receiver here covers (Cassandra, ClickHouse, CockroachDB) and an unknown or
|
|
1486
|
+
* empty engine yield an empty list, never a guess — every template reads one
|
|
1487
|
+
* receiver's metric names, so nothing applies to a database whose metrics no
|
|
1488
|
+
* template's receiver produces.
|
|
1489
|
+
*/
|
|
1490
|
+
export function getDatabaseAlertTemplates(engine) {
|
|
1491
|
+
const descriptor = getDatabaseSystemDescriptor(engine);
|
|
1492
|
+
if (!descriptor) {
|
|
1493
|
+
return [];
|
|
1494
|
+
}
|
|
1495
|
+
return ALL_DATABASE_ALERT_TEMPLATES.filter((template) => {
|
|
1496
|
+
return descriptor.receiverTypes.includes(template.receiver);
|
|
1497
|
+
});
|
|
1498
|
+
}
|
|
1499
|
+
export function getDatabaseAlertTemplateById(id) {
|
|
1500
|
+
return ALL_DATABASE_ALERT_TEMPLATES.find((template) => {
|
|
1501
|
+
return template.id === id;
|
|
1502
|
+
});
|
|
1503
|
+
}
|
|
1504
|
+
/*
|
|
1505
|
+
* The engines this module's templates were written for (the engine each
|
|
1506
|
+
* receiver reports), in declaration order. Derived rather than hand-listed
|
|
1507
|
+
* so it cannot drift from the templates.
|
|
1508
|
+
*/
|
|
1509
|
+
export function getDatabaseEnginesWithAlertTemplates() {
|
|
1510
|
+
const engines = [];
|
|
1511
|
+
for (const template of ALL_DATABASE_ALERT_TEMPLATES) {
|
|
1512
|
+
if (!engines.includes(template.engine)) {
|
|
1513
|
+
engines.push(template.engine);
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
return engines;
|
|
1517
|
+
}
|
|
1518
|
+
//# sourceMappingURL=DatabaseAlertTemplates.js.map
|