使用snmp4j实现trap告警

来源:互联网 发布:ios 大型游戏源码 编辑:程序博客网 时间:2024/06/07 07:04

使用snmp4j实现trap告警

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

一、整体设计思路

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


二、示例程序搭建

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

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


a) spring 配置文件applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"><bean id="trapListener" class="com.hepan.listener.impl.SnmpTrapListener"><property name="ip" value="192.168.122.34"></property><property name="port" value="162"></property></bean></beans>

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<CommandResponderEvent> trapQueue = new LinkedBlockingQueue<CommandResponderEvent>();/** * 获得trap队列 * @return CommandResponderEvent */public static LinkedBlockingQueue<CommandResponderEvent> getRespEvntMsg (){if(trapQueue==null){return new LinkedBlockingQueue<CommandResponderEvent>();}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 {@Overridepublic void putMessage2Queue(CommandResponderEvent respEvnt) {try {QueueCenter.putRespEvntLogsQueue(respEvnt);} catch (InterruptedException e) {e.printStackTrace();}}@Overridepublic 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; //本地IPprivate String port; //监听端口private Address listenAddress; //地址信息private ThreadPool threadPool;private MultiThreadedMessageDispatcher dispatcher;@Overridepublic 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信息入队@Overridepublic 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{@Overridepublic 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后面我会陆续完成