Skip to content

Instantly share code, notes, and snippets.

@erickok
Last active February 14, 2024 06:27
Show Gist options
  • Star 19 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save erickok/e371a9e0b9e702ed441d to your computer and use it in GitHub Desktop.
Save erickok/e371a9e0b9e702ed441d to your computer and use it in GitHub Desktop.
Simple logging interceptor for OkHttp that logs full request headers and response headers + body (useful for use with Retrofit 2 where logging was removed)
if (BuildConfig.DEBUG) {
httpclient.interceptors().add(new LoggingInterceptor());
}
public class LoggingInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
long t1 = System.nanoTime();
Log.d("OkHttp", String.format("--> Sending request %s on %s%n%s", request.url(), chain.connection(), request.headers()));
Buffer requestBuffer = new Buffer();
request.body().writeTo(requestBuffer);
Log.d("OkHttp", requestBuffer.readUtf8());
Response response = chain.proceed(request);
long t2 = System.nanoTime();
Log.d("OkHttp", String.format("<-- Received response for %s in %.1fms%n%s", response.request().url(), (t2 - t1) / 1e6d, response.headers()));
MediaType contentType = response.body().contentType();
BufferedSource buffer = Okio.buffer(new GzipSource(response.body().source()));
String content = buffer.readUtf8();
Log.d("OkHttp", content);
ResponseBody wrappedBody = ResponseBody.create(contentType, content);
return response.newBuilder().removeHeader("Content-Encoding").body(wrappedBody).build();
}
}
if (BuildConfig.DEBUG) {
httpclient.interceptors().add(new LoggingInterceptor());
}
public class LoggingInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
long t1 = System.nanoTime();
Log.d("OkHttp", String.format("--> Sending request %s on %s%n%s", request.url(), chain.connection(), request.headers()));
Buffer requestBuffer = new Buffer();
request.body().writeTo(requestBuffer);
Log.d("OkHttp", requestBuffer.readUtf8());
Response response = chain.proceed(request);
long t2 = System.nanoTime();
Log.d("OkHttp", String.format("<-- Received response for %s in %.1fms%n%s", response.request().url(), (t2 - t1) / 1e6d, response.headers()));
MediaType contentType = response.body().contentType();
String content = response.body().string();
Log.d("OkHttp", content);
ResponseBody wrappedBody = ResponseBody.create(contentType, content);
return response.newBuilder().body(wrappedBody).build();
}
}
@bradroid
Copy link

bradroid commented Dec 7, 2015

Hi, one question: why do you create new response at the end of the block with

ResponseBody wrappedBody = ResponseBody.create(contentType, content);
        return response.newBuilder().body(wrappedBody).build();

can't you just return the response object you got in line 17?

return response;

@Nxele
Copy link

Nxele commented Jan 31, 2019

Hi erickok

i need help I'm new to interceptors how can i execute this interceptor so it addHeader

OkHttpClient.Builder httpClient = new OkHttpClient.Builder();

    if (BuildConfig.DEBUG) {
        httpClient.interceptors().add(new Interceptor() {

            @Override
            public Response intercept(Interceptor.Chain chain) throws IOException {
                Request original = chain.request();
                Toast.makeText(getApplicationContext(),"Please work now", Toast.LENGTH_LONG).show();
                Request request = original.newBuilder()
                        //.header("User-Agent", "AirbusMapBox")
                        .addHeader("Authorization",Airbus_key)
                        .method(original.method(), original.body())
                        .build();
                return chain.proceed(request);
            }
        });

        OkHttpClient client = httpClient.build();

        Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://view.geoapi-airbusds.com")
            .addConverterFactory(GsonConverterFactory.create())
            .client(client)
            .build();
    }

@behelit
Copy link

behelit commented Dec 9, 2019

This doesn't seem to log timeout's or exceptions

@rfermontero
Copy link

Hi, one question: why do you create new response at the end of the block with

ResponseBody wrappedBody = ResponseBody.create(contentType, content);
        return response.newBuilder().body(wrappedBody).build();

can't you just return the response object you got in line 17?

return response;

I think it's because the stream is closed when prints body

@flocsy
Copy link

flocsy commented Jul 12, 2021

Here's a merged version that can log gzip and non-gzip responses as well:

public class ResponseLoggingInterceptor implements Interceptor {
    
        public static final String CONTENT_ENCODING = "content-encoding";
    
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            Response response = chain.proceed(request);
    
            String content = null;
            ResponseBody body = response.body();
            if (body != null) {
                MediaType contentType = body.contentType();
                String contentEncoding = response.header(CONTENT_ENCODING);
                if ("gzip".equals(contentEncoding)) {
                    BufferedSource buffer = Okio.buffer(new GzipSource(body.source()));
                    content = buffer.readUtf8();
                    ResponseBody wrappedBody = ResponseBody.create(contentType, content);
                    response = response.newBuilder().removeHeader(CONTENT_ENCODING).body(wrappedBody).build();
                } else {
                    content = body.string();
                    ResponseBody wrappedBody = ResponseBody.create(contentType, content);
                    response = response.newBuilder().body(wrappedBody).build();
                }
            }
            String protocol = response.protocol().name().replaceFirst("_", "/");
            protocol = protocol.replace('_', '.');
            String httpLine = "" + protocol + ' ' + response.code();
            Log.v("OkHttp", String.format("%s\n%s\n\n%s", httpLine, response.headers(), content));
    
