source

Retrofit 2를 사용한 로깅

factcode 2022. 8. 12. 23:18
반응형

Retrofit 2를 사용한 로깅

요청하신 JSON과 정확히 일치하도록 노력하고 있습니다.코드는 다음과 같습니다.

OkHttpClient client = new OkHttpClient();
client.interceptors().add(new Interceptor(){
   @Override public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
      Request request = chain.request();
      Log.e(String.format("\nrequest:\n%s\nheaders:\n%s",
                          request.body().toString(), request.headers()));
      com.squareup.okhttp.Response response = chain.proceed(request);
      return response;
   }
});
Retrofit retrofit = new Retrofit.Builder()
   .baseUrl(API_URL)
   .addConverterFactory(GsonConverterFactory.create())
   .client(client).build();

그러나 로그에는 다음과 같은 내용만 표시됩니다.

request:
com.squareup.okhttp.RequestBody$1@3ff4074d
headers:
Content-Type: application/vnd.ll.event.list+json

" " " " " " " " " " " " 가 되었을 때 어떻게 적절한?setLog() ★★★★★★★★★★★★★★★★★」setLogLevel()리트로핏1 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」

Retrofit 2에서는 Http Logging을 사용해야 합니다.가로채기.

를 「」에 추가합니다.build.gradle 최신 은 다음과 같습니다

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

작성하다Retrofit다음과 같이 합니다.

HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://backend.example.com")
        .client(client)
        .addConverterFactory(GsonConverterFactory.create())
        .build();

return retrofit.create(ApiClient.class);

경고의 는, 변경해 .setLevel 삭제:

interceptor.level(HttpLoggingInterceptor.Level.BODY);

위의 솔루션에서는 logcat 메시지가 에 의해 설정된 이전 메시지와 매우 유사합니다.

setLogLevel(RestAdapter.LogLevel.FULL)

다음과 같은 경우:

Retrofit 버전이 할 수 .logging-interceptor 하다 자세한 내용은 .상세한 것에 대하여는, 코멘트 섹션을 참조하십시오.

Retrofit:Love working with apis on Android (여기 링크) (아니오!)라는 의 저자에게 물어보려고 했는데, 당신이 만난 것을 알게 되었습니다.나는 그들을 위해 광고를 만드는 것이 아니다.하지만 그들은 정말 좋은 남자들이다:) 그리고 저자는 Retrofit 1.9와 Retrofit 2.0-beta 둘 다 Log method로 저에게 바로 답장을 주었습니다.

Retrofit 2.0-beta 코드는 다음과 같습니다.

HttpLoggingInterceptor logging = new HttpLoggingInterceptor();  
// set your desired log level
logging.setLevel(Level.BODY);

OkHttpClient httpClient = new OkHttpClient();  
// add your other interceptors …

// add logging as last interceptor
httpClient.interceptors().add(logging);  // <-- this is the important line!

Retrofit retrofit = new Retrofit.Builder()  
   .baseUrl(API_BASE_URL)
   .addConverterFactory(GsonConverterFactory.create())
   .client(httpClient)
   .build();

HttpLogging을 사용하여 로깅 방식을 추가하는 방법은 다음과 같습니다.가로채기.또, 위에서 말한 그 책의 독자라면, Retrofit 2.0에서는 로그 메서드는 더 이상 존재하지 않는다고 하는 것을 알 수 있을 것입니다.저자에게 물어봤지만, 그것은 올바르지 않습니다.그것에 대해 이야기하면서 내년에 책을 갱신할 예정입니다.

// Retrofit의 Log 메서드에 익숙하지 않은 경우, 더 공유하고 싶은 것이 있습니다.

선택할 수 있는 Logging Level도 몇 가지 있습니다.Level을 사용합니다.대부분의 경우 BODY는 다음과 같은 결과를 가져옵니다.

여기에 이미지 설명 입력

이미지 내의 거의 모든 http 스태프는 헤더, 콘텐츠 및 응답 등입니다.

