注意:该功能随原生网络监控功能一并开启,否则无法生效。
一、前提条件
qapmplugin 升级至3.6版本,默认会对 gRPC 的 OkHttpChannelBuilder 的 build 方法插桩。
二、配置步骤
// 原代码ManagedChannel channel = OkHttpChannelBuilder.forAddress(host, port).usePlaintext().build();// 替换成以下代码OkHttpChannelBuilder builder = OkHttpChannelBuilder.forAddress(host, port).usePlaintext();ManagedChannel channel = QAPMGrpcInstrumentation.builderInit(builder);
三、手动集成
如果你的 gRPC 不是使用上述 API 来创建的,或者是插桩失败,则需要手动添加拦截器。
四、配置步骤
import com.tencent.qapmsdk.impl.instrumentation.grpc.QAPMGrpcInterceptor;xxxx.intercept(new QAPMGrpcInterceptor())
五、添加混淆
SDK 会有反射 gRPC 接口的相关动作,为了避免混淆 GRPC SDK,在 App 的 proguard-rules.pro 文件中增加以下配置。
-keep class io.grpc.** { *; }
六、相关接口
为了开发更方便的分析 gRPC 的性能问题,我们提供了如下的相关回调接口。
QAPM.setProperty(QAPM.PropertyGrpcListener, new IGrpcListener() { @Override public void onStart(QAPMGrpcRequestMeta meta) { meta.customFieldUd1 = "onStart"; Log.e(TAG, "onStart: " + meta.bareMethod + " " + meta.serviceName + " " + meta.methodType); } @Override public void sendMessage(QAPMGrpcRequestMeta meta) { meta.customFieldUd2 = "sendMessage"; Log.e(TAG, "sendMessage: " + meta.reqBody.get(meta.reqBody.size() – 1)); } @Override public void onRequest(QAPMGrpcRequestMeta meta) { meta.customFieldUd3 = "onRequest"; } @Override public void onMessage(QAPMGrpcRequestMeta meta) { meta.customFieldUd4 = "onMessage"; meta.customFieldUv1 = 10009; Log.e(TAG, "onMessage: " + meta.respBody.get(meta.respBody.size() – 1)); } @Override public void onClose(QAPMGrpcRequestMeta meta) { meta.customFieldUd5 = "onClose"; meta.customFieldUv2 = 10008; Log.e(TAG, "onClose: " + meta.status); }});
·实现上述接口,我们会在5个不同的时机分别回调。
| 回调方法 | 回调时机 |
| onStart | 接口开始执行 |
| sendMessage | 每次发送消息的时候 |
| onRequest | 每次请求后台的时候 |
| onMessage | 每次接收消息的时候 |
| onClose | 请求结束的时候 |
·其中 QAPMGrpcRequestMeta 的结构如下:
public class QAPMGrpcRequestMeta<ReqT, RespT> { public String bareMethod; public String serviceName; public MethodDescriptor.MethodType methodType; // 请求的响应体,每一次信息都会追加到这个list中,最后一个为最新接收的消息 public List<RespT> respBody = new ArrayList<>(); // 请求的body, 每一次信息都会追加到这个list中,最后一个为最新发送的消息 public List<ReqT> reqBody = new ArrayList<>(); // 请求的头部信息 public Map<String, String> requestHeaders; // 响应的头部信息 public Map<String, String> responseHeaders; // 最终结果 public Status status; public void addRespBody(RespT respBody) { this.respBody.add(respBody); } public void addReqBody(ReqT reqBody) { this.reqBody.add(reqBody); } /** * 开放字段uv1-uv10,用于指标聚合 */ public long customFieldUv1; public long customFieldUv2; public long customFieldUv3; public long customFieldUv4; public long customFieldUv5; public long customFieldUv6; public long customFieldUv7; public long customFieldUv8; public long customFieldUv9; public long customFieldUv10; /** * 开放字段ud1-ud5,用于日志上下文展示 */ public String customFieldUd1; public String customFieldUd2; public String customFieldUd3; public String customFieldUd4; public String customFieldUd5;}
·开发可以根据 bareMethod、serviceName 等信息,动态的修改开放字段,开放字段会在当条请求结束后,跟随打包一起上报到后台。
七、校验功能是否正常
·检索 TAG:QAPM_manager_QAPMPluginManager,打印如下日志则表示功能正常开启。
·检索 TAG: [plugin::142]。每次网络请求后1分钟,如打印以下日志,则代表网络数据上报成功: