From 03d2bfcd908817efba3ef0eaa5a7b2f7e17433cc Mon Sep 17 00:00:00 2001 From: xiaojianjun Date: Mon, 24 Jan 2022 20:35:00 +0800 Subject: [PATCH 01/16] [Feature] Support collecting database connection pool metric,support druid/hikari #8450 --- .../org.apache.skywalking.apm.agent.core.boot.BootService | 1 + 1 file changed, 1 insertion(+) diff --git a/apm-sniffer/apm-agent-core/src/main/resources/META-INF/services/org.apache.skywalking.apm.agent.core.boot.BootService b/apm-sniffer/apm-agent-core/src/main/resources/META-INF/services/org.apache.skywalking.apm.agent.core.boot.BootService index cfda93521c..655b769cc5 100644 --- a/apm-sniffer/apm-agent-core/src/main/resources/META-INF/services/org.apache.skywalking.apm.agent.core.boot.BootService +++ b/apm-sniffer/apm-agent-core/src/main/resources/META-INF/services/org.apache.skywalking.apm.agent.core.boot.BootService @@ -36,3 +36,4 @@ org.apache.skywalking.apm.agent.core.remote.LogReportServiceClient org.apache.skywalking.apm.agent.core.conf.dynamic.ConfigurationDiscoveryService org.apache.skywalking.apm.agent.core.remote.EventReportServiceClient org.apache.skywalking.apm.agent.core.ServiceInstanceGenerator +org.apache.skywalking.apm.agent.core.datasource.DatasourceService From 5e890962410f6619b0e383d70e40758b87b2342b Mon Sep 17 00:00:00 2001 From: xiaojianjun Date: Mon, 24 Jan 2022 20:35:38 +0800 Subject: [PATCH 02/16] [Feature] Support collecting database connection pool metric,support druid/hikari #8450 --- .../core/datasource/AbstractRegister.java | 179 ++++++++++++++++++ .../core/datasource/DatasourceRegister.java | 26 +++ .../core/datasource/DatasourceService.java | 82 ++++++++ .../agent/core/datasource/DruidRegister.java | 69 +++++++ .../core/datasource/HikaricpRegister.java | 65 +++++++ 5 files changed, 421 insertions(+) create mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/AbstractRegister.java create mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/DatasourceRegister.java create mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/DatasourceService.java create mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/DruidRegister.java create mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/HikaricpRegister.java diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/AbstractRegister.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/AbstractRegister.java new file mode 100644 index 0000000000..39c075d38c --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/AbstractRegister.java @@ -0,0 +1,179 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.skywalking.apm.agent.core.datasource; + +import lombok.Data; +import org.apache.skywalking.apm.agent.core.logging.api.ILog; +import org.apache.skywalking.apm.agent.core.logging.api.LogManager; + +import javax.management.MBeanServer; +import javax.management.ObjectName; +import java.lang.management.ManagementFactory; +import java.util.LinkedHashMap; +import java.util.Map; + +public abstract class AbstractRegister implements DatasourceRegister { + private static final ILog LOGGER = LogManager.getLogger(AbstractRegister.class); + protected MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer(); + private Map connections = new LinkedHashMap(); + private static final String ERROR_ATTRIBUTE = "unknown"; + + private String find(String con, String key) { + int index = con.indexOf(key); + int start = 0; + int end = 0; + if (index > -1) { + for (int i = index + key.length(); i < con.length(); i++) { + if (con.charAt(i) == '=') { + start = i + 1; + } + if (con.charAt(i) == ')') { + end = i; + break; + } + } + } + return con.substring(start, end); + } + + public Database parseDatabase(String connection) { + Database database = connections.get(String.valueOf(connection)); + + if (database == null && null != connection && !"".equals(connection)) { + try { + if (connection.contains("jdbc:mysql://")) { + String con = connection.split("jdbc:mysql://")[1]; + con = con.split("\\?")[0]; + int index = con.indexOf(":"); + String ip = ""; + + if (index < 0) { + ip = con.split("/")[0]; + } else { + ip = con.substring(0, index); + } + + String name = con.substring(con.indexOf("/") + 1); + database = new Database(name, ip); + + connections.put(connection, database); + } else if (connection.contains("jdbc:oracle")) { + if (connection.contains("DESCRIPTION")) { + String name = find(connection, "SERVICE_NAME"); + String ip = find(connection, "HOST"); + + database = new Database(name, ip); + connections.put(connection, database); + } else if (connection.contains("@//")) { + String[] tabs = connection.split("/"); + String name = tabs[tabs.length - 1]; + String ip = tabs[tabs.length - 2]; + int index = ip.indexOf(':'); + + if (index > -1) { + ip = ip.substring(0, index); + } + database = new Database(name, ip); + connections.put(connection, database); + } else { + String[] tabs = connection.split(":"); + String ip = "Default"; + + for (String str : tabs) { + int index = str.indexOf("@"); + + if (index > -1) { + ip = str.substring(index + 1).trim(); + } + } + String name = tabs[tabs.length - 1]; + int index = name.indexOf('/'); + + if (index > -1) { + name = name.substring(index + 1); + } + + database = new Database(name, ip); + + connections.put(connection, database); + } + } else { + return new Database("default", "default"); + } + } catch (Exception e) { + LOGGER.error("parse Database url fail ", e); + } + } + return database; + } + + @Data + public class Database { + private String name; + private String ip; + + Database(String name, String ip) { + this.name = name; + this.ip = ip; + } + + @Override + public String toString() { + return name + '_' + ip; + } + } + + protected Integer getIntegerAttribute(ObjectName objectName, String attribute) { + try { + Integer value = (Integer) mbeanServer.getAttribute(objectName, attribute); + return value; + } catch (Exception e) { + return 0; + } + } + + protected Long getLongAttribute(ObjectName objectName, String attribute) { + try { + Long value = (Long) mbeanServer.getAttribute(objectName, attribute); + return value; + } catch (Exception e) { + return 0L; + } + } + + protected String getStringAttribute(ObjectName objectName, String attribute) { + try { + return (String) mbeanServer.getAttribute(objectName, attribute); + } catch (Exception e) { + return ERROR_ATTRIBUTE; + } + } + + protected String getConnection(Map datasources, String key) { + Integer index = datasources.get(key); + if (index == null) { + datasources.put(key, 0); + return key; + } else { + index++; + datasources.put(key, index); + return key + '[' + index + ']'; + } + } +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/DatasourceRegister.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/DatasourceRegister.java new file mode 100644 index 0000000000..9e34dc2934 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/DatasourceRegister.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.skywalking.apm.agent.core.datasource; + +public interface DatasourceRegister { + /** + * @return + */ + boolean register(); +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/DatasourceService.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/DatasourceService.java new file mode 100644 index 0000000000..84303fd280 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/DatasourceService.java @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.skywalking.apm.agent.core.datasource; + +import org.apache.skywalking.apm.agent.core.boot.BootService; +import org.apache.skywalking.apm.agent.core.boot.DefaultImplementor; +import org.apache.skywalking.apm.agent.core.boot.DefaultNamedThreadFactory; +import org.apache.skywalking.apm.agent.core.logging.api.ILog; +import org.apache.skywalking.apm.agent.core.logging.api.LogManager; +import org.apache.skywalking.apm.util.RunnableWithExceptionProtection; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +/** + * The DatasourceService represents a timer, which register Datasource monitor metrics + * {@link DatasourceRegister} + */ +@DefaultImplementor +public class DatasourceService implements BootService, Runnable { + private static final ILog LOGGER = LogManager.getLogger(DatasourceService.class); + private volatile ScheduledFuture registerMetricFuture; + private volatile List datasourceRegisters = new ArrayList(); + + @Override + public void prepare() throws Throwable { + datasourceRegisters.add(new DruidRegister()); + datasourceRegisters.add(new HikaricpRegister()); + } + + @Override + public void boot() throws Throwable { + + registerMetricFuture = Executors.newSingleThreadScheduledExecutor( + new DefaultNamedThreadFactory("DatasourceService-Register")) + .scheduleAtFixedRate(new RunnableWithExceptionProtection( + this, + new RunnableWithExceptionProtection.CallbackWhenException() { + @Override + public void handle(Throwable t) { + LOGGER.error("DatasourceService Register metrics failure.", t); + } + } + ), 0, 30, TimeUnit.SECONDS); + } + + @Override + public void onComplete() throws Throwable { + + } + + @Override + public void shutdown() throws Throwable { + registerMetricFuture.cancel(true); + } + + @Override + public void run() { + for (DatasourceRegister datasourceRegister : datasourceRegisters) { + datasourceRegister.register(); + } + } +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/DruidRegister.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/DruidRegister.java new file mode 100644 index 0000000000..86801f055a --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/DruidRegister.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.skywalking.apm.agent.core.datasource; + +import org.apache.skywalking.apm.agent.core.logging.api.ILog; +import org.apache.skywalking.apm.agent.core.logging.api.LogManager; +import org.apache.skywalking.apm.agent.core.meter.Counter; +import org.apache.skywalking.apm.agent.core.meter.MeterFactory; + +import javax.management.ObjectName; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +public class DruidRegister extends AbstractRegister { + private static final ILog LOGGER = LogManager.getLogger(DruidRegister.class); + + @Override + public boolean register() { + try { + LOGGER.info("DruidRegister register start"); + ObjectName pooledDataSourceObjectName = new ObjectName("com.alibaba.druid:type=DruidDataSource,id=*"); + Set objectNameSet = mbeanServer.queryNames(pooledDataSourceObjectName, null); + + if (objectNameSet == null || objectNameSet.isEmpty()) { + return false; + } + + Map datasources = new LinkedHashMap(); + for (ObjectName objectName : objectNameSet) { + String jdbcUrl = getStringAttribute(objectName, "Url"); + Database datasource = super.parseDatabase(jdbcUrl); + String key = getConnection(datasources, datasource.toString()); + LOGGER.debug("key {}", key); + + MeterFactory.gauge("datasource", () -> getIntegerAttribute(objectName, "ActiveCount").doubleValue()).tag("name", key + "/active").build(); + MeterFactory.gauge("datasource", () -> getIntegerAttribute(objectName, "PoolingCount").doubleValue()).tag("name", key + "/total").build(); + MeterFactory.gauge("datasource", () -> getIntegerAttribute(objectName, "PoolingCount").doubleValue() - getIntegerAttribute(objectName, "ActiveCount").doubleValue()).tag("name", key + "/idle").build(); + MeterFactory.gauge("datasource", () -> getIntegerAttribute(objectName, "LockQueueLength").doubleValue()).tag("name", key + "/lock").build(); + MeterFactory.gauge("datasource", () -> getIntegerAttribute(objectName, "MaxWaitThreadCount").doubleValue()).tag("name", key + "/wait").build(); + MeterFactory.gauge("datasource", () -> getLongAttribute(objectName, "CommitCount").doubleValue()).tag("name", key + "/commit").build(); + MeterFactory.gauge("datasource", () -> getLongAttribute(objectName, "ConnectCount").doubleValue()).tag("name", key + "/connect").build(); + MeterFactory.gauge("datasource", () -> getLongAttribute(objectName, "ConnectErrorCount").doubleValue()).tag("name", key + "/connect_error").build(); + MeterFactory.gauge("datasource", () -> getLongAttribute(objectName, "CreateErrorCount").doubleValue()).tag("name", key + "/create_error").build(); + } + LOGGER.info("DruidRegister register end"); + } catch (Exception e) { + LOGGER.error("Druid Register fail", e); + } + return true; + } + +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/HikaricpRegister.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/HikaricpRegister.java new file mode 100644 index 0000000000..7aa0985683 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/HikaricpRegister.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.skywalking.apm.agent.core.datasource; + +import org.apache.skywalking.apm.agent.core.logging.api.ILog; +import org.apache.skywalking.apm.agent.core.logging.api.LogManager; +import org.apache.skywalking.apm.agent.core.meter.MeterFactory; + +import javax.management.ObjectName; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +public class HikaricpRegister extends AbstractRegister { + private static final ILog LOGGER = LogManager.getLogger(HikaricpRegister.class); + + @Override + public boolean register() { + try { + LOGGER.info("HikariCPRegister register start"); + + ObjectName pooledDataSourceObjectName = new ObjectName("com.zaxxer.hikari:type=Pool (*)"); + Set objectNameSet = mbeanServer.queryNames(pooledDataSourceObjectName, null); + + if (objectNameSet == null || objectNameSet.isEmpty()) { + return false; + } + Map datasources = new LinkedHashMap(); + + for (ObjectName objectName : objectNameSet) { + String jdbcUrl = getStringAttribute(objectName, "Url"); + LOGGER.info("jdbcUrl", jdbcUrl); + Database datasource = super.parseDatabase(jdbcUrl); + String key = getConnection(datasources, datasource.toString()); + + MeterFactory.gauge("datasource", () -> getIntegerAttribute(objectName, "activeConnections").doubleValue()).tag("name", key + "/active").build(); + MeterFactory.gauge("datasource", () -> getIntegerAttribute(objectName, "totalConnections").doubleValue()).tag("name", key + "/total").build(); + MeterFactory.gauge("datasource", () -> getIntegerAttribute(objectName, "idleConnections").doubleValue()).tag("name", key + "/idle").build(); + MeterFactory.gauge("datasource", () -> getIntegerAttribute(objectName, "threadsAwaitingConnection").doubleValue()).tag("name", key + "/wait").build(); + + } + LOGGER.info("HikariCPRegister register end"); + } catch (Exception e) { + LOGGER.error("HikariCP Register fail", e); + } + return true; + } + +} From 5f6aabe3326f9fe54ce2834ee2ad9b797a122e49 Mon Sep 17 00:00:00 2001 From: xiaojianjun Date: Fri, 28 Jan 2022 11:03:28 +0800 Subject: [PATCH 03/16] [Feature] Support collecting database connection pool metric,support druid/hikari/dbcp2 #8450 --- .../core/datasource/AbstractRegister.java | 179 ------------------ .../core/datasource/DatasourceRegister.java | 26 --- .../core/datasource/DatasourceService.java | 82 -------- .../agent/core/datasource/DruidRegister.java | 69 ------- .../core/datasource/HikaricpRegister.java | 65 ------- ...skywalking.apm.agent.core.boot.BootService | 1 - .../apm-sdk-plugin/dbcp-2.x-plugin/pom.xml | 8 +- .../v2/PoolingSetUrlSourceInterceptor.java | 78 ++++++++ .../BasicDataSourceInstrumentation.java | 27 ++- .../apm-sdk-plugin/druid-1.x-plugin/pom.xml | 10 +- .../v1/PoolingSetUrlSourceInterceptor.java | 79 ++++++++ .../DruidDataSourceInstrumentation.java | 27 ++- .../src/main/resources/skywalking-plugin.def | 2 +- .../hikaricp-3.x-4.x-plugin/pom.xml | 8 +- ...ikariDataSourceConstructorInterceptor.java | 60 ++++++ .../define/HikariPoolInstrumentation.java | 75 ++++++++ .../src/main/resources/skywalking-plugin.def | 3 +- 17 files changed, 365 insertions(+), 434 deletions(-) delete mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/AbstractRegister.java delete mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/DatasourceRegister.java delete mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/DatasourceService.java delete mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/DruidRegister.java delete mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/HikaricpRegister.java create mode 100644 apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlSourceInterceptor.java create mode 100644 apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/PoolingSetUrlSourceInterceptor.java create mode 100644 apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/HikariDataSourceConstructorInterceptor.java create mode 100644 apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/define/HikariPoolInstrumentation.java diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/AbstractRegister.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/AbstractRegister.java deleted file mode 100644 index 39c075d38c..0000000000 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/AbstractRegister.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.skywalking.apm.agent.core.datasource; - -import lombok.Data; -import org.apache.skywalking.apm.agent.core.logging.api.ILog; -import org.apache.skywalking.apm.agent.core.logging.api.LogManager; - -import javax.management.MBeanServer; -import javax.management.ObjectName; -import java.lang.management.ManagementFactory; -import java.util.LinkedHashMap; -import java.util.Map; - -public abstract class AbstractRegister implements DatasourceRegister { - private static final ILog LOGGER = LogManager.getLogger(AbstractRegister.class); - protected MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer(); - private Map connections = new LinkedHashMap(); - private static final String ERROR_ATTRIBUTE = "unknown"; - - private String find(String con, String key) { - int index = con.indexOf(key); - int start = 0; - int end = 0; - if (index > -1) { - for (int i = index + key.length(); i < con.length(); i++) { - if (con.charAt(i) == '=') { - start = i + 1; - } - if (con.charAt(i) == ')') { - end = i; - break; - } - } - } - return con.substring(start, end); - } - - public Database parseDatabase(String connection) { - Database database = connections.get(String.valueOf(connection)); - - if (database == null && null != connection && !"".equals(connection)) { - try { - if (connection.contains("jdbc:mysql://")) { - String con = connection.split("jdbc:mysql://")[1]; - con = con.split("\\?")[0]; - int index = con.indexOf(":"); - String ip = ""; - - if (index < 0) { - ip = con.split("/")[0]; - } else { - ip = con.substring(0, index); - } - - String name = con.substring(con.indexOf("/") + 1); - database = new Database(name, ip); - - connections.put(connection, database); - } else if (connection.contains("jdbc:oracle")) { - if (connection.contains("DESCRIPTION")) { - String name = find(connection, "SERVICE_NAME"); - String ip = find(connection, "HOST"); - - database = new Database(name, ip); - connections.put(connection, database); - } else if (connection.contains("@//")) { - String[] tabs = connection.split("/"); - String name = tabs[tabs.length - 1]; - String ip = tabs[tabs.length - 2]; - int index = ip.indexOf(':'); - - if (index > -1) { - ip = ip.substring(0, index); - } - database = new Database(name, ip); - connections.put(connection, database); - } else { - String[] tabs = connection.split(":"); - String ip = "Default"; - - for (String str : tabs) { - int index = str.indexOf("@"); - - if (index > -1) { - ip = str.substring(index + 1).trim(); - } - } - String name = tabs[tabs.length - 1]; - int index = name.indexOf('/'); - - if (index > -1) { - name = name.substring(index + 1); - } - - database = new Database(name, ip); - - connections.put(connection, database); - } - } else { - return new Database("default", "default"); - } - } catch (Exception e) { - LOGGER.error("parse Database url fail ", e); - } - } - return database; - } - - @Data - public class Database { - private String name; - private String ip; - - Database(String name, String ip) { - this.name = name; - this.ip = ip; - } - - @Override - public String toString() { - return name + '_' + ip; - } - } - - protected Integer getIntegerAttribute(ObjectName objectName, String attribute) { - try { - Integer value = (Integer) mbeanServer.getAttribute(objectName, attribute); - return value; - } catch (Exception e) { - return 0; - } - } - - protected Long getLongAttribute(ObjectName objectName, String attribute) { - try { - Long value = (Long) mbeanServer.getAttribute(objectName, attribute); - return value; - } catch (Exception e) { - return 0L; - } - } - - protected String getStringAttribute(ObjectName objectName, String attribute) { - try { - return (String) mbeanServer.getAttribute(objectName, attribute); - } catch (Exception e) { - return ERROR_ATTRIBUTE; - } - } - - protected String getConnection(Map datasources, String key) { - Integer index = datasources.get(key); - if (index == null) { - datasources.put(key, 0); - return key; - } else { - index++; - datasources.put(key, index); - return key + '[' + index + ']'; - } - } -} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/DatasourceRegister.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/DatasourceRegister.java deleted file mode 100644 index 9e34dc2934..0000000000 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/DatasourceRegister.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.skywalking.apm.agent.core.datasource; - -public interface DatasourceRegister { - /** - * @return - */ - boolean register(); -} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/DatasourceService.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/DatasourceService.java deleted file mode 100644 index 84303fd280..0000000000 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/DatasourceService.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.skywalking.apm.agent.core.datasource; - -import org.apache.skywalking.apm.agent.core.boot.BootService; -import org.apache.skywalking.apm.agent.core.boot.DefaultImplementor; -import org.apache.skywalking.apm.agent.core.boot.DefaultNamedThreadFactory; -import org.apache.skywalking.apm.agent.core.logging.api.ILog; -import org.apache.skywalking.apm.agent.core.logging.api.LogManager; -import org.apache.skywalking.apm.util.RunnableWithExceptionProtection; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -/** - * The DatasourceService represents a timer, which register Datasource monitor metrics - * {@link DatasourceRegister} - */ -@DefaultImplementor -public class DatasourceService implements BootService, Runnable { - private static final ILog LOGGER = LogManager.getLogger(DatasourceService.class); - private volatile ScheduledFuture registerMetricFuture; - private volatile List datasourceRegisters = new ArrayList(); - - @Override - public void prepare() throws Throwable { - datasourceRegisters.add(new DruidRegister()); - datasourceRegisters.add(new HikaricpRegister()); - } - - @Override - public void boot() throws Throwable { - - registerMetricFuture = Executors.newSingleThreadScheduledExecutor( - new DefaultNamedThreadFactory("DatasourceService-Register")) - .scheduleAtFixedRate(new RunnableWithExceptionProtection( - this, - new RunnableWithExceptionProtection.CallbackWhenException() { - @Override - public void handle(Throwable t) { - LOGGER.error("DatasourceService Register metrics failure.", t); - } - } - ), 0, 30, TimeUnit.SECONDS); - } - - @Override - public void onComplete() throws Throwable { - - } - - @Override - public void shutdown() throws Throwable { - registerMetricFuture.cancel(true); - } - - @Override - public void run() { - for (DatasourceRegister datasourceRegister : datasourceRegisters) { - datasourceRegister.register(); - } - } -} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/DruidRegister.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/DruidRegister.java deleted file mode 100644 index 86801f055a..0000000000 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/DruidRegister.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.skywalking.apm.agent.core.datasource; - -import org.apache.skywalking.apm.agent.core.logging.api.ILog; -import org.apache.skywalking.apm.agent.core.logging.api.LogManager; -import org.apache.skywalking.apm.agent.core.meter.Counter; -import org.apache.skywalking.apm.agent.core.meter.MeterFactory; - -import javax.management.ObjectName; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; - -public class DruidRegister extends AbstractRegister { - private static final ILog LOGGER = LogManager.getLogger(DruidRegister.class); - - @Override - public boolean register() { - try { - LOGGER.info("DruidRegister register start"); - ObjectName pooledDataSourceObjectName = new ObjectName("com.alibaba.druid:type=DruidDataSource,id=*"); - Set objectNameSet = mbeanServer.queryNames(pooledDataSourceObjectName, null); - - if (objectNameSet == null || objectNameSet.isEmpty()) { - return false; - } - - Map datasources = new LinkedHashMap(); - for (ObjectName objectName : objectNameSet) { - String jdbcUrl = getStringAttribute(objectName, "Url"); - Database datasource = super.parseDatabase(jdbcUrl); - String key = getConnection(datasources, datasource.toString()); - LOGGER.debug("key {}", key); - - MeterFactory.gauge("datasource", () -> getIntegerAttribute(objectName, "ActiveCount").doubleValue()).tag("name", key + "/active").build(); - MeterFactory.gauge("datasource", () -> getIntegerAttribute(objectName, "PoolingCount").doubleValue()).tag("name", key + "/total").build(); - MeterFactory.gauge("datasource", () -> getIntegerAttribute(objectName, "PoolingCount").doubleValue() - getIntegerAttribute(objectName, "ActiveCount").doubleValue()).tag("name", key + "/idle").build(); - MeterFactory.gauge("datasource", () -> getIntegerAttribute(objectName, "LockQueueLength").doubleValue()).tag("name", key + "/lock").build(); - MeterFactory.gauge("datasource", () -> getIntegerAttribute(objectName, "MaxWaitThreadCount").doubleValue()).tag("name", key + "/wait").build(); - MeterFactory.gauge("datasource", () -> getLongAttribute(objectName, "CommitCount").doubleValue()).tag("name", key + "/commit").build(); - MeterFactory.gauge("datasource", () -> getLongAttribute(objectName, "ConnectCount").doubleValue()).tag("name", key + "/connect").build(); - MeterFactory.gauge("datasource", () -> getLongAttribute(objectName, "ConnectErrorCount").doubleValue()).tag("name", key + "/connect_error").build(); - MeterFactory.gauge("datasource", () -> getLongAttribute(objectName, "CreateErrorCount").doubleValue()).tag("name", key + "/create_error").build(); - } - LOGGER.info("DruidRegister register end"); - } catch (Exception e) { - LOGGER.error("Druid Register fail", e); - } - return true; - } - -} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/HikaricpRegister.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/HikaricpRegister.java deleted file mode 100644 index 7aa0985683..0000000000 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/datasource/HikaricpRegister.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.skywalking.apm.agent.core.datasource; - -import org.apache.skywalking.apm.agent.core.logging.api.ILog; -import org.apache.skywalking.apm.agent.core.logging.api.LogManager; -import org.apache.skywalking.apm.agent.core.meter.MeterFactory; - -import javax.management.ObjectName; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; - -public class HikaricpRegister extends AbstractRegister { - private static final ILog LOGGER = LogManager.getLogger(HikaricpRegister.class); - - @Override - public boolean register() { - try { - LOGGER.info("HikariCPRegister register start"); - - ObjectName pooledDataSourceObjectName = new ObjectName("com.zaxxer.hikari:type=Pool (*)"); - Set objectNameSet = mbeanServer.queryNames(pooledDataSourceObjectName, null); - - if (objectNameSet == null || objectNameSet.isEmpty()) { - return false; - } - Map datasources = new LinkedHashMap(); - - for (ObjectName objectName : objectNameSet) { - String jdbcUrl = getStringAttribute(objectName, "Url"); - LOGGER.info("jdbcUrl", jdbcUrl); - Database datasource = super.parseDatabase(jdbcUrl); - String key = getConnection(datasources, datasource.toString()); - - MeterFactory.gauge("datasource", () -> getIntegerAttribute(objectName, "activeConnections").doubleValue()).tag("name", key + "/active").build(); - MeterFactory.gauge("datasource", () -> getIntegerAttribute(objectName, "totalConnections").doubleValue()).tag("name", key + "/total").build(); - MeterFactory.gauge("datasource", () -> getIntegerAttribute(objectName, "idleConnections").doubleValue()).tag("name", key + "/idle").build(); - MeterFactory.gauge("datasource", () -> getIntegerAttribute(objectName, "threadsAwaitingConnection").doubleValue()).tag("name", key + "/wait").build(); - - } - LOGGER.info("HikariCPRegister register end"); - } catch (Exception e) { - LOGGER.error("HikariCP Register fail", e); - } - return true; - } - -} diff --git a/apm-sniffer/apm-agent-core/src/main/resources/META-INF/services/org.apache.skywalking.apm.agent.core.boot.BootService b/apm-sniffer/apm-agent-core/src/main/resources/META-INF/services/org.apache.skywalking.apm.agent.core.boot.BootService index 655b769cc5..cfda93521c 100644 --- a/apm-sniffer/apm-agent-core/src/main/resources/META-INF/services/org.apache.skywalking.apm.agent.core.boot.BootService +++ b/apm-sniffer/apm-agent-core/src/main/resources/META-INF/services/org.apache.skywalking.apm.agent.core.boot.BootService @@ -36,4 +36,3 @@ org.apache.skywalking.apm.agent.core.remote.LogReportServiceClient org.apache.skywalking.apm.agent.core.conf.dynamic.ConfigurationDiscoveryService org.apache.skywalking.apm.agent.core.remote.EventReportServiceClient org.apache.skywalking.apm.agent.core.ServiceInstanceGenerator -org.apache.skywalking.apm.agent.core.datasource.DatasourceService diff --git a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/pom.xml index 1ad2d47eea..37cedb9a85 100644 --- a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/pom.xml @@ -38,7 +38,13 @@ ${dbcp.version} provided + + org.apache.skywalking + apm-jdbc-commons + ${project.version} + provided + - \ No newline at end of file + diff --git a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlSourceInterceptor.java b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlSourceInterceptor.java new file mode 100644 index 0000000000..c5bd912af5 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlSourceInterceptor.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.dbcp.v2; + +import org.apache.commons.dbcp2.BasicDataSource; +import org.apache.skywalking.apm.agent.core.logging.api.ILog; +import org.apache.skywalking.apm.agent.core.logging.api.LogManager; +import org.apache.skywalking.apm.agent.core.meter.MeterFactory; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.plugin.jdbc.connectionurl.parser.URLParser; +import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * {@link PoolingSetUrlSourceInterceptor} intercepted the method of DBCP set url and register metric monitor. + */ +public class PoolingSetUrlSourceInterceptor implements InstanceMethodsAroundInterceptor { + private static final String METER_NAME = "datasource"; + private static final ILog LOGGER = LogManager.getLogger(PoolingSetUrlSourceInterceptor.class); + + private static final Map>> METRIC_MAP = new HashMap>>(); + + static { + METRIC_MAP.put("numActive", (BasicDataSource basicDataSource) -> () -> (double) basicDataSource.getNumActive()); + METRIC_MAP.put("maxTotal", (BasicDataSource basicDataSource) -> () -> (double) basicDataSource.getMaxTotal()); + METRIC_MAP.put("numIdle", (BasicDataSource basicDataSource) -> () -> (double) (basicDataSource.getNumIdle())); + METRIC_MAP.put("maxWaitMillis", (BasicDataSource basicDataSource) -> () -> (double) basicDataSource.getMaxWaitMillis()); + METRIC_MAP.put("maxIdle", (BasicDataSource basicDataSource) -> () -> (double) basicDataSource.getMaxIdle()); + METRIC_MAP.put("minIdle", (BasicDataSource basicDataSource) -> () -> (double) basicDataSource.getMinIdle()); + METRIC_MAP.put("initialSize", (BasicDataSource basicDataSource) -> () -> (double) basicDataSource.getInitialSize()); + } + + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { + if (LOGGER.isInfoEnable()) { + LOGGER.info("metric dbcp init"); + } + BasicDataSource basicDataSource = (BasicDataSource) objInst; + ConnectionInfo connectionInfo = URLParser.parser((String) allArguments[0]); + String tagValue = connectionInfo.getDatabaseName() + "_" + connectionInfo.getDatabasePeer(); + METRIC_MAP.forEach((key, value) -> MeterFactory.gauge(METER_NAME, value.apply(basicDataSource)) + .tag("name", tagValue).tag("status", key).build()); + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/define/BasicDataSourceInstrumentation.java b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/define/BasicDataSourceInstrumentation.java index 2885905758..f99f39d74c 100755 --- a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/define/BasicDataSourceInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/define/BasicDataSourceInstrumentation.java @@ -25,16 +25,18 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; -import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.*; import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; /** * BasicDataSource provides a "one stop shopping" solution for database connection pool solution * basic requirements. BasicDataSource#getConnection() creates (if necessary) and return a connection. + * BasicDataSource#setUrl(String) set url */ public class BasicDataSourceInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { private static final String ENHANCE_CLASS = "org.apache.commons.dbcp2.BasicDataSource"; private static final String CONNECT_GET_INTERCEPTOR = "org.apache.skywalking.apm.plugin.dbcp.v2.PoolingGetConnectInterceptor"; + private static final String INTERCEPTOR_URL_CLASS = "org.apache.skywalking.apm.plugin.dbcp.v2.PoolingSetUrlSourceInterceptor"; @Override protected ClassMatch enhanceClass() { @@ -48,7 +50,7 @@ public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { @Override public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { - return new InstanceMethodsInterceptPoint[] { + return new InstanceMethodsInterceptPoint[]{ new InstanceMethodsInterceptPoint() { @Override public ElementMatcher getMethodsMatcher() { @@ -60,6 +62,22 @@ public String getMethodsInterceptor() { return CONNECT_GET_INTERCEPTOR; } + @Override + public boolean isOverrideArgs() { + return false; + } + }, + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named("setUrl").and(takesArgument(0, String.class)); + } + + @Override + public String getMethodsInterceptor() { + return INTERCEPTOR_URL_CLASS; + } + @Override public boolean isOverrideArgs() { return false; @@ -72,4 +90,9 @@ public boolean isOverrideArgs() { public StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() { return new StaticMethodsInterceptPoint[0]; } + + @Override + public boolean isBootstrapInstrumentation() { + return true; + } } diff --git a/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/pom.xml index f72907ebe7..647e098c53 100644 --- a/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/pom.xml @@ -38,7 +38,11 @@ ${druid.version} provided + + org.apache.skywalking + apm-jdbc-commons + ${project.version} + provided + - - - \ No newline at end of file + diff --git a/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/PoolingSetUrlSourceInterceptor.java b/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/PoolingSetUrlSourceInterceptor.java new file mode 100644 index 0000000000..9be5d9e64f --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/PoolingSetUrlSourceInterceptor.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.druid.v1; + +import com.alibaba.druid.pool.DruidDataSource; +import org.apache.skywalking.apm.agent.core.logging.api.ILog; +import org.apache.skywalking.apm.agent.core.logging.api.LogManager; +import org.apache.skywalking.apm.agent.core.meter.MeterFactory; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.plugin.jdbc.connectionurl.parser.URLParser; +import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * {@link PoolingSetUrlSourceInterceptor} intercepted the method of Druid set url and register metric monitor. + */ +public class PoolingSetUrlSourceInterceptor implements InstanceMethodsAroundInterceptor { + private static final String METER_NAME = "datasource"; + private static final ILog LOGGER = LogManager.getLogger(PoolingSetUrlSourceInterceptor.class); + + private static final Map>> METRIC_MAP = new HashMap>>(); + + static { + METRIC_MAP.put("activeCount", (DruidDataSource druidDataSource) -> () -> (double) druidDataSource.getActiveCount()); + METRIC_MAP.put("poolingCount", (DruidDataSource druidDataSource) -> () -> (double) druidDataSource.getPoolingCount()); + METRIC_MAP.put("idleCount", (DruidDataSource druidDataSource) -> () -> (double) (druidDataSource.getPoolingCount() - druidDataSource.getActiveCount())); + METRIC_MAP.put("lockQueueLength", (DruidDataSource druidDataSource) -> () -> (double) druidDataSource.getLockQueueLength()); + METRIC_MAP.put("maxWaitThreadCount", (DruidDataSource druidDataSource) -> () -> (double) druidDataSource.getMaxWaitThreadCount()); + METRIC_MAP.put("commitCount", (DruidDataSource druidDataSource) -> () -> (double) druidDataSource.getCommitCount()); + METRIC_MAP.put("connectCount", (DruidDataSource druidDataSource) -> () -> (double) druidDataSource.getConnectCount()); + METRIC_MAP.put("connectError", (DruidDataSource druidDataSource) -> () -> (double) druidDataSource.getConnectErrorCount()); + METRIC_MAP.put("createError", (DruidDataSource druidDataSource) -> () -> (double) druidDataSource.getCreateErrorCount()); + } + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { + if (LOGGER.isInfoEnable()) { + LOGGER.info("metric druid init"); + } + DruidDataSource druidDataSource = (DruidDataSource) objInst; + ConnectionInfo connectionInfo = URLParser.parser((String) allArguments[0]); + String tagValue = connectionInfo.getDatabaseName() + "_" + connectionInfo.getDatabasePeer(); + METRIC_MAP.forEach((key, value) -> MeterFactory.gauge(METER_NAME, value.apply(druidDataSource)) + .tag("name", tagValue).tag("status", key).build()); + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/define/DruidDataSourceInstrumentation.java b/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/define/DruidDataSourceInstrumentation.java index 1a0468576d..b59c9c8aa3 100644 --- a/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/define/DruidDataSourceInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/define/DruidDataSourceInstrumentation.java @@ -25,9 +25,7 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; -import static net.bytebuddy.matcher.ElementMatchers.named; -import static net.bytebuddy.matcher.ElementMatchers.takesArguments; -import static net.bytebuddy.matcher.ElementMatchers.takesNoArguments; +import static net.bytebuddy.matcher.ElementMatchers.*; import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; /** @@ -41,6 +39,7 @@ public class DruidDataSourceInstrumentation extends ClassInstanceMethodsEnhanceP private static final String ENHANCE_CLASS = "com.alibaba.druid.pool.DruidDataSource"; private static final String ENHANCE_METHOD = "getConnection"; private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.druid.v1.PoolingGetConnectInterceptor"; + private static final String INTERCEPTOR_URL_CLASS = "org.apache.skywalking.apm.plugin.druid.v1.PoolingSetUrlSourceInterceptor"; @Override protected ClassMatch enhanceClass() { @@ -82,6 +81,22 @@ public String getMethodsInterceptor() { return INTERCEPTOR_CLASS; } + @Override + public boolean isOverrideArgs() { + return false; + } + }, + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named("setUrl").and(takesArgument(0, String.class)); + } + + @Override + public String getMethodsInterceptor() { + return INTERCEPTOR_URL_CLASS; + } + @Override public boolean isOverrideArgs() { return false; @@ -94,4 +109,10 @@ public boolean isOverrideArgs() { public StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() { return new StaticMethodsInterceptPoint[0]; } + + @Override + public boolean isBootstrapInstrumentation() { + return true; + } + } diff --git a/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/resources/skywalking-plugin.def index b0746b3d81..5c04f0b61b 100644 --- a/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/resources/skywalking-plugin.def +++ b/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/resources/skywalking-plugin.def @@ -15,4 +15,4 @@ # limitations under the License. druid-1.x=org.apache.skywalking.apm.plugin.druid.v1.define.DruidPooledConnectionInstrumentation -druid-1.x=org.apache.skywalking.apm.plugin.druid.v1.define.DruidDataSourceInstrumentation \ No newline at end of file +druid-1.x=org.apache.skywalking.apm.plugin.druid.v1.define.DruidDataSourceInstrumentation diff --git a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/pom.xml index fdf63179b4..7a5a813631 100644 --- a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/pom.xml @@ -39,6 +39,12 @@ ${hikaricp.version} provided + + org.apache.skywalking + apm-jdbc-commons + ${project.version} + provided + - \ No newline at end of file + diff --git a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/HikariDataSourceConstructorInterceptor.java b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/HikariDataSourceConstructorInterceptor.java new file mode 100644 index 0000000000..cbdba8317c --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/HikariDataSourceConstructorInterceptor.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.hikaricp; + +import com.google.common.collect.ImmutableMap; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariPoolMXBean; +import org.apache.skywalking.apm.agent.core.logging.api.ILog; +import org.apache.skywalking.apm.agent.core.logging.api.LogManager; +import org.apache.skywalking.apm.agent.core.meter.MeterFactory; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor; +import org.apache.skywalking.apm.plugin.jdbc.connectionurl.parser.URLParser; +import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; + +import java.util.Map; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * {@link HikariDataSourceConstructorInterceptor} intercepted the method of HikariData construct. + */ +public class HikariDataSourceConstructorInterceptor implements InstanceConstructorInterceptor { + private static final String METER_NAME = "datasource"; + private static final ILog LOGGER = LogManager.getLogger(HikariDataSourceConstructorInterceptor.class); + + private static final Map>> METRIC_MAP = ImmutableMap.of( + "activeConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getActiveConnections(), + "totalConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getTotalConnections(), + "idleConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) (hikariPoolMXBean.getIdleConnections()), + "threadsAwaitingConnection", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getThreadsAwaitingConnection()); + + @Override + public void onConstruct(EnhancedInstance objInst, Object[] allArguments) throws Throwable { + if (LOGGER.isInfoEnable()) { + LOGGER.debug("metric hikari init"); + } + HikariPoolMXBean hikariDataSource = (HikariPoolMXBean) objInst; + HikariConfig hikariConfig = (HikariConfig) allArguments[0]; + ConnectionInfo connectionInfo = URLParser.parser(hikariConfig.getJdbcUrl()); + String tagValue = connectionInfo.getDatabaseName() + "_" + connectionInfo.getDatabasePeer(); + METRIC_MAP.forEach((key, value) -> MeterFactory.gauge(METER_NAME, value.apply(hikariDataSource)) + .tag("name", tagValue).tag("status", key).build()); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/define/HikariPoolInstrumentation.java b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/define/HikariPoolInstrumentation.java new file mode 100644 index 0000000000..a1c44222bd --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/define/HikariPoolInstrumentation.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.hikaricp.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; + +import static net.bytebuddy.matcher.ElementMatchers.any; +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +/** + * {@link HikariPoolInstrumentation} presents that skywalking intercepts {@link + * * com.zaxxer.hikari.pool.HikariPool}. + */ +public class HikariPoolInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + private static final String ENHANCE_CLASS = "com.zaxxer.hikari.pool.HikariPool"; + private static final String INTERCEPTOR_CONSTRUCTOR = "org.apache.skywalking.apm.plugin.hikaricp.HikariDataSourceConstructorInterceptor"; + + @Override + protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); + } + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[]{ + new ConstructorInterceptPoint() { + + @Override + public ElementMatcher getConstructorMatcher() { + return any(); + } + + @Override + public String getConstructorInterceptor() { + return INTERCEPTOR_CONSTRUCTOR; + } + } + }; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[0]; + } + + @Override + public StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() { + return new StaticMethodsInterceptPoint[0]; + } + @Override + public boolean isBootstrapInstrumentation() { + return true; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/resources/skywalking-plugin.def index 80d38e88c5..044b0c1e09 100644 --- a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/resources/skywalking-plugin.def +++ b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/resources/skywalking-plugin.def @@ -15,4 +15,5 @@ # limitations under the License. hikaricp-3.x/4.x=org.apache.skywalking.apm.plugin.hikaricp.define.HikariProxyConnectionInstrumentation -hikaricp-3.x/4.x=org.apache.skywalking.apm.plugin.hikaricp.define.HikariDataSourceInstrumentation \ No newline at end of file +hikaricp-3.x/4.x=org.apache.skywalking.apm.plugin.hikaricp.define.HikariDataSourceInstrumentation +hikaricp-3.x/4.x=org.apache.skywalking.apm.plugin.hikaricp.define.HikariPoolInstrumentation From 6ca6867f91be409500df78e727b19e9901bd9421 Mon Sep 17 00:00:00 2001 From: xiaojianjun Date: Fri, 28 Jan 2022 15:18:56 +0800 Subject: [PATCH 04/16] modify format#8450 --- .../dbcp/v2/PoolingSetUrlSourceInterceptor.java | 2 -- .../v2/define/BasicDataSourceInstrumentation.java | 3 ++- .../v1/define/DruidDataSourceInstrumentation.java | 5 ++++- .../HikariDataSourceConstructorInterceptor.java | 14 ++++++++------ .../hikaricp/define/HikariPoolInstrumentation.java | 7 ++----- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlSourceInterceptor.java b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlSourceInterceptor.java index c5bd912af5..4a21b85f61 100644 --- a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlSourceInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlSourceInterceptor.java @@ -39,7 +39,6 @@ public class PoolingSetUrlSourceInterceptor implements InstanceMethodsAroundInterceptor { private static final String METER_NAME = "datasource"; private static final ILog LOGGER = LogManager.getLogger(PoolingSetUrlSourceInterceptor.class); - private static final Map>> METRIC_MAP = new HashMap>>(); static { @@ -52,7 +51,6 @@ public class PoolingSetUrlSourceInterceptor implements InstanceMethodsAroundInte METRIC_MAP.put("initialSize", (BasicDataSource basicDataSource) -> () -> (double) basicDataSource.getInitialSize()); } - @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { diff --git a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/define/BasicDataSourceInstrumentation.java b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/define/BasicDataSourceInstrumentation.java index f99f39d74c..27c48cf9d8 100755 --- a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/define/BasicDataSourceInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/define/BasicDataSourceInstrumentation.java @@ -25,7 +25,8 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; -import static net.bytebuddy.matcher.ElementMatchers.*; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; /** diff --git a/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/define/DruidDataSourceInstrumentation.java b/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/define/DruidDataSourceInstrumentation.java index b59c9c8aa3..bab5bb168b 100644 --- a/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/define/DruidDataSourceInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/define/DruidDataSourceInstrumentation.java @@ -25,7 +25,10 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; -import static net.bytebuddy.matcher.ElementMatchers.*; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.takesNoArguments; +import static net.bytebuddy.matcher.ElementMatchers.takesArguments; +import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; /** diff --git a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/HikariDataSourceConstructorInterceptor.java b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/HikariDataSourceConstructorInterceptor.java index cbdba8317c..be08768ff8 100644 --- a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/HikariDataSourceConstructorInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/HikariDataSourceConstructorInterceptor.java @@ -17,7 +17,6 @@ package org.apache.skywalking.apm.plugin.hikaricp; -import com.google.common.collect.ImmutableMap; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariPoolMXBean; import org.apache.skywalking.apm.agent.core.logging.api.ILog; @@ -28,6 +27,7 @@ import org.apache.skywalking.apm.plugin.jdbc.connectionurl.parser.URLParser; import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; +import java.util.HashMap; import java.util.Map; import java.util.function.Function; import java.util.function.Supplier; @@ -38,12 +38,14 @@ public class HikariDataSourceConstructorInterceptor implements InstanceConstructorInterceptor { private static final String METER_NAME = "datasource"; private static final ILog LOGGER = LogManager.getLogger(HikariDataSourceConstructorInterceptor.class); + private static final Map>> METRIC_MAP = new HashMap>>(); - private static final Map>> METRIC_MAP = ImmutableMap.of( - "activeConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getActiveConnections(), - "totalConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getTotalConnections(), - "idleConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) (hikariPoolMXBean.getIdleConnections()), - "threadsAwaitingConnection", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getThreadsAwaitingConnection()); + static { + METRIC_MAP.put("activeConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getActiveConnections()); + METRIC_MAP.put("totalConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getTotalConnections()); + METRIC_MAP.put("idleConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) (hikariPoolMXBean.getIdleConnections())); + METRIC_MAP.put("threadsAwaitingConnection", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getThreadsAwaitingConnection()); + } @Override public void onConstruct(EnhancedInstance objInst, Object[] allArguments) throws Throwable { diff --git a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/define/HikariPoolInstrumentation.java b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/define/HikariPoolInstrumentation.java index a1c44222bd..a355984eee 100644 --- a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/define/HikariPoolInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/define/HikariPoolInstrumentation.java @@ -30,7 +30,7 @@ /** * {@link HikariPoolInstrumentation} presents that skywalking intercepts {@link - * * com.zaxxer.hikari.pool.HikariPool}. + * com.zaxxer.hikari.pool.HikariPool}. */ public class HikariPoolInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { private static final String ENHANCE_CLASS = "com.zaxxer.hikari.pool.HikariPool"; @@ -68,8 +68,5 @@ public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { public StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() { return new StaticMethodsInterceptPoint[0]; } - @Override - public boolean isBootstrapInstrumentation() { - return true; - } + } From 5b2f0442fdc2390b7bd73a595c1518fb87dc3467 Mon Sep 17 00:00:00 2001 From: xiaojianjun Date: Fri, 28 Jan 2022 18:09:46 +0800 Subject: [PATCH 05/16] druid metric monitor #8450 --- ...PoolingAddDruidDataSourceInterceptor.java} | 19 +++-- .../DruidDataSourceInstrumentation.java | 23 ------ ...dDataSourceStatManagerInstrumentation.java | 79 +++++++++++++++++++ .../src/main/resources/skywalking-plugin.def | 1 + 4 files changed, 89 insertions(+), 33 deletions(-) rename apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/{PoolingSetUrlSourceInterceptor.java => PoolingAddDruidDataSourceInterceptor.java} (78%) create mode 100644 apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/define/DruidDataSourceStatManagerInstrumentation.java diff --git a/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/PoolingSetUrlSourceInterceptor.java b/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/PoolingAddDruidDataSourceInterceptor.java similarity index 78% rename from apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/PoolingSetUrlSourceInterceptor.java rename to apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/PoolingAddDruidDataSourceInterceptor.java index 9be5d9e64f..b4f3aed66a 100644 --- a/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/PoolingSetUrlSourceInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/PoolingAddDruidDataSourceInterceptor.java @@ -21,9 +21,8 @@ import org.apache.skywalking.apm.agent.core.logging.api.ILog; import org.apache.skywalking.apm.agent.core.logging.api.LogManager; import org.apache.skywalking.apm.agent.core.meter.MeterFactory; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMethodsAroundInterceptor; import org.apache.skywalking.apm.plugin.jdbc.connectionurl.parser.URLParser; import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; @@ -34,11 +33,11 @@ import java.util.function.Supplier; /** - * {@link PoolingSetUrlSourceInterceptor} intercepted the method of Druid set url and register metric monitor. + * {@link PoolingAddDruidDataSourceInterceptor} intercepted the method of druid addDataSource and register metric monitor. */ -public class PoolingSetUrlSourceInterceptor implements InstanceMethodsAroundInterceptor { +public class PoolingAddDruidDataSourceInterceptor implements StaticMethodsAroundInterceptor { private static final String METER_NAME = "datasource"; - private static final ILog LOGGER = LogManager.getLogger(PoolingSetUrlSourceInterceptor.class); + private static final ILog LOGGER = LogManager.getLogger(PoolingAddDruidDataSourceInterceptor.class); private static final Map>> METRIC_MAP = new HashMap>>(); @@ -55,17 +54,17 @@ public class PoolingSetUrlSourceInterceptor implements InstanceMethodsAroundInte } @Override - public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + public void beforeMethod(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, MethodInterceptResult result) { } @Override - public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { + public Object afterMethod(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, Object ret) { if (LOGGER.isInfoEnable()) { LOGGER.info("metric druid init"); } - DruidDataSource druidDataSource = (DruidDataSource) objInst; - ConnectionInfo connectionInfo = URLParser.parser((String) allArguments[0]); + DruidDataSource druidDataSource = (DruidDataSource) allArguments[0]; + ConnectionInfo connectionInfo = URLParser.parser(druidDataSource.getUrl()); String tagValue = connectionInfo.getDatabaseName() + "_" + connectionInfo.getDatabasePeer(); METRIC_MAP.forEach((key, value) -> MeterFactory.gauge(METER_NAME, value.apply(druidDataSource)) .tag("name", tagValue).tag("status", key).build()); @@ -73,7 +72,7 @@ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allA } @Override - public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + public void handleMethodException(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, Throwable t) { } } diff --git a/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/define/DruidDataSourceInstrumentation.java b/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/define/DruidDataSourceInstrumentation.java index bab5bb168b..ba8c3c77ca 100644 --- a/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/define/DruidDataSourceInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/define/DruidDataSourceInstrumentation.java @@ -28,7 +28,6 @@ import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.takesNoArguments; import static net.bytebuddy.matcher.ElementMatchers.takesArguments; -import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; /** @@ -42,7 +41,6 @@ public class DruidDataSourceInstrumentation extends ClassInstanceMethodsEnhanceP private static final String ENHANCE_CLASS = "com.alibaba.druid.pool.DruidDataSource"; private static final String ENHANCE_METHOD = "getConnection"; private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.druid.v1.PoolingGetConnectInterceptor"; - private static final String INTERCEPTOR_URL_CLASS = "org.apache.skywalking.apm.plugin.druid.v1.PoolingSetUrlSourceInterceptor"; @Override protected ClassMatch enhanceClass() { @@ -84,22 +82,6 @@ public String getMethodsInterceptor() { return INTERCEPTOR_CLASS; } - @Override - public boolean isOverrideArgs() { - return false; - } - }, - new InstanceMethodsInterceptPoint() { - @Override - public ElementMatcher getMethodsMatcher() { - return named("setUrl").and(takesArgument(0, String.class)); - } - - @Override - public String getMethodsInterceptor() { - return INTERCEPTOR_URL_CLASS; - } - @Override public boolean isOverrideArgs() { return false; @@ -113,9 +95,4 @@ public StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() { return new StaticMethodsInterceptPoint[0]; } - @Override - public boolean isBootstrapInstrumentation() { - return true; - } - } diff --git a/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/define/DruidDataSourceStatManagerInstrumentation.java b/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/define/DruidDataSourceStatManagerInstrumentation.java new file mode 100644 index 0000000000..e383389c66 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/define/DruidDataSourceStatManagerInstrumentation.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.druid.v1.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassStaticMethodsEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; + +import static net.bytebuddy.matcher.ElementMatchers.takesArguments; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +/** + * Druid is a database connection pool from Alibaba inc. + *

