本文主要研究一下skywalking的lettuce-plugin
skywalking-6.6.0/apm-sniffer/optional-plugins/lettuce-5.x-plugin/src/main/resources/skywalking-plugin.def
lettuce-5.x=org.apache.skywalking.apm.plugin.lettuce.v5.define.AbstractRedisClientInstrumentation lettuce-5.x=org.apache.skywalking.apm.plugin.lettuce.v5.define.AsyncCommandInstrumentation lettuce-5.x=org.apache.skywalking.apm.plugin.lettuce.v5.define.ClientOptionsInstrumentation lettuce-5.x=org.apache.skywalking.apm.plugin.lettuce.v5.define.RedisChannelWriterInstrumentation lettuce-5.x=org.apache.skywalking.apm.plugin.lettuce.v5.define.RedisClientInstrumentation lettuce-5.x=org.apache.skywalking.apm.plugin.lettuce.v5.define.RedisClusterClientInstrumentation
skywalking-6.6.0/apm-sniffer/optional-plugins/lettuce-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/lettuce/v5/define/AbstractRedisClientInstrumentation.java
public class AbstractRedisClientInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { private static final String ENHANCE_CLASS = "io.lettuce.core.AbstractRedisClient"; private static final String ABSTRACT_REDIS_CLIENT_CONSTRUCTOR_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.lettuce.v5.AbstractRedisClientInterceptor"; @Override public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { return new ConstructorInterceptPoint[0]; } @Override public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { return new InstanceMethodsInterceptPoint[] { new InstanceMethodsInterceptPoint() { @Override public ElementMatcher<MethodDescription> getMethodsMatcher() { return named("setOptions").and(takesArgumentWithType(0, "io.lettuce.core.ClientOptions")); } @Override public String getMethodsInterceptor() { return ABSTRACT_REDIS_CLIENT_CONSTRUCTOR_INTERCEPTOR_CLASS; } @Override public boolean isOverrideArgs() { return false; } } }; } @Override public ClassMatch enhanceClass() { return byName(ENHANCE_CLASS); } }
skywalking-6.6.0/apm-sniffer/optional-plugins/lettuce-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/lettuce/v5/AbstractRedisClientInterceptor.java
public class AbstractRedisClientInterceptor implements InstanceMethodsAroundInterceptor { @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable { EnhancedInstance clientOptions = (EnhancedInstance) allArguments[0]; if (clientOptions == null) { return; } AbstractRedisClient client = (AbstractRedisClient) objInst; if (client.getOptions() == null || ((EnhancedInstance) client.getOptions()).getSkyWalkingDynamicField() == null) { return; } clientOptions.setSkyWalkingDynamicField(((EnhancedInstance) client.getOptions()).getSkyWalkingDynamicField()); } @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) { } }
skywalking-6.6.0/apm-sniffer/optional-plugins/lettuce-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/lettuce/v5/define/AsyncCommandInstrumentation.java
public class AsyncCommandInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { private static final String ENHANCE_CLASS = "io.lettuce.core.protocol.AsyncCommand"; private static final String ASYNC_COMMAND_METHOD_INTERCEPTOR = "org.apache.skywalking.apm.plugin.lettuce.v5.AsyncCommandMethodInterceptor"; @Override public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { return new ConstructorInterceptPoint[0]; } @Override public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { return new InstanceMethodsInterceptPoint[]{ new InstanceMethodsInterceptPoint() { @Override public ElementMatcher<MethodDescription> getMethodsMatcher() { return (named("onComplete").and(takesArgumentWithType(0,"java.util.function.Consumer"))) .or(named("onComplete").and(takesArgumentWithType(0,"java.util.function.BiConsumer"))); } @Override public String getMethodsInterceptor() { return ASYNC_COMMAND_METHOD_INTERCEPTOR; } @Override public boolean isOverrideArgs() { return true; } } }; } @Override public ClassMatch enhanceClass() { return byName(ENHANCE_CLASS); } }
skywalking-6.6.0/apm-sniffer/optional-plugins/lettuce-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/lettuce/v5/AsyncCommandMethodInterceptor.java
public class AsyncCommandMethodInterceptor implements InstanceMethodsAroundInterceptor { @Override @SuppressWarnings("unchecked") public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable { AsyncCommand asyncCommand = (AsyncCommand) objInst; String operationName = "Lettuce/" + asyncCommand.getType().name(); AbstractSpan span = ContextManager.createLocalSpan(operationName + "/onComplete"); span.setComponent(ComponentsDefine.LETTUCE); if (allArguments[0] instanceof Consumer) { allArguments[0] = new SWConsumer((Consumer) allArguments[0], ContextManager.capture(), operationName); } else { allArguments[0] = new SWBiConsumer((BiConsumer) allArguments[0], ContextManager.capture(), operationName); } } @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) { ContextManager.activeSpan().errorOccurred().log(t); } }
skywalking-6.6.0/apm-sniffer/optional-plugins/lettuce-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/lettuce/v5/define/ClientOptionsInstrumentation.java
public class ClientOptionsInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { private static final String ENHANCE_CLASS = "io.lettuce.core.ClientOptions"; private static final String CLIENT_OPTIONS_CONSTRUCTOR_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.lettuce.v5.ClientOptionsConstructorInterceptor"; @Override public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { return new ConstructorInterceptPoint[]{ new ConstructorInterceptPoint() { @Override public ElementMatcher<MethodDescription> getConstructorMatcher() { return any(); } @Override public String getConstructorInterceptor() { return CLIENT_OPTIONS_CONSTRUCTOR_INTERCEPTOR_CLASS; } } }; } @Override public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { return new InstanceMethodsInterceptPoint[0]; } @Override public ClassMatch enhanceClass() { return byName(ENHANCE_CLASS); } }
skywalking-6.6.0/apm-sniffer/optional-plugins/lettuce-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/lettuce/v5/ClientOptionsConstructorInterceptor.java
public class ClientOptionsConstructorInterceptor implements InstanceConstructorInterceptor { @Override public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { } }
skywalking-6.6.0/apm-sniffer/optional-plugins/lettuce-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/lettuce/v5/define/RedisChannelWriterInstrumentation.java
public class RedisChannelWriterInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { private static final String ENHANCE_CLASS = "io.lettuce.core.protocol.DefaultEndpoint"; private static final String REDIS_CHANNEL_WRITER_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.lettuce.v5.RedisChannelWriterInterceptor"; @Override public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { return new ConstructorInterceptPoint[] { new ConstructorInterceptPoint() { @Override public ElementMatcher<MethodDescription> getConstructorMatcher() { return takesArgumentWithType(0, "io.lettuce.core.ClientOptions"); } @Override public String getConstructorInterceptor() { return REDIS_CHANNEL_WRITER_INTERCEPTOR_CLASS; } } }; } @Override public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { return new InstanceMethodsInterceptPoint[]{ new InstanceMethodsInterceptPoint() { @Override public ElementMatcher<MethodDescription> getMethodsMatcher() { return named("writeToChannelAndFlush").or(named("writeAndFlush")); } @Override public String getMethodsInterceptor() { return REDIS_CHANNEL_WRITER_INTERCEPTOR_CLASS; } @Override public boolean isOverrideArgs() { return false; } } }; } @Override public ClassMatch enhanceClass() { return byName(ENHANCE_CLASS); } }
skywalking-6.6.0/apm-sniffer/optional-plugins/lettuce-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/lettuce/v5/RedisChannelWriterInterceptor.java
public class RedisChannelWriterInterceptor implements InstanceMethodsAroundInterceptor, InstanceConstructorInterceptor { @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable { String peer = (String) objInst.getSkyWalkingDynamicField(); StringBuilder dbStatement = new StringBuilder(); String operationName = "Lettuce/"; if (allArguments[0] instanceof RedisCommand) { RedisCommand redisCommand = (RedisCommand) allArguments[0]; String command = redisCommand.getType().name(); operationName = operationName + command; dbStatement.append(command); } else if (allArguments[0] instanceof Collection) { @SuppressWarnings("unchecked") Collection<RedisCommand> redisCommands = (Collection<RedisCommand>) allArguments[0]; operationName = operationName + "BATCH_WRITE"; for (RedisCommand redisCommand : redisCommands) { dbStatement.append(redisCommand.getType().name()).append(";"); } } AbstractSpan span = ContextManager.createExitSpan(operationName, peer); span.setComponent(ComponentsDefine.LETTUCE); Tags.DB_TYPE.set(span, "Redis"); Tags.DB_STATEMENT.set(span, dbStatement.toString()); SpanLayer.asCache(span); } @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); } @Override public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { EnhancedInstance optionsInst = (EnhancedInstance) allArguments[0]; objInst.setSkyWalkingDynamicField(optionsInst.getSkyWalkingDynamicField()); } }
skywalking-6.6.0/apm-sniffer/optional-plugins/lettuce-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/lettuce/v5/define/RedisClientInstrumentation.java
public class RedisClientInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { private static final String ENHANCE_CLASS = "io.lettuce.core.RedisClient"; private static final String REDIS_CLIENT_CONSTRUCTOR_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.lettuce.v5.RedisClientConstructorInterceptor"; @Override public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { return new ConstructorInterceptPoint[]{ new ConstructorInterceptPoint() { @Override public ElementMatcher<MethodDescription> getConstructorMatcher() { return takesArgumentWithType(1, "io.lettuce.core.RedisURI"); } @Override public String getConstructorInterceptor() { return REDIS_CLIENT_CONSTRUCTOR_INTERCEPTOR_CLASS; } } }; } @Override public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { return new InstanceMethodsInterceptPoint[0]; } @Override public ClassMatch enhanceClass() { return byName(ENHANCE_CLASS); } }
skywalking-6.6.0/apm-sniffer/optional-plugins/lettuce-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/lettuce/v5/RedisClientConstructorInterceptor.java
public class RedisClientConstructorInterceptor implements InstanceConstructorInterceptor { @Override public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { RedisURI redisURI = (RedisURI) allArguments[1]; RedisClient redisClient = (RedisClient) objInst; EnhancedInstance optionsInst = (EnhancedInstance) redisClient.getOptions(); optionsInst.setSkyWalkingDynamicField(redisURI.getHost() + ":" + redisURI.getPort()); } }
skywalking-6.6.0/apm-sniffer/optional-plugins/lettuce-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/lettuce/v5/define/RedisClusterClientInstrumentation.java
public class RedisClusterClientInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { private static final String ENHANCE_CLASS = "io.lettuce.core.cluster.RedisClusterClient"; private static final String REDIS_CLUSTER_CLIENT_CONSTRUCTOR_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.lettuce.v5.RedisClusterClientConstructorInterceptor"; @Override public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { return new ConstructorInterceptPoint[]{ new ConstructorInterceptPoint() { @Override public ElementMatcher<MethodDescription> getConstructorMatcher() { return takesArgumentWithType(1, "java.lang.Iterable"); } @Override public String getConstructorInterceptor() { return REDIS_CLUSTER_CLIENT_CONSTRUCTOR_INTERCEPTOR_CLASS; } } }; } @Override public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { return new InstanceMethodsInterceptPoint[0]; } @Override public ClassMatch enhanceClass() { return byName(ENHANCE_CLASS); } }
skywalking-6.6.0/apm-sniffer/optional-plugins/lettuce-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/lettuce/v5/RedisClusterClientConstructorInterceptor.java
public class RedisClusterClientConstructorInterceptor implements InstanceConstructorInterceptor { @Override public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { @SuppressWarnings("unchecked") Iterable<RedisURI> redisURIs = (Iterable<RedisURI>) allArguments[1]; RedisClusterClient redisClusterClient = (RedisClusterClient) objInst; StringBuilder peer = new StringBuilder(); for (RedisURI redisURI : redisURIs) { peer.append(redisURI.getHost()).append(":").append(redisURI.getPort()).append(";"); } EnhancedInstance optionsInst = (EnhancedInstance) redisClusterClient.getOptions(); optionsInst.setSkyWalkingDynamicField(PeerFormat.shorten(peer.toString())); } }
skywalking的lettuce-plugin提供了AbstractRedisClientInstrumentation、AsyncCommandInstrumentation、ClientOptionsInstrumentation、RedisChannelWriterInstrumentation、RedisClientInstrumentation、RedisClusterClientInstrumentation增强