未验证 提交 fe79a497 编写于 作者: A Ax1an 提交者: GitHub

Fix possible memory leaks in mybatis plugin. (#6913)

上级 5f26710d
......@@ -104,8 +104,6 @@ public interface AbstractSpan extends AsyncSpan {
String getOperationName();
int getComponentId();
/**
* Reference other trace segment.
*
......
......@@ -232,11 +232,6 @@ public abstract class AbstractTracingSpan implements AbstractSpan {
return operationName;
}
@Override
public int getComponentId() {
return componentId;
}
@Override
public AbstractTracingSpan setLayer(SpanLayer layer) {
this.layer = layer;
......
......@@ -100,11 +100,6 @@ public class NoopSpan implements AbstractSpan {
return "";
}
@Override
public int getComponentId() {
return 0;
}
@Override
public void ref(TraceSegmentRef ref) {
}
......
/*
* 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.mybatis;
public class Constants {
public static final String MYBATIS_SHELL_METHOD_NAME = "mybatis_shell_method_name";
}
......@@ -28,45 +28,33 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInt
import org.apache.skywalking.apm.agent.core.util.MethodUtil;
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
public class SqlSessionOperationInterceptor implements InstanceMethodsAroundInterceptor {
public static final String MYBATIS_ENTRY_METHOD_NAME = "mybatis_entry_method_name";
public class MyBatisInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
String operationName = MethodUtil.generateOperationName(method);
AbstractSpan lastSpan = null;
if (ContextManager.isActive()) {
lastSpan = ContextManager.activeSpan();
}
if (lastSpan == null || lastSpan.getComponentId() != ComponentsDefine.MYBATIS.getId()) {
AbstractSpan span = ContextManager.createLocalSpan(operationName);
span.setComponent(ComponentsDefine.MYBATIS);
if (allArguments != null && allArguments.length != 0) {
Tags.MYBATIS_MAPPER.set(span, (String) allArguments[0]);
}
ContextManager.getRuntimeContext().put(MYBATIS_ENTRY_METHOD_NAME, operationName);
String operationName;
if (ContextManager.getRuntimeContext().get(Constants.MYBATIS_SHELL_METHOD_NAME) != null) {
operationName = String.valueOf(ContextManager.getRuntimeContext().get(Constants.MYBATIS_SHELL_METHOD_NAME));
ContextManager.getRuntimeContext().remove(Constants.MYBATIS_SHELL_METHOD_NAME);
} else {
operationName = MethodUtil.generateOperationName(method);
}
AbstractSpan span = ContextManager.createLocalSpan(operationName);
span.setComponent(ComponentsDefine.MYBATIS);
Tags.MYBATIS_MAPPER.set(span, (String) allArguments[0]);
}
@Override
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
Object ret) throws Throwable {
String operationName = MethodUtil.generateOperationName(method);
if (String.valueOf(ContextManager.getRuntimeContext().get(MYBATIS_ENTRY_METHOD_NAME)).equals(operationName)) {
ContextManager.getRuntimeContext().remove(MYBATIS_ENTRY_METHOD_NAME);
ContextManager.stopSpan();
}
ContextManager.stopSpan();
return ret;
}
@Override
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
String operationName = MethodUtil.generateOperationName(method);
if (String.valueOf(ContextManager.getRuntimeContext().get(MYBATIS_ENTRY_METHOD_NAME)).equals(operationName)) {
ContextManager.activeSpan().log(t);
}
ContextManager.activeSpan().log(t);
}
}
......@@ -22,16 +22,25 @@ import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
public enum MyBatisMethodMatch {
INSTANCE;
public ElementMatcher<MethodDescription> getMyBatisMethodMatcher() {
return named("selectOne").or(named("selectList"))
.or(named("selectMap"))
.or(named("select"))
return named("select").and(takesArguments(4))
.or(named("selectList").and(takesArguments(3)))
.or(named("update").and(takesArguments(2)));
}
public ElementMatcher<MethodDescription> getMyBatisShellMethodMatcher() {
return named("selectOne").or(named("selectMap"))
.or(named("insert"))
.or(named("update"))
.or(named("delete"));
.or(named("delete"))
.or(named("select").and(takesArguments(2)))
.or(named("select").and(takesArguments(3)))
.or(named("selectList").and(takesArguments(1)))
.or(named("selectList").and(takesArguments(2)))
.or(named("update").and(takesArguments(1)));
}
}
/*
* 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.mybatis;
import java.lang.reflect.Method;
import org.apache.skywalking.apm.agent.core.context.ContextManager;
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.util.MethodUtil;
public class MyBatisShellMethodInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
if (ContextManager.getRuntimeContext().get(Constants.MYBATIS_SHELL_METHOD_NAME) == null) {
String operationName = MethodUtil.generateOperationName(method);
ContextManager.getRuntimeContext().put(Constants.MYBATIS_SHELL_METHOD_NAME, operationName);
}
}
@Override
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
Object ret) throws Throwable {
return ret;
}
@Override
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
}
}
......@@ -46,7 +46,7 @@ public class MyBatisInstrumentation extends ClassInstanceMethodsEnhancePluginDef
@Override
public String getMethodsInterceptor() {
return "org.apache.skywalking.apm.plugin.mybatis.SqlSessionOperationInterceptor";
return "org.apache.skywalking.apm.plugin.mybatis.MyBatisInterceptor";
}
@Override
......
......@@ -28,7 +28,7 @@ import org.apache.skywalking.apm.plugin.mybatis.MyBatisMethodMatch;
import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
public class MyBatisSpringInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
public class MyBatisShellMethodInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
@Override
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
......@@ -41,12 +41,12 @@ public class MyBatisSpringInstrumentation extends ClassInstanceMethodsEnhancePlu
new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
return MyBatisMethodMatch.INSTANCE.getMyBatisMethodMatcher();
return MyBatisMethodMatch.INSTANCE.getMyBatisShellMethodMatcher();
}
@Override
public String getMethodsInterceptor() {
return "org.apache.skywalking.apm.plugin.mybatis.SqlSessionOperationInterceptor";
return "org.apache.skywalking.apm.plugin.mybatis.MyBatisShellMethodInterceptor";
}
@Override
......@@ -59,6 +59,6 @@ public class MyBatisSpringInstrumentation extends ClassInstanceMethodsEnhancePlu
@Override
public ClassMatch enhanceClass() {
return byName("org.mybatis.spring.SqlSessionTemplate");
return byName("org.apache.ibatis.session.defaults.DefaultSqlSession");
}
}
......@@ -15,4 +15,4 @@
# limitations under the License.
mybatis-3.x=org.apache.skywalking.apm.plugin.mybatis.define.MyBatisInstrumentation
mybatis-3.x=org.apache.skywalking.apm.plugin.mybatis.define.MyBatisSpringInstrumentation
\ No newline at end of file
mybatis-3.x=org.apache.skywalking.apm.plugin.mybatis.define.MyBatisShellMethodInstrumentation
\ No newline at end of file
......@@ -35,23 +35,7 @@ segmentItems:
- {key: db.type, value: sql}
- {key: db.instance, value: ''}
- {key: db.statement, value: 'insert into test.table_demo (name) values (?)'}
- operationName: Mysql/JDBI/Connection/close
operationId: 0
parentSpanId: 1
spanId: 3
spanLayer: Database
startTime: not null
endTime: not null
componentId: 33
isError: false
spanType: Exit
peer: mysql:3306
skipAnalysis: 'false'
tags:
- {key: db.type, value: sql}
- {key: db.instance, value: ''}
- {key: db.statement, value: ''}
- operationName: org.mybatis.spring.SqlSessionTemplate.insert(java.lang.String,java.lang.Object)
- operationName: org.apache.ibatis.session.defaults.DefaultSqlSession.insert(java.lang.String,java.lang.Object)
operationId: 0
parentSpanId: 0
spanId: 1
......@@ -65,10 +49,10 @@ segmentItems:
skipAnalysis: 'false'
tags:
- {key: mybatis.mapper, value: test.apache.skywalking.apm.testcase.mybatis.mapper.DemoMapper.insert}
- operationName: Mysql/JDBI/PreparedStatement/execute
- operationName: Mysql/JDBI/Connection/close
operationId: 0
parentSpanId: 4
spanId: 5
parentSpanId: 0
spanId: 3
spanLayer: Database
startTime: not null
endTime: not null
......@@ -78,13 +62,13 @@ segmentItems:
peer: mysql:3306
skipAnalysis: 'false'
tags:
- {key: db.type, value: sql}
- {key: db.instance, value: ''}
- {key: db.statement, value: 'insert into test.table_demo (name) values (?)'}
- operationName: Mysql/JDBI/Connection/close
- {key: db.type, value: sql}
- {key: db.instance, value: ''}
- {key: db.statement, value: ''}
- operationName: Mysql/JDBI/PreparedStatement/execute
operationId: 0
parentSpanId: 4
spanId: 6
spanId: 5
spanLayer: Database
startTime: not null
endTime: not null
......@@ -96,8 +80,8 @@ segmentItems:
tags:
- {key: db.type, value: sql}
- {key: db.instance, value: ''}
- {key: db.statement, value: ''}
- operationName: org.mybatis.spring.SqlSessionTemplate.insert(java.lang.String,java.lang.Object)
- {key: db.statement, value: 'insert into test.table_demo (name) values (?)'}
- operationName: org.apache.ibatis.session.defaults.DefaultSqlSession.insert(java.lang.String,java.lang.Object)
operationId: 0
parentSpanId: 0
spanId: 4
......@@ -111,6 +95,22 @@ segmentItems:
skipAnalysis: 'false'
tags:
- {key: mybatis.mapper, value: test.apache.skywalking.apm.testcase.mybatis.mapper.DemoMapper.insert}
- operationName: Mysql/JDBI/Connection/close
operationId: 0
parentSpanId: 0
spanId: 6
spanLayer: Database
startTime: not null
endTime: not null
componentId: 33
isError: false
spanType: Exit
peer: mysql:3306
skipAnalysis: 'false'
tags:
- {key: db.type, value: sql}
- {key: db.instance, value: ''}
- {key: db.statement, value: ''}
- operationName: /case/mybatis-case
operationId: 0
parentSpanId: -1
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册