告别千篇一律:手把手教你定制okhttputils日志拦截器

告别千篇一律:手把手教你定制okhttputils日志拦截器

【免费下载链接】okhttputils [停止维护]okhttp的辅助类 【免费下载链接】okhttputils 项目地址: https://gitcode.com/gh_mirrors/ok/okhttputils

你是否还在为网络请求调试时杂乱无章的日志发愁?是否觉得默认日志格式总是差那么点意思?本文将带你深度剖析okhttputils中的LoggerInterceptor.java,通过5个实用场景案例,教你如何打造完全个性化的网络请求日志系统。

拦截器工作原理

LoggerInterceptor实现了OkHttp的Interceptor接口,其核心逻辑在intercept方法中:

@Override
public Response intercept(Chain chain) throws IOException {
    Request request = chain.request();
    logForRequest(request);  // 打印请求日志
    Response response = chain.proceed(request);
    return logForResponse(response);  // 打印响应日志
}

整个拦截流程分为三个阶段:

  1. 请求拦截:在logForRequest方法中处理请求信息
  2. 继续请求:通过chain.proceed(request)将请求传递给下一个拦截器
  3. 响应拦截:在logForResponse方法中处理响应信息

默认日志格式解析

默认情况下,拦截器会输出类似以下格式的日志:

========request'log=======
method : GET
url : https://api.example.com/users
headers : Content-Type: application/json
requestBody's contentType : application/json
requestBody's content : {"username":"test"}
========request'log=======end

========response'log=======
url : https://api.example.com/users
code : 200
protocol : HTTP_1_1
responseBody's contentType : application/json
responseBody's content : {"code":0,"data":{}}
========response'log=======end

这种格式虽然完整,但在实际开发中可能存在信息过载或关键信息不突出的问题。

实用定制场景

1. 精简日志输出

修改logForRequest方法,只保留关键信息:

private void logForRequest(Request request) {
    try {
        Log.d(tag, String.format("[%s] %s", request.method(), request.url()));
        // 仅保留方法和URL,移除headers和body打印
    } catch (Exception e) {
        // 异常处理
    }
}

2. 添加请求耗时统计

在intercept方法中添加时间戳计算:

@Override
public Response intercept(Chain chain) throws IOException {
    long startTime = System.currentTimeMillis();
    Request request = chain.request();
    Response response = chain.proceed(request);
    long endTime = System.currentTimeMillis();
    
    Log.d(tag, String.format("耗时: %dms", endTime - startTime));
    return response;
}

3. 敏感信息脱敏

修改bodyToString方法,对密码等敏感信息进行脱敏:

private String bodyToString(final Request request) {
    try {
        // 原有代码...
        String body = buffer.readUtf8();
        // 替换密码字段
        return body.replaceAll("\"password\":\"[^\"]+\"", "\"password\":\"***\"");
    } catch (final IOException e) {
        return "something error when show requestBody.";
    }
}

4. 日志写入文件系统

结合Android的文件操作,将日志保存到本地文件:

private void logToFile(String log) {
    try {
        File logFile = new File(Environment.getExternalStorageDirectory(), "okhttp_logs.txt");
        FileWriter writer = new FileWriter(logFile, true);
        writer.append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " " + log + "\n");
        writer.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

然后在logForRequest和logForResponse方法中调用此方法。

5. 自定义日志级别控制

扩展LoggerInterceptor类,添加日志级别控制:

public enum LogLevel {
    NONE, BASIC, HEADERS, BODY
}

private LogLevel logLevel = LogLevel.BASIC;

// 在logForRequest中根据级别控制输出内容
if (logLevel == LogLevel.BASIC || logLevel == LogLevel.HEADERS || logLevel == LogLevel.BODY) {
    Log.e(tag, "method : " + request.method());
    Log.e(tag, "url : " + url);
}

if (logLevel == LogLevel.HEADERS || logLevel == LogLevel.BODY) {
    // 打印headers
}

if (logLevel == LogLevel.BODY) {
    // 打印body
}

高级应用:日志拦截器链

OkHttp支持多个拦截器组成拦截器链,你可以创建多个功能专一的日志拦截器:

OkHttpClient client = new OkHttpClient.Builder()
    .addInterceptor(new TimeCostInterceptor())  // 耗时统计
    .addInterceptor(new SensitiveDataInterceptor())  // 敏感信息处理
    .addInterceptor(new FileLogInterceptor())  // 文件日志
    .build();

这种方式遵循单一职责原则,让每个拦截器只负责一项日志功能。

总结与最佳实践

通过定制LoggerInterceptor,我们可以:

  • 提高调试效率:只显示需要的信息
  • 保护用户隐私:脱敏敏感数据
  • 优化性能:控制日志输出频率和内容
  • 方便问题追踪:结构化日志便于分析

建议在开发环境使用详细日志,生产环境使用精简日志并添加异常上报功能。完整的自定义拦截器代码可参考项目中的sample-okhttp模块。

希望本文能帮助你打造更高效的网络调试体验。如果觉得有用,请点赞收藏,下期我们将介绍如何结合CookieStore实现自动登录功能。

【免费下载链接】okhttputils [停止维护]okhttp的辅助类 【免费下载链接】okhttputils 项目地址: https://gitcode.com/gh_mirrors/ok/okhttputils

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值