-
Notifications
You must be signed in to change notification settings - Fork 6.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add [Agent] Jedis LETTUCE client plugin #832
Changes from 10 commits
975961f
ad93cf2
af7ca80
88f8c29
6050e88
0cbeb4c
f123435
79607a2
719cf46
f38c0d3
994b958
115f49a
0ab6ea5
955db87
1317a06
97e92eb
41223a1
b0b4bdc
6d3cd68
8f61418
1596b61
350ddc1
d411235
b4b1806
6dafc2e
49cd58f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<parent> | ||
<artifactId>apm-lettuce-plugin</artifactId> | ||
<groupId>org.apache.skywalking</groupId> | ||
<version>5.0.0-alpha-SNAPSHOT</version> | ||
</parent> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>lettuce-4.x-plugin</artifactId> | ||
<dependencies> | ||
<dependency> | ||
<groupId>biz.paluch.redis</groupId> | ||
<artifactId>lettuce</artifactId> | ||
<version>4.4.0.Final</version> | ||
<scope>provided</scope> | ||
</dependency> | ||
</dependencies> | ||
|
||
</project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/* | ||
* 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.lettuce.v4; | ||
|
||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; | ||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor; | ||
|
||
public class CommandHandlerInterceptor implements InstanceConstructorInterceptor { | ||
|
||
@Override | ||
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { | ||
|
||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
* 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.lettuce.v4; | ||
|
||
import com.lambdaworks.redis.RedisURI; | ||
import java.lang.reflect.Method; | ||
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.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; | ||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; | ||
|
||
public class RedisClientInterceptor implements InstanceMethodsAroundInterceptor, InstanceConstructorInterceptor { | ||
|
||
@Override | ||
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { | ||
RedisURI redisURI = (RedisURI)allArguments[1]; | ||
String peer = redisURI.getHost() + ":" + redisURI.getPort(); | ||
objInst.setSkyWalkingDynamicField(peer); | ||
} | ||
|
||
@Override | ||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, | ||
MethodInterceptResult result) throws Throwable { | ||
String peer = (String)objInst.getSkyWalkingDynamicField(); | ||
EnhancedInstance obj = (EnhancedInstance)allArguments[0]; | ||
obj.setSkyWalkingDynamicField(peer); | ||
} | ||
|
||
@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) { | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
* 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.lettuce.v4; | ||
|
||
import com.lambdaworks.redis.RedisURI; | ||
import java.lang.reflect.Method; | ||
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.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; | ||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; | ||
|
||
public class RedisClusterClientInterceptor implements InstanceMethodsAroundInterceptor, InstanceConstructorInterceptor { | ||
|
||
@Override | ||
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { | ||
Iterable<RedisURI> redisURI = (Iterable<RedisURI>)allArguments[1]; | ||
objInst.setSkyWalkingDynamicField(redisURI); | ||
} | ||
|
||
@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 { | ||
Iterable<RedisURI> redisURI = (Iterable<RedisURI>)objInst.getSkyWalkingDynamicField(); | ||
EnhancedInstance obj = (EnhancedInstance)ret; | ||
obj.setSkyWalkingDynamicField(redisURI); | ||
return obj; | ||
} | ||
|
||
@Override | ||
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, | ||
Class<?>[] argumentsTypes, Throwable t) { | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/* | ||
* 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.lettuce.v4; | ||
|
||
import com.lambdaworks.redis.RedisURI; | ||
import com.lambdaworks.redis.protocol.RedisCommand; | ||
import java.lang.reflect.Method; | ||
import org.apache.skywalking.apm.agent.core.context.ContextManager; | ||
import org.apache.skywalking.apm.agent.core.context.tag.Tags; | ||
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; | ||
import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer; | ||
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.network.trace.component.ComponentsDefine; | ||
|
||
public class StatefulRedisClusterConnectionImplInterceptor implements InstanceMethodsAroundInterceptor { | ||
|
||
@Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, | ||
Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable { | ||
RedisCommand command = (RedisCommand)allArguments[0]; | ||
String comandType = String.valueOf(command.getType()); | ||
if (!"AUTH".equals(comandType)) { | ||
Iterable<RedisURI> redisURIs = (Iterable<RedisURI>)objInst.getSkyWalkingDynamicField(); | ||
AbstractSpan span = ContextManager.createExitSpan("REDIS-Lettuce/" + comandType, redisURIs.toString()); | ||
span.setComponent(ComponentsDefine.REDIS); | ||
Tags.DB_TYPE.set(span, "Redis"); | ||
SpanLayer.asCache(span); | ||
Tags.DB_STATEMENT.set(span, command.getArgs().toString()); | ||
} | ||
} | ||
|
||
@Override | ||
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, | ||
Object ret) throws Throwable { | ||
RedisCommand command = (RedisCommand)allArguments[0]; | ||
if (null != command.getOutput().getError()) { | ||
AbstractSpan span = ContextManager.activeSpan(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It maybe cause exception if the command type equals There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
||
span.errorOccurred(); | ||
} | ||
ContextManager.stopSpan(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It maybe cause exception if the |
||
return ret; | ||
} | ||
|
||
@Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, | ||
Class<?>[] argumentsTypes, Throwable t) { | ||
AbstractSpan span = ContextManager.activeSpan(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this should also check the command type |
||
span.errorOccurred(); | ||
span.log(t); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
/* | ||
* 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.lettuce.v4; | ||
|
||
import com.lambdaworks.redis.protocol.RedisCommand; | ||
import java.lang.reflect.Method; | ||
import org.apache.skywalking.apm.agent.core.context.ContextManager; | ||
import org.apache.skywalking.apm.agent.core.context.tag.Tags; | ||
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; | ||
import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer; | ||
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.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; | ||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; | ||
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; | ||
|
||
public class StatefulRedisConnectionImplInterceptor implements InstanceMethodsAroundInterceptor, InstanceConstructorInterceptor { | ||
|
||
@Override | ||
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { | ||
EnhancedInstance commandHandler = (EnhancedInstance)allArguments[0]; | ||
String peer = (String)commandHandler.getSkyWalkingDynamicField(); | ||
objInst.setSkyWalkingDynamicField(peer); | ||
} | ||
|
||
@Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, | ||
Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable { | ||
RedisCommand command = (RedisCommand)allArguments[0]; | ||
String comandType = String.valueOf(command.getType()); | ||
if (checkIgnoreCommandType(comandType)) { | ||
String peer = String.valueOf(objInst.getSkyWalkingDynamicField()); | ||
AbstractSpan span = ContextManager.createExitSpan("REDIS-Lettuce/" + comandType, peer); | ||
span.setComponent(ComponentsDefine.REDIS); | ||
Tags.DB_TYPE.set(span, "Redis"); | ||
SpanLayer.asCache(span); | ||
Tags.DB_STATEMENT.set(span, command.getArgs().toString()); | ||
} | ||
} | ||
|
||
@Override | ||
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, | ||
Object ret) throws Throwable { | ||
RedisCommand command = (RedisCommand)allArguments[0]; | ||
if (null != command.getOutput().getError()) { | ||
AbstractSpan span = ContextManager.activeSpan(); | ||
span.errorOccurred(); | ||
} | ||
ContextManager.stopSpan(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It maybe cause exception if the command type is ignore command type, because of I saw that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Already updated There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cannot see any update |
||
return ret; | ||
} | ||
|
||
@Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, | ||
Class<?>[] argumentsTypes, Throwable t) { | ||
AbstractSpan span = ContextManager.activeSpan(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this should also check the command type |
||
span.errorOccurred(); | ||
span.log(t); | ||
} | ||
|
||
/** | ||
* Check the comandtype ,ignore "AUTH" "CLIENT" "CLUSTER" . | ||
*/ | ||
private Boolean checkIgnoreCommandType(String comandType) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method is make confuse. I suggest that the method name change to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
||
if ("AUTH".equals(comandType) || "CLIENT".equals(comandType) || "CLUSTER".equals(comandType)) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* | ||
* 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.lettuce.v4.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.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; | ||
|
||
/** | ||
* @author liyuntao | ||
*/ | ||
public class CommandHandlerInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { | ||
|
||
private static final String ENHANCE_CLASS = "com.lambdaworks.redis.protocol.CommandHandler"; | ||
private static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.lettuce.v4.CommandHandlerInterceptor"; | ||
|
||
@Override | ||
public ClassMatch enhanceClass() { | ||
return byName(ENHANCE_CLASS); | ||
} | ||
|
||
@Override | ||
protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { | ||
return new ConstructorInterceptPoint[] { | ||
new ConstructorInterceptPoint() { | ||
@Override | ||
public ElementMatcher<MethodDescription> getConstructorMatcher() { | ||
return any(); | ||
} | ||
|
||
@Override | ||
public String getConstructorInterceptor() { | ||
return INTERCEPT_CLASS; | ||
} | ||
} | ||
}; | ||
} | ||
|
||
@Override | ||
protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { | ||
return new InstanceMethodsInterceptPoint[0]; | ||
|
||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure what the value about
redisURIs.toString()
look like. Can you show me an example?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
redisURIs.toString()=[RedisURI [host='100.100.144.134', port=30001]]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not a typical peer. In traditional, the peer like
ip1:port1,ip2:port2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok