Okhttp3.0 日志拦截器HttpLoggingInterceptor的上传大文件时OutOfMemory以及修复

项目中有使用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> *
         */
        
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值