@oneuptime/common 11.4.1 → 11.5.1
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/AIRun.ts +50 -0
- package/Models/DatabaseModels/AlertSeverity.ts +6 -0
- package/Models/DatabaseModels/IncidentSeverity.ts +6 -0
- package/Models/DatabaseModels/Index.ts +16 -0
- package/Models/DatabaseModels/IoTDeviceCredential.ts +471 -0
- package/Models/DatabaseModels/LlmLog.ts +56 -0
- package/Models/DatabaseModels/LlmProvider.ts +33 -0
- package/Models/DatabaseModels/NetworkDevice.ts +1385 -0
- package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +717 -0
- package/Models/DatabaseModels/NetworkDeviceLabelRule.ts +514 -0
- package/Models/DatabaseModels/NetworkDeviceOwnerRule.ts +596 -0
- package/Models/DatabaseModels/NetworkDeviceOwnerTeam.ts +487 -0
- package/Models/DatabaseModels/NetworkDeviceOwnerUser.ts +486 -0
- package/Models/DatabaseModels/NetworkInterface.ts +563 -0
- package/Models/DatabaseModels/Project.ts +145 -0
- package/Models/DatabaseModels/TelemetryEntityRelationship.ts +54 -0
- package/Server/API/AIInvestigationAPI.ts +131 -63
- package/Server/API/AlertAPI.ts +5 -0
- package/Server/API/IncidentAPI.ts +10 -0
- package/Server/API/IncidentEpisodeAPI.ts +5 -0
- package/Server/API/LlmProviderAPI.ts +4 -0
- package/Server/API/ScheduledMaintenanceAPI.ts +5 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783650000000-AddAdditionalParamsToLlmProvider.ts +19 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783695782697-AddCacheTokenColumnsToLlmLog.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783701585317-AddAlertInvestigationGating.ts +31 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783702431535-AddAiDailyAutonomousTokenLimitToProject.ts +19 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783720000000-AddNetworkDeviceTables.ts +105 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783721121260-AddAttemptCountToAIRun.ts +15 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783730000000-AddNetworkDeviceOwnersAndRules.ts +192 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783740000000-AddNetworkDeviceDiscoveryScan.ts +37 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783750000000-AddLldpNeighborsToNetworkDevice.ts +19 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783760576655-AddInvestigationTuningToProject.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783762505482-AddTelemetryEntityRelationshipMetrics.ts +31 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783780000000-AddIoTDeviceCredentialTable.ts +79 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783790000000-AddSnmpV3AuthColumnsToNetworkDevice.ts +49 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +26 -0
- package/Server/Services/AIRunService.ts +58 -0
- package/Server/Services/AIService.ts +101 -0
- package/Server/Services/IncidentService.ts +14 -41
- package/Server/Services/Index.ts +14 -0
- package/Server/Services/IoTDeviceCredentialService.ts +351 -0
- package/Server/Services/IoTDeviceService.ts +64 -21
- package/Server/Services/LlmLogService.ts +26 -0
- package/Server/Services/LlmProviderService.ts +3 -0
- package/Server/Services/MonitorService.ts +4 -1
- package/Server/Services/NetworkDeviceDiscoveryScanService.ts +10 -0
- package/Server/Services/NetworkDeviceLabelRuleEngineService.ts +204 -0
- package/Server/Services/NetworkDeviceLabelRuleService.ts +14 -0
- package/Server/Services/NetworkDeviceOwnerRuleEngineService.ts +222 -0
- package/Server/Services/NetworkDeviceOwnerRuleService.ts +14 -0
- package/Server/Services/NetworkDeviceOwnerTeamService.ts +10 -0
- package/Server/Services/NetworkDeviceOwnerUserService.ts +10 -0
- package/Server/Services/NetworkDeviceService.ts +50 -0
- package/Server/Services/NetworkInterfaceService.ts +10 -0
- package/Server/Services/TelemetryEntityRelationshipService.ts +23 -0
- package/Server/Services/TelemetryEntityService.ts +72 -2
- package/Server/Utils/AI/Sentinel/AlertInvestigationRunner.ts +244 -12
- package/Server/Utils/AI/Sentinel/IncidentInvestigationRunner.ts +92 -19
- package/Server/Utils/AI/Sentinel/InvestigationQueue.ts +493 -0
- package/Server/Utils/AI/Sentinel/SentinelInvestigationEngine.ts +88 -68
- package/Server/Utils/AI/Toolbox/Index.ts +2 -1
- package/Server/Utils/AI/Toolbox/MetricTools.ts +391 -0
- package/Server/Utils/LLM/LLMService.ts +21 -0
- package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +170 -2
- package/Server/Utils/Monitor/IoTDeviceAbsenceSeries.ts +101 -0
- package/Server/Utils/Monitor/MonitorAlert.ts +15 -3
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +1 -1
- package/Server/Utils/Monitor/MonitorIncident.ts +19 -3
- package/Server/Utils/Monitor/MonitorMetricUtil.ts +87 -0
- package/Server/Utils/Monitor/MonitorResource.ts +77 -21
- package/Server/Utils/Monitor/MonitorTemplateUtil.ts +1 -1
- package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +201 -0
- package/Server/Utils/Monitor/NetworkInventoryUtil.ts +215 -0
- package/Server/Utils/Monitor/SnmpInterfaceRateUtil.ts +169 -0
- package/Tests/Server/Services/AIServiceDailyBudget.test.ts +173 -0
- package/Tests/Server/Services/IncidentInternalNoteAnnouncement.test.ts +97 -0
- package/Tests/Server/Services/IoTDeviceService.test.ts +54 -0
- package/Tests/Server/Utils/AI/BaselineAnomalyTool.test.ts +253 -0
- package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +44 -0
- package/Tests/Server/Utils/AI/SentinelAlertGating.test.ts +360 -0
- package/Tests/Server/Utils/AI/SentinelInvestigationQueue.test.ts +295 -0
- package/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.ts +59 -0
- package/Tests/Server/Utils/Monitor/IoTDeviceAbsenceSeries.test.ts +113 -0
- package/Tests/Server/Utils/Monitor/PerSeriesRecoveryResolution.test.ts +198 -0
- package/Tests/Types/Monitor/MonitorType.test.ts +1 -1
- package/Tests/Utils/Monitor/LatencyMatrixUtil.test.ts +111 -0
- package/Types/AI/AIRunStatus.ts +9 -0
- package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +0 -1
- package/Types/Dashboard/DashboardComponents/DashboardLogChartComponent.ts +8 -3
- package/Types/LlmLogStatus.ts +1 -0
- package/Types/Monitor/CriteriaFilter.ts +5 -0
- package/Types/Monitor/IotAlertTemplates.ts +22 -3
- package/Types/Monitor/LatencyMatrix.ts +27 -0
- package/Types/Monitor/MonitorCriteriaInstance.ts +2 -2
- package/Types/Monitor/MonitorMetricType.ts +10 -0
- package/Types/Monitor/MonitorStep.ts +36 -11
- package/Types/Monitor/MonitorStepNetworkDeviceMonitor.ts +55 -0
- package/Types/Monitor/MonitorStepSnmpMonitor.ts +8 -0
- package/Types/Monitor/MonitorType.ts +14 -9
- package/Types/Monitor/SnmpMonitor/LldpNeighbor.ts +12 -0
- package/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.ts +116 -0
- package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +29 -0
- package/Types/Monitor/SnmpMonitor/SnmpInterface.ts +31 -0
- package/Types/Monitor/SnmpMonitor/SnmpMonitorResponse.ts +24 -0
- package/Types/Monitor/SnmpMonitor/SnmpTrap.ts +20 -0
- package/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.ts +173 -0
- package/Types/Permission.ts +314 -0
- package/Types/Probe/ProbeMonitorResponse.ts +8 -0
- package/UI/Components/Icon/Icon.tsx +8 -6
- package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +2 -2
- package/UI/Components/MoreMenu/MoreMenu.tsx +61 -2
- package/UI/Components/Tabs/Tabs.tsx +10 -1
- package/UI/Utils/Navigation.ts +10 -1
- package/Utils/Dashboard/Components/DashboardLogChartComponent.ts +16 -21
- package/Utils/Monitor/LatencyMatrixUtil.ts +162 -0
- package/Utils/Monitor/MonitorMetricType.ts +71 -1
- package/Utils/Monitor/NetworkTopologyUtil.ts +159 -0
- package/Utils/Telemetry/EntityRelationship.ts +11 -0
- package/build/dist/Models/DatabaseModels/AIRun.js +52 -0
- package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertSeverity.js +6 -0
- package/build/dist/Models/DatabaseModels/AlertSeverity.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentSeverity.js +6 -0
- package/build/dist/Models/DatabaseModels/IncidentSeverity.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/IoTDeviceCredential.js +493 -0
- package/build/dist/Models/DatabaseModels/IoTDeviceCredential.js.map +1 -0
- package/build/dist/Models/DatabaseModels/LlmLog.js +58 -0
- package/build/dist/Models/DatabaseModels/LlmLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/LlmProvider.js +33 -0
- package/build/dist/Models/DatabaseModels/LlmProvider.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +1426 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +738 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceLabelRule.js +522 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceLabelRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceOwnerRule.js +603 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceOwnerRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceOwnerTeam.js +503 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceOwnerTeam.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceOwnerUser.js +502 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceOwnerUser.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkInterface.js +589 -0
- package/build/dist/Models/DatabaseModels/NetworkInterface.js.map +1 -0
- package/build/dist/Models/DatabaseModels/Project.js +147 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js +57 -0
- package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +95 -55
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/AlertAPI.js +5 -0
- package/build/dist/Server/API/AlertAPI.js.map +1 -1
- package/build/dist/Server/API/IncidentAPI.js +10 -0
- package/build/dist/Server/API/IncidentAPI.js.map +1 -1
- package/build/dist/Server/API/IncidentEpisodeAPI.js +5 -0
- package/build/dist/Server/API/IncidentEpisodeAPI.js.map +1 -1
- package/build/dist/Server/API/LlmProviderAPI.js +5 -7
- package/build/dist/Server/API/LlmProviderAPI.js.map +1 -1
- package/build/dist/Server/API/ScheduledMaintenanceAPI.js +5 -0
- package/build/dist/Server/API/ScheduledMaintenanceAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783650000000-AddAdditionalParamsToLlmProvider.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783650000000-AddAdditionalParamsToLlmProvider.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783695782697-AddCacheTokenColumnsToLlmLog.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783695782697-AddCacheTokenColumnsToLlmLog.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783701585317-AddAlertInvestigationGating.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783701585317-AddAlertInvestigationGating.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783702431535-AddAiDailyAutonomousTokenLimitToProject.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783702431535-AddAiDailyAutonomousTokenLimitToProject.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783720000000-AddNetworkDeviceTables.js +51 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783720000000-AddNetworkDeviceTables.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783721121260-AddAttemptCountToAIRun.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783721121260-AddAttemptCountToAIRun.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783730000000-AddNetworkDeviceOwnersAndRules.js +101 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783730000000-AddNetworkDeviceOwnersAndRules.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783740000000-AddNetworkDeviceDiscoveryScan.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783740000000-AddNetworkDeviceDiscoveryScan.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783750000000-AddLldpNeighborsToNetworkDevice.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783750000000-AddLldpNeighborsToNetworkDevice.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783760576655-AddInvestigationTuningToProject.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783760576655-AddInvestigationTuningToProject.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783762505482-AddTelemetryEntityRelationshipMetrics.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783762505482-AddTelemetryEntityRelationshipMetrics.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783780000000-AddIoTDeviceCredentialTable.js +38 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783780000000-AddIoTDeviceCredentialTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783790000000-AddSnmpV3AuthColumnsToNetworkDevice.js +22 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783790000000-AddSnmpV3AuthColumnsToNetworkDevice.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +26 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/AIRunService.js +33 -0
- package/build/dist/Server/Services/AIRunService.js.map +1 -1
- package/build/dist/Server/Services/AIService.js +82 -9
- package/build/dist/Server/Services/AIService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +14 -25
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +14 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/IoTDeviceCredentialService.js +321 -0
- package/build/dist/Server/Services/IoTDeviceCredentialService.js.map +1 -0
- package/build/dist/Server/Services/IoTDeviceService.js +49 -15
- package/build/dist/Server/Services/IoTDeviceService.js.map +1 -1
- package/build/dist/Server/Services/LlmLogService.js +29 -0
- package/build/dist/Server/Services/LlmLogService.js.map +1 -1
- package/build/dist/Server/Services/LlmProviderService.js +3 -0
- package/build/dist/Server/Services/LlmProviderService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +2 -1
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js +9 -0
- package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js +166 -0
- package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceLabelRuleService.js +13 -0
- package/build/dist/Server/Services/NetworkDeviceLabelRuleService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js +186 -0
- package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceOwnerRuleService.js +13 -0
- package/build/dist/Server/Services/NetworkDeviceOwnerRuleService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceOwnerTeamService.js +9 -0
- package/build/dist/Server/Services/NetworkDeviceOwnerTeamService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceOwnerUserService.js +9 -0
- package/build/dist/Server/Services/NetworkDeviceOwnerUserService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceService.js +52 -0
- package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -0
- package/build/dist/Server/Services/NetworkInterfaceService.js +9 -0
- package/build/dist/Server/Services/NetworkInterfaceService.js.map +1 -0
- package/build/dist/Server/Services/TelemetryEntityRelationshipService.js +22 -0
- package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryEntityService.js +64 -2
- package/build/dist/Server/Services/TelemetryEntityService.js.map +1 -1
- package/build/dist/Server/Utils/AI/Sentinel/AlertInvestigationRunner.js +189 -9
- package/build/dist/Server/Utils/AI/Sentinel/AlertInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Sentinel/IncidentInvestigationRunner.js +84 -17
- package/build/dist/Server/Utils/AI/Sentinel/IncidentInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Sentinel/InvestigationQueue.js +428 -0
- package/build/dist/Server/Utils/AI/Sentinel/InvestigationQueue.js.map +1 -0
- package/build/dist/Server/Utils/AI/Sentinel/SentinelInvestigationEngine.js +63 -47
- package/build/dist/Server/Utils/AI/Sentinel/SentinelInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/Index.js +2 -1
- package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/MetricTools.js +300 -0
- package/build/dist/Server/Utils/AI/Toolbox/MetricTools.js.map +1 -1
- package/build/dist/Server/Utils/LLM/LLMService.js +16 -0
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +130 -2
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/IoTDeviceAbsenceSeries.js +81 -0
- package/build/dist/Server/Utils/Monitor/IoTDeviceAbsenceSeries.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +18 -7
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +25 -10
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +69 -3
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +76 -30
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +147 -0
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +167 -0
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/SnmpInterfaceRateUtil.js +93 -0
- package/build/dist/Server/Utils/Monitor/SnmpInterfaceRateUtil.js.map +1 -0
- package/build/dist/Types/AI/AIRunStatus.js +9 -0
- package/build/dist/Types/AI/AIRunStatus.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +0 -1
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
- package/build/dist/Types/LlmLogStatus.js +1 -0
- package/build/dist/Types/LlmLogStatus.js.map +1 -1
- package/build/dist/Types/Monitor/CriteriaFilter.js +5 -0
- package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
- package/build/dist/Types/Monitor/IotAlertTemplates.js +7 -7
- package/build/dist/Types/Monitor/IotAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/LatencyMatrix.js +2 -0
- package/build/dist/Types/Monitor/LatencyMatrix.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +2 -2
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorMetricType.js +9 -0
- package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +22 -9
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepNetworkDeviceMonitor.js +36 -0
- package/build/dist/Types/Monitor/MonitorStepNetworkDeviceMonitor.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorStepSnmpMonitor.js +3 -0
- package/build/dist/Types/Monitor/MonitorStepSnmpMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorType.js +14 -9
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/LldpNeighbor.js +2 -0
- package/build/dist/Types/Monitor/SnmpMonitor/LldpNeighbor.js.map +1 -0
- package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js +89 -0
- package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js.map +1 -0
- package/build/dist/Types/Monitor/SnmpMonitor/NetworkTopology.js +2 -0
- package/build/dist/Types/Monitor/SnmpMonitor/NetworkTopology.js.map +1 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpInterface.js +2 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpInterface.js.map +1 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpTrap.js +2 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpTrap.js.map +1 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js +137 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js.map +1 -0
- package/build/dist/Types/Permission.js +280 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +8 -6
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +2 -2
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js +44 -4
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
- package/build/dist/UI/Components/Tabs/Tabs.js +3 -1
- package/build/dist/UI/Components/Tabs/Tabs.js.map +1 -1
- package/build/dist/UI/Utils/Navigation.js +11 -1
- package/build/dist/UI/Utils/Navigation.js.map +1 -1
- package/build/dist/Utils/Dashboard/Components/DashboardLogChartComponent.js +17 -20
- package/build/dist/Utils/Dashboard/Components/DashboardLogChartComponent.js.map +1 -1
- package/build/dist/Utils/Monitor/LatencyMatrixUtil.js +89 -0
- package/build/dist/Utils/Monitor/LatencyMatrixUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorMetricType.js +68 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +112 -0
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -0
- package/build/dist/Utils/Telemetry/EntityRelationship.js.map +1 -1
- package/package.json +1 -1
|
@@ -41,6 +41,7 @@ export interface LLMCompletionRequest {
|
|
|
41
41
|
messages: Array<LLMMessage>;
|
|
42
42
|
temperature?: number | undefined;
|
|
43
43
|
maxTokens?: number | undefined;
|
|
44
|
+
additionalParams?: JSONObject | undefined;
|
|
44
45
|
tools?: Array<LLMToolDefinition> | undefined;
|
|
45
46
|
llmProviderConfig: LLMProviderConfig;
|
|
46
47
|
}
|
|
@@ -226,6 +227,26 @@ export default class LLMService {
|
|
|
226
227
|
data["tools"] = this.toOpenAITools(request.tools);
|
|
227
228
|
}
|
|
228
229
|
|
|
230
|
+
// Provider-configured overrides are applied last so they win over defaults.
|
|
231
|
+
if (request.additionalParams) {
|
|
232
|
+
Object.assign(data, request.additionalParams);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/*
|
|
236
|
+
* OpenAI's newer model families (gpt-5, o1, o3, ...) reject the legacy
|
|
237
|
+
* `max_tokens` parameter and require `max_completion_tokens` instead; the
|
|
238
|
+
* two are mutually exclusive. When a provider opts into
|
|
239
|
+
* `max_completion_tokens` via additionalParams, drop the default
|
|
240
|
+
* `max_tokens` so the request is accepted. Legacy OpenAI-compatible
|
|
241
|
+
* backends (Ollama, vLLM, LocalAI, ...) keep receiving `max_tokens`.
|
|
242
|
+
*/
|
|
243
|
+
if (
|
|
244
|
+
data["max_completion_tokens"] !== undefined &&
|
|
245
|
+
data["max_tokens"] !== undefined
|
|
246
|
+
) {
|
|
247
|
+
delete data["max_tokens"];
|
|
248
|
+
}
|
|
249
|
+
|
|
229
250
|
return data;
|
|
230
251
|
}
|
|
231
252
|
|
|
@@ -5,9 +5,11 @@ import {
|
|
|
5
5
|
CriteriaFilter,
|
|
6
6
|
FilterType,
|
|
7
7
|
} from "../../../../Types/Monitor/CriteriaFilter";
|
|
8
|
+
import SnmpInterface from "../../../../Types/Monitor/SnmpMonitor/SnmpInterface";
|
|
8
9
|
import SnmpMonitorResponse, {
|
|
9
10
|
SnmpOidResponse,
|
|
10
11
|
} from "../../../../Types/Monitor/SnmpMonitor/SnmpMonitorResponse";
|
|
12
|
+
import SnmpTrap from "../../../../Types/Monitor/SnmpMonitor/SnmpTrap";
|
|
11
13
|
import ProbeMonitorResponse from "../../../../Types/Probe/ProbeMonitorResponse";
|
|
12
14
|
import EvaluateOverTime from "./EvaluateOverTime";
|
|
13
15
|
import CaptureSpan from "../../Telemetry/CaptureSpan";
|
|
@@ -28,6 +30,63 @@ export default class SnmpMonitorCriteria {
|
|
|
28
30
|
const snmpResponse: SnmpMonitorResponse | undefined =
|
|
29
31
|
dataToProcess.snmpResponse;
|
|
30
32
|
|
|
33
|
+
/*
|
|
34
|
+
* Event/check separation. Trap responses are evaluated ONLY against
|
|
35
|
+
* trap criteria; polled check responses never match trap criteria.
|
|
36
|
+
* This keeps a trap from misfiring "is online" style filters (it has
|
|
37
|
+
* no check data) and keeps every poll from re-firing trap criteria.
|
|
38
|
+
*/
|
|
39
|
+
const snmpTrap: SnmpTrap | undefined = dataToProcess.snmpTrapResponse;
|
|
40
|
+
|
|
41
|
+
if (input.criteriaFilter.checkOn === CheckOn.SnmpTrapReceived) {
|
|
42
|
+
if (!snmpTrap) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const expectedOid: string = String(threshold || "").trim();
|
|
47
|
+
|
|
48
|
+
if (!expectedOid) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const trapOid: string = snmpTrap.trapOid;
|
|
53
|
+
let isMatch: boolean = false;
|
|
54
|
+
|
|
55
|
+
switch (input.criteriaFilter.filterType) {
|
|
56
|
+
case FilterType.EqualTo:
|
|
57
|
+
isMatch = trapOid === expectedOid;
|
|
58
|
+
break;
|
|
59
|
+
case FilterType.NotEqualTo:
|
|
60
|
+
isMatch = trapOid !== expectedOid;
|
|
61
|
+
break;
|
|
62
|
+
case FilterType.Contains:
|
|
63
|
+
isMatch = trapOid.includes(expectedOid);
|
|
64
|
+
break;
|
|
65
|
+
case FilterType.NotContains:
|
|
66
|
+
isMatch = !trapOid.includes(expectedOid);
|
|
67
|
+
break;
|
|
68
|
+
case FilterType.StartsWith:
|
|
69
|
+
isMatch = trapOid.startsWith(expectedOid);
|
|
70
|
+
break;
|
|
71
|
+
case FilterType.EndsWith:
|
|
72
|
+
isMatch = trapOid.endsWith(expectedOid);
|
|
73
|
+
break;
|
|
74
|
+
default:
|
|
75
|
+
isMatch = false;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (isMatch) {
|
|
79
|
+
return `SNMP trap ${trapOid} received from ${snmpTrap.sourceIpAddress}.`;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (snmpTrap) {
|
|
86
|
+
// Trap events never evaluate check-based criteria.
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
|
|
31
90
|
let overTimeValue: Array<number | boolean> | number | boolean | undefined =
|
|
32
91
|
undefined;
|
|
33
92
|
|
|
@@ -91,6 +150,108 @@ export default class SnmpMonitorCriteria {
|
|
|
91
150
|
});
|
|
92
151
|
}
|
|
93
152
|
|
|
153
|
+
// Check if any monitored interface is down (admin-up but oper-down)
|
|
154
|
+
if (input.criteriaFilter.checkOn === CheckOn.SnmpInterfaceIsDown) {
|
|
155
|
+
const interfaces: Array<SnmpInterface> | undefined =
|
|
156
|
+
snmpResponse?.interfaces;
|
|
157
|
+
|
|
158
|
+
if (!interfaces || interfaces.length === 0) {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/*
|
|
163
|
+
* Administratively disabled interfaces are intentionally down and
|
|
164
|
+
* never count as failures.
|
|
165
|
+
*/
|
|
166
|
+
const downInterfaces: Array<SnmpInterface> = interfaces.filter(
|
|
167
|
+
(snmpInterface: SnmpInterface) => {
|
|
168
|
+
return (
|
|
169
|
+
snmpInterface.isAdministrativelyUp &&
|
|
170
|
+
!snmpInterface.isOperationallyUp
|
|
171
|
+
);
|
|
172
|
+
},
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
const isTrueFilter: boolean =
|
|
176
|
+
input.criteriaFilter.filterType === FilterType.True;
|
|
177
|
+
const isFalseFilter: boolean =
|
|
178
|
+
input.criteriaFilter.filterType === FilterType.False;
|
|
179
|
+
|
|
180
|
+
if (downInterfaces.length > 0 && isTrueFilter) {
|
|
181
|
+
const names: string = downInterfaces
|
|
182
|
+
.slice(0, 5)
|
|
183
|
+
.map((snmpInterface: SnmpInterface) => {
|
|
184
|
+
return snmpInterface.name;
|
|
185
|
+
})
|
|
186
|
+
.join(", ");
|
|
187
|
+
return `${downInterfaces.length} interface(s) down: ${names}${
|
|
188
|
+
downInterfaces.length > 5 ? ", …" : ""
|
|
189
|
+
}.`;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (downInterfaces.length === 0 && isFalseFilter) {
|
|
193
|
+
return "All administratively enabled interfaces are up.";
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Check the busiest interface's utilization
|
|
200
|
+
if (
|
|
201
|
+
input.criteriaFilter.checkOn === CheckOn.SnmpInterfaceUtilizationPercent
|
|
202
|
+
) {
|
|
203
|
+
threshold = CompareCriteria.convertToNumber(threshold);
|
|
204
|
+
|
|
205
|
+
if (threshold === null || threshold === undefined) {
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const utilizations: Array<number> = (snmpResponse?.interfaces || [])
|
|
210
|
+
.map((snmpInterface: SnmpInterface) => {
|
|
211
|
+
return snmpInterface.utilizationPercent;
|
|
212
|
+
})
|
|
213
|
+
.filter((value: number | undefined): value is number => {
|
|
214
|
+
return typeof value === "number";
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
if (utilizations.length === 0) {
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return CompareCriteria.compareCriteriaNumbers({
|
|
222
|
+
value: Math.max(...utilizations),
|
|
223
|
+
threshold: threshold as number,
|
|
224
|
+
criteriaFilter: input.criteriaFilter,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Check the worst interface's error rate
|
|
229
|
+
if (input.criteriaFilter.checkOn === CheckOn.SnmpInterfaceErrorsPerSecond) {
|
|
230
|
+
threshold = CompareCriteria.convertToNumber(threshold);
|
|
231
|
+
|
|
232
|
+
if (threshold === null || threshold === undefined) {
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const errorRates: Array<number> = (snmpResponse?.interfaces || [])
|
|
237
|
+
.map((snmpInterface: SnmpInterface) => {
|
|
238
|
+
return snmpInterface.errorsPerSecond;
|
|
239
|
+
})
|
|
240
|
+
.filter((value: number | undefined): value is number => {
|
|
241
|
+
return typeof value === "number";
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
if (errorRates.length === 0) {
|
|
245
|
+
return null;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return CompareCriteria.compareCriteriaNumbers({
|
|
249
|
+
value: Math.max(...errorRates),
|
|
250
|
+
threshold: threshold as number,
|
|
251
|
+
criteriaFilter: input.criteriaFilter,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
|
|
94
255
|
// Check if a specific OID exists (returns a value)
|
|
95
256
|
if (input.criteriaFilter.checkOn === CheckOn.SnmpOidExists) {
|
|
96
257
|
const oid: string | undefined =
|
|
@@ -145,8 +306,15 @@ export default class SnmpMonitorCriteria {
|
|
|
145
306
|
|
|
146
307
|
const oidValue: string | number = oidResponse.value;
|
|
147
308
|
|
|
148
|
-
|
|
149
|
-
|
|
309
|
+
/*
|
|
310
|
+
* Numeric comparison — only when the value is genuinely numeric. Guard
|
|
311
|
+
* against empty/whitespace OctetStrings, which Number("") coerces to 0
|
|
312
|
+
* and would spuriously satisfy a "== 0" criterion.
|
|
313
|
+
*/
|
|
314
|
+
const isNumeric: boolean =
|
|
315
|
+
typeof oidValue === "number" ||
|
|
316
|
+
(String(oidValue).trim() !== "" && !isNaN(Number(oidValue)));
|
|
317
|
+
if (isNumeric) {
|
|
150
318
|
const numericValue: number =
|
|
151
319
|
typeof oidValue === "number" ? oidValue : Number(oidValue);
|
|
152
320
|
const numericThreshold: number | null =
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import AggregatedResult from "../../../Types/BaseDatabase/AggregatedResult";
|
|
2
|
+
import { JSONObject } from "../../../Types/JSON";
|
|
3
|
+
import MetricSeriesResult from "../../../Types/Monitor/MetricMonitor/MetricSeriesResult";
|
|
4
|
+
import MetricSeriesFingerprint from "../../../Utils/Metrics/MetricSeriesFingerprint";
|
|
5
|
+
|
|
6
|
+
/*
|
|
7
|
+
* Pure helpers backing per-device "went silent" detection for IoT
|
|
8
|
+
* Device monitors — the IoT analogue of HostAbsenceSeries (which also
|
|
9
|
+
* supplies the shared monitorStepOptsIntoNoDataDetection and
|
|
10
|
+
* queriesScopeHostSubset gates; both are entity-agnostic).
|
|
11
|
+
*
|
|
12
|
+
* A group-by-device metric query only returns a series for devices
|
|
13
|
+
* that emitted rows in the evaluation window — a device that stopped
|
|
14
|
+
* reporting simply has no row, so its absence is invisible to the
|
|
15
|
+
* criteria evaluator. These helpers synthesize an empty "no data"
|
|
16
|
+
* series for every REGISTERED device (IoTDeviceCredential) missing
|
|
17
|
+
* from the current window, so the per-series NoDataPolicy path fires
|
|
18
|
+
* one correctly-labeled alert per silent device. Kept pure (no DB) so
|
|
19
|
+
* the gating and series construction are unit-testable; the worker
|
|
20
|
+
* supplies the expected-device list.
|
|
21
|
+
*
|
|
22
|
+
* Unlike hosts there is NO recency aging: registration is an explicit
|
|
23
|
+
* expected-list, so a registered-but-silent device alerts until its
|
|
24
|
+
* credential is disabled or deleted — that is the designed semantic.
|
|
25
|
+
*
|
|
26
|
+
* Device ids are handled VERBATIM: device.id datapoint labels are
|
|
27
|
+
* stored byte-exact (unlike host.name, which is canonicalized at
|
|
28
|
+
* ingest), so canonicalizing here would fork the fingerprint from the
|
|
29
|
+
* device's real series and break incident dedupe/auto-resolve.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
// The datapoint label that identifies a device within a fleet.
|
|
33
|
+
export const IOT_DEVICE_ID_ATTRIBUTE_KEY: string = "device.id";
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* If the monitor is grouped by exactly the device-id label, return
|
|
37
|
+
* that group-by key; otherwise null. Absent-device synthesis only
|
|
38
|
+
* makes sense for a pure per-device group-by.
|
|
39
|
+
*/
|
|
40
|
+
export function getIoTDeviceAbsenceGroupByKey(
|
|
41
|
+
groupByAttributeKeys: Array<string>,
|
|
42
|
+
): string | null {
|
|
43
|
+
if (!groupByAttributeKeys || groupByAttributeKeys.length !== 1) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
const key: string = groupByAttributeKeys[0]!;
|
|
47
|
+
return key === IOT_DEVICE_ID_ATTRIBUTE_KEY ? key : null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Build synthetic "no data" series for every registered device absent
|
|
52
|
+
* from the current window's series breakdown. Each synthetic series
|
|
53
|
+
* has empty aggregated-result slots (one per query + formula,
|
|
54
|
+
* matching how present series are shaped) so the criteria evaluator's
|
|
55
|
+
* NoDataPolicy path fires for it, and labels/fingerprint identical to
|
|
56
|
+
* what the device's present series would carry so the resulting
|
|
57
|
+
* incident dedupes and auto-resolves when the device returns.
|
|
58
|
+
*/
|
|
59
|
+
export function buildAbsentIoTDeviceSeries(input: {
|
|
60
|
+
presentSeries: Array<MetricSeriesResult>;
|
|
61
|
+
expectedDeviceExternalIds: Array<string>;
|
|
62
|
+
deviceKey: string;
|
|
63
|
+
slotCount: number;
|
|
64
|
+
}): Array<MetricSeriesResult> {
|
|
65
|
+
const presentDevices: Set<string> = new Set<string>();
|
|
66
|
+
for (const series of input.presentSeries) {
|
|
67
|
+
const raw: unknown = series.labels?.[input.deviceKey];
|
|
68
|
+
if (raw === undefined || raw === null || String(raw) === "") {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
presentDevices.add(String(raw));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const slotCount: number = Math.max(input.slotCount, 1);
|
|
75
|
+
const seen: Set<string> = new Set<string>();
|
|
76
|
+
const absentSeries: Array<MetricSeriesResult> = [];
|
|
77
|
+
|
|
78
|
+
for (const externalId of input.expectedDeviceExternalIds) {
|
|
79
|
+
const identifier: string = String(externalId);
|
|
80
|
+
if (!identifier || presentDevices.has(identifier) || seen.has(identifier)) {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
seen.add(identifier);
|
|
84
|
+
|
|
85
|
+
const labels: JSONObject = { [input.deviceKey]: identifier };
|
|
86
|
+
const aggregatedResults: Array<AggregatedResult> = Array.from(
|
|
87
|
+
{ length: slotCount },
|
|
88
|
+
(): AggregatedResult => {
|
|
89
|
+
return { data: [] };
|
|
90
|
+
},
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
absentSeries.push({
|
|
94
|
+
fingerprint: MetricSeriesFingerprint.computeFingerprint(labels),
|
|
95
|
+
labels,
|
|
96
|
+
aggregatedResults,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return absentSeries;
|
|
101
|
+
}
|
|
@@ -749,9 +749,21 @@ export default class MonitorAlert {
|
|
|
749
749
|
input.breachingSeriesFingerprints !== undefined &&
|
|
750
750
|
openSeriesFingerprint
|
|
751
751
|
) {
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
752
|
+
/*
|
|
753
|
+
* The breaching set is the matched criteria's per-series matches.
|
|
754
|
+
* On a recovery tick the matched criteria is the RECOVERY criteria
|
|
755
|
+
* and its matches are healthy series, not breaches; counting them
|
|
756
|
+
* would pin the open offline alert open forever. Membership only
|
|
757
|
+
* counts as still-breaching when the matched criteria actually
|
|
758
|
+
* creates alerts (createAlerts=false recovery criteria contributes
|
|
759
|
+
* no breaches, letting the per-series alert auto-resolve).
|
|
760
|
+
*/
|
|
761
|
+
const matchedCriteriaCreatesAlerts: boolean =
|
|
762
|
+
input.criteriaInstance?.data?.createAlerts === true;
|
|
763
|
+
|
|
764
|
+
const stillBreaching: boolean =
|
|
765
|
+
matchedCriteriaCreatesAlerts &&
|
|
766
|
+
input.breachingSeriesFingerprints.has(openSeriesFingerprint);
|
|
755
767
|
|
|
756
768
|
if (stillBreaching) {
|
|
757
769
|
return false;
|
|
@@ -775,7 +775,7 @@ ${contextBlock}
|
|
|
775
775
|
}
|
|
776
776
|
}
|
|
777
777
|
|
|
778
|
-
if (input.monitor.monitorType === MonitorType.
|
|
778
|
+
if (input.monitor.monitorType === MonitorType.NetworkDevice) {
|
|
779
779
|
const snmpMonitorResult: string | null =
|
|
780
780
|
await SnmpMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
|
|
781
781
|
dataToProcess: input.dataToProcess,
|
|
@@ -1141,9 +1141,25 @@ export default class MonitorIncident {
|
|
|
1141
1141
|
input.breachingSeriesFingerprints !== undefined &&
|
|
1142
1142
|
openSeriesFingerprint
|
|
1143
1143
|
) {
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1144
|
+
/*
|
|
1145
|
+
* The breaching set is the matched criteria's per-series matches.
|
|
1146
|
+
* Only ONE criteria wins per evaluation tick, so on a recovery
|
|
1147
|
+
* tick the matched criteria is the RECOVERY criteria (e.g.
|
|
1148
|
+
* Min(iot_device_up) >= 1) and its "matches" are healthy series —
|
|
1149
|
+
* NOT breaches. Treating them as breaching would leave the open
|
|
1150
|
+
* offline incident's fingerprint in the set and pin it open
|
|
1151
|
+
* forever once no other series is down. So membership only counts
|
|
1152
|
+
* as still-breaching when the matched criteria actually creates
|
|
1153
|
+
* incidents (an offline/breach criteria); a recovery criteria
|
|
1154
|
+
* (createIncidents=false) contributes no breaches and lets the
|
|
1155
|
+
* per-series incident auto-resolve.
|
|
1156
|
+
*/
|
|
1157
|
+
const matchedCriteriaCreatesIncidents: boolean =
|
|
1158
|
+
input.criteriaInstance?.data?.createIncidents === true;
|
|
1159
|
+
|
|
1160
|
+
const stillBreaching: boolean =
|
|
1161
|
+
matchedCriteriaCreatesIncidents &&
|
|
1162
|
+
input.breachingSeriesFingerprints.has(openSeriesFingerprint);
|
|
1147
1163
|
|
|
1148
1164
|
if (stillBreaching) {
|
|
1149
1165
|
return false;
|
|
@@ -17,6 +17,7 @@ import CapturedMetric from "../../../Types/Monitor/CustomCodeMonitor/CapturedMet
|
|
|
17
17
|
import HttpPhaseTimings from "../../../Types/Monitor/HttpPhaseTimings";
|
|
18
18
|
import MonitorMetricType from "../../../Types/Monitor/MonitorMetricType";
|
|
19
19
|
import PingMonitorResponse from "../../../Types/Monitor/PingMonitor/PingMonitorResponse";
|
|
20
|
+
import SnmpInterface from "../../../Types/Monitor/SnmpMonitor/SnmpInterface";
|
|
20
21
|
import ProbeMonitorResponse from "../../../Types/Probe/ProbeMonitorResponse";
|
|
21
22
|
import ServerMonitorResponse from "../../../Types/Monitor/ServerMonitor/ServerMonitorResponse";
|
|
22
23
|
import SyntheticMonitorResponse from "../../../Types/Monitor/SyntheticMonitors/SyntheticMonitorResponse";
|
|
@@ -889,6 +890,92 @@ export default class MonitorMetricUtil {
|
|
|
889
890
|
metricNameServiceNameMap[MonitorMetricType.ResponseTime] = metricType;
|
|
890
891
|
}
|
|
891
892
|
|
|
893
|
+
const snmpInterfaces: Array<SnmpInterface> | undefined = (
|
|
894
|
+
data.dataToProcess as ProbeMonitorResponse
|
|
895
|
+
).snmpResponse?.interfaces;
|
|
896
|
+
|
|
897
|
+
if (snmpInterfaces && snmpInterfaces.length > 0) {
|
|
898
|
+
/*
|
|
899
|
+
* Cap per-check interface series to keep a single check from writing
|
|
900
|
+
* unbounded rows (large routers can expose thousands of
|
|
901
|
+
* subinterfaces). Same approach as the custom-metric cap below.
|
|
902
|
+
*/
|
|
903
|
+
const interfacesToEmit: Array<SnmpInterface> = snmpInterfaces.slice(
|
|
904
|
+
0,
|
|
905
|
+
200,
|
|
906
|
+
);
|
|
907
|
+
|
|
908
|
+
if (interfacesToEmit.length < snmpInterfaces.length) {
|
|
909
|
+
logger.warn(
|
|
910
|
+
`Monitor ${data.monitorId.toString()}: emitting metrics for first ${interfacesToEmit.length} of ${snmpInterfaces.length} SNMP interfaces`,
|
|
911
|
+
);
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
for (const snmpInterface of interfacesToEmit) {
|
|
915
|
+
const extraAttributes: JSONObject = {
|
|
916
|
+
probeId: (
|
|
917
|
+
data.dataToProcess as ProbeMonitorResponse
|
|
918
|
+
).probeId.toString(),
|
|
919
|
+
interfaceName: snmpInterface.name,
|
|
920
|
+
interfaceIndex: snmpInterface.interfaceIndex.toString(),
|
|
921
|
+
};
|
|
922
|
+
|
|
923
|
+
const interfaceMetrics: Array<{
|
|
924
|
+
metricName: MonitorMetricType;
|
|
925
|
+
value: number | undefined;
|
|
926
|
+
description: string;
|
|
927
|
+
unit: string;
|
|
928
|
+
}> = [
|
|
929
|
+
{
|
|
930
|
+
metricName: MonitorMetricType.SnmpInterfaceOperStatus,
|
|
931
|
+
value: snmpInterface.isOperationallyUp ? 1 : 0,
|
|
932
|
+
description: "SNMP interface operational status (1 up, 0 down)",
|
|
933
|
+
unit: "",
|
|
934
|
+
},
|
|
935
|
+
{
|
|
936
|
+
metricName: MonitorMetricType.SnmpInterfaceInBitsPerSecond,
|
|
937
|
+
value: snmpInterface.inBitsPerSecond,
|
|
938
|
+
description: "SNMP interface inbound bandwidth",
|
|
939
|
+
unit: "bps",
|
|
940
|
+
},
|
|
941
|
+
{
|
|
942
|
+
metricName: MonitorMetricType.SnmpInterfaceOutBitsPerSecond,
|
|
943
|
+
value: snmpInterface.outBitsPerSecond,
|
|
944
|
+
description: "SNMP interface outbound bandwidth",
|
|
945
|
+
unit: "bps",
|
|
946
|
+
},
|
|
947
|
+
{
|
|
948
|
+
metricName: MonitorMetricType.SnmpInterfaceUtilizationPercent,
|
|
949
|
+
value: snmpInterface.utilizationPercent,
|
|
950
|
+
description: "SNMP interface utilization",
|
|
951
|
+
unit: "%",
|
|
952
|
+
},
|
|
953
|
+
{
|
|
954
|
+
metricName: MonitorMetricType.SnmpInterfaceErrorsPerSecond,
|
|
955
|
+
value: snmpInterface.errorsPerSecond,
|
|
956
|
+
description: "SNMP interface errors per second",
|
|
957
|
+
unit: "errors/s",
|
|
958
|
+
},
|
|
959
|
+
];
|
|
960
|
+
|
|
961
|
+
for (const interfaceMetric of interfaceMetrics) {
|
|
962
|
+
await this.pushMonitorMetric({
|
|
963
|
+
projectId: data.projectId,
|
|
964
|
+
monitorId: data.monitorId,
|
|
965
|
+
monitorName: data.monitorName,
|
|
966
|
+
probeName: data.probeName,
|
|
967
|
+
metricName: interfaceMetric.metricName,
|
|
968
|
+
value: interfaceMetric.value,
|
|
969
|
+
description: interfaceMetric.description,
|
|
970
|
+
unit: interfaceMetric.unit,
|
|
971
|
+
extraAttributes: extraAttributes,
|
|
972
|
+
metricRows: metricRows,
|
|
973
|
+
metricNameServiceNameMap: metricNameServiceNameMap,
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
|
|
892
979
|
if ((data.dataToProcess as ProbeMonitorResponse).httpTimings) {
|
|
893
980
|
const httpTimings: HttpPhaseTimings = (
|
|
894
981
|
data.dataToProcess as ProbeMonitorResponse
|
|
@@ -5,10 +5,13 @@ import logger from "../Logger";
|
|
|
5
5
|
import MonitorCriteriaEvaluator from "./MonitorCriteriaEvaluator";
|
|
6
6
|
import MonitorLogUtil from "./MonitorLogUtil";
|
|
7
7
|
import MonitorMetricUtil from "./MonitorMetricUtil";
|
|
8
|
+
import NetworkInventoryUtil from "./NetworkInventoryUtil";
|
|
9
|
+
import SnmpInterfaceRateUtil from "./SnmpInterfaceRateUtil";
|
|
8
10
|
import DataToProcess from "./DataToProcess";
|
|
9
11
|
import SortOrder from "../../../Types/BaseDatabase/SortOrder";
|
|
10
12
|
import Dictionary from "../../../Types/Dictionary";
|
|
11
13
|
import BadDataException from "../../../Types/Exception/BadDataException";
|
|
14
|
+
import { JSONObject } from "../../../Types/JSON";
|
|
12
15
|
import Semaphore, { SemaphoreMutex } from "../../Infrastructure/Semaphore";
|
|
13
16
|
import IncomingMonitorRequest from "../../../Types/Monitor/IncomingMonitor/IncomingMonitorRequest";
|
|
14
17
|
import MonitorCriteria from "../../../Types/Monitor/MonitorCriteria";
|
|
@@ -237,6 +240,16 @@ export default class MonitorResourceUtil {
|
|
|
237
240
|
let probeName: string | undefined = undefined;
|
|
238
241
|
const monitorName: string | undefined = monitor.name || undefined;
|
|
239
242
|
|
|
243
|
+
/*
|
|
244
|
+
* SNMP trap responses are event-driven, not check results. They are
|
|
245
|
+
* evaluated ONLY against trap criteria; they must not overwrite the
|
|
246
|
+
* last check's counters, participate in probe agreement, or reset the
|
|
247
|
+
* monitor to its default status when no criteria matches.
|
|
248
|
+
*/
|
|
249
|
+
const isSnmpTrapEvent: boolean = Boolean(
|
|
250
|
+
(dataToProcess as ProbeMonitorResponse).snmpTrapResponse,
|
|
251
|
+
);
|
|
252
|
+
|
|
240
253
|
// save the last log to MonitorProbe.
|
|
241
254
|
|
|
242
255
|
// get last log. We do this because there are many monitoring steps and we need to store those.
|
|
@@ -275,26 +288,58 @@ export default class MonitorResourceUtil {
|
|
|
275
288
|
|
|
276
289
|
probeName = monitorProbe.probe?.name || undefined;
|
|
277
290
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
291
|
+
/*
|
|
292
|
+
* SNMP interface rates (bandwidth, utilization, errors/sec) are
|
|
293
|
+
* deltas against the previous check's counters — computed here,
|
|
294
|
+
* while the previous log is still available, so the computed
|
|
295
|
+
* values flow into metrics, criteria, and the stored log below.
|
|
296
|
+
*/
|
|
297
|
+
if (monitor.monitorType === MonitorType.NetworkDevice) {
|
|
298
|
+
SnmpInterfaceRateUtil.attachInterfaceRates({
|
|
299
|
+
probeMonitorResponse: dataToProcess as ProbeMonitorResponse,
|
|
300
|
+
previousStepLog: (
|
|
301
|
+
monitorProbe.lastMonitoringLog as JSONObject | undefined
|
|
302
|
+
)?.[
|
|
303
|
+
(dataToProcess as ProbeMonitorResponse).monitorStepId.toString()
|
|
304
|
+
] as JSONObject | undefined,
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
/*
|
|
308
|
+
* Sync the NetworkDevice/NetworkInterface inventory from the
|
|
309
|
+
* walk, then prune the response to monitored interfaces so
|
|
310
|
+
* criteria and metrics ignore muted ports. Trap events carry
|
|
311
|
+
* no walk data — nothing to sync.
|
|
312
|
+
*/
|
|
313
|
+
if (!isSnmpTrapEvent) {
|
|
314
|
+
await NetworkInventoryUtil.updateFromWalk({
|
|
315
|
+
monitor: monitor,
|
|
316
|
+
dataToProcess: dataToProcess as ProbeMonitorResponse,
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (!isSnmpTrapEvent) {
|
|
322
|
+
await MonitorProbeService.updateOneBy({
|
|
323
|
+
query: {
|
|
324
|
+
monitorId: monitor.id!,
|
|
325
|
+
probeId: (dataToProcess as ProbeMonitorResponse).probeId!,
|
|
326
|
+
},
|
|
327
|
+
data: {
|
|
328
|
+
lastMonitoringLog: {
|
|
329
|
+
...(monitorProbe.lastMonitoringLog || {}),
|
|
330
|
+
[(
|
|
331
|
+
dataToProcess as ProbeMonitorResponse
|
|
332
|
+
).monitorStepId.toString()]: {
|
|
333
|
+
...JSON.parse(JSON.stringify(dataToProcess)),
|
|
334
|
+
monitoredAt: OneUptimeDate.getCurrentDate(),
|
|
335
|
+
},
|
|
336
|
+
} as any,
|
|
337
|
+
},
|
|
338
|
+
props: {
|
|
339
|
+
isRoot: true,
|
|
340
|
+
},
|
|
341
|
+
});
|
|
342
|
+
}
|
|
298
343
|
}
|
|
299
344
|
}
|
|
300
345
|
|
|
@@ -603,7 +648,12 @@ export default class MonitorResourceUtil {
|
|
|
603
648
|
// Check probe agreement for probe-based monitors
|
|
604
649
|
if (
|
|
605
650
|
monitor.monitorType &&
|
|
606
|
-
MonitorTypeHelper.isProbableMonitor(monitor.monitorType)
|
|
651
|
+
MonitorTypeHelper.isProbableMonitor(monitor.monitorType) &&
|
|
652
|
+
/*
|
|
653
|
+
* Traps arrive on exactly one probe — other probes' polled state
|
|
654
|
+
* cannot corroborate them, so agreement would always veto the trap.
|
|
655
|
+
*/
|
|
656
|
+
!isSnmpTrapEvent
|
|
607
657
|
) {
|
|
608
658
|
const probeAgreementResult: ProbeAgreementResult =
|
|
609
659
|
await MonitorResourceUtil.checkProbeAgreement({
|
|
@@ -874,6 +924,12 @@ export default class MonitorResourceUtil {
|
|
|
874
924
|
});
|
|
875
925
|
} else if (
|
|
876
926
|
!response.criteriaMetId &&
|
|
927
|
+
/*
|
|
928
|
+
* A trap that matches no criteria is simply ignored — it must not
|
|
929
|
+
* reset the monitor to its default status (the polled checks own
|
|
930
|
+
* the monitor's state).
|
|
931
|
+
*/
|
|
932
|
+
!isSnmpTrapEvent &&
|
|
877
933
|
monitorSteps.data.defaultMonitorStatusId &&
|
|
878
934
|
monitor.currentMonitorStatusId?.toString() !==
|
|
879
935
|
monitorSteps.data.defaultMonitorStatusId.toString()
|
|
@@ -245,7 +245,7 @@ export default class MonitorTemplateUtil {
|
|
|
245
245
|
} as JSONObject;
|
|
246
246
|
}
|
|
247
247
|
|
|
248
|
-
if (data.monitorType === MonitorType.
|
|
248
|
+
if (data.monitorType === MonitorType.NetworkDevice) {
|
|
249
249
|
const snmpResponse: SnmpMonitorResponse | undefined = (
|
|
250
250
|
data.dataToProcess as ProbeMonitorResponse
|
|
251
251
|
).snmpResponse;
|