@oneuptime/common 11.4.1 → 11.5.0
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 +24 -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/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 +24 -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/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
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import NetworkDevice from "../../../Models/DatabaseModels/NetworkDevice";
|
|
2
|
+
import NetworkDeviceService from "../../Services/NetworkDeviceService";
|
|
3
|
+
import MonitorSteps from "../../../Types/Monitor/MonitorSteps";
|
|
4
|
+
import QueryHelper from "../../Types/Database/QueryHelper";
|
|
5
|
+
import LIMIT_MAX from "../../../Types/Database/LimitMax";
|
|
6
|
+
import MonitorType from "../../../Types/Monitor/MonitorType";
|
|
7
|
+
import SnmpVersion from "../../../Types/Monitor/SnmpMonitor/SnmpVersion";
|
|
8
|
+
import SnmpV3Auth from "../../../Types/Monitor/SnmpMonitor/SnmpV3Auth";
|
|
9
|
+
import SnmpSecurityLevel from "../../../Types/Monitor/SnmpMonitor/SnmpSecurityLevel";
|
|
10
|
+
import SnmpAuthProtocol from "../../../Types/Monitor/SnmpMonitor/SnmpAuthProtocol";
|
|
11
|
+
import SnmpPrivProtocol from "../../../Types/Monitor/SnmpMonitor/SnmpPrivProtocol";
|
|
12
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
13
|
+
import logger from "../Logger";
|
|
14
|
+
|
|
15
|
+
/*
|
|
16
|
+
* Network Device monitor steps reference a NetworkDevice resource instead of
|
|
17
|
+
* carrying SNMP connection details. Probes are stateless and only understand
|
|
18
|
+
* concrete SNMP config, so before work is handed out the referenced device's
|
|
19
|
+
* hostname/credentials are hydrated into each step's `snmpMonitor` field.
|
|
20
|
+
*/
|
|
21
|
+
export interface HydratableMonitor {
|
|
22
|
+
id?: ObjectID | null | undefined;
|
|
23
|
+
monitorType?: MonitorType | undefined;
|
|
24
|
+
monitorSteps?: MonitorSteps | undefined;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default class NetworkDeviceHydrationUtil {
|
|
28
|
+
// Accepts Monitor and MonitorTest alike (structural: monitorType + monitorSteps).
|
|
29
|
+
public static async hydrateNetworkDeviceMonitors(
|
|
30
|
+
monitors: Array<HydratableMonitor>,
|
|
31
|
+
): Promise<void> {
|
|
32
|
+
const deviceIds: Set<string> = new Set();
|
|
33
|
+
|
|
34
|
+
for (const monitor of monitors) {
|
|
35
|
+
if (monitor.monitorType !== MonitorType.NetworkDevice) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
for (const step of monitor.monitorSteps?.data
|
|
40
|
+
?.monitorStepsInstanceArray || []) {
|
|
41
|
+
const deviceId: string | undefined =
|
|
42
|
+
step.data?.networkDeviceMonitor?.networkDeviceId;
|
|
43
|
+
if (deviceId) {
|
|
44
|
+
deviceIds.add(deviceId);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (deviceIds.size === 0) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const devices: Array<NetworkDevice> = await NetworkDeviceService.findBy({
|
|
54
|
+
query: {
|
|
55
|
+
_id: QueryHelper.any(Array.from(deviceIds)),
|
|
56
|
+
},
|
|
57
|
+
select: {
|
|
58
|
+
_id: true,
|
|
59
|
+
hostname: true,
|
|
60
|
+
snmpVersion: true,
|
|
61
|
+
snmpCommunityString: true,
|
|
62
|
+
snmpPort: true,
|
|
63
|
+
snmpV3Auth: true,
|
|
64
|
+
snmpV3SecurityLevel: true,
|
|
65
|
+
snmpV3Username: true,
|
|
66
|
+
snmpV3AuthProtocol: true,
|
|
67
|
+
snmpV3AuthKey: true,
|
|
68
|
+
snmpV3PrivProtocol: true,
|
|
69
|
+
snmpV3PrivKey: true,
|
|
70
|
+
},
|
|
71
|
+
limit: LIMIT_MAX,
|
|
72
|
+
skip: 0,
|
|
73
|
+
props: {
|
|
74
|
+
isRoot: true,
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const devicesById: Map<string, NetworkDevice> = new Map();
|
|
79
|
+
for (const device of devices) {
|
|
80
|
+
if (device.id) {
|
|
81
|
+
devicesById.set(device.id.toString(), device);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
for (const monitor of monitors) {
|
|
86
|
+
if (monitor.monitorType !== MonitorType.NetworkDevice) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
for (const step of monitor.monitorSteps?.data
|
|
91
|
+
?.monitorStepsInstanceArray || []) {
|
|
92
|
+
const deviceId: string | undefined =
|
|
93
|
+
step.data?.networkDeviceMonitor?.networkDeviceId;
|
|
94
|
+
|
|
95
|
+
if (!deviceId || !step.data) {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const device: NetworkDevice | undefined = devicesById.get(deviceId);
|
|
100
|
+
|
|
101
|
+
if (!device || !device.hostname) {
|
|
102
|
+
logger.warn(
|
|
103
|
+
`Network Device monitor ${monitor.id?.toString()} references missing device ${deviceId}. Step will not be executable.`,
|
|
104
|
+
);
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
step.data.snmpMonitor = {
|
|
109
|
+
snmpVersion: NetworkDeviceHydrationUtil.parseSnmpVersion(
|
|
110
|
+
device.snmpVersion,
|
|
111
|
+
),
|
|
112
|
+
hostname: device.hostname,
|
|
113
|
+
port: device.snmpPort || 161,
|
|
114
|
+
communityString: device.snmpCommunityString || undefined,
|
|
115
|
+
snmpV3Auth: NetworkDeviceHydrationUtil.buildSnmpV3Auth(device),
|
|
116
|
+
oids: step.data.networkDeviceMonitor?.oids || [],
|
|
117
|
+
timeout: 5000,
|
|
118
|
+
retries: 3,
|
|
119
|
+
monitorInterfaces:
|
|
120
|
+
step.data.networkDeviceMonitor?.monitorInterfaces !== false,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/*
|
|
127
|
+
* Assembles the SnmpV3Auth object the probe expects. Prefers the flattened
|
|
128
|
+
* snmpV3* columns (the current storage), falling back to the deprecated
|
|
129
|
+
* snmpV3Auth JSON column so devices created before the columns existed keep
|
|
130
|
+
* working. Returns undefined when no v3 username is configured.
|
|
131
|
+
*/
|
|
132
|
+
private static buildSnmpV3Auth(
|
|
133
|
+
device: NetworkDevice,
|
|
134
|
+
): SnmpV3Auth | undefined {
|
|
135
|
+
if (device.snmpV3Username) {
|
|
136
|
+
return {
|
|
137
|
+
securityLevel:
|
|
138
|
+
(device.snmpV3SecurityLevel as SnmpSecurityLevel) ||
|
|
139
|
+
SnmpSecurityLevel.NoAuthNoPriv,
|
|
140
|
+
username: device.snmpV3Username,
|
|
141
|
+
authProtocol:
|
|
142
|
+
(device.snmpV3AuthProtocol as SnmpAuthProtocol | undefined) ||
|
|
143
|
+
undefined,
|
|
144
|
+
authKey: device.snmpV3AuthKey || undefined,
|
|
145
|
+
privProtocol:
|
|
146
|
+
(device.snmpV3PrivProtocol as SnmpPrivProtocol | undefined) ||
|
|
147
|
+
undefined,
|
|
148
|
+
privKey: device.snmpV3PrivKey || undefined,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Legacy devices stored the whole object in the snmpV3Auth JSON column.
|
|
153
|
+
const legacy: SnmpV3Auth | undefined = device.snmpV3Auth as
|
|
154
|
+
| SnmpV3Auth
|
|
155
|
+
| undefined;
|
|
156
|
+
if (legacy && legacy.username) {
|
|
157
|
+
return legacy;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return undefined;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Tolerates both enum values ("2c") and enum keys ("V2c") in stored config.
|
|
164
|
+
private static parseSnmpVersion(value: string | undefined): SnmpVersion {
|
|
165
|
+
switch ((value || "").toLowerCase()) {
|
|
166
|
+
case "1":
|
|
167
|
+
case "v1":
|
|
168
|
+
return SnmpVersion.V1;
|
|
169
|
+
case "3":
|
|
170
|
+
case "v3":
|
|
171
|
+
return SnmpVersion.V3;
|
|
172
|
+
default:
|
|
173
|
+
return SnmpVersion.V2c;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/*
|
|
178
|
+
* Resolves which NetworkDevices (polled by the given probe) match a trap
|
|
179
|
+
* source IP. Used by the trap ingest to fan traps out to device monitors.
|
|
180
|
+
*/
|
|
181
|
+
public static async findDevicesByProbeAndSource(data: {
|
|
182
|
+
probeId: ObjectID;
|
|
183
|
+
sourceIpAddress: string;
|
|
184
|
+
}): Promise<Array<NetworkDevice>> {
|
|
185
|
+
return NetworkDeviceService.findBy({
|
|
186
|
+
query: {
|
|
187
|
+
probeId: data.probeId,
|
|
188
|
+
hostname: data.sourceIpAddress,
|
|
189
|
+
},
|
|
190
|
+
select: {
|
|
191
|
+
_id: true,
|
|
192
|
+
projectId: true,
|
|
193
|
+
},
|
|
194
|
+
limit: LIMIT_MAX,
|
|
195
|
+
skip: 0,
|
|
196
|
+
props: {
|
|
197
|
+
isRoot: true,
|
|
198
|
+
},
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import Monitor from "../../../Models/DatabaseModels/Monitor";
|
|
2
|
+
import NetworkInterface from "../../../Models/DatabaseModels/NetworkInterface";
|
|
3
|
+
import NetworkDeviceService from "../../Services/NetworkDeviceService";
|
|
4
|
+
import NetworkInterfaceService from "../../Services/NetworkInterfaceService";
|
|
5
|
+
import LIMIT_MAX from "../../../Types/Database/LimitMax";
|
|
6
|
+
import MonitorStep from "../../../Types/Monitor/MonitorStep";
|
|
7
|
+
import SnmpInterface from "../../../Types/Monitor/SnmpMonitor/SnmpInterface";
|
|
8
|
+
import LldpNeighbor from "../../../Types/Monitor/SnmpMonitor/LldpNeighbor";
|
|
9
|
+
import ProbeMonitorResponse from "../../../Types/Probe/ProbeMonitorResponse";
|
|
10
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
11
|
+
import OneUptimeDate from "../../../Types/Date";
|
|
12
|
+
import logger from "../Logger";
|
|
13
|
+
|
|
14
|
+
/*
|
|
15
|
+
* Keeps the NetworkDevice / NetworkInterface inventory in sync with each
|
|
16
|
+
* interface walk, then prunes the in-flight response down to MONITORED
|
|
17
|
+
* interfaces so criteria and metrics only consider ports the user cares
|
|
18
|
+
* about. Inventory rows always reflect every walked interface; the
|
|
19
|
+
* isMonitored flag is user-owned and never overwritten here.
|
|
20
|
+
*/
|
|
21
|
+
export default class NetworkInventoryUtil {
|
|
22
|
+
public static async updateFromWalk(data: {
|
|
23
|
+
monitor: Monitor;
|
|
24
|
+
dataToProcess: ProbeMonitorResponse;
|
|
25
|
+
}): Promise<void> {
|
|
26
|
+
const step: MonitorStep | undefined =
|
|
27
|
+
data.monitor.monitorSteps?.data?.monitorStepsInstanceArray?.find(
|
|
28
|
+
(monitorStep: MonitorStep) => {
|
|
29
|
+
return (
|
|
30
|
+
monitorStep.id.toString() ===
|
|
31
|
+
data.dataToProcess.monitorStepId.toString()
|
|
32
|
+
);
|
|
33
|
+
},
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const deviceIdAsString: string | undefined =
|
|
37
|
+
step?.data?.networkDeviceMonitor?.networkDeviceId;
|
|
38
|
+
|
|
39
|
+
if (!deviceIdAsString || !data.monitor.projectId) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const deviceId: ObjectID = new ObjectID(deviceIdAsString);
|
|
44
|
+
const walkedInterfaces: Array<SnmpInterface> =
|
|
45
|
+
data.dataToProcess.snmpResponse?.interfaces || [];
|
|
46
|
+
const systemInfo:
|
|
47
|
+
| { sysDescr?: string | undefined; sysName?: string | undefined }
|
|
48
|
+
| undefined = data.dataToProcess.snmpResponse?.systemInfo;
|
|
49
|
+
const lldpNeighbors: Array<LldpNeighbor> | undefined =
|
|
50
|
+
data.dataToProcess.snmpResponse?.lldpNeighbors;
|
|
51
|
+
|
|
52
|
+
const now: Date = OneUptimeDate.getCurrentDate();
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
// --- Device enrichment + cached counts ---
|
|
56
|
+
const deviceUpdate: Record<string, unknown> = {
|
|
57
|
+
lastSeenAt: now,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
if (systemInfo?.sysDescr) {
|
|
61
|
+
deviceUpdate["sysDescr"] = systemInfo.sysDescr.substring(0, 500);
|
|
62
|
+
}
|
|
63
|
+
if (systemInfo?.sysName) {
|
|
64
|
+
deviceUpdate["sysName"] = systemInfo.sysName.substring(0, 100);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/*
|
|
68
|
+
* Store the LLDP snapshot (capped) whenever the walk ran, even if it
|
|
69
|
+
* found nothing — clearing stale neighbors is as important as adding
|
|
70
|
+
* new ones for keeping the topology accurate.
|
|
71
|
+
*/
|
|
72
|
+
if (lldpNeighbors !== undefined) {
|
|
73
|
+
deviceUpdate["lldpNeighbors"] = lldpNeighbors.slice(0, 256);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (walkedInterfaces.length > 0) {
|
|
77
|
+
deviceUpdate["interfacesTotal"] = walkedInterfaces.length;
|
|
78
|
+
deviceUpdate["interfacesUp"] = walkedInterfaces.filter(
|
|
79
|
+
(walked: SnmpInterface) => {
|
|
80
|
+
return walked.isAdministrativelyUp && walked.isOperationallyUp;
|
|
81
|
+
},
|
|
82
|
+
).length;
|
|
83
|
+
deviceUpdate["interfacesDown"] = walkedInterfaces.filter(
|
|
84
|
+
(walked: SnmpInterface) => {
|
|
85
|
+
return walked.isAdministrativelyUp && !walked.isOperationallyUp;
|
|
86
|
+
},
|
|
87
|
+
).length;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
await NetworkDeviceService.updateOneById({
|
|
91
|
+
id: deviceId,
|
|
92
|
+
data: deviceUpdate as any,
|
|
93
|
+
props: {
|
|
94
|
+
isRoot: true,
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
if (walkedInterfaces.length === 0) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// --- Interface upsert ---
|
|
103
|
+
const existingInterfaces: Array<NetworkInterface> =
|
|
104
|
+
await NetworkInterfaceService.findBy({
|
|
105
|
+
query: {
|
|
106
|
+
networkDeviceId: deviceId,
|
|
107
|
+
},
|
|
108
|
+
select: {
|
|
109
|
+
_id: true,
|
|
110
|
+
interfaceIndex: true,
|
|
111
|
+
isMonitored: true,
|
|
112
|
+
},
|
|
113
|
+
limit: LIMIT_MAX,
|
|
114
|
+
skip: 0,
|
|
115
|
+
props: {
|
|
116
|
+
isRoot: true,
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
const existingByIndex: Map<number, NetworkInterface> = new Map();
|
|
121
|
+
for (const existing of existingInterfaces) {
|
|
122
|
+
if (existing.interfaceIndex !== undefined) {
|
|
123
|
+
existingByIndex.set(existing.interfaceIndex, existing);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const unmonitoredIndexes: Set<number> = new Set();
|
|
128
|
+
|
|
129
|
+
for (const walked of walkedInterfaces) {
|
|
130
|
+
const existing: NetworkInterface | undefined = existingByIndex.get(
|
|
131
|
+
walked.interfaceIndex,
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
if (existing && existing.isMonitored === false) {
|
|
135
|
+
unmonitoredIndexes.add(walked.interfaceIndex);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const interfaceData: Record<string, unknown> = {
|
|
139
|
+
name: (walked.name || "").substring(0, 100),
|
|
140
|
+
alias: walked.alias ? walked.alias.substring(0, 100) : null,
|
|
141
|
+
isOperationallyUp: walked.isOperationallyUp,
|
|
142
|
+
isAdministrativelyUp: walked.isAdministrativelyUp,
|
|
143
|
+
speedInMbps:
|
|
144
|
+
walked.speedInBitsPerSecond !== undefined
|
|
145
|
+
? walked.speedInBitsPerSecond / 1000000
|
|
146
|
+
: null,
|
|
147
|
+
inRateMbps:
|
|
148
|
+
walked.inBitsPerSecond !== undefined
|
|
149
|
+
? Math.round((walked.inBitsPerSecond / 1000000) * 1000) / 1000
|
|
150
|
+
: null,
|
|
151
|
+
outRateMbps:
|
|
152
|
+
walked.outBitsPerSecond !== undefined
|
|
153
|
+
? Math.round((walked.outBitsPerSecond / 1000000) * 1000) / 1000
|
|
154
|
+
: null,
|
|
155
|
+
utilizationPercent: walked.utilizationPercent ?? null,
|
|
156
|
+
errorsPerSecond: walked.errorsPerSecond ?? null,
|
|
157
|
+
lastSeenAt: now,
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
if (existing && existing.id) {
|
|
161
|
+
await NetworkInterfaceService.updateOneById({
|
|
162
|
+
id: existing.id,
|
|
163
|
+
data: interfaceData as any,
|
|
164
|
+
props: {
|
|
165
|
+
isRoot: true,
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
} else {
|
|
169
|
+
const newInterface: NetworkInterface = new NetworkInterface();
|
|
170
|
+
newInterface.projectId = data.monitor.projectId;
|
|
171
|
+
newInterface.networkDeviceId = deviceId;
|
|
172
|
+
newInterface.interfaceIndex = walked.interfaceIndex;
|
|
173
|
+
newInterface.name = (walked.name || "").substring(0, 100);
|
|
174
|
+
if (walked.alias) {
|
|
175
|
+
newInterface.alias = walked.alias.substring(0, 100);
|
|
176
|
+
}
|
|
177
|
+
newInterface.isMonitored = true;
|
|
178
|
+
newInterface.isOperationallyUp = walked.isOperationallyUp;
|
|
179
|
+
newInterface.isAdministrativelyUp = walked.isAdministrativelyUp;
|
|
180
|
+
if (walked.speedInBitsPerSecond !== undefined) {
|
|
181
|
+
newInterface.speedInMbps = walked.speedInBitsPerSecond / 1000000;
|
|
182
|
+
}
|
|
183
|
+
newInterface.lastSeenAt = now;
|
|
184
|
+
|
|
185
|
+
await NetworkInterfaceService.create({
|
|
186
|
+
data: newInterface,
|
|
187
|
+
props: {
|
|
188
|
+
isRoot: true,
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/*
|
|
195
|
+
* Prune the in-flight response to monitored interfaces only, so
|
|
196
|
+
* criteria (interface down / utilization / errors) and per-interface
|
|
197
|
+
* metrics ignore ports the user muted. The inventory above keeps the
|
|
198
|
+
* full picture.
|
|
199
|
+
*/
|
|
200
|
+
if (unmonitoredIndexes.size > 0 && data.dataToProcess.snmpResponse) {
|
|
201
|
+
data.dataToProcess.snmpResponse.interfaces = walkedInterfaces.filter(
|
|
202
|
+
(walked: SnmpInterface) => {
|
|
203
|
+
return !unmonitoredIndexes.has(walked.interfaceIndex);
|
|
204
|
+
},
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
} catch (err) {
|
|
208
|
+
// Inventory bookkeeping must never fail the check pipeline.
|
|
209
|
+
logger.error(
|
|
210
|
+
`Failed to update network inventory for device ${deviceIdAsString}:`,
|
|
211
|
+
);
|
|
212
|
+
logger.error(err);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { JSONObject } from "../../../Types/JSON";
|
|
2
|
+
import SnmpInterface from "../../../Types/Monitor/SnmpMonitor/SnmpInterface";
|
|
3
|
+
import ProbeMonitorResponse from "../../../Types/Probe/ProbeMonitorResponse";
|
|
4
|
+
import OneUptimeDate from "../../../Types/Date";
|
|
5
|
+
import logger from "../Logger";
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
* Computes per-interface rates (bandwidth, utilization, errors) for SNMP
|
|
9
|
+
* monitors by comparing the cumulative IF-MIB counters of the current check
|
|
10
|
+
* against the previous check stored in MonitorProbe.lastMonitoringLog.
|
|
11
|
+
*
|
|
12
|
+
* Probes stay stateless — the delta is computed here, on ingest, before the
|
|
13
|
+
* response is persisted. Negative deltas (counter wrap or device reboot) are
|
|
14
|
+
* skipped for that interface; rates resume on the following check.
|
|
15
|
+
*/
|
|
16
|
+
export default class SnmpInterfaceRateUtil {
|
|
17
|
+
public static attachInterfaceRates(data: {
|
|
18
|
+
probeMonitorResponse: ProbeMonitorResponse;
|
|
19
|
+
previousStepLog: JSONObject | undefined;
|
|
20
|
+
}): void {
|
|
21
|
+
const interfaces: Array<SnmpInterface> | undefined =
|
|
22
|
+
data.probeMonitorResponse.snmpResponse?.interfaces;
|
|
23
|
+
|
|
24
|
+
if (!interfaces || interfaces.length === 0) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (!data.previousStepLog) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const previousSnmpResponse: JSONObject | undefined = data.previousStepLog[
|
|
33
|
+
"snmpResponse"
|
|
34
|
+
] as JSONObject | undefined;
|
|
35
|
+
|
|
36
|
+
const previousInterfaces: Array<JSONObject> | undefined =
|
|
37
|
+
previousSnmpResponse?.["interfaces"] as Array<JSONObject> | undefined;
|
|
38
|
+
|
|
39
|
+
const previousMonitoredAtValue: unknown =
|
|
40
|
+
data.previousStepLog["monitoredAt"];
|
|
41
|
+
|
|
42
|
+
if (
|
|
43
|
+
!previousInterfaces ||
|
|
44
|
+
previousInterfaces.length === 0 ||
|
|
45
|
+
!previousMonitoredAtValue
|
|
46
|
+
) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const previousMonitoredAt: Date = new Date(
|
|
51
|
+
previousMonitoredAtValue as string,
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
if (isNaN(previousMonitoredAt.getTime())) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/*
|
|
59
|
+
* lastMonitoringLog stores server receipt time as monitoredAt, so the
|
|
60
|
+
* current side of the delta uses server time too.
|
|
61
|
+
*/
|
|
62
|
+
const elapsedSeconds: number =
|
|
63
|
+
(OneUptimeDate.getCurrentDate().getTime() -
|
|
64
|
+
previousMonitoredAt.getTime()) /
|
|
65
|
+
1000;
|
|
66
|
+
|
|
67
|
+
if (elapsedSeconds <= 0) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const counterDelta: (
|
|
72
|
+
currentValue: number | undefined,
|
|
73
|
+
previousValue: unknown,
|
|
74
|
+
) => number | undefined = (
|
|
75
|
+
currentValue: number | undefined,
|
|
76
|
+
previousValue: unknown,
|
|
77
|
+
) => {
|
|
78
|
+
if (
|
|
79
|
+
currentValue === undefined ||
|
|
80
|
+
typeof previousValue !== "number" ||
|
|
81
|
+
!isFinite(previousValue)
|
|
82
|
+
) {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const delta: number = currentValue - previousValue;
|
|
87
|
+
|
|
88
|
+
// Negative delta: counter wrapped or the device rebooted.
|
|
89
|
+
return delta >= 0 ? delta : undefined;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const round: (value: number) => number = (value: number) => {
|
|
93
|
+
return Math.round(value * 100) / 100;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const previousByIndex: Map<number, JSONObject> = new Map();
|
|
97
|
+
for (const previousInterface of previousInterfaces) {
|
|
98
|
+
const index: unknown = previousInterface["interfaceIndex"];
|
|
99
|
+
if (typeof index === "number") {
|
|
100
|
+
previousByIndex.set(index, previousInterface);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
for (const currentInterface of interfaces) {
|
|
105
|
+
const previousInterface: JSONObject | undefined = previousByIndex.get(
|
|
106
|
+
currentInterface.interfaceIndex,
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
if (!previousInterface) {
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const inOctetsDelta: number | undefined = counterDelta(
|
|
114
|
+
currentInterface.inOctets,
|
|
115
|
+
previousInterface["inOctets"],
|
|
116
|
+
);
|
|
117
|
+
const outOctetsDelta: number | undefined = counterDelta(
|
|
118
|
+
currentInterface.outOctets,
|
|
119
|
+
previousInterface["outOctets"],
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
if (inOctetsDelta !== undefined) {
|
|
123
|
+
currentInterface.inBitsPerSecond = round(
|
|
124
|
+
(inOctetsDelta * 8) / elapsedSeconds,
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (outOctetsDelta !== undefined) {
|
|
129
|
+
currentInterface.outBitsPerSecond = round(
|
|
130
|
+
(outOctetsDelta * 8) / elapsedSeconds,
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (
|
|
135
|
+
currentInterface.speedInBitsPerSecond &&
|
|
136
|
+
currentInterface.speedInBitsPerSecond > 0 &&
|
|
137
|
+
(currentInterface.inBitsPerSecond !== undefined ||
|
|
138
|
+
currentInterface.outBitsPerSecond !== undefined)
|
|
139
|
+
) {
|
|
140
|
+
const busiestDirectionBps: number = Math.max(
|
|
141
|
+
currentInterface.inBitsPerSecond || 0,
|
|
142
|
+
currentInterface.outBitsPerSecond || 0,
|
|
143
|
+
);
|
|
144
|
+
currentInterface.utilizationPercent = round(
|
|
145
|
+
(busiestDirectionBps / currentInterface.speedInBitsPerSecond) * 100,
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const inErrorsDelta: number | undefined = counterDelta(
|
|
150
|
+
currentInterface.inErrors,
|
|
151
|
+
previousInterface["inErrors"],
|
|
152
|
+
);
|
|
153
|
+
const outErrorsDelta: number | undefined = counterDelta(
|
|
154
|
+
currentInterface.outErrors,
|
|
155
|
+
previousInterface["outErrors"],
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
if (inErrorsDelta !== undefined || outErrorsDelta !== undefined) {
|
|
159
|
+
currentInterface.errorsPerSecond = round(
|
|
160
|
+
((inErrorsDelta || 0) + (outErrorsDelta || 0)) / elapsedSeconds,
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
logger.debug(
|
|
166
|
+
`Attached SNMP interface rates for monitor ${data.probeMonitorResponse.monitorId.toString()} over ${round(elapsedSeconds)}s window`,
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
}
|