告别千篇一律:手把手教你定制okhttputils日志拦截器
【免费下载链接】okhttputils [停止维护]okhttp的辅助类 项目地址: 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); // 打印响应日志
}
整个拦截流程分为三个阶段:
- 请求拦截:在logForRequest方法中处理请求信息
- 继续请求:通过chain.proceed(request)将请求传递给下一个拦截器
- 响应拦截:在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的辅助类 项目地址: https://gitcode.com/gh_mirrors/ok/okhttputils
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



