[Feature] Support collecting database connection pool metric,support dbcp2/druid/hikari (#96)

* [Feature] Support collecting database connection pool metric,support druid/hikari #8450

* [Feature] Support collecting database connection pool metric,support druid/hikari #8450

* [Feature] Support collecting database connection pool metric,support druid/hikari/dbcp2 #8450
This commit is contained in:
xiaojianjun 2022-02-11 15:02:57 +08:00 committed by GitHub
parent a48a16b6d6
commit 00cf97e425
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 704 additions and 12 deletions

View File

@ -8,6 +8,9 @@ Release Notes.
* Support Tomcat thread pool metric collect.
* Remove plugin for ServiceComb Java Chassis 0.x
* Add Guava EventBus plugin.
* Support Druid Connection pool metrics collecting.
* Support HikariCP Connection pool metrics collecting.
* Support Dbcp2 Connection pool metrics collecting.
#### Documentation

View File

@ -38,7 +38,11 @@
<version>${dbcp.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-jdbc-commons</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
</project>

View File

@ -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 PoolingJmxRegisterInterceptor} intercepted the method of DBCP jmxRegister register metric monitor.
*/
public class PoolingJmxRegisterInterceptor 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<String, Function<BasicDataSourceMXBean, Supplier<Double>>> 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<String, Function<BasicDataSourceMXBean, Supplier<Double>>> getMetrics() {
Map<String, Function<BasicDataSourceMXBean, Supplier<Double>>> 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;
}
}

View File

@ -0,0 +1,51 @@
/*
* 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.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;
/**
* {@link PoolingSetUrlInterceptor} intercepted the method of DBCP set url Get parameters.
*/
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 {
}
@Override
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();
objInst.setSkyWalkingDynamicField(tagValue);
return ret;
}
@Override
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Throwable t) {
}
}

View File

@ -31,10 +31,13 @@ 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.PoolingSetUrlInterceptor";
private static final String INTERCEPTOR_CREATE_CLASS = "org.apache.skywalking.apm.plugin.dbcp.v2.PoolingJmxRegisterInterceptor";
@Override
protected ClassMatch enhanceClass() {
@ -48,7 +51,7 @@ public class BasicDataSourceInstrumentation extends ClassInstanceMethodsEnhanceP
@Override
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
return new InstanceMethodsInterceptPoint[]{
new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
@ -60,6 +63,38 @@ public class BasicDataSourceInstrumentation extends ClassInstanceMethodsEnhanceP
return CONNECT_GET_INTERCEPTOR;
}
@Override
public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named("setUrl");
}
@Override
public String getMethodsInterceptor() {
return INTERCEPTOR_URL_CLASS;
}
@Override
public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named("jmxRegister");
}
@Override
public String getMethodsInterceptor() {
return INTERCEPTOR_CREATE_CLASS;
}
@Override
public boolean isOverrideArgs() {
return false;

View File

@ -38,7 +38,11 @@
<version>${druid.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-jdbc-commons</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
</project>

View File

@ -0,0 +1,73 @@
/*
* 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.DruidDataSourceMBean;
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;
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 PoolingAddDruidDataSourceInterceptor} intercepted the method of druid addDataSource and register metric monitor.
*/
public class PoolingAddDruidDataSourceInterceptor implements StaticMethodsAroundInterceptor {
private static final String METER_NAME = "datasource";
@Override
public void beforeMethod(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes, MethodInterceptResult result) {
}
@Override
public Object afterMethod(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes, Object ret) {
DruidDataSourceMBean druidDataSource = (DruidDataSourceMBean) allArguments[0];
ConnectionInfo connectionInfo = URLParser.parser(druidDataSource.getUrl());
String tagValue = connectionInfo.getDatabaseName() + "_" + connectionInfo.getDatabasePeer();
Map<String, Function<DruidDataSourceMBean, Supplier<Double>>> metricMap = getMetrics();
metricMap.forEach((key, value) -> MeterFactory.gauge(METER_NAME, value.apply(druidDataSource))
.tag("name", tagValue).tag("status", key).build());
return ret;
}
@Override
public void handleMethodException(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes, Throwable t) {
}
private Map<String, Function<DruidDataSourceMBean, Supplier<Double>>> getMetrics() {
Map<String, Function<DruidDataSourceMBean, Supplier<Double>>> 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()));
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());
return metricMap;
}
}

