基於snmp 交換機監控系統實現

本博客屬作者原創,未經允許禁止轉載,請尊重原創!如有問題請聯繫QQ509961766

交換機監控系統,主要是監控網絡交換機的各項數據,端口狀態,上下行速率,設備在線狀態以及限速,POE開關控制,設備重啓等等,主要用於網絡環境,機房監控,動環等系統集成。

  • 儀表盤
  • 數據採集
  • 告警處理
  • 網絡安全
  • 數據分析
  • 報表分析
  • 消息推送
  • 網絡性能分析優化
  • 大屏可視化

1.準備工作

1.熟悉SNMP協議
2.熟悉使用MIB Browser調試工具
3.廠商提供私有MIB文件
4.熟悉共有私有OID
5.熟悉使用jPoto HTML5 Canvas

類型 技術棧
前端 JSP Servlet Jquery Echart DataTable Canvas
後端 Spring Struts Hibernate
環境 JDK1.8+ Mysql5.6+ Maven3.5+
工具 IntelliJ IDEA 18.3
部署 Tomcat
類型 說明
廠商 深圳光網視POE交換機
型號 ONV-POE36028PFM
協議 SNMP V2
工具 MIB Browser

2.系統頁面

圖一中分爲3部分:
左上:交換機的上傳下載實時速率,echarts儀表盤
左下:CPU負荷率,echarts折線圖
右邊:機房網絡拓撲圖,用的jPoto HTML5 Canvas實現
在這裏插入圖片描述
圖二是交換機24口的列表信息以及交換機的IP設置,和重啓刷新
在這裏插入圖片描述

3.頁面核心代碼

