From f9a06e7a85c0ce3b9762beebba84cf4159565afc Mon Sep 17 00:00:00 2001 From: wenshao Date: Sat, 17 Aug 2013 22:36:21 +0800 Subject: [PATCH] improve monitor support --- .../druid/support/monitor/MonitorClient.java | 87 ++++++++++++- .../druid/support/monitor/MonitorContext.java | 36 +++--- .../monitor/dao/MonitorDaoJdbcImpl.java | 117 ++++++++++++++++-- .../support/monitor/entity/MonitorDomain.java | 39 ------ .../java/com/alibaba/druid/util/Utils.java | 16 +-- .../resources/support/monitor/mysql/wall.sql | 78 ++++++++++++ .../monitor/MonitorDaoJdbcImplTest.java | 25 ++-- 7 files changed, 309 insertions(+), 89 deletions(-) delete mode 100644 src/main/java/com/alibaba/druid/support/monitor/entity/MonitorDomain.java create mode 100644 src/main/resources/support/monitor/mysql/wall.sql diff --git a/src/main/java/com/alibaba/druid/support/monitor/MonitorClient.java b/src/main/java/com/alibaba/druid/support/monitor/MonitorClient.java index 11badc1d39..fc71b1ae54 100644 --- a/src/main/java/com/alibaba/druid/support/monitor/MonitorClient.java +++ b/src/main/java/com/alibaba/druid/support/monitor/MonitorClient.java @@ -18,6 +18,7 @@ import static com.alibaba.druid.util.Utils.getBoolean; import static com.alibaba.druid.util.Utils.getInteger; +import java.lang.management.ManagementFactory; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -40,6 +41,7 @@ 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; @@ -63,7 +65,20 @@ public class MonitorClient { private MonitorDao dao; + private String domain; + private String app; + private String cluster; + private String host; + private int pid; + public MonitorClient(){ + String name = ManagementFactory.getRuntimeMXBean().getName(); + + String[] items = name.split("@"); + + pid = Integer.parseInt(items[0]); + host = items[1]; + configFromPropety(System.getProperties()); } @@ -128,10 +143,30 @@ public void configFromPropety(Properties properties) { 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() { @@ -216,8 +251,14 @@ public void collectSql() { private MonitorContext createContext() { MonitorContext ctx = new MonitorContext(); + + ctx.setDomain(domain); + ctx.setApp(app); + ctx.setCluster(cluster); + ctx.setCollectTime(new Date()); - ctx.setPID(Utils.getPID()); + ctx.setPID(pid); + ctx.setHost(host); ctx.setCollectTime(Utils.getStartTime()); return ctx; } @@ -376,4 +417,44 @@ 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; + } + } diff --git a/src/main/java/com/alibaba/druid/support/monitor/MonitorContext.java b/src/main/java/com/alibaba/druid/support/monitor/MonitorContext.java index 1737d723c4..308139eec2 100644 --- a/src/main/java/com/alibaba/druid/support/monitor/MonitorContext.java +++ b/src/main/java/com/alibaba/druid/support/monitor/MonitorContext.java @@ -21,17 +21,23 @@ public class MonitorContext { + public static String DEFAULT_DOMAIN; + private final Map atrributes = new HashMap(); - private String domainName = "default"; - private String appName = "default"; - private String clusterName = "default"; + private String domain = "default"; + private String app = "default"; + private String cluster = "default"; private String host; private int pid; private Date collectTime; private Date startTime; + public MonitorContext(){ + + } + public Date getCollectTime() { return collectTime; } @@ -76,28 +82,28 @@ public void setPid(int pid) { this.pid = pid; } - public String getDomainName() { - return domainName; + public String getDomain() { + return domain; } - public void setDomainName(String domainName) { - this.domainName = domainName; + public void setDomain(String domain) { + this.domain = domain; } - public String getAppName() { - return appName; + public String getApp() { + return app; } - public void setAppName(String appName) { - this.appName = appName; + public void setApp(String app) { + this.app = app; } - public String getClusterName() { - return clusterName; + public String getCluster() { + return cluster; } - public void setClusterName(String clusterName) { - this.clusterName = clusterName; + public void setCluster(String cluster) { + this.cluster = cluster; } } diff --git a/src/main/java/com/alibaba/druid/support/monitor/dao/MonitorDaoJdbcImpl.java b/src/main/java/com/alibaba/druid/support/monitor/dao/MonitorDaoJdbcImpl.java index 5cbaf877eb..cf49bb564d 100644 --- a/src/main/java/com/alibaba/druid/support/monitor/dao/MonitorDaoJdbcImpl.java +++ b/src/main/java/com/alibaba/druid/support/monitor/dao/MonitorDaoJdbcImpl.java @@ -44,11 +44,15 @@ import com.alibaba.druid.support.monitor.annotation.AggregateType; import com.alibaba.druid.support.monitor.annotation.MField; import com.alibaba.druid.support.monitor.annotation.MTable; +import com.alibaba.druid.support.monitor.entity.MonitorApp; import com.alibaba.druid.support.spring.stat.SpringMethodStatValue; import com.alibaba.druid.util.JdbcUtils; import com.alibaba.druid.util.StringUtils; import com.alibaba.druid.util.Utils; +import com.alibaba.druid.wall.WallFunctionStatValue; import com.alibaba.druid.wall.WallProviderStatValue; +import com.alibaba.druid.wall.WallSqlStatValue; +import com.alibaba.druid.wall.WallTableStatValue; public class MonitorDaoJdbcImpl implements MonitorDao { @@ -62,6 +66,11 @@ public class MonitorDaoJdbcImpl implements MonitorDao { private BeanInfo webURIStatBeanInfo = new BeanInfo(WebURIStatValue.class); private BeanInfo webAppStatBeanInfo = new BeanInfo(WebAppStatValue.class); + private BeanInfo wallProviderStatBeanInfo = new BeanInfo(WallProviderStatValue.class); + private BeanInfo wallSqlStatBeanInfo = new BeanInfo(WallSqlStatValue.class); + private BeanInfo wallTableStatBeanInfo = new BeanInfo(WallTableStatValue.class); + private BeanInfo wallFunctionStatBeanInfo = new BeanInfo(WallFunctionStatValue.class); + public MonitorDaoJdbcImpl(){ } @@ -72,7 +81,9 @@ public void createTables(String dbType) { "springmethod.sql", // "sql.sql", // "webapp.sql", // - "weburi.sql" }; + "weburi.sql", + "wall.sql" + }; for (String item : resources) { String path = "/support/monitor/" + dbType + "/" + item; @@ -99,7 +110,7 @@ public void setDataSource(DataSource dataSource) { @Override public void saveSql(MonitorContext ctx, List dataSourceList) { save(dataSourceStatBeanInfo, ctx, dataSourceList); - + for (DruidDataSourceStatValue dataSourceStatValue : dataSourceList) { List sqlList = dataSourceStatValue.getSqlList(); save(sqlStatBeanInfo, ctx, sqlList); @@ -115,6 +126,19 @@ public void saveSpringMethod(MonitorContext ctx, List lis public void saveWebURI(MonitorContext ctx, List list) { save(webURIStatBeanInfo, ctx, list); } + + @Override + public void saveSqlWall(MonitorContext ctx, List statList) { + save(wallProviderStatBeanInfo, ctx, statList); + + for (WallProviderStatValue providerStat : statList) { + save(wallSqlStatBeanInfo, ctx, providerStat.getWhiteList()); + save(wallSqlStatBeanInfo, ctx, providerStat.getBlackList()); + + save(wallTableStatBeanInfo, ctx, providerStat.getTables()); + save(wallFunctionStatBeanInfo, ctx, providerStat.getFunctions()); + } + } @Override public void saveWebApp(MonitorContext ctx, List list) { @@ -437,8 +461,8 @@ private void saveHash(FieldInfo hashField, MonitorContext ctx, List list) { conn = dataSource.getConnection(); stmt = conn.prepareStatement(sql); - stmt.setString(1, ctx.getDomainName()); - stmt.setString(2, ctx.getAppName()); + stmt.setString(1, ctx.getDomain()); + stmt.setString(2, ctx.getApp()); stmt.setString(3, hashType); stmt.setLong(4, hash); stmt.setString(5, value); @@ -463,6 +487,10 @@ private void saveHash(FieldInfo hashField, MonitorContext ctx, List list) { } private void save(BeanInfo beanInfo, MonitorContext ctx, List list) { + if (list.size() == 0) { + return; + } + for (FieldInfo hashField : beanInfo.getHashFields()) { saveHash(hashField, ctx, list); } @@ -496,9 +524,9 @@ protected void setParameterForSqlStat(BeanInfo beanInfo, // Object sqlStat) throws SQLException { int paramIndex = 1; - setParam(stmt, paramIndex++, ctx.getDomainName()); - setParam(stmt, paramIndex++, ctx.getAppName()); - setParam(stmt, paramIndex++, ctx.getClusterName()); + setParam(stmt, paramIndex++, ctx.getDomain()); + setParam(stmt, paramIndex++, ctx.getApp()); + setParam(stmt, paramIndex++, ctx.getCluster()); setParam(stmt, paramIndex++, ctx.getHost()); setParam(stmt, paramIndex++, ctx.getPID()); setParam(stmt, paramIndex++, ctx.getCollectTime()); @@ -518,8 +546,10 @@ protected void setParameterForSqlStat(BeanInfo beanInfo, // setParam(stmt, paramIndex, (String) value); } else if (fieldType.equals(Date.class)) { setParam(stmt, paramIndex, (Date) value); + } else if (fieldType.equals(boolean.class) || fieldType.equals(Boolean.class)) { + setParam(stmt, paramIndex, (Boolean) value); } else { - throw new UnsupportedOperationException(); + throw new UnsupportedOperationException("not support type : " + fieldType); } paramIndex++; @@ -585,6 +615,14 @@ static void setParam(PreparedStatement stmt, int paramIndex, String value) throw stmt.setString(paramIndex, value); } } + + static void setParam(PreparedStatement stmt, int paramIndex, Boolean value) throws SQLException { + if (value == null) { + stmt.setNull(paramIndex, Types.BOOLEAN); + } else { + stmt.setBoolean(paramIndex, value); + } + } static void setParam(PreparedStatement stmt, int paramIndex, Long value) throws SQLException { if (value == null || value == 0) { @@ -755,8 +793,67 @@ public String getCacheValue(long hash) { } } - @Override - public void saveSqlWall(MonitorContext ctx, List statList) { + public void insertAppIfNotExits(String domain, String app) throws SQLException { + MonitorApp monitorApp = findApp(domain, app); + if (monitorApp != null) { + return; + } + + String sql = "insert druid_app (domain, app) values (?, ?)"; + JdbcUtils.execute(dataSource, sql, domain, app); + } + + public List listApp(String domain) throws SQLException { + List list = new ArrayList(); + + String sql = "select id, domain, app from druid_app where domain = ? and app = ?"; + Connection conn = null; + PreparedStatement stmt = null; + ResultSet rs = null; + try { + conn = dataSource.getConnection(); + stmt = conn.prepareStatement(sql); + rs = stmt.executeQuery(); + if (rs.next()) { + list.add(readApp(rs)); + } + + return list; + } finally { + JdbcUtils.close(rs); + JdbcUtils.close(stmt); + JdbcUtils.close(conn); + } + } + + public MonitorApp findApp(String domain, String app) throws SQLException { + String sql = "select id, domain, app from druid_app where domain = ? and app = ?"; + Connection conn = null; + PreparedStatement stmt = null; + ResultSet rs = null; + try { + conn = dataSource.getConnection(); + stmt = conn.prepareStatement(sql); + rs = stmt.executeQuery(); + if (rs.next()) { + return readApp(rs); + } + + return null; + } finally { + JdbcUtils.close(rs); + JdbcUtils.close(stmt); + JdbcUtils.close(conn); + } + } + + private MonitorApp readApp(ResultSet rs) throws SQLException { + MonitorApp app = new MonitorApp(); + + app.setId(rs.getLong(1)); + app.setDomain(rs.getString(2)); + app.setApp(rs.getString(3)); + return app; } } diff --git a/src/main/java/com/alibaba/druid/support/monitor/entity/MonitorDomain.java b/src/main/java/com/alibaba/druid/support/monitor/entity/MonitorDomain.java deleted file mode 100644 index f502dd761c..0000000000 --- a/src/main/java/com/alibaba/druid/support/monitor/entity/MonitorDomain.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 1999-2011 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.entity; - -public class MonitorDomain { - - private long id; - private String domain; - - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - public String getDomain() { - return domain; - } - - public void setDomain(String domain) { - this.domain = domain; - } - -} diff --git a/src/main/java/com/alibaba/druid/util/Utils.java b/src/main/java/com/alibaba/druid/util/Utils.java index 984b8ff554..412e824eb0 100644 --- a/src/main/java/com/alibaba/druid/util/Utils.java +++ b/src/main/java/com/alibaba/druid/util/Utils.java @@ -170,7 +170,7 @@ public static Boolean getBoolean(Properties properties, String key) { } return null; } - + public static Boolean getBoolean(GenericServlet servlet, String key) { String property = servlet.getInitParameter(key); if ("true".equals(property)) { @@ -236,20 +236,6 @@ public static Class loadClass(String className) { } } - private static int pid; - - public final static int getPID() { - if (pid == 0) { - String name = ManagementFactory.getRuntimeMXBean().getName(); - - String[] items = name.split("@"); - - pid = Integer.parseInt(items[0]); - } - - return pid; - } - private static Date startTime; public final static Date getStartTime() { diff --git a/src/main/resources/support/monitor/mysql/wall.sql b/src/main/resources/support/monitor/mysql/wall.sql new file mode 100644 index 0000000000..7077ffc32f --- /dev/null +++ b/src/main/resources/support/monitor/mysql/wall.sql @@ -0,0 +1,78 @@ +CREATE TABLE druid_wall( + id bigint(20) NOT NULL AUTO_INCREMENT, + domain varchar(45) NOT NULL, + app varchar(45) NOT NULL, + cluster varchar(45) NOT NULL, + host varchar(128), + pid int(10) NOT NULL, + collectTime datetime NOT NULL, + name varchar(256), + checkCount bigint(20), + hardCheckCount bigint(20), + violationCount bigint(20), + whiteListHitCount bigint(20), + blackListHitCount bigint(20), + syntaxErrorCount bigint(20), + violationEffectRowCount bigint(20), + PRIMARY KEY(id) +); +CREATE INDEX druid_wall_index ON druid_wall (collectTime, domain, app); + +CREATE TABLE druid_wall_sql( + id bigint(20) NOT NULL AUTO_INCREMENT, + domain varchar(45) NOT NULL, + app varchar(45) NOT NULL, + cluster varchar(45) NOT NULL, + host varchar(128), pid int(10) NOT NULL, + collectTime datetime NOT NULL, + sql varchar(256), + sqlSample varchar(256), + executeCount bigint(20), + fetchRowCount bigint(20), + updateCount bigint(20), + syntaxError int(1), + violationMessage varchar(256), + PRIMARY KEY(id) +); +CREATE INDEX druid_wall_sql_index ON druid_wall_sql (collectTime, domain, app); + +CREATE TABLE druid_wall_table( + id bigint(20) NOT NULL AUTO_INCREMENT, + domain varchar(45) NOT NULL, + app varchar(45) NOT NULL, + cluster varchar(45) NOT NULL, + host varchar(128), + pid int(10) NOT NULL, + collectTime datetime NOT NULL, + name varchar(256), + selectCount bigint(20), + selectIntoCount bigint(20), + insertCount bigint(20), + updateCount bigint(20), + deleteCount bigint(20), + truncateCount bigint(20), + createCount bigint(20), + alterCount bigint(20), + dropCount bigint(20), + replaceCount bigint(20), + deleteDataCount bigint(20), + updateDataCount bigint(20), + insertDataCount bigint(20), + fetchRowCount bigint(20), + PRIMARY KEY(id) +); +CREATE INDEX druid_wall_table_index ON druid_wall_table (collectTime, domain, app); + +CREATE TABLE druid_wall_function( + id bigint(20) NOT NULL AUTO_INCREMENT, + domain varchar(45) NOT NULL, + app varchar(45) NOT NULL, + cluster varchar(45) NOT NULL, + host varchar(128), + pid int(10) NOT NULL, + collectTime datetime NOT NULL, + name varchar(256), + invokeCount bigint(20), + PRIMARY KEY(id) +); +CREATE INDEX druid_wall_function_index ON druid_wall_function (collectTime, domain, app); \ No newline at end of file diff --git a/src/test/java/com/alibaba/druid/bvt/support/monitor/MonitorDaoJdbcImplTest.java b/src/test/java/com/alibaba/druid/bvt/support/monitor/MonitorDaoJdbcImplTest.java index 9888a82960..1201f90331 100644 --- a/src/test/java/com/alibaba/druid/bvt/support/monitor/MonitorDaoJdbcImplTest.java +++ b/src/test/java/com/alibaba/druid/bvt/support/monitor/MonitorDaoJdbcImplTest.java @@ -13,6 +13,10 @@ import com.alibaba.druid.support.monitor.dao.MonitorDaoJdbcImpl.BeanInfo; import com.alibaba.druid.support.monitor.dao.MonitorDaoJdbcImpl.FieldInfo; import com.alibaba.druid.util.JdbcUtils; +import com.alibaba.druid.wall.WallFunctionStatValue; +import com.alibaba.druid.wall.WallProviderStatValue; +import com.alibaba.druid.wall.WallSqlStatValue; +import com.alibaba.druid.wall.WallTableStatValue; public class MonitorDaoJdbcImplTest extends TestCase { @@ -22,7 +26,7 @@ public class MonitorDaoJdbcImplTest extends TestCase { protected void setUp() throws Exception { dataSource = new DruidDataSource(); dataSource.setUrl("jdbc:h2:mem:test"); -// dataSource.setUrl("jdbc:mysql://localhost:3306/druid-monitor"); + dataSource.setUrl("jdbc:mysql://localhost:3306/druid-monitor"); dataSource.setUsername("druid"); dataSource.setPassword("druid"); dataSource.setInitialSize(1); @@ -39,8 +43,13 @@ protected void tearDown() throws Exception { public void testBuildSql() throws Exception { MonitorDaoJdbcImpl dao = new MonitorDaoJdbcImpl(); dao.setDataSource(dataSource); - - dao.createTables("mysql"); + +// System.out.println(buildCreateSql(dao, new BeanInfo(WallProviderStatValue.class))); +// System.out.println(buildCreateSql(dao, new BeanInfo(WallSqlStatValue.class))); +// System.out.println(buildCreateSql(dao, new BeanInfo(WallTableStatValue.class))); +// System.out.println(buildCreateSql(dao, new BeanInfo(WallFunctionStatValue.class))); + +// dao.createTables("mysql"); MonitorClient client = new MonitorClient(); client.setDao(dao); @@ -52,17 +61,17 @@ public void testBuildSql() throws Exception { for (JdbcSqlStatValue sqlStatValue : sqlList) { System.out.println(sqlStatValue.getData()); } -// Assert.assertEquals(11, sqlList.size()); + // Assert.assertEquals(11, sqlList.size()); } client.collectSql(); - + { List sqlList = client.loadSqlList(Collections. emptyMap()); for (JdbcSqlStatValue sqlStatValue : sqlList) { System.out.println(sqlStatValue.getData()); } -// Assert.assertEquals(14, sqlList.size()); + // Assert.assertEquals(14, sqlList.size()); } } @@ -92,11 +101,13 @@ public String buildCreateSql(MonitorDaoJdbcImpl dao, BeanInfo beanInfo) { buf.append(" varchar(256)"); } else if (field.getFieldType().equals(Date.class)) { buf.append(" datetime"); + } else if (field.getFieldType().equals(boolean.class) || field.getFieldType().equals(Boolean.class)) { + buf.append(" int(1)"); } } buf.append(", PRIMARY KEY(id)"); buf.append(");"); - + buf.append("\n\nCREATE INDEX "); buf.append(dao.getTableName(beanInfo)); buf.append("_index ON ");