From cf04b973db10e14352fdb9c51976c6654f41f637 Mon Sep 17 00:00:00 2001 From: jaehong-kim Date: Tue, 17 Oct 2017 11:26:36 +0900 Subject: [PATCH] [#3423] add redis cluster. --- .../pinpoint/common/trace/AnnotationKey.java | 2 + .../plugin/redis/CommandContextFormatter.java | 36 ---- .../plugin/redis/JedisMethodNameFilter.java | 58 ++++++ .../plugin/redis/JedisMethodNames.java | 190 ----------------- .../redis/JedisPipelineMethodNames.java | 44 ---- .../pinpoint/plugin/redis/RedisPlugin.java | 193 ++++++++++-------- .../plugin/redis/RedisPluginConfig.java | 32 +-- .../plugin/redis/RedisTypeProvider.java | 3 +- ...or.java => AttachEndPointInterceptor.java} | 22 +- .../JedisClientConstructorInterceptor.java | 81 -------- .../interceptor/JedisMethodInterceptor.java | 19 +- .../JedisPipelineConstructorInterceptor.java | 34 --- .../JedisPipelineMethodInterceptor.java | 97 --------- ...disPipelineSetClientMethodInterceptor.java | 33 --- ...olSendCommandAndReadMethodInterceptor.java | 3 +- ...eptor.java => SetEndPointInterceptor.java} | 19 +- .../service/TransactionInfoServiceImpl.java | 17 +- .../callstacks/AnnotationRecordFormatter.java | 10 +- .../web/vo/callstacks/RecordFactory.java | 62 +++++- .../web/vo/callstacks/RecordFactoryTest.java | 15 +- 20 files changed, 293 insertions(+), 677 deletions(-) delete mode 100644 plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/CommandContextFormatter.java create mode 100644 plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/JedisMethodNameFilter.java delete mode 100644 plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/JedisMethodNames.java delete mode 100644 plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/JedisPipelineMethodNames.java rename plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/{JedisClientMetadataAttchInterceptor.java => AttachEndPointInterceptor.java} (76%) delete mode 100644 plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisClientConstructorInterceptor.java delete mode 100644 plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisPipelineConstructorInterceptor.java delete mode 100644 plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisPipelineMethodInterceptor.java delete mode 100644 plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisPipelineSetClientMethodInterceptor.java rename plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/{JedisConstructorInterceptor.java => SetEndPointInterceptor.java} (86%) diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/trace/AnnotationKey.java b/commons/src/main/java/com/navercorp/pinpoint/common/trace/AnnotationKey.java index 451b08ba5444..342eb1c0206c 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/trace/AnnotationKey.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/trace/AnnotationKey.java @@ -85,6 +85,7 @@ * 200cxf.operation * 201cxf.args * 300PROXY_HTTP_HEADER + * 310REDIS.IO * 9000gson.json.length * 9001jackson.json.length * 9002json-lib.json.length @@ -195,4 +196,5 @@ public interface AnnotationKey { AnnotationKey ASYNC = AnnotationKeyFactory.of(-100, "Asynchronous Invocation", VIEW_IN_RECORD_SET); AnnotationKey PROXY_HTTP_HEADER = AnnotationKeyFactory.of(300, "PROXY_HTTP_HEADER", VIEW_IN_RECORD_SET); + AnnotationKey REDIS_IO = AnnotationKeyFactory.of(310, "redis.io"); } \ No newline at end of file diff --git a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/CommandContextFormatter.java b/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/CommandContextFormatter.java deleted file mode 100644 index dbb6dba9dff8..000000000000 --- a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/CommandContextFormatter.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2017 NAVER Corp. - * - * Licensed 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 com.navercorp.pinpoint.plugin.redis; - -/** - * @author Woonduk Kang(emeroad) - */ -public class CommandContextFormatter { - - public static String format(CommandContext commandContext) { - final StringBuilder sb = new StringBuilder(); - sb.append("write=").append(commandContext.getWriteElapsedTime()); - if (commandContext.isWriteFail()) { - sb.append("(fail)"); - } - sb.append(", read=").append(commandContext.getReadElapsedTime()); - if (commandContext.isReadFail()) { - sb.append("(fail)"); - } - return sb.toString(); - } -} diff --git a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/JedisMethodNameFilter.java b/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/JedisMethodNameFilter.java new file mode 100644 index 000000000000..a203b4cd7977 --- /dev/null +++ b/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/JedisMethodNameFilter.java @@ -0,0 +1,58 @@ +/* + * Copyright 2017 NAVER Corp. + * + * Licensed 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 com.navercorp.pinpoint.plugin.redis; + +import com.navercorp.pinpoint.bootstrap.instrument.InstrumentMethod; +import com.navercorp.pinpoint.bootstrap.instrument.MethodFilter; + +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * @author jaehong.kim + */ +public class JedisMethodNameFilter implements MethodFilter { + + private final Set excludeMethodNames = new HashSet(16); + + public JedisMethodNameFilter() { + // object methods. + this.excludeMethodNames.addAll(Arrays.asList("clone", "equals", "finalize", "getClass", "hashCode", "notify", "notifyAll", "toString", "wait")); + // unnecessary methods. + this.excludeMethodNames.addAll(Arrays.asList("ping", "close", "disconnect", "resetState", "getClient", "setClient", "getDB", "isInMulti", "isInWatch", "clear", "pipelined", "setPassword", "setDb", "setDataSource", "getClusterNodes", "getConnectionFromSlot")); + } + + @Override + public boolean accept(final InstrumentMethod method) { + if (method != null) { + final int modifiers = method.getModifiers(); + // only public. + if (!Modifier.isPublic(modifiers) || Modifier.isStatic(modifiers) || Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) { + return false; + } + + final String name = method.getName(); + // skip pinpoint and object methods. + if (!name.startsWith("_$PINPOINT$_") && !this.excludeMethodNames.contains(name)) { + return true; + } + } + return false; + } +} diff --git a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/JedisMethodNames.java b/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/JedisMethodNames.java deleted file mode 100644 index bd6b1b955e8b..000000000000 --- a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/JedisMethodNames.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright 2014 NAVER Corp. - * - * Licensed 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 com.navercorp.pinpoint.plugin.redis; - -/** - * Jedis method names - * - * @author jaehong.kim - * - */ -public class JedisMethodNames { - - public static String[] get() { - return new String[] { - "get", - "type", - "append", - "keys", - "set", - "exists", - "sort", - "rename", - "hvals", - "scan", - "hexists", - "hmget", - "hincrBy", - "del", - "randomKey", - "renamenx", - "expire", - "expireAt", - "move", - "ttl", - "mget", - "getSet", - "setnx", - "mset", - "setex", - "hlen", - "hkeys", - "hdel", - "zrangeWithScores", - "zrevrangeWithScores", - "zrangeByScoreWithScores", - "zrevrangeByScore", - "zrevrangeByScoreWithScores", - "zremrangeByRank", - "zremrangeByScore", - "objectRefcount", - "objectEncoding", - "objectIdletime", - "incrBy", - "decr", - "incr", - "decrBy", - "msetnx", - "hset", - "substr", - "hget", - "hsetnx", - "hmset", - "hgetAll", - "rpush", - "lpush", - "llen", - "lrange", - "ltrim", - "lindex", - "lset", - "lrem", - "lpop", - "rpop", - "rpoplpush", - "sadd", - "smembers", - "srem", - "spop", - "smove", - "scard", - "sismember", - "sinter", - "sinterstore", - "sunion", - "sunionstore", - "sdiff", - "sdiffstore", - "srandmember", - "zadd", - "zrange", - "zrem", - "zincrby", - "zrank", - "zrevrank", - "zrevrange", - "zcard", - "zscore", - "watch", - "blpop", - "brpop", - "zcount", - "zrangeByScore", - "zunionstore", - "zinterstore", - "strlen", - "lpushx", - "persist", - "rpushx", - "echo", - "linsert", - "brpoplpush", - "setbit", - "getbit", - "setrange", - "getrange", - "configGet", - "configSet", - "eval", - "subscribe", - "publish", - "psubscribe", - "evalsha", - "scriptExists", - "scriptLoad", - "slowlogGet", - "bitcount", - "bitop", - "dump", - "restore", - "pexpire", - "pexpireAt", - "pttl", - "incrByFloat", - "psetex", - "clientKill", - "clientSetname", - "migrate", - "hincrByFloat", - "hscan", - "sscan", - "zscan", - "shutdown", - "debug", - "save", - "sync", - "time", - "select", - "resetState", - "configResetStat", - "randomBinaryKey", - "monitor", - "unwatch", - "slowlogReset", - "slowlogLen", - "ping", - "quit", - "flushDB", - "dbSize", - "flushAll", - "auth", - "bgsave", - "bgrewriteaof", - "lastsave", - "slaveof", - "slaveofNoOne", - "getDB", - "multi", - "scriptFlush", - "scriptKill", - "clientGetname", - "clientList", - "slowlogGetBinary", - "info" - }; - } -} \ No newline at end of file diff --git a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/JedisPipelineMethodNames.java b/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/JedisPipelineMethodNames.java deleted file mode 100644 index cd3f8521d52b..000000000000 --- a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/JedisPipelineMethodNames.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2014 NAVER Corp. - * - * Licensed 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 com.navercorp.pinpoint.plugin.redis; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * JedisPipeline method names - * - jedis method names + pipeline method names - * - * @author jaehong.kim - * - */ -public class JedisPipelineMethodNames { - - public static String[] get() { - final String[] methodNames = { - "sync", - "syncAndReturnAll" - }; - - final List names = new ArrayList(); - names.addAll(Arrays.asList(JedisMethodNames.get())); - names.addAll(Arrays.asList(methodNames)); - - return names.toArray(new String[names.size()]); - } -} \ No newline at end of file diff --git a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/RedisPlugin.java b/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/RedisPlugin.java index 0708337ce345..a180a48cdc98 100644 --- a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/RedisPlugin.java +++ b/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/RedisPlugin.java @@ -35,36 +35,40 @@ import static com.navercorp.pinpoint.common.util.VarArgs.va; /** - * * @author jaehong.kim - * */ public class RedisPlugin implements ProfilerPlugin, TransformTemplateAware { private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + private final JedisMethodNameFilter methodNameFilter = new JedisMethodNameFilter(); private TransformTemplate transformTemplate; @Override public void setup(ProfilerPluginSetupContext context) { final RedisPluginConfig config = new RedisPluginConfig(context.getConfig()); + if (!config.isEnable()) { + if (logger.isInfoEnabled()) { + logger.info("Disable RedisPlugin. config={}", config); + } + return; + } if (logger.isInfoEnabled()) { - logger.info("RedisPlugin config:{}", config); + logger.info("Enable RedisPlugin. config={}", config); } - final boolean pipelineEnabled = config.isPipelineEnabled(); - - // jedis - addJedisClassEditors(config); - addProtocolClassEditor(); - if (pipelineEnabled) { + final boolean pipeline = config.isPipeline(); + // jedis & jedis cluster + addJedis(config); + addProtocol(); + if (pipeline) { // jedis pipeline - addJedisClientClassEditor(); - addJedisPipelineClassEditors(config); + addClient(); + addPipeline(config); } } // Jedis & BinaryJedis - private void addJedisClassEditors(RedisPluginConfig config) { - addJedisExtendedClassEditor(config, "redis.clients.jedis.BinaryJedis", new TransformHandler() { + private void addJedis(RedisPluginConfig config) { + addBinaryJedisExtends(config, "redis.clients.jedis.BinaryJedis", new TransformHandler() { @Override public void handle(InstrumentClass target) throws InstrumentException { @@ -73,53 +77,57 @@ public void handle(InstrumentClass target) throws InstrumentException { }); // Jedis extends BinaryJedis - addJedisExtendedClassEditor(config, "redis.clients.jedis.Jedis", null); + addBinaryJedisExtends(config, "redis.clients.jedis.Jedis", null); } - private void addJedisExtendedClassEditor(final RedisPluginConfig config, final String targetClassName, final TransformHandler handler) { - transformTemplate.transform(targetClassName, new TransformCallback() { + private void addBinaryJedisExtends(final RedisPluginConfig config, final String targetClassName, final TransformHandler handler) { + transformTemplate.transform(targetClassName, new TransformCallback() { @Override public byte[] doInTransform(Instrumentor instrumentor, ClassLoader classLoader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws InstrumentException { - InstrumentClass target = instrumentor.getInstrumentClass(classLoader, className, classfileBuffer); + final InstrumentClass target = instrumentor.getInstrumentClass(classLoader, className, classfileBuffer); if (handler != null) { handler.handle(target); } - final InstrumentMethod constructorEditorBuilderArg1 = target.getConstructor("java.lang.String"); - if (constructorEditorBuilderArg1 != null) { - constructorEditorBuilderArg1.addInterceptor("com.navercorp.pinpoint.plugin.redis.interceptor.JedisConstructorInterceptor"); - } - - final InstrumentMethod constructorEditorBuilderArg2 = target.getConstructor("java.lang.String", "int"); - if (constructorEditorBuilderArg2 != null) { - constructorEditorBuilderArg2.addInterceptor("com.navercorp.pinpoint.plugin.redis.interceptor.JedisConstructorInterceptor"); - } - - final InstrumentMethod constructorEditorBuilderArg3 = target.getConstructor("java.lang.String", "int", "int"); - if (constructorEditorBuilderArg3 != null) { - constructorEditorBuilderArg3.addInterceptor("com.navercorp.pinpoint.plugin.redis.interceptor.JedisConstructorInterceptor"); - } - - final InstrumentMethod constructorEditorBuilderArg4 = target.getConstructor("java.net.URI"); - if (constructorEditorBuilderArg4 != null) { - constructorEditorBuilderArg4.addInterceptor("com.navercorp.pinpoint.plugin.redis.interceptor.JedisConstructorInterceptor"); - } - - final InstrumentMethod constructorEditorBuilderArg5 = target.getConstructor("redis.clients.jedis.JedisShardInfo"); - if (constructorEditorBuilderArg5 != null) { - constructorEditorBuilderArg5.addInterceptor("com.navercorp.pinpoint.plugin.redis.interceptor.JedisConstructorInterceptor"); - } - - for (InstrumentMethod method : target.getDeclaredMethods(MethodFilters.chain(MethodFilters.name(JedisMethodNames.get()), MethodFilters.modifierNot(MethodFilters.SYNTHETIC)))) { - try { - method.addScopedInterceptor("com.navercorp.pinpoint.plugin.redis.interceptor.JedisMethodInterceptor", va(config.isIo()), RedisConstants.REDIS_SCOPE); - } catch (Exception e) { - if (logger.isWarnEnabled()) { - logger.warn("Unsupported method {}", method, e); - } - } - } + // Set endpoint + // host + addSetEndPointInterceptor(target, "java.lang.String"); + // host, port + addSetEndPointInterceptor(target, "java.lang.String", "int"); + // host, port, ssl + addSetEndPointInterceptor(target, "java.lang.String", "int", "boolean"); + // host, port, ssl, sslSocketFactory, sslParameters, hostnameVerifier + addSetEndPointInterceptor(target, "java.lang.String", "int", "boolean", "javax.net.ssl.SSLSocketFactory", "javax.net.ssl.SSLParameters", "javax.net.ssl.HostnameVerifier"); + // host, port, timeout + addSetEndPointInterceptor(target, "java.lang.String", "int", "int"); + // host, port, timeout, ssl + addSetEndPointInterceptor(target, "java.lang.String", "int", "int", "boolean"); + // host, port, timeout, ssl, sslSocketFactory, sslParameters, hostnameVerifier + addSetEndPointInterceptor(target, "java.lang.String", "int", "int", "boolean", "javax.net.ssl.SSLSocketFactory", "javax.net.ssl.SSLParameters", "javax.net.ssl.HostnameVerifier"); + // host, port, connectionTimeout, soTimeout + addSetEndPointInterceptor(target, "java.lang.String", "int", "int", "int"); + // host, port, connectionTimeout, soTimeout, ssl + addSetEndPointInterceptor(target, "java.lang.String", "int", "int", "int", "boolean"); + // host, port, connectionTimeout, soTimeout, ssl, sslSocketFactory, sslParameters, hostnameVerifier + addSetEndPointInterceptor(target, "java.lang.String", "int", "int", "int", "boolean", "javax.net.ssl.SSLSocketFactory", "javax.net.ssl.SSLParameters", "javax.net.ssl.HostnameVerifier"); + // shardInfo + addSetEndPointInterceptor(target, "redis.clients.jedis.JedisShardInfo"); + // uri + addSetEndPointInterceptor(target, "java.net.URI"); + // uri, sslSocketFactory, sslParameters, hostnameVerifier + addSetEndPointInterceptor(target, "java.net.URI", "javax.net.ssl.SSLSocketFactory", "javax.net.ssl.SSLParameters", "javax.net.ssl.HostnameVerifier"); + // uri, timeout + addSetEndPointInterceptor(target, "java.net.URI", "int"); + // uri, timeout, sslSocketFactory, sslParameters, hostnameVerifier + addSetEndPointInterceptor(target, "java.net.URI", "int", "javax.net.ssl.SSLSocketFactory", "javax.net.ssl.SSLParameters", "javax.net.ssl.HostnameVerifier"); + // uri, connectionTimeout, soTimeout + addSetEndPointInterceptor(target, "java.net.URI", "int", "int"); + // uri, connectionTimeout, soTimeout, sslSocketFactory, sslParameters, hostnameVerifier + addSetEndPointInterceptor(target, "java.net.URI", "int", "int", "javax.net.ssl.SSLSocketFactory", "javax.net.ssl.SSLParameters", "javax.net.ssl.HostnameVerifier"); + + // methods(commands) + addJedisMethodInterceptor(target, config, RedisConstants.REDIS_SCOPE); return target.toBytecode(); } @@ -127,36 +135,42 @@ public byte[] doInTransform(Instrumentor instrumentor, ClassLoader classLoader, } // Client - private void addJedisClientClassEditor() { - transformTemplate.transform("redis.clients.jedis.Client", new TransformCallback() { + private void addClient() { + transformTemplate.transform("redis.clients.jedis.Client", new TransformCallback() { @Override public byte[] doInTransform(Instrumentor instrumentor, ClassLoader classLoader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws InstrumentException { - InstrumentClass target = instrumentor.getInstrumentClass(classLoader, className, classfileBuffer); + final InstrumentClass target = instrumentor.getInstrumentClass(classLoader, className, classfileBuffer); target.addField(RedisConstants.END_POINT_ACCESSOR); - final InstrumentMethod constructorEditorBuilderArg1 = target.getConstructor("java.lang.String"); - if (constructorEditorBuilderArg1 != null) { - constructorEditorBuilderArg1.addInterceptor("com.navercorp.pinpoint.plugin.redis.interceptor.JedisClientConstructorInterceptor"); - } - - final InstrumentMethod constructorEditorBuilderArg2 = target.getConstructor("java.lang.String", "int"); - if (constructorEditorBuilderArg2 != null) { - constructorEditorBuilderArg2.addInterceptor("com.navercorp.pinpoint.plugin.redis.interceptor.JedisClientConstructorInterceptor"); - } + // Set endpoint + // host + addSetEndPointInterceptor(target, "java.lang.String"); + // host, port + addSetEndPointInterceptor(target, "java.lang.String", "int"); + // host, port, ssl + addSetEndPointInterceptor(target, "java.lang.String", "int", "boolean"); + // host, port, ssl, sslSocketFactory, sslParameters, hostnameVerifier + addSetEndPointInterceptor(target, "java.lang.String", "int", "boolean", "javax.net.ssl.SSLSocketFactory", "javax.net.ssl.SSLParameters", "javax.net.ssl.HostnameVerifier"); return target.toBytecode(); } }); } - private void addProtocolClassEditor() { + private void addSetEndPointInterceptor(final InstrumentClass target, final String... parameterTypes) throws InstrumentException { + final InstrumentMethod method = target.getConstructor(parameterTypes); + if (method != null) { + method.addInterceptor("com.navercorp.pinpoint.plugin.redis.interceptor.SetEndPointInterceptor"); + } + } + + private void addProtocol() { transformTemplate.transform("redis.clients.jedis.Protocol", new TransformCallback() { @Override public byte[] doInTransform(Instrumentor instrumentor, ClassLoader classLoader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws InstrumentException { - InstrumentClass target = instrumentor.getInstrumentClass(classLoader, className, classfileBuffer); - + final InstrumentClass target = instrumentor.getInstrumentClass(classLoader, className, classfileBuffer); for (InstrumentMethod method : target.getDeclaredMethods(MethodFilters.chain(MethodFilters.name("sendCommand", "read"), MethodFilters.modifierNot(Modifier.PRIVATE)))) { method.addScopedInterceptor("com.navercorp.pinpoint.plugin.redis.interceptor.ProtocolSendCommandAndReadMethodInterceptor", RedisConstants.REDIS_SCOPE, ExecutionPolicy.INTERNAL); } @@ -167,57 +181,62 @@ public byte[] doInTransform(Instrumentor instrumentor, ClassLoader classLoader, } // Pipeline - private void addJedisPipelineClassEditors(RedisPluginConfig config) { - addJedisPipelineBaseExtendedClassEditor(config, "redis.clients.jedis.PipelineBase", null); + private void addPipeline(RedisPluginConfig config) { + addPipelineBaseExtends(config, "redis.clients.jedis.PipelineBase", null); // MultikeyPipellineBase extends PipelineBase - addJedisPipelineBaseExtendedClassEditor(config, "redis.clients.jedis.MultiKeyPipelineBase", null); + addPipelineBaseExtends(config, "redis.clients.jedis.MultiKeyPipelineBase", null); // Pipeline extends PipelineBase - addJedisPipelineBaseExtendedClassEditor(config, "redis.clients.jedis.Pipeline", new TransformHandler() { + addPipelineBaseExtends(config, "redis.clients.jedis.Pipeline", new TransformHandler() { @Override public void handle(InstrumentClass target) throws InstrumentException { target.addField(RedisConstants.END_POINT_ACCESSOR); - final InstrumentMethod setClientMethodEditorBuilder = target.getDeclaredMethod("setClient", "redis.clients.jedis.Client"); - if (setClientMethodEditorBuilder != null) { - setClientMethodEditorBuilder.addInterceptor("com.navercorp.pinpoint.plugin.redis.interceptor.JedisPipelineSetClientMethodInterceptor"); + final InstrumentMethod setClientMethod = target.getDeclaredMethod("setClient", "redis.clients.jedis.Client"); + if (setClientMethod != null) { + setClientMethod.addInterceptor("com.navercorp.pinpoint.plugin.redis.interceptor.AttachEndPointInterceptor"); } - final InstrumentMethod constructorEditorBuilder = target.getConstructor("redis.clients.jedis.Client"); - if (constructorEditorBuilder != null) { - constructorEditorBuilder.addInterceptor("com.navercorp.pinpoint.plugin.redis.interceptor.JedisPipelineConstructorInterceptor"); + final InstrumentMethod constructor = target.getConstructor("redis.clients.jedis.Client"); + if (constructor != null) { + constructor.addInterceptor("com.navercorp.pinpoint.plugin.redis.interceptor.AttachEndPointInterceptor"); } } }); } - private void addJedisPipelineBaseExtendedClassEditor(final RedisPluginConfig config, String targetClassName, final TransformHandler handler) { + private void addPipelineBaseExtends(final RedisPluginConfig config, String targetClassName, final TransformHandler handler) { transformTemplate.transform(targetClassName, new TransformCallback() { @Override public byte[] doInTransform(Instrumentor instrumentor, ClassLoader classLoader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws InstrumentException { - InstrumentClass target = instrumentor.getInstrumentClass(classLoader, className, classfileBuffer); + final InstrumentClass target = instrumentor.getInstrumentClass(classLoader, className, classfileBuffer); if (handler != null) { handler.handle(target); } - for (InstrumentMethod method : target.getDeclaredMethods(MethodFilters.chain(MethodFilters.name(JedisPipelineMethodNames.get()), MethodFilters.modifierNot(MethodFilters.SYNTHETIC)))) { - try { - method.addScopedInterceptor("com.navercorp.pinpoint.plugin.redis.interceptor.JedisPipelineMethodInterceptor", va(config.isIo()), RedisConstants.REDIS_SCOPE); - } catch (Exception e) { - if (logger.isWarnEnabled()) { - logger.warn("Unsupported method {}", method, e); - } - } - } + // methods(commands) + addJedisMethodInterceptor(target, config, RedisConstants.REDIS_SCOPE); return target.toBytecode(); } }); } + private void addJedisMethodInterceptor(final InstrumentClass target, final RedisPluginConfig config, final String scope) { + for (InstrumentMethod method : target.getDeclaredMethods(MethodFilters.chain(this.methodNameFilter, MethodFilters.modifierNot(MethodFilters.SYNTHETIC)))) { + try { + method.addScopedInterceptor("com.navercorp.pinpoint.plugin.redis.interceptor.JedisMethodInterceptor", va(config.isIo()), scope); + } catch (Exception e) { + if (logger.isWarnEnabled()) { + logger.warn("Unsupported method {}", method, e); + } + } + } + } + private interface TransformHandler { void handle(InstrumentClass target) throws InstrumentException; } diff --git a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/RedisPluginConfig.java b/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/RedisPluginConfig.java index 5b609192625e..d63e312de9e8 100644 --- a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/RedisPluginConfig.java +++ b/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/RedisPluginConfig.java @@ -18,21 +18,28 @@ import com.navercorp.pinpoint.bootstrap.config.ProfilerConfig; /** - * * @author jaehong.kim - * */ public class RedisPluginConfig { - private boolean pipelineEnabled = true; + private boolean enable = true; + private boolean pipeline = true; private boolean io = true; public RedisPluginConfig(ProfilerConfig src) { - pipelineEnabled = src.readBoolean("profiler.redis.pipeline", true); + this.enable = src.readBoolean("profiler.redis", true); + if (this.enable) { + this.enable = src.readBoolean("profiler.redis.enable", true); + } + pipeline = src.readBoolean("profiler.redis.pipeline", true); io = src.readBoolean("profiler.redis.io", true); } - public boolean isPipelineEnabled() { - return pipelineEnabled; + public boolean isEnable() { + return enable; + } + + public boolean isPipeline() { + return pipeline; } public boolean isIo() { @@ -41,12 +48,11 @@ public boolean isIo() { @Override public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("RedisPluginConfig{pipelineEnabled="); - builder.append(pipelineEnabled); - builder.append(", io="); - builder.append(io); - builder.append("}"); - return builder.toString(); + final StringBuilder sb = new StringBuilder("{"); + sb.append("enable=").append(enable); + sb.append(", pipeline=").append(pipeline); + sb.append(", io=").append(io); + sb.append('}'); + return sb.toString(); } } \ No newline at end of file diff --git a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/RedisTypeProvider.java b/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/RedisTypeProvider.java index d10fcfdb3192..3177b95641c6 100644 --- a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/RedisTypeProvider.java +++ b/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/RedisTypeProvider.java @@ -15,6 +15,7 @@ */ package com.navercorp.pinpoint.plugin.redis; +import com.navercorp.pinpoint.common.trace.AnnotationKey; import com.navercorp.pinpoint.common.trace.AnnotationKeyMatchers; import com.navercorp.pinpoint.common.trace.TraceMetadataProvider; import com.navercorp.pinpoint.common.trace.TraceMetadataSetupContext; @@ -23,6 +24,6 @@ public class RedisTypeProvider implements TraceMetadataProvider { @Override public void setup(TraceMetadataSetupContext context) { - context.addServiceType(RedisConstants.REDIS, AnnotationKeyMatchers.ARGS_MATCHER); + context.addServiceType(RedisConstants.REDIS, AnnotationKeyMatchers.exact(AnnotationKey.REDIS_IO)); } } diff --git a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisClientMetadataAttchInterceptor.java b/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/AttachEndPointInterceptor.java similarity index 76% rename from plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisClientMetadataAttchInterceptor.java rename to plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/AttachEndPointInterceptor.java index 126e9660bf7a..f7bc89d09634 100644 --- a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisClientMetadataAttchInterceptor.java +++ b/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/AttachEndPointInterceptor.java @@ -25,15 +25,13 @@ import com.navercorp.pinpoint.plugin.redis.EndPointAccessor; /** - * * @author jaehong.kim - * */ -public abstract class JedisClientMetadataAttchInterceptor implements AroundInterceptor { +public class AttachEndPointInterceptor implements AroundInterceptor { private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); private final boolean isDebug = logger.isDebugEnabled(); - public JedisClientMetadataAttchInterceptor(TraceContext traceContext, MethodDescriptor methodDescriptor) { + public AttachEndPointInterceptor(TraceContext traceContext, MethodDescriptor methodDescriptor) { } @Override @@ -58,22 +56,30 @@ public void before(Object target, Object[] args) { private boolean validate(final Object target, final Object[] args) { if (args == null || args.length == 0 || args[0] == null) { - logger.debug("Invalid arguments. Null or not found args({}).", args); + if (isDebug) { + logger.debug("Invalid arguments. Null or not found args({}).", args); + } return false; } if (!(args[0] instanceof Client)) { - logger.debug("Invalid arguments. Expect Client but args[0]({}).", args[0]); + if (isDebug) { + logger.debug("Invalid arguments. Expect Client but args[0]({}).", args[0]); + } return false; } if (!(args[0] instanceof EndPointAccessor)) { - logger.debug("Invalid args[0] object. Need field accessor({}).", EndPointAccessor.class.getName()); + if (isDebug) { + logger.debug("Invalid args[0] object. Need field accessor({}).", EndPointAccessor.class.getName()); + } return false; } if (!(target instanceof EndPointAccessor)) { - logger.debug("Invalid target object. Need field accessor({}).", EndPointAccessor.class.getName()); + if (isDebug) { + logger.debug("Invalid target object. Need field accessor({}).", EndPointAccessor.class.getName()); + } return false; } diff --git a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisClientConstructorInterceptor.java b/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisClientConstructorInterceptor.java deleted file mode 100644 index e0ed18f081d9..000000000000 --- a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisClientConstructorInterceptor.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2014 NAVER Corp. - * - * Licensed 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 com.navercorp.pinpoint.plugin.redis.interceptor; - -import com.navercorp.pinpoint.bootstrap.context.MethodDescriptor; -import com.navercorp.pinpoint.bootstrap.context.TraceContext; -import com.navercorp.pinpoint.bootstrap.interceptor.AroundInterceptor; -import com.navercorp.pinpoint.bootstrap.logging.PLogger; -import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory; -import com.navercorp.pinpoint.plugin.redis.EndPointAccessor; -import com.navercorp.pinpoint.plugin.redis.EndPointUtils; - -/** - * Jedis client(redis client) constructor interceptor - trace endPoint - * - * @author jaehong.kim - * - */ -public class JedisClientConstructorInterceptor implements AroundInterceptor { - - private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); - private final boolean isDebug = logger.isDebugEnabled(); - - public JedisClientConstructorInterceptor(TraceContext traceContext, MethodDescriptor methodDescriptor) { - } - - @Override - public void before(Object target, Object[] args) { - if (isDebug) { - logger.beforeInterceptor(target, args); - } - - try { - if (!validate(target, args)) { - return; - } - - final String endPoint = EndPointUtils.getEndPoint(args); - ((EndPointAccessor)target)._$PINPOINT$_setEndPoint(endPoint); - } catch (Throwable t) { - logger.warn("Failed to BEFORE process. {}", t.getMessage(), t); - } - } - - private boolean validate(final Object target, final Object[] args) { - if (args == null || args.length == 0 || args[0] == null) { - logger.debug("Invalid arguments. Null or not found args({}).", args); - return false; - } - - if (!(args[0] instanceof String)) { - logger.debug("Invalid arguments. Expect String but args[0]({}).", args[0]); - return false; - } - - if (!(target instanceof EndPointAccessor)) { - logger.debug("Invalid target object. Need field accessor({}).", EndPointAccessor.class.getName()); - return false; - } - - return true; - } - - @Override - public void after(Object target, Object[] args, Object result, Throwable throwable) { - } -} \ No newline at end of file diff --git a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisMethodInterceptor.java b/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisMethodInterceptor.java index 5a74fe0d6131..d1727d6d22ad 100644 --- a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisMethodInterceptor.java +++ b/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisMethodInterceptor.java @@ -23,17 +23,16 @@ import com.navercorp.pinpoint.bootstrap.interceptor.scope.InterceptorScope; import com.navercorp.pinpoint.bootstrap.interceptor.scope.InterceptorScopeInvocation; import com.navercorp.pinpoint.common.trace.AnnotationKey; +import com.navercorp.pinpoint.common.util.IntBooleanIntBooleanValue; import com.navercorp.pinpoint.plugin.redis.CommandContext; import com.navercorp.pinpoint.plugin.redis.CommandContextFactory; -import com.navercorp.pinpoint.plugin.redis.CommandContextFormatter; import com.navercorp.pinpoint.plugin.redis.EndPointAccessor; import com.navercorp.pinpoint.plugin.redis.RedisConstants; /** * Jedis (redis client) method interceptor - * - * @author jaehong.kim * + * @author jaehong.kim */ public class JedisMethodInterceptor extends SpanEventSimpleAroundInterceptorForPlugin { @@ -62,7 +61,7 @@ public void doInAfterTrace(SpanEventRecorder recorder, Object target, Object[] a if (target instanceof EndPointAccessor) { endPoint = ((EndPointAccessor) target)._$PINPOINT$_getEndPoint(); } - + final InterceptorScopeInvocation invocation = interceptorScope.getCurrentInvocation(); final Object attachment = getAttachment(invocation); if (attachment instanceof CommandContext) { @@ -70,10 +69,7 @@ public void doInAfterTrace(SpanEventRecorder recorder, Object target, Object[] a if (logger.isDebugEnabled()) { logger.debug("Check command context {}", commandContext); } - if (io) { - String commandContextString = format(commandContext); - recorder.recordAttribute(AnnotationKey.ARGS0, commandContextString); - } + recordIo(recorder, commandContext); // clear invocation.removeAttachment(); } @@ -85,8 +81,11 @@ public void doInAfterTrace(SpanEventRecorder recorder, Object target, Object[] a recorder.recordException(throwable); } - private String format(CommandContext commandContext) { - return CommandContextFormatter.format(commandContext); + private void recordIo(SpanEventRecorder recorder, CommandContext callContext) { + if (io) { + IntBooleanIntBooleanValue value = new IntBooleanIntBooleanValue((int) callContext.getWriteElapsedTime(), callContext.isWriteFail(), (int) callContext.getReadElapsedTime(), callContext.isReadFail()); + recorder.recordAttribute(AnnotationKey.REDIS_IO, value); + } } private Object getAttachment(InterceptorScopeInvocation invocation) { diff --git a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisPipelineConstructorInterceptor.java b/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisPipelineConstructorInterceptor.java deleted file mode 100644 index 1505296a3dfd..000000000000 --- a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisPipelineConstructorInterceptor.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2014 NAVER Corp. - * - * Licensed 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 com.navercorp.pinpoint.plugin.redis.interceptor; - -import com.navercorp.pinpoint.bootstrap.context.MethodDescriptor; -import com.navercorp.pinpoint.bootstrap.context.TraceContext; - -/** - * Jedis Pipeline(redis client) constructor interceptor - * - trace endPoint - * - * @author jaehong.kim - * - */ -public class JedisPipelineConstructorInterceptor extends JedisClientMetadataAttchInterceptor { - - public JedisPipelineConstructorInterceptor(TraceContext traceContext, MethodDescriptor methodDescriptor) { - super(traceContext, methodDescriptor); - } -} \ No newline at end of file diff --git a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisPipelineMethodInterceptor.java b/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisPipelineMethodInterceptor.java deleted file mode 100644 index 3ad650c9e402..000000000000 --- a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisPipelineMethodInterceptor.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2014 NAVER Corp. - * - * Licensed 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 com.navercorp.pinpoint.plugin.redis.interceptor; - -import com.navercorp.pinpoint.bootstrap.context.MethodDescriptor; -import com.navercorp.pinpoint.bootstrap.context.SpanEventRecorder; -import com.navercorp.pinpoint.bootstrap.context.TraceContext; -import com.navercorp.pinpoint.bootstrap.interceptor.SpanEventSimpleAroundInterceptorForPlugin; -import com.navercorp.pinpoint.bootstrap.interceptor.scope.InterceptorScope; -import com.navercorp.pinpoint.bootstrap.interceptor.scope.InterceptorScopeInvocation; -import com.navercorp.pinpoint.common.trace.AnnotationKey; -import com.navercorp.pinpoint.plugin.redis.CommandContext; -import com.navercorp.pinpoint.plugin.redis.CommandContextFactory; -import com.navercorp.pinpoint.plugin.redis.CommandContextFormatter; -import com.navercorp.pinpoint.plugin.redis.EndPointAccessor; -import com.navercorp.pinpoint.plugin.redis.RedisConstants; - -/** - * Jedis Pipeline(redis client) method interceptor - * - * @author jaehong.kim - * - */ -public class JedisPipelineMethodInterceptor extends SpanEventSimpleAroundInterceptorForPlugin { - - private InterceptorScope interceptorScope; - private boolean io; - - public JedisPipelineMethodInterceptor(TraceContext traceContext, MethodDescriptor methodDescriptor, InterceptorScope interceptorScope, boolean io) { - super(traceContext, methodDescriptor); - - this.interceptorScope = interceptorScope; - this.io = io; - } - - @Override - public void doInBeforeTrace(SpanEventRecorder recorder, Object target, Object[] args) { - final InterceptorScopeInvocation invocation = interceptorScope.getCurrentInvocation(); - if (invocation != null) { - invocation.getOrCreateAttachment(CommandContextFactory.COMMAND_CONTEXT_FACTORY); - } - } - - @Override - public void doInAfterTrace(SpanEventRecorder recorder, Object target, Object[] args, Object result, Throwable throwable) { - String endPoint = null; - if (target instanceof EndPointAccessor) { - endPoint = ((EndPointAccessor)target)._$PINPOINT$_getEndPoint(); - } - - final InterceptorScopeInvocation invocation = interceptorScope.getCurrentInvocation(); - final Object attachment = getAttachment(invocation); - if (attachment instanceof CommandContext) { - final CommandContext commandContext = (CommandContext) attachment; - if (logger.isDebugEnabled()) { - logger.debug("Check command context {}", commandContext); - } - if (io) { - String format = format(commandContext); - recorder.recordAttribute(AnnotationKey.ARGS0, format); - } - // clear - invocation.removeAttachment(); - } - - recorder.recordApi(getMethodDescriptor()); - recorder.recordEndPoint(endPoint != null ? endPoint : "Unknown"); - recorder.recordDestinationId(RedisConstants.REDIS.getName()); - recorder.recordServiceType(RedisConstants.REDIS); - recorder.recordException(throwable); - } - - private String format(CommandContext commandContext) { - return CommandContextFormatter.format(commandContext); - } - - private Object getAttachment(InterceptorScopeInvocation invocation) { - if (invocation == null) { - return null; - } - return invocation.getAttachment(); - } -} \ No newline at end of file diff --git a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisPipelineSetClientMethodInterceptor.java b/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisPipelineSetClientMethodInterceptor.java deleted file mode 100644 index 8666626e829d..000000000000 --- a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisPipelineSetClientMethodInterceptor.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2014 NAVER Corp. - * - * Licensed 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 com.navercorp.pinpoint.plugin.redis.interceptor; - -import com.navercorp.pinpoint.bootstrap.context.MethodDescriptor; -import com.navercorp.pinpoint.bootstrap.context.TraceContext; - -/** - * Jedis pipeline (redis client) setClient method interceptor - * - * @author jaehong.kim - * - */ -public class JedisPipelineSetClientMethodInterceptor extends JedisClientMetadataAttchInterceptor { - - public JedisPipelineSetClientMethodInterceptor(TraceContext traceContext, MethodDescriptor methodDescriptor) { - super(traceContext, methodDescriptor); - } -} \ No newline at end of file diff --git a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/ProtocolSendCommandAndReadMethodInterceptor.java b/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/ProtocolSendCommandAndReadMethodInterceptor.java index 6ae2d48801e9..648e59efd177 100644 --- a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/ProtocolSendCommandAndReadMethodInterceptor.java +++ b/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/ProtocolSendCommandAndReadMethodInterceptor.java @@ -79,7 +79,7 @@ public void before(Object target, Object[] args) { @Override public void after(Object target, Object[] args, Object result, Throwable throwable) { if (isDebug) { - logger.afterInterceptor(target, methodDescriptor.getClassName(), methodDescriptor.getMethodName(), "", args, result, throwable); + logger.afterInterceptor(target, args, result, throwable); } final Trace trace = traceContext.currentTraceObject(); @@ -114,5 +114,4 @@ private Object getAttachment(InterceptorScopeInvocation invocation) { } return invocation.getAttachment(); } - } \ No newline at end of file diff --git a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisConstructorInterceptor.java b/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/SetEndPointInterceptor.java similarity index 86% rename from plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisConstructorInterceptor.java rename to plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/SetEndPointInterceptor.java index 47c58e64efde..185421761255 100644 --- a/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/JedisConstructorInterceptor.java +++ b/plugins/redis/src/main/java/com/navercorp/pinpoint/plugin/redis/interceptor/SetEndPointInterceptor.java @@ -35,12 +35,12 @@ * * @author jaehong.kim */ -public class JedisConstructorInterceptor implements AroundInterceptor { +public class SetEndPointInterceptor implements AroundInterceptor { private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); private final boolean isDebug = logger.isDebugEnabled(); - public JedisConstructorInterceptor(TraceContext traceContext, MethodDescriptor methodDescriptor) { + public SetEndPointInterceptor(TraceContext traceContext, MethodDescriptor methodDescriptor) { } @Override @@ -64,35 +64,34 @@ public void before(Object target, Object[] args) { } private String getEndPoint(Object[] args) { - // first arg is host final Object argZero = args[0]; if (argZero instanceof String) { return EndPointUtils.getEndPoint(args); } else if (argZero instanceof URI) { final URI uri = (URI) argZero; - return HostAndPort.toHostAndPortString(uri.getHost(), uri.getPort()); } else if (argZero instanceof JedisShardInfo) { final JedisShardInfo info = (JedisShardInfo) argZero; - return HostAndPort.toHostAndPortString(info.getHost(), info.getPort()); } - return ""; + return "Unknown"; } - private boolean validate(final Object target, final Object[] args) { if (args == null || args.length == 0 || args[0] == null) { - logger.debug("Invalid arguments. Null or not found args({}).", args); + if (isDebug) { + logger.debug("Invalid arguments. Null or not found args({}).", args); + } return false; } if (!(target instanceof EndPointAccessor)) { - logger.debug("Invalid target object. Need field accessor({}).", EndPointAccessor.class.getName()); + if (isDebug) { + logger.debug("Invalid target object. Need field accessor({}).", EndPointAccessor.class.getName()); + } return false; } - return true; } diff --git a/web/src/main/java/com/navercorp/pinpoint/web/service/TransactionInfoServiceImpl.java b/web/src/main/java/com/navercorp/pinpoint/web/service/TransactionInfoServiceImpl.java index 222e2e1db39d..ce80fc26e35f 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/service/TransactionInfoServiceImpl.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/service/TransactionInfoServiceImpl.java @@ -71,9 +71,6 @@ public class TransactionInfoServiceImpl implements TransactionInfoService { @Autowired private AnnotationKeyRegistryService annotationKeyRegistryService; - @Autowired - private StringMetaDataDao stringMetaDataDao; - @Autowired(required=false) private MetaDataFilter metaDataFilter; @@ -295,14 +292,6 @@ private boolean isViewPoint(final SpanAlign spanAlign, long focusTimestamp, Stri return true; } - private String getArgument(final SpanAlign spanAlign) { - if (spanAlign.isSpan()) { - return getRpcArgument(spanAlign); - } - - return getDisplayArgument(spanAlign.getSpanEventBo()); - } - private String getRpcArgument(SpanAlign spanAlign) { SpanBo spanBo = spanAlign.getSpanBo(); String rpc = spanBo.getRpc(); @@ -349,7 +338,7 @@ private List populateSpanRecord(CallTreeIterator callTreeIterator) { } final List recordList = new ArrayList<>(callTreeIterator.size() * 2); - final RecordFactory factory = new RecordFactory(registry, annotationKeyRegistryService, stringMetaDataDao); + final RecordFactory factory = new RecordFactory(annotationKeyMatcherService, registry, annotationKeyRegistryService); // annotation id has nothing to do with spanAlign's seq and thus may be incremented as long as they don't overlap. while (callTreeIterator.hasNext()) { @@ -372,8 +361,7 @@ private List populateSpanRecord(CallTreeIterator callTreeIterator) { metaDataFilter.replaceAnnotationBo(align, MetaData.PARAM); } - final String argument = getArgument(align); - final Record record = factory.get(node, argument); + final Record record = factory.get(node); recordList.add(record); // add exception record. @@ -384,7 +372,6 @@ private List populateSpanRecord(CallTreeIterator callTreeIterator) { } } - // add annotation record. if (!align.getAnnotationBoList().isEmpty()) { final List annotations = factory.getAnnotations(record.getTab() + 1, record.getId(), align); diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/callstacks/AnnotationRecordFormatter.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/callstacks/AnnotationRecordFormatter.java index 785ecc7ebe26..444a27ca665e 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/callstacks/AnnotationRecordFormatter.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/callstacks/AnnotationRecordFormatter.java @@ -24,6 +24,7 @@ import com.navercorp.pinpoint.web.calltree.span.SpanAlign; import com.navercorp.pinpoint.web.dao.StringMetaDataDao; +import java.util.Objects; import java.util.concurrent.TimeUnit; /** @@ -39,10 +40,7 @@ public class AnnotationRecordFormatter { private static final String PROXY_APACHE = "PROXY(APACHE)"; private static final String PROXY_UNKNOWN = "PROXY(UNKNOWN)"; - private final StringMetaDataDao stringMetaDataDao; - - public AnnotationRecordFormatter(final StringMetaDataDao stringMetaDataDao) { - this.stringMetaDataDao = stringMetaDataDao; + public AnnotationRecordFormatter() { } public String formatTitle(final AnnotationKey annotationKey, final AnnotationBo annotationBo, SpanAlign align) { @@ -73,13 +71,13 @@ String formatArguments(final AnnotationKey annotationKey, final AnnotationBo ann } else { return "Unsupported type(collector server needs to be upgraded)"; } - } else if (annotationKey.getCode() == AnnotationKey.HTTP_IO.getCode()) { + } else if (annotationKey.getCode() == AnnotationKey.HTTP_IO.getCode() || annotationKey.getCode() == AnnotationKey.REDIS_IO.getCode()) { if (annotationBo.getValue() instanceof IntBooleanIntBooleanValue) { final IntBooleanIntBooleanValue value = (IntBooleanIntBooleanValue) annotationBo.getValue(); return buildHttpIoArguments(value); } } - return annotationBo.getValue().toString(); + return Objects.toString(annotationBo.getValue(), ""); } String buildProxyHttpHeaderAnnotationArguments(final LongIntIntByteByteStringValue value, final long startTimeMillis) { diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/callstacks/RecordFactory.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/callstacks/RecordFactory.java index 78cd77ad70db..8326e210181e 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/callstacks/RecordFactory.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/callstacks/RecordFactory.java @@ -17,13 +17,17 @@ import java.util.ArrayList; import java.util.List; +import java.util.Objects; import com.navercorp.pinpoint.common.server.bo.AnnotationBo; import com.navercorp.pinpoint.common.server.bo.ApiMetaDataBo; +import com.navercorp.pinpoint.common.server.bo.Event; import com.navercorp.pinpoint.common.server.bo.MethodTypeEnum; +import com.navercorp.pinpoint.common.server.bo.SpanBo; import com.navercorp.pinpoint.common.service.AnnotationKeyRegistryService; import com.navercorp.pinpoint.common.service.ServiceTypeRegistryService; import com.navercorp.pinpoint.common.trace.AnnotationKey; +import com.navercorp.pinpoint.common.trace.AnnotationKeyMatcher; import com.navercorp.pinpoint.common.trace.ServiceType; import com.navercorp.pinpoint.common.server.util.AnnotationUtils; import com.navercorp.pinpoint.common.util.ApiDescription; @@ -31,6 +35,7 @@ import com.navercorp.pinpoint.web.calltree.span.CallTreeNode; import com.navercorp.pinpoint.web.calltree.span.SpanAlign; import com.navercorp.pinpoint.web.dao.StringMetaDataDao; +import com.navercorp.pinpoint.web.service.AnnotationKeyMatcherService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,24 +48,26 @@ public class RecordFactory { // spans with id = 0 are regarded as root - start at 1 private int idGen = 1; + private AnnotationKeyMatcherService annotationKeyMatcherService; private ServiceTypeRegistryService registry; private AnnotationKeyRegistryService annotationKeyRegistryService; private final ApiDescriptionParser apiDescriptionParser = new ApiDescriptionParser(); private final AnnotationRecordFormatter annotationRecordFormatter; - public RecordFactory(final ServiceTypeRegistryService registry, final AnnotationKeyRegistryService annotationKeyRegistryService, final StringMetaDataDao stringMetaDataDao) { + public RecordFactory(final AnnotationKeyMatcherService annotationKeyMatcherService, final ServiceTypeRegistryService registry, final AnnotationKeyRegistryService annotationKeyRegistryService) { + this.annotationKeyMatcherService = annotationKeyMatcherService; this.registry = registry; this.annotationKeyRegistryService = annotationKeyRegistryService; - this.annotationRecordFormatter = new AnnotationRecordFormatter(stringMetaDataDao); + this.annotationRecordFormatter = new AnnotationRecordFormatter(); } - public Record get(final CallTreeNode node, final String argument) { + public Record get(final CallTreeNode node) { final SpanAlign align = node.getValue(); align.setId(getNextId()); final int parentId = getParentId(node); Api api = getApi(align); - + final String argument = getArgument(align); final Record record = new DefaultRecord(align.getDepth(), align.getId(), parentId, @@ -87,6 +94,53 @@ public Record get(final CallTreeNode node, final String argument) { return record; } + private String getArgument(final SpanAlign spanAlign) { + if (spanAlign.isSpan()) { + return getRpcArgument(spanAlign); + } + + return getDisplayArgument(spanAlign); + } + + private String getRpcArgument(SpanAlign spanAlign) { + SpanBo spanBo = spanAlign.getSpanBo(); + String rpc = spanBo.getRpc(); + if (rpc != null) { + return rpc; + } + return getDisplayArgument(spanAlign); + } + + private String getDisplayArgument(SpanAlign spanAlign) { + AnnotationBo displayArgument = getDisplayArgument0(spanAlign.getServiceType(), spanAlign.getAnnotationBoList()); + if (displayArgument == null) { + return ""; + } + + final AnnotationKey key = findAnnotationKey(displayArgument.getKey()); + return this.annotationRecordFormatter.formatArguments(key, displayArgument, spanAlign); + } + + private AnnotationBo getDisplayArgument0(final short serviceType, final List annotationBoList) { + if (annotationBoList == null) { + return null; + } + + final AnnotationKeyMatcher matcher = annotationKeyMatcherService.findAnnotationKeyMatcher(serviceType); + if (matcher == null) { + return null; + } + + for (AnnotationBo annotation : annotationBoList) { + int key = annotation.getKey(); + + if (matcher.matches(key)) { + return annotation; + } + } + return null; + } + public Record getFilteredRecord(final CallTreeNode node, String apiTitle) { final SpanAlign align = node.getValue(); align.setId(getNextId()); diff --git a/web/src/test/java/com/navercorp/pinpoint/web/vo/callstacks/RecordFactoryTest.java b/web/src/test/java/com/navercorp/pinpoint/web/vo/callstacks/RecordFactoryTest.java index 93208252dd78..cf9b639d1ce8 100644 --- a/web/src/test/java/com/navercorp/pinpoint/web/vo/callstacks/RecordFactoryTest.java +++ b/web/src/test/java/com/navercorp/pinpoint/web/vo/callstacks/RecordFactoryTest.java @@ -22,9 +22,12 @@ import com.navercorp.pinpoint.common.service.DefaultAnnotationKeyRegistryService; import com.navercorp.pinpoint.common.service.DefaultServiceTypeRegistryService; import com.navercorp.pinpoint.common.service.ServiceTypeRegistryService; +import com.navercorp.pinpoint.common.trace.AnnotationKeyMatcher; import com.navercorp.pinpoint.common.util.TransactionId; import com.navercorp.pinpoint.web.calltree.span.SpanAlign; import com.navercorp.pinpoint.web.dao.StringMetaDataDao; +import com.navercorp.pinpoint.web.service.AnnotationKeyMatcherService; +import com.navercorp.pinpoint.web.service.DefaultAnnotationKeyMatcherService; import org.junit.Assert; import org.junit.Test; @@ -38,15 +41,15 @@ public class RecordFactoryTest { private RecordFactory newRecordFactory() { - ServiceTypeRegistryService serviceTypeRegistryService = new DefaultServiceTypeRegistryService(); - AnnotationKeyRegistryService annotationKeyRegistryService = new DefaultAnnotationKeyRegistryService(); - StringMetaDataDao stringMetaDataDao = new StringMetaDataDao() { + AnnotationKeyMatcherService annotationKeyMatcherService = new AnnotationKeyMatcherService() { @Override - public List getStringMetaData(String agentId, long time, int stringId) { - return Collections.EMPTY_LIST; + public AnnotationKeyMatcher findAnnotationKeyMatcher(short serviceType) { + return null; } }; - return new RecordFactory(serviceTypeRegistryService, annotationKeyRegistryService, stringMetaDataDao); + ServiceTypeRegistryService serviceTypeRegistryService = new DefaultServiceTypeRegistryService(); + AnnotationKeyRegistryService annotationKeyRegistryService = new DefaultAnnotationKeyRegistryService(); + return new RecordFactory(annotationKeyMatcherService, serviceTypeRegistryService, annotationKeyRegistryService); } public void get() {