Làm cách nào để ghi nhật ký nội dung yêu cầu và phản hồi với Retrofit-Android?


129

Tôi không thể tìm thấy các phương pháp liên quan trong API trang bị thêm để ghi nhật ký các cơ quan yêu cầu / phản hồi hoàn chỉnh. Tôi đã mong đợi một số trợ giúp trong Hồ sơ (nhưng nó chỉ cung cấp siêu dữ liệu về phản hồi). Tôi đã thử đặt mức nhật ký trong Trình tạo, nhưng điều này cũng không giúp được tôi:

RestAdapter adapter = (new RestAdapter.Builder()).
                setEndpoint(baseUrl).
                setRequestInterceptor(interceptor).
                setProfiler(profiler).
                setClient(client).
                setExecutors(MyApplication.getWebServiceThreadPool()).
                setLogLevel(LogLevel.FULL).
                setLog(new RestAdapter.Log() {
                    @Override
                    public void log(String msg) {
                        Log.i(TAG, msg);
                    }
                }).
                build();

CHỈNH SỬA: Mã này hiện đang hoạt động. Tôi không biết tại sao nó không hoạt động sớm hơn. Có thể vì tôi đang sử dụng một số phiên bản trang bị thêm cũ hơn.


Bạn đã bao giờ con số này ra? Tài liệu nói rằng điều đó FULLđược cho là để cung cấp cho cơ thể nhưng có vẻ như không.
theblang

1
@mattblang: Tôi không biết đã xảy ra lỗi gì trước đó, nhưng mã này hiện đang hoạt động.
Jaguar

Có thể trùng lặp của Logging với Retrofit 2
bryant1410


Có lẽ chạy liền sai lầm smth nếu nó không làm việc trước đó
deathangel908

Câu trả lời:


91

Tôi đã sử dụng setLogLevel(LogLevel.FULL).setLog(new AndroidLog("YOUR_LOG_TAG")), nó đã giúp tôi.
CẬP NHẬT.
Bạn cũng có thể thử sử dụng cho mục đích gỡ lỗi retrofit.client.Responselàm mô hình phản hồi


2
AndroidLog, đó là lớp gì?
theblang

Nó đi kèm với thư viện Retrofit.
Alex Dzeshko

2
Tôi hiểu rồi. Thật không may, điều này không cung cấp cho bạn response body, mặc dù nó có trạng thái trong tài liệu LogLevel.FULL sẽ cung cấp cho bạn response body.
theblang

Điều này có thể được nhìn thấy với "YOUR_LOG_TAG" trong android logcat trong tab chi tiết.
rajeesh

4
LogLevel.Full không tồn tại trong trang bị thêm 2

121

Trang bị thêm 2.0 :

CẬP NHẬT: @ của Marcus Pöhls

Đăng nhập trang bị thêm 2

Retrofit 2 hoàn toàn dựa vào OkHttp cho bất kỳ hoạt động mạng nào. Vì OkHttp là một phụ thuộc ngang hàng của Retrofit 2, bạn sẽ không cần thêm phụ thuộc bổ sung sau khi Retrofit 2 được phát hành dưới dạng bản phát hành ổn định.

OkHttp 2.6.0 đi kèm với một bộ đánh chặn ghi nhật ký như một phần phụ thuộc nội bộ và bạn có thể trực tiếp sử dụng nó cho ứng dụng khách Retrofit của mình. Retrofit 2.0.0-beta2 vẫn sử dụng OkHttp 2.5.0. Các bản phát hành trong tương lai sẽ đẩy sự phụ thuộc lên các phiên bản OkHttp cao hơn. Đó là lý do tại sao bạn cần nhập trình đánh chặn ghi nhật ký theo cách thủ công. Thêm dòng sau vào nhập gradle trong tệp build.gradle của bạn để tìm nạp sự phụ thuộc của trình đánh chặn ghi nhật ký.

compile 'com.squareup.okhttp3:logging-interceptor:3.9.0'

