# 印出 API 的 Log--OkHttp HttpLoggingInterceptor (Retrofit 適用) > [name=Daniel Huang][time=Tue, Dec 27, 2022 10:56 AM] [TOC] ## 介紹 以往為了檢查 API 呼叫的 Request 或 Response 是否正確,都是土法煉鋼式的自行加註 `Log`。後來改用 Retrofit 之後,發現要加 `Log` 變得好麻煩,這才發現原來有 `HttpLoggingInterceptor` 可以自動印 Log 。 - [Java Doc: HttpLoggingInterceptor](https://square.github.io/okhttp/3.x/logging-interceptor/okhttp3/logging/HttpLoggingInterceptor.html) - [How to log request and response body with Retrofit-Android?](https://stackoverflow.com/a/33328524/9982091) :::warning [OkHttp 的 Interceptors](https://square.github.io/okhttp/features/interceptors/) 介面有許多實作的類別,可以針對 API 呼叫做很多不一樣的事情,有興趣的讀者可以多利用這個關鍵字下去尋找相關的資料,本篇文章就不贅述。  ::: ## 使用 ### 1. add gradle dependency ```groovy= implementation 'com.squareup.okhttp3:logging-interceptor:4.9.0' ``` :::danger 注意! 套件引用的版本,請以官方最新版本為準。 ::: ### 2. 新增 `HttpLoggingInterceptor` 到 `OkHttpClient` ```kotlin= private fun getOkHttpClient(): OkHttpClient { val loggingInterceptor: HttpLoggingInterceptor = HttpLoggingInterceptor().setLevel( if (BuildConfig.DEBUG) { // Debug 模式下才開啟 HttpLoggingInterceptor.Level.BODY } else { HttpLoggingInterceptor.Level.NONE } ) return OkHttpClient.Builder() .addInterceptor(loggingInterceptor) // ... .build() } ``` ### 3. 正常呼叫 API Logcat 就會出現相關的 Log 囉 #### Level.NONE 什麼都不印 #### Level.BASIC ``` --> POST /greeting http/1.1 (3-byte body) <-- 200 OK (22ms, 6-byte body) ``` #### Level.HEADERS 印 Request 跟 Response 的 Header。 ``` --> 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 ``` #### Level.BODY Body & Header 全部都印 ``` --> POST /greeting http/1.1 Host: example.com Content-Type: plain/text Content-Length: 3 Hi? --> END POST <-- 200 OK (22ms) Content-Type: plain/text Content-Length: 6 Hello! <-- END HTTP ``` ## 常見問題 ### 上傳大型檔案後出現閃退 公司專案中有一個需要上傳 01:30 長度的影片,檔案大小約 25MB。之前測試上傳都沒有問題,但在某測試版本中加上 `HttpLoggingInterceptor` 後,只要有影片的上傳都會閃退。 查詢 Firebase 與重現的錯誤都出現一樣的 `OutOfMemoryError`: ```!= Fatal Exception: java.lang.OutOfMemoryError: Failed to allocate a 88561088 byte allocation with 25165824 free bytes and 69MB until OOM, target footprint 220477624, growth limit 268435456 at okio.Buffer.readByteArray(Buffer.kt:1429) at okio.Buffer.readString(Buffer.kt:306) at okio.Buffer.readString(Buffer.kt:295) at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.kt:209) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at com.tms.qpass.data.remote.TokenInterceptor.intercept(TokenInterceptor.kt:43) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201) at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:517) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.lang.Thread.run(Thread.java:923) ``` :::success 經查測後發現與 StackOverflow 上的這篇 [Upload large video file use Retrofit(Android) have OutOfMemoryError](https://stackoverflow.com/q/52270693/9982091) 相符。 既然問題是出在 `HttpLoggingInterceptor` 所產生的 `OutOfMemoryError`,那其實不一定要像 StackOverflow 上說的改成 `Level.NONE`,==只要不是設定 `Level.BODY` 都可以。== 調整設定後確定可以正常上傳。🤗 ::: > 同步發表在 [iThelp](https://ithelp.ithome.com.tw/articles/10341913) ###### tags: `Android/Network`
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.