diff --git a/airframe-http-netty/src/test/scala/wvlet/airframe/http/netty/NettyLoggingTest.scala b/airframe-http-netty/src/test/scala/wvlet/airframe/http/netty/NettyLoggingTest.scala index 71a48e5eff..5e45f558fb 100644 --- a/airframe-http-netty/src/test/scala/wvlet/airframe/http/netty/NettyLoggingTest.scala +++ b/airframe-http-netty/src/test/scala/wvlet/airframe/http/netty/NettyLoggingTest.scala @@ -13,16 +13,19 @@ */ package wvlet.airframe.http.netty +import wvlet.airframe.http.* import wvlet.airframe.http.HttpLogger.InMemoryHttpLogger -import wvlet.airframe.http.{Http, HttpLogger, HttpServer, RPC, RPCContext, RxRouter} +import wvlet.airframe.http.HttpMessage.Response import wvlet.airframe.http.client.SyncClient -import wvlet.airframe.http.netty.NettyRxFilterTest.router1 +import wvlet.airframe.rx.Rx import wvlet.airspec.AirSpec import wvlet.log.LogSupport +import wvlet.log.io.IOUtil import scala.collection.immutable.ListMap object NettyLoggingTest extends AirSpec { + private val port = IOUtil.unusedPort @RPC class MyRPC extends LogSupport { @@ -35,6 +38,14 @@ object NettyLoggingTest extends AirSpec { requestCount += 1 trace("hello rpc") } + + def async(): Rx[Response] = { + RPCContext.current.setThreadLocal("user", "zzzz-xxxx") + Http.client + .newAsyncClient(s"localhost:${port}").send( + Http.POST("/wvlet.airframe.http.netty.NettyLoggingTest.MyRPC/hello") + ) + } } private var clientLogger: InMemoryHttpLogger = null @@ -44,6 +55,7 @@ object NettyLoggingTest extends AirSpec { _.add( Netty.server .withRouter(RxRouter.of[MyRPC]) + .withPort(port) .withHttpLogger { config => serverLogger = new InMemoryHttpLogger(config) serverLogger @@ -95,6 +107,13 @@ object NettyLoggingTest extends AirSpec { clientLogEntry shouldContain ("custom_log_entry" -> "log-test-client") } + test("async server response") { + syncClient.send(Http.POST("/wvlet.airframe.http.netty.NettyLoggingTest.MyRPC/async")) + val logEntry = serverLogger.getLogs.last + debug(logEntry) + logEntry shouldContain ("user" -> "zzzz-xxxx") + logEntry shouldContain ("rpc_method" -> "async") + } } } diff --git a/airframe-http/src/main/scala/wvlet/airframe/http/internal/RPCResponseFilter.scala b/airframe-http/src/main/scala/wvlet/airframe/http/internal/RPCResponseFilter.scala index 72f905090a..1966fc9500 100644 --- a/airframe-http/src/main/scala/wvlet/airframe/http/internal/RPCResponseFilter.scala +++ b/airframe-http/src/main/scala/wvlet/airframe/http/internal/RPCResponseFilter.scala @@ -25,7 +25,11 @@ import scala.util.{Failure, Success} class RPCResponseFilter(httpLogger: HttpLogger) extends RxHttpFilter with LogSupport { override def apply(request: HttpMessage.Request, next: RxHttpEndpoint): Rx[HttpMessage.Response] = { - def logContext = new HttpLogs.LogContext(request, httpLogger, None, Some(RPCContext.current)) + // Note: RPCContext is not set before calling next(request), so + // We need to lazily evaluate the RPCContext + def logContext = { + new HttpLogs.LogContext(request, httpLogger, None, Some(RPCContext.current)) + } next(request) .transform {