java - 使用 Quarkus Resteasy Reactive 记录实体主体

标签 java logging quarkus

我正在尝试实现一个日志记录过滤器来记录对我的 Quarkus 应用程序的 API 端点的请求和响应。我正在使用 Quarkus 1.13.3.Final 和 quarkus-resteasy-reactive。我在调用非阻塞端点时尝试记录请求正文时遇到问题。这是我用来记录请求的代码:

    @ServerRequestFilter(priority = 0)
    public void getFilter(UriInfo info,HttpServerRequest request,ContainerRequestContext ctx) {
        String uuid = UUID.randomUUID().toString();
        ctx.setProperty("log_id", uuid);
        String body = new BufferedReader(new InputStreamReader(ctx.getEntityStream())).lines().collect(Collectors.joining("\n"));
        ctx.setEntityStream(new ByteArrayInputStream(body.getBytes()));
        logger.info("Request: " + uuid + " Method: "+ ctx.getMethod() + " Path: " + info.getPath() + " Remote Address: " +  request.remoteAddress().toString() + " Body: " + body);
    }

当我调用具有@Blocking 注释的 API 端点时,这工作正常,但当我调用非阻塞 API 时,我收到以下错误:

2021-05-17 10:15:29,159 ERROR [org.jbo.res.rea.ser.cor.ExceptionMapping] (vert.x-eventloop-thread-10) Request failed : java.io.UncheckedIOException: java.io.IOException: Attempting a blocking read on io thread
        at java.base/java.io.BufferedReader$1.hasNext(BufferedReader.java:577)
        at java.base/java.util.Iterator.forEachRemaining(Iterator.java:132)
        at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
        at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
        at com.filters.LogginFilter.getFilter(LogginFilter.java:45)
        at com.filters.LogginFilter$GeneratedServerRequestFilter$getFilter.filter(LogginFilter$GeneratedServerRequestFilter$getFilter.zig:73)
        at com.filters.LogginFilter$GeneratedServerRequestFilter$getFilter_Subclass.filter$$superaccessor1(LogginFilter$GeneratedServerRequestFilter$getFilter_Subclass.zig:201)
        at com.filters.LogginFilter$GeneratedServerRequestFilter$getFilter_Subclass$$function$$3.apply(LogginFilter$GeneratedServerRequestFilter$getFilter_Subclass$$function$$3.zig:33)
        at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)
        at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.proceed(InvocationInterceptor.java:63)
        at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.monitor(InvocationInterceptor.java:49)
        at io.quarkus.arc.runtime.devconsole.InvocationInterceptor_Bean.intercept(InvocationInterceptor_Bean.zig:521)
        at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
        at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
        at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)

有没有办法解决这个问题并以非阻塞方式读取请求的主体?或其他记录请求正文的方式?

最佳答案

您需要在工作线程而不是事件循环上强制执行 RESTEasy Reactive 所有 JAX-RS 方法。

为此,只需将您的代码更改为:

@io.smallrye.common.annotation.Blocking
public class MyApplication extends javax.ws.rs.core.Application {

}

关于java - 使用 Quarkus Resteasy Reactive 记录实体主体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67565473/

相关文章:

java - 多线程和并发上下文中的 HttpClient 行为

django - 如何在gunicorn服务器下配置django日志记录以进行生产?

LInux 排序/uniq apache 日志

python - 将 TCL 脚本的输出记录到 Tkinter 文本小部件中

spring-boot - Quarkus Jandex 索引无法解析 Artifact org.springframework :spring-web

java - jackson vs json 简单的流解析

java - 上传后从 nexus 插件访问 Sonatype nexus 工件

java - 默认情况下对项目依赖项运行 gradle 测试

java - 如何在 Quarkus 中为 Kafka 使用 TLS?

jsf - 使用 JVM 模式使用 Quarkus 打包 JSF Web 应用程序