/* * Copyright 1999-2017 Alibaba Group Holding Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.alibaba.druid.support.monitor; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.pool.DruidDataSourceStatValue; import com.alibaba.druid.stat.DruidDataSourceStatManager; import com.alibaba.druid.stat.JdbcSqlStatValue; import com.alibaba.druid.support.http.stat.WebAppStat; import com.alibaba.druid.support.http.stat.WebAppStatManager; import com.alibaba.druid.support.http.stat.WebAppStatValue; import com.alibaba.druid.support.http.stat.WebURIStatValue; import com.alibaba.druid.support.logging.Log; import com.alibaba.druid.support.logging.LogFactory; import com.alibaba.druid.support.monitor.dao.MonitorDao; import com.alibaba.druid.support.spring.stat.SpringMethodStatValue; import com.alibaba.druid.support.spring.stat.SpringStat; import com.alibaba.druid.support.spring.stat.SpringStatManager; import com.alibaba.druid.util.StringUtils; import com.alibaba.druid.util.Utils; import com.alibaba.druid.wall.WallProviderStatValue; import java.lang.management.ManagementFactory; import java.net.InetAddress; import java.net.NetworkInterface; import java.util.ArrayList; import java.util.Date; import java.util.Enumeration; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import static com.alibaba.druid.util.Utils.getBoolean; import static com.alibaba.druid.util.Utils.getInteger; public class MonitorClient { private final static Log LOG = LogFactory.getLog(MonitorClient.class); private final static long DEFAULT_TIME_BETWEEN_COLLECT = 60 * 5; private ScheduledExecutorService scheduler; private int schedulerThreadSize = 1; private long timeBetweenSqlCollect = DEFAULT_TIME_BETWEEN_COLLECT; private long timeBetweenSpringCollect = DEFAULT_TIME_BETWEEN_COLLECT; private long timeBetweenWebUriCollect = DEFAULT_TIME_BETWEEN_COLLECT; private TimeUnit timeUnit = TimeUnit.SECONDS; private boolean collectSqlEnable = true; private boolean collectSqlWallEnable = true; private boolean collectSpringMethodEnable = true; private boolean collectWebAppEnable = true; private boolean collectWebURIEnable = true; private MonitorDao dao; private String domain; private String app; private String cluster; private String host; private String ip; private int pid; public MonitorClient(){ String name = ManagementFactory.getRuntimeMXBean().getName(); String[] items = name.split("@"); pid = Integer.parseInt(items[0]); host = items[1]; ip = getLocalIPAddress().getHostAddress(); configFromProperty(System.getProperties()); } public void configFromProperty(Properties properties) { { Integer value = getInteger(properties, "druid.monitor.client.schedulerThreadSize"); if (value != null) { this.setSchedulerThreadSize(value); } } { Integer value = getInteger(properties, "druid.monitor.client.timeBetweenSqlCollect"); if (value != null) { this.setTimeBetweenSqlCollect(value); } } { Integer value = getInteger(properties, "druid.monitor.client.timeBetweenSpringCollect"); if (value != null) { this.setTimeBetweenSpringCollect(value); } } { Integer value = getInteger(properties, "druid.monitor.client.timeBetweenWebUriCollect"); if (value != null) { this.setTimeBetweenWebUriCollect(value); } } { Boolean value = getBoolean(properties, "druid.monitor.client.collectSqlEnable"); if (value != null) { this.setCollectSqlEnable(value); } } { Boolean value = getBoolean(properties, "druid.monitor.client.collectSqlWallEnable"); if (value != null) { this.setCollectSqlWallEnable(value); } } { Boolean value = getBoolean(properties, "druid.monitor.client.collectSpringMethodEnable"); if (value != null) { this.setCollectSpringMethodEnable(value); } } { Boolean value = getBoolean(properties, "druid.monitor.client.collectWebAppEnable"); if (value != null) { this.setCollectWebAppEnable(value); } } { Boolean value = getBoolean(properties, "druid.monitor.client.collectWebURIEnable"); if (value != null) { this.setCollectWebURIEnable(value); } } { domain = properties.getProperty("druid.monitor.domain"); if (StringUtils.isEmpty(domain)) { domain = "default"; } } { app = properties.getProperty("druid.monitor.app"); if (StringUtils.isEmpty(app)) { app = "default"; } } { cluster = properties.getProperty("druid.monitor.cluster"); if (StringUtils.isEmpty(cluster)) { cluster = "default"; } } } public void stop() { } public void start() { checkInst(); if (scheduler == null) { scheduler = new ScheduledThreadPoolExecutor(schedulerThreadSize); } scheduler.scheduleAtFixedRate(new Runnable() { @Override public void run() { collectSql(); } }, timeBetweenSqlCollect, timeBetweenSqlCollect, timeUnit); scheduler.scheduleAtFixedRate(new Runnable() { @Override public void run() { collectSpringMethod(); } }, timeBetweenSpringCollect, timeBetweenSpringCollect, timeUnit); scheduler.scheduleAtFixedRate(new Runnable() { @Override public void run() { collectWebURI(); } }, timeBetweenWebUriCollect, timeBetweenWebUriCollect, timeUnit); } public ScheduledExecutorService getScheduler() { return scheduler; } public void setScheduler(ScheduledExecutorService scheduler) { this.scheduler = scheduler; } public void checkInst() { try { dao.insertAppIfNotExits(domain, app); dao.insertClusterIfNotExits(domain, app, cluster); dao.insertOrUpdateInstance(domain, app, cluster, host, ip, Utils.getStartTime(), pid); } catch (Exception ex) { LOG.error("checkInst error", ex); } } @SuppressWarnings("resource") public void collectSql() { if ((!collectSqlEnable) && !collectSqlWallEnable) { return; } Set<Object> dataSources = DruidDataSourceStatManager.getInstances().keySet(); List<DruidDataSourceStatValue> statValueList = new ArrayList<DruidDataSourceStatValue>(dataSources.size()); List<WallProviderStatValue> wallStatValueList = new ArrayList<WallProviderStatValue>(); for (Object item : dataSources) { if (!(item instanceof DruidDataSource)) { continue; } DruidDataSource dataSource = (DruidDataSource) item; if (collectSqlEnable) { DruidDataSourceStatValue statValue = dataSource.getStatValueAndReset(); statValueList.add(statValue); } if (collectSqlWallEnable) { WallProviderStatValue wallStatValue = dataSource.getWallStatValue(true); if (wallStatValue != null && wallStatValue.getCheckCount() > 0) { wallStatValueList.add(wallStatValue); } } } MonitorContext ctx = createContext(); if (statValueList.size() > 0) { dao.saveSql(ctx, statValueList); } if (wallStatValueList.size() > 0) { dao.saveSqlWall(ctx, wallStatValueList); } } private MonitorContext createContext() { MonitorContext ctx = new MonitorContext(); ctx.setDomain(domain); ctx.setApp(app); ctx.setCluster(cluster); ctx.setCollectTime(new Date()); ctx.setPID(pid); ctx.setHost(host); ctx.setCollectTime(Utils.getStartTime()); return ctx; } private void collectSpringMethod() { if (!collectSpringMethodEnable) { return; } List<SpringMethodStatValue> statValueList = new ArrayList<SpringMethodStatValue>(); Set<Object> stats = SpringStatManager.getInstance().getSpringStatSet(); for (Object item : stats) { if (!(item instanceof SpringStat)) { continue; } SpringStat sprintStat = (SpringStat) item; statValueList.addAll(sprintStat.getStatList(true)); } if (statValueList.size() > 0) { MonitorContext ctx = createContext(); dao.saveSpringMethod(ctx, statValueList); } } private void collectWebURI() { if ((!collectWebAppEnable) && !collectWebURIEnable) { return; } List<WebURIStatValue> webURIValueList = new ArrayList<WebURIStatValue>(); List<WebAppStatValue> webAppStatValueList = new ArrayList<WebAppStatValue>(); Set<Object> stats = WebAppStatManager.getInstance().getWebAppStatSet(); for (Object item : stats) { if (!(item instanceof WebAppStat)) { continue; } WebAppStat webAppStat = (WebAppStat) item; if (collectWebAppEnable) { WebAppStatValue webAppStatValue = webAppStat.getStatValue(true); webAppStatValueList.add(webAppStatValue); } if (collectWebURIEnable) { webURIValueList.addAll(webAppStat.getURIStatValueList(true)); } } MonitorContext ctx = createContext(); if (webURIValueList.size() > 0) { dao.saveWebURI(ctx, webURIValueList); } if (webAppStatValueList.size() > 0) { dao.saveWebApp(ctx, webAppStatValueList); } } public List<JdbcSqlStatValue> loadSqlList(Map<String, Object> filters) { return dao.loadSqlList(filters); } public MonitorDao getDao() { return dao; } public void setDao(MonitorDao dao) { this.dao = dao; } public long getTimeBetweenSqlCollect() { return timeBetweenSqlCollect; } public void setTimeBetweenSqlCollect(long timeBetweenSqlCollect) { this.timeBetweenSqlCollect = timeBetweenSqlCollect; } public long getTimeBetweenSpringCollect() { return timeBetweenSpringCollect; } public void setTimeBetweenSpringCollect(long timeBetweenSpringCollect) { this.timeBetweenSpringCollect = timeBetweenSpringCollect; } public long getTimeBetweenWebUriCollect() { return timeBetweenWebUriCollect; } public void setTimeBetweenWebUriCollect(long timeBetweenWebUriCollect) { this.timeBetweenWebUriCollect = timeBetweenWebUriCollect; } public TimeUnit getTimeUnit() { return timeUnit; } public void setTimeUnit(TimeUnit timeUnit) { this.timeUnit = timeUnit; } public boolean isCollectSqlEnable() { return collectSqlEnable; } public void setCollectSqlEnable(boolean collectSqlEnable) { this.collectSqlEnable = collectSqlEnable; } public boolean isCollectSqlWallEnable() { return collectSqlWallEnable; } public void setCollectSqlWallEnable(boolean collectSqlWallEnable) { this.collectSqlWallEnable = collectSqlWallEnable; } public boolean isCollectSpringMethodEnable() { return collectSpringMethodEnable; } public void setCollectSpringMethodEnable(boolean collectSpringMethodEnable) { this.collectSpringMethodEnable = collectSpringMethodEnable; } public boolean isCollectWebAppEnable() { return collectWebAppEnable; } public void setCollectWebAppEnable(boolean collectWebAppEnable) { this.collectWebAppEnable = collectWebAppEnable; } public boolean isCollectWebURIEnable() { return collectWebURIEnable; } public void setCollectWebURIEnable(boolean collectWebURIEnable) { this.collectWebURIEnable = collectWebURIEnable; } public int getSchedulerThreadSize() { return schedulerThreadSize; } public void setSchedulerThreadSize(int schedulerThreadSize) { this.schedulerThreadSize = schedulerThreadSize; } public String getDomain() { return domain; } public void setDomain(String domain) { this.domain = domain; } public String getApp() { return app; } public void setApp(String app) { this.app = app; } public String getCluster() { return cluster; } public void setCluster(String cluster) { this.cluster = cluster; } public String getHost() { return host; } public void setHost(String host) { this.host = host; } public int getPid() { return pid; } public void setPid(int pid) { this.pid = pid; } public static InetAddress getLocalIPAddress() { try { Enumeration<?> netInterfaces = NetworkInterface.getNetworkInterfaces(); InetAddress inetAddress = null; while (netInterfaces.hasMoreElements()) { NetworkInterface ni = (NetworkInterface) netInterfaces.nextElement(); Enumeration<?> e2 = ni.getInetAddresses(); while (e2.hasMoreElements()) { inetAddress = (InetAddress) e2.nextElement(); if (!inetAddress.isLoopbackAddress() && !inetAddress.getHostAddress().contains(":")) { return inetAddress; } } } } catch (Exception e) { LOG.error("getLocalIP error", e); } return null; } }