View File

@ -26,8 +26,8 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInst
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.takesArguments;
import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
/**
@ -94,4 +94,5 @@ public class DruidDataSourceInstrumentation extends ClassInstanceMethodsEnhanceP
public StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() {
return new StaticMethodsInterceptPoint[0];
}
}

View File

@ -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.
* <p>
* 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<MethodDescription> getMethodsMatcher() {
return named(ENHANCE_METHOD).and(takesArguments(Object.class, String.class));
}
@Override
public String getMethodsInterceptor() {
return INTERCEPTOR_CLASS;
}
@Override
public boolean isOverrideArgs() {
return false;
}
}
};
}
}

View File

@ -15,4 +15,5 @@
# 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
druid-1.x=org.apache.skywalking.apm.plugin.druid.v1.define.DruidDataSourceInstrumentation
druid-1.x=org.apache.skywalking.apm.plugin.druid.v1.define.DruidDataSourceStatManagerInstrumentation

View File

@ -39,6 +39,11 @@
<version>${hikaricp.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-jdbc-commons</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
</project>

View File

@ -0,0 +1,87 @@
/*
* 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.HikariConfigMXBean;
import com.zaxxer.hikari.HikariDataSource;
import com.zaxxer.hikari.HikariPoolMXBean;
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 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 {
HikariDataSource hikariDataSource = (HikariDataSource) objInst;
ConnectionInfo connectionInfo = URLParser.parser(hikariDataSource.getJdbcUrl());
String tagValue = connectionInfo.getDatabaseName() + "_" + connectionInfo.getDatabasePeer();
final Map<String, Function<HikariPoolMXBean, Supplier<Double>>> poolMetricMap = getPoolMetrics();
final Map<String, Function<HikariConfigMXBean, Supplier<Double>>> 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))
.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<String, Function<HikariPoolMXBean, Supplier<Double>>> getPoolMetrics() {
final Map<String, Function<HikariPoolMXBean, Supplier<Double>>> 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<String, Function<HikariConfigMXBean, Supplier<Double>>> getConfigMetrics() {
final Map<String, Function<HikariConfigMXBean, Supplier<Double>>> 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());
return metricConfigMap;
}
}

View File

@ -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 class HikariDataSourceInstrumentation extends ClassInstanceMethodsEnhance
return INTERCEPTOR_CLASS;
}
@Override
public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named("seal");
}
@Override
public String getMethodsInterceptor() {
return SEAL_INTERCEPTOR_CLASS;
}
@Override
public boolean isOverrideArgs() {
return false;

View File

@ -15,4 +15,4 @@
# 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
hikaricp-3.x/4.x=org.apache.skywalking.apm.plugin.hikaricp.define.HikariDataSourceInstrumentation

View File

@ -131,6 +131,9 @@
<sourceDirectories>
<sourceDirectory>${project.build.sourceDirectory}</sourceDirectory>
<sourceDirectory>${project.build.testSourceDirectory}</sourceDirectory>
<sourceDirectory>scenarios/dbcp-2.x-scenario</sourceDirectory>
<sourceDirectory>scenarios/druid-1.x-scenario</sourceDirectory>
<sourceDirectory>scenarios/druid-1.x</sourceDirectory>
</sourceDirectories>
<resourceIncludes>
**/*.properties,

View File

@ -221,3 +221,79 @@ 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: 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 -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: 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

View File

@ -203,3 +203,91 @@ 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: 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 -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: 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

View File

@ -203,3 +203,97 @@ segmentItems:
tags:
- {key: url, value: 'http://localhost:8080/hikaricp-scenario/case/hikaricp-scenario'}
- {key: http.method, value: GET}
meterItems:
- 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