Skip to content
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

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
975961f
Add [Agent] Jedis LETTUCE client plugin
lytscu Feb 26, 2018
ad93cf2
Merge remote-tracking branch 'upstream/master' into jedis
lytscu Feb 27, 2018
af7ca80
Merge branch 'master' into jedis
lytscu Feb 27, 2018
88f8c29
Merge branch 'jedis' of https://github.com/lytscu/incubator-skywalkin…
lytscu Feb 27, 2018
6050e88
Update pom.xml
lytscu Feb 27, 2018
0cbeb4c
Update pom.xml 5.0.0-alpha-SNAPSHOT
lytscu Feb 27, 2018
f123435
Update comments (HttpClientInstrumentation.java)
lytscu Feb 27, 2018
79607a2
Merge branch 'master' into jedis
wu-sheng Feb 27, 2018
719cf46
Merge branch 'master' into jedis
lytscu Feb 27, 2018
f38c0d3
Merge branch 'master' into jedis
wu-sheng Feb 27, 2018
994b958
Update StatefulRedisClusterConnectionImplInterceptor.java
lytscu Feb 27, 2018
115f49a
Merge branch 'master' into jedis
lytscu Feb 27, 2018
0ab6ea5
Merge branch 'jedis' of https://github.com/lytscu/incubator-skywalkin…
lytscu Feb 27, 2018
955db87
Update peer
lytscu Feb 27, 2018
1317a06
Merge branch 'master' into jedis
wu-sheng Feb 28, 2018
97e92eb
Update afterMethod ignore CommandType
lytscu Feb 28, 2018
41223a1
Merge branch 'jedis' of https://github.com/lytscu/incubator-skywalkin…
lytscu Feb 28, 2018
b0b4bdc
Update handleMethodException
lytscu Feb 28, 2018
6d3cd68
Merge branch 'master' into jedis
lytscu Feb 28, 2018
8f61418
Merge branch 'master' into jedis
ascrutae Feb 28, 2018
1596b61
Update StatefulRedisConnectionImplInterceptorTest
lytscu Feb 28, 2018
350ddc1
Merge branch 'jedis' of https://github.com/lytscu/incubator-skywalkin…
lytscu Feb 28, 2018
d411235
Merge branch 'master' into jedis
ascrutae Feb 28, 2018
b4b1806
Merge branch 'master' into jedis
wu-sheng Mar 1, 2018
6dafc2e
Merge branch 'master' into jedis
lytscu Mar 1, 2018
49cd58f
Merge branch 'master' into jedis
lytscu Mar 5, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;

/**
* @author zhangxin
*/
public abstract class HttpClientInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {

private static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.httpClient.v4.HttpClientExecuteInterceptor";
Expand Down
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());
Copy link
Member

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?

Copy link
Contributor Author

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]]

Copy link
Member

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

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();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It maybe cause exception if the command type equals AUTH, because of I saw that StatefulRedisClusterConnectionImplInterceptor doesn't create span if the command type equals AUTH

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

span.errorOccurred();
}
ContextManager.stopSpan();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It maybe cause exception if the commandType equals AUTH, because of I saw that StatefulRedisClusterConnectionImplInterceptor doesn't create span if the commandType equals AUTH

return ret;
}

@Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
AbstractSpan span = ContextManager.activeSpan();
Copy link
Member

Choose a reason for hiding this comment

The 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();
Copy link
Member

@ascrutae ascrutae Feb 27, 2018

Choose a reason for hiding this comment

The 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 StatefulRedisClusterConnectionImplInterceptor doesn't create span if the command type is ignore command type

Copy link
Contributor Author

@lytscu lytscu Feb 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already updated

Copy link
Member

Choose a reason for hiding this comment

The 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();
Copy link
Member

Choose a reason for hiding this comment

The 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) {
Copy link
Member

Choose a reason for hiding this comment

The 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 checkIfNotIgnoreCommandType

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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];

}
}