그리고 파티에 모든 손님이 꼭 필요한 것은 아닙니다.정상적으로 연결되었는지, 내 Activi & Fragmetn에서 인터넷 통화가 정상적으로 이루어졌는지 알고 싶을 뿐입니다.그러면 Level을 자유롭게 사용할 수 있습니다.BASIC은 다음과 같은 내용을 반환합니다.

여기에 이미지 설명 입력

안에서 상태 코드 200 OK를 찾을 수 있습니까?이상입니다:)

그리고 레벨이라는 또 다른 사람이 있다.HEADER: 네트워크의 헤더만 반환됩니다.물론 여기 또 다른 사진이 있습니다.

여기에 이미지 설명 입력

이것으로 Logging의 트릭은 끝입니다.

그리고 거기서 많이 배운 튜토리얼을 소개해드리겠습니다.그들은 Retrofit에 관한 거의 모든 것에 대해 이야기하는 훌륭한 게시물을 많이 가지고 있으며, Retrofit 2.0이 출시되는 동시에 게시물을 계속 업데이트하고 있다.그 작품들을 봐주세요.시간이 많이 절약될 것 같아요.

여기 있습니다.Interceptor는 요구와 응답 본문을 모두 기록합니다(OkHttp 문서 및 기타 SO 응답 예에 따라 Timber를 사용합니다).

public class TimberLoggingInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();

        long t1 = System.nanoTime();
        Timber.i("Sending request %s on %s%n%s", request.url(), chain.connection(), request.headers());
        Timber.v("REQUEST BODY BEGIN\n%s\nREQUEST BODY END", bodyToString(request));

        Response response = chain.proceed(request);

        ResponseBody responseBody = response.body();
        String responseBodyString = response.body().string();

        // now we have extracted the response body but in the process
        // we have consumed the original reponse and can't read it again
        // so we need to build a new one to return from this method

        Response newResponse = response.newBuilder().body(ResponseBody.create(responseBody.contentType(), responseBodyString.getBytes())).build();

        long t2 = System.nanoTime();
        Timber.i("Received response for %s in %.1fms%n%s", response.request().url(), (t2 - t1) / 1e6d, response.headers());
        Timber.v("RESPONSE BODY BEGIN:\n%s\nRESPONSE BODY END", responseBodyString);

        return newResponse;
    }

    private static String bodyToString(final Request request){

        try {
            final Request copy = request.newBuilder().build();
            final Buffer buffer = new Buffer();
            copy.body().writeTo(buffer);
            return buffer.readUtf8();
        } catch (final IOException e) {
            return "did not work";
        }
    }
}

제가 직면한 주요 문제는 헤더를 동적으로 추가하고 디버깅로그캣에 기록하는 것이었습니다.두 개의 요격기를 추가하려고 했어요하나는 로깅용이고 다른 하나는 이동 중 헤더 추가용입니다(토큰 인가).문제는 .addInterceptor 또는 .addNetwork 입니다.가로채기."네트워크 인터셉터는 항상 어플리케이션 인터셉터 뒤에 있습니다.https://github.com/square/okhttp/wiki/Interceptors 를 참조해 주세요.헤더와 로그의 작업 예를 다음에 나타냅니다.

OkHttpClient httpClient = new OkHttpClient.Builder()
            //here we can add Interceptor for dynamical adding headers
            .addNetworkInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    Request request = chain.request().newBuilder().addHeader("test", "test").build();
                    return chain.proceed(request);
                }
            })
            //here we adding Interceptor for full level logging
            .addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
            .build();

    Retrofit retrofit = new Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create(gsonBuilder.create()))
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .client(httpClient)
            .baseUrl(AppConstants.SERVER_ADDRESS)
            .build();

이것을 시험해 보세요.

Request request = chain.request();
Buffer buffer = new Buffer();
request.body().writeTo(buffer);
String body = buffer.readUtf8();

후 그,에서bodyJSON을 사용하다

