Okhttp3日志采集功能
原文地址以示尊重:http://www.jianshu.com/p/d836271b1ae4
日志采集是一个APP必备的功能,可以方便开发人员快速定位问题,解决问题,那么我们在使用okhttp的时候应该怎样添加日志功能呢?
直接上干货
private class LogInterceptor implements Interceptor {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Log.v("zcb", "request:" + request.toString());
long t1 = System.nanoTime();
okhttp3.Response response = chain.proceed(chain.request());
long t2 = System.nanoTime();
Log.v("zcb", String.format(Locale.getDefault(), "Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers()));
okhttp3.MediaType mediaType = response.body().contentType();
String content = response.body().string();
Log.i("zcb", "response body:" + content);
return response.newBuilder()
.body(okhttp3.ResponseBody.create(mediaType, content))
.build();
}
}
...
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(new LogInterceptor())
.build();
首先我们实现了一个拦截器LogInterceptor,里面做了三件事情:打印request内容->执行request->打印response内容,过程简单清晰。但是有一个地方需要注意一下,在调用了response.body().string()方法之后,response中的流会被关闭,我们需要创建出一个新的response给应用层处理。手快的同学已经敲完了代码并验证了一遍,发现拦截器中能获取到body的内容,但是在拦截器外面就获取不到了。
这是为什么呢?Talk is cheap show me the code。先看一下response.body().string()的实现
public final String string() throws IOException {
return new String(bytes(), charset().name());
}
string()调用了bytes()来获取内容
public final byte[] bytes() throws IOException {
//省略部分代码
BufferedSource source = source();
byte[] bytes;
try {
bytes = source.readByteArray();
} finally {
Util.closeQuietly(source);
}
//省略部分代码
return bytes;
}
在bytes()方法中先得到了BufferedSource,然后将BufferedSource中的内容读取出来,最后将BufferedSource中的文件流关闭,似乎并没有什么问题。等等,我们在拦截器中将BufferedSource中的文件流关闭,而在ResponseBody中没有相应的数据缓存,所以我们在拦截器外部再想获取body的内容就失败了,一切终于真相大白。
可以看到,我们在拦截器中相当于手动处理了网络请求的整个过程,这就意味着在拦截器中可以做非常多的事情,例如虚拟一个返回结果等等,这些就不是本文的内容了。
Update
使用Logging Interceptor可以很轻松的实现日志采集功能,具体细节参考
参考内容:
[1]. https://github.com/square/okhttp/wiki/Interceptors
Okhttp3日志采集功能的更多相关文章
- 基于Flume+LOG4J+Kafka的日志采集架构方案
本文将会介绍如何使用 Flume.log4j.Kafka进行规范的日志采集. Flume 基本概念 Flume是一个完善.强大的日志采集工具,关于它的配置,在网上有很多现成的例子和资料,这里仅做简单说 ...
- flume日志采集
1. Log4j Appender 1.1. 使用说明 1.1.2. Client端Log4j配置文件 (黄色文字为需要配置的内容) log4j.rootLogger=INFO,A1,R # C ...
- 日志采集框架Flume以及Flume的安装部署(一个分布式、可靠、和高可用的海量日志采集、聚合和传输的系统)
Flume支持众多的source和sink类型,详细手册可参考官方文档,更多source和sink组件 http://flume.apache.org/FlumeUserGuide.html Flum ...
- 苏宁基于Spark Streaming的实时日志分析系统实践 Spark Streaming 在数据平台日志解析功能的应用
https://mp.weixin.qq.com/s/KPTM02-ICt72_7ZdRZIHBA 苏宁基于Spark Streaming的实时日志分析系统实践 原创: AI+落地实践 AI前线 20 ...
- 海量日志采集Flume(HA)
海量日志采集Flume(HA) 1.介绍: Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集.聚合和传输的系统,Flume支持在日志系统中定制各类数据发送方,用于收集数据 ...
- Filebeat+Kafka+Logstash+ElasticSearch+Kibana 日志采集方案
前言 Elastic Stack 提供 Beats 和 Logstash 套件来采集任何来源.任何格式的数据.其实Beats 和 Logstash的功能差不多,都能够与 Elasticsearch 产 ...
- idou老师教你学Istio :如何用istio实现监控和日志采集
大家都知道istio可以帮助我们实现灰度发布.流量监控.流量治理等功能.每一个功能都帮助我们在不同场景中实现不同的业务.那Istio是如何帮助我们实现监控和日志采集的呢? 这里我们依然以Bookinf ...
- 2018年ElasticSearch6.2.2教程ELK搭建日志采集分析系统(教程详情)
章节一 2018年 ELK课程计划和效果演示1.课程安排和效果演示 简介:课程介绍和主要知识点说明,ES搜索接口演示,部署的ELK项目演示 es: localhost:9200 k ...
- 2018年ElasticSearch6.2.2教程ELK搭建日志采集分析系统(目录)
章节一 2018年 ELK课程计划和效果演示 1.课程安排和效果演示 简介:课程介绍和主要知识点说明,ES搜索接口演示,部署的ELK项目演示 章节二 elasticSearch 6.2版本基础讲解到 ...
随机推荐
- Printing Architecture
Printing Architecture http://www.codeproject.com/Articles/8916/Printing-Architecture This articl ...
- XML在数据传输哪些方面会比JSON有优势,在哪些领域更加适合?
XML 跟 JSON 的圣战,或许会成为自 vim/emacs 圣战,cli/gui 圣战等等圣战以来的又一个圣战,而所有的圣战大抵都不会有结果,因为每方都有各自的道理,谁都不服谁. 在我看来,XML ...
- linux signal 用法和注意事项
http://blog.chinaunix.net/uid-9354-id-2425031.html 所以希望能用相同方式处理信号的多次出现,最好用sigaction.信号只出现并处理一次,可以用si ...
- DPDK2.1开发者手册1-2
Programmer’s Guide Release 2.1.0 翻译的目的是强化自己对dpdk的理解,看看2.1版本和现在使用的版本的差异,其次就是可能要走了,为那些要上手dpdk,但是又不想看英文 ...
- 让 Dreamweaver 支持 Emmet(原ZenCoding)
注:目前暂不支持 DW CC,期待作者早是更新.Update:2013/10/12 鉴于某些原因,每个 Coder 所钟爱的 IDE 各不相同.而作为一个软件爱好者,我几乎所有 IDE 都使用过一段时 ...
- android 多项对话框
在main.xml中 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:a ...
- 大数据笔记10:大数据之Hadoop的MapReduce的原理
1. MapReduce(并行处理的框架) 思想:分而治之,一个大任务分解成多个小的子任务(map),并行执行后,合并结果(Reduce) (1)大任务分解成多个小任务,这个过程就是map: (2)多 ...
- python字符串连接方式(转)
在python中有很多字符串连接方式,今天就在这里具体总结一下: ①.最原始的字符串连接方式:str1 + str2②.python 新字符串连接语法:str1, str2③.奇怪的字符串方式:str ...
- iOS避免键盘遮挡输入方案
项目中经常会遇到这样的问题:一个tableView中有大量的textField,当点击屏幕底部的textfield时,由于键盘弹出挡住了textfield输入框里的内容,造成很差的用户体验,如下图,点 ...
- UITextField点击return后注销第一响应者
// 当点击了return按钮,就让text调用自己的endEditing方法 [textField addTarget:textField action:@selector(endEditing:) ...