如何让OkHTTP日志拦截器仅记录请求?
OkHTTP 仅记录请求日志避免Logcat溢出的解决方案
有两种近乎开箱即用的实现方式,不用复杂改造就能满足需求:
方式一:自定义极简请求日志拦截器
直接写一个只处理请求日志的拦截器,完全跳过响应内容的记录,逻辑清晰且可控:
class RequestOnlyLoggingInterceptor : Interceptor { private val tag = "OkHTTP-Request" override fun intercept(chain: Interceptor.Chain): Response { val originalRequest = chain.request() var request = originalRequest // 构建请求日志内容 val logBuilder = StringBuilder() logBuilder.append("Sending request: ${originalRequest.method} ${originalRequest.url}\n") logBuilder.append("Request Headers:\n${originalRequest.headers}\n") // 仅打印文本类型的请求体,避免二进制内容乱码或日志过大 originalRequest.body?.let { body -> body.contentType()?.let { contentType -> if (contentType.subtype.contains("json") || contentType.subtype.contains("text")) { val bodyString = body.string() logBuilder.append("Request Body:\n$bodyString\n") // 注意:body.string()会消耗请求体,必须重新构建请求才能继续发送 request = originalRequest.newBuilder() .body(RequestBody.create(contentType, bodyString)) .build() } } } Log.d(tag, logBuilder.toString()) return chain.proceed(request) } }
添加到OkHttpClient的方式:
val okHttpClient = OkHttpClient.Builder() .addInterceptor(RequestOnlyLoggingInterceptor()) .build()
方式二:改造官方HttpLoggingInterceptor
利用官方自带的拦截器,通过自定义Logger过滤掉响应相关的日志输出,保留请求部分:
val requestOnlyLogger = HttpLoggingInterceptor.Logger { message -> // 只保留请求相关的日志行,过滤响应内容 if (message.startsWith("Sending request") || message.startsWith("Request Headers:") || message.startsWith("Request Body:")) { Log.d("OkHTTP-Request", message) } } val loggingInterceptor = HttpLoggingInterceptor(requestOnlyLogger) // 设置级别为BODY,确保能拿到完整的请求信息,再通过Logger过滤 loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY val okHttpClient = OkHttpClient.Builder() .addInterceptor(loggingInterceptor) .build()
注意事项
- 如果请求体是二进制类型(比如文件上传),不要打印body内容,否则会出现乱码且占用大量日志缓冲区;
- 自定义拦截器中调用
body.string()后必须重新构建请求体,否则后续请求会因请求体被消耗而失败; - 可以根据需求调整日志的TAG和输出级别(比如用
Log.i或Log.v)。
内容的提问来源于stack exchange,提问作者Andy Victors
相关产品推荐
相关产品推荐

