聊聊skywalking的jedispulgin

编程

skywalking-plugin.def

skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/resources/skywalking-plugin.def

jedis-2.x=org.apache.skywalking.apm.plugin.jedis.v2.define.JedisClusterInstrumentation

jedis-2.x=org.apache.skywalking.apm.plugin.jedis.v2.define.JedisInstrumentation

  • skywalking的jedis-pulgin提供了JedisClusterInstrumentation及JedisInstrumentation两个增强

JedisClusterInstrumentation

skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v2/define/JedisClusterInstrumentation.java

public class JedisClusterInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {

private static final String ARGUMENT_TYPE_NAME = "redis.clients.jedis.HostAndPort";

private static final String ENHANCE_CLASS = "redis.clients.jedis.JedisCluster";

private static final String CONSTRUCTOR_WITH_LIST_HOSTANDPORT_ARG_INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.jedis.v2.JedisClusterConstructorWithListHostAndPortArgInterceptor";

private static final String METHOD_INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.jedis.v2.JedisMethodInterceptor";

private static final String CONSTRUCTOR_WITH_HOSTANDPORT_ARG_INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.jedis.v2.JedisClusterConstructorWithHostAndPortArgInterceptor";

@Override

public ClassMatch enhanceClass() {

return byName(ENHANCE_CLASS);

}

@Override

public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {

return new ConstructorInterceptPoint[] {

new ConstructorInterceptPoint() {

@Override

public ElementMatcher<MethodDescription> getConstructorMatcher() {

return takesArgument(0, Set.class);

}

@Override

public String getConstructorInterceptor() {

return CONSTRUCTOR_WITH_LIST_HOSTANDPORT_ARG_INTERCEPT_CLASS;

}

},

new ConstructorInterceptPoint() {

@Override

public ElementMatcher<MethodDescription> getConstructorMatcher() {

return takesArgumentWithType(0, ARGUMENT_TYPE_NAME);

}

@Override

public String getConstructorInterceptor() {

return CONSTRUCTOR_WITH_HOSTANDPORT_ARG_INTERCEPT_CLASS;

}

}

};

}

@Override

public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {

return new InstanceMethodsInterceptPoint[] {

new InstanceMethodsInterceptPoint() {

@Override

public ElementMatcher<MethodDescription> getMethodsMatcher() {

return RedisMethodMatch.INSTANCE.getJedisClusterMethodMatcher();

}

@Override

public String getMethodsInterceptor() {

return METHOD_INTERCEPT_CLASS;

}

@Override public boolean isOverrideArgs() {

return false;

}

}

};

}

}

  • JedisClusterInstrumentation继承了ClassInstanceMethodsEnhancePluginDefine,它增强的是redis.clients.jedis.JedisCluster类;它使用org.apache.skywalking.apm.plugin.jedis.v2.JedisClusterConstructorWithListHostAndPortArgInterceptor增强其第一个参数类型为Set的构造方法;它使用org.apache.skywalking.apm.plugin.jedis.v2.JedisClusterConstructorWithHostAndPortArgInterceptor增强第一个参数类型为redis.clients.jedis.HostAndPort的构造方法;它使用org.apache.skywalking.apm.plugin.jedis.v2.JedisMethodInterceptor增强了RedisMethodMatch.INSTANCE.getJedisClusterMethodMatcher()匹配的方法

JedisClusterConstructorWithListHostAndPortArgInterceptor

skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v2/JedisClusterConstructorWithListHostAndPortArgInterceptor.java

public class JedisClusterConstructorWithListHostAndPortArgInterceptor implements InstanceConstructorInterceptor {

@Override

public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {

StringBuilder redisConnInfo = new StringBuilder();

Set<HostAndPort> hostAndPorts = (Set<HostAndPort>)allArguments[0];

for (HostAndPort hostAndPort : hostAndPorts) {

redisConnInfo.append(hostAndPort.toString()).append(";");

}

objInst.setSkyWalkingDynamicField(PeerFormat.shorten(redisConnInfo.toString()));

}

}

  • JedisClusterConstructorWithListHostAndPortArgInterceptor实现了InstanceConstructorInterceptor接口,其onConstruct取出hostAndPorts信息然后设置到objInst的skyWalkingDynamicField

