Created
April 7, 2023 03:23
-
-
Save matale/8026e473f63ef381d8c6177e41a816ea to your computer and use it in GitHub Desktop.
Crashlytics Logging Interceptor for OkHttp when you cant figure out where that error is comming from
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.google.firebase.crashlytics.FirebaseCrashlytics | |
import okhttp3.Interceptor | |
import okhttp3.Request | |
import okhttp3.Response | |
import okio.Buffer | |
import java.io.IOException | |
/* | |
Log HTTP requests to Crashlytics. | |
Note you need to be mindful of logging sensitive info. | |
These logs will appear in the details of the next fatal or non fatal crash on Firebase -> Crashlytics. | |
Logs are not sent unless a fatal crash happens or you record a non-fatal exception with | |
FirebaseCrashlytics.getInstance().recordException(throwable) | |
Remember that Crashlytics will only include the last 64kB of log messages with each crash so logging too much might be counter productive its best to be selective with what is logged. | |
Usage. | |
Wherever you are creating your OkHttpClient add this as an interceptor. e.g. | |
val okHttpClient = OkHttpClient.Builder() | |
.addInterceptor(CrashlyticsOkHttpInterceptor()) | |
.build() | |
*/ | |
class CrashlyticsOkHttpInterceptor : Interceptor { | |
@Throws(IOException::class) | |
override fun intercept(chain: Interceptor.Chain): Response { | |
val request: Request = chain.request() | |
val response: Response = chain.proceed(request) | |
val code = response.code | |
//Here we are only logging full req/response if the response was above HTTP code 200 (Success) | |
if (code > 200) { | |
val requestBuffer = Buffer() | |
request.body?.writeTo(requestBuffer) | |
val requestHeaders = request.headers.toString() | |
val responseBody = response.peekBody(Long.MAX_VALUE).string() | |
val responseHeaders = response.headers.toString() | |
val requestUrl = response.request.url.toString() | |
val msg = "code: $code url:$requestUrl reqH:$requestHeaders reqB:${requestBuffer.readUtf8()} resH:$responseHeaders resB:$responseBody" | |
FirebaseCrashlytics.getInstance().log(msg) | |
} else { | |
//If its HTTP 200 or less just log the request URL. To reduce size of logs. | |
val requestUrl = response.request.url.toString() | |
val msg = "code: $code url:$requestUrl" | |
FirebaseCrashlytics.getInstance().log(msg) | |
} | |
/* | |
Optionally record a non-fatal exception for some http codes, this will cause the logs to actually be sent. | |
Without this the logs will only be sent if the app crashes somewhere else after this request. | |
You can see full list of HTTP codes at https://developer.mozilla.org/en-US/docs/Web/HTTP/Status | |
*/ | |
if (code == 500) { | |
FirebaseCrashlytics.getInstance().recordException(Throwable("Http logging code: $code")) | |
} | |
return response | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have noticed that this has a problem if you are also using the same okHttpClient to download/upload binaries/files, it will attempt to log the entire binary content which can cause out of memory errors, one fix is to use separate okHttpClient for the downloading/uploading of files or exclude logging in this interceptor if the body does not contain text you can see an example of this here https://github.com/square/okhttp/blob/master/okhttp-logging-interceptor/src/main/kotlin/okhttp3/logging/HttpLoggingInterceptor.kt