網絡拓撲圖
基於用jPoto HTML5 Canvas實現的,參照官網Demo

	var canvasHeight = windowHeight - 250;
	var canvasWidth = (windowWidth - 300)/2;
	//初始化畫布
    var canvas = document.getElementById('canvas');
    var stage = new JTopo.Stage(canvas);
    //顯示工具欄
    //showJTopoToobar(stage);
    var scene = new JTopo.Scene();    
    //scene.background = '/ibms/image/bgnew.jpg';
    
    //創建節點
    function node(x, y,img,text){
        var node = new JTopo.Node();
        if(img != null){
	        node.setImage('/ibms/alarmMonitoring/img/' + img, true);                
        }
        if(text != null){
        	node.text = text;
        }
        node.setLocation(x, y);
        scene.add(node);
        return node;
    }                
    

    var dianXin = node(300, 50, 'vpc.png','Internet');
    var jiaoHuanJi = node(300, 150, 'jhj.png','Switch');
    var luYouQi = node(300, 250, 'net1.png','Router');
    
    linkNode(dianXin, jiaoHuanJi, false);
    linkNode(jiaoHuanJi, luYouQi, false);
    
    
    var wangZi = node(50, 500, 'pc.png','WPPC');
    wangZi.alarm = 'CPU負荷:89%\n內存佔用:88%\nCPU溫度:88℃\n上傳速度:55mb/s\n下載速度:88ms/s\n運行時長:12h 45m\nip地址:192.168.1.44\nDNS攻擊:0';
    
    wangZi.paintAlarmText = function(a) {
        if (null != this.alarm && "" != this.alarm) {
            var b = this.alarmColor || "255,140,140",
                c = this.alarmAlpha || .5;
            a.beginPath(),
            a.font = this.alarmFont || "10px 微軟雅黑";

            var textArray = this.alarm.split('\n');
            var rowCnt = textArray.length;
            var i = 0, maxLength = 0, maxText = textArray[0];
            for(;i<rowCnt;i++){
                    var nowText = textArray[i],textLength = nowText.length;
                    if(textLength >=maxLength){
                        maxLength = textLength;
                        maxText = nowText;
                    }
            }
            var maxWidth = a.measureText(maxText).width;
            var lineHeight = 16; // 字體大小 + 6
            // alarm框的寬度
            var d =( (a.measureText(this.alarm).width/rowCnt +6) > maxWidth? (a.measureText(this.alarm).width/rowCnt +6) : maxWidth);
            var e =(lineHeight)*(rowCnt), // alarm 框高度 行高*行數
                f = this.width / 2 - d / 2 , // alarm 框橫向位置
                g = - this.height /2  - e - 20; // alarm 縱橫向位置
    //
            //繪製alarm框
            a.strokeStyle = "rgba(" + b + ", " + c + ")",
            a.fillStyle = "rgba(" + b + ", " + c + ")",
            a.lineCap = "round",
            a.lineWidth = 1,
            a.moveTo(f -10, g - 10), // 左上  這些10是調整 alarm 邊框離文字的距離
            a.lineTo(f + d +10, g - 10), // 右上
            a.lineTo(f + d +10, g + e + 10), // 右下
            a.lineTo(f + d / 2 + 6, g + e  + 10),
            a.lineTo(f + d / 2, g + e + 8  + 10),
            a.lineTo(f + d / 2 - 6, g + e  + 10),
            a.lineTo(f - 10, g + e  + 10), // 左下
            a.lineTo(f -10, g -10),
            a.fill(),
            a.stroke(),
            a.closePath(),
            a.beginPath(),
            a.strokeStyle = "rgba(" + this.fontColor + ", " + this.alpha + ")",
            a.fillStyle = "rgba(" + this.fontColor + ", " + this.alpha + ")",
            (function(a,b,x,y,textArray){
                    for(var j= 0;j<textArray.length;j++){
                        var words = textArray[j];
                        a.fillText(words,x ,y);
                        y+= lineHeight;
                    }
            })(a,this,f,g+8,textArray),
            a.closePath()
        }
    }
    
    var zhangZi = node(150, 500, 'pc.png','ZQPC');
    var zhaoZi = node(250, 500, 'pc.png','ZWPC');
    var liuZi = node(350, 500, 'pc.png','LHZPC');
    var linuxServer = node(450, 500, 'server.png','linux');
    linuxServer.alarm = 'CPU負荷:23%;\n內存佔用:44%\nCPU溫度:56℃\n上傳速度:45mb/s\n下載速度:67ms/s\n運行時長:22h 45m\n內網地址:192.168.1.66\nDNS攻擊:0';
    linuxServer.paintAlarmText = function(a) {
        if (null != this.alarm && "" != this.alarm) {
            var b = this.alarmColor || "154, 230, 125",
                c = this.alarmAlpha || .5;
            a.beginPath(),
            a.font = this.alarmFont || "10px 微軟雅黑";

            var textArray = this.alarm.split('\n');
            var rowCnt = textArray.length;
            var i = 0, maxLength = 0, maxText = textArray[0];
            for(;i<rowCnt;i++){
                    var nowText = textArray[i],textLength = nowText.length;
                    if(textLength >=maxLength){
                        maxLength = textLength;
                        maxText = nowText;
                    }
            }
            var maxWidth = a.measureText(maxText).width;
            var lineHeight = 16; // 字體大小 + 6
            // alarm框的寬度
            var d =( (a.measureText(this.alarm).width/rowCnt +6) > maxWidth? (a.measureText(this.alarm).width/rowCnt +6) : maxWidth);
            var e =(lineHeight)*(rowCnt), // alarm 框高度 行高*行數
                f = this.width / 2 - d / 2 , // alarm 框橫向位置
                g = - this.height /2  - e - 20; // alarm 縱橫向位置
    //
            //繪製alarm框
            a.strokeStyle = "rgba(" + b + ", " + c + ")",
            a.fillStyle = "rgba(" + b + ", " + c + ")",
            a.lineCap = "round",
            a.lineWidth = 1,
            a.moveTo(f -10, g - 10), // 左上  這些10是調整 alarm 邊框離文字的距離
            a.lineTo(f + d +10, g - 10), // 右上
            a.lineTo(f + d +10, g + e + 10), // 右下
            a.lineTo(f + d / 2 + 6, g + e  + 10),
            a.lineTo(f + d / 2, g + e + 8  + 10),
            a.lineTo(f + d / 2 - 6, g + e  + 10),
            a.lineTo(f - 10, g + e  + 10), // 左下
            a.lineTo(f -10, g -10),
            a.fill(),
            a.stroke(),
            a.closePath(),
            a.beginPath(),
            a.strokeStyle = "rgba(" + this.fontColor + ", " + this.alpha + ")",
            a.fillStyle = "rgba(" + this.fontColor + ", " + this.alpha + ")",
            (function(a,b,x,y,textArray){
                    for(var j= 0;j<textArray.length;j++){
                        var words = textArray[j];
                        a.fillText(words,x ,y);
                        y+= lineHeight;
                    }
            })(a,this,f,g+8,textArray),
            a.closePath()
        }
    }
    var windowsServer = node(550, 500, 'server.png','windows');
    var print = node(200, 300, 'print.png','print');
    var disk = node(400, 300, 'disk.png','videoDisk');
    var video = node(500, 300, 'video.png','video');
    hostLink(luYouQi, wangZi);
    hostLink(luYouQi, zhangZi);
    hostLink(luYouQi, zhaoZi);
    hostLink(luYouQi, liuZi);
    hostLink(luYouQi, linuxServer);
    hostLink(luYouQi, windowsServer);
    
    newCurveLink(luYouQi, print);
    newCurveLink(luYouQi, disk);
    
    linkNode(disk, video, false);
    //直線
    function linkNode(nodeA, nodeZ, f){
        var link;
        if(f){
            link = new JTopo.FoldLink(nodeA, nodeZ);
        }else{
            link = new JTopo.Link(nodeA, nodeZ);
        }
        link.direction = 'vertical';
        scene.add(link);
        return link;
    }
	//曲線
    function hostLink(nodeA, nodeZ){                
        var link = new JTopo.FlexionalLink(nodeA, nodeZ);                
        link.shadow = false;
        link.offsetGap = 80;
        scene.add(link);
        return link;
    }
    
    //曲線
    function newCurveLink(nodeA, nodeZ, text){
        var link = new JTopo.CurveLink(nodeA, nodeZ, text);
        link.lineWidth = 3; // 線寬
        scene.add(link);
        return link;
    }
    //報警閃爍
    setInterval(function(){
        if(print.alarm == '網絡連接中斷'){
        	print.alarm = null;
        	wangZi.alarm = null;
        }else{
        	print.alarm = '網絡連接中斷';
        	wangZi.alarm = 'CPU負荷:89%\n內存佔用:89%\nCPU溫度:88℃\n上傳速度:55mb/s\n下載速度:88ms/s\n運行時長:12h 45m\n內網地址:192.168.1.44\nDNS攻擊:0';
        }
    }, 600);
    //加入到畫布對象中
    stage.add(scene);

上傳下載儀表盤

//初始化儀表盤
function initCharts(){
	var upOption = initOption('上傳速度',46);
	var downOption = initOption('下載速度',38);
	var myChart1 = echarts.init(document.getElementById('echarts1'));
	var myChart2 = echarts.init(document.getElementById('echarts2'));
 	myChart1.setOption(upOption, true);
    myChart2.setOption(downOption, true);
	
	setInterval(function () {
		upOption.series[0].data[0].value = (Math.random() * 100).toFixed(2) - 0;
		downOption.series[0].data[0].value = (Math.random() * 100).toFixed(2) - 0;
	    myChart1.setOption(upOption, true);
	    myChart2.setOption(downOption, true);
	},2000);
}
//設置option
function initOption(name,value){
	var option = {
	    tooltip : {
	        formatter: "{a} <br/>{b} : {c}%"
	    },
	    series: [
	        {
	            name: name,
	            radius: '100%',
	            type: 'gauge',
	            title : {
	                color:'white'
	            },
	            axisLine: {      
	                lineStyle: {
	                    width: 10,
	                    color:[[0.2, '#ff7878'], [0.8, '#efd573'], [1, '#89e274']]
	                }
	            },
	            detail: {
	            	formatter:'{value}mb/s',
	                fontSize: 18
	            },
	            data: [{value: value, name: name}]
	        }
	    ]
	};
	return option;
}