JedisClusterConstructorWithHostAndPortArgInterceptor

skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v2/JedisClusterConstructorWithHostAndPortArgInterceptor.java

public class JedisClusterConstructorWithHostAndPortArgInterceptor implements InstanceConstructorInterceptor {

@Override

public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {

HostAndPort hostAndPort = (HostAndPort)allArguments[0];

objInst.setSkyWalkingDynamicField(hostAndPort.getHost() + ":" + hostAndPort.getPort());

}

}

  • JedisClusterConstructorWithHostAndPortArgInterceptor实现了InstanceConstructorInterceptor接口,其onConstruct方法获取hostAndPort信息然后设置到objInst的skyWalkingDynamicField

JedisMethodInterceptor

skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v2/JedisMethodInterceptor.java

public class JedisMethodInterceptor implements InstanceMethodsAroundInterceptor {

@Override

public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,

Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {

String peer = String.valueOf(objInst.getSkyWalkingDynamicField());

AbstractSpan span = ContextManager.createExitSpan("Jedis/" + method.getName(), peer);

span.setComponent(ComponentsDefine.JEDIS);

Tags.DB_TYPE.set(span, "Redis");

SpanLayer.asCache(span);

if (allArguments.length > 0 && allArguments[0] instanceof String) {

Tags.DB_STATEMENT.set(span, method.getName() + " " + allArguments[0]);

} else if (allArguments.length > 0 && allArguments[0] instanceof byte[]) {

Tags.DB_STATEMENT.set(span, method.getName());

}

}

@Override

public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,

Class<?>[] argumentsTypes, Object ret) throws Throwable {

ContextManager.stopSpan();

return ret;

}

@Override

public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,

Class<?>[] argumentsTypes, Throwable t) {

AbstractSpan span = ContextManager.activeSpan();

span.errorOccurred();

span.log(t);

}

}

  • JedisMethodInterceptor实现了InstanceMethodsAroundInterceptor接口,其beforeMethod方法获取peer信息设置DB_TYPE、DB_STATEMENT信息;其afterMethod方法执行ContextManager.stopSpan();其handleMethodException方法执行span.errorOccurred()以及span.log(t)

JedisInstrumentation

skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v2/define/JedisInstrumentation.java

