feat: add quarkus-client-logger module with RedactingClientLogger
Some checks failed
Build / build (pull_request) Failing after 25s
Some checks failed
Build / build (pull_request) Failing after 25s
This commit is contained in:
parent
1f38615a15
commit
e6ec3f57f8
2 changed files with 107 additions and 0 deletions
1
pom.xml
1
pom.xml
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module>quarkus-audit-tools</module>
|
<module>quarkus-audit-tools</module>
|
||||||
|
<module>quarkus-client-logger</module>
|
||||||
<module>quarkus-clock-service</module>
|
<module>quarkus-clock-service</module>
|
||||||
<module>quarkus-json-service</module>
|
<module>quarkus-json-service</module>
|
||||||
<module>quarkus-message-digest-service</module>
|
<module>quarkus-message-digest-service</module>
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
package ch.phoenix.oss.quarkus.commons.client.logger;
|
||||||
|
|
||||||
|
import io.vertx.core.Handler;
|
||||||
|
import io.vertx.core.MultiMap;
|
||||||
|
import io.vertx.core.buffer.Buffer;
|
||||||
|
import io.vertx.core.http.HttpClientRequest;
|
||||||
|
import io.vertx.core.http.HttpClientResponse;
|
||||||
|
import jakarta.enterprise.context.Dependent;
|
||||||
|
import jakarta.ws.rs.core.HttpHeaders;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
import org.jboss.resteasy.reactive.client.api.ClientLogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is based on org.jboss.resteasy.reactive.client.logging.DefaultClientLogger,
|
||||||
|
* with the only change being that the value of "Authorization" header, when present,
|
||||||
|
* is redacted.
|
||||||
|
*/
|
||||||
|
@Dependent
|
||||||
|
public class RedactingClientLogger implements ClientLogger {
|
||||||
|
|
||||||
|
private static final Logger log = Logger.getLogger(RedactingClientLogger.class);
|
||||||
|
|
||||||
|
private int bodySize;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBodySize(int bodySize) {
|
||||||
|
this.bodySize = bodySize;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void logResponse(HttpClientResponse response, boolean redirect) {
|
||||||
|
if (!log.isDebugEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//noinspection Convert2Lambda
|
||||||
|
response.bodyHandler(new Handler<>() {
|
||||||
|
@Override
|
||||||
|
public void handle(Buffer body) {
|
||||||
|
log.debugf(
|
||||||
|
"%s: %s %s, Status[%d %s], Headers[%s], Body:\n%s",
|
||||||
|
redirect ? "Redirect" : "Response",
|
||||||
|
response.request().getMethod(),
|
||||||
|
response.request().absoluteURI(),
|
||||||
|
response.statusCode(),
|
||||||
|
response.statusMessage(),
|
||||||
|
asString(response.headers()),
|
||||||
|
bodyToString(body));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void logRequest(HttpClientRequest request, Buffer body, boolean omitBody) {
|
||||||
|
if (!log.isDebugEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (omitBody) {
|
||||||
|
log.debugf(
|
||||||
|
"Request: %s %s Headers[%s], Body omitted",
|
||||||
|
request.getMethod(), request.absoluteURI(), asString(request.headers()));
|
||||||
|
} else if (body == null || body.length() == 0) {
|
||||||
|
log.debugf(
|
||||||
|
"Request: %s %s Headers[%s], Empty body",
|
||||||
|
request.getMethod(), request.absoluteURI(), asString(request.headers()));
|
||||||
|
} else {
|
||||||
|
log.debugf(
|
||||||
|
"Request: %s %s Headers[%s], Body:\n%s",
|
||||||
|
request.getMethod(), request.absoluteURI(), asString(request.headers()), bodyToString(body));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String bodyToString(Buffer body) {
|
||||||
|
if (body == null) {
|
||||||
|
return "";
|
||||||
|
} else if (bodySize <= 0) {
|
||||||
|
return body.toString();
|
||||||
|
} else {
|
||||||
|
String bodyAsString = body.toString();
|
||||||
|
return bodyAsString.substring(0, Math.min(bodySize, bodyAsString.length()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String asString(MultiMap headers) {
|
||||||
|
if (headers.isEmpty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
StringBuilder sb = new StringBuilder((headers.size() * (6 + 1 + 6))
|
||||||
|
+ (headers.size() - 1)); // this is a very rough estimate of a result like 'key1=value1 key2=value2'
|
||||||
|
boolean isFirst = true;
|
||||||
|
for (Map.Entry<String, String> entry : headers) {
|
||||||
|
if (isFirst) {
|
||||||
|
isFirst = false;
|
||||||
|
} else {
|
||||||
|
sb.append(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
var key = entry.getKey();
|
||||||
|
var value = HttpHeaders.AUTHORIZATION.equalsIgnoreCase(key) ? "*****" : entry.getValue();
|
||||||
|
|
||||||
|
sb.append(key).append('=').append(value);
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue