Skip to content

Commit

Permalink
feat: log http response body in debug mode (#95)
Browse files Browse the repository at this point in the history
* feat: log http response body when log_level equals debug

* refactor: reset input stream after logging response

* refactor: fix prom sink tests by mocking response body

* refactor: print response body via toString method

* feat: log http response body if debug is enabled

* refactor: remove serializableHttpResponse class

Co-authored-by: mayur.gubrele <2310-mayur.gubrele@users.noreply.source.golabs.io>
  • Loading branch information
MayurGubrele and mayur.gubrele committed Sep 10, 2021
1 parent f06e5d8 commit 1918215
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/main/java/io/odpf/firehose/metrics/Instrumentation.java
Expand Up @@ -75,6 +75,9 @@ public void logError(String template, Object... t) {
logger.error(template, t);
}

public boolean isDebugEnabled() {
return logger.isDebugEnabled();
}
// ============== FILTER MESSAGES ==============

/**
Expand Down
22 changes: 22 additions & 0 deletions src/main/java/io/odpf/firehose/sink/common/AbstractHttpSink.java
Expand Up @@ -14,12 +14,17 @@
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.util.EntityUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static io.odpf.firehose.metrics.Metrics.SINK_HTTP_RESPONSE_CODE_TOTAL;

Expand Down Expand Up @@ -49,6 +54,9 @@ public List<Message> execute() throws Exception {
response = httpClient.execute(httpRequest);
List<String> contentStringList = null;
getInstrumentation().logInfo("Response Status: {}", statusCode(response));
if (shouldLogResponse(response)) {
printResponse(response);
}
if (shouldLogRequest(response)) {
contentStringList = readContent(httpRequest);
printRequest(httpRequest, contentStringList);
Expand Down Expand Up @@ -88,6 +96,10 @@ private boolean shouldLogRequest(HttpResponse response) {
return response == null || getRequestLogStatusCodeRanges().containsKey(response.getStatusLine().getStatusCode());
}

private boolean shouldLogResponse(HttpResponse response) {
return getInstrumentation().isDebugEnabled() && response != null;
}

private boolean shouldRetry(HttpResponse response) {
return response == null || getRetryStatusCodeRanges().containsKey(response.getStatusLine().getStatusCode());
}
Expand Down Expand Up @@ -119,6 +131,16 @@ private void printRequest(HttpEntityEnclosingRequestBase httpRequest, List<Strin
getInstrumentation().logInfo(entireRequest);
}

private void printResponse(HttpResponse httpResponse) throws IOException {
try (InputStream inputStream = httpResponse.getEntity().getContent()) {
String responseBody = String.format("Response Body: %s",
Strings.join(new BufferedReader(new InputStreamReader(
inputStream,
StandardCharsets.UTF_8)).lines().collect(Collectors.toList()), "\n"));
getInstrumentation().logDebug(responseBody);
}
}

protected abstract List<String> readContent(HttpEntityEnclosingRequestBase httpRequest) throws IOException;

protected abstract void captureMessageDropCount(HttpResponse response, List<String> contentString) throws IOException;
Expand Down
22 changes: 22 additions & 0 deletions src/test/java/io/odpf/firehose/sink/http/HttpSinkTest.java
Expand Up @@ -407,4 +407,26 @@ public void shouldCaptureResponseStatusCount() throws Exception {

verify(instrumentation, times(1)).captureCountWithTags("firehose_sink_http_response_code_total", 1, "status_code=" + statusLine.getStatusCode(), "url=" + uri.getPath());
}

@Test
public void shouldLogResponseBodyWhenDebugIsEnabledAndNonNullResponse() throws Exception {
when(response.getStatusLine()).thenReturn(statusLine);
when(statusLine.getStatusCode()).thenReturn(200);

List<HttpEntityEnclosingRequestBase> httpRequests = Collections.singletonList(httpPut);

when(httpPut.getMethod()).thenReturn("PUT");
when(httpPut.getURI()).thenReturn(new URI("http://dummy.com"));
when(httpClient.execute(httpPut)).thenReturn(response);
when(response.getEntity()).thenReturn(httpEntity);
when(httpEntity.getContent()).thenReturn(new StringInputStream("[{\"key\":\"value1\"},{\"key\":\"value2\"}]"));
when(request.build(messages)).thenReturn(httpRequests);
when(instrumentation.isDebugEnabled()).thenReturn(true);

HttpSink httpSink = new HttpSink(instrumentation, request, httpClient, stencilClient,
retryStatusCodeRange, requestLogStatusCodeRanges);
httpSink.prepare(messages);
httpSink.execute();
verify(instrumentation, times(1)).logDebug("Response Body: [{\"key\":\"value1\"},{\"key\":\"value2\"}]");
}
}

0 comments on commit 1918215

Please sign in to comment.