public class JedisInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {

private static final String HOST_AND_PORT_ARG_TYPE_NAME = "redis.clients.jedis.HostAndPort";

private static final String JEDIS_SHARD_INFO_ARG_TYPE_NAME = "redis.clients.jedis.JedisShardInfo";

private static final String ENHANCE_CLASS = "redis.clients.jedis.Jedis";

private static final String CONSTRUCTOR_WITH_STRING_ARG_INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.jedis.v2.JedisConstructorWithStringArgInterceptor";

private static final String CONSTRUCTOR_WITH_SHARD_INFO_ARG_INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.jedis.v2.JedisConstructorWithShardInfoArgInterceptor";

private static final String CONSTRUCTOR_WITH_HOST_AND_PORT_INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.jedis.v2.JedisClusterConstructorWithHostAndPortArgInterceptor";

private static final String CONSTRUCTOR_WITH_URI_ARG_INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.jedis.v2.JedisConstructorWithUriArgInterceptor";

private static final String JEDIS_METHOD_INTERCET_CLASS = "org.apache.skywalking.apm.plugin.jedis.v2.JedisMethodInterceptor";

@Override

public ClassMatch enhanceClass() {

return byName(ENHANCE_CLASS);

}

@Override

public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {

return new ConstructorInterceptPoint[] {

new ConstructorInterceptPoint() {

@Override

public ElementMatcher<MethodDescription> getConstructorMatcher() {

return takesArgument(0, String.class);

}

@Override

public String getConstructorInterceptor() {

return CONSTRUCTOR_WITH_STRING_ARG_INTERCEPT_CLASS;

}

},

new ConstructorInterceptPoint() {

@Override

public ElementMatcher<MethodDescription> getConstructorMatcher() {

return takesArgumentWithType(0, HOST_AND_PORT_ARG_TYPE_NAME);

}

@Override

public String getConstructorInterceptor() {

return CONSTRUCTOR_WITH_HOST_AND_PORT_INTERCEPT_CLASS;

}

},

new ConstructorInterceptPoint() {

@Override

public ElementMatcher<MethodDescription> getConstructorMatcher() {

return takesArgumentWithType(0, JEDIS_SHARD_INFO_ARG_TYPE_NAME);

}

@Override

public String getConstructorInterceptor() {

return CONSTRUCTOR_WITH_SHARD_INFO_ARG_INTERCEPT_CLASS;

}

},

new ConstructorInterceptPoint() {

@Override

public ElementMatcher<MethodDescription> getConstructorMatcher() {

return takesArgument(0, URI.class);

}

@Override

public String getConstructorInterceptor() {

return CONSTRUCTOR_WITH_URI_ARG_INTERCEPT_CLASS;

}

}

};

}

@Override

public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {

return new InstanceMethodsInterceptPoint[] {

new InstanceMethodsInterceptPoint() {

@Override

public ElementMatcher<MethodDescription> getMethodsMatcher() {

return RedisMethodMatch.INSTANCE.getJedisMethodMatcher();

}

@Override

public String getMethodsInterceptor() {

return JEDIS_METHOD_INTERCET_CLASS;

}

@Override public boolean isOverrideArgs() {

return false;

}

}

};

}

}

  • JedisInstrumentation继承了ClassInstanceMethodsEnhancePluginDefine,它增强的是redis.clients.jedis.Jedis类;它使用org.apache.skywalking.apm.plugin.jedis.v2.JedisConstructorWithStringArgInterceptor增强其第一个参数类型为String的构造器;它使用org.apache.skywalking.apm.plugin.jedis.v2.JedisClusterConstructorWithHostAndPortArgInterceptor增强第一个参数类型为redis.clients.jedis.HostAndPort的构造器;它使用org.apache.skywalking.apm.plugin.jedis.v2.JedisConstructorWithShardInfoArgInterceptor增强第一个参数类型为redis.clients.jedis.JedisShardInfo的构造器;它使用org.apache.skywalking.apm.plugin.jedis.v2.JedisConstructorWithUriArgInterceptor增强第一个参数类型为URI的构造器;它使用org.apache.skywalking.apm.plugin.jedis.v2.JedisMethodInterceptor增强RedisMethodMatch.INSTANCE.getJedisMethodMatcher()匹配的方法

JedisConstructorWithStringArgInterceptor

skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v2/JedisConstructorWithStringArgInterceptor.java

public class JedisConstructorWithStringArgInterceptor implements InstanceConstructorInterceptor {

@Override

public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {

String host = (String)allArguments[0];

String port = "6379";

if (allArguments.length > 1) {

port = String.valueOf(allArguments[1]);

}

objInst.setSkyWalkingDynamicField(host + ":" + port);

}

}

  • JedisConstructorWithStringArgInterceptor实现了InstanceConstructorInterceptor接口,其onConstruct获取port信息并设置到objInst的skyWalkingDynamicField

JedisConstructorWithShardInfoArgInterceptor

skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v2/JedisConstructorWithShardInfoArgInterceptor.java

public class JedisConstructorWithShardInfoArgInterceptor implements InstanceConstructorInterceptor {

@Override

public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {

String redisConnInfo;

JedisShardInfo shardInfo = (JedisShardInfo)allArguments[0];

redisConnInfo = shardInfo.getHost() + ":" + shardInfo.getPort();

objInst.setSkyWalkingDynamicField(redisConnInfo);

}

}

  • JedisConstructorWithShardInfoArgInterceptor实现了InstanceConstructorInterceptor接口,其onConstruct方法获取shardInfo信息并设置到objInst的skyWalkingDynamicField

