Skip to content

Conversation

@ennoeller
Copy link
Contributor

No description provided.

@ennoeller ennoeller requested a review from rammrain September 2, 2024 06:11
@rammrain rammrain marked this pull request as draft September 2, 2024 11:11
@rammrain rammrain requested a review from Jorich September 2, 2024 11:19
@rammrain
Copy link
Member

rammrain commented Sep 2, 2024

Let's take the opportunity to replace okhttp3.logging.HttpLoggingInterceptor with our own implementation that will fix the most common flaws with the interceptor provided by Retrofit:

  1. Add the ability to extend and modify the behaviour of logging
  2. Use fewer logging entries to log the entire request-response cycle
  3. Use MDC to improve the request-response log filtering in Graylog and other platforms

Otherwise the new interceptor should follow the same features as Retrofit has, including log levels and header suppression.

Let's try and fit the entire log in a single log entry.


sb.append(getRequestDescription(request, connection));

if (loggingLevel.getLevel() >= 2) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For readability reasons I would've written like this
if (loggingLevel.getLevel() >= LoggingLevel.HEADERS.getLevel()) ...
It would've been even better to write something like this
if (loggingLevel.includes(LoggingLevel.HEADERS))

}

private OkHttpClient.Builder createDefaultBuilder(HttpLoggingInterceptor loggingInterceptor) {
private OkHttpClient.Builder createDefaultBuilder(Interceptor loggingInterceptor) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should be LoggingInterceptor otherwise someone might misuse it.

sb.append("\n").append(getRequestHeaders(request));
}

if (loggingLevel.getLevel() >= 3) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here
if (loggingLevel.getLevel() >= LoggingLevel.BODY.getLevel()) ...
It would've been even better to write something like this
if (loggingLevel.includes(LoggingLevel.BODY))


for (int i = 0; i < requestHeaders.size(); i++) {
var name = requestHeaders.name(i);
if (List.of("content-type", "content-length").contains(name.toLowerCase())) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In some places we use constants, others we hardcode. Maybe we should follow same convention - use constants


for (int i = 0; i < responseHeaders.size(); i++) {
var name = responseHeaders.name(i);
if (List.of("content-type", "content-length").contains(name.toLowerCase())) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In some places we use constants, others we hardcode. Maybe we should follow same convention - use constants

}

if (contentLength != 0L) {
return buffer.clone().readString(charset);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should allow to limit how much of the content gets logged. If response is a 150k element json list of objects, this log entry could cause harm to log collector and become virtually unreadable.

import static okhttp3.internal.http.HttpHeaders.promisesBody;

@Slf4j
public class RetrofitLoggingInterceptor implements LoggingInterceptor {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to add some sort of white/blacklist logic to control for which endpoints we want to log/omit bodies.
This would allow for example to omit response bodies for requests that contain confidential data in body and handle that separately.

@rammrain
Copy link
Member

Copy link
Contributor

@Jorich Jorich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly looks promising. Just a few small fixes

private Converter.Factory converterFactory;
private OkHttpClient.Builder clientBuilder;

public static <T> RetrofitApiBuilder<T> create(String baseUrl, Class<T> definition) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here goes the backward compatibility :)
I am not sure how many cases use retrofit api builder directly but I am afraid this change is a major version bump.

return this;
}

public RetrofitApiBuilder<T> loggingLevel(LoggingLevel level) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also results in major version bump

public void write(Map<String, String> container) {
Map<String, String> currentContext = MDC.getCopyOfContextMap();

log(container);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would wrap this in try {} finally {} block so that MDC wouldn't be left unswapped

ennoeller and others added 7 commits October 31, 2024 11:08
Jorich
Jorich previously approved these changes Nov 5, 2024
return new RetrofitLoggingInterceptorImplementation(mappers, new RetrofitLogLoggerWriterAdapter());
}

// testida üle, kui on vajadus mapper üle kirjutada
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose that is done

…r-interceptor' into feature/enable-custom-http-logger-interceptor
@sonarqubecloud
Copy link

sonarqubecloud bot commented Nov 5, 2024

@ennoeller ennoeller marked this pull request as ready for review November 5, 2024 10:19
@ennoeller ennoeller merged commit 29fb286 into master Nov 5, 2024
@ennoeller ennoeller deleted the feature/enable-custom-http-logger-interceptor branch November 5, 2024 10:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants