How to log request and response bodies in Spring WebFlux

前端 未结 9 1147
一向
一向 2020-11-27 16:41

I want to have centralised logging for requests and responses in my REST API on Spring WebFlux with Kotlin. So far I\'ve tried this approaches

@Bean
fun apiR         


        
9条回答
  •  一向
    一向 (楼主)
    2020-11-27 17:08

    I didn't find a good way to log request/response bodies, but if you are just interested in meta data then you can do it like follows.

    import org.springframework.http.HttpHeaders
    import org.springframework.http.HttpStatus
    import org.springframework.http.server.reactive.ServerHttpResponse
    import org.springframework.stereotype.Component
    import org.springframework.web.server.ServerWebExchange
    import org.springframework.web.server.WebFilter
    import org.springframework.web.server.WebFilterChain
    import reactor.core.publisher.Mono
    
    @Component
    class LoggingFilter(val requestLogger: RequestLogger, val requestIdFactory: RequestIdFactory) : WebFilter {
        val logger = logger()
    
        override fun filter(exchange: ServerWebExchange, chain: WebFilterChain): Mono {
            logger.info(requestLogger.getRequestMessage(exchange))
            val filter = chain.filter(exchange)
            exchange.response.beforeCommit {
                logger.info(requestLogger.getResponseMessage(exchange))
                Mono.empty()
            }
            return filter
        }
    }
    
    @Component
    class RequestLogger {
    
        fun getRequestMessage(exchange: ServerWebExchange): String {
            val request = exchange.request
            val method = request.method
            val path = request.uri.path
            val acceptableMediaTypes = request.headers.accept
            val contentType = request.headers.contentType
            return ">>> $method $path ${HttpHeaders.ACCEPT}: $acceptableMediaTypes ${HttpHeaders.CONTENT_TYPE}: $contentType"
        }
    
        fun getResponseMessage(exchange: ServerWebExchange): String {
            val request = exchange.request
            val response = exchange.response
            val method = request.method
            val path = request.uri.path
            val statusCode = getStatus(response)
            val contentType = response.headers.contentType
            return "<<< $method $path HTTP${statusCode.value()} ${statusCode.reasonPhrase} ${HttpHeaders.CONTENT_TYPE}: $contentType"
        }
    
        private fun getStatus(response: ServerHttpResponse): HttpStatus =
            try {
                response.statusCode
            } catch (ex: Exception) {
                HttpStatus.CONTINUE
            }
    }
    

提交回复
热议问题