CPU負荷率折線圖

function initLineChart(){
	var data100 = [];
	var data10 = [];
	var data1 = [];
	var xTime = [];
	initData();
	//從後臺獲取數據
	function initData() {
		$.ajax({
			url:'/xxx/xxx!searchCpuLoadData.action',
			type:'Post',
			dataType:"json", 
			async:true,
			success : function(json) {
				var dto = json.theObj;
				data100.push(dto.cpuLoadPercentAge100msec);
				data10.push(dto.cpuLoadPercentAge10sec);
				data1.push(dto.cpuLoadPercentAge1sec);
				xTime.push(dto.systemRunTimes);
			}
		});
	}

	//初始化echarts折線圖
	var myChart = echarts.init(document.getElementById('echarts3'));
	var option = {
	    title: {
	        text: 'CPU負荷率(%)',
	        x: 'center',
	        textStyle:{
	            color:'white',
	            fontSize:16,
	            fontFamily:'華文細黑'
	        }
	    },
	    color:['#ff7878','#efd573','#89e274'],
	    legend: {
	        data:['100ms %','10sec %','1sec %'],
	        x: 'left',
	        textStyle:{
	            color:'white',
	            fontSize:16,
	            fontFamily:'華文細黑'
	        }
	    },
	    grid: {
	        left: '3%',
	        right: '4%',
	        bottom: '3%',
	        containLabel: true
	    },
	    textStyle:{
	        fontSize:20,
	        color:'white',
	        fontFamily:'華文細黑'
	    },
	    tooltip: {
	        trigger: 'axis',
	        axisPointer: {
	            animation: false
	        }
	    },
	    xAxis: {
	        type: 'category',
	        data:xTime,
	        axisLine:{
	        	lineStyle:{
	        		color:'white'
	        	}
	        },
	        splitLine: {
	            show: false
	        }
	    },
	    yAxis: {
	        type: 'value',
	        boundaryGap: [0, '100%'],
	        axisLine:{
	        	lineStyle:{
	        		color:'white'
	        	}
	        },
	        splitLine: {
	            show: false
	        }
	    },
	    series: [
		{
		    name: '100ms %',
		    type: 'line',
		    showSymbol: false,
		    hoverAnimation: false,
		    data: data100
		},
		{
		    name: '10sec %',
		    type: 'line',
		    showSymbol: false,
		    hoverAnimation: false,
		    data: data10
		},
		{
		    name: '1sec %',
		    type: 'line',
		    showSymbol: false,
		    hoverAnimation: false,
		    data: data1
		}
        ]
	};

	//每3秒刷新一次數據
	setInterval(function () {
		initData();
	    myChart.setOption({
	    	xAxis:{data:xTime},
	        series: [
            {	
            	name: '100ms %',
            	data: data100
	        },{
	        	name: '10sec %',
            	data: data10
	        },{
	        	name: '1sec %',
            	data: data1
	        }]
	    });
	}, 3000);
	myChart.setOption(option, true);
}

24端口監控列表
基於datatable實現,包括交換機的信息,IP設置,重啓,刷新,以及每個端口的速度控制,POE開關,當前速度,當前狀態,帶寬,電流電壓功率,溫度,允許上傳最大限制,累計上傳下載包大小等等。

//初始化datatable列表數據
function initNetworkMonitor(){
	$.ajax({
		url:'/xxx/xxx!searchNetworkMonitorData.action',
		type:'Post',
		dataType:"json", 
		async:true,
		success : function(json) {
			var dto = json.theObj;
			var list = dto.list;
			var tableInnerHtml = '';
			if(list != null && list.length > 0){
				for(var i = 0; i < list.length; i ++){
					var icon = list[i].status == 1 ? '<i class="fa fa-circle" style="color:#6dff6d;margin-top: 5px;"></i>' : '<i class="fa fa-circle" style="color:red;margin-top: 5px;"></i>';
					var poe = '';
					if(list[i].poeStatus == 3){
						poe = '<i class="fa fa-battery-full" style="color:#6dff6d;margin-top: 5px;"></i>';
					}else if(list[i].poeStatus == 4 || list[i].poeStatus == 7){
						poe = '<i class="fa fa-times-circle" style="color:red;margin-top: 5px;"></i>';
					}else{
						poe = '<i class="fa fa-question-circle" style="color:orange;margin-top: 5px;"></i>';
					}
					tableInnerHtml += '<tr><td>' + list[i].portName + '</td><td>' + icon + '</td><td>' + list[i].maxTransUnit + '(bytes)</td><td align="center"><select vid="' + list[i].speedBandWidthValue + '" class="form-control selectSpeed" οnchange="changeSpeed(' + list[i].oid + ',this.value)" style="width:110px;"></select></td><td>' + list[i].currentSpeed + '</td><td>' + list[i].macAdd + '</td><td>' + list[i].receivedStr + '</td><td>' + list[i].transmittedStr + '</td><td>' + list[i].temperature + '</td><td>' + poe + '</td><td>' + list[i].poePower + '</td><td>' + list[i].poeCurrent + '</td></tr>';
				}
			}
			$("#networkMonitorData").html(tableInnerHtml);
			
			var titleHtml = '<span class="switchTitle">交換機型號:	' + dto.systemName + '</span>'+
							'<span class="switchTitle">已運行時長:	' + dto.systemRunTimes + '</span>'+
							'<span class="switchTitle">接口總數:	24(個)</span>'+
							'<span class="btn btn-info btnSty_3" style="margin-right:10px;margin-left: 7px;" οnclick="ipConfig()">'+
								'<i class="fa fa-repeat"></i>&nbsp;IP設置'+
							'</span>'+
							'<span class="btn btn-danger btnSty_3" style="margin-right:10px;margin-left: 7px;" οnclick="reLoadSwitch()">'+
								'<i class="fa fa-repeat"></i>&nbsp;重新啓動'+
							'</span>'+
							'<span class="btn btn-success btnSty_3" style="margin-right:10px;margin-left: 7px;" οnclick="refreshSwitch()">'+
								'<i class="fa fa-refresh"></i>&nbsp;刷新'+
							'</span>';
			$("#switchTitle").html(titleHtml);
			initSpeedOptions();
		}
	});
}