JedisConstructorWithUriArgInterceptor

public class JedisConstructorWithUriArgInterceptor implements InstanceConstructorInterceptor {

@Override

public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {

URI uri = (URI)allArguments[0];

objInst.setSkyWalkingDynamicField(uri.getHost() + ":" + uri.getPort());

}

}

  • JedisConstructorWithUriArgInterceptor实现了InstanceConstructorInterceptor接口,其onConstruct方法获取uri信息并设置到objInst的skyWalkingDynamicField

JedisMethodInterceptor

skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v2/JedisMethodInterceptor.java

public class JedisMethodInterceptor implements InstanceMethodsAroundInterceptor {

@Override

public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,

Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {

String peer = String.valueOf(objInst.getSkyWalkingDynamicField());

AbstractSpan span = ContextManager.createExitSpan("Jedis/" + method.getName(), peer);

span.setComponent(ComponentsDefine.JEDIS);

Tags.DB_TYPE.set(span, "Redis");

SpanLayer.asCache(span);

if (allArguments.length > 0 && allArguments[0] instanceof String) {

Tags.DB_STATEMENT.set(span, method.getName() + " " + allArguments[0]);

} else if (allArguments.length > 0 && allArguments[0] instanceof byte[]) {

Tags.DB_STATEMENT.set(span, method.getName());

}

}

@Override

public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,

Class<?>[] argumentsTypes, Object ret) throws Throwable {

ContextManager.stopSpan();

return ret;

}

@Override

public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,

Class<?>[] argumentsTypes, Throwable t) {

AbstractSpan span = ContextManager.activeSpan();

span.errorOccurred();

span.log(t);

}

}

  • JedisMethodInterceptor实现了InstanceMethodsAroundInterceptor接口,其beforeMethod方法获取peer信息设置DB_TYPE、DB_STATEMENT;其afterMethod方法执行ContextManager.stopSpan()方法;其handleMethodException方法执行span.errorOccurred()及span.log(t)方法

RedisMethodMatch

skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v2/RedisMethodMatch.java

