diff --git a/pom.xml b/pom.xml index dc812b1f..a70eb14f 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ tracer-all-parent - 3.0.11 + 3.0.12 pom tracer-all-parent Alipay SOFATracer Log Implemented by OpenTracing @@ -33,11 +33,11 @@ tracer-test/logback-test tracer-test/log4j2-test tracer-test/log4j-test + sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin 0.22.0 - 3.0.11 1.8 1.8 1.9.3 @@ -89,62 +89,67 @@ com.alipay.sofa tracer-core - ${sofa.tracer.version} + ${project.version} com.alipay.sofa tracer-extensions - ${sofa.tracer.version} + ${project.version} com.alipay.sofa sofa-tracer-springmvc-plugin - ${sofa.tracer.version} + ${project.version} com.alipay.sofa sofa-tracer-httpclient-plugin - ${sofa.tracer.version} + ${project.version} + + + com.alipay.sofa + sofa-tracer-okhttp-plugin + ${project.version} com.alipay.sofa sofa-tracer-resttmplate-plugin - ${sofa.tracer.version} + ${project.version} com.alipay.sofa sofa-tracer-datasource-plugin - ${sofa.tracer.version} + ${project.version} com.alipay.sofa sofa-tracer-zipkin-plugin - ${sofa.tracer.version} + ${project.version} com.alipay.sofa sofa-tracer-spring-cloud-plugin - ${sofa.tracer.version} + ${project.version} com.alipay.sofa - sofa-tracer-dubbo-plugin - ${sofa.tracer.version} + sofa-tracer-dubbo-common-plugin + ${project.version} com.alipay.sofa sofa-tracer-flexible-plugin - ${sofa.tracer.version} + ${project.version} com.alipay.sofa tracer-all - ${sofa.tracer.version} + ${project.version} com.alipay.sofa tracer-sofa-boot-starter - ${sofa.tracer.version} + ${project.version} diff --git a/sofa-tracer-plugins/sofa-tracer-datasource-plugin/pom.xml b/sofa-tracer-plugins/sofa-tracer-datasource-plugin/pom.xml index b0aaf7ca..349642f3 100644 --- a/sofa-tracer-plugins/sofa-tracer-datasource-plugin/pom.xml +++ b/sofa-tracer-plugins/sofa-tracer-datasource-plugin/pom.xml @@ -5,7 +5,7 @@ tracer-all-parent com.alipay.sofa - 3.0.11 + 3.0.12 ../../pom.xml 4.0.0 diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-2.6.x-plugin/pom.xml b/sofa-tracer-plugins/sofa-tracer-dubbo-2.6.x-plugin/pom.xml index e86f4953..d267458d 100644 --- a/sofa-tracer-plugins/sofa-tracer-dubbo-2.6.x-plugin/pom.xml +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-2.6.x-plugin/pom.xml @@ -5,7 +5,7 @@ tracer-all-parent com.alipay.sofa - 3.0.11 + 3.0.12 ../../pom.xml 4.0.0 diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/pom.xml b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/pom.xml new file mode 100644 index 00000000..e562638e --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/pom.xml @@ -0,0 +1,50 @@ + + + + tracer-all-parent + com.alipay.sofa + 3.0.12 + ../../pom.xml + + 4.0.0 + + sofa-tracer-dubbo-common-plugin + + + + com.alibaba + dubbo + 2.6.2 + provided + + + + org.apache.dubbo + dubbo + 2.7.3 + provided + + + + com.alipay.sofa + tracer-core + + + junit + junit + test + + + commons-io + commons-io + test + + + com.alibaba + fastjson + + + + diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/constants/AttachmentKeyConstants.java b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/constants/AttachmentKeyConstants.java new file mode 100644 index 00000000..1bafa97b --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/constants/AttachmentKeyConstants.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.plugins.dubbo.constants; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/7/26 5:25 PM + * @since: + **/ +public class AttachmentKeyConstants { + + public static final String SERVER_DESERIALIZE_SIZE = "server.deserialize.size"; + public static final String SERVER_SERIALIZE_SIZE = "server.serialize.size"; + public static final String CLIENT_DESERIALIZE_SIZE = "client.deserialize.size"; + public static final String CLIENT_SERIALIZE_SIZE = "client.serialize.size"; + + public static final String SERVER_DESERIALIZE_TIME = "server.deserialize.time"; + public static final String SERVER_SERIALIZE_TIME = "server.serialize.time"; + public static final String CLIENT_DESERIALIZE_TIME = "client.deserialize.time"; + public static final String CLIENT_SERIALIZE_TIME = "client.serialize.time"; +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/encoder/DubboClientDigestEncoder.java b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/encoder/DubboClientDigestEncoder.java new file mode 100644 index 00000000..63ff41af --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/encoder/DubboClientDigestEncoder.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.plugins.dubbo.encoder; + +import com.alipay.common.tracer.core.appender.builder.JsonStringBuilder; +import com.alipay.common.tracer.core.appender.builder.XStringBuilder; +import com.alipay.common.tracer.core.middleware.parent.AbstractDigestSpanEncoder; +import com.alipay.common.tracer.core.span.CommonSpanTags; +import com.alipay.common.tracer.core.span.SofaTracerSpan; +import com.alipay.common.tracer.core.utils.StringUtils; +import com.alipay.sofa.tracer.plugins.dubbo.constants.AttachmentKeyConstants; +import io.opentracing.tag.Tags; + +import java.util.Map; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/9/1 2:46 PM + * @since: + **/ +public class DubboClientDigestEncoder extends AbstractDigestSpanEncoder { + + @Override + protected void appendComponentSlot(XStringBuilder xsb, JsonStringBuilder jsb, + SofaTracerSpan span) { + Map tagWithStr = span.getTagsWithStr(); + Map tagWithNum = span.getTagsWithNumber(); + //protocol + xsb.append(tagWithStr.get(CommonSpanTags.PROTOCOL)); + // service + xsb.append(tagWithStr.get(CommonSpanTags.SERVICE)); + // method + xsb.append(tagWithStr.get(CommonSpanTags.METHOD)); + // invoke type + xsb.append(tagWithStr.get(CommonSpanTags.INVOKE_TYPE)); + // remote host + xsb.append(tagWithStr.get(CommonSpanTags.REMOTE_HOST)); + // remote port + xsb.append(tagWithStr.get(CommonSpanTags.REMOTE_PORT)); + // local port + xsb.append(tagWithStr.get(CommonSpanTags.LOCAL_HOST)); + // client.serialize.time + xsb.append(tagWithNum.get(AttachmentKeyConstants.CLIENT_SERIALIZE_TIME) + ""); + // client.deserialize.time + xsb.append(tagWithNum.get(AttachmentKeyConstants.CLIENT_DESERIALIZE_TIME) + ""); + // client.serialize.size + Number reqSizeNum = tagWithNum.get(AttachmentKeyConstants.CLIENT_SERIALIZE_SIZE); + xsb.append(reqSizeNum == null ? 0 : reqSizeNum.longValue()); + // client.deserialize.size + Number respSizeNum = tagWithNum.get(AttachmentKeyConstants.CLIENT_DESERIALIZE_SIZE); + xsb.append(respSizeNum == null ? 0 : respSizeNum.longValue()); + // error message + xsb.append(StringUtils.isBlank(tagWithStr.get(Tags.ERROR.getKey())) ? "" : tagWithStr + .get(Tags.ERROR.getKey())); + } +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/encoder/DubboClientDigestJsonEncoder.java b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/encoder/DubboClientDigestJsonEncoder.java new file mode 100644 index 00000000..3052640e --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/encoder/DubboClientDigestJsonEncoder.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.plugins.dubbo.encoder; + +import com.alipay.common.tracer.core.appender.builder.JsonStringBuilder; +import com.alipay.common.tracer.core.appender.builder.XStringBuilder; +import com.alipay.common.tracer.core.middleware.parent.AbstractDigestSpanEncoder; +import com.alipay.common.tracer.core.span.CommonSpanTags; +import com.alipay.common.tracer.core.span.SofaTracerSpan; +import com.alipay.common.tracer.core.utils.StringUtils; +import com.alipay.sofa.tracer.plugins.dubbo.constants.AttachmentKeyConstants; +import io.opentracing.tag.Tags; + +import java.util.Map; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/2/26 3:56 PM + * @since: + **/ +public class DubboClientDigestJsonEncoder extends AbstractDigestSpanEncoder { + + @Override + protected void appendComponentSlot(XStringBuilder xsb, JsonStringBuilder jsb, + SofaTracerSpan span) { + Map tagStr = span.getTagsWithStr(); + Map tagNum = span.getTagsWithNumber(); + + // protocol + jsb.append(CommonSpanTags.PROTOCOL, tagStr.get(CommonSpanTags.PROTOCOL)); + // serviceName + jsb.append(CommonSpanTags.SERVICE, tagStr.get(CommonSpanTags.SERVICE)); + // method + jsb.append(CommonSpanTags.METHOD, tagStr.get(CommonSpanTags.METHOD)); + //invoke type + jsb.append(CommonSpanTags.INVOKE_TYPE, tagStr.get(CommonSpanTags.INVOKE_TYPE)); + //target ip + jsb.append(CommonSpanTags.REMOTE_HOST, tagStr.get(CommonSpanTags.REMOTE_HOST)); + //target port + jsb.append(CommonSpanTags.REMOTE_PORT, tagStr.get(CommonSpanTags.REMOTE_PORT)); + //local ip + jsb.append(CommonSpanTags.LOCAL_HOST, tagStr.get(CommonSpanTags.LOCAL_HOST)); + //request serialize time + jsb.append(CommonSpanTags.CLIENT_SERIALIZE_TIME, + tagNum.get(AttachmentKeyConstants.CLIENT_SERIALIZE_TIME)); + //response deserialize time + jsb.append(CommonSpanTags.CLIENT_DESERIALIZE_TIME, + tagNum.get(AttachmentKeyConstants.CLIENT_DESERIALIZE_TIME)); + //Request Body bytes length + Number reqSizeNum = tagNum.get(AttachmentKeyConstants.CLIENT_SERIALIZE_SIZE); + jsb.append(CommonSpanTags.REQ_SIZE, reqSizeNum == null ? 0 : reqSizeNum.longValue()); + //Response Body bytes length + Number respSizeNum = tagNum.get(AttachmentKeyConstants.CLIENT_DESERIALIZE_SIZE); + jsb.append(CommonSpanTags.RESP_SIZE, respSizeNum == null ? 0 : respSizeNum.longValue()); + + //error message + if (StringUtils.isNotBlank(tagStr.get(Tags.ERROR.getKey()))) { + jsb.append(Tags.ERROR.getKey(), tagStr.get(Tags.ERROR.getKey())); + } else { + jsb.append(Tags.ERROR.getKey(), StringUtils.EMPTY_STRING); + } + } +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/encoder/DubboServerDigestEncoder.java b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/encoder/DubboServerDigestEncoder.java new file mode 100644 index 00000000..58685e44 --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/encoder/DubboServerDigestEncoder.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.plugins.dubbo.encoder; + +import com.alipay.common.tracer.core.appender.builder.JsonStringBuilder; +import com.alipay.common.tracer.core.appender.builder.XStringBuilder; +import com.alipay.common.tracer.core.middleware.parent.AbstractDigestSpanEncoder; +import com.alipay.common.tracer.core.span.CommonSpanTags; +import com.alipay.common.tracer.core.span.SofaTracerSpan; +import com.alipay.common.tracer.core.utils.StringUtils; +import com.alipay.sofa.tracer.plugins.dubbo.constants.AttachmentKeyConstants; +import io.opentracing.tag.Tags; + +import java.util.Map; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/9/1 2:46 PM + * @since: + **/ +public class DubboServerDigestEncoder extends AbstractDigestSpanEncoder { + + @Override + protected void appendComponentSlot(XStringBuilder xsb, JsonStringBuilder jsb, + SofaTracerSpan span) { + Map tagWithStr = span.getTagsWithStr(); + Map tagWithNum = span.getTagsWithNumber(); + + //protocol + xsb.append(tagWithStr.get(CommonSpanTags.PROTOCOL)); + // service + xsb.append(tagWithStr.get(CommonSpanTags.SERVICE)); + // method + xsb.append(tagWithStr.get(CommonSpanTags.METHOD)); + // invoke type + xsb.append(tagWithStr.get(CommonSpanTags.INVOKE_TYPE)); + xsb.append(tagWithStr.get(CommonSpanTags.REMOTE_HOST)); + xsb.append(tagWithStr.get(CommonSpanTags.REMOTE_PORT)); + xsb.append(tagWithStr.get(CommonSpanTags.LOCAL_HOST)); + xsb.append(tagWithNum.get(AttachmentKeyConstants.CLIENT_SERIALIZE_TIME) + ""); + xsb.append(tagWithNum.get(AttachmentKeyConstants.CLIENT_DESERIALIZE_TIME) + ""); + //Request Body bytes length + long serializeTime = getTime(tagWithNum.get(AttachmentKeyConstants.SERVER_SERIALIZE_TIME)); + long deserializeTime = getTime(tagWithNum + .get(AttachmentKeyConstants.SERVER_DESERIALIZE_TIME)); + xsb.append(String.valueOf(serializeTime)); + xsb.append(String.valueOf(deserializeTime)); + Number reqSizeNum = tagWithNum.get(AttachmentKeyConstants.SERVER_DESERIALIZE_SIZE); + xsb.append(reqSizeNum == null ? 0 : reqSizeNum.longValue()); + Number respSizeNum = tagWithNum.get(AttachmentKeyConstants.SERVER_SERIALIZE_SIZE); + xsb.append(respSizeNum == null ? 0 : respSizeNum.longValue()); + + xsb.append(StringUtils.isBlank(tagWithStr.get(Tags.ERROR.getKey())) ? "" : tagWithStr + .get(Tags.ERROR.getKey())); + } + + private long getTime(Number number) { + if (number != null) { + return number.longValue(); + } + return 0; + } + +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/encoder/DubboServerDigestJsonEncoder.java b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/encoder/DubboServerDigestJsonEncoder.java new file mode 100644 index 00000000..b20e5eb0 --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/encoder/DubboServerDigestJsonEncoder.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.plugins.dubbo.encoder; + +import com.alipay.common.tracer.core.appender.builder.JsonStringBuilder; +import com.alipay.common.tracer.core.appender.builder.XStringBuilder; +import com.alipay.common.tracer.core.middleware.parent.AbstractDigestSpanEncoder; +import com.alipay.common.tracer.core.span.CommonSpanTags; +import com.alipay.common.tracer.core.span.SofaTracerSpan; +import com.alipay.common.tracer.core.utils.StringUtils; +import com.alipay.sofa.tracer.plugins.dubbo.constants.AttachmentKeyConstants; +import io.opentracing.tag.Tags; + +import java.util.Map; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/2/26 4:19 PM + * @since: + **/ +public class DubboServerDigestJsonEncoder extends AbstractDigestSpanEncoder { + + @Override + protected void appendComponentSlot(XStringBuilder xsb, JsonStringBuilder jsb, + SofaTracerSpan span) { + Map tagStr = span.getTagsWithStr(); + Map tagNum = span.getTagsWithNumber(); + + //protocol + jsb.append(CommonSpanTags.PROTOCOL, tagStr.get(CommonSpanTags.PROTOCOL)); + //serviceName + jsb.append(CommonSpanTags.SERVICE, tagStr.get(CommonSpanTags.SERVICE)); + //method + jsb.append(CommonSpanTags.METHOD, tagStr.get(CommonSpanTags.METHOD)); + //local ip + jsb.append(CommonSpanTags.LOCAL_HOST, tagStr.get(CommonSpanTags.LOCAL_HOST)); + //local port + jsb.append(CommonSpanTags.LOCAL_PORT, tagStr.get(CommonSpanTags.LOCAL_PORT)); + + long serializeTime = getTime(tagNum.get(AttachmentKeyConstants.SERVER_SERIALIZE_TIME)); + jsb.append(CommonSpanTags.SERVER_SERIALIZE_TIME, serializeTime); + long deserializeTime = getTime(tagNum.get(AttachmentKeyConstants.SERVER_DESERIALIZE_TIME)); + jsb.append(CommonSpanTags.SERVER_DESERIALIZE_TIME, deserializeTime); + + Number reqSizeNum = tagNum.get(AttachmentKeyConstants.SERVER_DESERIALIZE_SIZE); + jsb.append(CommonSpanTags.REQ_SIZE, reqSizeNum == null ? 0 : reqSizeNum.longValue()); + Number respSizeNum = tagNum.get(AttachmentKeyConstants.SERVER_SERIALIZE_SIZE); + jsb.append(CommonSpanTags.RESP_SIZE, respSizeNum == null ? 0 : respSizeNum.longValue()); + + //error message + if (StringUtils.isNotBlank(tagStr.get(Tags.ERROR.getKey()))) { + jsb.append(Tags.ERROR.getKey(), tagStr.get(Tags.ERROR.getKey())); + } else { + jsb.append(Tags.ERROR.getKey(), StringUtils.EMPTY_STRING); + } + } + + private long getTime(Number number) { + if (number != null) { + return number.longValue(); + } + return 0; + } +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/enums/DubboLogEnum.java b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/enums/DubboLogEnum.java new file mode 100644 index 00000000..48829250 --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/enums/DubboLogEnum.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.plugins.dubbo.enums; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/2/26 3:43 PM + * @since: + **/ +public enum DubboLogEnum { + + DUBBO_SERVER_DIGEST("dubbo_server_digest_log_name", "dubbo-server-digest.log", + "dubbo_server_digest_rolling"), + + DUBBO_SERVER_STAT("dubbo_server_stat_log_name", "dubbo-server-stat.log", + "dubbo_server_stat_rolling"), + + DUBBO_CLIENT_DIGEST("dubbo_client_digest_log_name", "dubbo-client-digest.log", + "dubbo_client_digest_rolling"), + + DUBBO_CLIENT_STAT("dubbo_client_stat_log_name", "dubbo-client-stat.log", + "dubbot_client_stat_rolling"); + + private String logNameKey; + private String defaultLogName; + private String rollingKey; + + DubboLogEnum(String logNameKey, String defaultLogName, String rollingKey) { + this.logNameKey = logNameKey; + this.defaultLogName = defaultLogName; + this.rollingKey = rollingKey; + } + + public String getLogNameKey() { + //log reserve config key + return logNameKey; + } + + public String getDefaultLogName() { + return defaultLogName; + } + + public String getRollingKey() { + return rollingKey; + } + +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/stat/DubboClientStatJsonReporter.java b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/stat/DubboClientStatJsonReporter.java new file mode 100644 index 00000000..d36c6408 --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/stat/DubboClientStatJsonReporter.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.plugins.dubbo.stat; + +import com.alipay.common.tracer.core.constants.SofaTracerConstant; +import com.alipay.common.tracer.core.reporter.stat.AbstractSofaTracerStatisticReporter; +import com.alipay.common.tracer.core.reporter.stat.model.StatMapKey; +import com.alipay.common.tracer.core.span.CommonSpanTags; +import com.alipay.common.tracer.core.span.SofaTracerSpan; +import com.alipay.common.tracer.core.utils.TracerUtils; + +import java.util.Map; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/2/26 4:23 PM + * @since: + **/ +public class DubboClientStatJsonReporter extends AbstractSofaTracerStatisticReporter { + + public DubboClientStatJsonReporter(String statTracerName, String rollingPolicy, + String logReserveConfig) { + super(statTracerName, rollingPolicy, logReserveConfig); + } + + @Override + public void doReportStat(SofaTracerSpan sofaTracerSpan) { + //tags + Map tagsWithStr = sofaTracerSpan.getTagsWithStr(); + StatMapKey statKey = new StatMapKey(); + String appName = tagsWithStr.get(CommonSpanTags.LOCAL_APP); + //service name + String serviceName = tagsWithStr.get(CommonSpanTags.SERVICE); + //method name + String methodName = tagsWithStr.get(CommonSpanTags.METHOD); + statKey.addKey(CommonSpanTags.LOCAL_APP, appName); + statKey.addKey(CommonSpanTags.SERVICE, serviceName); + statKey.addKey(CommonSpanTags.METHOD, methodName); + + String resultCode = tagsWithStr.get(CommonSpanTags.RESULT_CODE); + statKey + .setResult(SofaTracerConstant.RESULT_CODE_SUCCESS.equals(resultCode) ? SofaTracerConstant.STAT_FLAG_SUCCESS + : SofaTracerConstant.STAT_FLAG_FAILS); + statKey.setEnd(buildString(new String[] { getLoadTestMark(sofaTracerSpan) })); + statKey.setLoadTest(TracerUtils.isLoadTest(sofaTracerSpan)); + + long duration = sofaTracerSpan.getEndTime() - sofaTracerSpan.getStartTime(); + long[] values = new long[] { 1, duration }; + this.addStat(statKey, values); + } + + protected String getLoadTestMark(SofaTracerSpan span) { + if (TracerUtils.isLoadTest(span)) { + return "T"; + } else { + return "F"; + } + } +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/stat/DubboClientStatReporter.java b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/stat/DubboClientStatReporter.java new file mode 100644 index 00000000..449f060a --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/stat/DubboClientStatReporter.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.plugins.dubbo.stat; + +import com.alipay.common.tracer.core.constants.SofaTracerConstant; +import com.alipay.common.tracer.core.reporter.stat.AbstractSofaTracerStatisticReporter; +import com.alipay.common.tracer.core.reporter.stat.model.StatKey; +import com.alipay.common.tracer.core.span.CommonSpanTags; +import com.alipay.common.tracer.core.span.SofaTracerSpan; +import com.alipay.common.tracer.core.utils.TracerUtils; + +import java.util.Map; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/9/1 5:27 PM + * @since: + **/ +public class DubboClientStatReporter extends AbstractSofaTracerStatisticReporter { + + public DubboClientStatReporter(String statTracerName, String rollingPolicy, + String logReserveConfig) { + super(statTracerName, rollingPolicy, logReserveConfig); + } + + @Override + public void doReportStat(SofaTracerSpan sofaTracerSpan) { + Map tagsWithStr = sofaTracerSpan.getTagsWithStr(); + StatKey statKey = new StatKey(); + String appName = tagsWithStr.get(CommonSpanTags.LOCAL_APP); + //service name + String serviceName = tagsWithStr.get(CommonSpanTags.SERVICE); + //method name + String methodName = tagsWithStr.get(CommonSpanTags.METHOD); + statKey.setKey(buildString(new String[] { appName, serviceName, methodName })); + String resultCode = tagsWithStr.get(CommonSpanTags.RESULT_CODE); + statKey + .setResult(SofaTracerConstant.RESULT_CODE_SUCCESS.equals(resultCode) ? SofaTracerConstant.STAT_FLAG_SUCCESS + : SofaTracerConstant.STAT_FLAG_FAILS); + + statKey.setEnd(buildString(new String[] { TracerUtils.getLoadTestMark(sofaTracerSpan) })); + //pressure mark + statKey.setLoadTest(TracerUtils.isLoadTest(sofaTracerSpan)); + //value the count and duration + long duration = sofaTracerSpan.getEndTime() - sofaTracerSpan.getStartTime(); + long[] values = new long[] { 1, duration }; + //reserve + this.addStat(statKey, values); + } + +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/stat/DubboServerStatJsonReporter.java b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/stat/DubboServerStatJsonReporter.java new file mode 100644 index 00000000..70281ebe --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/stat/DubboServerStatJsonReporter.java @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.plugins.dubbo.stat; + +import com.alipay.common.tracer.core.constants.SofaTracerConstant; +import com.alipay.common.tracer.core.reporter.stat.AbstractSofaTracerStatisticReporter; +import com.alipay.common.tracer.core.reporter.stat.model.StatMapKey; +import com.alipay.common.tracer.core.span.CommonSpanTags; +import com.alipay.common.tracer.core.span.SofaTracerSpan; +import com.alipay.common.tracer.core.utils.TracerUtils; + +import java.util.Map; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/2/26 4:23 PM + * @since: + **/ +public class DubboServerStatJsonReporter extends AbstractSofaTracerStatisticReporter { + + public DubboServerStatJsonReporter(String statTracerName, String rollingPolicy, + String logReserveConfig) { + super(statTracerName, rollingPolicy, logReserveConfig); + } + + @Override + public void doReportStat(SofaTracerSpan sofaTracerSpan) { + //tags + Map tagsWithStr = sofaTracerSpan.getTagsWithStr(); + StatMapKey statKey = new StatMapKey(); + String appName = tagsWithStr.get(CommonSpanTags.LOCAL_APP); + //service name + String serviceName = tagsWithStr.get(CommonSpanTags.SERVICE); + //method name + String methodName = tagsWithStr.get(CommonSpanTags.METHOD); + + statKey.addKey(CommonSpanTags.LOCAL_APP, appName); + statKey.addKey(CommonSpanTags.SERVICE, serviceName); + statKey.addKey(CommonSpanTags.METHOD, methodName); + + String resultCode = tagsWithStr.get(CommonSpanTags.RESULT_CODE); + statKey + .setResult(SofaTracerConstant.RESULT_CODE_SUCCESS.equals(resultCode) ? SofaTracerConstant.STAT_FLAG_SUCCESS + : SofaTracerConstant.STAT_FLAG_FAILS); + statKey.setEnd(buildString(new String[] { getLoadTestMark(sofaTracerSpan) })); + statKey.setLoadTest(TracerUtils.isLoadTest(sofaTracerSpan)); + + long duration = sofaTracerSpan.getEndTime() - sofaTracerSpan.getStartTime(); + long[] values = new long[] { 1, duration }; + this.addStat(statKey, values); + } + + protected String getLoadTestMark(SofaTracerSpan span) { + if (TracerUtils.isLoadTest(span)) { + return "T"; + } else { + return "F"; + } + } +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/stat/DubboServerStatReporter.java b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/stat/DubboServerStatReporter.java new file mode 100644 index 00000000..48796c6d --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/stat/DubboServerStatReporter.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.plugins.dubbo.stat; + +import com.alipay.common.tracer.core.constants.SofaTracerConstant; +import com.alipay.common.tracer.core.reporter.stat.AbstractSofaTracerStatisticReporter; +import com.alipay.common.tracer.core.reporter.stat.model.StatKey; +import com.alipay.common.tracer.core.span.CommonSpanTags; +import com.alipay.common.tracer.core.span.SofaTracerSpan; +import com.alipay.common.tracer.core.utils.TracerUtils; + +import java.util.Map; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/9/1 5:36 PM + * @since: + **/ +public class DubboServerStatReporter extends AbstractSofaTracerStatisticReporter { + + public DubboServerStatReporter(String statTracerName, String rollingPolicy, + String logReserveConfig) { + super(statTracerName, rollingPolicy, logReserveConfig); + } + + @Override + public void doReportStat(SofaTracerSpan sofaTracerSpan) { + Map tagsWithStr = sofaTracerSpan.getTagsWithStr(); + StatKey statKey = new StatKey(); + String appName = tagsWithStr.get(CommonSpanTags.LOCAL_APP); + //service name + String serviceName = tagsWithStr.get(CommonSpanTags.SERVICE); + //method name + String methodName = tagsWithStr.get(CommonSpanTags.METHOD); + statKey.setKey(buildString(new String[] { appName, serviceName, methodName })); + String resultCode = tagsWithStr.get(CommonSpanTags.RESULT_CODE); + statKey + .setResult(SofaTracerConstant.RESULT_CODE_SUCCESS.equals(resultCode) ? SofaTracerConstant.STAT_FLAG_SUCCESS + : SofaTracerConstant.STAT_FLAG_FAILS); + statKey.setEnd(buildString(new String[] { TracerUtils.getLoadTestMark(sofaTracerSpan) })); + //pressure mark + statKey.setLoadTest(TracerUtils.isLoadTest(sofaTracerSpan)); + //value the count and duration + long duration = sofaTracerSpan.getEndTime() - sofaTracerSpan.getStartTime(); + long[] values = new long[] { 1, duration }; + //reserve + this.addStat(statKey, values); + } +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/tracer/DubboConsumerSofaTracer.java b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/tracer/DubboConsumerSofaTracer.java new file mode 100644 index 00000000..e7c8232b --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/tracer/DubboConsumerSofaTracer.java @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.plugins.dubbo.tracer; + +import com.alipay.common.tracer.core.appender.encoder.SpanEncoder; +import com.alipay.common.tracer.core.configuration.SofaTracerConfiguration; +import com.alipay.common.tracer.core.constants.ComponentNameConstants; +import com.alipay.common.tracer.core.reporter.stat.AbstractSofaTracerStatisticReporter; +import com.alipay.common.tracer.core.span.SofaTracerSpan; +import com.alipay.common.tracer.core.tracer.AbstractClientTracer; +import com.alipay.sofa.tracer.plugins.dubbo.encoder.DubboClientDigestEncoder; +import com.alipay.sofa.tracer.plugins.dubbo.encoder.DubboClientDigestJsonEncoder; +import com.alipay.sofa.tracer.plugins.dubbo.enums.DubboLogEnum; +import com.alipay.sofa.tracer.plugins.dubbo.stat.DubboClientStatJsonReporter; +import com.alipay.sofa.tracer.plugins.dubbo.stat.DubboClientStatReporter; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/2/26 3:33 PM + * @since: + **/ +public class DubboConsumerSofaTracer extends AbstractClientTracer { + + private volatile static DubboConsumerSofaTracer dubboConsumerSofaTracer = null; + + public static DubboConsumerSofaTracer getDubboConsumerSofaTracerSingleton() { + if (dubboConsumerSofaTracer == null) { + synchronized (DubboConsumerSofaTracer.class) { + if (dubboConsumerSofaTracer == null) { + dubboConsumerSofaTracer = new DubboConsumerSofaTracer( + ComponentNameConstants.DUBBO_CLIENT); + } + } + } + return dubboConsumerSofaTracer; + } + + public DubboConsumerSofaTracer(String tracerType) { + super(tracerType); + } + + @Override + protected String getClientDigestReporterLogName() { + return DubboLogEnum.DUBBO_CLIENT_DIGEST.getDefaultLogName(); + } + + @Override + protected String getClientDigestReporterRollingKey() { + return DubboLogEnum.DUBBO_CLIENT_DIGEST.getRollingKey(); + } + + @Override + protected String getClientDigestReporterLogNameKey() { + return DubboLogEnum.DUBBO_CLIENT_DIGEST.getLogNameKey(); + } + + @Override + protected SpanEncoder getClientDigestEncoder() { + if (SofaTracerConfiguration.isJsonOutput()) { + return new DubboClientDigestJsonEncoder(); + } else { + return new DubboClientDigestEncoder(); + } + } + + @Override + protected AbstractSofaTracerStatisticReporter generateClientStatReporter() { + DubboLogEnum dubboClientStat = DubboLogEnum.DUBBO_CLIENT_STAT; + String statLog = dubboClientStat.getDefaultLogName(); + String statRollingPolicy = SofaTracerConfiguration.getRollingPolicy(dubboClientStat + .getRollingKey()); + String statLogReserveConfig = SofaTracerConfiguration.getLogReserveConfig(dubboClientStat + .getLogNameKey()); + if (SofaTracerConfiguration.isJsonOutput()) { + return new DubboClientStatJsonReporter(statLog, statRollingPolicy, statLogReserveConfig); + } else { + return new DubboClientStatReporter(statLog, statRollingPolicy, statLogReserveConfig); + } + } +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/tracer/DubboProviderSofaTracer.java b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/tracer/DubboProviderSofaTracer.java new file mode 100644 index 00000000..731e122d --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/tracer/DubboProviderSofaTracer.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.plugins.dubbo.tracer; + +import com.alipay.common.tracer.core.appender.encoder.SpanEncoder; +import com.alipay.common.tracer.core.configuration.SofaTracerConfiguration; +import com.alipay.common.tracer.core.constants.ComponentNameConstants; +import com.alipay.common.tracer.core.reporter.stat.AbstractSofaTracerStatisticReporter; +import com.alipay.common.tracer.core.span.SofaTracerSpan; +import com.alipay.common.tracer.core.tracer.AbstractServerTracer; +import com.alipay.sofa.tracer.plugins.dubbo.encoder.DubboServerDigestEncoder; +import com.alipay.sofa.tracer.plugins.dubbo.encoder.DubboServerDigestJsonEncoder; +import com.alipay.sofa.tracer.plugins.dubbo.enums.DubboLogEnum; +import com.alipay.sofa.tracer.plugins.dubbo.stat.DubboServerStatJsonReporter; +import com.alipay.sofa.tracer.plugins.dubbo.stat.DubboServerStatReporter; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/2/26 3:47 PM + * @since: + **/ +public class DubboProviderSofaTracer extends AbstractServerTracer { + + private volatile static DubboProviderSofaTracer dubboProviderSofaTracer = null; + + public static DubboProviderSofaTracer getDubboProviderSofaTracerSingleton() { + if (dubboProviderSofaTracer == null) { + synchronized (DubboProviderSofaTracer.class) { + if (dubboProviderSofaTracer == null) { + dubboProviderSofaTracer = new DubboProviderSofaTracer( + ComponentNameConstants.DUBBO_SERVER); + } + } + } + return dubboProviderSofaTracer; + } + + public DubboProviderSofaTracer(String tracerType) { + super(tracerType); + } + + @Override + protected String getServerDigestReporterLogName() { + return DubboLogEnum.DUBBO_SERVER_DIGEST.getDefaultLogName(); + } + + @Override + protected String getServerDigestReporterRollingKey() { + return DubboLogEnum.DUBBO_SERVER_DIGEST.getRollingKey(); + } + + @Override + protected String getServerDigestReporterLogNameKey() { + return DubboLogEnum.DUBBO_SERVER_DIGEST.getLogNameKey(); + } + + @Override + protected SpanEncoder getServerDigestEncoder() { + if (SofaTracerConfiguration.isJsonOutput()) { + return new DubboServerDigestJsonEncoder(); + } else { + return new DubboServerDigestEncoder(); + } + } + + @Override + protected AbstractSofaTracerStatisticReporter generateServerStatReporter() { + DubboLogEnum dubboClientStat = DubboLogEnum.DUBBO_SERVER_STAT; + String statLog = dubboClientStat.getDefaultLogName(); + String statRollingPolicy = SofaTracerConfiguration.getRollingPolicy(dubboClientStat + .getRollingKey()); + String statLogReserveConfig = SofaTracerConfiguration.getLogReserveConfig(dubboClientStat + .getLogNameKey()); + + if (SofaTracerConfiguration.isJsonOutput()) { + return new DubboServerStatJsonReporter(statLog, statRollingPolicy, statLogReserveConfig); + } else { + return new DubboServerStatReporter(statLog, statRollingPolicy, statLogReserveConfig); + } + } +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo26x/DubboSofaTracerFilter.java b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo26x/DubboSofaTracerFilter.java new file mode 100644 index 00000000..4c838d45 --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo26x/DubboSofaTracerFilter.java @@ -0,0 +1,586 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.plugins.dubbo26x; + +import com.alibaba.dubbo.common.Constants; +import com.alibaba.dubbo.common.extension.Activate; +import com.alibaba.dubbo.remoting.RemotingException; +import com.alibaba.dubbo.remoting.exchange.ResponseCallback; +import com.alibaba.dubbo.remoting.exchange.ResponseFuture; +import com.alibaba.dubbo.rpc.Filter; +import com.alibaba.dubbo.rpc.Invocation; +import com.alibaba.dubbo.rpc.Invoker; +import com.alibaba.dubbo.rpc.Result; +import com.alibaba.dubbo.rpc.RpcContext; +import com.alibaba.dubbo.rpc.RpcException; +import com.alibaba.dubbo.rpc.RpcResult; +import com.alibaba.dubbo.rpc.protocol.dubbo.FutureAdapter; +import com.alibaba.dubbo.rpc.support.RpcUtils; +import com.alipay.common.tracer.core.appender.self.SelfLog; +import com.alipay.common.tracer.core.configuration.SofaTracerConfiguration; +import com.alipay.common.tracer.core.constants.SofaTracerConstant; +import com.alipay.common.tracer.core.context.span.SofaTracerSpanContext; +import com.alipay.common.tracer.core.context.trace.SofaTraceContext; +import com.alipay.common.tracer.core.holder.SofaTraceContextHolder; +import com.alipay.common.tracer.core.samplers.Sampler; +import com.alipay.common.tracer.core.span.CommonSpanTags; +import com.alipay.common.tracer.core.span.LogData; +import com.alipay.common.tracer.core.span.SofaTracerSpan; +import com.alipay.common.tracer.core.utils.StringUtils; +import com.alipay.sofa.tracer.plugins.dubbo.constants.AttachmentKeyConstants; +import com.alipay.sofa.tracer.plugins.dubbo.tracer.DubboConsumerSofaTracer; +import com.alipay.sofa.tracer.plugins.dubbo.tracer.DubboProviderSofaTracer; + +import io.opentracing.tag.Tags; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Future; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/2/26 2:02 PM + * @since: 2.3.4 + **/ +@Activate(group = { Constants.PROVIDER, Constants.CONSUMER }, order = 1) +public class DubboSofaTracerFilter implements Filter { + + private String appName = StringUtils.EMPTY_STRING; + + private static final String BLANK = StringUtils.EMPTY_STRING; + + private DubboConsumerSofaTracer dubboConsumerSofaTracer; + + private DubboProviderSofaTracer dubboProviderSofaTracer; + + private static Map TracerSpanMap = new ConcurrentHashMap<>(); + + @Override + public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { + // do not record + if ("$echo".equals(invocation.getMethodName())) { + return invoker.invoke(invocation); + } + + RpcContext rpcContext = RpcContext.getContext(); + // get appName + if (StringUtils.isBlank(this.appName)) { + this.appName = SofaTracerConfiguration + .getProperty(SofaTracerConfiguration.TRACER_APPNAME_KEY); + } + // get span kind by rpc request type + String spanKind = spanKind(rpcContext); + Result result; + if (spanKind.equals(Tags.SPAN_KIND_SERVER)) { + result = doServerFilter(invoker, invocation); + } else { + result = doClientFilter(rpcContext, invoker, invocation); + } + return result; + } + + /** + * rpc client handler + * + * @param rpcContext + * @param invoker + * @param invocation + * @return + */ + private Result doClientFilter(RpcContext rpcContext, Invoker invoker, Invocation invocation) { + // to build tracer instance + if (dubboConsumerSofaTracer == null) { + this.dubboConsumerSofaTracer = DubboConsumerSofaTracer + .getDubboConsumerSofaTracerSingleton(); + } + // get methodName + String methodName = rpcContext.getMethodName(); + // get service interface + String service = invoker.getInterface().getSimpleName(); + // build a dubbo rpc span + SofaTracerSpan sofaTracerSpan = dubboConsumerSofaTracer.clientSend(service + "#" + + methodName); + // set tags to span + appendRpcClientSpanTags(invoker, sofaTracerSpan); + // do serialized and then transparent transmission to the rpc server + String serializedSpanContext = sofaTracerSpan.getSofaTracerSpanContext() + .serializeSpanContext(); + //put into attachments + invocation.getAttachments().put(CommonSpanTags.RPC_TRACE_NAME, serializedSpanContext); + // 同时更新rpc上下文里的内容, 防止新版 com.alibaba.dubbo.rpc.protocol.AbstractInvoker.invoke 里又用rpcContext的attachments覆盖invocation的attachments + rpcContext.setAttachment(CommonSpanTags.RPC_TRACE_NAME, serializedSpanContext); + + boolean isOneWay = false, deferFinish = false; + + // check invoke type + boolean isAsync = RpcUtils.isAsync(invoker.getUrl(), invocation); + + // set invoke type tag + if (isAsync) { + sofaTracerSpan.setTag(CommonSpanTags.INVOKE_TYPE, "future"); + } else { + isOneWay = RpcUtils.isOneway(invoker.getUrl(), invocation); + if (isOneWay) { + sofaTracerSpan.setTag(CommonSpanTags.INVOKE_TYPE, "oneway"); + } else { + sofaTracerSpan.setTag(CommonSpanTags.INVOKE_TYPE, "sync"); + } + } + + Result result; + Throwable exception = null; + String resultCode = SofaTracerConstant.RESULT_CODE_SUCCESS; + try { + // do invoke + result = invoker.invoke(invocation); + if (result.hasException()) { + exception = result.getException(); + } + // the case on async client invocation + Future future = rpcContext.getFuture(); + if (future instanceof FutureAdapter) { + deferFinish = ensureSpanFinishes(future, invocation, invoker, sofaTracerSpan); + } + return result; + } catch (RpcException e) { + exception = e; + throw e; + } catch (Throwable t) { + exception = t; + throw new RpcException(t); + } finally { + if (exception != null) { + // finish span on exception, delay to clear tl in handleError + handleError(exception, null); + } else { + // sync invoke + if (isOneWay || !deferFinish) { + dubboConsumerSofaTracer.clientReceive(resultCode); + } else { + // to clean SofaTraceContext + SofaTraceContext sofaTraceContext = SofaTraceContextHolder + .getSofaTraceContext(); + SofaTracerSpan clientSpan = sofaTraceContext.pop(); + if (clientSpan != null) { + // Record client send event + sofaTracerSpan.log(LogData.CLIENT_SEND_EVENT_VALUE); + } + if (clientSpan != null && clientSpan.getParentSofaTracerSpan() != null) { + //restore parent + sofaTraceContext.push(clientSpan.getParentSofaTracerSpan()); + } + } + } + } + } + + boolean ensureSpanFinishes(Future future, Invocation invocation, Invoker invoker, + SofaTracerSpan sofaTracerSpan) { + boolean deferFinish = false; + if (future instanceof FutureAdapter) { + deferFinish = true; + ResponseFuture original = ((FutureAdapter) future).getFuture(); + ResponseFuture wrapped = new AsyncResponseFutureDelegate(invocation, invoker, original, + sofaTracerSpan); + // Ensures even if no callback added later, for example when a consumer, we finish the span + wrapped.setCallback(null); + RpcContext.getContext().setFuture(new FutureAdapter<>(wrapped)); + } + return deferFinish; + } + + /** + * finish tracer under async + * + * @param result + * @param sofaTracerSpan + * @param invocation + */ + public static void doFinishTracerUnderAsync(Result result, SofaTracerSpan sofaTracerSpan, + Invocation invocation) { + DubboConsumerSofaTracer dubboConsumerSofaTracer = DubboConsumerSofaTracer + .getDubboConsumerSofaTracerSingleton(); + // to build tracer instance + String resultCode = SofaTracerConstant.RESULT_CODE_SUCCESS; + if (result.hasException()) { + if (result.getException() instanceof RpcException) { + resultCode = Integer.toString(((RpcException) result.getException()).getCode()); + sofaTracerSpan.setTag(CommonSpanTags.RESULT_CODE, resultCode); + } else { + resultCode = SofaTracerConstant.RESULT_CODE_ERROR; + } + } + // add elapsed time + appendElapsedTimeTags(invocation, sofaTracerSpan, result, true); + dubboConsumerSofaTracer.clientReceiveTagFinish(sofaTracerSpan, resultCode); + } + + /** + * handler when exception + * + * @param error + * @param span + */ + private static void handleError(Throwable error, SofaTracerSpan span) { + String errorCode; + if (error instanceof RpcException) { + errorCode = Integer.toString(((RpcException) error).getCode()); + } else { + errorCode = SofaTracerConstant.RESULT_CODE_ERROR; + } + if (span == null) { + SofaTracerSpan currentSpan = SofaTraceContextHolder.getSofaTraceContext() + .getCurrentSpan(); + if (currentSpan != null) { + currentSpan.setTag(Tags.ERROR.getKey(), error.getMessage()); + DubboConsumerSofaTracer.getDubboConsumerSofaTracerSingleton().clientReceive( + errorCode); + } + } else { + span.setTag(Tags.ERROR.getKey(), error.getMessage()); + DubboConsumerSofaTracer.getDubboConsumerSofaTracerSingleton().clientReceiveTagFinish( + span, errorCode); + } + } + + /** + * rpc client handler + * + * @param invoker + * @param invocation + * @return + */ + private Result doServerFilter(Invoker invoker, Invocation invocation) { + if (dubboProviderSofaTracer == null) { + this.dubboProviderSofaTracer = DubboProviderSofaTracer + .getDubboProviderSofaTracerSingleton(); + } + SofaTracerSpan sofaTracerSpan = serverReceived(invocation); + appendRpcServerSpanTags(invoker, sofaTracerSpan); + Result result; + Throwable exception = null; + try { + result = invoker.invoke(invocation); + if (result == null) { + return null; + } else { + appendElapsedTimeTags(invocation, sofaTracerSpan, result, false); + } + if (result.hasException()) { + exception = result.getException(); + } + return result; + } catch (RpcException e) { + exception = e; + throw e; + } catch (Throwable t) { + exception = t; + throw new RpcException(t); + } finally { + String resultCode = SofaTracerConstant.RESULT_CODE_SUCCESS; + if (exception != null) { + if (exception instanceof RpcException) { + sofaTracerSpan.setTag(Tags.ERROR.getKey(), exception.getMessage()); + RpcException rpcException = (RpcException) exception; + if (rpcException.isBiz()) { + resultCode = String.valueOf(rpcException.getCode()); + } + } else { + resultCode = SofaTracerConstant.RESULT_CODE_ERROR; + } + } + dubboProviderSofaTracer.serverSend(resultCode); + } + } + + /** + * dubbo server receive request + * + * @param invocation + * @return + */ + private SofaTracerSpan serverReceived(Invocation invocation) { + Map tags = new HashMap<>(); + tags.put(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER); + String serializeSpanContext = invocation.getAttachments() + .get(CommonSpanTags.RPC_TRACE_NAME); + RpcContext rpcContext = RpcContext.getContext(); + if (rpcContext != null) { + rpcContext.removeAttachment(CommonSpanTags.RPC_TRACE_NAME); + } + SofaTracerSpanContext sofaTracerSpanContext = SofaTracerSpanContext + .deserializeFromString(serializeSpanContext); + boolean isCalculateSampler = false; + boolean isSampled = true; + if (sofaTracerSpanContext == null) { + SelfLog + .error("SpanContext created error when server received and root SpanContext created."); + sofaTracerSpanContext = SofaTracerSpanContext.rootStart(); + isCalculateSampler = true; + } + String simpleName = invocation.getInvoker().getInterface().getSimpleName(); + SofaTracerSpan serverSpan = new SofaTracerSpan(dubboProviderSofaTracer.getSofaTracer(), + System.currentTimeMillis(), simpleName, sofaTracerSpanContext, tags); + // calculate sampler + if (isCalculateSampler) { + Sampler sampler = dubboProviderSofaTracer.getSofaTracer().getSampler(); + if (sampler != null) { + isSampled = sampler.sample(serverSpan).isSampled(); + } + sofaTracerSpanContext.setSampled(isSampled); + } + SofaTraceContext sofaTraceContext = SofaTraceContextHolder.getSofaTraceContext(); + // Record server receive event + serverSpan.log(LogData.SERVER_RECV_EVENT_VALUE); + sofaTraceContext.push(serverSpan); + return serverSpan; + } + + /** + * append tag + * + * @param invocation + * @param sofaTracerSpan + * @param result + * @param isClient + */ + private static void appendElapsedTimeTags(Invocation invocation, SofaTracerSpan sofaTracerSpan, + Result result, boolean isClient) { + if (sofaTracerSpan == null) { + return; + } + String reqSize; + String respSize; + String elapsed; + String deElapsed; + if (isClient) { + reqSize = invocation.getAttachment(AttachmentKeyConstants.CLIENT_SERIALIZE_SIZE); + elapsed = invocation.getAttachment(AttachmentKeyConstants.CLIENT_SERIALIZE_TIME); + respSize = result.getAttachment(AttachmentKeyConstants.CLIENT_DESERIALIZE_SIZE); + deElapsed = result.getAttachment(AttachmentKeyConstants.CLIENT_DESERIALIZE_TIME); + sofaTracerSpan.setTag(AttachmentKeyConstants.CLIENT_SERIALIZE_TIME, + parseAttachment(elapsed, 0)); + sofaTracerSpan.setTag(AttachmentKeyConstants.CLIENT_DESERIALIZE_TIME, + parseAttachment(deElapsed, 0)); + sofaTracerSpan.setTag(AttachmentKeyConstants.CLIENT_SERIALIZE_SIZE, + parseAttachment(reqSize, 0)); + sofaTracerSpan.setTag(AttachmentKeyConstants.CLIENT_DESERIALIZE_SIZE, + parseAttachment(respSize, 0)); + } else { + reqSize = invocation.getAttachment(AttachmentKeyConstants.SERVER_DESERIALIZE_SIZE); + deElapsed = invocation.getAttachment(AttachmentKeyConstants.SERVER_DESERIALIZE_TIME); + respSize = result.getAttachment(AttachmentKeyConstants.SERVER_SERIALIZE_SIZE); + elapsed = result.getAttachment(AttachmentKeyConstants.SERVER_SERIALIZE_TIME); + sofaTracerSpan.setTag(AttachmentKeyConstants.SERVER_DESERIALIZE_SIZE, + parseAttachment(reqSize, 0)); + sofaTracerSpan.setTag(AttachmentKeyConstants.SERVER_DESERIALIZE_TIME, + parseAttachment(deElapsed, 0)); + sofaTracerSpan.setTag(AttachmentKeyConstants.SERVER_SERIALIZE_SIZE, + parseAttachment(respSize, 0)); + sofaTracerSpan.setTag(AttachmentKeyConstants.SERVER_SERIALIZE_TIME, + parseAttachment(elapsed, 0)); + } + + } + + /** + * parse dubbo attachment + * + * @param value + * @param defaultVal + * @return + */ + private static int parseAttachment(String value, int defaultVal) { + try { + if (StringUtils.isNotBlank(value)) { + defaultVal = Integer.parseInt(value); + } + } catch (Exception e) { + SelfLog.error("Failed to parse Dubbo plugin params.", e); + } + return defaultVal; + } + + /** + * set rpc server span tags + * + * @param invoker + * @param sofaTracerSpan + */ + private void appendRpcServerSpanTags(Invoker invoker, SofaTracerSpan sofaTracerSpan) { + if (sofaTracerSpan == null) { + return; + } + RpcContext rpcContext = RpcContext.getContext(); + Map tagsStr = sofaTracerSpan.getTagsWithStr(); + tagsStr.put(Tags.SPAN_KIND.getKey(), spanKind(rpcContext)); + String service = invoker.getInterface().getName(); + tagsStr.put(CommonSpanTags.SERVICE, service == null ? BLANK : service); + String methodName = rpcContext.getMethodName(); + tagsStr.put(CommonSpanTags.METHOD, methodName == null ? BLANK : methodName); + String app = rpcContext.getUrl().getParameter(Constants.APPLICATION_KEY); + tagsStr.put(CommonSpanTags.REMOTE_HOST, rpcContext.getRemoteHost()); + tagsStr.put(CommonSpanTags.LOCAL_APP, app == null ? BLANK : app); + tagsStr.put(CommonSpanTags.CURRENT_THREAD_NAME, Thread.currentThread().getName()); + String protocol = rpcContext.getUrl().getProtocol(); + tagsStr.put(CommonSpanTags.PROTOCOL, protocol == null ? BLANK : protocol); + tagsStr.put(CommonSpanTags.LOCAL_HOST, rpcContext.getLocalHost()); + tagsStr.put(CommonSpanTags.LOCAL_PORT, String.valueOf(rpcContext.getLocalPort())); + } + + /** + * set rpc client span tags + * + * @param invoker + * @param sofaTracerSpan + */ + private void appendRpcClientSpanTags(Invoker invoker, SofaTracerSpan sofaTracerSpan) { + if (sofaTracerSpan == null) { + return; + } + RpcContext rpcContext = RpcContext.getContext(); + Map tagsStr = sofaTracerSpan.getTagsWithStr(); + tagsStr.put(Tags.SPAN_KIND.getKey(), spanKind(rpcContext)); + String protocol = rpcContext.getUrl().getProtocol(); + tagsStr.put(CommonSpanTags.PROTOCOL, protocol == null ? BLANK : protocol); + String service = invoker.getInterface().getName(); + tagsStr.put(CommonSpanTags.SERVICE, service == null ? BLANK : service); + String methodName = rpcContext.getMethodName(); + tagsStr.put(CommonSpanTags.METHOD, methodName == null ? BLANK : methodName); + tagsStr.put(CommonSpanTags.CURRENT_THREAD_NAME, Thread.currentThread().getName()); + String app = rpcContext.getUrl().getParameter(Constants.APPLICATION_KEY); + tagsStr.put(CommonSpanTags.LOCAL_APP, app == null ? BLANK : app); + tagsStr.put(CommonSpanTags.REMOTE_HOST, rpcContext.getRemoteHost()); + tagsStr.put(CommonSpanTags.REMOTE_PORT, String.valueOf(rpcContext.getRemotePort())); + tagsStr.put(CommonSpanTags.LOCAL_HOST, rpcContext.getLocalHost()); + } + + private String spanKind(RpcContext rpcContext) { + return rpcContext.isConsumerSide() ? Tags.SPAN_KIND_CLIENT : Tags.SPAN_KIND_SERVER; + } + + /** + * ResponseFuture Delegate Class to Resolve ResponseCallBack are covered + */ + public class AsyncResponseFutureDelegate implements ResponseFuture { + + private final ResponseFuture responseFuture; + private final Invocation invocation; + private final Invoker invoker; + private final SofaTracerSpan sofaTracerSpan; + + public AsyncResponseFutureDelegate(Invocation invocation, Invoker invoker, + ResponseFuture responseFuture, + SofaTracerSpan sofaTracerSpan) { + this.responseFuture = responseFuture; + this.invocation = invocation; + this.invoker = invoker; + this.sofaTracerSpan = sofaTracerSpan; + } + + @Override + public Object get() throws RemotingException { + return responseFuture.get(); + } + + @Override + public Object get(int timeoutInMillis) throws RemotingException { + return responseFuture.get(timeoutInMillis); + } + + @Override + public void setCallback(ResponseCallback callback) { + ResponseCallback delegate = TracingResponseCallback.create(callback, invocation, + invoker, sofaTracerSpan); + responseFuture.setCallback(delegate); + } + + @Override + public boolean isDone() { + return responseFuture.isDone(); + } + } + + static class TracingResponseCallback { + + static ResponseCallback create(ResponseCallback delegate, Invocation invocation, + Invoker invoker, SofaTracerSpan sofaTracerSpan) { + if (delegate == null) { + return new FinishSpan(invocation, invoker, sofaTracerSpan); + } + return new DelegateAndFinishSpan(delegate, invocation, invoker, sofaTracerSpan); + } + + static class FinishSpan implements ResponseCallback { + + final Invocation invocation; + final Invoker invoker; + final SofaTracerSpan sofaSpan; + + FinishSpan(Invocation invocation, Invoker invoker, SofaTracerSpan sofaSpan) { + this.invocation = invocation; + this.invoker = invoker; + this.sofaSpan = sofaSpan; + } + + @Override + public void done(Object response) { + if (response instanceof RpcResult && sofaSpan != null) { + // add elapsed time + doFinishTracerUnderAsync((RpcResult) response, sofaSpan, invocation); + } + } + + @Override + public void caught(Throwable throwable) { + // get and clear cache map + if (sofaSpan != null) { + handleError(throwable, sofaSpan); + } + } + } + + static final class DelegateAndFinishSpan extends FinishSpan { + + final ResponseCallback origin; + + DelegateAndFinishSpan(ResponseCallback origin, Invocation invocation, Invoker invoker, + SofaTracerSpan sofaSpan) { + super(invocation, invoker, sofaSpan); + this.origin = origin; + } + + @Override + public void done(Object response) { + try { + origin.done(response); + } finally { + super.done(response); + } + } + + @Override + public void caught(Throwable exception) { + try { + origin.caught(exception); + } finally { + super.caught(exception); + } + } + } + } +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo26x/wrapper/DataSizeCodecWrapper.java b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo26x/wrapper/DataSizeCodecWrapper.java new file mode 100644 index 00000000..7deb39a9 --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo26x/wrapper/DataSizeCodecWrapper.java @@ -0,0 +1,141 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.plugins.dubbo26x.wrapper; + +import com.alibaba.dubbo.remoting.Channel; +import com.alibaba.dubbo.remoting.Codec2; +import com.alibaba.dubbo.remoting.buffer.ChannelBuffer; +import com.alibaba.dubbo.remoting.exchange.Request; +import com.alibaba.dubbo.remoting.exchange.Response; +import com.alibaba.dubbo.rpc.RpcInvocation; +import com.alibaba.dubbo.rpc.RpcResult; +import com.alipay.sofa.tracer.plugins.dubbo.constants.AttachmentKeyConstants; + +import java.io.IOException; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/2/26 7:46 PM + * @since: + **/ +public class DataSizeCodecWrapper implements Codec2 { + /** + * origin codec + */ + protected Codec2 codec; + + public DataSizeCodecWrapper(Codec2 codec) { + this.codec = codec; + } + + @Override + public void encode(Channel channel, ChannelBuffer buffer, Object message) throws IOException { + if (message instanceof Request) { + Object data = ((Request) message).getData(); + if (data instanceof RpcInvocation) { + RpcInvocation invocation = (RpcInvocation) data; + encodeRequestWithTracer(channel, buffer, message, invocation); + return; + } + } else if (message instanceof Response) { + Object response = ((Response) message).getResult(); + if (response instanceof RpcResult) { + encodeResultWithTracer(channel, buffer, message); + return; + } + } + codec.encode(channel, buffer, message); + } + + /** + * @param channel a long connection + * @param buffer buffer + * @param message the original Request object + * @param invocation Invocation in Request + * @throws IOException serialization exception + */ + protected void encodeRequestWithTracer(Channel channel, ChannelBuffer buffer, Object message, + RpcInvocation invocation) throws IOException { + long startTime = System.currentTimeMillis(); + int index = buffer.writerIndex(); + // serialization + codec.encode(channel, buffer, message); + int reqSize = buffer.writerIndex() - index; + long elapsed = System.currentTimeMillis() - startTime; + invocation.setAttachment(AttachmentKeyConstants.CLIENT_SERIALIZE_SIZE, + String.valueOf(reqSize)); + invocation.setAttachment(AttachmentKeyConstants.CLIENT_SERIALIZE_TIME, + String.valueOf(elapsed)); + } + + /** + * @param channel a long connection + * @param buffer buffer + * @param message the original Request object + * @throws IOException serialization exception + */ + protected void encodeResultWithTracer(Channel channel, ChannelBuffer buffer, Object message) + throws IOException { + Object result = ((Response) message).getResult(); + long startTime = System.currentTimeMillis(); + int index = buffer.writerIndex(); + codec.encode(channel, buffer, message); + int respSize = buffer.writerIndex() - index; + long elapsed = System.currentTimeMillis() - startTime; + ((RpcResult) result).setAttachment(AttachmentKeyConstants.SERVER_SERIALIZE_SIZE, + String.valueOf(respSize)); + ((RpcResult) result).setAttachment(AttachmentKeyConstants.SERVER_SERIALIZE_TIME, + String.valueOf(elapsed)); + } + + /** + * deserialization operation + * @param channel + * @param input + * @return + * @throws IOException + */ + @Override + public Object decode(Channel channel, ChannelBuffer input) throws IOException { + long startTime = System.currentTimeMillis(); + int index = input.readerIndex(); + Object ret = codec.decode(channel, input); + int size = input.readerIndex() - index; + long elapsed = System.currentTimeMillis() - startTime; + if (ret instanceof Request) { + // server-side deserialize the Request + Object data = ((Request) ret).getData(); + if (data instanceof RpcInvocation) { + RpcInvocation invocation = (RpcInvocation) data; + invocation.setAttachment(AttachmentKeyConstants.SERVER_DESERIALIZE_SIZE, + String.valueOf(size)); + invocation.setAttachment(AttachmentKeyConstants.SERVER_DESERIALIZE_TIME, + String.valueOf(elapsed)); + } + } else if (ret instanceof Response) { + // client-side deserialize the Response + Object result = ((Response) ret).getResult(); + if (result instanceof RpcResult) { + RpcResult rpcResult = (RpcResult) result; + rpcResult.setAttachment(AttachmentKeyConstants.CLIENT_DESERIALIZE_SIZE, + String.valueOf(size)); + rpcResult.setAttachment(AttachmentKeyConstants.CLIENT_DESERIALIZE_TIME, + String.valueOf(elapsed)); + } + } + return ret; + } +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo27x/DubboSofaTracerFilter.java b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo27x/DubboSofaTracerFilter.java new file mode 100644 index 00000000..208e7208 --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo27x/DubboSofaTracerFilter.java @@ -0,0 +1,425 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.plugins.dubbo27x; + +import com.alipay.common.tracer.core.appender.self.SelfLog; +import com.alipay.common.tracer.core.configuration.SofaTracerConfiguration; +import com.alipay.common.tracer.core.constants.SofaTracerConstant; +import com.alipay.common.tracer.core.context.span.SofaTracerSpanContext; +import com.alipay.common.tracer.core.context.trace.SofaTraceContext; +import com.alipay.common.tracer.core.holder.SofaTraceContextHolder; +import com.alipay.common.tracer.core.samplers.Sampler; +import com.alipay.common.tracer.core.span.CommonSpanTags; +import com.alipay.common.tracer.core.span.LogData; +import com.alipay.common.tracer.core.span.SofaTracerSpan; +import com.alipay.common.tracer.core.utils.StringUtils; +import com.alipay.sofa.tracer.plugins.dubbo.constants.AttachmentKeyConstants; +import com.alipay.sofa.tracer.plugins.dubbo.tracer.DubboConsumerSofaTracer; +import com.alipay.sofa.tracer.plugins.dubbo.tracer.DubboProviderSofaTracer; + +import io.opentracing.SpanContext; +import io.opentracing.tag.Tags; + +import org.apache.dubbo.common.constants.CommonConstants; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.remoting.TimeoutException; +import org.apache.dubbo.rpc.Filter; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.Result; +import org.apache.dubbo.rpc.RpcContext; +import org.apache.dubbo.rpc.RpcException; +import org.apache.dubbo.rpc.support.RpcUtils; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/2/26 2:02 PM + * @since: 2.3.4 + **/ +@Activate(group = { CommonConstants.PROVIDER, CommonConstants.CONSUMER }, order = 1) +public class DubboSofaTracerFilter implements Filter { + + private String appName = StringUtils.EMPTY_STRING; + + private static final String BLANK = StringUtils.EMPTY_STRING; + + private DubboConsumerSofaTracer dubboConsumerSofaTracer; + + private DubboProviderSofaTracer dubboProviderSofaTracer; + + private static Map TracerSpanMap = new ConcurrentHashMap(); + + @Override + public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { + // do not record + if ("$echo".equals(invocation.getMethodName())) { + return invoker.invoke(invocation); + } + + RpcContext rpcContext = RpcContext.getContext(); + // get appName + if (StringUtils.isBlank(this.appName)) { + this.appName = SofaTracerConfiguration + .getProperty(SofaTracerConfiguration.TRACER_APPNAME_KEY); + } + // get span kind by rpc request type + String spanKind = spanKind(rpcContext); + Result result; + if (spanKind.equals(Tags.SPAN_KIND_SERVER)) { + result = doServerFilter(invoker, invocation); + } else { + result = doClientFilter(rpcContext, invoker, invocation); + } + return result; + } + + @Override + public Result onResponse(Result result, Invoker invoker, Invocation invocation) { + // 不管是被调用(server) 还是 调出去(client) 都会进入这个方法 + // 由于目前我们没有支持服务端异步调用, 因此在这个方法里不用处理这种case + // http://dubbo.apache.org/zh-cn/docs/user/demos/async-execute-on-provider.html + String tracerContextStr = invocation.getAttachment(CommonSpanTags.RPC_TRACE_NAME); + if (tracerContextStr == null) { + return result; + } + String spanKey = getTracerSpanMapKey(SofaTracerSpanContext + .deserializeFromString(tracerContextStr)); + SofaTracerSpan sofaTracerSpan = TracerSpanMap.remove(spanKey); + // only the asynchronous callback to print + boolean isAsync = RpcUtils.isAsync(invoker.getUrl(), invocation); + if (!isAsync) { + return result; + } + if (sofaTracerSpan != null) { + // to build tracer instance + if (dubboConsumerSofaTracer == null) { + this.dubboConsumerSofaTracer = DubboConsumerSofaTracer + .getDubboConsumerSofaTracerSingleton(); + } + String resultCode = SofaTracerConstant.RESULT_CODE_SUCCESS; + if (result.hasException()) { + if (result.getException() instanceof RpcException) { + resultCode = Integer.toString(((RpcException) result.getException()).getCode()); + sofaTracerSpan.setTag(CommonSpanTags.RESULT_CODE, resultCode); + } else { + resultCode = SofaTracerConstant.RESULT_CODE_ERROR; + } + } + // add elapsed time + appendElapsedTimeTags(invocation, sofaTracerSpan, result, true); + dubboConsumerSofaTracer.clientReceiveTagFinish(sofaTracerSpan, resultCode); + } + return result; + } + + /** + * rpc client handler + * + * @param rpcContext + * @param invoker + * @param invocation + * @return + */ + private Result doClientFilter(RpcContext rpcContext, Invoker invoker, Invocation invocation) { + // to build tracer instance + if (dubboConsumerSofaTracer == null) { + this.dubboConsumerSofaTracer = DubboConsumerSofaTracer + .getDubboConsumerSofaTracerSingleton(); + } + // get methodName + String methodName = rpcContext.getMethodName(); + // get service interface + String service = invoker.getInterface().getSimpleName(); + // build a dubbo rpc span + SofaTracerSpan sofaTracerSpan = dubboConsumerSofaTracer.clientSend(service + "#" + + methodName); + // set tags to span + appendRpcClientSpanTags(invoker, sofaTracerSpan); + // do serialized and then transparent transmission to the rpc server + String serializedSpanContext = sofaTracerSpan.getSofaTracerSpanContext() + .serializeSpanContext(); + //put into attachments + // 这里需要放到 RpcContext 里才对, 因为在 com.alibaba.dubbo.rpc.protocol.AbstractInvoker.invoke 里回拿RpcContext的attachments重新覆盖invocation的 + rpcContext.setAttachment(CommonSpanTags.RPC_TRACE_NAME, serializedSpanContext); + // check invoke type + boolean isAsync = RpcUtils.isAsync(invoker.getUrl(), invocation); + boolean isOneWay = false; + if (isAsync) { + sofaTracerSpan.setTag(CommonSpanTags.INVOKE_TYPE, "future"); + } else { + isOneWay = RpcUtils.isOneway(invoker.getUrl(), invocation); + if (isOneWay) { + sofaTracerSpan.setTag(CommonSpanTags.INVOKE_TYPE, "oneway"); + } else { + sofaTracerSpan.setTag(CommonSpanTags.INVOKE_TYPE, "sync"); + } + } + Result result; + Throwable exception = null; + String resultCode = SofaTracerConstant.RESULT_CODE_SUCCESS; + try { + // do invoke + result = invoker.invoke(invocation); + // check result + if (result == null) { + // isOneWay, we think that the current request is successful + if (isOneWay) { + sofaTracerSpan.setTag(CommonSpanTags.RESP_SIZE, 0); + } + } else { + // add elapsed time + appendElapsedTimeTags(invocation, sofaTracerSpan, result, true); + } + } catch (RpcException e) { + exception = e; + throw e; + } catch (Throwable t) { + exception = t; + throw new RpcException(t); + } finally { + if (exception != null) { + if (exception instanceof RpcException) { + sofaTracerSpan.setTag(Tags.ERROR.getKey(), exception.getMessage()); + RpcException rpcException = (RpcException) exception; + resultCode = String.valueOf(rpcException.getCode()); + } else { + resultCode = SofaTracerConstant.RESULT_CODE_ERROR; + } + } + + if (!isAsync) { + dubboConsumerSofaTracer.clientReceive(resultCode); + } else { + SofaTraceContext sofaTraceContext = SofaTraceContextHolder.getSofaTraceContext(); + SofaTracerSpan clientSpan = sofaTraceContext.pop(); + if (clientSpan != null) { + // Record client send event + sofaTracerSpan.log(LogData.CLIENT_SEND_EVENT_VALUE); + // cache the current span + // 别使用invoker作为key, 因为它并不是每次请求都new一个, 而是复用的 + TracerSpanMap.put(getTracerSpanMapKey(clientSpan.getSofaTracerSpanContext()), sofaTracerSpan); + } + if (clientSpan != null && clientSpan.getParentSofaTracerSpan() != null) { + //restore parent + sofaTraceContext.push(clientSpan.getParentSofaTracerSpan()); + } + CompletableFuture future = (CompletableFuture) rpcContext.getFuture(); + future.whenComplete((object, throwable) -> { + if (throwable != null && throwable instanceof TimeoutException) { + sofaTracerSpan.setTag(Tags.ERROR.getKey(), throwable.getMessage()); + dubboConsumerSofaTracer.clientReceiveTagFinish(sofaTracerSpan, "03"); + } + }); + } + } + return result; + } + + /** + * rpc client handler + * + * @param invoker + * @param invocation + * @return + */ + private Result doServerFilter(Invoker invoker, Invocation invocation) { + if (dubboProviderSofaTracer == null) { + this.dubboProviderSofaTracer = DubboProviderSofaTracer + .getDubboProviderSofaTracerSingleton(); + } + SofaTracerSpan sofaTracerSpan = serverReceived(invocation); + appendRpcServerSpanTags(invoker, sofaTracerSpan); + Result result; + Throwable exception = null; + try { + result = invoker.invoke(invocation); + if (result == null) { + return null; + } else { + appendElapsedTimeTags(invocation, sofaTracerSpan, result, false); + } + if (result.hasException()) { + exception = result.getException(); + } + return result; + } catch (RpcException e) { + exception = e; + throw e; + } catch (Throwable t) { + exception = t; + throw new RpcException(t); + } finally { + String resultCode = SofaTracerConstant.RESULT_CODE_SUCCESS; + if (exception != null) { + if (exception instanceof RpcException) { + sofaTracerSpan.setTag(Tags.ERROR.getKey(), exception.getMessage()); + RpcException rpcException = (RpcException) exception; + if (rpcException.isBiz()) { + resultCode = String.valueOf(rpcException.getCode()); + } + } else { + resultCode = SofaTracerConstant.RESULT_CODE_ERROR; + } + } + dubboProviderSofaTracer.serverSend(resultCode); + } + } + + private SofaTracerSpan serverReceived(Invocation invocation) { + Map tags = new HashMap<>(); + tags.put(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER); + // 这里也可以从RpcContext取数据, 两者的结果应该是一样的 + String serializeSpanContext = invocation.getAttachments() + .get(CommonSpanTags.RPC_TRACE_NAME); + SofaTracerSpanContext sofaTracerSpanContext = SofaTracerSpanContext + .deserializeFromString(serializeSpanContext); + boolean isCalculateSampler = false; + boolean isSampled = true; + if (sofaTracerSpanContext == null) { + SelfLog + .error("SpanContext created error when server received and root SpanContext created."); + sofaTracerSpanContext = SofaTracerSpanContext.rootStart(); + isCalculateSampler = true; + } + String simpleName = invocation.getInvoker().getInterface().getSimpleName(); + SofaTracerSpan serverSpan = new SofaTracerSpan(dubboProviderSofaTracer.getSofaTracer(), + System.currentTimeMillis(), simpleName, sofaTracerSpanContext, tags); + // calculate sampler + if (isCalculateSampler) { + Sampler sampler = dubboProviderSofaTracer.getSofaTracer().getSampler(); + if (sampler != null) { + isSampled = sampler.sample(serverSpan).isSampled(); + } + sofaTracerSpanContext.setSampled(isSampled); + } + SofaTraceContext sofaTraceContext = SofaTraceContextHolder.getSofaTraceContext(); + // Record server receive event + serverSpan.log(LogData.SERVER_RECV_EVENT_VALUE); + sofaTraceContext.push(serverSpan); + return serverSpan; + } + + private void appendElapsedTimeTags(Invocation invocation, SofaTracerSpan sofaTracerSpan, + Result result, boolean isClient) { + if (sofaTracerSpan == null) { + return; + } + String reqSize; + String respSize; + String elapsed; + String deElapsed; + if (isClient) { + reqSize = invocation.getAttachment(AttachmentKeyConstants.CLIENT_SERIALIZE_SIZE); + elapsed = invocation.getAttachment(AttachmentKeyConstants.CLIENT_SERIALIZE_TIME); + respSize = result.getAttachment(AttachmentKeyConstants.CLIENT_DESERIALIZE_SIZE); + deElapsed = result.getAttachment(AttachmentKeyConstants.CLIENT_DESERIALIZE_TIME); + sofaTracerSpan.setTag(AttachmentKeyConstants.CLIENT_SERIALIZE_TIME, + parseAttachment(elapsed, 0)); + sofaTracerSpan.setTag(AttachmentKeyConstants.CLIENT_DESERIALIZE_TIME, + parseAttachment(deElapsed, 0)); + sofaTracerSpan.setTag(AttachmentKeyConstants.CLIENT_SERIALIZE_SIZE, + parseAttachment(reqSize, 0)); + sofaTracerSpan.setTag(AttachmentKeyConstants.CLIENT_DESERIALIZE_SIZE, + parseAttachment(respSize, 0)); + } else { + reqSize = invocation.getAttachment(AttachmentKeyConstants.SERVER_DESERIALIZE_SIZE); + deElapsed = invocation.getAttachment(AttachmentKeyConstants.SERVER_DESERIALIZE_TIME); + respSize = result.getAttachment(AttachmentKeyConstants.SERVER_SERIALIZE_SIZE); + elapsed = result.getAttachment(AttachmentKeyConstants.SERVER_SERIALIZE_TIME); + sofaTracerSpan.setTag(AttachmentKeyConstants.SERVER_DESERIALIZE_SIZE, + parseAttachment(reqSize, 0)); + sofaTracerSpan.setTag(AttachmentKeyConstants.SERVER_DESERIALIZE_TIME, + parseAttachment(deElapsed, 0)); + sofaTracerSpan.setTag(AttachmentKeyConstants.SERVER_SERIALIZE_SIZE, + parseAttachment(respSize, 0)); + sofaTracerSpan.setTag(AttachmentKeyConstants.SERVER_SERIALIZE_TIME, + parseAttachment(elapsed, 0)); + } + + } + + private int parseAttachment(String value, int defaultVal) { + try { + if (StringUtils.isNotBlank(value)) { + defaultVal = Integer.parseInt(value); + } + } catch (Exception e) { + SelfLog.error("Failed to parse Dubbo plugin params.", e); + } + return defaultVal; + } + + /** + * set rpc server span tags + * + * @param invoker + * @param sofaTracerSpan + */ + private void appendRpcServerSpanTags(Invoker invoker, SofaTracerSpan sofaTracerSpan) { + if (sofaTracerSpan == null) { + return; + } + RpcContext rpcContext = RpcContext.getContext(); + Map tagsStr = sofaTracerSpan.getTagsWithStr(); + tagsStr.put(Tags.SPAN_KIND.getKey(), spanKind(rpcContext)); + String service = invoker.getInterface().getName(); + tagsStr.put(CommonSpanTags.SERVICE, service == null ? BLANK : service); + String methodName = rpcContext.getMethodName(); + tagsStr.put(CommonSpanTags.METHOD, methodName == null ? BLANK : methodName); + String app = rpcContext.getUrl().getParameter(CommonConstants.APPLICATION_KEY); + tagsStr.put(CommonSpanTags.REMOTE_HOST, rpcContext.getRemoteHost()); + tagsStr.put(CommonSpanTags.LOCAL_APP, app == null ? BLANK : app); + tagsStr.put(CommonSpanTags.CURRENT_THREAD_NAME, Thread.currentThread().getName()); + String protocol = rpcContext.getUrl().getProtocol(); + tagsStr.put(CommonSpanTags.PROTOCOL, protocol == null ? BLANK : protocol); + tagsStr.put(CommonSpanTags.LOCAL_HOST, rpcContext.getLocalHost()); + tagsStr.put(CommonSpanTags.LOCAL_PORT, String.valueOf(rpcContext.getLocalPort())); + } + + private void appendRpcClientSpanTags(Invoker invoker, SofaTracerSpan sofaTracerSpan) { + if (sofaTracerSpan == null) { + return; + } + RpcContext rpcContext = RpcContext.getContext(); + Map tagsStr = sofaTracerSpan.getTagsWithStr(); + tagsStr.put(Tags.SPAN_KIND.getKey(), spanKind(rpcContext)); + String protocol = rpcContext.getUrl().getProtocol(); + tagsStr.put(CommonSpanTags.PROTOCOL, protocol == null ? BLANK : protocol); + String service = invoker.getInterface().getName(); + tagsStr.put(CommonSpanTags.SERVICE, service == null ? BLANK : service); + String methodName = rpcContext.getMethodName(); + tagsStr.put(CommonSpanTags.METHOD, methodName == null ? BLANK : methodName); + tagsStr.put(CommonSpanTags.CURRENT_THREAD_NAME, Thread.currentThread().getName()); + String app = rpcContext.getUrl().getParameter(CommonConstants.APPLICATION_KEY); + tagsStr.put(CommonSpanTags.LOCAL_APP, app == null ? BLANK : app); + tagsStr.put(CommonSpanTags.REMOTE_HOST, rpcContext.getRemoteHost()); + tagsStr.put(CommonSpanTags.REMOTE_PORT, String.valueOf(rpcContext.getRemotePort())); + tagsStr.put(CommonSpanTags.LOCAL_HOST, rpcContext.getLocalHost()); + } + + private String spanKind(RpcContext rpcContext) { + return rpcContext.isConsumerSide() ? Tags.SPAN_KIND_CLIENT : Tags.SPAN_KIND_SERVER; + } + + private String getTracerSpanMapKey(SofaTracerSpanContext context) { + return context.getTraceId() + "/" + context.getSpanId(); + } +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo27x/wrapper/DataSizeCodecWrapper.java b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo27x/wrapper/DataSizeCodecWrapper.java new file mode 100644 index 00000000..2ecbc072 --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo27x/wrapper/DataSizeCodecWrapper.java @@ -0,0 +1,141 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.tracer.plugins.dubbo27x.wrapper; + +import com.alipay.sofa.tracer.plugins.dubbo.constants.AttachmentKeyConstants; +import org.apache.dubbo.remoting.Channel; +import org.apache.dubbo.remoting.Codec2; +import org.apache.dubbo.remoting.buffer.ChannelBuffer; +import org.apache.dubbo.remoting.exchange.Request; +import org.apache.dubbo.remoting.exchange.Response; +import org.apache.dubbo.rpc.AppResponse; +import org.apache.dubbo.rpc.RpcInvocation; + +import java.io.IOException; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/2/26 7:46 PM + * @since: + **/ +public class DataSizeCodecWrapper implements Codec2 { + /** + * origin codec + */ + protected Codec2 codec; + + public DataSizeCodecWrapper(Codec2 codec) { + this.codec = codec; + } + + @Override + public void encode(Channel channel, ChannelBuffer buffer, Object message) throws IOException { + if (message instanceof Request) { + Object data = ((Request) message).getData(); + if (data instanceof RpcInvocation) { + RpcInvocation invocation = (RpcInvocation) data; + encodeRequestWithTracer(channel, buffer, message, invocation); + return; + } + } else if (message instanceof Response) { + Object response = ((Response) message).getResult(); + if (response instanceof AppResponse) { + encodeResultWithTracer(channel, buffer, message); + return; + } + } + codec.encode(channel, buffer, message); + } + + /** + * @param channel a long connection + * @param buffer buffer + * @param message the original Request object + * @param invocation Invocation in Request + * @throws IOException serialization exception + */ + protected void encodeRequestWithTracer(Channel channel, ChannelBuffer buffer, Object message, + RpcInvocation invocation) throws IOException { + long startTime = System.currentTimeMillis(); + int index = buffer.writerIndex(); + // serialization + codec.encode(channel, buffer, message); + int reqSize = buffer.writerIndex() - index; + long elapsed = System.currentTimeMillis() - startTime; + invocation.setAttachment(AttachmentKeyConstants.CLIENT_SERIALIZE_SIZE, + String.valueOf(reqSize)); + invocation.setAttachment(AttachmentKeyConstants.CLIENT_SERIALIZE_TIME, + String.valueOf(elapsed)); + } + + /** + * @param channel a long connection + * @param buffer buffer + * @param message the original Request object + * @throws IOException serialization exception + */ + protected void encodeResultWithTracer(Channel channel, ChannelBuffer buffer, Object message) + throws IOException { + Object result = ((Response) message).getResult(); + long startTime = System.currentTimeMillis(); + int index = buffer.writerIndex(); + codec.encode(channel, buffer, message); + int respSize = buffer.writerIndex() - index; + long elapsed = System.currentTimeMillis() - startTime; + ((AppResponse) result).setAttachment(AttachmentKeyConstants.SERVER_SERIALIZE_SIZE, + String.valueOf(respSize)); + ((AppResponse) result).setAttachment(AttachmentKeyConstants.SERVER_SERIALIZE_TIME, + String.valueOf(elapsed)); + } + + /** + * deserialization operation + * @param channel + * @param input + * @return + * @throws IOException + */ + @Override + public Object decode(Channel channel, ChannelBuffer input) throws IOException { + long startTime = System.currentTimeMillis(); + int index = input.readerIndex(); + Object ret = codec.decode(channel, input); + int size = input.readerIndex() - index; + long elapsed = System.currentTimeMillis() - startTime; + if (ret instanceof Request) { + // server-side deserialize the Request + Object data = ((Request) ret).getData(); + if (data instanceof RpcInvocation) { + RpcInvocation invocation = (RpcInvocation) data; + invocation.setAttachment(AttachmentKeyConstants.SERVER_DESERIALIZE_SIZE, + String.valueOf(size)); + invocation.setAttachment(AttachmentKeyConstants.SERVER_DESERIALIZE_TIME, + String.valueOf(elapsed)); + } + } else if (ret instanceof Response) { + // client-side deserialize the Response + Object result = ((Response) ret).getResult(); + if (result instanceof AppResponse) { + AppResponse rpcResult = (AppResponse) result; + rpcResult.setAttachment(AttachmentKeyConstants.CLIENT_DESERIALIZE_SIZE, + String.valueOf(size)); + rpcResult.setAttachment(AttachmentKeyConstants.CLIENT_DESERIALIZE_TIME, + String.valueOf(elapsed)); + } + } + return ret; + } +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.remoting.Codec2 b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.remoting.Codec2 new file mode 100644 index 00000000..d1389d96 --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.remoting.Codec2 @@ -0,0 +1 @@ +tracerCodec=com.alipay.sofa.tracer.plugins.dubbo26x.wrapper.DataSizeCodecWrapper \ No newline at end of file diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter new file mode 100644 index 00000000..a52a2a26 --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter @@ -0,0 +1 @@ +dubboSofaTracerFilter=com.alipay.sofa.tracer.plugins.dubbo26x.DubboSofaTracerFilter diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/resources/META-INF/dubbo/org.apache.dubbo.remoting.Codec2 b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/resources/META-INF/dubbo/org.apache.dubbo.remoting.Codec2 new file mode 100644 index 00000000..d7849057 --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/resources/META-INF/dubbo/org.apache.dubbo.remoting.Codec2 @@ -0,0 +1 @@ +tracerCodec=com.alipay.sofa.tracer.plugins.dubbo27x.wrapper.DataSizeCodecWrapper \ No newline at end of file diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter new file mode 100644 index 00000000..c0942b4d --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-common-plugin/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter @@ -0,0 +1 @@ +dubboSofaTracerFilter=com.alipay.sofa.tracer.plugins.dubbo27x.DubboSofaTracerFilter \ No newline at end of file diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/pom.xml b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/pom.xml index dec47d48..fb4e6efe 100644 --- a/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/pom.xml +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/pom.xml @@ -5,7 +5,7 @@ tracer-all-parent com.alipay.sofa - 3.0.11 + 3.0.12 ../../pom.xml 4.0.0 diff --git a/sofa-tracer-plugins/sofa-tracer-flexible-plugin/pom.xml b/sofa-tracer-plugins/sofa-tracer-flexible-plugin/pom.xml index 047a096c..0af76a28 100644 --- a/sofa-tracer-plugins/sofa-tracer-flexible-plugin/pom.xml +++ b/sofa-tracer-plugins/sofa-tracer-flexible-plugin/pom.xml @@ -5,7 +5,7 @@ tracer-all-parent com.alipay.sofa - 3.0.11 + 3.0.12 ../../pom.xml 4.0.0 diff --git a/sofa-tracer-plugins/sofa-tracer-httpclient-plugin/pom.xml b/sofa-tracer-plugins/sofa-tracer-httpclient-plugin/pom.xml index 16a802fb..3d365437 100644 --- a/sofa-tracer-plugins/sofa-tracer-httpclient-plugin/pom.xml +++ b/sofa-tracer-plugins/sofa-tracer-httpclient-plugin/pom.xml @@ -5,7 +5,7 @@ tracer-all-parent com.alipay.sofa - 3.0.11 + 3.0.12 ../../pom.xml 4.0.0 diff --git a/sofa-tracer-plugins/sofa-tracer-okhttp-plugin/pom.xml b/sofa-tracer-plugins/sofa-tracer-okhttp-plugin/pom.xml index f8a47b76..9e2236a9 100644 --- a/sofa-tracer-plugins/sofa-tracer-okhttp-plugin/pom.xml +++ b/sofa-tracer-plugins/sofa-tracer-okhttp-plugin/pom.xml @@ -5,7 +5,7 @@ tracer-all-parent com.alipay.sofa - 3.0.11 + 3.0.12 ../../pom.xml 4.0.0 @@ -21,6 +21,7 @@ com.squareup.okhttp3 okhttp 3.12.1 + true @@ -65,4 +66,4 @@ - \ No newline at end of file + diff --git a/sofa-tracer-plugins/sofa-tracer-resttmplate-plugin/pom.xml b/sofa-tracer-plugins/sofa-tracer-resttmplate-plugin/pom.xml index 1caf88b6..e8870c46 100644 --- a/sofa-tracer-plugins/sofa-tracer-resttmplate-plugin/pom.xml +++ b/sofa-tracer-plugins/sofa-tracer-resttmplate-plugin/pom.xml @@ -5,7 +5,7 @@ tracer-all-parent com.alipay.sofa - 3.0.11 + 3.0.12 ../../pom.xml 4.0.0 diff --git a/sofa-tracer-plugins/sofa-tracer-spring-cloud-plugin/pom.xml b/sofa-tracer-plugins/sofa-tracer-spring-cloud-plugin/pom.xml index e79b4926..f9e693ad 100644 --- a/sofa-tracer-plugins/sofa-tracer-spring-cloud-plugin/pom.xml +++ b/sofa-tracer-plugins/sofa-tracer-spring-cloud-plugin/pom.xml @@ -5,7 +5,7 @@ tracer-all-parent com.alipay.sofa - 3.0.11 + 3.0.12 ../../pom.xml 4.0.0 @@ -16,6 +16,7 @@ org.springframework.cloud spring-cloud-starter-openfeign + true com.alipay.sofa @@ -26,4 +27,4 @@ tracer-extensions - \ No newline at end of file + diff --git a/sofa-tracer-plugins/sofa-tracer-spring-cloud-plugin/src/main/java/com/alipay/sofa/tracer/plugins/springcloud/instruments/feign/SofaTracerFeignClient.java b/sofa-tracer-plugins/sofa-tracer-spring-cloud-plugin/src/main/java/com/alipay/sofa/tracer/plugins/springcloud/instruments/feign/SofaTracerFeignClient.java index 988bcb72..de686609 100644 --- a/sofa-tracer-plugins/sofa-tracer-spring-cloud-plugin/src/main/java/com/alipay/sofa/tracer/plugins/springcloud/instruments/feign/SofaTracerFeignClient.java +++ b/sofa-tracer-plugins/sofa-tracer-spring-cloud-plugin/src/main/java/com/alipay/sofa/tracer/plugins/springcloud/instruments/feign/SofaTracerFeignClient.java @@ -107,7 +107,11 @@ private void appendResponseSpanTags(Response response, SofaTracerSpan sofaTracer if (sofaTracerSpan == null) { return; } - sofaTracerSpan.setTag(CommonSpanTags.RESP_SIZE, response.body().length()); + Integer responseSize = null; + if (response.body() != null) { + responseSize = response.body().length(); + } + sofaTracerSpan.setTag(CommonSpanTags.RESP_SIZE, responseSize); sofaTracerSpan.setTag(CommonSpanTags.CURRENT_THREAD_NAME, Thread.currentThread().getName()); sofaTracerSpan.setTag(CommonSpanTags.RESULT_CODE, response.status()); } diff --git a/sofa-tracer-plugins/sofa-tracer-springmvc-plugin/pom.xml b/sofa-tracer-plugins/sofa-tracer-springmvc-plugin/pom.xml index 3810f1e9..fa433b45 100644 --- a/sofa-tracer-plugins/sofa-tracer-springmvc-plugin/pom.xml +++ b/sofa-tracer-plugins/sofa-tracer-springmvc-plugin/pom.xml @@ -4,7 +4,7 @@ tracer-all-parent com.alipay.sofa - 3.0.11 + 3.0.12 ../../pom.xml diff --git a/sofa-tracer-plugins/sofa-tracer-zipkin-plugin/pom.xml b/sofa-tracer-plugins/sofa-tracer-zipkin-plugin/pom.xml index 11212345..05c5714a 100644 --- a/sofa-tracer-plugins/sofa-tracer-zipkin-plugin/pom.xml +++ b/sofa-tracer-plugins/sofa-tracer-zipkin-plugin/pom.xml @@ -5,7 +5,7 @@ tracer-all-parent com.alipay.sofa - 3.0.11 + 3.0.12 ../../pom.xml 4.0.0 @@ -99,4 +99,4 @@ - \ No newline at end of file + diff --git a/tracer-all/pom.xml b/tracer-all/pom.xml index f8038203..71853c1d 100644 --- a/tracer-all/pom.xml +++ b/tracer-all/pom.xml @@ -5,12 +5,12 @@ tracer-all-parent com.alipay.sofa - 3.0.11 + 3.0.12 4.0.0 tracer-all - 3.0.11 + 3.0.12 jar SOFATracer in one without SOFABoot starter diff --git a/tracer-core/pom.xml b/tracer-core/pom.xml index aaf0e06a..40ab8674 100644 --- a/tracer-core/pom.xml +++ b/tracer-core/pom.xml @@ -4,7 +4,7 @@ tracer-all-parent com.alipay.sofa - 3.0.11 + 3.0.12 ../pom.xml diff --git a/tracer-extensions/pom.xml b/tracer-extensions/pom.xml index 8e8631dc..eaf88e45 100644 --- a/tracer-extensions/pom.xml +++ b/tracer-extensions/pom.xml @@ -4,7 +4,7 @@ tracer-all-parent com.alipay.sofa - 3.0.11 + 3.0.12 tracer-extensions diff --git a/tracer-sofa-boot-starter/pom.xml b/tracer-sofa-boot-starter/pom.xml index 9f2a1353..26419e2f 100644 --- a/tracer-sofa-boot-starter/pom.xml +++ b/tracer-sofa-boot-starter/pom.xml @@ -5,7 +5,7 @@ tracer-all-parent com.alipay.sofa - 3.0.11 + 3.0.12 ../pom.xml @@ -53,7 +53,7 @@ com.alipay.sofa - sofa-tracer-dubbo-plugin + sofa-tracer-dubbo-common-plugin com.alipay.sofa @@ -65,6 +65,11 @@ sofa-tracer-flexible-plugin + + com.alipay.sofa + sofa-tracer-okhttp-plugin + + org.springframework.boot spring-boot @@ -98,7 +103,7 @@ io.zipkin.reporter2 zipkin-reporter - 2.7.13 + 2.7.15 true diff --git a/tracer-test/core-test/pom.xml b/tracer-test/core-test/pom.xml index 5ebdbb4e..acade523 100644 --- a/tracer-test/core-test/pom.xml +++ b/tracer-test/core-test/pom.xml @@ -4,7 +4,7 @@ tracer-all-parent com.alipay.sofa - 3.0.11 + 3.0.12 ../../pom.xml diff --git a/tracer-test/log4j-test/pom.xml b/tracer-test/log4j-test/pom.xml index bbb7bdc6..d877a1e9 100644 --- a/tracer-test/log4j-test/pom.xml +++ b/tracer-test/log4j-test/pom.xml @@ -4,7 +4,7 @@ tracer-all-parent com.alipay.sofa - 3.0.11 + 3.0.12 ../../pom.xml diff --git a/tracer-test/log4j2-test/pom.xml b/tracer-test/log4j2-test/pom.xml index c469928e..d3e50ceb 100644 --- a/tracer-test/log4j2-test/pom.xml +++ b/tracer-test/log4j2-test/pom.xml @@ -4,7 +4,7 @@ tracer-all-parent com.alipay.sofa - 3.0.11 + 3.0.12 ../../pom.xml diff --git a/tracer-test/logback-test/pom.xml b/tracer-test/logback-test/pom.xml index ce560957..0405e230 100644 --- a/tracer-test/logback-test/pom.xml +++ b/tracer-test/logback-test/pom.xml @@ -4,7 +4,7 @@ tracer-all-parent com.alipay.sofa - 3.0.11 + 3.0.12 ../../pom.xml