//初始化速度下拉框
function initSpeedOptions(){
	var options = '<option value="5">AUTO</option>'+ 
				  '<option value="0">10MFdx</option>'+
				  '<option value="1">10MHdx</option>'+
				  '<option value="2">100MFdx</option>'+
				  '<option value="3">100MHdx</option>'+
				  '<option value="4">1G</option>';
	$(".selectSpeed").html(options);
	$(".selectSpeed").each(function(index){
		var value = $(this).attr('vid');
		$(this).val(value);
	});
}

//控制速度
function changeSpeed(oid,speed){
	$.ajax({ 
		url:'/xxx/xxx!configSpeed.action',
        type:'post', 
        data:{
        	speed:speed,
        	oid:oid
        },
        dataType:"json", 
        success:function(data){
        	if(data.success == true){
        		swal({
    				title: "設置成功!",
    				type: "success",
    				showCancelButton: false,
    				confirmButtonColor: '#AEDEF4',
    				confirmButtonText: 'OK',
    				closeOnConfirm: true
    			},
    			function(){
    				initNetworkMonitor();
    			});
        	}else{
        		swal("重啓失敗!"); 
        	}
        }, 
        error:function(){ 
        	swal("重啓失敗!"); 
        }
	});
}

//設置IP
function configIp(){
	var ip = $("#ipAddress").val();
	if(ip == null || ip == '' || ip == undefined){
		return;
	}
	swal({
		title: "確定要更改IP地址嗎?",
		text: "更改IP地址後連接中斷,10秒後重連!",
		type: "warning",
		showCancelButton: true,
		confirmButtonColor: '#DD6B55',
		confirmButtonText: '是, 更改IP地址!',
		closeOnConfirm: false
	},
	function(){
		swal("設置成功!"); 
	});
}
//設備刷新數據
function refreshSwitch(){
	$("#networkMonitorData").html('<tr><td colspan="12"><img src="/ibms/image/load.gif">  正在初始化數據,請稍後。。。</td></tr>');
	initNetworkMonitor();
}

4.後臺核心代碼

Action類核心代碼

	/**
	 * @description:獲取網絡監測數據datatable
	 * @return
	 */
	public String searchNetworkMonitorData(){
		NetworkMonitorDTO dto = ((NetworkMonitorService)service).getSwitchMonitorDataPublic();
		List<NetworkMonitorDTO> list = ((NetworkMonitorService)service).getSwitchMonitorDataPrivate();
		dto.setList(list);
		JSONObject json = JSONObject.fromObject(dto);
		this.setTheObj(json);
		return Result.JSON;
	}
	
	/**
	 * @description:重啓交換機
	 * @return
	 */
	public String reLoadSwitch(){
		boolean flag = ((NetworkMonitorService)service).reLoadSwitch();
		this.setSuccess(flag);
		return Result.JSON;
	}

	/**
	 * @description:獲取CPU負荷echarts 折線圖
	 * @return
	 */
	public String searchCpuLoadData(){
		NetworkMonitorDTO dto = ((NetworkMonitorService)service).getCpuLoadData();
		JSONObject json = JSONObject.fromObject(dto);
		this.setTheObj(json);
		return Result.JSON;
	}
	
	/**
	 * @description:控制端口速度
	 * @return
	 */
	public String configSpeed(){
		String speed = this.getRequest().getParameter("speed");
		String oid = this.getRequest().getParameter("oid");
		boolean flag = ((NetworkMonitorService)service).configSpeed(speed,oid);
		this.setSuccess(flag);
		return Result.JSON;
	}

