使用snmp4j实现trap告警

使用snmp4j实现trap告警

Snmp4jtrap处理的文章在网上看了一些不过都是浅尝辄止,基本都是大概的讲述了一下如何接收trap等简单的技术。但是这些对于企业级的开发往往是不够的,随着纳入trap接收服务器的设备增加其接收到的trap信息也是成级数增加的。这里就需要我们对于这种大数据量的trap处理进行管理。本文不对trap的各种名词进行解释,需要有一定的snmp基础知识及java编程知识理解。

一、整体设计思路

         由于trap可能瞬时数据量特别的大,所以我们可以采用接收与处理相互分离的设计方法。即开启一个线程专门接收trap,接收到trap后不做任何处理直接放入一个队列中。然后开启另一个线程从队列中取数据,将取得的数据派发给多线程的处理接口处理。符合我们上报条件的trap向前台推送告警并让前台页面展现。具体流程如下图。


二、示例程序搭建

        本程序采用myeclipse开发,所以直接引用myeclipse的spring包即可。此外还需要snmp4j包,这里就不提供下载地址了。

         实例项目第一版的目录结构如下图


a) spring 配置文件applicationContext.xml



	
		
		
	


b)main方法类Start.java

package com.hepan;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.hepan.handler.SnmpTrapHandler;
import com.hepan.listener.impl.SnmpTrapListener;


/**
 * 启动类
 * @author 何盼
 *
 */
public class Start {
	public static ApplicationContext fsxac;
	public static void main(String[] args) {
		fsxac = new ClassPathXmlApplicationContext("applicationContext.xml");
		
		//启动处理线程
		new Thread(new SnmpTrapHandler()).start();
		//启动监听线程
		new Thread((SnmpTrapListener)fsxac.getBean("trapListener")).start();
		
	}
}

c) 队列中心 QueueCenter.java

package com.hepan.queue;

import java.util.concurrent.LinkedBlockingQueue;

import org.snmp4j.CommandResponderEvent;

/**
 * 队列中心存放原始trap记录即接收到的CommandResponderEvent对象
 * @author 何盼
 *
 */
public class QueueCenter {
	private static LinkedBlockingQueue trapQueue = new LinkedBlockingQueue();

	
	/**
	 * 获得trap队列
	 * @return CommandResponderEvent
	 */
	public static LinkedBlockingQueue getRespEvntMsg (){
		if(trapQueue==null){
			return new LinkedBlockingQueue();
		}else{
			return trapQueue;
		}
	}

	/**
	 * 存入trap队列
	 * @param message
	 * @throws InterruptedException
	 * 
	 * 
	 */
	public static void putRespEvntLogsQueue(CommandResponderEvent message) throws InterruptedException{
		trapQueue.put(message);
	}
}

d) 监听接口ListenerInterface.java

package com.hepan.listener;

import org.snmp4j.CommandResponderEvent;

/**
 * 接收trap信息类接口定义
 * @author 何盼
 *
 */
public interface ListenerInterface {
	/**
	 * 存入队列方法
	 * @param respEvnt
	 */
	public void putMessage2Queue(CommandResponderEvent respEvnt );
	
	/**
	 * 初始化方法初始化监听端口、ip等信息,这些信息需要从SPRING配置文件中读取
	 */
	public void init();
}


d) 监听抽象AbstListener .java

package com.hepan.listener;

import org.snmp4j.CommandResponderEvent;

import com.hepan.queue.QueueCenter;

/**
 * 处理类的抽象方法
 * 
 * @author 何盼
 *
 */
public abstract class AbstListener implements ListenerInterface ,Runnable {

	@Override
	public void putMessage2Queue(CommandResponderEvent respEvnt) {
		try {
			QueueCenter.putRespEvntLogsQueue(respEvnt);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void run() {
		init();
	}
	

}

f) 监听具体实现方法类 SnmpTrapListener.java

package com.hepan.listener.impl;

import org.snmp4j.CommandResponder;
import org.snmp4j.CommandResponderEvent;
import org.snmp4j.MessageDispatcherImpl;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.mp.MPv1;
import org.snmp4j.mp.MPv2c;
import org.snmp4j.mp.MPv3;
import org.snmp4j.security.SecurityModels;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.security.USM;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.TcpAddress;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.transport.DefaultTcpTransportMapping;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.MultiThreadedMessageDispatcher;
import org.snmp4j.util.ThreadPool;

import com.hepan.listener.AbstListener;

/**
 * 监听类
 * @author 何盼
 *
 */
public class SnmpTrapListener extends AbstListener implements CommandResponder{
	
	private String ip; //本地IP
	private String port; //监听端口
	private Address listenAddress; //地址信息
	private ThreadPool threadPool;
	private MultiThreadedMessageDispatcher dispatcher;
	@Override
	public void init() {
		try{
		threadPool=ThreadPool.create("Trap", 2); 
		dispatcher=new MultiThreadedMessageDispatcher(threadPool, new MessageDispatcherImpl());
		listenAddress = GenericAddress.parse(System.getProperty(
				"snmp4j.listenAddress", "udp:" + ip + "/" + port));
		TransportMapping transport;
		// 对TCP与UDP协议进行处理
		if (listenAddress instanceof UdpAddress) {
			transport = new DefaultUdpTransportMapping(
					(UdpAddress) listenAddress);
		} else {
			transport = new DefaultTcpTransportMapping(
					(TcpAddress) listenAddress);
		}
		Snmp snmp = new Snmp(dispatcher, transport);
		snmp.getMessageDispatcher().addMessageProcessingModel(new MPv1());
		snmp.getMessageDispatcher().addMessageProcessingModel(new MPv2c());
		snmp.getMessageDispatcher().addMessageProcessingModel(new MPv3());
		USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(
				MPv3.createLocalEngineID()), 0);
		SecurityModels.getInstance().addSecurityModel(usm);
		snmp.listen();
		snmp.addCommandResponder(this);
		
		System.out.println("启动监听成功");
		}catch (Exception e){
			System.out.println("snmp 初始化失败");
			e.printStackTrace();
		}
	}
	
	
	//此方法为CommandResponder 接口实现方法用于监听后的处理方法,将接收到的trap信息入队
	@Override
	public void processPdu(CommandResponderEvent CREvent) {
		System.out.println("in processPdu");
		this.putMessage2Queue(CREvent);
	}


	public String getIp() {
		return ip;
	}


	public void setIp(String ip) {
		this.ip = ip;
	}


	public String getPort() {
		return port;
	}


	public void setPort(String port) {
		this.port = port;
	}


	public Address getListenAddress() {
		return listenAddress;
	}


	public void setListenAddress(Address listenAddress) {
		this.listenAddress = listenAddress;
	}



}

g) 处理实现类 SnmpTrapHandler.java

package com.hepan.handler;

import org.snmp4j.CommandResponderEvent;

import com.hepan.queue.QueueCenter;

/**
 * 处理类
 * @author 何盼
 *
 */
public class SnmpTrapHandler implements Runnable{

	@Override
	public void run() {
		while(true){
			try {
				CommandResponderEvent resEvent=QueueCenter.getRespEvntMsg().take();
				
				System.out.println("event:"+resEvent);
				
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}

三、测试trap接收

a)首先启动程序,运行Start.java得到如图所示。


b)发送trap

        发送trap我们采用ibm为我们提供的SolarWinds的Trap Editor软件,界面如下图。




新建一个trap,然后点击发送按钮。如图下图所示。



填入IP后即可发送模拟trap了,程序收到这条信息后控制台的输出结果如下图说是



对于如何处理该条trap后面我会陆续完成


你可能感兴趣的:(网管,trap,snmp)