我正在创建一个日志系统,其中所有由特定请求生成的日志都存储在一个请求范围内的对象中,并随后记录在一个ContainerResponseFilter上。因此,与每个请求有许多日志不同,我将只有一个包含有关该特定请求的所有信息的日志。
如何存储日志:
@RequestScoped
class Logs {
private List<Log> logs;
...
}
如何添加日志:
@Inject
Logs logs;
...
private void myFunction(){
logs.add(new Log(...));
}
如何在ContainerResponseFilter中编写它们:
@Inject
Logs logs;
@Inject
Logger logger;
@Override
public void filter(final ContainerRequestContext requestContext, final ContainerResponseContext responseContext) {
logger.log(logs.entries());
}
如何启动async代码:
Uni.createFrom().item(myItem)
.emitOn(Infrastructure.getDefaultWorkerPool())
.subscribe().with(this::myFunc)
我遇到的问题是一个请求启动了一个在工作线程上运行的异步Uni。由于它不在请求的同一线程上,我有两个问题:
- ContainerResponseFilter可能在Uni之前完成执行,这意味着在Uni中执行的任何日志都将丢失。
- 由于@RequestScoped上下文似乎是线程本地的,因此在Uni中执行的日志被放置在一个完全独立的结构上。
通过让ContainerResponseFilter启动一个在前面提到的异步uni之后运行的Uni,我设法解决了第一个问题,但没有解决第二个问题。
对于如何解决最后一个问题,有什么建议吗?当运行在工作线程或任何其他与请求本身异步的上下文上时,我可以立即单独记录日志。
1条答案
按热度按时间hs1ihplo1#
如果你真的需要在过滤器中以异步方式完成一些事情(我承认我不确定你是否会这样做),那么你应该使用Quarkus的ServerResponseFilter,它允许你返回
Uni
作为响应类型。他是一个典型的例子:
您可以在这里找到更多信息。