/* * MonitoringAgent.java * Copyright (C) 2011,2012 Wannes De Smet * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.xenmaster.monitoring; import com.google.common.collect.ArrayListMultimap; import com.lmax.disruptor.*; import java.io.IOException; import java.net.InetAddress; import java.util.List; import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import org.apache.commons.net.ntp.NTPUDPClient; import org.apache.commons.net.ntp.TimeInfo; import org.apache.log4j.Logger; import org.joda.time.DateTime; import org.xenmaster.monitoring.data.Record; import org.xenmaster.monitoring.engine.Collector; import org.xenmaster.monitoring.engine.Correlator; import org.xenmaster.monitoring.engine.Slot; /** * * @created Oct 6, 2011 * * @author double-u */ public class MonitoringAgent { protected boolean lazy = false, run; protected EventHandler eventHandler; protected Comptroller comptroller; protected Emitter emitter; protected Collector collector; protected Correlator correl; protected EventPublisher publisher; protected ArrayListMultimap<String, Record> vmData, hostData; protected ConcurrentSkipListMap<String, String> data; protected TimeInfo timeInfo; // Disrupting your pants protected RingBuffer<Record> ringBuffer; protected Executor engine; protected static final int RING_SIZE = 32; public static final String NTP_SERVER = "pool.ntp.org"; private static MonitoringAgent instance; private MonitoringAgent() { vmData = ArrayListMultimap.create(); hostData = ArrayListMultimap.create(); data = new ConcurrentSkipListMap<>(); NTPUDPClient nuc = new NTPUDPClient(); ringBuffer = new RingBuffer<>(Record.EVENT_FACTORY, new SingleThreadedClaimStrategy(RING_SIZE), new BlockingWaitStrategy()); eventHandler = new EventHandler(); comptroller = new Comptroller(); emitter = new Emitter(); collector = new Collector(); correl = new Correlator(); setUpEngine(); try { timeInfo = nuc.getTime(InetAddress.getByName(NTP_SERVER)); timeInfo.computeDetails(); Logger.getLogger(getClass()).info("Current time " + new DateTime(System.currentTimeMillis() + timeInfo.getOffset()).toString("dd/MM/yyyy HH:mm:ss.S") + ". Clock drift " + timeInfo.getOffset() + " milliseconds"); } catch (IOException ex) { Logger.getLogger(getClass()).warn("NTP time retrieval failed", ex); } } public static MonitoringAgent get() { if (instance == null) { instance = new MonitoringAgent(); } return instance; } protected final void setUpEngine() { engine = Executors.newCachedThreadPool(new ThreadFactory() { @Override public Thread newThread(Runnable r) { Thread t = new Thread(r); t.setName("Monitoring engine " + r.getClass().getSimpleName()); return t; } }); SequenceBarrier collectorBarrier = ringBuffer.newBarrier(); BatchEventProcessor<Record> cr = new BatchEventProcessor<>(ringBuffer, collectorBarrier, collector); SequenceBarrier correlatorBarrier = ringBuffer.newBarrier(cr.getSequence()); BatchEventProcessor<Record> cb = new BatchEventProcessor<>(ringBuffer, correlatorBarrier, correl); ringBuffer.setGatingSequences(cb.getSequence()); engine.execute(cr); engine.execute(cb); } public void boot() { collector.boot(); } public Correlator getCorrelator() { return correl; } protected class EventPublisher extends Collector.TimingProvider { @Override public void run() { while (run) { long sequence = ringBuffer.next(); Slot nextSlot = getNextSlot(); if (nextSlot == null) { run = false; break; } Record r = ringBuffer.get(sequence); r.attachSlot(nextSlot); ringBuffer.publish(sequence); } } } public List<Record> requestVMData(String ref, int start, int delta, int end) { return null; } public List<Record> requestHostData(String ref, int start, int delta, int end) { return null; } public EventHandler getEventHandler() { return eventHandler; } public Comptroller getComptroller() { return comptroller; } public void start() { run = true; emitter.listenToEvents(eventHandler); eventHandler.start(); comptroller.scheduleSensors(); engine.execute(new EventPublisher()); } public void stop() { run = false; eventHandler.stop(); comptroller.stop(); } }