public enum RedisMethodMatch {

INSTANCE;

private ElementMatcher.Junction<MethodDescription> getIntersectionalMethodMacher() {

return named("zcount").or(named("sunionstore")).or(named("zunionstore"))

.or(named("del")).or(named("zinterstore")).or(named("echo"))

.or(named("hscan")).or(named("psubscribe")).or(named("type"))

.or(named("sinterstore")).or(named("setex")).or(named("zlexcount"))

.or(named("brpoplpush")).or(named("bitcount")).or(named("llen"))

.or(named("zscan")).or(named("lpushx")).or(named("bitpos"))

.or(named("setnx")).or(named("hvals")).or(named("evalsha"))

.or(named("substr")).or(named("geodist")).or(named("zrangeByLex"))

.or(named("geoadd")).or(named("expire")).or(named("bitop"))

.or(named("zrangeByScore")).or(named("smove")).or(named("lset"))

.or(named("decrBy")).or(named("pttl")).or(named("scan"))

.or(named("zrank")).or(named("blpop")).or(named("rpoplpush"))

.or(named("zremrangeByLex")).or(named("get")).or(named("lpop"))

.or(named("persist")).or(named("scriptExists")).or(named("georadius"))

.or(named("set")).or(named("srandmember")).or(named("incr")).or(named("setbit"))

.or(named("hexists")).or(named("expireAt")).or(named("pexpire")).or(named("zcard"))

.or(named("bitfield")).or(named("zrevrangeByLex")).or(named("sinter")).or(named("srem"))

.or(named("getrange")).or(named("rename")).or(named("zrevrank")).or(named("exists"))

.or(named("setrange")).or(named("zremrangeByRank")).or(named("sadd")).or(named("sdiff"))

.or(named("zrevrange")).or(named("getbit")).or(named("scard")).or(named("sdiffstore"))

.or(named("zrevrangeByScore")).or(named("zincrby")).or(named("rpushx")).or(named("psetex"))

.or(named("zrevrangeWithScores")).or(named("strlen")).or(named("hdel")).or(named("zremrangeByScore"))

.or(named("geohash")).or(named("brpop")).or(named("lrem")).or(named("hlen")).or(named("decr"))

.or(named("scriptLoad")).or(named("lpush")).or(named("lindex")).or(named("zrange")).or(named("incrBy"))

.or(named("getSet")).or(named("ltrim")).or(named("incrByFloat")).or(named("rpop")).or(named("sort"))

.or(named("zrevrangeByScoreWithScores")).or(named("pfadd")).or(named("eval")).or(named("linsert"))

.or(named("pfcount")).or(named("hkeys")).or(named("hsetnx")).or(named("hincrBy")).or(named("hgetAll"))

.or(named("hset")).or(named("spop")).or(named("zrangeWithScores")).or(named("hincrByFloat"))

.or(named("hmset")).or(named("renamenx")).or(named("zrem")).or(named("msetnx")).or(named("hmget"))

.or(named("sunion")).or(named("hget")).or(named("zadd")).or(named("move")).or(named("subscribe"))

.or(named("geopos")).or(named("mset")).or(named("zrangeByScoreWithScores")).or(named("zscore"))

.or(named("pexpireAt")).or(named("georadiusByMember")).or(named("ttl")).or(named("lrange"))

.or(named("smembers")).or(named("pfmerge")).or(named("rpush")).or(named("publish"))

.or(named("mget")).or(named("sscan")).or(named("append")).or(named("sismember"));

}

public ElementMatcher<MethodDescription> getJedisMethodMatcher() {

return getIntersectionalMethodMacher().or(named("sentinelMasters")).or(named("clusterReplicate")).or(named("readonly"))

.or(named("randomKey")).or(named("clusterInfo")).or(named("pubsubNumSub"))

.or(named("sentinelSlaves")).or(named("clusterSetSlotImporting")).or(named("clusterSlaves"))

.or(named("clusterFailover")).or(named("clusterSetSlotMigrating")).or(named("watch"))

.or(named("clientKill")).or(named("clusterKeySlot")).or(named("clusterCountKeysInSlot"))

.or(named("sentinelGetMasterAddrByName")).or(named("objectRefcount")).or(named("clusterMeet"))

.or(named("sentinelSet")).or(named("clusterSetSlotNode")).or(named("clusterAddSlots"))

.or(named("pubsubNumPat")).or(named("slowlogGet")).or(named("sentinelReset")).or(named("clusterNodes"))

.or(named("sentinelMonitor")).or(named("configGet")).or(named("objectIdletime"))

.or(named("pubsubChannels")).or(named("getParams")).or(named("sentinelRemove"))

.or(named("migrate")).or(named("clusterForget")).or(named("asking")).or(named("keys"))

.or(named("clientSetname")).or(named("clusterSaveConfig")).or(named("configSet"))

.or(named("dump")).or(named("clusterFlushSlots")).or(named("clusterGetKeysInSlot"))

.or(named("clusterReset")).or(named("restore")).or(named("clusterDelSlots"))

.or(named("sentinelFailover")).or(named("clusterSetSlotStable")).or(named("objectEncoding"));

}

public ElementMatcher<MethodDescription> getJedisClusterMethodMatcher() {

return getIntersectionalMethodMacher();

}

}

  • RedisMethodMatch的getIntersectionalMethodMacher主要是匹配redis相关命令对应的方法;getJedisMethodMatcher主要匹配cluster、sentinel相关命令

小结

skywalking的jedis-pulgin提供了JedisClusterInstrumentation及JedisInstrumentation两个增强

doc

  • JedisClusterInstrumentation
  • JedisInstrumentation

以上是 聊聊skywalking的jedispulgin 的全部内容, 来源链接: utcz.com/z/514376.html

回到顶部