Bạn cũng có thể truy cập trang GitHub của Square về máy đánh chặn này

Thêm ghi nhật ký vào trang bị thêm 2

Trong khi phát triển ứng dụng của bạn và cho mục đích gỡ lỗi, thật tuyệt khi được tích hợp tính năng nhật ký để hiển thị thông tin yêu cầu và phản hồi. Vì ghi nhật ký không được tích hợp theo mặc định nữa trong Retrofit 2, nên chúng tôi cần thêm một bộ chặn ghi nhật ký cho OkHttp. May mắn thay, OkHttp đã có thiết bị đánh chặn này và bạn chỉ cần kích hoạt nó cho OkHttpClient của mình.

HttpLoggingInterceptor logging = new HttpLoggingInterceptor();  
// set your desired log level
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();   
// add your other interceptors …
// add logging as last interceptor
httpClient.addInterceptor(logging);  // <-- this is the important line!
Retrofit retrofit = new Retrofit.Builder()  
        .baseUrl(API_BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .client(httpClient.build())
        .build();

Chúng tôi khuyên bạn nên thêm ghi nhật ký làm công cụ chặn cuối cùng, vì điều này cũng sẽ ghi nhật ký thông tin mà bạn đã thêm với các công cụ chặn trước đó vào yêu cầu của mình.

Mức độ nhật ký

Việc ghi quá nhiều thông tin sẽ làm nổ màn hình Android của bạn, đó là lý do tại sao trình chặn ghi nhật ký của OkHttp có bốn cấp độ nhật ký: KHÔNG, CƠ BẢN, ĐẦU, CƠ THỂ. Chúng tôi sẽ hướng dẫn bạn qua từng cấp độ nhật ký và mô tả đầu ra của chúng.

thêm thông tin vui lòng truy cập: Trang bị thêm 2 - Yêu cầu và phản hồi nhật ký

CÂU TRẢ LỜI CŨ:

không đăng nhập Retrofit 2 nữa. Nhóm phát triển đã loại bỏ tính năng ghi nhật ký. Thành thật mà nói, tính năng ghi nhật ký dù sao cũng không đáng tin cậy. Jake Wharton đã tuyên bố rõ ràng rằng các thông báo hoặc đối tượng đã ghi là các giá trị giả định và chúng không thể được chứng minh là đúng. Yêu cầu thực sự đến máy chủ có thể có phần thân yêu cầu đã thay đổi hoặc thứ gì đó khác.

Mặc dù không có ghi nhật ký tích hợp theo mặc định, bạn có thể tận dụng bất kỳ trình ghi nhật ký Java nào và sử dụng nó trong bộ đánh chặn OkHttp tùy chỉnh.

Thông tin thêm về Trang bị thêm 2, vui lòng tham khảo: Trang bị thêm - Bắt đầu và tạo ứng dụng khách Android


1
Ngoài ra còn có một bài cụ thể cho khai thác gỗ trong Retrofit 2.0: futurestud.io/blog/retrofit-2-log-requests-and-responses
peitek

Cách tuyệt vời để làm cho mọi thứ trở nên phức tạp hơn mức cần thiết. Làm tôi nhớ đến việc ghi nhật ký Jersey 1 vs Jersey 2. Nhiều mã boilerplate ....
breakline

Việc thêm các bộ chặn theo cách này bây giờ sẽ dẫn đến một ngoại lệ không được hỗ trợ trong OkHttp v3. Cách mới là: OkHttpClient.Builder () addInterceptor (logging) .build (). Github.com/square/okhttp/issues/2219
Amagi82

@JawadLeWywadi có sử dụng mã này bạn có thể in cơ thể
Dhaval Jivani

Đối với Retrofit 2, điều này dễ dàng hơn nhiều.
Gary99,

31

Cập nhật cho Retrofit 2.0.0-beta3

Bây giờ bạn phải sử dụng okhttp3 với trình xây dựng. Ngoài ra máy đánh chặn cũ sẽ không hoạt động. Phản hồi này được điều chỉnh cho Android.

Đây là một bản sao nhanh dán cho bạn với nội dung mới.

1. Sửa đổi tệp gradle của bạn thành

  compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3'
  compile "com.squareup.retrofit2:converter-gson:2.0.0-beta3"
  compile "com.squareup.retrofit2:adapter-rxjava:2.0.0-beta3"
  compile 'com.squareup.okhttp3:logging-interceptor:3.0.1'

2. Kiểm tra mã mẫu này:

với hàng nhập khẩu mới. Bạn có thể loại bỏ Rx nếu bạn không sử dụng nó, cũng loại bỏ những gì bạn không sử dụng.

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.GsonConverterFactory;
import retrofit2.Retrofit;
import retrofit2.RxJavaCallAdapterFactory;
import retrofit2.http.GET;
import retrofit2.http.Query;
import rx.Observable;

public interface APIService {

  String ENDPOINT = "http://api.openweathermap.org";
  String API_KEY = "2de143494c0b2xxxx0e0";

  @GET("/data/2.5/weather?appid=" + API_KEY) Observable<WeatherPojo> getWeatherForLatLon(@Query("lat") double lat, @Query("lng") double lng, @Query("units") String units);


  class Factory {

    public static APIService create(Context context) {

      OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
      builder.readTimeout(10, TimeUnit.SECONDS);
      builder.connectTimeout(5, TimeUnit.SECONDS);

      if (BuildConfig.DEBUG) {
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
        builder.addInterceptor(interceptor);
      }

      //Extra Headers

      //builder.addNetworkInterceptor().add(chain -> {
      //  Request request = chain.request().newBuilder().addHeader("Authorization", authToken).build();
      //  return chain.proceed(request);
      //});

      builder.addInterceptor(new UnauthorisedInterceptor(context));
      OkHttpClient client = builder.build();

      Retrofit retrofit =
          new Retrofit.Builder().baseUrl(APIService.ENDPOINT).client(client).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJavaCallAdapterFactory.create()).build();

      return retrofit.create(APIService.class);
    }
  }
}