도 비슷한 .setLevel() 때 메서드가 되지 않았습니다.격기, ,이

HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

Retrofit2의 로그를 생성하기 위해 해결한 방법은 다음과 같습니다.

부양가족을 추가한 것 같은데

implementation "com.squareup.okhttp3:logging-interceptor:4.7.2"

최신 버전의 경우 다음 링크를 참조하십시오.

https://github.com/square/okhttp/tree/master/okhttp-logging-interceptor )

여기에서는 추가 방법에 대해서도 설명했습니다.

는 는는 with with with with with with with with with with with with라는 이름으로 클래스를 만들었습니다.AddLoggingInterceptor 암호는

public class AddLoggingInterceptor {

    public static OkHttpClient setLogging(){
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
        loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(loggingInterceptor)
                .build();

        return okHttpClient;
    }
}

그럼, 우리가 레트로핏을 인스턴스화 할 때,

 public static Retrofit getRetrofitInstance() {
    if (retrofit == null) {
        retrofit = new retrofit2.Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .client(AddLoggingInterceptor.setLogging()) // here the method is called inside client() method, with the name of class, since it is a static method.
                .build();
    }
    return retrofit;
}

Android를 볼 수. 【Android Studio】를 하십시오. 이치노okHttp이치노그것은 나에게 효과가 있었다.무슨 문제가 있으면 여기로 문자 보내 주세요.

Retrofit2 및 okhttp3를 사용하는 경우 대행 수신기가 대기열별로 작동한다는 것을 알아야 합니다.따라서 로깅 추가다른 요격기 다음으로 마지막에 요격기:

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))//first
                .addInterceptor(new OAuthInterceptor(context))//second
                .authenticator(new BearerTokenAuthenticator(context))
                .addInterceptor(loggingInterceptor)//third, log at the end
                .build();

setLogLevel()이 Retrofit의 최종 2.0 버전에서 반환될지는 모르겠지만, 현재로서는 로깅에 인터셉터를 사용할 수 있습니다.

좋은 예는 OkHttp wiki에서 찾을 수 있습니다.https://github.com/square/okhttp/wiki/Interceptors

OkHttpClient client = new OkHttpClient();
client.interceptors().add(new LoggingInterceptor());

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://www.yourjsonapi.com")
        .addConverterFactory(GsonConverterFactory.create())
        .client(client)
        .build();

Retrofit에서 높은 수준의 로그가 필요한 경우 가로채기를 다음과 같이 사용하세요.

public static class LoggingInterceptor implements Interceptor {
    @Override public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        long t1 = System.nanoTime();
        String requestLog = String.format("Sending request %s on %s%n%s",
                request.url(), chain.connection(), request.headers());
        //YLog.d(String.format("Sending request %s on %s%n%s",
        //        request.url(), chain.connection(), request.headers()));
        if(request.method().compareToIgnoreCase("post")==0){
            requestLog ="\n"+requestLog+"\n"+bodyToString(request);
        }
        Log.d("TAG","request"+"\n"+requestLog);

        Response response = chain.proceed(request);
        long t2 = System.nanoTime();

        String responseLog = String.format("Received response for %s in %.1fms%n%s",
                response.request().url(), (t2 - t1) / 1e6d, response.headers());

        String bodyString = response.body().string();

        Log.d("TAG","response"+"\n"+responseLog+"\n"+bodyString);

        return response.newBuilder()
                .body(ResponseBody.create(response.body().contentType(), bodyString))
                .build();
        //return response;
    }
}