ConstantEnum枚舉類核心代碼

	/*	
	 * snmpwalk是對OID值的遍歷(比如某個OID值下面有N個節點,則依次遍歷出這N個節點的值。如果對某個葉子節點的OID值做walk,則取得到數據就不正確了,因爲它會認爲該節點是某些節點的父節點,而對其進行遍歷,而實際上該節點已經沒有子節點了,那麼它會取出與該葉子節點平級的下一個葉子節點的值,而不是當前請求的節子節點的值。)
	 * snmpget是取具體的OID的值。(適用於OID值是一個葉子節點的情況)
	 */
	public final static String SNMP_REQUEST_METHOD_GET = "GET";
	public final static String SNMP_REQUEST_METHOD_WALK = "WALK";
	public final static String SNMP_REQUEST_METHOD_SET = "SET";
	
	public final static String SNMP_SET_VALUE_TYPE_NULL = null;
	public final static String SNMP_SET_VALUE_TYPE_INTEGER = "Integer";//整型
	public final static String SNMP_SET_VALUE_TYPE_STRING = "OctetString";//字符串
	public final static String SNMP_SET_VALUE_TYPE_TIME = "TimeTicks";//是一個時間單位,表示以0.01s(即10ms)爲單位計算的時間
	public final static String SNMP_SET_VALUE_TYPE_GAUGE = "Gauge";//非負整數,它可以遞增或遞減,但達到最大值時保持在最大值,最大值爲2^32-1
	
	public static final String COMMUNITY_READ = "public";
	public static final String COMMUNITY_WRITE = "private";
	

	public enum MIBObject{

		//獲取系統基本信息
		SysDesc("1.3.6.1.2.1.1.1.0",SNMP_REQUEST_METHOD_GET),
		//系統運行時間
		SysUptime("1.3.6.1.2.1.1.3.0",SNMP_REQUEST_METHOD_GET),
		//系統聯繫人
		SysContact("1.3.6.1.2.1.1.4.0",SNMP_REQUEST_METHOD_GET),
		//系統名稱
		SysName("1.3.6.1.2.1.1.5.0",SNMP_REQUEST_METHOD_GET),
		//系統運行的進程列表
		HrSWRunName("1.3.6.1.2.1.25.4.2.1.2",SNMP_REQUEST_METHOD_WALK),
		//系統安裝的軟件列表
		HrSWInstalledName("1.3.6.1.2.1.25.6.3.1.2",SNMP_REQUEST_METHOD_WALK),
		
		//***********網絡接口***********
		//獲取所有接口mib
		IfIndex(".1.3.6.1.2.1.2.2.1.1",SNMP_REQUEST_METHOD_GET),
		//獲取接口數量
		IfNumber(".1.3.6.1.2.1.2.1.0",SNMP_REQUEST_METHOD_GET),
		//網絡接口信息描述
		IfDescr(".1.3.6.1.2.1.2.2.1.2",SNMP_REQUEST_METHOD_GET),
		//網絡接口類型 (POE交換機接口類型)
		IfType(".1.3.6.1.2.1.2.2.1.3",SNMP_REQUEST_METHOD_GET),
		//獲取接口max transmision unit(short 1518-9600)
		IfMTU(".1.3.6.1.2.1.2.2.1.4",SNMP_REQUEST_METHOD_GET),
		//接口的物理地址
		IfPhysAddress(".1.3.6.1.2.1.2.2.1.6",SNMP_REQUEST_METHOD_GET),
		//接口當前操作狀態 INTEGER {up(1), down(2),testing(3), unknown(4), dormant(5),notPresent(6), lowerLayerDown(7) }
		IfOperStatus(".1.3.6.1.2.1.2.2.1.8",SNMP_REQUEST_METHOD_GET),
		//接口收到的字節數
		IfInOctet(".1.3.6.1.2.1.2.2.1.10",SNMP_REQUEST_METHOD_GET),
		//接口發送的字節數
		IfOutOctet(".1.3.6.1.2.1.2.2.1.16",SNMP_REQUEST_METHOD_GET),
		//接口帶寬
		IfSpeed(".1.3.6.1.2.1.2.2.1.5",SNMP_REQUEST_METHOD_GET),
		
		//***********CPU負載***********
/*		//系統CPU百分比
		SsCpuSystem,
		//空閒CPU百分比
		SsCpuIdle,
		//系統CPU使用時間
		SsCpuRawSystem,
		//系統CPU空閒時間
		SsCpuRawIdle,
		//CPU的當前負載,N個核就有N個負載(CPU使用率=N個VALUE相加/N)
		HrProcessorLoad,
		
		//***********內存及磁盤***********
		//獲取內存大小
		HrMemorySize,
		//存儲設備編號
		HrStorageIndex,
		//存儲設備類型
		HrStorageType,
		//存儲設備描述
		HrStorageDescr,
		//簇的大小
		HrStorageAllocationUnits,
		//簇的的數目
		HrStorageSize,
		//使用多少,跟總容量相除就是佔用率
		HrStorageUsed;*/
		
		//***********光網視交換機***********
		//交換機重啓 (INTEGER) {noReboot(0), coldReboot(1), warmReboot(2) }
		VtssSysutilControlRebootType(".1.3.6.1.4.1.6603.1.24.1.4.1.1.2.1",SNMP_REQUEST_METHOD_SET),
		//獲取交換機PORT (INTEGER) {force10ModeFdx(0),force10ModeHdx(1),force100ModeFdx(2),force100ModeHdx(3),force1GModeFdx(4),autoNegMode(5),force2G5ModeFdx(6),force5GModeFdx(7),force10GModeFdx(8),force12GModeFdx(9) }
		VtssPortConfigSpeed(".1.3.6.1.4.1.6603.1.11.1.2.1.1.3",SNMP_REQUEST_METHOD_GET),
		//獲取交換機PORT TYPE (INTEGER) {rj45(0), sfp(1), dual(2) }
		VtssPortConfigMediaType(".1.3.6.1.4.1.6603.1.11.1.2.1.1.5",SNMP_REQUEST_METHOD_GET),
		//獲取交換機max transmision unit(short 1518-9600)
		VtssPortConfigMTU(".1.3.6.1.4.1.6603.1.11.1.2.1.1.7",SNMP_REQUEST_METHOD_GET),
		//獲取交換機 received (good and bad) bytes
		VtssPortStatisticsRmonStatisticsRxOctets(".1.3.6.1.4.1.6603.1.11.1.5.1.1.3",SNMP_REQUEST_METHOD_GET),
		//獲取交換機 transmitted (good and bad) bytes
		VtssPortStatisticsRmonStatisticsTxOctets(".1.3.6.1.4.1.6603.1.11.1.5.1.1.3",SNMP_REQUEST_METHOD_GET),
		//獲取交換機port link status (INTEGER) {true(1), false(2) }
		VtssPortStatusInformationLink(".1.3.6.1.4.1.6603.1.11.1.3.1.1.2",SNMP_REQUEST_METHOD_GET),
		//獲取交換機current interface speed(INTEGER) {undefined(0), speed10M(1), speed100M(2),speed1G(3), speed2G5(4), speed5G(5),speed10G(6), speed12G(7) }
		VtssPortStatusInformationSpeed(".1.3.6.1.4.1.6603.1.11.1.3.1.1.5",SNMP_REQUEST_METHOD_GET),
		//獲取交換機接口當前溫度
		VtssThermalProtectionStatusInterfaceTemperature(".1.3.6.1.4.1.6603.1.78.1.3.1.1.2",SNMP_REQUEST_METHOD_GET),
		//獲取交換機Average CPU load (%) in 100msec/10sec/1sec.
		VtssSysutilStatusCpuLoadAverage100msec("1.3.6.1.4.1.6603.1.24.1.3.1.1.0",SNMP_REQUEST_METHOD_GET),
		VtssSysutilStatusCpuLoadAverage10sec("1.3.6.1.4.1.6603.1.24.1.3.1.3.0",SNMP_REQUEST_METHOD_GET),
		VtssSysutilStatusCpuLoadAverage1sec("1.3.6.1.4.1.6603.1.24.1.3.1.2.0",SNMP_REQUEST_METHOD_GET),
		
		//獲取接口當前POE功率(單位:十瓦特)
		VtssPoeStatusInterfacePowerConsumption(".1.3.6.1.4.1.6603.1.43.1.3.1.1.4",SNMP_REQUEST_METHOD_GET),
		//獲取接口當前POE電流(單位:毫安)
		VtssPoeStatusInterfaceCurrentConsumption(".1.3.6.1.4.1.6603.1.43.1.3.1.1.5",SNMP_REQUEST_METHOD_GET),
		//獲取接口當前POE供電狀態(INTEGER) {notSupported(0), budgetExceeded(1), noPoweredDeviceDetected(2), poweredDeviceOn(3), poweredDeviceOff(4), poweredDeviceOverloaded(5), unknownState(6),disabled(7) }
		VtssPoeStatusInterfaceCurrentState(".1.3.6.1.4.1.6603.1.43.1.3.1.1.3",SNMP_REQUEST_METHOD_GET);
		private String oid;
	    private String method;
	    
	    private MIBObject(String oid, String method) {
	        this.oid = oid;
	        this.method = method;
	    }
		public String getOid() {
			return oid;
		}

		public void setOid(String oid) {
			this.oid = oid;
		}

		public String getMethod() {
			return method;
		}

		public void setMethod(String method) {
			this.method = method;
		}
	}

