项目中有使用okhttp+logging-interceptor上传本地保存的log文件,
代码片段:
var logLevel = HttpLoggingInterceptor.Level.BODY //默认BODY级别
val builder = OkHttpClient.Builder()
//...略
.addInterceptor(
HttpLoggingInterceptor().setLevel(logLevel)
然后由于最开始只有一个log文件,日积月累,日志文件很大,有80M+的(这个已经优化成多个文件),
so第一次上传的时候HttpLoggingInterceptor里面报错了,查log是OutOfMemory,
也就是如下代码片段报错了,HttpLoggingInterceptor中直接读取所有80M+的内容
@Override
public Response intercept(Chain chain) throws IOException {
//...略
if (isPlaintext(buffer)) {
logger.log(buffer.readString(charset)); //打印参数内容时,直接读取全部内容,爆掉了
logger.log("--> END " + request.method()
+ " (" + requestBody.contentLength() + "-byte body)");
} else {
logger.log("--> END " + request.method() + " (binary "
+ requestBody.contentLength() + "-byte body omitted)");
}
}
这里没有加判断条件,也没有大小限制,显示是有问题的。
于是思路就重写日志打印拦截器,主要也就是读取以及打印这块地方:
后面查了官方issue,之前也有人遇到过这个问题,参考他们方案,加了2个全局变量requestBodyLogMax和responseBodyLogMax,设置最大打印的大小,超过了只截取部分内容打印。
设置临界值
val builder = OkHttpClient.Builder()
builder
.addInterceptor(
CommonHttpLoggingInterceptor().setLevel(logLevel).setRequestBodyLogMax(2000).setResponseBodyLogMax(
2000
)
)
CommonHttpLoggingInterceptor.java文件如下:
class CommonHttpLoggingInterceptor(val logger: Logger = Logger.DEFAULT) : Interceptor {
@Volatile
private var level = Level.NONE
@Volatile
private var requestBodyLogMax = LOG_LIMITATION_NONE
@Volatile
private var responseBodyLogMax = LOG_LIMITATION_NONE
enum class Level {
/** No logs. */
NONE,
/**
* Logs request and response lines.
*
*
* Example:
* <pre>`--> POST /greeting http/1.1 (3-byte body)
*
* <-- 200 OK (22ms, 6-byte body)
`</pre> *
*/
BASIC,
/**
* Logs request and response lines and their respective headers.
*
*
* Example:
* <pre>`--> POST /greeting http/1.1
* Host: example.com
* Content-Type: plain/text
* Content-Length: 3
* --> END POST
*
* <-- 200 OK (22ms)
* Content-Type: plain/text
* Content-Length: 6
* <-- END HTTP
`</pre> *
*/