当前位置: 首页 > article >正文

Kotlin下OkHttp的LoggingInterceptor配置指南:从基础使用到高级定制

Kotlin下OkHttp的LoggingInterceptor配置指南从基础使用到高级定制在移动开发领域网络请求日志记录是调试和问题排查的重要工具。OkHttp作为Android平台上最流行的HTTP客户端之一其内置的LoggingInterceptor为开发者提供了便捷的日志记录功能。本文将深入探讨如何在Kotlin环境下充分利用这一工具从基础配置到高级定制帮助开发者构建更高效的网络请求监控系统。1. LoggingInterceptor基础配置OkHttp的LoggingInterceptor是Interceptor接口的一个实现专门用于记录HTTP请求和响应的详细信息。要开始使用它首先需要在项目中添加OkHttp依赖implementation(com.squareup.okhttp3:okhttp:4.10.0)最基本的配置方式是在构建OkHttpClient时添加LoggingInterceptor实例val httpLoggingInterceptor HttpLoggingInterceptor().apply { level HttpLoggingInterceptor.Level.BASIC } val okHttpClient OkHttpClient.Builder() .addInterceptor(httpLoggingInterceptor) .build()LoggingInterceptor提供了四种日志级别日志级别记录内容NONE不记录任何日志BASIC记录请求方法、URL、响应状态码和响应时间HEADERS在BASIC基础上增加请求和响应头信息BODY记录完整的请求和响应内容包括body数据提示在生产环境中建议使用BASIC或NONE级别避免敏感信息泄露开发环境可以使用BODY级别进行详细调试。2. 日志格式优化与自定义默认的LoggingInterceptor输出格式可能包含过多冗余信息我们可以通过自定义Logger接口来优化输出格式val loggingInterceptor HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger { override fun log(message: String) { // 过滤掉空行和分隔线 if (message.isNotBlank() !message.startsWith(--) !message.startsWith(--)) { Log.d(Network, message) } } }).apply { level HttpLoggingInterceptor.Level.BODY }对于需要特定格式的场景可以创建自定义的日志标签和格式val customLogger object : HttpLoggingInterceptor.Logger { private val timestampFormat SimpleDateFormat(HH:mm:ss.SSS, Locale.getDefault()) override fun log(message: String) { val timestamp timestampFormat.format(Date()) Log.d(Network, [$timestamp] $message) } }3. 高级定制实现自定义Interceptor当LoggingInterceptor的功能无法满足需求时我们可以实现自己的Interceptor来获得完全控制权。以下是一个增强版的日志拦截器示例class EnhancedLoggingInterceptor : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { val request chain.request() val startTime System.nanoTime() // 记录请求信息 logRequest(request) // 执行请求 val response chain.proceed(request) // 记录响应信息 logResponse(response, startTime) return response } private fun logRequest(request: Request) { val body request.body?.let { bodyToString(it) } ?: null Log.d(Network, Request: URL: ${request.url} Method: ${request.method} Headers: ${request.headers} Body: $body .trimIndent()) } private fun logResponse(response: Response, startTime: Long) { val timeMs (System.nanoTime() - startTime) / 1_000_000 val body response.peekBody(Long.MAX_VALUE).string() Log.d(Network, Response: Code: ${response.code} Time: ${timeMs}ms Headers: ${response.headers} Body: $body .trimIndent()) } private fun bodyToString(request: RequestBody): String { return try { val buffer Buffer() request.writeTo(buffer) buffer.readUtf8() } catch (e: Exception) { could not serialize request body } } }这个自定义拦截器提供了以下增强功能更清晰的请求/响应分隔精确的请求耗时计算完整的请求体和响应体记录更好的可读性格式4. 性能优化与最佳实践在使用LoggingInterceptor时需要注意以下几点性能优化建议日志级别动态切换根据构建类型自动设置日志级别val logLevel if (BuildConfig.DEBUG) { HttpLoggingInterceptor.Level.BODY } else { HttpLoggingInterceptor.Level.NONE }敏感信息过滤在记录日志前过滤掉敏感数据val secureLogger object : HttpLoggingInterceptor.Logger { override fun log(message: String) { val filteredMessage message.replace(Regex((password|token)[^]), $1***) Log.d(Network, filteredMessage) } }日志采样在高频请求场景下可以采样记录部分请求class SamplingLoggingInterceptor( private val delegate: HttpLoggingInterceptor, private val sampleRate: Float 0.1f ) : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { if (Random.nextFloat() sampleRate) { return delegate.intercept(chain) } return chain.proceed(chain.request()) } }日志文件输出将重要网络请求日志保存到文件val fileLogger object : HttpLoggingInterceptor.Logger { private val logFile File(context.filesDir, network_logs.txt) override fun log(message: String) { logFile.appendText($message\n) } }5. 多Interceptor组合策略在实际项目中我们经常需要组合多个Interceptor来实现不同的功能。OkHttp的Interceptor执行顺序很重要应用拦截器addInterceptor最先添加的最后执行网络拦截器addNetworkInterceptor最后添加的最先执行一个典型的配置示例val okHttpClient OkHttpClient.Builder() .addInterceptor(HeaderInterceptor()) // 添加公共请求头 .addInterceptor(AuthInterceptor()) // 处理认证 .addNetworkInterceptor(LoggingInterceptor()) // 记录网络层日志 .addNetworkInterceptor(StethoInterceptor()) // Facebook的调试工具 .build()注意LoggingInterceptor通常作为网络拦截器添加这样可以记录到最完整的网络层信息包括重定向和重试的请求。6. 常见问题排查与调试技巧在使用LoggingInterceptor过程中可能会遇到一些常见问题日志不完整或缺失确保Interceptor被正确添加到OkHttpClient检查日志级别设置是否足够详细确认没有其他Interceptor修改或消费了请求/响应体性能问题避免在生产环境使用BODY级别对于大文件上传/下载考虑禁用日志或使用BASIC级别使用采样策略减少日志量敏感信息泄露实现自定义Logger过滤敏感字段在发布构建中禁用或限制日志级别考虑使用混淆工具处理日志中的敏感数据日志分析工具使用Logcat过滤器tag:Network集成第三方日志收集系统如Bugsnag或Firebase Crashlytics开发自定义日志分析工具解析网络请求模式// 示例使用Firebase记录关键网络请求指标 firebaseAnalytics.logEvent(network_request, bundleOf( url to request.url.host, duration_ms to duration, status_code to response.code ))在实际项目中使用OkHttp的LoggingInterceptor时我发现最有价值的实践是为不同的API端点配置不同的日志级别。例如对于支付等关键接口使用详细日志而对于图片加载等高频低重要性请求使用BASIC级别或采样记录。这种差异化配置既保证了关键信息的可追踪性又避免了日志爆炸影响性能。

相关文章:

Kotlin下OkHttp的LoggingInterceptor配置指南:从基础使用到高级定制

Kotlin下OkHttp的LoggingInterceptor配置指南:从基础使用到高级定制 在移动开发领域,网络请求日志记录是调试和问题排查的重要工具。OkHttp作为Android平台上最流行的HTTP客户端之一,其内置的LoggingInterceptor为开发者提供了便捷的日志记录…...

别再傻傻等conda下载了!手把手教你用迅雷+清华源离线安装PyTorch(附pip/conda双方案)

突破网络限制:PyTorch离线安装全攻略(清华源迅雷实战) 每次看到conda进度条卡住不动的时候,是不是特别想砸键盘?尤其是在公司内网或者校园网环境下,PyTorch的安装过程简直是一场噩梦。今天我要分享的这套方…...

ArcGIS新手必看:从安装到基础操作的完整指南(附常见问题解决方案)

ArcGIS新手必看:从安装到基础操作的完整指南(附常见问题解决方案) 如果你是第一次接触ArcGIS,可能会被它庞大的功能体系所震撼。作为地理信息系统(GIS)领域的行业标准软件,ArcGIS提供了从数据采…...

保姆级教程:用ThreeJS和3DTilesRendererJS加载无人机倾斜摄影模型(附源码)

从无人机航测到Web3D展示:ThreeJS与3DTiles全流程实战指南 倾斜摄影技术正逐渐成为数字城市建设、工程测绘等领域的重要工具。当您完成无人机航拍并获取了大量OSGB格式数据后,如何将这些专业数据转化为可在网页中流畅展示的3D模型?本文将带您…...

Ubuntu离线环境部署ClamTk:从依赖包处理到图形化扫描实战

1. 离线环境下的安全防护挑战 在企业的内网环境中,服务器和工作站通常处于严格的网络隔离状态。这种安全措施虽然有效防止了外部攻击,但也带来了软件部署的难题——尤其是杀毒软件这类需要频繁更新的安全工具。我去年就遇到过这样的场景:某金…...

配电网电压控制的二阶锥优化实战(MATLAB篇)

配电网电压控制、二阶锥优化SOCP、matlab、光伏风电机。 使用二阶锥模型对有源配电网进行电压控制。 系统:33节点配电网 被控对象:光伏、风机、SVC 平台:matlab 框架:集中式 算法:二阶锥 超级适合小白入门学习。最近在研究有源配电网电压控制时发现,二阶锥优化&…...

Ubuntu24.04下Qt6安装全攻略:从镜像加速到常见错误解决

Ubuntu 24.04下Qt6安装全攻略:从镜像加速到疑难排错 在Linux生态中,Qt框架一直是跨平台开发的标杆工具。随着Ubuntu 24.04 LTS的发布和Qt6的成熟,许多开发者开始在新系统上搭建开发环境。本文将带你完整走通Qt6的安装流程,并解决那…...

从Ring-Allreduce到实战:用DDP加速你的PyTorch多卡训练(附A100配置模板)

从Ring-Allreduce到实战:用DDP加速你的PyTorch多卡训练(附A100配置模板) 在深度学习模型规模爆炸式增长的今天,单卡训练已经无法满足大模型的需求。PyTorch的DistributedDataParallel(DDP)凭借其高效的Ring…...

COCO数据集迁移学习全攻略:从预训练模型到自定义数据集训练

COCO数据集迁移学习实战指南:从模型选择到自定义训练全流程 在计算机视觉领域,迁移学习已成为加速模型开发、提升性能的关键技术。作为业界标杆的COCO数据集,其预训练模型为各类视觉任务提供了强大的基础。本文将深入探讨如何基于COCO预训练模…...

免费部署!腾讯HY-MT1.5翻译模型实战:搭建你的专属翻译助手

免费部署!腾讯HY-MT1.5翻译模型实战:搭建你的专属翻译助手 你是不是也遇到过这样的场景?看英文技术文档时,一段话来回查好几遍词典;浏览海外产品页面,对描述细节一知半解;或者想快速翻译一份多…...

Pixel Dimension Fissioner惊艳效果:同一产品描述裂变为科技感/复古风/童话风三版本

Pixel Dimension Fissioner惊艳效果:同一产品描述裂变为科技感/复古风/童话风三版本 1. 效果展示:文字维度的华丽变身 Pixel Dimension Fissioner(像素语言维度裂变器)是一款基于MT5-Zero-Shot-Augment核心引擎构建的文本改写工…...

DDR5 JESD79-5标准解析:AC/DC输入测量与信号完整性关键指标

1. DDR5内存技术的关键挑战与JESD79-5标准概述 当你把DDR5内存条插入主板时,可能不会想到那些金属触点背后正在进行着每秒数十亿次的电压博弈。作为JEDEC固态技术协会发布的第五代双倍数据率内存标准,DDR5将数据传输速率推向了6400MT/s的新高度&#xff…...

跨平台文件同步器:OpenClaw调用ollama-QwQ-32B智能去重方案

跨平台文件同步器:OpenClaw调用ollama-QwQ-32B智能去重方案 1. 为什么需要智能文件同步器 作为一个经常在多台设备间切换工作的开发者,我长期被文件同步问题困扰。传统的同步工具(如rsync或云盘同步)只能解决"文件是否存在…...

西门子200SMART PLC间PUT/GET通讯实战指南

1. 西门子200SMART PLC通讯基础 在工业自动化领域,PLC之间的数据交互就像工厂里不同部门之间的信息传递一样重要。西门子S7-200SMART系列PLC提供的PUT/GET通讯协议,就是专门为这种场景设计的"内部通讯工具"。简单来说,PUT就是"…...

InoProShop串口通讯避坑指南:自由协议配置中的5个常见错误

InoProShop串口通讯实战:自由协议配置中的5个关键陷阱与解决方案 在工业自动化领域,串口通讯作为基础却至关重要的通讯方式,依然是许多PLC控制系统中的首选方案。汇川技术的InoProShop平台凭借其强大的功能和灵活性,在工程师群体中…...

华大HC32F460硬件SPI驱动ST7735S屏避坑指南:为什么加了50ns延时才能正常显示?

HC32F460硬件SPI驱动ST7735S屏幕的时序优化实战 从STM32切换到华大HC32F460平台时,硬件SPI驱动ST7735S液晶屏遇到了一个棘手问题——屏幕无法正常显示。经过逻辑分析仪捕获波形和反复调试,最终发现关键点在于发送数据后需要插入精确的硬件延时。本文将深…...

PP-DocLayoutV3生产环境:Docker Compose编排多实例负载均衡应对日均万级文档处理

PP-DocLayoutV3生产环境:Docker Compose编排多实例负载均衡应对日均万级文档处理 1. 引言 想象一下,你负责一个大型档案数字化项目,每天需要处理上万份扫描的合同、报告和发票。每份文档都要自动识别出标题、正文、表格和图片的位置&#x…...

嵌入式C++固定点数运算库:零依赖、确定性、高性能

1. 项目概述fixedpoint是一个专为嵌入式 C 环境设计的单头文件、零依赖固定点数运算库。其核心设计哲学是在无硬件浮点单元(FPU)或整数除法指令的受限 MCU 上,以确定性、零开销、可预测的方式替代浮点运算。该库不分配堆内存、不抛出异常、不…...

Leather Dress Collection部署案例:高校服装设计课程AI辅助教学实践

Leather Dress Collection部署案例:高校服装设计课程AI辅助教学实践 1. 项目背景与教育价值 在服装设计教育领域,学生常常面临创意构思与快速呈现之间的矛盾。传统设计流程需要经历手绘草图、面料选择、效果图绘制等多个环节,耗时费力且难以…...

BM8563实时时钟芯片原理与嵌入式RTC驱动集成

1. BM8563实时时钟芯片技术解析与嵌入式集成实践BM8563是由NXP(原Philips)推出的低功耗CMOS实时时钟/日历(RTC)芯片,广泛应用于工业控制、智能电表、便携式医疗设备及物联网终端等对时间精度、功耗和可靠性有严苛要求的…...

别再让专业名词难倒你的语音模型:SenseVoice/Paraformer微调实战避坑指南

语音模型专业术语识别优化实战:从数据清洗到模型评估的全流程解析 医疗报告中的"肌钙蛋白"被识别成"鸡蛋白",金融对话里的"量化宽松"变成"量化宽松裤"——专业术语识别一直是语音模型的阿喀琉斯之踵。本文将手把…...

Avellaneda Stoikov做市策略的工程化实践:关键参数动态调整与加密市场适配

1. 从理论到实践:AS做市策略的核心参数解析 第一次看到Avellaneda & Stoikov论文里的希腊字母公式时,我也被那些γ、κ、σ绕得头晕。但真正在加密市场实操这个策略三年后,我发现这些参数就像汽车的仪表盘——理解每个参数的含义&#xf…...

TM6605 LRA触觉驱动库:谐振跟踪与精确制动实现

1. 项目概述DFRobot_TM6605 是一款面向嵌入式平台的高精度线性谐振执行器(Linear Resonant Actuator, LRA)触觉反馈驱动库,专为简化 TM6605 专用 Haptic 驱动芯片在 Arduino 生态中的集成而设计。该库并非通用电机控制抽象层,而是…...

避坑指南:SpyGlass的link design前后那些容易踩的坑(附解决方案)

SpyGlass时序敏感操作避坑指南:从状态机视角解析link design前后的关键陷阱 在数字芯片设计验证领域,SpyGlass作为业界公认的RTL Sign-off解决方案,其严谨的流程控制机制既是确保分析可靠性的基石,也是中高级用户最容易"踩坑…...

Rails+百度地图API实战:5分钟搞定房屋周边设施数据抓取与存储

Rails与百度地图API高效整合:房屋周边数据自动化采集实战指南 当我们需要分析房产价值时,周边设施数据往往是最关键却又最耗时的手工收集环节。本文将展示如何用Rails框架与百度地图API构建一个自动化数据采集系统,5分钟内完成从技术对接到数…...

轻量模型InternLM2-Chat-1.8B在嵌入式领域的联想:STM32开发日志智能分析

轻量模型InternLM2-Chat-1.8B在嵌入式领域的联想:STM32开发日志智能分析 最近在折腾一个STM32的物联网项目,设备跑起来后,每天产生的日志数据量不小。看着那一行行的时间戳、状态码和调试信息,我就在想,有没有更聪明的…...

基于STM32的多参数家庭健康监测终端设计

1. 项目概述1.1 设计目标与应用场景本项目面向家庭健康监测场景,构建一套便携式、多参数、低功耗的嵌入式健康检测终端。其核心设计目标是:在无专业医疗人员介入的前提下,为普通家庭用户提供可信赖的日常生理参数采集能力,重点覆盖…...

嵌入式轻量级命令行解释器设计与实践

1. 项目概述UtilifyCommandInterpreter 是一款专为资源受限嵌入式平台设计的轻量级命令行解释器库,原生支持 ESP32 和 Arduino Uno 两类主流开发板。其核心定位并非通用 Shell 替代品,而是面向设备调试、现场配置与固件交互场景的工程化工具链组件。在实…...

二极管单向导电性的秘密:硅管和锗管的门限电压详解及实际应用

二极管单向导电性的秘密:硅管和锗管的门限电压详解及实际应用 在电子设计的浩瀚宇宙中,二极管就像一位沉默的守门人,严格遵循着"单向通行"的规则。这种看似简单的特性背后,隐藏着半导体材料的精妙物理机制。对于电子工程…...

Qwen3.5-9B开源可部署价值凸显:9B参数模型在24G显存GPU上稳定运行

Qwen3.5-9B开源可部署价值凸显:9B参数模型在24G显存GPU上稳定运行 1. 模型概述与技术亮点 Qwen3.5-9B作为新一代开源大模型,在保持9B参数规模的同时,通过多项技术创新实现了在24G显存GPU上的稳定运行。这一突破性进展使得高性能大模型的门槛…...