You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言SNMP多设备查询的异常处理与程序续行需求

Got it, let's fix this issue step by step. The main problem with your original code is that log.Fatalf() immediately terminates the program when an error hits—so your custom error messages never get printed, and you can't proceed to check other devices. Here's a revised solution that meets all your requirements:

Robust Multi-Device SNMP Handling in Go

First, let's break down the core issues in your code:

  • log.Fatalf() calls os.Exit(1) under the hood, killing the program before your custom error messages can run.
  • The code only handles a single device, but you need to process multiple targets.
  • Using the global g.Default instance can cause state conflicts when switching between devices.

Revised Code

package main

import (
	"fmt"
	"log"
	"time"

	g "github.com/soniah/gosnmp"
)

// handleSNMPDevice wraps all logic for querying a single device with error handling
func handleSNMPDevice(target string, oids []string) {
	// Create a fresh SNMP instance for each device to avoid cross-device state issues
	snmpClient := &g.GoSNMP{
		Target:    target,
		Port:      161,
		Version:   g.Version2c,
		Community: "public", // Update this to match your device's SNMP community
		Timeout:   5 * time.Second,
		Retries:   3,
	}

	// Handle connection failures
	err := snmpClient.Connect()
	if err != nil {
		log.Printf("Connection to %s failed: %v", target, err)
		fmt.Println("Fail connection")
		return // Exit this function, move to next device
	}
	defer snmpClient.Conn.Close() // Ensure connection is closed when done

	// Handle OID read errors
	result, readErr := snmpClient.Get(oids)
	if readErr != nil {
		log.Printf("OID read from %s failed: %v", target, readErr)
		fmt.Println("Error read OID")
		return // Exit this function, move to next device
	}

	// Print successful results
	fmt.Printf("\n--- Results for %s ---\n", target)
	for idx, variable := range result.Variables {
		fmt.Printf("%d: oid: %s ", idx, variable.Name)
		switch variable.Type {
		case g.OctetString:
			fmt.Printf("string: %s\n", string(variable.Value.([]byte)))
		default:
			fmt.Printf("number: %d\n", g.ToBigInt(variable.Value))
		}
	}
}

func main() {
	// List of devices you want to query
	targetDevices := []string{"192.168.10.1", "192.168.10.2", "192.168.10.3"}
	targetOIDs := []string{"1.3.6.1.2.1.1.4.0", "1.3.6.1.2.1.1.7.0"}

	// Process each device sequentially
	for _, device := range targetDevices {
		handleSNMPDevice(device, targetOIDs)
	}

	fmt.Println("\nAll devices processed successfully")
}

Key Changes Explained

  • Removed log.Fatalf(): We use log.Printf() instead, which logs errors without terminating the program. This lets your custom error messages print and allows the program to move to the next device.
  • Per-Device SNMP Instances: Creating a new GoSNMP client for each device prevents state leakage (like leftover connection settings) between targets, making the code more reliable.
  • Encapsulated Logic: The handleSNMPDevice function wraps all logic for a single device, making the code cleaner and easier to modify later.
  • Explicit Error Returns: Each error condition (connection failure, OID read failure) exits the function early, so the program continues processing other devices instead of crashing.
  • Multi-Device Support: We added a list of target devices and loop through them, so you can easily add more devices to query.

Quick Notes

  • Update the Community string to match your devices' actual SNMP community settings.
  • Adjust Timeout and Retries based on your network conditions to reduce false timeouts.
  • If you want faster processing, you can add goroutines to handle multiple devices in parallel (just add synchronization like a sync.WaitGroup if needed).

内容的提问来源于stack exchange,提问作者Сергей Власов

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:36:11