+ * DruidDataSource provides a "one stop" solution for database connection pool solution + * basic requirements. DruidDataSourceStatManager.addDataSource(Object dataSource, String name) + */ +public class DruidDataSourceStatManagerInstrumentation extends ClassStaticMethodsEnhancePluginDefine { + private static final String ENHANCE_CLASS = "com.alibaba.druid.stat.DruidDataSourceStatManager"; + private static final String ENHANCE_METHOD = "addDataSource"; + private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.druid.v1.PoolingAddDruidDataSourceInterceptor"; + + @Override + protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); + } + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[0]; + } + + @Override + public StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() { + return new StaticMethodsInterceptPoint[]{ + new StaticMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named(ENHANCE_METHOD).and(takesArguments(Object.class, String.class)); + } + + @Override + public String getMethodsInterceptor() { + return INTERCEPTOR_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/resources/skywalking-plugin.def index 5c04f0b61b..95ed76e17b 100644 --- a/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/resources/skywalking-plugin.def +++ b/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/resources/skywalking-plugin.def @@ -16,3 +16,4 @@ druid-1.x=org.apache.skywalking.apm.plugin.druid.v1.define.DruidPooledConnectionInstrumentation druid-1.x=org.apache.skywalking.apm.plugin.druid.v1.define.DruidDataSourceInstrumentation +druid-1.x=org.apache.skywalking.apm.plugin.druid.v1.define.DruidDataSourceStatManagerInstrumentation From 6ab8cf77fdc09b34cb5ddb7cabfe41fb631d2c28 Mon Sep 17 00:00:00 2001 From: xiaojianjun Date: Mon, 7 Feb 2022 15:05:10 +0800 Subject: [PATCH 06/16] add support config params collect #96 --- ...ikariDataSourceConstructorInterceptor.java | 62 ------------- .../hikaricp/PoolingSealInterceptor.java | 86 +++++++++++++++++++ .../HikariDataSourceInstrumentation.java | 17 ++++ .../define/HikariPoolInstrumentation.java | 72 ---------------- .../src/main/resources/skywalking-plugin.def | 1 - 5 files changed, 103 insertions(+), 135 deletions(-) delete mode 100644 apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/HikariDataSourceConstructorInterceptor.java create mode 100644 apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/PoolingSealInterceptor.java delete mode 100644 apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/define/HikariPoolInstrumentation.java diff --git a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/HikariDataSourceConstructorInterceptor.java b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/HikariDataSourceConstructorInterceptor.java deleted file mode 100644 index be08768ff8..0000000000 --- a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/HikariDataSourceConstructorInterceptor.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.hikaricp; - -import com.zaxxer.hikari.HikariConfig; -import com.zaxxer.hikari.HikariPoolMXBean; -import org.apache.skywalking.apm.agent.core.logging.api.ILog; -import org.apache.skywalking.apm.agent.core.logging.api.LogManager; -import org.apache.skywalking.apm.agent.core.meter.MeterFactory; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor; -import org.apache.skywalking.apm.plugin.jdbc.connectionurl.parser.URLParser; -import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; - -import java.util.HashMap; -import java.util.Map; -import java.util.function.Function; -import java.util.function.Supplier; - -/** - * {@link HikariDataSourceConstructorInterceptor} intercepted the method of HikariData construct. - */ -public class HikariDataSourceConstructorInterceptor implements InstanceConstructorInterceptor { - private static final String METER_NAME = "datasource"; - private static final ILog LOGGER = LogManager.getLogger(HikariDataSourceConstructorInterceptor.class); - private static final Map>> METRIC_MAP = new HashMap>>(); - - static { - METRIC_MAP.put("activeConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getActiveConnections()); - METRIC_MAP.put("totalConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getTotalConnections()); - METRIC_MAP.put("idleConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) (hikariPoolMXBean.getIdleConnections())); - METRIC_MAP.put("threadsAwaitingConnection", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getThreadsAwaitingConnection()); - } - - @Override - public void onConstruct(EnhancedInstance objInst, Object[] allArguments) throws Throwable { - if (LOGGER.isInfoEnable()) { - LOGGER.debug("metric hikari init"); - } - HikariPoolMXBean hikariDataSource = (HikariPoolMXBean) objInst; - HikariConfig hikariConfig = (HikariConfig) allArguments[0]; - ConnectionInfo connectionInfo = URLParser.parser(hikariConfig.getJdbcUrl()); - String tagValue = connectionInfo.getDatabaseName() + "_" + connectionInfo.getDatabasePeer(); - METRIC_MAP.forEach((key, value) -> MeterFactory.gauge(METER_NAME, value.apply(hikariDataSource)) - .tag("name", tagValue).tag("status", key).build()); - } -} diff --git a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/PoolingSealInterceptor.java b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/PoolingSealInterceptor.java new file mode 100644 index 0000000000..a41735d693 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/PoolingSealInterceptor.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.hikaricp; + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import com.zaxxer.hikari.HikariPoolMXBean; +import org.apache.skywalking.apm.agent.core.logging.api.ILog; +import org.apache.skywalking.apm.agent.core.logging.api.LogManager; +import org.apache.skywalking.apm.agent.core.meter.MeterFactory; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.plugin.jdbc.connectionurl.parser.URLParser; +import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * {@link PoolingSealInterceptor} intercepted the method of HikariCP getting connection. + */ +public class PoolingSealInterceptor implements InstanceMethodsAroundInterceptor { + + private static final ILog LOGGER = LogManager.getLogger(PoolingSealInterceptor.class); + private static final String METER_NAME = "datasource"; + private static final Map>> METRIC_CONFIG_MAP = new HashMap>>(); + private static final Map>> METRIC_MAP = new HashMap>>(); + + static { + METRIC_CONFIG_MAP.put("activeConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getActiveConnections()); + METRIC_CONFIG_MAP.put("totalConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getTotalConnections()); + METRIC_CONFIG_MAP.put("idleConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getIdleConnections()); + METRIC_CONFIG_MAP.put("threadsAwaitingConnection", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getThreadsAwaitingConnection()); + METRIC_MAP.put("connectionTimeout", (HikariConfig hikariConfig) -> () -> (double) hikariConfig.getConnectionTimeout()); + METRIC_MAP.put("validationTimeout", (HikariConfig hikariConfig) -> () -> (double) hikariConfig.getValidationTimeout()); + METRIC_MAP.put("idleTimeout", (HikariConfig hikariConfig) -> () -> (double) hikariConfig.getIdleTimeout()); + METRIC_MAP.put("leakDetectionThreshold", (HikariConfig hikariConfig) -> () -> (double) hikariConfig.getLeakDetectionThreshold()); + METRIC_MAP.put("minimumIdle", (HikariConfig hikariConfig) -> () -> (double) hikariConfig.getMinimumIdle()); + METRIC_MAP.put("maximumPoolSize", (HikariConfig hikariConfig) -> () -> (double) hikariConfig.getMaximumPoolSize()); + } + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { + if (LOGGER.isInfoEnable()) { + LOGGER.info("metric hikari init"); + } + + HikariDataSource hikariDataSource = (HikariDataSource) objInst; + ConnectionInfo connectionInfo = URLParser.parser(hikariDataSource.getJdbcUrl()); + String tagValue = connectionInfo.getDatabaseName() + "_" + connectionInfo.getDatabasePeer(); + METRIC_CONFIG_MAP.forEach((key, value) -> MeterFactory.gauge(METER_NAME, value.apply(hikariDataSource.getHikariPoolMXBean())) + .tag("name", tagValue).tag("status", key).build()); + METRIC_MAP.forEach((key, value) -> MeterFactory.gauge(METER_NAME, value.apply(hikariDataSource)) + .tag("name", tagValue).tag("status", key).build()); + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/define/HikariDataSourceInstrumentation.java b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/define/HikariDataSourceInstrumentation.java index 6273cfd308..9cc51116ed 100644 --- a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/define/HikariDataSourceInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/define/HikariDataSourceInstrumentation.java @@ -41,6 +41,7 @@ public class HikariDataSourceInstrumentation extends ClassInstanceMethodsEnhance private static final String ENHANCE_CLASS = "com.zaxxer.hikari.HikariDataSource"; private static final String ENHANCE_METHOD = "getConnection"; private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.hikaricp.PoolingGetConnectInterceptor"; + private static final String SEAL_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.hikaricp.PoolingSealInterceptor"; @Override protected ClassMatch enhanceClass() { @@ -82,6 +83,22 @@ public String getMethodsInterceptor() { return INTERCEPTOR_CLASS; } + @Override + public boolean isOverrideArgs() { + return false; + } + }, + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named("seal"); + } + + @Override + public String getMethodsInterceptor() { + return SEAL_INTERCEPTOR_CLASS; + } + @Override public boolean isOverrideArgs() { return false; diff --git a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/define/HikariPoolInstrumentation.java b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/define/HikariPoolInstrumentation.java deleted file mode 100644 index a355984eee..0000000000 --- a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/define/HikariPoolInstrumentation.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.hikaricp.define; - -import net.bytebuddy.description.method.MethodDescription; -import net.bytebuddy.matcher.ElementMatcher; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; -import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; - -import static net.bytebuddy.matcher.ElementMatchers.any; -import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; - -/** - * {@link HikariPoolInstrumentation} presents that skywalking intercepts {@link - * com.zaxxer.hikari.pool.HikariPool}. - */ -public class HikariPoolInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { - private static final String ENHANCE_CLASS = "com.zaxxer.hikari.pool.HikariPool"; - private static final String INTERCEPTOR_CONSTRUCTOR = "org.apache.skywalking.apm.plugin.hikaricp.HikariDataSourceConstructorInterceptor"; - - @Override - protected ClassMatch enhanceClass() { - return byName(ENHANCE_CLASS); - } - - @Override - public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { - return new ConstructorInterceptPoint[]{ - new ConstructorInterceptPoint() { - - @Override - public ElementMatcher getConstructorMatcher() { - return any(); - } - - @Override - public String getConstructorInterceptor() { - return INTERCEPTOR_CONSTRUCTOR; - } - } - }; - } - - @Override - public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { - return new InstanceMethodsInterceptPoint[0]; - } - - @Override - public StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() { - return new StaticMethodsInterceptPoint[0]; - } - -} diff --git a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/resources/skywalking-plugin.def index 044b0c1e09..1741344aaa 100644 --- a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/resources/skywalking-plugin.def +++ b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/resources/skywalking-plugin.def @@ -16,4 +16,3 @@ hikaricp-3.x/4.x=org.apache.skywalking.apm.plugin.hikaricp.define.HikariProxyConnectionInstrumentation hikaricp-3.x/4.x=org.apache.skywalking.apm.plugin.hikaricp.define.HikariDataSourceInstrumentation -hikaricp-3.x/4.x=org.apache.skywalking.apm.plugin.hikaricp.define.HikariPoolInstrumentation From a2f3d9c64c20f1516a7e29783378347d7a0f88ca Mon Sep 17 00:00:00 2001 From: xiaojianjun Date: Wed, 9 Feb 2022 03:15:30 +0800 Subject: [PATCH 07/16] static field static field Enhanced class changed to interface,add test #96 --- CHANGES.md | 3 + .../apm-sdk-plugin/dbcp-2.x-plugin/pom.xml | 2 - ...tor.java => PoolingSetUrlInterceptor.java} | 26 +-- .../BasicDataSourceInstrumentation.java | 10 +- .../PoolingAddDruidDataSourceInterceptor.java | 24 +-- .../hikaricp-3.x-4.x-plugin/pom.xml | 1 - .../hikaricp/PoolingSealInterceptor.java | 16 +- test/plugin/pom.xml | 3 + .../config/expectedData.yaml | 158 +++++++++++++++++- .../config/expectedData.yaml | 47 ++++++ .../config/expectedData.yaml | 58 +++++++ .../config/expectedData.yaml | 64 +++++++ 12 files changed, 367 insertions(+), 45 deletions(-) rename apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/{PoolingSetUrlSourceInterceptor.java => PoolingSetUrlInterceptor.java} (66%) diff --git a/CHANGES.md b/CHANGES.md index 570b63d9cc..f53c502a84 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,9 @@ Release Notes. ------------------ * Support Undertow thread pool metrics collecting. * Support Tomcat thread pool metric collect. +* Support Druid Connection pool metrics collecting. +* Support HikariCP Connection pool metrics collecting. +* Support Dbcp2 Connection pool metrics collecting. #### Documentation diff --git a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/pom.xml index 121a7c1e78..1c86da838f 100644 --- a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/pom.xml @@ -45,6 +45,4 @@ provided - - diff --git a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlSourceInterceptor.java b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java similarity index 66% rename from apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlSourceInterceptor.java rename to apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java index 4a21b85f61..7f01c68d3b 100644 --- a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlSourceInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java @@ -17,7 +17,7 @@ package org.apache.skywalking.apm.plugin.dbcp.v2; -import org.apache.commons.dbcp2.BasicDataSource; +import org.apache.commons.dbcp2.BasicDataSourceMXBean; import org.apache.skywalking.apm.agent.core.logging.api.ILog; import org.apache.skywalking.apm.agent.core.logging.api.LogManager; import org.apache.skywalking.apm.agent.core.meter.MeterFactory; @@ -34,21 +34,21 @@ import java.util.function.Supplier; /** - * {@link PoolingSetUrlSourceInterceptor} intercepted the method of DBCP set url and register metric monitor. + * {@link PoolingSetUrlInterceptor} intercepted the method of DBCP set url and register metric monitor. */ -public class PoolingSetUrlSourceInterceptor implements InstanceMethodsAroundInterceptor { +public class PoolingSetUrlInterceptor implements InstanceMethodsAroundInterceptor { private static final String METER_NAME = "datasource"; - private static final ILog LOGGER = LogManager.getLogger(PoolingSetUrlSourceInterceptor.class); - private static final Map>> METRIC_MAP = new HashMap>>(); + private static final ILog LOGGER = LogManager.getLogger(PoolingSetUrlInterceptor.class); + private static final Map>> METRIC_MAP = new HashMap>>(); static { - METRIC_MAP.put("numActive", (BasicDataSource basicDataSource) -> () -> (double) basicDataSource.getNumActive()); - METRIC_MAP.put("maxTotal", (BasicDataSource basicDataSource) -> () -> (double) basicDataSource.getMaxTotal()); - METRIC_MAP.put("numIdle", (BasicDataSource basicDataSource) -> () -> (double) (basicDataSource.getNumIdle())); - METRIC_MAP.put("maxWaitMillis", (BasicDataSource basicDataSource) -> () -> (double) basicDataSource.getMaxWaitMillis()); - METRIC_MAP.put("maxIdle", (BasicDataSource basicDataSource) -> () -> (double) basicDataSource.getMaxIdle()); - METRIC_MAP.put("minIdle", (BasicDataSource basicDataSource) -> () -> (double) basicDataSource.getMinIdle()); - METRIC_MAP.put("initialSize", (BasicDataSource basicDataSource) -> () -> (double) basicDataSource.getInitialSize()); + METRIC_MAP.put("numActive", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getNumActive()); + METRIC_MAP.put("maxTotal", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getMaxTotal()); + METRIC_MAP.put("numIdle", (BasicDataSourceMXBean basicDataSource) -> () -> (double) (basicDataSource.getNumIdle())); + METRIC_MAP.put("maxWaitMillis", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getMaxWaitMillis()); + METRIC_MAP.put("maxIdle", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getMaxIdle()); + METRIC_MAP.put("minIdle", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getMinIdle()); + METRIC_MAP.put("initialSize", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getInitialSize()); } @Override @@ -61,7 +61,7 @@ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allA if (LOGGER.isInfoEnable()) { LOGGER.info("metric dbcp init"); } - BasicDataSource basicDataSource = (BasicDataSource) objInst; + BasicDataSourceMXBean basicDataSource = (BasicDataSourceMXBean) objInst; ConnectionInfo connectionInfo = URLParser.parser((String) allArguments[0]); String tagValue = connectionInfo.getDatabaseName() + "_" + connectionInfo.getDatabasePeer(); METRIC_MAP.forEach((key, value) -> MeterFactory.gauge(METER_NAME, value.apply(basicDataSource)) diff --git a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/define/BasicDataSourceInstrumentation.java b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/define/BasicDataSourceInstrumentation.java index 27c48cf9d8..22ddca121e 100755 --- a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/define/BasicDataSourceInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/define/BasicDataSourceInstrumentation.java @@ -26,7 +26,6 @@ import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; import static net.bytebuddy.matcher.ElementMatchers.named; -import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; /** @@ -37,7 +36,7 @@ public class BasicDataSourceInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { private static final String ENHANCE_CLASS = "org.apache.commons.dbcp2.BasicDataSource"; private static final String CONNECT_GET_INTERCEPTOR = "org.apache.skywalking.apm.plugin.dbcp.v2.PoolingGetConnectInterceptor"; - private static final String INTERCEPTOR_URL_CLASS = "org.apache.skywalking.apm.plugin.dbcp.v2.PoolingSetUrlSourceInterceptor"; + private static final String INTERCEPTOR_URL_CLASS = "org.apache.skywalking.apm.plugin.dbcp.v2.PoolingSetUrlInterceptor"; @Override protected ClassMatch enhanceClass() { @@ -71,7 +70,7 @@ public boolean isOverrideArgs() { new InstanceMethodsInterceptPoint() { @Override public ElementMatcher getMethodsMatcher() { - return named("setUrl").and(takesArgument(0, String.class)); + return named("setUrl"); } @Override @@ -91,9 +90,4 @@ public boolean isOverrideArgs() { public StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() { return new StaticMethodsInterceptPoint[0]; } - - @Override - public boolean isBootstrapInstrumentation() { - return true; - } } diff --git a/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/PoolingAddDruidDataSourceInterceptor.java b/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/PoolingAddDruidDataSourceInterceptor.java index b4f3aed66a..acffcc8999 100644 --- a/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/PoolingAddDruidDataSourceInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/PoolingAddDruidDataSourceInterceptor.java @@ -17,7 +17,7 @@ package org.apache.skywalking.apm.plugin.druid.v1; -import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.pool.DruidDataSourceMBean; import org.apache.skywalking.apm.agent.core.logging.api.ILog; import org.apache.skywalking.apm.agent.core.logging.api.LogManager; import org.apache.skywalking.apm.agent.core.meter.MeterFactory; @@ -39,18 +39,18 @@ public class PoolingAddDruidDataSourceInterceptor implements StaticMethodsAround private static final String METER_NAME = "datasource"; private static final ILog LOGGER = LogManager.getLogger(PoolingAddDruidDataSourceInterceptor.class); - private static final Map>> METRIC_MAP = new HashMap>>(); + private static final Map>> METRIC_MAP = new HashMap>>(); static { - METRIC_MAP.put("activeCount", (DruidDataSource druidDataSource) -> () -> (double) druidDataSource.getActiveCount()); - METRIC_MAP.put("poolingCount", (DruidDataSource druidDataSource) -> () -> (double) druidDataSource.getPoolingCount()); - METRIC_MAP.put("idleCount", (DruidDataSource druidDataSource) -> () -> (double) (druidDataSource.getPoolingCount() - druidDataSource.getActiveCount())); - METRIC_MAP.put("lockQueueLength", (DruidDataSource druidDataSource) -> () -> (double) druidDataSource.getLockQueueLength()); - METRIC_MAP.put("maxWaitThreadCount", (DruidDataSource druidDataSource) -> () -> (double) druidDataSource.getMaxWaitThreadCount()); - METRIC_MAP.put("commitCount", (DruidDataSource druidDataSource) -> () -> (double) druidDataSource.getCommitCount()); - METRIC_MAP.put("connectCount", (DruidDataSource druidDataSource) -> () -> (double) druidDataSource.getConnectCount()); - METRIC_MAP.put("connectError", (DruidDataSource druidDataSource) -> () -> (double) druidDataSource.getConnectErrorCount()); - METRIC_MAP.put("createError", (DruidDataSource druidDataSource) -> () -> (double) druidDataSource.getCreateErrorCount()); + METRIC_MAP.put("activeCount", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getActiveCount()); + METRIC_MAP.put("poolingCount", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getPoolingCount()); + METRIC_MAP.put("idleCount", (DruidDataSourceMBean druidDataSource) -> () -> (double) (druidDataSource.getPoolingCount() - druidDataSource.getActiveCount())); + METRIC_MAP.put("lockQueueLength", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getLockQueueLength()); + METRIC_MAP.put("maxWaitThreadCount", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getMaxWaitThreadCount()); + METRIC_MAP.put("commitCount", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getCommitCount()); + METRIC_MAP.put("connectCount", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getConnectCount()); + METRIC_MAP.put("connectError", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getConnectErrorCount()); + METRIC_MAP.put("createError", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getCreateErrorCount()); } @Override @@ -63,7 +63,7 @@ public Object afterMethod(Class clazz, Method method, Object[] allArguments, Cla if (LOGGER.isInfoEnable()) { LOGGER.info("metric druid init"); } - DruidDataSource druidDataSource = (DruidDataSource) allArguments[0]; + DruidDataSourceMBean druidDataSource = (DruidDataSourceMBean) allArguments[0]; ConnectionInfo connectionInfo = URLParser.parser(druidDataSource.getUrl()); String tagValue = connectionInfo.getDatabaseName() + "_" + connectionInfo.getDatabasePeer(); METRIC_MAP.forEach((key, value) -> MeterFactory.gauge(METER_NAME, value.apply(druidDataSource)) diff --git a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/pom.xml index cb9a856461..cc403a9c3f 100644 --- a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/pom.xml @@ -46,5 +46,4 @@ provided - diff --git a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/PoolingSealInterceptor.java b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/PoolingSealInterceptor.java index a41735d693..45d676862b 100644 --- a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/PoolingSealInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/PoolingSealInterceptor.java @@ -17,7 +17,7 @@ package org.apache.skywalking.apm.plugin.hikaricp; -import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariConfigMXBean; import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.HikariPoolMXBean; import org.apache.skywalking.apm.agent.core.logging.api.ILog; @@ -43,19 +43,19 @@ public class PoolingSealInterceptor implements InstanceMethodsAroundInterceptor private static final ILog LOGGER = LogManager.getLogger(PoolingSealInterceptor.class); private static final String METER_NAME = "datasource"; private static final Map>> METRIC_CONFIG_MAP = new HashMap>>(); - private static final Map>> METRIC_MAP = new HashMap>>(); + private static final Map>> METRIC_MAP = new HashMap>>(); static { METRIC_CONFIG_MAP.put("activeConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getActiveConnections()); METRIC_CONFIG_MAP.put("totalConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getTotalConnections()); METRIC_CONFIG_MAP.put("idleConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getIdleConnections()); METRIC_CONFIG_MAP.put("threadsAwaitingConnection", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getThreadsAwaitingConnection()); - METRIC_MAP.put("connectionTimeout", (HikariConfig hikariConfig) -> () -> (double) hikariConfig.getConnectionTimeout()); - METRIC_MAP.put("validationTimeout", (HikariConfig hikariConfig) -> () -> (double) hikariConfig.getValidationTimeout()); - METRIC_MAP.put("idleTimeout", (HikariConfig hikariConfig) -> () -> (double) hikariConfig.getIdleTimeout()); - METRIC_MAP.put("leakDetectionThreshold", (HikariConfig hikariConfig) -> () -> (double) hikariConfig.getLeakDetectionThreshold()); - METRIC_MAP.put("minimumIdle", (HikariConfig hikariConfig) -> () -> (double) hikariConfig.getMinimumIdle()); - METRIC_MAP.put("maximumPoolSize", (HikariConfig hikariConfig) -> () -> (double) hikariConfig.getMaximumPoolSize()); + METRIC_MAP.put("connectionTimeout", (HikariConfigMXBean hikariConfigMXBean) -> () -> (double) hikariConfigMXBean.getConnectionTimeout()); + METRIC_MAP.put("validationTimeout", (HikariConfigMXBean hikariConfigMXBean) -> () -> (double) hikariConfigMXBean.getValidationTimeout()); + METRIC_MAP.put("idleTimeout", (HikariConfigMXBean hikariConfigMXBean) -> () -> (double) hikariConfigMXBean.getIdleTimeout()); + METRIC_MAP.put("leakDetectionThreshold", (HikariConfigMXBean hikariConfigMXBean) -> () -> (double) hikariConfigMXBean.getLeakDetectionThreshold()); + METRIC_MAP.put("minimumIdle", (HikariConfigMXBean hikariConfigMXBean) -> () -> (double) hikariConfigMXBean.getMinimumIdle()); + METRIC_MAP.put("maximumPoolSize", (HikariConfigMXBean hikariConfigMXBean) -> () -> (double) hikariConfigMXBean.getMaximumPoolSize()); } @Override diff --git a/test/plugin/pom.xml b/test/plugin/pom.xml index d4811bf950..b9df3c6bfa 100644 --- a/test/plugin/pom.xml +++ b/test/plugin/pom.xml @@ -131,6 +131,9 @@ ${project.build.sourceDirectory} ${project.build.testSourceDirectory} +scenarios/dbcp-2.x-scenario +scenarios/druid-1.x-scenario +scenarios/druid-1.x **/*.properties, diff --git a/test/plugin/scenarios/apm-toolkit-trace-scenario/config/expectedData.yaml b/test/plugin/scenarios/apm-toolkit-trace-scenario/config/expectedData.yaml index 436ddf17e5..1fe73f06ab 100644 --- a/test/plugin/scenarios/apm-toolkit-trace-scenario/config/expectedData.yaml +++ b/test/plugin/scenarios/apm-toolkit-trace-scenario/config/expectedData.yaml @@ -481,7 +481,7 @@ segmentItems: skipAnalysis: 'true' meterItems: - serviceName: apm-toolkit-trace-scenario - meterSize: 8 + meterSize: 34 meters: - meterId: name: test_counter @@ -532,3 +532,159 @@ meterItems: - {name: metric_type, value: queue_size} - {name: pool_name, value: tomcat_execute_pool} singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: numActive} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: maxTotal} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: numIdle} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: maxWaitMillis} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: maxIdle} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: minIdle} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: initialSize} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: activeCount} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: poolingCount} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: idleCount} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: lockQueueLength} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: maxWaitThreadCount} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: commitCount} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: connectCount} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: connectError} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: createError} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: activeConnections} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: totalConnections} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: idleConnections} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: threadsAwaitingConnection} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: connectionTimeout} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: validationTimeout} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: idleTimeout} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: leakDetectionThreshold} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: minimumIdle} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: maximumPoolSize} + singleValue: ge 0 diff --git a/test/plugin/scenarios/dbcp-2.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/dbcp-2.x-scenario/config/expectedData.yaml index 2971dbdc03..5f4c78245d 100755 --- a/test/plugin/scenarios/dbcp-2.x-scenario/config/expectedData.yaml +++ b/test/plugin/scenarios/dbcp-2.x-scenario/config/expectedData.yaml @@ -221,3 +221,50 @@ segmentItems: tags: - {key: url, value: 'http://localhost:8080/dbcp-2.x-scenario/case/dbcp-2.x-scenario'} - {key: http.method, value: GET} + +meterItems: + - serviceName: dbcp-2.x-scenario + meterSize: 7 + meters: + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: numActive} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: maxTotal} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: numIdle} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: maxWaitMillis} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: maxIdle} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: minIdle} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: initialSize} + singleValue: ge 0 diff --git a/test/plugin/scenarios/druid-1.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/druid-1.x-scenario/config/expectedData.yaml index 68c84a560b..5c315382c1 100644 --- a/test/plugin/scenarios/druid-1.x-scenario/config/expectedData.yaml +++ b/test/plugin/scenarios/druid-1.x-scenario/config/expectedData.yaml @@ -203,3 +203,61 @@ segmentItems: tags: - {key: url, value: 'http://localhost:8080/druid-1.x-scenario/case/druid-1.x-scenario'} - {key: http.method, value: GET} +meterItems: + - serviceName: druid-1.x-scenario + meterSize: 9 + meters: + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: activeCount} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: poolingCount} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: idleCount} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: lockQueueLength} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: maxWaitThreadCount} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: commitCount} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: connectCount} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: connectError} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: createError} + singleValue: ge 0 diff --git a/test/plugin/scenarios/hikaricp-scenario/config/expectedData.yaml b/test/plugin/scenarios/hikaricp-scenario/config/expectedData.yaml index 678d32a63d..2ef8a36516 100644 --- a/test/plugin/scenarios/hikaricp-scenario/config/expectedData.yaml +++ b/test/plugin/scenarios/hikaricp-scenario/config/expectedData.yaml @@ -203,3 +203,67 @@ segmentItems: tags: - {key: url, value: 'http://localhost:8080/hikaricp-scenario/case/hikaricp-scenario'} - {key: http.method, value: GET} +meterItems: + - serviceName: hikaricp-scenario + meterSize: 10 + meters: + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: activeConnections} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: totalConnections} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: idleConnections} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: threadsAwaitingConnection} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: connectionTimeout} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: validationTimeout} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: idleTimeout} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: leakDetectionThreshold} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: minimumIdle} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: maximumPoolSize} + singleValue: ge 0 From c6adcf8ba55c3e05ce8f526dfc3d92c520bdf400 Mon Sep 17 00:00:00 2001 From: xiaojianjun Date: Wed, 9 Feb 2022 11:48:12 +0800 Subject: [PATCH 08/16] remove static field and log #96 --- .../dbcp/v2/PoolingSetUrlInterceptor.java | 32 ++++++-------- .../PoolingAddDruidDataSourceInterceptor.java | 36 +++++++--------- .../hikaricp/PoolingSealInterceptor.java | 42 +++++++++---------- 3 files changed, 47 insertions(+), 63 deletions(-) diff --git a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java index 7f01c68d3b..b4f636603e 100644 --- a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java @@ -18,8 +18,6 @@ package org.apache.skywalking.apm.plugin.dbcp.v2; import org.apache.commons.dbcp2.BasicDataSourceMXBean; -import org.apache.skywalking.apm.agent.core.logging.api.ILog; -import org.apache.skywalking.apm.agent.core.logging.api.LogManager; import org.apache.skywalking.apm.agent.core.meter.MeterFactory; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; @@ -38,19 +36,6 @@ */ public class PoolingSetUrlInterceptor implements InstanceMethodsAroundInterceptor { private static final String METER_NAME = "datasource"; - private static final ILog LOGGER = LogManager.getLogger(PoolingSetUrlInterceptor.class); - private static final Map>> METRIC_MAP = new HashMap>>(); - - static { - METRIC_MAP.put("numActive", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getNumActive()); - METRIC_MAP.put("maxTotal", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getMaxTotal()); - METRIC_MAP.put("numIdle", (BasicDataSourceMXBean basicDataSource) -> () -> (double) (basicDataSource.getNumIdle())); - METRIC_MAP.put("maxWaitMillis", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getMaxWaitMillis()); - METRIC_MAP.put("maxIdle", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getMaxIdle()); - METRIC_MAP.put("minIdle", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getMinIdle()); - METRIC_MAP.put("initialSize", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getInitialSize()); - } - @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { @@ -58,13 +43,12 @@ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allAr @Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { - if (LOGGER.isInfoEnable()) { - LOGGER.info("metric dbcp init"); - } BasicDataSourceMXBean basicDataSource = (BasicDataSourceMXBean) objInst; ConnectionInfo connectionInfo = URLParser.parser((String) allArguments[0]); String tagValue = connectionInfo.getDatabaseName() + "_" + connectionInfo.getDatabasePeer(); - METRIC_MAP.forEach((key, value) -> MeterFactory.gauge(METER_NAME, value.apply(basicDataSource)) + Map>> metricMap = new HashMap(); + initMetrics(metricMap); + metricMap.forEach((key, value) -> MeterFactory.gauge(METER_NAME, value.apply(basicDataSource)) .tag("name", tagValue).tag("status", key).build()); return ret; } @@ -73,4 +57,14 @@ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allA public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { } + + private void initMetrics(Map>> metricMap) { + metricMap.put("numActive", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getNumActive()); + metricMap.put("maxTotal", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getMaxTotal()); + metricMap.put("numIdle", (BasicDataSourceMXBean basicDataSource) -> () -> (double) (basicDataSource.getNumIdle())); + metricMap.put("maxWaitMillis", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getMaxWaitMillis()); + metricMap.put("maxIdle", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getMaxIdle()); + metricMap.put("minIdle", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getMinIdle()); + metricMap.put("initialSize", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getInitialSize()); + } } diff --git a/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/PoolingAddDruidDataSourceInterceptor.java b/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/PoolingAddDruidDataSourceInterceptor.java index acffcc8999..364226d61a 100644 --- a/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/PoolingAddDruidDataSourceInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/PoolingAddDruidDataSourceInterceptor.java @@ -18,8 +18,6 @@ package org.apache.skywalking.apm.plugin.druid.v1; import com.alibaba.druid.pool.DruidDataSourceMBean; -import org.apache.skywalking.apm.agent.core.logging.api.ILog; -import org.apache.skywalking.apm.agent.core.logging.api.LogManager; import org.apache.skywalking.apm.agent.core.meter.MeterFactory; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMethodsAroundInterceptor; @@ -37,21 +35,6 @@ */ public class PoolingAddDruidDataSourceInterceptor implements StaticMethodsAroundInterceptor { private static final String METER_NAME = "datasource"; - private static final ILog LOGGER = LogManager.getLogger(PoolingAddDruidDataSourceInterceptor.class); - - private static final Map>> METRIC_MAP = new HashMap>>(); - - static { - METRIC_MAP.put("activeCount", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getActiveCount()); - METRIC_MAP.put("poolingCount", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getPoolingCount()); - METRIC_MAP.put("idleCount", (DruidDataSourceMBean druidDataSource) -> () -> (double) (druidDataSource.getPoolingCount() - druidDataSource.getActiveCount())); - METRIC_MAP.put("lockQueueLength", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getLockQueueLength()); - METRIC_MAP.put("maxWaitThreadCount", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getMaxWaitThreadCount()); - METRIC_MAP.put("commitCount", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getCommitCount()); - METRIC_MAP.put("connectCount", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getConnectCount()); - METRIC_MAP.put("connectError", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getConnectErrorCount()); - METRIC_MAP.put("createError", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getCreateErrorCount()); - } @Override public void beforeMethod(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, MethodInterceptResult result) { @@ -60,13 +43,12 @@ public void beforeMethod(Class clazz, Method method, Object[] allArguments, Clas @Override public Object afterMethod(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, Object ret) { - if (LOGGER.isInfoEnable()) { - LOGGER.info("metric druid init"); - } DruidDataSourceMBean druidDataSource = (DruidDataSourceMBean) allArguments[0]; ConnectionInfo connectionInfo = URLParser.parser(druidDataSource.getUrl()); String tagValue = connectionInfo.getDatabaseName() + "_" + connectionInfo.getDatabasePeer(); - METRIC_MAP.forEach((key, value) -> MeterFactory.gauge(METER_NAME, value.apply(druidDataSource)) + Map>> metricMap = new HashMap(); + initMetrics(metricMap); + metricMap.forEach((key, value) -> MeterFactory.gauge(METER_NAME, value.apply(druidDataSource)) .tag("name", tagValue).tag("status", key).build()); return ret; } @@ -75,4 +57,16 @@ public Object afterMethod(Class clazz, Method method, Object[] allArguments, Cla public void handleMethodException(Class clazz, Method method, Object[] allArguments, Class[] parameterTypes, Throwable t) { } + + private void initMetrics(Map>> metricMap) { + metricMap.put("activeCount", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getActiveCount()); + metricMap.put("poolingCount", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getPoolingCount()); + metricMap.put("idleCount", (DruidDataSourceMBean druidDataSource) -> () -> (double) (druidDataSource.getPoolingCount() - druidDataSource.getActiveCount())); + metricMap.put("lockQueueLength", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getLockQueueLength()); + metricMap.put("maxWaitThreadCount", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getMaxWaitThreadCount()); + metricMap.put("commitCount", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getCommitCount()); + metricMap.put("connectCount", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getConnectCount()); + metricMap.put("connectError", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getConnectErrorCount()); + metricMap.put("createError", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getCreateErrorCount()); + } } diff --git a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/PoolingSealInterceptor.java b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/PoolingSealInterceptor.java index 45d676862b..05e4d4839a 100644 --- a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/PoolingSealInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/PoolingSealInterceptor.java @@ -20,8 +20,6 @@ import com.zaxxer.hikari.HikariConfigMXBean; import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.HikariPoolMXBean; -import org.apache.skywalking.apm.agent.core.logging.api.ILog; -import org.apache.skywalking.apm.agent.core.logging.api.LogManager; import org.apache.skywalking.apm.agent.core.meter.MeterFactory; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; @@ -40,23 +38,7 @@ */ public class PoolingSealInterceptor implements InstanceMethodsAroundInterceptor { - private static final ILog LOGGER = LogManager.getLogger(PoolingSealInterceptor.class); private static final String METER_NAME = "datasource"; - private static final Map>> METRIC_CONFIG_MAP = new HashMap>>(); - private static final Map>> METRIC_MAP = new HashMap>>(); - - static { - METRIC_CONFIG_MAP.put("activeConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getActiveConnections()); - METRIC_CONFIG_MAP.put("totalConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getTotalConnections()); - METRIC_CONFIG_MAP.put("idleConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getIdleConnections()); - METRIC_CONFIG_MAP.put("threadsAwaitingConnection", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getThreadsAwaitingConnection()); - METRIC_MAP.put("connectionTimeout", (HikariConfigMXBean hikariConfigMXBean) -> () -> (double) hikariConfigMXBean.getConnectionTimeout()); - METRIC_MAP.put("validationTimeout", (HikariConfigMXBean hikariConfigMXBean) -> () -> (double) hikariConfigMXBean.getValidationTimeout()); - METRIC_MAP.put("idleTimeout", (HikariConfigMXBean hikariConfigMXBean) -> () -> (double) hikariConfigMXBean.getIdleTimeout()); - METRIC_MAP.put("leakDetectionThreshold", (HikariConfigMXBean hikariConfigMXBean) -> () -> (double) hikariConfigMXBean.getLeakDetectionThreshold()); - METRIC_MAP.put("minimumIdle", (HikariConfigMXBean hikariConfigMXBean) -> () -> (double) hikariConfigMXBean.getMinimumIdle()); - METRIC_MAP.put("maximumPoolSize", (HikariConfigMXBean hikariConfigMXBean) -> () -> (double) hikariConfigMXBean.getMaximumPoolSize()); - } @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { @@ -65,16 +47,16 @@ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allAr @Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { - if (LOGGER.isInfoEnable()) { - LOGGER.info("metric hikari init"); - } HikariDataSource hikariDataSource = (HikariDataSource) objInst; ConnectionInfo connectionInfo = URLParser.parser(hikariDataSource.getJdbcUrl()); String tagValue = connectionInfo.getDatabaseName() + "_" + connectionInfo.getDatabasePeer(); - METRIC_CONFIG_MAP.forEach((key, value) -> MeterFactory.gauge(METER_NAME, value.apply(hikariDataSource.getHikariPoolMXBean())) + final Map>> poolMetricMap = new HashMap(); + final Map>> metricConfigMap = new HashMap(); + initMetrics(metricConfigMap, poolMetricMap); + poolMetricMap.forEach((key, value) -> MeterFactory.gauge(METER_NAME, value.apply(hikariDataSource.getHikariPoolMXBean())) .tag("name", tagValue).tag("status", key).build()); - METRIC_MAP.forEach((key, value) -> MeterFactory.gauge(METER_NAME, value.apply(hikariDataSource)) + metricConfigMap.forEach((key, value) -> MeterFactory.gauge(METER_NAME, value.apply(hikariDataSource)) .tag("name", tagValue).tag("status", key).build()); return ret; } @@ -83,4 +65,18 @@ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allA public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { } + + private void initMetrics(Map>> metricConfigMap, Map>> poolMetricMap) { + metricConfigMap.put("connectionTimeout", (HikariConfigMXBean hikariConfigMXBean) -> () -> (double) hikariConfigMXBean.getConnectionTimeout()); + metricConfigMap.put("validationTimeout", (HikariConfigMXBean hikariConfigMXBean) -> () -> (double) hikariConfigMXBean.getValidationTimeout()); + metricConfigMap.put("idleTimeout", (HikariConfigMXBean hikariConfigMXBean) -> () -> (double) hikariConfigMXBean.getIdleTimeout()); + metricConfigMap.put("leakDetectionThreshold", (HikariConfigMXBean hikariConfigMXBean) -> () -> (double) hikariConfigMXBean.getLeakDetectionThreshold()); + metricConfigMap.put("minimumIdle", (HikariConfigMXBean hikariConfigMXBean) -> () -> (double) hikariConfigMXBean.getMinimumIdle()); + metricConfigMap.put("maximumPoolSize", (HikariConfigMXBean hikariConfigMXBean) -> () -> (double) hikariConfigMXBean.getMaximumPoolSize()); + poolMetricMap.put("activeConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getActiveConnections()); + poolMetricMap.put("totalConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getTotalConnections()); + poolMetricMap.put("idleConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getIdleConnections()); + poolMetricMap.put("threadsAwaitingConnection", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getThreadsAwaitingConnection()); + + } } From 15aa2ab93b41c281ccf92d658ea9eef82bfcf342 Mon Sep 17 00:00:00 2001 From: xiaojianjun Date: Wed, 9 Feb 2022 11:57:52 +0800 Subject: [PATCH 09/16] format #96 --- .../skywalking/apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java index b4f636603e..823da00ac2 100644 --- a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java @@ -36,6 +36,7 @@ */ public class PoolingSetUrlInterceptor implements InstanceMethodsAroundInterceptor { private static final String METER_NAME = "datasource"; + @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { From c08204b9bd3d8bf2d60d678992e2ff6f1025b157 Mon Sep 17 00:00:00 2001 From: xiaojianjun Date: Wed, 9 Feb 2022 16:05:10 +0800 Subject: [PATCH 10/16] optimization #96 --- .../dbcp/v2/PoolingSetUrlInterceptor.java | 9 ++++---- .../PoolingAddDruidDataSourceInterceptor.java | 7 +++--- .../hikaricp/PoolingSealInterceptor.java | 23 +++++++++++-------- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java index 823da00ac2..f5b530a7b8 100644 --- a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java @@ -36,7 +36,7 @@ */ public class PoolingSetUrlInterceptor implements InstanceMethodsAroundInterceptor { private static final String METER_NAME = "datasource"; - + @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { @@ -47,8 +47,7 @@ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allA BasicDataSourceMXBean basicDataSource = (BasicDataSourceMXBean) objInst; ConnectionInfo connectionInfo = URLParser.parser((String) allArguments[0]); String tagValue = connectionInfo.getDatabaseName() + "_" + connectionInfo.getDatabasePeer(); - Map>> metricMap = new HashMap(); - initMetrics(metricMap); + Map>> metricMap = getMetrics(); metricMap.forEach((key, value) -> MeterFactory.gauge(METER_NAME, value.apply(basicDataSource)) .tag("name", tagValue).tag("status", key).build()); return ret; @@ -59,7 +58,8 @@ public void handleMethodException(EnhancedInstance objInst, Method method, Objec } - private void initMetrics(Map>> metricMap) { + private Map>> getMetrics() { + Map>> metricMap = new HashMap(); metricMap.put("numActive", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getNumActive()); metricMap.put("maxTotal", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getMaxTotal()); metricMap.put("numIdle", (BasicDataSourceMXBean basicDataSource) -> () -> (double) (basicDataSource.getNumIdle())); @@ -67,5 +67,6 @@ private void initMetrics(Map () -> (double) basicDataSource.getMaxIdle()); metricMap.put("minIdle", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getMinIdle()); metricMap.put("initialSize", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getInitialSize()); + return metricMap; } } diff --git a/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/PoolingAddDruidDataSourceInterceptor.java b/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/PoolingAddDruidDataSourceInterceptor.java index 364226d61a..63a85409de 100644 --- a/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/PoolingAddDruidDataSourceInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/druid-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/druid/v1/PoolingAddDruidDataSourceInterceptor.java @@ -46,8 +46,7 @@ public Object afterMethod(Class clazz, Method method, Object[] allArguments, Cla DruidDataSourceMBean druidDataSource = (DruidDataSourceMBean) allArguments[0]; ConnectionInfo connectionInfo = URLParser.parser(druidDataSource.getUrl()); String tagValue = connectionInfo.getDatabaseName() + "_" + connectionInfo.getDatabasePeer(); - Map>> metricMap = new HashMap(); - initMetrics(metricMap); + Map>> metricMap = getMetrics(); metricMap.forEach((key, value) -> MeterFactory.gauge(METER_NAME, value.apply(druidDataSource)) .tag("name", tagValue).tag("status", key).build()); return ret; @@ -58,7 +57,8 @@ public void handleMethodException(Class clazz, Method method, Object[] allArgume } - private void initMetrics(Map>> metricMap) { + private Map>> getMetrics() { + Map>> metricMap = new HashMap(); metricMap.put("activeCount", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getActiveCount()); metricMap.put("poolingCount", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getPoolingCount()); metricMap.put("idleCount", (DruidDataSourceMBean druidDataSource) -> () -> (double) (druidDataSource.getPoolingCount() - druidDataSource.getActiveCount())); @@ -68,5 +68,6 @@ private void initMetrics(Map () -> (double) druidDataSource.getConnectCount()); metricMap.put("connectError", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getConnectErrorCount()); metricMap.put("createError", (DruidDataSourceMBean druidDataSource) -> () -> (double) druidDataSource.getCreateErrorCount()); + return metricMap; } } diff --git a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/PoolingSealInterceptor.java b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/PoolingSealInterceptor.java index 05e4d4839a..7be4b562c2 100644 --- a/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/PoolingSealInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/hikaricp-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hikaricp/PoolingSealInterceptor.java @@ -51,9 +51,8 @@ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allA HikariDataSource hikariDataSource = (HikariDataSource) objInst; ConnectionInfo connectionInfo = URLParser.parser(hikariDataSource.getJdbcUrl()); String tagValue = connectionInfo.getDatabaseName() + "_" + connectionInfo.getDatabasePeer(); - final Map>> poolMetricMap = new HashMap(); - final Map>> metricConfigMap = new HashMap(); - initMetrics(metricConfigMap, poolMetricMap); + final Map>> poolMetricMap = getPoolMetrics(); + final Map>> metricConfigMap = getConfigMetrics(); poolMetricMap.forEach((key, value) -> MeterFactory.gauge(METER_NAME, value.apply(hikariDataSource.getHikariPoolMXBean())) .tag("name", tagValue).tag("status", key).build()); metricConfigMap.forEach((key, value) -> MeterFactory.gauge(METER_NAME, value.apply(hikariDataSource)) @@ -66,17 +65,23 @@ public void handleMethodException(EnhancedInstance objInst, Method method, Objec } - private void initMetrics(Map>> metricConfigMap, Map>> poolMetricMap) { + private Map>> getPoolMetrics() { + final Map>> poolMetricMap = new HashMap(); + poolMetricMap.put("activeConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getActiveConnections()); + poolMetricMap.put("totalConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getTotalConnections()); + poolMetricMap.put("idleConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getIdleConnections()); + poolMetricMap.put("threadsAwaitingConnection", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getThreadsAwaitingConnection()); + return poolMetricMap; + } + + private Map>> getConfigMetrics() { + final Map>> metricConfigMap = new HashMap(); metricConfigMap.put("connectionTimeout", (HikariConfigMXBean hikariConfigMXBean) -> () -> (double) hikariConfigMXBean.getConnectionTimeout()); metricConfigMap.put("validationTimeout", (HikariConfigMXBean hikariConfigMXBean) -> () -> (double) hikariConfigMXBean.getValidationTimeout()); metricConfigMap.put("idleTimeout", (HikariConfigMXBean hikariConfigMXBean) -> () -> (double) hikariConfigMXBean.getIdleTimeout()); metricConfigMap.put("leakDetectionThreshold", (HikariConfigMXBean hikariConfigMXBean) -> () -> (double) hikariConfigMXBean.getLeakDetectionThreshold()); metricConfigMap.put("minimumIdle", (HikariConfigMXBean hikariConfigMXBean) -> () -> (double) hikariConfigMXBean.getMinimumIdle()); metricConfigMap.put("maximumPoolSize", (HikariConfigMXBean hikariConfigMXBean) -> () -> (double) hikariConfigMXBean.getMaximumPoolSize()); - poolMetricMap.put("activeConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getActiveConnections()); - poolMetricMap.put("totalConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getTotalConnections()); - poolMetricMap.put("idleConnections", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getIdleConnections()); - poolMetricMap.put("threadsAwaitingConnection", (HikariPoolMXBean hikariPoolMXBean) -> () -> (double) hikariPoolMXBean.getThreadsAwaitingConnection()); - + return metricConfigMap; } } From fd9b150aa35281942187b13c87a2fbd9a25c3ce5 Mon Sep 17 00:00:00 2001 From: xiaojianjun Date: Wed, 9 Feb 2022 23:24:47 +0800 Subject: [PATCH 11/16] remove space key #96 --- test/plugin/scenarios/dbcp-2.x-scenario/config/expectedData.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/test/plugin/scenarios/dbcp-2.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/dbcp-2.x-scenario/config/expectedData.yaml index 5f4c78245d..f1e1ef9947 100755 --- a/test/plugin/scenarios/dbcp-2.x-scenario/config/expectedData.yaml +++ b/test/plugin/scenarios/dbcp-2.x-scenario/config/expectedData.yaml @@ -221,7 +221,6 @@ segmentItems: tags: - {key: url, value: 'http://localhost:8080/dbcp-2.x-scenario/case/dbcp-2.x-scenario'} - {key: http.method, value: GET} - meterItems: - serviceName: dbcp-2.x-scenario meterSize: 7 From 1ec6f116a228976e5fd18e81a9270c3627048605 Mon Sep 17 00:00:00 2001 From: xiaojianjun Date: Thu, 10 Feb 2022 15:47:09 +0800 Subject: [PATCH 12/16] add tomcat metric #96 --- .../config/expectedData.yaml | 120 +++++++++----- .../config/expectedData.yaml | 144 +++++++++------- .../config/expectedData.yaml | 156 +++++++++++------- 3 files changed, 255 insertions(+), 165 deletions(-) diff --git a/test/plugin/scenarios/dbcp-2.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/dbcp-2.x-scenario/config/expectedData.yaml index f1e1ef9947..402ed76d14 100755 --- a/test/plugin/scenarios/dbcp-2.x-scenario/config/expectedData.yaml +++ b/test/plugin/scenarios/dbcp-2.x-scenario/config/expectedData.yaml @@ -222,48 +222,78 @@ segmentItems: - {key: url, value: 'http://localhost:8080/dbcp-2.x-scenario/case/dbcp-2.x-scenario'} - {key: http.method, value: GET} meterItems: - - serviceName: dbcp-2.x-scenario - meterSize: 7 - meters: - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: numActive} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: maxTotal} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: numIdle} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: maxWaitMillis} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: maxIdle} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: minIdle} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: initialSize} - singleValue: ge 0 +- serviceName: dbcp-2.x-scenario + meterSize: 12 + meters: + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: numActive} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: maxTotal} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: numIdle} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: maxWaitMillis} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: maxIdle} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: minIdle} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: initialSize} + singleValue: ge 0 + - meterId: + name: thread_pool + tags: + - {name: metric_type, value: core_pool_size} + - {name: pool_name, value: tomcat_execute_pool} + singleValue: ge 1 + - meterId: + name: thread_pool + tags: + - {name: metric_type, value: max_pool_size} + - {name: pool_name, value: tomcat_execute_pool} + singleValue: ge 1 + - meterId: + name: thread_pool + tags: + - {name: metric_type, value: pool_size} + - {name: pool_name, value: tomcat_execute_pool} + singleValue: ge 0 + - meterId: + name: thread_pool + tags: + - {name: metric_type, value: active_size} + - {name: pool_name, value: tomcat_execute_pool} + singleValue: ge 0 + - meterId: + name: thread_pool + tags: + - {name: metric_type, value: queue_size} + - {name: pool_name, value: tomcat_execute_pool} + singleValue: ge 0 diff --git a/test/plugin/scenarios/druid-1.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/druid-1.x-scenario/config/expectedData.yaml index 5c315382c1..c9326bbc85 100644 --- a/test/plugin/scenarios/druid-1.x-scenario/config/expectedData.yaml +++ b/test/plugin/scenarios/druid-1.x-scenario/config/expectedData.yaml @@ -204,60 +204,90 @@ segmentItems: - {key: url, value: 'http://localhost:8080/druid-1.x-scenario/case/druid-1.x-scenario'} - {key: http.method, value: GET} meterItems: - - serviceName: druid-1.x-scenario - meterSize: 9 - meters: - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: activeCount} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: poolingCount} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: idleCount} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: lockQueueLength} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: maxWaitThreadCount} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: commitCount} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: connectCount} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: connectError} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: createError} - singleValue: ge 0 +- serviceName: druid-1.x-scenario + meterSize: 14 + meters: + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: activeCount} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: poolingCount} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: idleCount} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: lockQueueLength} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: maxWaitThreadCount} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: commitCount} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: connectCount} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: connectError} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: createError} + singleValue: ge 0 + - meterId: + name: thread_pool + tags: + - {name: metric_type, value: core_pool_size} + - {name: pool_name, value: tomcat_execute_pool} + singleValue: ge 1 + - meterId: + name: thread_pool + tags: + - {name: metric_type, value: max_pool_size} + - {name: pool_name, value: tomcat_execute_pool} + singleValue: ge 1 + - meterId: + name: thread_pool + tags: + - {name: metric_type, value: pool_size} + - {name: pool_name, value: tomcat_execute_pool} + singleValue: ge 0 + - meterId: + name: thread_pool + tags: + - {name: metric_type, value: active_size} + - {name: pool_name, value: tomcat_execute_pool} + singleValue: ge 0 + - meterId: + name: thread_pool + tags: + - {name: metric_type, value: queue_size} + - {name: pool_name, value: tomcat_execute_pool} + singleValue: ge 0 diff --git a/test/plugin/scenarios/hikaricp-scenario/config/expectedData.yaml b/test/plugin/scenarios/hikaricp-scenario/config/expectedData.yaml index 2ef8a36516..afc4c3c5cc 100644 --- a/test/plugin/scenarios/hikaricp-scenario/config/expectedData.yaml +++ b/test/plugin/scenarios/hikaricp-scenario/config/expectedData.yaml @@ -204,66 +204,96 @@ segmentItems: - {key: url, value: 'http://localhost:8080/hikaricp-scenario/case/hikaricp-scenario'} - {key: http.method, value: GET} meterItems: - - serviceName: hikaricp-scenario - meterSize: 10 - meters: - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: activeConnections} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: totalConnections} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: idleConnections} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: threadsAwaitingConnection} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: connectionTimeout} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: validationTimeout} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: idleTimeout} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: leakDetectionThreshold} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: minimumIdle} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: maximumPoolSize} - singleValue: ge 0 +- serviceName: hikaricp-scenario + meterSize: 15 + meters: + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: activeConnections} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: totalConnections} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: idleConnections} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: threadsAwaitingConnection} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: connectionTimeout} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: validationTimeout} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: idleTimeout} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: leakDetectionThreshold} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: minimumIdle} + singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: maximumPoolSize} + singleValue: ge 0 + - meterId: + name: thread_pool + tags: + - {name: metric_type, value: core_pool_size} + - {name: pool_name, value: tomcat_execute_pool} + singleValue: ge 1 + - meterId: + name: thread_pool + tags: + - {name: metric_type, value: max_pool_size} + - {name: pool_name, value: tomcat_execute_pool} + singleValue: ge 1 + - meterId: + name: thread_pool + tags: + - {name: metric_type, value: pool_size} + - {name: pool_name, value: tomcat_execute_pool} + singleValue: ge 0 + - meterId: + name: thread_pool + tags: + - {name: metric_type, value: active_size} + - {name: pool_name, value: tomcat_execute_pool} + singleValue: ge 0 + - meterId: + name: thread_pool + tags: + - {name: metric_type, value: queue_size} + - {name: pool_name, value: tomcat_execute_pool} + singleValue: ge 0 From b6ee8a0bd3b57ffd3efc75d5c6ddc50d716e0357 Mon Sep 17 00:00:00 2001 From: xiaojianjun Date: Thu, 10 Feb 2022 16:40:40 +0800 Subject: [PATCH 13/16] validate value change #96 --- .../config/expectedData.yaml | 148 +++++++++--------- .../config/expectedData.yaml | 2 +- .../config/expectedData.yaml | 2 +- 3 files changed, 76 insertions(+), 76 deletions(-) diff --git a/test/plugin/scenarios/apm-toolkit-trace-scenario/config/expectedData.yaml b/test/plugin/scenarios/apm-toolkit-trace-scenario/config/expectedData.yaml index 1fe73f06ab..32fd5912bf 100644 --- a/test/plugin/scenarios/apm-toolkit-trace-scenario/config/expectedData.yaml +++ b/test/plugin/scenarios/apm-toolkit-trace-scenario/config/expectedData.yaml @@ -537,25 +537,25 @@ meterItems: tags: - {name: name, value: test_mysql-server:3306} - {name: status, value: numActive} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: maxTotal} singleValue: ge 0 - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: numIdle} + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: maxTotal} singleValue: ge 0 - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: maxWaitMillis} + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: numIdle} singleValue: ge 0 + - meterId: + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: maxWaitMillis} + singleValue: ge -1 - meterId: name: datasource tags: @@ -569,41 +569,41 @@ meterItems: - {name: status, value: minIdle} singleValue: ge 0 - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: initialSize} + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: initialSize} singleValue: ge 0 - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: activeCount} + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: activeCount} singleValue: ge 0 - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: poolingCount} + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: poolingCount} singleValue: ge 0 - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: idleCount} + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: idleCount} singleValue: ge 0 - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: lockQueueLength} + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: lockQueueLength} singleValue: ge 0 - meterId: name: datasource tags: - {name: name, value: test_mysql-server:3306} - {name: status, value: maxWaitThreadCount} - singleValue: ge 0 + singleValue: ge -1 - meterId: name: datasource tags: @@ -611,10 +611,10 @@ meterItems: - {name: status, value: commitCount} singleValue: ge 0 - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: connectCount} + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: connectCount} singleValue: ge 0 - meterId: name: datasource @@ -623,34 +623,34 @@ meterItems: - {name: status, value: connectError} singleValue: ge 0 - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: createError} + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: createError} singleValue: ge 0 - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: activeConnections} + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: activeConnections} singleValue: ge 0 - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: totalConnections} + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: totalConnections} singleValue: ge 0 - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: idleConnections} + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: idleConnections} singleValue: ge 0 - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: threadsAwaitingConnection} + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: threadsAwaitingConnection} singleValue: ge 0 - meterId: name: datasource @@ -665,26 +665,26 @@ meterItems: - {name: status, value: validationTimeout} singleValue: ge 0 - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: idleTimeout} + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: idleTimeout} singleValue: ge 0 - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: leakDetectionThreshold} + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: leakDetectionThreshold} singleValue: ge 0 - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: minimumIdle} + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} + - {name: status, value: minimumIdle} singleValue: ge 0 - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} + name: datasource + tags: + - {name: name, value: test_mysql-server:3306} - {name: status, value: maximumPoolSize} singleValue: ge 0 diff --git a/test/plugin/scenarios/dbcp-2.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/dbcp-2.x-scenario/config/expectedData.yaml index 402ed76d14..1cfc8dc337 100755 --- a/test/plugin/scenarios/dbcp-2.x-scenario/config/expectedData.yaml +++ b/test/plugin/scenarios/dbcp-2.x-scenario/config/expectedData.yaml @@ -248,7 +248,7 @@ meterItems: tags: - {name: name, value: test_mysql-server:3306} - {name: status, value: maxWaitMillis} - singleValue: ge 0 + singleValue: ge -1 - meterId: name: datasource tags: diff --git a/test/plugin/scenarios/druid-1.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/druid-1.x-scenario/config/expectedData.yaml index c9326bbc85..a20d9baea7 100644 --- a/test/plugin/scenarios/druid-1.x-scenario/config/expectedData.yaml +++ b/test/plugin/scenarios/druid-1.x-scenario/config/expectedData.yaml @@ -236,7 +236,7 @@ meterItems: tags: - {name: name, value: test_mysql-server:3306} - {name: status, value: maxWaitThreadCount} - singleValue: ge 0 + singleValue: ge -1 - meterId: name: datasource tags: From 820cd0f2d349b20df14ea81570b56555b8ec05f8 Mon Sep 17 00:00:00 2001 From: xiaojianjun Date: Thu, 10 Feb 2022 18:05:02 +0800 Subject: [PATCH 14/16] remove datasource metric #96 --- .../config/expectedData.yaml | 158 +----------------- 1 file changed, 1 insertion(+), 157 deletions(-) diff --git a/test/plugin/scenarios/apm-toolkit-trace-scenario/config/expectedData.yaml b/test/plugin/scenarios/apm-toolkit-trace-scenario/config/expectedData.yaml index 32fd5912bf..436ddf17e5 100644 --- a/test/plugin/scenarios/apm-toolkit-trace-scenario/config/expectedData.yaml +++ b/test/plugin/scenarios/apm-toolkit-trace-scenario/config/expectedData.yaml @@ -481,7 +481,7 @@ segmentItems: skipAnalysis: 'true' meterItems: - serviceName: apm-toolkit-trace-scenario - meterSize: 34 + meterSize: 8 meters: - meterId: name: test_counter @@ -532,159 +532,3 @@ meterItems: - {name: metric_type, value: queue_size} - {name: pool_name, value: tomcat_execute_pool} singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: numActive} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: maxTotal} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: numIdle} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: maxWaitMillis} - singleValue: ge -1 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: maxIdle} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: minIdle} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: initialSize} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: activeCount} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: poolingCount} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: idleCount} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: lockQueueLength} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: maxWaitThreadCount} - singleValue: ge -1 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: commitCount} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: connectCount} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: connectError} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: createError} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: activeConnections} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: totalConnections} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: idleConnections} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: threadsAwaitingConnection} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: connectionTimeout} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: validationTimeout} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: idleTimeout} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: leakDetectionThreshold} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: minimumIdle} - singleValue: ge 0 - - meterId: - name: datasource - tags: - - {name: name, value: test_mysql-server:3306} - - {name: status, value: maximumPoolSize} - singleValue: ge 0 From 8ae75171c54a9079c309f8f3dd3b3684720ca4b5 Mon Sep 17 00:00:00 2001 From: xiaojianjun Date: Fri, 11 Feb 2022 11:06:55 +0800 Subject: [PATCH 15/16] optimize interception point #96 --- .../PoolingCreateDataSourceInterceptor.java | 71 +++++++++++++++++++ .../dbcp/v2/PoolingSetUrlInterceptor.java | 29 ++------ .../BasicDataSourceInstrumentation.java | 17 +++++ 3 files changed, 93 insertions(+), 24 deletions(-) create mode 100644 apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingCreateDataSourceInterceptor.java diff --git a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingCreateDataSourceInterceptor.java b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingCreateDataSourceInterceptor.java new file mode 100644 index 0000000000..c3d2bdd9c9 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingCreateDataSourceInterceptor.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.skywalking.apm.plugin.dbcp.v2; + +import org.apache.commons.dbcp2.BasicDataSourceMXBean; +import org.apache.skywalking.apm.agent.core.meter.MeterFactory; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * {@link PoolingCreateDataSourceInterceptor} intercepted the method of DBCP createDataSource register metric monitor. + */ +public class PoolingCreateDataSourceInterceptor implements InstanceMethodsAroundInterceptor { + private static final String METER_NAME = "datasource"; + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { + if (objInst.getSkyWalkingDynamicField() != null) { + BasicDataSourceMXBean basicDataSource = (BasicDataSourceMXBean) objInst; + String tagValue = (String) objInst.getSkyWalkingDynamicField(); + Map>> metricMap = getMetrics(); + metricMap.forEach((key, value) -> MeterFactory.gauge(METER_NAME, value.apply(basicDataSource)) + .tag("name", tagValue).tag("status", key).build()); + } + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + + } + + private Map>> getMetrics() { + Map>> metricMap = new HashMap(); + metricMap.put("numActive", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getNumActive()); + metricMap.put("maxTotal", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getMaxTotal()); + metricMap.put("numIdle", (BasicDataSourceMXBean basicDataSource) -> () -> (double) (basicDataSource.getNumIdle())); + metricMap.put("maxWaitMillis", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getMaxWaitMillis()); + metricMap.put("maxIdle", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getMaxIdle()); + metricMap.put("minIdle", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getMinIdle()); + metricMap.put("initialSize", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getInitialSize()); + return metricMap; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java index f5b530a7b8..cad1af3662 100644 --- a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java @@ -17,8 +17,6 @@ package org.apache.skywalking.apm.plugin.dbcp.v2; -import org.apache.commons.dbcp2.BasicDataSourceMXBean; -import org.apache.skywalking.apm.agent.core.meter.MeterFactory; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; @@ -26,13 +24,9 @@ import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Function; -import java.util.function.Supplier; /** - * {@link PoolingSetUrlInterceptor} intercepted the method of DBCP set url and register metric monitor. + * {@link PoolingSetUrlInterceptor} intercepted the method of DBCP set url Get parameters. */ public class PoolingSetUrlInterceptor implements InstanceMethodsAroundInterceptor { private static final String METER_NAME = "datasource"; @@ -44,29 +38,16 @@ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allAr @Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { - BasicDataSourceMXBean basicDataSource = (BasicDataSourceMXBean) objInst; ConnectionInfo connectionInfo = URLParser.parser((String) allArguments[0]); String tagValue = connectionInfo.getDatabaseName() + "_" + connectionInfo.getDatabasePeer(); - Map>> metricMap = getMetrics(); - metricMap.forEach((key, value) -> MeterFactory.gauge(METER_NAME, value.apply(basicDataSource)) - .tag("name", tagValue).tag("status", key).build()); - return ret; + if (tagValue != null) { + objInst.setSkyWalkingDynamicField(tagValue); + } + return ret; } @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { } - - private Map>> getMetrics() { - Map>> metricMap = new HashMap(); - metricMap.put("numActive", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getNumActive()); - metricMap.put("maxTotal", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getMaxTotal()); - metricMap.put("numIdle", (BasicDataSourceMXBean basicDataSource) -> () -> (double) (basicDataSource.getNumIdle())); - metricMap.put("maxWaitMillis", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getMaxWaitMillis()); - metricMap.put("maxIdle", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getMaxIdle()); - metricMap.put("minIdle", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getMinIdle()); - metricMap.put("initialSize", (BasicDataSourceMXBean basicDataSource) -> () -> (double) basicDataSource.getInitialSize()); - return metricMap; - } } diff --git a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/define/BasicDataSourceInstrumentation.java b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/define/BasicDataSourceInstrumentation.java index 22ddca121e..acffae0250 100755 --- a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/define/BasicDataSourceInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/define/BasicDataSourceInstrumentation.java @@ -37,6 +37,7 @@ public class BasicDataSourceInstrumentation extends ClassInstanceMethodsEnhanceP private static final String ENHANCE_CLASS = "org.apache.commons.dbcp2.BasicDataSource"; private static final String CONNECT_GET_INTERCEPTOR = "org.apache.skywalking.apm.plugin.dbcp.v2.PoolingGetConnectInterceptor"; private static final String INTERCEPTOR_URL_CLASS = "org.apache.skywalking.apm.plugin.dbcp.v2.PoolingSetUrlInterceptor"; + private static final String INTERCEPTOR_CREATE_CLASS = "org.apache.skywalking.apm.plugin.dbcp.v2.PoolingCreateDataSourceInterceptor"; @Override protected ClassMatch enhanceClass() { @@ -78,6 +79,22 @@ public String getMethodsInterceptor() { return INTERCEPTOR_URL_CLASS; } + @Override + public boolean isOverrideArgs() { + return false; + } + }, + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named("createDataSource"); + } + + @Override + public String getMethodsInterceptor() { + return INTERCEPTOR_CREATE_CLASS; + } + @Override public boolean isOverrideArgs() { return false; From bee196f03cfb0cce7e81c6aaff8b360c111c951c Mon Sep 17 00:00:00 2001 From: xiaojianjun Date: Fri, 11 Feb 2022 13:46:41 +0800 Subject: [PATCH 16/16] Optimize interception point #96 --- ...eInterceptor.java => PoolingJmxRegisterInterceptor.java} | 4 ++-- .../apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java | 6 ++---- .../dbcp/v2/define/BasicDataSourceInstrumentation.java | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-) rename apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/{PoolingCreateDataSourceInterceptor.java => PoolingJmxRegisterInterceptor.java} (94%) diff --git a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingCreateDataSourceInterceptor.java b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingJmxRegisterInterceptor.java similarity index 94% rename from apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingCreateDataSourceInterceptor.java rename to apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingJmxRegisterInterceptor.java index c3d2bdd9c9..6ea9892cab 100644 --- a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingCreateDataSourceInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingJmxRegisterInterceptor.java @@ -30,9 +30,9 @@ import java.util.function.Supplier; /** - * {@link PoolingCreateDataSourceInterceptor} intercepted the method of DBCP createDataSource register metric monitor. + * {@link PoolingJmxRegisterInterceptor} intercepted the method of DBCP jmxRegister register metric monitor. */ -public class PoolingCreateDataSourceInterceptor implements InstanceMethodsAroundInterceptor { +public class PoolingJmxRegisterInterceptor implements InstanceMethodsAroundInterceptor { private static final String METER_NAME = "datasource"; @Override diff --git a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java index cad1af3662..b2a9914ad5 100644 --- a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/PoolingSetUrlInterceptor.java @@ -40,10 +40,8 @@ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allAr public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { ConnectionInfo connectionInfo = URLParser.parser((String) allArguments[0]); String tagValue = connectionInfo.getDatabaseName() + "_" + connectionInfo.getDatabasePeer(); - if (tagValue != null) { - objInst.setSkyWalkingDynamicField(tagValue); - } - return ret; + objInst.setSkyWalkingDynamicField(tagValue); + return ret; } @Override diff --git a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/define/BasicDataSourceInstrumentation.java b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/define/BasicDataSourceInstrumentation.java index acffae0250..6e5bf93b82 100755 --- a/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/define/BasicDataSourceInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/dbcp-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/dbcp/v2/define/BasicDataSourceInstrumentation.java @@ -37,7 +37,7 @@ public class BasicDataSourceInstrumentation extends ClassInstanceMethodsEnhanceP private static final String ENHANCE_CLASS = "org.apache.commons.dbcp2.BasicDataSource"; private static final String CONNECT_GET_INTERCEPTOR = "org.apache.skywalking.apm.plugin.dbcp.v2.PoolingGetConnectInterceptor"; private static final String INTERCEPTOR_URL_CLASS = "org.apache.skywalking.apm.plugin.dbcp.v2.PoolingSetUrlInterceptor"; - private static final String INTERCEPTOR_CREATE_CLASS = "org.apache.skywalking.apm.plugin.dbcp.v2.PoolingCreateDataSourceInterceptor"; + private static final String INTERCEPTOR_CREATE_CLASS = "org.apache.skywalking.apm.plugin.dbcp.v2.PoolingJmxRegisterInterceptor"; @Override protected ClassMatch enhanceClass() { @@ -87,7 +87,7 @@ public boolean isOverrideArgs() { new InstanceMethodsInterceptPoint() { @Override public ElementMatcher getMethodsMatcher() { - return named("createDataSource"); + return named("jmxRegister"); } @Override