            return response;
        }
    }

@LDuncAndroid
Copy link

Spot on for me @flocsy thank you.

@dimaslanjaka
Copy link

dimaslanjaka commented Jan 13, 2024

I modify this code with okhttp v4 latest 2023. Please remove non project code, i was pasted without removing my util code.

implementation(platform("com.squareup.okhttp3:okhttp-bom:4.12.0"))
implementation("com.squareup.okhttp3:okhttp")
implementation("com.squareup.okhttp3:okhttp-urlconnection")
implementation("com.squareup.okhttp3:logging-interceptor")
import im3.FileManager;
import okhttp3.*;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.GzipSource;
import okio.Okio;
import org.jetbrains.annotations.NotNull;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Hashtable;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


// source https://gist.github.com/erickok/e371a9e0b9e702ed441d
public static class OkHttpGzippedLoggingInterceptor implements Interceptor {
    /**
     * get log file curl result
     *
     * @param url the url
     */
    public static String getLogFile(URI url) {
        return FileManager.getDir(new File("intercepts", "/" + url.getHost() + "/" + url.getPath()).toString()) + "/http.log";
    }

    public static String getLogFile(String urlstr) throws URISyntaxException {
        URI url = new URI(urlstr);
        return FileManager.getDir(new File("intercepts", "/" + url.getHost() + "/" + url.getPath()).toString()) + "/http.log";
    }

    @Override
    public @NotNull Response intercept(Chain chain) throws IOException {
        Request request = chain.request();

        long t1 = System.nanoTime();
        String reqMsg = String.format("--> Sending request %s %s on %s%n%s", request.method(), request.url(), chain.connection(), request.headers());
        System.out.println(reqMsg);

        BufferedSink requestBuffer = Okio.buffer(Okio.sink(new File(".cache", "okhttp-gzipped.log")));
        //            Buffer requestBuffer = new Buffer();
        RequestBody requestBody = request.body();
        if (requestBody != null) requestBody.writeTo(requestBuffer);
        String reqBody = requestBuffer.getBuffer().readUtf8();
        System.out.println(reqBody + "\n");

        Response response = chain.proceed(request);

        String filePath;
        try {
            URI url = new URI(request.url().toString());
            filePath = getLogFile(url);
        } catch (URISyntaxException e) {
            filePath = "";
        }

        long t2 = System.nanoTime();
        String resMsg = String.format("<-- Received response for %s %s in %.1fms%n%s", response.request().url(), response.protocol().toString().toUpperCase(Locale.ROOT), (t2 - t1) / 1e6 d, response.headers());
        System.out.println(resMsg);

        ResponseBody responseBody = response.body();
        MediaType contentType = null;
        BufferedSource buffer;
        String content = "NO CONTENT IN RESPONSE";
        if (responseBody != null) {
            contentType = responseBody.contentType();
            buffer = Okio.buffer(new GzipSource(responseBody.source()));
            content = buffer.readUtf8();
            System.out.println(content);
        }

        if (!filePath.isEmpty()) {
            FileManager.save(filePath, String.format("%s%n%s%n%s%n%s%n", reqMsg, reqBody, resMsg, content));
        }

        ResponseBody wrappedBody = ResponseBody.create(contentType, content);
        return response.newBuilder().removeHeader("Content-Encoding").body(wrappedBody).build();
    }
}

// source https://gist.github.com/erickok/e371a9e0b9e702ed441d
public static class OkhttpLoggingInterceptor implements Interceptor {
    @Override
    public @NotNull Response intercept(Chain chain) throws IOException {
        Request request = chain.request();

        long t1 = System.nanoTime();
        String reqMsg = String.format("--> Sending request %s %s on %s%n%s", request.method(), request.url(), chain.connection(), request.headers());
        System.out.println(reqMsg);

        BufferedSink requestBuffer = Okio.buffer(Okio.sink(new File(".cache", "okhttp-gzipped.log")));
        //            Buffer requestBuffer = new Buffer();
        RequestBody requestBody = request.body();
        if (requestBody != null) requestBody.writeTo(requestBuffer);
        String reqBody = requestBuffer.getBuffer().readUtf8();
        System.out.println(reqBody + "\n");

        Response response = chain.proceed(request);

        String filePath;
        try {
            URI url = new URI(request.url().toString());
            filePath = OkHttpGzippedLoggingInterceptor.getLogFile(url);
        } catch (URISyntaxException e) {
            filePath = "";
        }

        long t2 = System.nanoTime();
        String resMsg = String.format("<-- Received response for %s %s in %.1fms%n%s", response.request().url(), response.protocol().toString().toUpperCase(Locale.ROOT), (t2 - t1) / 1e6 d, response.headers());
        System.out.println(resMsg);

        ResponseBody responseBody = response.body();
        MediaType contentType = null;
        String content = "NO CONTENT IN RESPONSE";
        if (responseBody != null) {
            contentType = responseBody.contentType();
            content = responseBody.string();
            System.out.println(content);
        }

        if (!filePath.isEmpty()) {
            FileManager.save(filePath, String.format("%s%n%s%n%s%n%s%n", reqMsg, reqBody, resMsg, content));
        }

        ResponseBody wrappedBody = ResponseBody.create(contentType, content);
        return response.newBuilder().removeHeader("Content-Encoding").body(wrappedBody).build();
    }
}

the log result in file and console
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment