如何提供2个Retrofit接口宽度不同级别的日志记录?

时间:2017-06-21 07:31:12

标签: android retrofit2 dagger-2 okhttp3

我担心的是应该打印多少OkHttp日志 在我的应用的某些屏幕上,有太多的API调用 - > logcat被淹没所以我想限制/关闭那里的日志记录除了一次性调试

我是Dagger 2和依赖注入的新手,一直关注this tutorial

我有以下哪些有效,但我不确定那里是否有任何不良做法或是否可以进一步改进:
(我的应用程序中有大约20个Retrofit API接口/ 20个不同的端点)

@Module
public class NetModule {

    private String mBaseUrl;
    private final HttpLoggingInterceptor LOGGING_FULL = new HttpLoggingInterceptor().setLevel
        (HttpLoggingInterceptor
                .Level.BODY);
private final HttpLoggingInterceptor LOGGING_HEADERS = new HttpLoggingInterceptor().setLevel
        (HttpLoggingInterceptor
                .Level.HEADERS);

    // Constructor needs one parameter to instantiate.
    public NetModule(String baseUrl) {
        this.mBaseUrl = baseUrl;
    }

    @Provides
    @Singleton
    OkHttpClient.Builder provideOkHttpClientBuilder() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        //...
        return builder;
    }

    @Provides
    @Singleton
    Retrofit.Builder provideRetrofitBuilder() {
        return new Retrofit.Builder()
                .baseUrl(mBaseUrl);
    }

    @Provides
    @Singleton
    Api1 provideApi1(OkHttpClient.Builder okHttpClientBuilder, Retrofit.Builder retrofitBuilder) {
        if (BuildConfig.DEBUG || !BuildConfig.FLAVOR.equals(FLAVOUR_PRODUCTION)) {
            okHttpClientBuilder.addInterceptor(LOGGING_HEADERS);
        }
        return retrofitBuilder.client(okHttpClientBuilder.build()).build().create(Api1.class);
    }
    @Provides
    @Named("logging_full")
    @Singleton
    Api1 provideApi1FullLog(OkHttpClient.Builder okHttpClientBuilder, Retrofit.Builder retrofitBuilder) {
        if (BuildConfig.DEBUG || !BuildConfig.FLAVOR.equals(FLAVOUR_PRODUCTION)) {
            okHttpClientBuilder.addInterceptor(LOGGING_FULL);
        }
        return retrofitBuilder.client(okHttpClientBuilder.build()).build().create(Api1.class);
    }
    //... Repeats for Api2, Api3, ..., Api20

}

用法:
1)在大多数情况下,不需要记录体:

@Inject
Api1 api1;

2)在某些情况下,需要登录正文:

@Inject
@Named("logging_full")
Api1 api2;

1 个答案:

答案 0 :(得分:1)

我认为这是一个过度设计的解决方案。如果在http拦截器层需要不同的行为,则不应该处理Api,httpclients或其他任何实例。

这是我解决问题的第一步。

1)为Api使用单个实例,为OkHttpClient使用单个实例(没有多个Dagger提供者)

2)有一个用于调试的拦截器,没有用于生产的拦截器。这样就可以避免使用if( Build.DEBUG )逻辑。

3)为每个端点添加自定义标头

   interface YourApi {

      @Headers("YourCustomLoggingHeader: HEADERS")
      @GET("/your_path")
      ReturnType yourApiMethod( ParamType p);
   }

4)如果注入拦截器(调试版本),则检查拦截方法中的头部并相应地记录。

    @Override public Response intercept(Chain chain) throws IOException {

         String headerValue = chain.request().headers().get("YourCustomLoggingHeader");

         if( TextUtils.isEmpty(headervalue)){
            return = chain.proceed(request);
         }

         // TODO remove header for real request

         switch( headerValue ){
           case "HEADERS":
                //TODO log headers 
                break;
           case "BODY":
                //TODO log body 
                break;
         }
    }

这是伪代码,因为我不在IDE上。