从VMware的vCenter中读取事件,每几分钟从vCenter中的事件管理中读取事件,得到事件后,再对事件做处理。上代码。
连接vCenter的连接类
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.vmware.vim25.mo.ServiceInstance;
/**
* @Title: vCenter连接池
*/
public class VmwareConnectionUtil {
private static Logger logger = LogManager.getLogger(VmwareConnectionUtil.class);
private static final VmwareConnectionUtil instance = new VmwareConnectionUtil();
private Map<String, ServiceInstance> poolMap = new HashMap<String, ServiceInstance>(); // Map<ip,ServiceInstance>
private static final int GETTESTSTATUSTIMEOUT = 60;
private VmwareConnectionUtil() {
}
/**
* 单例模式
* @return
*/
public static synchronized VmwareConnectionUtil getInstance() {
return instance;
}
/**
* 建立与vCenter的连接
* @param url数组: IP, port, username, password
* @return
*/
public synchronized ServiceInstance getConnection(String[] url) {
String key = getKey(url);
ServiceInstance conn = poolMap.get(key);
if (conn != null) {
try {
conn.currentTime();
} catch (Exception e) {
logger.error("Get VmWare vCenter connection exception", e);
poolMap.remove(key);
conn.getServerConnection().logout();
conn = null;
}
} else {
poolMap.remove(key);
conn = initConnection(url);
poolMap.put(key, conn);
}
return conn;
}
private ServiceInstance initConnection(String[] param) {
try {
// ignoreSsl();
} catch (Exception e1) {
logger.error("Ignore SSL error", e1);
}
ServiceInstance conn = null;
URL url = null;
String spec = "";
if(param[1] == null || param[1].trim().equals(""))
spec = "https://" + param[0] + "/sdk"; //没有端口
else
spec = "https://" + param[0] + ":" + param[1] + "/sdk";
try {
url = new URL(spec);
logger.info("Connect to VmWare vCenter " + url);
} catch (MalformedURLException e) {
logger.error("Connect to VmWare vCenter exception", e);
return conn;
}
try {
conn = new ServiceInstance(url, param[2], param[3], true);
} catch (Exception e) {
if (conn != null) {
conn.getServerConnection().logout();
}
conn = null;
logger.error("Failed to init VmWare vCenter webservice connection URL " + spec + ", user:" + param[2], e);
}
return conn;
}
private ServiceInstance initConnectTimeOut(final String[] param) {
ServiceInstance conn = null;
final ExecutorService exec = Executors.newFixedThreadPool(1);
Callable<ServiceInstance> call = new Callable<ServiceInstance>() {
public ServiceInstance call() throws Exception {
ServiceInstance conn = initConnection(param);
return conn;
}
};
try {
Future<ServiceInstance> future = exec.submit(call);
conn = future.get(GETTESTSTATUSTIMEOUT, TimeUnit.SECONDS); // 任务处理超时时间设为60 秒
} catch (TimeoutException ex) {
logger.error("Init connect time out", ex);
} catch (Exception e) {
logger.error("Init connect exception", e);
}
exec.shutdown(); // 关闭线程池
return conn;
}
/**
* IP:userName|password
* @param url
* @return
*/
private String getKey(String[] url) {
return url[0] + ":" + url[2] + "|" + url[3];
}
public boolean testConnection(String ip, String port, String username, String password) {
String[] param = new String[] { ip, port, username, password };
ServiceInstance serviceInstance = null;
serviceInstance = initConnectTimeOut(param);
if (serviceInstance == null) {
return false;
}
return true;
}
public Map<String, ServiceInstance> getPoolMap() {
return poolMap;
}
public void setPoolMap(Map<String, ServiceInstance> poolMap) {
this.poolMap = poolMap;
}
public void deleteConnPoolMap(String key) {
this.poolMap.remove(key);
}
}
从vCenter中读取事件
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.collector.vm.vmware.util.VmwareConnectionUtil;
import com.vmware.vim25.ComputeResourceEventArgument;
import com.vmware.vim25.DatacenterEventArgument;
import com.vmware.vim25.Event;
import com.vmware.vim25.EventEx;
import com.vmware.vim25.EventFilterSpec;
import com.vmware.vim25.EventFilterSpecByTime;
import com.vmware.vim25.ExtendedEvent;
import com.vmware.vim25.HostEventArgument;
import com.vmware.vim25.ManagedObjectReference;
import com.vmware.vim25.VmEventArgument;
import com.vmware.vim25.mo.EventManager;
import com.vmware.vim25.mo.ServiceInstance;
/**
* @Title:采集Vmware事件
* @description 从vCenter中的事件管理器中,每几分钟读取新发生的事件
*/
public class EventCollector {
private Logger log = LogManager.getLogger(EventCollector.class);
//上次事件采集时间点缓存 key:url , value:time
private static Map<String, Long> lastDateMap = new HashMap<String, Long>();
private static final long interval = 1200000l; //20分钟
private static HashMap<String, String> keyMap = new HashMap<String, String>();
//事件类型
private String[] eventTypes = null;
public EventCollector() {
eventTypes = new String[]{"VmRemovedEvent","VmCreatedEvent","VmRenamedEvent",
"VmBeingRelocatedEvent","MigrationResourceWarningEvent","HostConnectionLostEvent","HostConnectedEvent",
"HostDisconnectedEvent","HostRemovedEvent","DatastoreRemovedOnHostEvent","HostOvercommittedEvent","HostCnxFailedTimeoutEvent",
"MigrationErrorEvent","VmCloneFailedEvent","VmConnectedEvent","VmDisconnectedEvent","ClusterCreatedEvent",
"ClusterDestroyedEvent","HostOvercommittedEvent","DatastoreDestroyedEvent","DatastoreFileDeletedEvent","DuplicateIpDetectedEvent",
"HostIpChangedEvent","ResourcePoolDestroyedEvent","VmFailedToPowerOnEvent","VmFailedToPowerOffEvent","EnteredMaintenanceModeEvent",
"VmStateFailedToRevertToSnapshot","VmStateRevertedToSnapshot"};
}
/**
* 取采集开始时间
* @param key
* @return
*/
private long getLastTime(String key) {
long lastTime = 0l;
if (!lastDateMap.containsKey(key)) {
Calendar startTime = Calendar.getInstance();
startTime.setTimeInMillis(System.currentTimeMillis() - interval * 3); //前60分钟的
lastTime = startTime.getTimeInMillis();
lastDateMap.put(key, lastTime);
log.info("First start collect time from: "+ getSimpleDateFormat(lastTime) + ", key:" + key);
}
lastTime = lastDateMap.get(key);
return lastTime;
}
/**
* 查询事件
* @param url
* @throws CollectorException
*/
private void doCollect(String[] url) {
try {
String key = "Datacenter@" + url[0];
long lastEventDate = getLastTime(key);
log.info("Start collect event data by " + url[0] + " from " + getSimpleDateFormat(lastEventDate));
ServiceInstance serviceInstance = VmwareConnectionUtil.getInstance().getConnection(url);
EventFilterSpec efs = new EventFilterSpec();
efs.setType(eventTypes);
//设置事件过滤器,根据时间查询事件
EventFilterSpecByTime tFilter = new EventFilterSpecByTime();
Calendar startTime = Calendar.getInstance();
startTime.setTimeInMillis(lastEventDate);
tFilter.setBeginTime(startTime);
efs.setTime(tFilter);
EventManager evtMgr = serviceInstance.getEventManager();
try {
Event[] events = evtMgr.queryEvents(efs);
if(events != null){
for (Event event : events) {
printEvent(event);
String eventKey = key + "_" + event.getKey();
if(!keyMap.containsKey(eventKey)) { //已有的事件不再处理
EventProcessor ep = new EventProcessor();
ep.process(event, url);
}
keyMap.put(eventKey, "");
}
} else
log.warn("Query events from " + url[0] + " empty");
} catch(Exception e) {
log.error("Query events exception", e);
}
long nextStart = System.currentTimeMillis() - interval;
lastDateMap.put(key, nextStart);
log.info("Next start query event time: " + getSimpleDateFormat(nextStart) + ", key:" + key);
} catch (Throwable e) {
log.error("Collect Event exception by " + url[0], e);
}
}
/**
* 输出事件信息
* @param evt
*/
private void printEvent(Event evt) {
String type = evt.getClass().getSimpleName();// 事件类型
int key = evt.getKey();// 事件ID
// int chainId = evt.getChainId();// 父或组ID
// String userName = evt.getUserName();// 引发该事件的用户
long createdTime = evt.getCreatedTime().getTimeInMillis();// 创建时间
String formattedMessage = evt.getFullFormattedMessage();// 事件内容
String logInfo="type="+type;
String eventTypeId="";
if(evt instanceof EventEx){
EventEx e=(EventEx)evt;
eventTypeId=e.getEventTypeId();
logInfo=logInfo+", eventTypeId="+eventTypeId;
}else if(evt instanceof ExtendedEvent){
ExtendedEvent e=(ExtendedEvent)evt;
eventTypeId=e.getEventTypeId();
logInfo=logInfo+", eventTypeId="+eventTypeId;
}
logInfo=logInfo+ ", key=" + key + ", time=" + getSimpleDateFormat(createdTime)+", message=" + formattedMessage;
if (evt.getDatacenter() != null) {
DatacenterEventArgument dc= evt.getDatacenter();
ManagedObjectReference mor=dc.getDatacenter();
logInfo=logInfo+"\n datacenter=" +dc.getName() + ", datacenterEntity=" + mor.getVal();
}
if (evt.getComputeResource() != null) {
ComputeResourceEventArgument cr= evt.getComputeResource();
ManagedObjectReference mor= cr.getComputeResource();
logInfo=logInfo+"\n cluster=" +cr.getName() + ", clusterEntity=" + mor.getVal();
}
if (evt.getHost() != null) {
HostEventArgument host= evt.getHost();
ManagedObjectReference mor= host.getHost();
logInfo=logInfo+"\n host:" +host.getName() + ", hostEntity=" + mor.getVal();
}
if (evt.getVm() != null) {
VmEventArgument vm= evt.getVm();
ManagedObjectReference mor= vm.getVm();
logInfo=logInfo+"\n vm:" +vm.getName() + ", vmEntity:" + mor.getVal();
}
log.info(logInfo);
}
/**
* 格式化时间
* @param time
* @return
*/
private String getSimpleDateFormat(long time) {
if(time == 0l)
return "";
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return format.format(new Date(time));
}
/**
* 测试方法
* @param args
*/
public static void main(String[] args) {
try {
Calendar startTime = Calendar.getInstance();
startTime.roll(Calendar.DATE, false);//设置查询,一天内的事件
EventCollector collector = new EventCollector();
String[] url = new String[4];
url[1] = "";
url[0] = "192.168.98.203"; //云中心的IP
url[2] = "administrator";
url[3] = "ulabcde!@#";
collector.doCollect(url);
} catch (Exception e) {
e.printStackTrace();
}
}
}
VMware事件处理
package com.ultrapower.ultranms.monitor.collector.vm.vmware.event;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.vmware.vim25.ComputeResourceEventArgument;
import com.vmware.vim25.DatacenterEventArgument;
import com.vmware.vim25.DatastoreEventArgument;
import com.vmware.vim25.Event;
import com.vmware.vim25.HostEventArgument;
import com.vmware.vim25.VmEventArgument;
/**
* @Title:VMware事件处理
*/
public class EventProcessor {
private Logger log = LogManager.getLogger(EventProcessor.class);
public void process(Event evt, String[] url) {
String type = evt.getClass().getSimpleName();// 事件类型
String text = evt.getFullFormattedMessage();// 事件内容
String userName = evt.getUserName();// 引发该事件的用户
if(userName != null && !userName.trim().equals(""))
text += ", 操作用户:" + userName;
if(type.equals("VmCreatedEvent") || type.equals("VmRemovedEvent")) { //成功创建虚拟机事件/虚拟机被清除回收事件
if (evt.getDatacenter() != null) {
DatacenterEventArgument dc = evt.getDatacenter();
System.out.println("DataCenter: " + dc.getDatacenter().getVal() + ", type: " + type + ", text: " + text);
VmEventArgument vm = evt.getVm();
}
} else if(type.equals("VmRenamedEvent") || type.equals("VmBeingRelocatedEvent") || //虚拟机虚拟机重命名事件/虚拟机被迁移事件
type.equals("MigrationErrorEvent") || type.equals("VmCloneFailedEvent") || //迁移错误事件/克隆失败事件
type.equals("VmDisconnectedEvent") || //虚拟机断开连接事件
type.equals("MigrationResourceWarningEvent") || type.equals("VmFailedToPowerOnEvent") || type.equals("VmFailedToPowerOffEvent")){ //资源迁移警告事件/虚拟机启动失败事件/虚拟机关闭失败事件
if (evt.getVm() != null) {
VmEventArgument vm = evt.getVm();
System.out.println("VM: " + vm.getVm().getVal() + ", " + vm.getName() + ", type: " + type + ", text: " + text);
} else if (evt.getHost() != null) {
HostEventArgument host = evt.getHost();
System.out.println("Host: " + host.getName() + ", type: " + type + ", text: " + text);
} else if (evt.getDatacenter() != null) {
DatacenterEventArgument dc = evt.getDatacenter();
System.out.println("DataCenter: " + dc.getDatacenter().getVal() + ", type: " + type + ", text: " + text);
}
} else if(type.equals("VmConnectedEvent")){ //虚拟机已连接事件
if (evt.getDatacenter() != null) {
DatacenterEventArgument dc = evt.getDatacenter();
System.out.println("DataCenter: " + dc.getDatacenter().getVal() + ", type: " + type + ", text: " + text);
}
} else if(type.equals("ClusterCreatedEvent") || type.equals("ClusterDestroyedEvent") ) { //集群创建/删除事件
if (evt.getDatacenter() != null) {
DatacenterEventArgument dc = evt.getDatacenter();
System.out.println("DataCenter: " + dc.getDatacenter().getVal() + ", type: " + type + ", text: " + text);
}
} else if(type.equals("HostOvercommittedEvent")) { //集群超出主机容量事件
if (evt.getComputeResource() != null) {
ComputeResourceEventArgument cr = evt.getComputeResource();
System.out.println("ComputeResource: " + cr.getName() + ", type: " + type + ", text: " + text);
} else if (evt.getDatacenter() != null) {
DatacenterEventArgument dc = evt.getDatacenter();
System.out.println("DataCenter: " + dc.getDatacenter().getVal() + ", type: " + type + ", text: " + text);
}
} else if(type.equals("HostConnectionLostEvent") || type.equals("HostRemovedEvent")) { //主机连接/主机删除事件
if (evt.getDatacenter() != null) {
DatacenterEventArgument dc = evt.getDatacenter();
System.out.println("DataCenter: " + dc.getDatacenter().getVal() + ", type: " + type + ", text: " + text);
}
} else if(type.equals("HostConnectedEvent")) { //主机已连接事件
if (evt.getDatacenter() != null) {
DatacenterEventArgument dc = evt.getDatacenter();
System.out.println("DataCenter: " + dc.getDatacenter().getVal() + ", type: " + type + ", text: " + text);
}
} else if(type.equals("HostDisconnectedEvent") || type.equals("HostIpChangedEvent") || //主机断开/主机IP改变事件
type.equals("DatastoreRemovedOnHostEvent") || type.equals("EnteredMaintenanceModeEvent") || //删除在主机的数据存储事件/已经进入维护模式
type.equals("HostCnxFailedTimeoutEvent") || type.equals("DuplicateIpDetectedEvent")) { //主机连接超时事件/检测到IP重复事件
if (evt.getHost() != null) {
HostEventArgument host = evt.getHost();
System.out.println("Host: " + host.getName() + ", type: " + type + ", text: " + text);
} else if (evt.getDatacenter() != null) {
DatacenterEventArgument dc = evt.getDatacenter();
System.out.println("DataCenter: " + dc.getDatacenter().getVal() + ", type: " + type + ", text: " + text);
}
} else if(type.equals("DatastoreDestroyedEvent") ) { //数据存储被删除
if (evt.getDatacenter() != null) {
DatacenterEventArgument dc = evt.getDatacenter();
System.out.println("DataCenter: " + dc.getDatacenter().getVal() + ", type: " + type + ", text: " + text);
}
} else if(type.equals("DatastoreFileDeletedEvent")) { //删除数据存储文件事件
if (evt.getDs() != null) {
DatastoreEventArgument ce = evt.getDs();
System.out.println("Datastore: " + ce.getName() + ", type: " + type + ", text: " + text);
} else if (evt.getDatacenter() != null) {
DatacenterEventArgument dc = evt.getDatacenter();
System.out.println("DataCenter: " + dc.getDatacenter().getVal() + ", type: " + type + ", text: " + text);
}
} else if(type.equals("VmStateFailedToRevertToSnapshot") || type.equals("VmStateRevertedToSnapshot")) { //创建快照失败, 创建快照
if (evt.getVm() != null) {
VmEventArgument vm = evt.getVm();
System.out.println("VM: " + vm.getVm().getVal() + ", " + vm.getName() + ", type: " + type + ", text: " + text);
} else if (evt.getDatacenter() != null) {
DatacenterEventArgument dc = evt.getDatacenter();
System.out.println("DataCenter: " + dc.getDatacenter().getVal() + ", type: " + type + ", text: " + text);
}
}
}
}