Tặng kem

Tôi biết nó không hợp lý nhưng tôi thấy nó rất hay.

Trong trường hợp có mã lỗi http không được phép , đây là một trình chặn. Tôi sử dụng eventbus để truyền sự kiện.

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import com.androidadvance.ultimateandroidtemplaterx.BaseApplication;
import com.androidadvance.ultimateandroidtemplaterx.events.AuthenticationErrorEvent;

import de.greenrobot.event.EventBus;
import java.io.IOException;
import javax.inject.Inject;
import okhttp3.Interceptor;
import okhttp3.Response;

public class UnauthorisedInterceptor implements Interceptor {

  @Inject EventBus eventBus;

  public UnauthorisedInterceptor(Context context) {
    BaseApplication.get(context).getApplicationComponent().inject(this);
  }

  @Override public Response intercept(Chain chain) throws IOException {
    Response response = chain.proceed(chain.request());
    if (response.code() == 401) {
      new Handler(Looper.getMainLooper()).post(() -> eventBus.post(new AuthenticationErrorEvent()));
    }
    return response;
  }
}

lấy mã từ https://github.com/AndreiD/UltimAndroidTemplateRx (dự án của tôi).


9

Dường như không có cách nào để thực hiện cơ bản + nội dung, nhưng bạn có thể sử dụng FULL và lọc các tiêu đề mà bạn không muốn.

RestAdapter adapter = new RestAdapter.Builder()
                          .setEndpoint(syncServer)
                          .setErrorHandler(err)
                          .setConverter(new GsonConverter(gson))
                          .setLogLevel(logLevel)
                          .setLog(new RestAdapter.Log() {
                              @Override
                              public void log(String msg) {
                                  String[] blacklist = {"Access-Control", "Cache-Control", "Connection", "Content-Type", "Keep-Alive", "Pragma", "Server", "Vary", "X-Powered-By"};
                                  for (String bString : blacklist) {
                                      if (msg.startsWith(bString)) {
                                          return;
                                      }
                                  }
                                  Log.d("Retrofit", msg);
                              }
                          }).build();

