JedisMethodInterceptor.java 4.4 KB
Newer Older
1 2 3 4
package com.a.eye.skywalking.plugin.jedis.v2;

import com.a.eye.skywalking.api.context.ContextManager;
import com.a.eye.skywalking.api.plugin.interceptor.EnhancedClassInstanceContext;
5
import com.a.eye.skywalking.api.plugin.interceptor.assist.NoConcurrencyAccessObject;
6
import com.a.eye.skywalking.api.plugin.interceptor.enhance.InstanceMethodInvokeContext;
7
import com.a.eye.skywalking.api.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
8
import com.a.eye.skywalking.api.plugin.interceptor.enhance.MethodInterceptResult;
Z
zhangxin 已提交
9
import com.a.eye.skywalking.api.util.StringUtil;
10 11 12 13
import com.a.eye.skywalking.trace.Span;
import com.a.eye.skywalking.trace.tag.Tags;

/**
14 15 16
 * {@link JedisMethodInterceptor} intercept all method of {@link redis.clients.jedis.Jedis}
 * or {@link redis.clients.jedis.JedisCluster}. {@link JedisMethodInterceptor} record
 * the redis host, operation name and the key of the operation.
17 18 19
 *
 * @author zhangxin
 */
20
public class JedisMethodInterceptor extends NoConcurrencyAccessObject implements InstanceMethodsAroundInterceptor {
21 22 23 24 25
    /**
     * The key name that redis connection information in {@link EnhancedClassInstanceContext#context}.
     */
    protected static final String KEY_OF_REDIS_CONN_INFO = "REDIS_CONNECTION_INFO";
    /**
Z
zhangxin 已提交
26
     * The key name that multiple redis hosts in {@link EnhancedClassInstanceContext#context}.
27 28
     */
    protected static final String KEY_OF_REDIS_HOSTS = "KEY_OF_REDIS_HOSTS";
Z
zhangxin 已提交
29 30 31 32 33 34 35 36 37 38 39 40
    /**
     * The key name that redis host in {@link EnhancedClassInstanceContext#context}.
     * it will be null if the value that fetch from {@link EnhancedClassInstanceContext#context}
     * by using {@link #KEY_OF_REDIS_HOSTS} is not null.
     */
    protected static final String KEY_OF_REDIS_HOST = "KEY_OF_REDIS_HOST";
    /**
     * The key name that redis port in {@link EnhancedClassInstanceContext#context}.
     * It can not be null if the value that fetch from {@link EnhancedClassInstanceContext#context} by
     * using {@link #KEY_OF_REDIS_HOST} is not null.
     */
    protected static final String KEY_OF_REDIS_PORT = "KEY_OF_REDIS_PORT";
41

Z
zhangxin 已提交
42 43
    private static final String REDIS_COMPONENT = "Redis";

44
    @Override
45 46
    public void beforeMethod(final EnhancedClassInstanceContext context,
        final InstanceMethodInvokeContext interceptorContext, MethodInterceptResult result) {
A
ascrutae 已提交
47
        this.whenEnter(context, interceptorContext);
48 49
    }

Z
zhangxin 已提交
50 51 52 53
    /**
     * set peer host information for the current active span.
     */
    private void tagPeer(Span span, EnhancedClassInstanceContext context) {
54
        String redisHosts = (String)context.get(KEY_OF_REDIS_HOSTS);
Z
zhangxin 已提交
55
        if (!StringUtil.isEmpty(redisHosts)) {
56
            Tags.PEERS.set(span, (String)context.get(KEY_OF_REDIS_HOSTS));
Z
zhangxin 已提交
57
        } else {
58 59
            Tags.PEER_HOST.set(span, (String)context.get(KEY_OF_REDIS_HOST));
            Tags.PEER_PORT.set(span, (Integer)context.get(KEY_OF_REDIS_PORT));
Z
zhangxin 已提交
60 61 62
        }
    }

63
    @Override
64 65
    public Object afterMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext,
        Object ret) {
A
ascrutae 已提交
66
        this.whenExist(context);
67 68 69 70
        return ret;
    }

    @Override
71 72
    public void handleMethodException(Throwable t, EnhancedClassInstanceContext context,
        InstanceMethodInvokeContext interceptorContext) {
73
        ContextManager.activeSpan().log(t);
74
    }
A
ascrutae 已提交
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100

    @Override
    protected void enter(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext) {
        Span span = ContextManager.createSpan("Jedis/" + interceptorContext.methodName());
        Tags.COMPONENT.set(span, REDIS_COMPONENT);
        Tags.DB_TYPE.set(span, REDIS_COMPONENT);
        Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_CLIENT);
        tagPeer(span, context);
        Tags.SPAN_LAYER.asDB(span);
        if (StringUtil.isEmpty(context.get(KEY_OF_REDIS_HOST, String.class))) {
            Tags.PEERS.set(span, String.valueOf(context.get(KEY_OF_REDIS_HOSTS)));
        } else {
            Tags.PEER_HOST.set(span, context.get(KEY_OF_REDIS_HOST, String.class));
            Tags.PEER_PORT.set(span, (Integer)context.get(KEY_OF_REDIS_PORT));
        }

        if (interceptorContext.allArguments().length > 0
            && interceptorContext.allArguments()[0] instanceof String) {
            Tags.DB_STATEMENT.set(span, interceptorContext.methodName() + " " + interceptorContext.allArguments()[0]);
        }
    }

    @Override
    protected void exit() {
        ContextManager.stopSpan();
    }
101
}