基于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;
	}

相关资料工具和源代码我会在后面上传到我的资源中给大家下载,谢谢支持!

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