public static String bodyToString(final Request request) {
    try {
        final Request copy = request.newBuilder().build();
        final Buffer buffer = new Buffer();
        copy.body().writeTo(buffer);
        return buffer.readUtf8();
    } catch (final IOException e) {
        return "did not work";
    }
}`

우대 : https://github.com/square/retrofit/issues/1072 #

코틀린 코드

        val interceptor = HttpLoggingInterceptor()
        interceptor.level = HttpLoggingInterceptor.Level.BODY
        val client = OkHttpClient.Builder().addInterceptor(interceptor).build()
        val retrofit = Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .build()

        return retrofit.create(PointApi::class.java)

다음 코드 세트는 문제없이 작동합니다.

그라들

// Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.12.1'

Retrofit 클라이언트

HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);

OkHttpClient client = new OkHttpClient.Builder()
        .addInterceptor(logging)
        .build();

retrofit = new Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .client(client)
        .build();

Android Studio 하단의 Profiler 탭으로 이동하여 + 기호를 클릭하여 새 세션을 시작하고 "네트워크"에서 원하는 스파이크를 선택하여 결과를 확인할 수도 있습니다.그곳에서는 모든 것을 얻을 수 있지만, 번거롭고 느리다.아래 이미지를 참조해 주세요.

여기에 이미지 설명 입력

Facebook의 Stetho를 추가하여 Chrome의 네트워크 트레이스를 참조할 수도 있습니다.http://facebook.github.io/stetho/

final OkHttpClient.Builder builder = new OkHttpClient.Builder();
if (BuildConfig.DEBUG) {
    builder.networkInterceptors().add(new StethoInterceptor());
}

그런 다음 Chrome에서 "crome://inspect"를 엽니다.

Retrofit 2.0.2의 경우 코드는 다음과 같습니다.

   **HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient.Builder httpClient=new OkHttpClient.Builder();
        httpClient.addInterceptor(logging);**


        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    **.client(httpClient.build())**
                    .build();
        }

이렇게 하면 별도의 객체를 작성하지 않고 Logging을 사용하여 개조 객체가 생성됩니다.

 private static final Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(new OkHttpClient().newBuilder()
                    .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
                    .readTimeout(READ_TIMEOUT_SECONDS, TimeUnit.SECONDS)
                    .writeTimeout(WRITE_TIMEOUT_SECONDS, TimeUnit.SECONDS)
                    .connectTimeout(CONNECTION_TIMEOUT_SECONDS, TimeUnit.SECONDS)
                    .build())
            .addConverterFactory(GsonConverterFactory.create())
            .build();

먼저 build.gradle에 종속성 추가:

구현 'com'squareup.okhttp3: square-opervisor: 3.12.1'

Kotlin을 사용하는 동안 다음과 같이 Logging Interceptor를 추가할 수 있습니다.

companion object {
    val okHttpClient = OkHttpClient().newBuilder()
            .addInterceptor(HttpLoggingInterceptor().apply {
                level = HttpLoggingInterceptor.Level.BODY
            })
            .build()


    fun getRetrofitInstance(): Retrofit {
        val retrofit = Retrofit.Builder()
                .client(okHttpClient)
                .baseUrl(ScanNShopConstants.BASE_URL)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build()

        return retrofit
    }
}

Retrofit 2에서 이를 제대로 수행하는 가장 좋은 방법은 로거 인터셉터를 네트워크로 추가하는 것입니다.인터셉터 네트워크 헤더와 커스텀헤더도 출력합니다.중요한 것은 인터셉터가 스택으로 기능한다는 것을 명심하고 마지막에 로거를 추가하는 것입니다.

OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addInterceptor(new MyCustomInterceptor());
builder.connectTimeout(60, TimeUnit.SECONDS);
builder.readTimeout(60, TimeUnit.SECONDS);
builder.writeTimeout(60, TimeUnit.SECONDS);
// important line here
builder.addNetworkInterceptor(LoggerInterceptor());

이 답변의 대부분은 로그를 확인하는 가장 멋진 방법 중 하나인 이 도구를 제외한 거의 모든 것을 다루고 있습니다.

페이스북의 스테토입니다.이것은 Google Chrome에서 앱의 네트워크 트래픽을 모니터링/로그할 수 있는 뛰어난 도구입니다.이곳 Github에서도 찾을 수 있습니다.

여기에 이미지 설명 입력

다음은 로그에서 요청/응답 매개 변수를 필터링하는 간단한 방법입니다.HttpLoggingInterceptor:

// Request patterns to filter
private static final String[] REQUEST_PATTERNS = {
    "Content-Type",
};
// Response patterns to filter
private static final String[] RESPONSE_PATTERNS = {"Server", "server", "X-Powered-By", "Set-Cookie", "Expires", "Cache-Control", "Pragma", "Content-Length", "access-control-allow-origin"};

// Log requests and response
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
    @Override
    public void log(String message) {

        // Blacklist the elements not required
        for (String pattern: REQUEST_PATTERNS) {
            if (message.startsWith(pattern)) {
                return;
            }
        }
        // Any response patterns as well...
        for (String pattern: RESPONSE_PATTERNS) {
            if (message.startsWith(pattern)) {
                return;
            }
        }
        Log.d("RETROFIT", message);
    }
});
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

자세한 내용은 다음과 같습니다.

https://gist.github.com/mankum93/179c2d5378f27e95742c3f2434de7168

개조 로그

Retrofit의 대행 수신기는 http 요청을 처리할 수 있는 훌륭한 기능입니다.여기에는 다음 두 가지 유형이 있습니다.application그리고.network가로채기

요청/응답 기록이 필요한 경우 사용을 권장합니다.출력은 와 매우 유사합니다.Stetho 더 인 '어플리케이션,어플리케이션,어플리케이션,어플리케이션,어플리케이션,어플리케이션,어플리케이션,어플리케이션 등입니다.

[찰스 프록시 변경 응답]

Retrofit에서 인쇄 로그를 찾는 방법을 찾았습니다.

OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .addInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    Request request = chain.request();
                    if (BuildConfig.DEBUG) {
                        Log.e(getClass().getName(), request.method() + " " + request.url());
                        Log.e(getClass().getName(), "" + request.header("Cookie"));
                        RequestBody rb = request.body();
                        Buffer buffer = new Buffer();
                        if (rb != null)
                            rb.writeTo(buffer);
                        LogUtils.LOGE(getClass().getName(), "Payload- " + buffer.readUtf8());
                    }
                    return chain.proceed(request);
                }
            })
            .readTimeout(60, TimeUnit.SECONDS)
            .connectTimeout(60, TimeUnit.SECONDS)
            .build();

            iServices = new Retrofit.Builder()
                    .baseUrl("Your Base URL")
                    .client(okHttpClient)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build()
                    .create(Your Service Interface .class);

저는 좋아요.

java.lang.ClassNotFoundException를 들고

제거했습니다.

implementation("com.squareup.okhttp3:okhttp:4.9.0")

모든 게 잘 풀려요

이봐, 난 이미 해결책을 찾았어

  public static <T> T createApi(Context context, Class<T> clazz, String host, boolean debug) {
    if (singleton == null) {
        synchronized (RetrofitUtils.class) {
            if (singleton == null) {
                RestAdapter.Builder builder = new RestAdapter.Builder();
                builder
                        .setEndpoint(host)
                        .setClient(new OkClient(OkHttpUtils.getInstance(context)))
                        .setRequestInterceptor(RequestIntercepts.newInstance())
                        .setConverter(new GsonConverter(GsonUtils.newInstance()))
                        .setErrorHandler(new ErrorHandlers())
                        .setLogLevel(debug ? RestAdapter.LogLevel.FULL : RestAdapter.LogLevel.NONE)/*LogLevel.BASIC will cause response.getBody().in() close*/
                        .setLog(new RestAdapter.Log() {
                            @Override
                            public void log(String message) {
                                if (message.startsWith("{") || message.startsWith("["))
                                    Logger.json(message);
                                else {
                                    Logger.i(message);
                                }
                            }
                        });
                singleton = builder.build();
            }
        }
    }
    return singleton.create(clazz);
}

언급URL : https://stackoverflow.com/questions/32514410/logging-with-retrofit-2

반응형