package jvmmonitor.agent.monitor; import com.alibaba.fastjson.JSON; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import jvmmonitor.agent.Config; import jvmmonitor.agent.Util; import jvmmonitor.agent.flag.FlagsContainer; import sun.jvmstat.monitor.*; import sun.jvmstat.monitor.event.HostEvent; import sun.jvmstat.monitor.event.HostListener; import sun.jvmstat.monitor.event.VmStatusChangeEvent; import sun.tools.jps.Arguments; import java.net.URISyntaxException; import java.util.Map; import java.util.Set; import java.util.Timer; import java.util.TimerTask; /** * Created by peiliping on 16-12-19. */ public class MonitorManager { private static Arguments JPS_ARGUMENTS = new Arguments(new String[] {"-l"}); private final Map<Integer, MonitorItem> CONTAINER = Maps.newHashMap(); private final DataContainer DATACONTAINER = new DataContainer(); private Config config; private MonitoredHost monitoredHost; private Timer timer = new Timer("Jps"); public MonitorManager(Config config) throws MonitorException { this.config = config; this.monitoredHost = MonitoredHost.getMonitoredHost(JPS_ARGUMENTS.hostId()); this.timer.schedule(new TimerTask() { @Override public void run() { try { Set<Integer> last = Sets.newHashSet(CONTAINER.keySet()); Set<Integer> current = monitoredHost.activeVms(); last.removeAll(current); if (last.size() > 0) { close(last); } findActiveJVM(false, null); } catch (Exception e) { e.printStackTrace(); } } }, 60000, 60000); this.monitoredHost.addHostListener(new HostListener() { public void vmStatusChanged(VmStatusChangeEvent event) { } public void disconnected(HostEvent event) { close(null); } }); this.DATACONTAINER.initMeta(config); } private static VmIdentifier buildVmIdentifier(Integer id) throws URISyntaxException { String vmidString = "//" + id + "?mode=r"; return new VmIdentifier(vmidString); } public synchronized void findActiveJVM(boolean restartAgent, Set<Integer> jvmIds) { try { if (jvmIds == null || jvmIds.size() == 0) { jvmIds = this.monitoredHost.activeVms(); } for (Integer id : jvmIds) { if (!this.CONTAINER.containsKey(id) && this.config.filterPid(id)) { try { MonitoredVm vm = this.monitoredHost.getMonitoredVm(buildVmIdentifier(id), 1000); String mainClass = MonitoredVmUtil.mainClass(vm, true); if (!this.config.filterKeyWords(mainClass)) { MonitorItem item = MonitorItem.builder().pid(id).mainClass(mainClass).monitoredVm(vm).build(); item.initBaseInfo(); if (!restartAgent || this.config.isParseFlagsWhenRestartAgent()) { item.initJVMFlags(); FlagsContainer fc = new FlagsContainer(this.DATACONTAINER, item); if (this.config.isDebug()) System.out.println(JSON.toJSONString(fc)); Util.httpPost(this.config.getUrl(), Util.compress(fc)); } item.initModules(this.config); this.CONTAINER.put(id, item); } else { this.monitoredHost.detach(vm); } } catch (Throwable e) { System.out.println("ID : " + id); e.printStackTrace(); } } } } catch (Exception e) { e.printStackTrace(); } } public synchronized void close(Set<Integer> vmIds) { if (vmIds == null || vmIds.size() == 0) { vmIds = Sets.newHashSet(); vmIds.addAll(this.CONTAINER.keySet()); } for (Integer id : vmIds) { MonitorItem item = this.CONTAINER.remove(id); try { if (item != null) { this.DATACONTAINER.getData().remove(item.getMainClass()); this.monitoredHost.detach(item.getMonitoredVm()); } } catch (MonitorException e) { e.printStackTrace(); } } } private int counter = 1; private boolean match4SendData() { return this.counter % this.config.getMultiple4SendData() == 0; } public synchronized void run() { boolean match = match4SendData(); for (Map.Entry<Integer, MonitorItem> item : this.CONTAINER.entrySet()) { try { item.getValue().run(); if (match) { Map<String, Map<String, long[][]>> v = item.getValue().getMetrics(); if (v.size() > 0) { this.DATACONTAINER.getData().put(item.getValue().getMainClass(), v); } } } catch (Exception e) { e.printStackTrace(); } } if (match) { try { if (this.config.isDebug()) { System.out.println("Monitor Pids : " + CONTAINER.keySet().toString()); System.out.println(JSON.toJSONString(this.DATACONTAINER)); } Util.httpPost(this.config.getUrl(), Util.compress(this.DATACONTAINER)); } catch (Exception e) { e.printStackTrace(); } } this.counter++; } public synchronized void printPerfData() { for (Map.Entry<Integer, MonitorItem> item : CONTAINER.entrySet()) { item.getValue().printPerfData(); } } }