diff --git a/src/main/java/com/alibaba/druid/support/monitor/PushService.java b/src/main/java/com/alibaba/druid/support/monitor/PushService.java index feee40b21f..429c70f8c1 100644 --- a/src/main/java/com/alibaba/druid/support/monitor/PushService.java +++ b/src/main/java/com/alibaba/druid/support/monitor/PushService.java @@ -18,60 +18,191 @@ package com.alibaba.druid.support.monitor; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; import com.alibaba.druid.stat.DruidStatManagerFacade; import com.alibaba.druid.support.http.stat.WebAppStatManager; import com.alibaba.druid.support.json.JSONUtils; import com.alibaba.druid.support.spring.stat.SpringStatManager; +import com.alibaba.druid.util.DaemonThreadFactory; +import com.alibaba.druid.util.HttpClientUtils; +/** + *
+ * 将指定的信息 (includeSql,includeWebApp,includeWebUri,includeWebSession,includeSpring)
+ * 定期 (cycleTime)
+ * post到指定的url (serverUrl) ,请求超时时间(pushTimeOut)
+ * 并进行清零 (autoReset)
+ * 
+ * + * @author sandzhang + */ public class PushService { - private final DruidStatManagerFacade statManagerFacade = DruidStatManagerFacade.getInstance(); + private final static PushService instance = new PushService(); + private static final int DEFAULT_CYCLE_TIME = 5 * 60 * 1000; + private static final int DEFAULT_PUSH_TIMEOUT = 60 * 1000; + + private final DruidStatManagerFacade statManagerFacade = DruidStatManagerFacade.getInstance(); + private final WebAppStatManager webAppStatManager = WebAppStatManager.getInstance(); + private final SpringStatManager springStatManager = SpringStatManager.getInstance(); private String serverUrl; - private boolean includeSql = true; + private boolean includeSql = true; + private boolean includeWebApp = true; + private boolean includeWebUri = true; + private boolean includeWebSession = true; + private boolean includeSpring = true; - private boolean includeWebApp = true; - private boolean includeWebUri = true; - private boolean includeWebSession = true; - private boolean includeSpring = true; + private boolean autoReset = true; - public void collect() { + private long cycleTime = DEFAULT_CYCLE_TIME; + private long pushTimeOut = DEFAULT_PUSH_TIMEOUT; + + private ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1, + new DaemonThreadFactory( + "DruidPullService-Scheduler")); + + private ScheduledFuture executeFuture = null; + + private PushService(){ + } + + public static PushService getInstance() { + return instance; + } + + public void start() { + executeFuture = scheduler.scheduleAtFixedRate(new Runnable() { + + @Override + public void run() { + execute(); + } + + }, 0, cycleTime, TimeUnit.MILLISECONDS); + } + + public void stop() { + if (executeFuture != null) { + if (executeFuture.cancel(true)) { + executeFuture = null; + } + } + } + + protected void execute() { + Map data = collectAndReset(); + String json = JSONUtils.toJSONString(data); + push("data=" + json); + } + + /** + * @return + */ + protected Map collectAndReset() { Map data = new HashMap(); if (includeSql) { List> dataSources = statManagerFacade.getDataSourceStatDataList(true); - data.put("DataSources", dataSources); } if (includeWebApp) { - List> list = WebAppStatManager.getInstance().getWebAppStatData(); + List> list = webAppStatManager.getWebAppStatData(); data.put("WebApp", list); } if (includeWebUri) { - List> list = WebAppStatManager.getInstance().getURIStatData(); - + List> list = webAppStatManager.getURIStatData(); data.put("WebURI", list); } if (includeWebSession) { - List> list = WebAppStatManager.getInstance().getSessionStatData(); - + List> list = webAppStatManager.getSessionStatData(); data.put("WebSession", list); } if (includeSpring) { - List> list = SpringStatManager.getInstance().getMethodStatData(); - + List> list = springStatManager.getMethodStatData(); data.put("Spring", list); } + + if (autoReset) { + statManagerFacade.resetAll(); + } + return data; } - protected void push(Map data) { - String json = JSONUtils.toJSONString(data); - //TODO URL Connection Post + protected void push(String data) { + HttpClientUtils.post(serverUrl, data, pushTimeOut); + } + + public long getCycleTime() { + return cycleTime; + } + + public void setCycleTime(long cycleTime) { + this.cycleTime = cycleTime; + } + + public String getServerUrl() { + return serverUrl; + } + + public void setServerUrl(String serverUrl) { + this.serverUrl = serverUrl; + } + + public boolean isIncludeSql() { + return includeSql; + } + + public void setIncludeSql(boolean includeSql) { + this.includeSql = includeSql; + } + + public boolean isIncludeWebApp() { + return includeWebApp; + } + + public void setIncludeWebApp(boolean includeWebApp) { + this.includeWebApp = includeWebApp; + } + + public boolean isIncludeWebUri() { + return includeWebUri; + } + + public void setIncludeWebUri(boolean includeWebUri) { + this.includeWebUri = includeWebUri; + } + + public boolean isIncludeWebSession() { + return includeWebSession; + } + + public void setIncludeWebSession(boolean includeWebSession) { + this.includeWebSession = includeWebSession; + } + + public boolean isIncludeSpring() { + return includeSpring; + } + + public void setIncludeSpring(boolean includeSpring) { + this.includeSpring = includeSpring; + } + + public boolean isAutoReset() { + return autoReset; + } + + public void setAutoReset(boolean autoReset) { + this.autoReset = autoReset; } } diff --git a/src/main/java/com/alibaba/druid/support/monitor/PushServiceListener.java b/src/main/java/com/alibaba/druid/support/monitor/PushServiceListener.java new file mode 100644 index 0000000000..112f503baf --- /dev/null +++ b/src/main/java/com/alibaba/druid/support/monitor/PushServiceListener.java @@ -0,0 +1,38 @@ +package com.alibaba.druid.support.monitor; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import com.alibaba.druid.support.logging.Log; +import com.alibaba.druid.support.logging.LogFactory; + +public class PushServiceListener implements ServletContextListener { + + private final static Log LOG = LogFactory.getLog(PushServiceListener.class); + + private final static String MONITOR_SERVER_URL = "monitorServerUrl"; + + @Override + public void contextInitialized(ServletContextEvent sce) { + PushService pushService = PushService.getInstance(); + String serverUrl = sce.getServletContext().getInitParameter(MONITOR_SERVER_URL); + if (serverUrl == null) { + LOG.error(MONITOR_SERVER_URL + " can't be null"); + return; + } + + if (LOG.isDebugEnabled()) { + LOG.debug(MONITOR_SERVER_URL + "= " + serverUrl); + } + pushService.setServerUrl(serverUrl); + pushService.start(); + + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + // TODO Auto-generated method stub + + } + +} diff --git a/src/main/java/com/alibaba/druid/util/DaemonThreadFactory.java b/src/main/java/com/alibaba/druid/util/DaemonThreadFactory.java new file mode 100644 index 0000000000..e1a4a18565 --- /dev/null +++ b/src/main/java/com/alibaba/druid/util/DaemonThreadFactory.java @@ -0,0 +1,28 @@ +package com.alibaba.druid.util; + +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author sandzhang + */ +public class DaemonThreadFactory implements ThreadFactory { + + private AtomicInteger threadNo = new AtomicInteger(1); + private final String nameStart; + private final String nameEnd = "]"; + + public DaemonThreadFactory(String poolName){ + nameStart = "[" + poolName + "-"; + } + + public Thread newThread(Runnable r) { + Thread newThread = new Thread(r, nameStart + threadNo.getAndIncrement() + nameEnd); + newThread.setDaemon(true); + if (newThread.getPriority() != Thread.NORM_PRIORITY) { + newThread.setPriority(Thread.NORM_PRIORITY); + } + return newThread; + } + +} diff --git a/src/main/java/com/alibaba/druid/util/HttpClientUtils.java b/src/main/java/com/alibaba/druid/util/HttpClientUtils.java new file mode 100644 index 0000000000..a0e5a742ed --- /dev/null +++ b/src/main/java/com/alibaba/druid/util/HttpClientUtils.java @@ -0,0 +1,74 @@ +package com.alibaba.druid.util; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.net.URL; +import java.net.URLConnection; + +import com.alibaba.druid.support.logging.Log; +import com.alibaba.druid.support.logging.LogFactory; + +/** + * @author sandzhang + */ +public class HttpClientUtils { + + private final static Log LOG = LogFactory.getLog(HttpClientUtils.class); + + public static boolean post(String serverUrl, String data, long timeout) { + StringBuilder responseBuilder = null; + BufferedReader reader = null; + OutputStreamWriter wr = null; + + URL url; + try { + url = new URL(serverUrl); + URLConnection conn = url.openConnection(); + conn.setDoOutput(true); + conn.setConnectTimeout(1000 * 5); + wr = new OutputStreamWriter(conn.getOutputStream()); + + wr.write(data); + wr.flush(); + + if (LOG.isDebugEnabled()) { + reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); + responseBuilder = new StringBuilder(); + String line = null; + while ((line = reader.readLine()) != null) { + responseBuilder.append(line + "\n"); + } + LOG.debug(responseBuilder.toString()); + } + } catch (IOException e) { + LOG.error("", e); + } finally { + + if (wr != null) { + try { + wr.close(); + } catch (IOException e) { + LOG.error("close error", e); + } + } + + if (reader != null) { + try { + reader.close(); + } catch (IOException e) { + LOG.error("close error", e); + } + } + + } + + return false; + } + + public static void main(String args[]) { + post("http://www.alibaba.com/trade/search", "fsb=y&IndexArea=product_en&CatId=&SearchText=test", 6000); + } + +}