我用的是Spring项目Reactor堆芯3.1.8。释放我正在为我的微服务实现一个日志框架,使其具有JSON审计日志,因此使用上下文来存储某些字段,如userID、collaboration ID、component Name和其他几个在请求生命周期中常见的字段。由于Threadlocal
不能在反应式服务中用于存储这些元素,因此我必须使用上下文。但是,要了解上下文显然非常困难。我可以通过doOnEach
函数调用从信号中获取对上下文的引用,就这样。如果我使用doOnEach
,它会被所有信号类型调用,我无法隔离错误、成功等。此外,如果其间发生错误,那么所有后续的doOnEach
都会被调用,因此日志会重复使用多个onError
日志类型。
关于如何在Spring reactor中获取对上下文对象的引用,文档非常有限。任何关于更好地生成审计日志的方法的帮助,都将在函数调用和外部调用之间存储并传播协作ID和其他特定于请求的ID,我们将不胜感激。
代码片段——在WebFilter中,我设置了几个键值对,如下所示-
override fun filter(exchange: ServerWebExchange, filterChain: WebFilterChain): Mono<Void> {
// add the context variables at the end of the chain as the context moves from
// downstream to upstream.
return filterChain.filter(exchange)
.subscriberContext { context ->
var ctx = context.put(RestRequestInfo::class.java, restRequestInfo(exchange))
ctx = ctx.put(COLLABORATION_ID, UUID.randomUUID().toString())
ctx=ctx.put(COMPONENT_NAME, "sample-component-name")
ctx=ctx.put(USER_NAME, "POSTMAN")
ctx
}
}
然后我想在所有后续日志中使用上面添加的键值对,这样日志聚合器(如Splunk)就可以根据协作ID获取与这个特定请求相关的所有JSON日志。现在,从上下文中获取值的唯一方法是通过doOnEach函数调用,在这里,我们得到信号的句柄,通过它我们得到上下文的句柄。但所有doOnEach都会在每个事件中被调用,无论每个函数调用是成功还是失败
return Mono.just(request)
.doOnEach(**Code to log with context data**)
.map(RequestValidations::validateRequest)
.doOnEach(**Code to log with context data**)
.map(RequestValidations::buildRequest)
.map(RequestValidations::validateQueryParameters)
.doOnEach(**Code to log with context data**)
.flatMap(coverageSummariesGateway::getCoverageSummaries)
.doOnEach(**Code to log with context data**)
.map({ coverageSummaries ->
getCoverageSummariesResponse(coverageSummaries, serviceReferenceId) })
.doOnEach(**Code to log with context data**)
.flatMap(this::renderSuccess)
.doOnEach(**Code to log with context data**)
.doOnError { logger.info("ERROR OCCURRED") }
非常感谢。
你可以这样做:
return Mono.just(request)
.doOnEach(**Code to log with context data**)
.flatMap( r -> withMDC(r, RequestValidations::validateRequest))
下面的方法将填充mapping diagnostic context(MDC),以便您的日志中自动包含它(取决于您的日志模式)。例如,logback有%X{traceId}
其中traceId
是tracingContext
映射中的一个键。
java prettyprint-override">public static <T, R> Mono<R> withMDC(T value, Function<T, Mono<R>> f) {
return Mono.subscriberContext()
.flatMap( ctx -> {
Optional<Map> tracingContext = ctx.getOrEmpty("tracing-context-key");
if (tracingContext.isPresent()) {
try {
MDC.setContextMap(tracingContext.get());
return f.apply(value);
} finally {
MDC.clear();
}
} else{
return f.apply(value);
}
});
}
这不是很好,希望它最终能通过日志框架得到改进,并自动注入上下文。
问题内容: 我正在使用通过上下文传递的函数。 现在我用。这可行。 如果我需要来自两个不同父组件的函数,该怎么办? 问题答案: 您仍然可以通过16.3 Context API来使用子级功能消费者节点,这是React文档建议的做法: 要在组件的上下文中使用函数,通常将组件包装在HOC中,以便将上下文作为prop传递: 如果您正在运行React 16.8+,则还可以使用钩子更干净地执行此操作,而无需使用
问题内容: 问候 , 有什么方法可以将值从web.xml context-param转换为Spring上下文吗? 例如,我将web.xml中的值定义为: 我想将该值分配给bean属性为: 提前致谢? 问题答案: 是的- 本文介绍了详细信息。简而言之,您需要: 然后使用以下属性: 或搭配
我已经插入反应路由器4到我的反应创建应用程序和运行我得到以下错误: 我在用react-router@4.2.0,并对路由器作出反应-dom@4.2.2 我已确保我的
我在Spring Boot应用程序中使用React Axios进行API调用。 我的应用程序上下文路径是test 当我在浏览器中启动应用程序时,http://localhost:8080/test,反应页面呈现。在页面呈现中,我正在调用服务 因此,预期调用应为http://localhost:8080/test/api/events,因为test是上下文根。但是,API调用中添加了测试。 只是打电
我多年来一直在使用Spring MVC,我试图理解与Spring Boot的一些关键区别。 你能帮我确认一下吗?或者让我明白我在这里遗漏了什么?
我还尝试了一个flatMap()和一个mono.subscriberContext(),但我不确定如何正确地插入过滤器(特别是在错误的情况下)。 实现这一目标的最佳方法是什么?