Có vẻ như khi ghi đè nhật ký, phần nội dung được bắt đầu bằng một thẻ tương tự như

[ 02-25 10:42:30.317 25645:26335 D/Retrofit ]

vì vậy sẽ dễ dàng đăng nhập cơ bản + nội dung bằng cách điều chỉnh bộ lọc tùy chỉnh. Tôi đang sử dụng danh sách đen, nhưng cũng có thể sử dụng danh sách trắng tùy theo nhu cầu của bạn.


4

mã bên dưới đang hoạt động cho cả có tiêu đề và không có tiêu đề để in yêu cầu và phản hồi nhật ký. Lưu ý: Chỉ nhận xét dòng .addHeader () nếu không sử dụng tiêu đề.

HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(interceptor)
                //.addInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)
                .addNetworkInterceptor(new Interceptor() {

                    @Override

                    public okhttp3.Response intercept(Chain chain) throws IOException {
                        Request request = chain.request().newBuilder()
                                // .addHeader(Constant.Header, authToken)
                                   .build();
                        return chain.proceed(request);
                    }
                }).build();

        final Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Constant.baseUrl)
                .client(client) // This line is important
                .addConverterFactory(GsonConverterFactory.create())
                .build();

3

Tôi hy vọng mã này sẽ giúp bạn đăng nhập.
bạn chỉ cần thêm interceptor vào Build.Gradlesau đó thực hiện RetrofitClient.

Bước đầu tiên

Thêm dòng này vào của bạn build.gradle

 implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1' 

Bước thứ hai

Làm cho khách hàng trang bị thêm của bạn


   public class RetrofitClient {

    private Retrofit retrofit;
    private static OkHttpClient.Builder httpClient =
            new OkHttpClient.Builder();
    private static RetrofitClient instance = null;
    private static ApiServices service = null;
    private static HttpLoggingInterceptor logging =
            new HttpLoggingInterceptor();

    private RetrofitClient(final Context context) {
        httpClient.interceptors().add(new Interceptor() {
            @Override
            public okhttp3.Response intercept(Interceptor.Chain chain) throws IOException {
                Request originalRequest = chain.request();
                Request.Builder builder = originalRequest.newBuilder().
                        method(originalRequest.method(), originalRequest.body());
                okhttp3.Response response = chain.proceed(builder.build());
                /*
                Do what you want
                 */
                return response;
            }
        });

        if (BuildConfig.DEBUG) {
            logging.setLevel(HttpLoggingInterceptor.Level.BODY);
            // add logging as last interceptor
            httpClient.addInterceptor(logging);
        }

        retrofit = new Retrofit.Builder().client(httpClient.build()).
                baseUrl(Constants.BASE_URL).
                addConverterFactory(GsonConverterFactory.create()).build();
        service = retrofit.create(ApiServices.class);
    }


    public static RetrofitClient getInstance(Context context) {
        if (instance == null) {
            instance = new RetrofitClient(context);
        }
        return instance;
    }

    public ApiServices getApiService() {
        return service;
    }
}

Kêu gọi

RetrofitClient.getInstance(context).getApiService().yourRequestCall(); 

2

Nếu bạn đang sử dụng Retrofit2 và okhttp3 thì bạn cần biết rằng Interceptor hoạt động theo hàng đợi. Vì vậy, hãy thêm loggingInterceptor vào cuối, sau các Interceptor khác của bạn:

HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
        if (BuildConfig.DEBUG)
            loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);

 new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .addInterceptor(new CatalogInterceptor(context))
                .addInterceptor(new OAuthInterceptor(context))
                .authenticator(new BearerTokenAuthenticator(context))
                .addInterceptor(loggingInterceptor)//at the end
                .build();


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.