Skip to content

Commit

Permalink
Fix a bug where content preview is not logged (line#4979)
Browse files Browse the repository at this point in the history
Motivation:

I got a report that a content preview is not logged with
`Logging{Service,Client}`.

Previously, a content preview could be used to log when sanitized
content is null.
https://github.com/line/armeria/blob/f6f479de876456aca34e231d2f7071c2fa26fd5d/core/src/main/java/com/linecorp/armeria/common/logging/DefaultRequestLog.java#L1528-L1530
When we migrated the code to `LogFomatter`, the condition has changed
slightly. The new condition does not attempt to read a content preview
when `RESPONSE_CONTENT` is available.

https://github.com/line/armeria/blob/f221c8fda5b92412d9985ea659d085168835aa05/core/src/main/java/com/linecorp/armeria/common/logging/TextLogFormatter.java#L229-L234

`RESPONSE_CONTENT` flag can be set with a null value for REST API.
Because `RESPONSE_CONTENT` is mostly used for RPC. If the actual content
is null, we still need to check whether `RESPONSE_CONTENT_PREVIEW` is
available.

Modifications:

- If the value of `REQUEST_CONTENT` or `RESPONSE_CONTENT` is null, try
to get a content preview.

Result:

You can now correctly see a content preview from `LoggingService` and
`LoggingClient`.

Co-authored-by: jrhee17 <[email protected]>
  • Loading branch information
ikhoon and jrhee17 authored Jun 28, 2023
1 parent daa90b2 commit 0c2e28c
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ public String formatRequest(RequestOnlyLog log) {
if (content != null) {
sanitizedContent = requestContentSanitizer.apply(ctx, content);
}
} else if (RequestLogProperty.REQUEST_CONTENT_PREVIEW.isAvailable(flags)) {
}
if (sanitizedContent == null && RequestLogProperty.REQUEST_CONTENT_PREVIEW.isAvailable(flags)) {
final String contentPreview = log.requestContentPreview();
if (contentPreview != null) {
sanitizedContent = requestContentSanitizer.apply(ctx, contentPreview);
Expand Down Expand Up @@ -217,7 +218,8 @@ public String formatResponse(RequestLog log) {
if (content != null) {
sanitizedContent = responseContentSanitizer.apply(ctx, content);
}
} else if (RequestLogProperty.RESPONSE_CONTENT_PREVIEW.isAvailable(flags)) {
}
if (sanitizedContent == null && RequestLogProperty.RESPONSE_CONTENT_PREVIEW.isAvailable(flags)) {
final String contentPreview = log.responseContentPreview();
if (contentPreview != null) {
sanitizedContent = responseContentSanitizer.apply(ctx, contentPreview);
Expand Down Expand Up @@ -264,7 +266,7 @@ public String formatResponse(RequestLog log) {
}

final List<RequestLogAccess> children = log.children();
final int numChildren = children != null ? children.size() : 0;
final int numChildren = children.size();
if (numChildren > 1) {
// Append only when there were retries which the numChildren is greater than 1.
objectNode.put("totalAttempts", String.valueOf(numChildren));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ public String formatRequest(RequestOnlyLog log) {
if (content != null) {
sanitizedContent = requestContentSanitizer.apply(ctx, content);
}
} else if (RequestLogProperty.REQUEST_CONTENT_PREVIEW.isAvailable(flags)) {
}
if (sanitizedContent == null && RequestLogProperty.REQUEST_CONTENT_PREVIEW.isAvailable(flags)) {
final String contentPreview = log.requestContentPreview();
if (contentPreview != null) {
sanitizedContent = requestContentSanitizer.apply(ctx, contentPreview);
Expand Down Expand Up @@ -231,7 +232,8 @@ public String formatResponse(RequestLog log) {
if (content != null) {
sanitizedContent = responseContentSanitizer.apply(ctx, content);
}
} else if (RequestLogProperty.RESPONSE_CONTENT_PREVIEW.isAvailable(flags)) {
}
if (sanitizedContent == null && RequestLogProperty.RESPONSE_CONTENT_PREVIEW.isAvailable(flags)) {
final String contentPreview = log.responseContentPreview();
if (contentPreview != null) {
sanitizedContent = responseContentSanitizer.apply(ctx, contentPreview);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright 2023 LINE Corporation
*
* LINE Corporation licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

package com.linecorp.armeria.common.logging;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import com.linecorp.armeria.client.BlockingWebClient;
import com.linecorp.armeria.client.ClientRequestContextCaptor;
import com.linecorp.armeria.client.Clients;
import com.linecorp.armeria.client.logging.ContentPreviewingClient;
import com.linecorp.armeria.client.logging.LoggingClient;
import com.linecorp.armeria.common.HttpResponse;
import com.linecorp.armeria.common.MediaType;
import com.linecorp.armeria.server.ServerBuilder;
import com.linecorp.armeria.server.logging.ContentPreviewingService;
import com.linecorp.armeria.server.logging.LoggingService;
import com.linecorp.armeria.testing.junit5.server.ServerExtension;

class ContentPreviewInLogFormatterTest {

@RegisterExtension
static ServerExtension server = new ServerExtension() {
@Override
protected void configure(ServerBuilder sb) {
sb.decorator(LoggingService.newDecorator());
sb.decorator(ContentPreviewingService.newDecorator(ContentPreviewerFactory.text(10000)));
sb.service("/foo", (ctx, req) -> {
return HttpResponse.from(req.aggregate().thenApply(agg -> {
return HttpResponse.of("World");
}));
});
}
};

@Test
void shouldLogContentPreview() throws InterruptedException {
final BlockingWebClient client = server.blockingWebClient(cb -> {
cb.decorator(LoggingClient.newDecorator())
.decorator(ContentPreviewingClient.newDecorator(10000));
});

try (ClientRequestContextCaptor captor = Clients.newContextCaptor()) {
client.prepare()
.post("/foo")
.content(MediaType.PLAIN_TEXT_UTF_8, "Hello")
.execute();
final RequestLogAccess log = captor.get().log();
assertContentPreview(log);
assertContentPreview(server.requestContextCaptor().take().log());
}
}

private static void assertContentPreview(RequestLogAccess logAccess) {
final RequestLog log = logAccess.whenComplete().join();
assertThat(log.requestContentPreview()).isEqualTo("Hello");
assertThat(log.responseContentPreview()).isEqualTo("World");

final LogFormatter textLogFormatter = LogFormatter.ofText();
assertThat(textLogFormatter.formatRequest(log)).contains(", content=Hello");
assertThat(textLogFormatter.formatResponse(log)).contains(", content=World");
final LogFormatter jsonLogFormatter = LogFormatter.ofJson();
assertThat(jsonLogFormatter.formatRequest(log)).contains("\"content\":\"Hello\"");
assertThat(jsonLogFormatter.formatResponse(log)).contains("\"content\":\"World\"");
}
}

0 comments on commit 0c2e28c

Please sign in to comment.