SnmpUtil工具類核心代碼


	/*
	 * SNMPv3
	 * 需要創建USM對象並添加User
	 * 需要創建UserTarget對象,而不是創建CommunityTarget對象
	 * 需要創建ScopedPDU對象,而不是PDU對象
	 */
	 
	/**
	 * @description:創建對象communityTarget
	 * @param ip
	 * @param community
	 * @return
	 */
	public static CommunityTarget createDefault(String ip, String community) {
		
		//snmp 版本
		int version = Integer.valueOf(PropertyUtil.getProperty("snmp_version2c"));
		//snmp 端口
		int port = Integer.valueOf(PropertyUtil.getProperty("snmp_switch_port"));
		//snmp 協議
		String protocol = PropertyUtil.getProperty("snmp_default_protocol");
		//snmp 超時時間
		long timeout = Long.valueOf(PropertyUtil.getProperty("snmp_default_timeout"));
		//snmp 重試
		int retry = Integer.valueOf(PropertyUtil.getProperty("snmp_default_retry"));
		//創建地址
		Address address = GenericAddress.parse(protocol + ":" + ip + "/" + port);
		//創建CommunityTarget對象
		CommunityTarget target = new CommunityTarget();
		//設置社區名稱
		target.setCommunity(new OctetString(community));
		//設置ip端口
		target.setAddress(address);
		//設置版本
		target.setVersion(version);
		//設置超時時間
		target.setTimeout(timeout);
		//設置retry
		target.setRetries(retry);
		return target;
	}

	/**
	 * @description:GET方式獲取單個OID的單個值
	 * @param ip
	 * @param community
	 * @param oid
	 */
	public static Map<String, String> snmpGetByOID(String ip, String community, String oid) {
		Map<String, String> map = new HashMap<String, String>();
		CommunityTarget target = createDefault(ip, community);
		Snmp snmp = null;
		try {
			PDU pdu = new PDU();
			pdu.add(new VariableBinding(new OID(oid)));
			DefaultUdpTransportMapping transport = new DefaultUdpTransportMapping();
			snmp = new Snmp(transport);
			snmp.listen();
			pdu.setType(PDU.GET);
			ResponseEvent respEvent = snmp.send(pdu, target);
			PDU response = respEvent.getResponse();
			if (response == null) {
				log.warn("response is null, request time out");
			} else {
				for (int i = 0; i < response.size(); i++) {
					VariableBinding vb = response.get(i);
					map.put(vb.getOid().toString(), vb.getVariable().toString());
				}
			}
		} catch (Exception e) {
			log.error("SNMP snmpGetByOID Exception:" + e);
		} finally {
			if (snmp != null) {
				try {
					snmp.close();
				} catch (IOException ex1) {
					snmp = null;
				}
			}
		}
		return map;
	}

	/**
	 * @description:GET方式獲取多個OID(返回list map)
	 * @param ip
	 * @param community
	 * @param oidList
	 * @return
	 */
	public static List<Map<String, String>> snmpGetListMapByOIDs(String ip, String community,List<String> oidList) {
		List<Map<String, String>> list = new ArrayList<Map<String,String>>();
		CommunityTarget target = createDefault(ip, community);
		Snmp snmp = null;
		try {
			PDU pdu = new PDU();
			for (String oid : oidList) {
				pdu.add(new VariableBinding(new OID(oid)));
			}
			DefaultUdpTransportMapping transport = new DefaultUdpTransportMapping();
			snmp = new Snmp(transport);
			snmp.listen();
			pdu.setType(PDU.GET);
			ResponseEvent respEvent = snmp.send(pdu, target);
			PDU response = respEvent.getResponse();
			if (response == null) {
				log.warn("response is null, request time out");
			} else {
				for (int i = 0; i < response.size(); i++) {
					
					Map<String, String> map = new HashMap<String, String>();
					VariableBinding vb = response.get(i);
					map.put(vb.getOid().toString(), vb.getVariable().toString());
					list.add(map);
				}
			}
		} catch (Exception e) {
			log.error("SNMP snmpGetListMapByOIDs Exception:" + e);
		} finally {
			if (snmp != null) {
				try {
					snmp.close();
				} catch (IOException ex1) {
					snmp = null;
				}
			}
		}
		return list;
	}
	
	/**
	 * @description:GET方式獲取多個OID(返回list string)
	 * @param ip
	 * @param community
	 * @param oidList
	 * @return
	 */
	public static List<String> snmpGetListByOIDs(String ip, String community,List<String> oidList) {
		List<String> list = new ArrayList<String>();
		CommunityTarget target = createDefault(ip, community);
		Snmp snmp = null;
		try {
			PDU pdu = new PDU();
			for (String oid : oidList) {
				pdu.add(new VariableBinding(new OID(oid)));
			}
			DefaultUdpTransportMapping transport = new DefaultUdpTransportMapping();
			snmp = new Snmp(transport);
			snmp.listen();
			pdu.setType(PDU.GET);
			ResponseEvent respEvent = snmp.send(pdu, target);
			PDU response = respEvent.getResponse();
			if (response == null) {
				log.warn("response is null, request time out");
			} else {
				for (int i = 0; i < response.size(); i++) {
					VariableBinding vb = response.get(i);
					list.add(vb.getVariable().toString());
				}
			}
		} catch (Exception e) {
			log.error("SNMP snmpGetListByOIDs Exception:" + e);
		} finally {
			if (snmp != null) {
				try {
					snmp.close();
				} catch (IOException ex1) {
					snmp = null;
				}
			}
		}
		return list;
	}

	/**
	 * @description:異步GET多個OID
	 * @param ip
	 * @param community
	 * @param oidList
	 */
	public static List<Map<String, String>> snmpAsynGetListByOIDs(String ip, String community,List<String> oidList) {
		final List<Map<String, String>> list = new ArrayList<Map<String,String>>();
		CommunityTarget target = createDefault(ip, community);
		Snmp snmp = null;
		try {
			PDU pdu = new PDU();
			for (String oid : oidList) {
				pdu.add(new VariableBinding(new OID(oid)));
			}
			DefaultUdpTransportMapping transport = new DefaultUdpTransportMapping();
			snmp = new Snmp(transport);
			snmp.listen();
			pdu.setType(PDU.GET);
			/* 異步獲取 */
			final CountDownLatch latch = new CountDownLatch(1);
			ResponseListener listener = new ResponseListener() {
				public void onResponse(ResponseEvent event) {
					((Snmp) event.getSource()).cancel(event.getRequest(), this);
					PDU response = event.getResponse();
					if (response == null) {
						log.error("[ERROR]: response is null");
					} else if (response.getErrorStatus() != 0) {
						log.error("[ERROR]: response status"
								+ response.getErrorStatus() + " Text:"
								+ response.getErrorStatusText());
					} else {
						for (int i = 0; i < response.size(); i++) {
							Map<String, String> map = new HashMap<String, String>();
							VariableBinding vb = response.get(i);
							map.put(vb.getOid().toString(), vb.getVariable().toString());
							list.add(map);
						}
						latch.countDown();
					}
				}
			};
			snmp.send(pdu, target, null, listener);
			latch.await(30, TimeUnit.SECONDS);
		} catch (Exception e) {
			log.error("SNMP snmpAsynGetListByOIDs Exception:" + e);
		} finally {
			if (snmp != null) {
				try {
					snmp.close();
				} catch (IOException ex1) {
					snmp = null;
				}
			}
		}
		return list;
	}

	/* 根據targetOID,獲取樹形數據 */
	
	/**
	 * @description: walk遍歷子節點獲取所有
	 * @param ip
	 * @param community
	 * @param targetOid
	 */
	public static List<Map<String, String>> snmpWalk(String ip, String community, String targetOid) {
		List<Map<String, String>> list = new ArrayList<Map<String,String>>();
		CommunityTarget target = createDefault(ip, community);
		TransportMapping transport = null;
		Snmp snmp = null;
		try {
			transport = new DefaultUdpTransportMapping();
			snmp = new Snmp(transport);
			transport.listen();
			PDU pdu = new PDU();
			OID targetOID = new OID(targetOid);
			pdu.add(new VariableBinding(targetOID));
			boolean finished = false;
			while (!finished) {
				VariableBinding vb = null;
				ResponseEvent respEvent = snmp.getNext(pdu, target);
				PDU response = respEvent.getResponse();
				if (response == null) {
					log.warn("response is null, request time out");
					finished = true;
					break;
				} else {
					vb = response.get(0);
				}
				//檢查是否遍歷完成,否則一直遍歷
				finished = checkWalkFinished(targetOID, pdu, vb);
				if (!finished) {
					Map<String, String> map = new HashMap<String, String>();
					map.put(vb.getOid().toString(), vb.getVariable().toString());
					list.add(map);
					//爲下一次遍歷綁定參數
					pdu.setRequestID(new Integer32(0));
					pdu.set(0, vb);
				} else {
					log.info("SNMP walk OID has finished.");
				}
			}
		} catch (Exception e) {
			log.error("SNMP snmpWalk Exception:" + e);
		} finally {
			if (snmp != null) {
				try {
					snmp.close();
				} catch (IOException ex1) {
					snmp = null;
				}
			}
		}
		return list;
	}

	/**
	 * @description:檢查walk遍歷是否結束
	 * @param targetOID
	 * @param pdu
	 * @param vb
	 * @return
	 */
	private static boolean checkWalkFinished(OID targetOID, PDU pdu,VariableBinding vb) {
		boolean finished = false;
		if (pdu.getErrorStatus() != 0) {
			log.info("[true] responsePDU.getErrorStatus() != 0 ");
			finished = true;
		} else if (vb.getOid() == null) {
			log.info("[true] vb.getOid() == null");
			finished = true;
		} else if (vb.getOid().size() < targetOID.size()) {
			log.info("[true] vb.getOid().size() < targetOID.size()");
			finished = true;
		} else if (targetOID.leftMostCompare(targetOID.size(), vb.getOid()) != 0) {
			log.info("[true] targetOID.leftMostCompare() != 0");
			finished = true;
		} else if (Null.isExceptionSyntax(vb.getVariable().getSyntax())) {
			log.info("[true] Null.isExceptionSyntax(vb.getVariable().getSyntax())");
			finished = true;
		} else if (vb.getOid().compareTo(targetOID) <= 0) {
			log.info("[true] Variable received is not lexicographic successor of requested one:");
			log.info(vb.toString() + " <= " + targetOID);
			finished = true;
		}
		return finished;

	}

	/* 根據targetOID,異步獲取樹形數據 */
	public static List<Map<String, String>> snmpAsynWalk(String ip, String community, String oid) {
		final List<Map<String, String>> list = new ArrayList<Map<String,String>>();
		final CommunityTarget target = createDefault(ip, community);
		Snmp snmp = null;
		try {
			DefaultUdpTransportMapping transport = new DefaultUdpTransportMapping();
			snmp = new Snmp(transport);
			snmp.listen();

			final PDU pdu = new PDU();
			final OID targetOID = new OID(oid);
			final CountDownLatch latch = new CountDownLatch(1);
			pdu.add(new VariableBinding(targetOID));

			ResponseListener listener = new ResponseListener() {
				public void onResponse(ResponseEvent event) {
					((Snmp) event.getSource()).cancel(event.getRequest(), this);
					try {
						PDU response = event.getResponse();
						if (response == null) {
							log.error("[ERROR]: response is null");
						} else if (response.getErrorStatus() != 0) {
							log.error("[ERROR]: response status"
									+ response.getErrorStatus() + " Text:"
									+ response.getErrorStatusText());
						} else {
							VariableBinding vb = response.get(0);
							boolean finished = checkWalkFinished(targetOID,pdu, vb);
							if (!finished) {
								Map<String, String> map = new HashMap<String, String>();
								map.put(vb.getOid().toString(), vb.getVariable().toString());
								list.add(map);
								//爲下一次遍歷綁定參數
								pdu.setRequestID(new Integer32(0));
								pdu.set(0, vb);
								((Snmp) event.getSource()).getNext(pdu, target, null, this);
							} else {
								log.error("SNMP Asyn walk OID value success !");
								latch.countDown();
							}
						}
					} catch (Exception e) {
						log.error("SNMP snmpAsynWalk Exception:" + e);
						latch.countDown();
					}
				}
			};
			snmp.getNext(pdu, target, null, listener);
			boolean wait = latch.await(30, TimeUnit.SECONDS);
		} catch (Exception e) {
			log.error("SNMP snmpAsynWalk Exception:" + e);
		} finally {
			if (snmp != null) {
				try {
					snmp.close();
				} catch (IOException ex1) {
					snmp = null;
				}
			}
		}
		return list;
	}

	/**
	 * @description:     設置OID值
	 * @param ip         主機IP
	 * @param community  團體名稱
	 * @param oid	     OID
	 * @param val        值
	 * @param valueType  值類型
	 * @throws IOException
	 */
	public static boolean setPDUValue(String ip, String community, String oid,String val,String valueType) throws IOException {
		
		boolean flag = false;
		CommunityTarget target = createDefault(ip, community);
		Snmp snmp = null;
		PDU pdu = new PDU();
		
		switch (valueType) {
		case ConstantEnum.SNMP_SET_VALUE_TYPE_INTEGER:
			pdu.add(new VariableBinding(new OID(oid), new Integer32(Integer.parseInt(val))));
			break;
		case ConstantEnum.SNMP_SET_VALUE_TYPE_STRING:
			pdu.add(new VariableBinding(new OID(oid), new OctetString(val)));
			break;
		case ConstantEnum.SNMP_SET_VALUE_TYPE_TIME:
			pdu.add(new VariableBinding(new OID(oid), new TimeTicks(Long.parseLong(val))));
			break;
		case ConstantEnum.SNMP_SET_VALUE_TYPE_GAUGE:
			pdu.add(new VariableBinding(new OID(oid), new Gauge32(Long.parseLong(val))));
			break;
		default:
			break;
		}
		pdu.setType(PDU.SET);
		DefaultUdpTransportMapping transport = new DefaultUdpTransportMapping();
		snmp = new Snmp(transport);
		snmp.listen();
		
		ResponseEvent respEvent = snmp.send(pdu, target);
		PDU response = respEvent.getResponse();
		if (response == null) {
			log.warn("response is null, request time out");
		} else {
			flag = true;
		}
		snmp.close();
		return flag;
	}

相關資料工具和源代碼我會在後面上傳到我的資源中給大家下載,謝謝支持!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章