diff --git a/docs/src/main/asciidoc/spring-cloud-gateway.adoc b/docs/src/main/asciidoc/spring-cloud-gateway.adoc index 2e2c0bb8..16c8400f 100644 --- a/docs/src/main/asciidoc/spring-cloud-gateway.adoc +++ b/docs/src/main/asciidoc/spring-cloud-gateway.adoc @@ -21,7 +21,7 @@ for details on setting up your build system with the current Spring Cloud Releas If you include the starter, but, for some reason, you do not want the gateway to be enabled, set `spring.cloud.gateway.enabled=false`. -IMPORTANT: Spring Cloud Gateway is built upon https://spring.io/projects/spring-boot#learn[Spring Boot 2.0], +IMPORTANT: Spring Cloud Gateway is built upon https://spring.io/projects/spring-boot#learn[Spring Boot 2.x], https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html[Spring WebFlux], and https://projectreactor.io/docs[Project Reactor]. As a consequence many of the familiar synchronous libraries (Spring Data and Spring Security, for example) and patterns you may @@ -1726,6 +1726,29 @@ The table below summarises the Spring Cloud Gateway actuator endpoints. Note tha |=== +[[troubleshooting]] +== Troubleshooting + +=== Log Levels + +Below are some useful loggers that contain valuable trouble shooting infomration at the `DEBUG` and `TRACE` levels. + +- `org.springframework.cloud.gateway` +- `org.springframework.http.server.reactive` +- `org.springframework.web.reactive` +- `org.springframework.boot.autoconfigure.web` +- `reactor.netty` +- `redisratelimiter` + +=== Wiretap + +The Reactor Netty `HttpClient` and `HttpServer` can have wiretap enabled. When combined +with setting the `reactor.netty` log level to `DEBUG` or `TRACE` will enable logging of +information such as headers and bodies sent and received across the wire. To enable this, +set `spring.cloud.gateway.httpserver.wiretap=true` and/or +`spring.cloud.gateway.httpclient.wiretap=true` for the `HttpServer` and `HttpClient` +respectively. + == Developer Guide TODO: overview of writing custom integrations diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java index bd069d45..e2a23713 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java @@ -40,10 +40,13 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.NoneNestedConditions; +import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.boot.autoconfigure.web.embedded.NettyWebServerFactoryCustomizer; import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration; import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; import org.springframework.cloud.gateway.actuate.GatewayControllerEndpoint; import org.springframework.cloud.gateway.actuate.GatewayLegacyControllerEndpoint; import org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter; @@ -519,6 +522,19 @@ public class GatewayAutoConfiguration { @ConditionalOnClass(HttpClient.class) protected static class NettyConfiguration { + @Bean + @ConditionalOnProperty(name = "spring.cloud.gateway.httpserver.wiretap") + public NettyWebServerFactoryCustomizer nettyServerWiretapCustomizer( + Environment environment, ServerProperties serverProperties) { + return new NettyWebServerFactoryCustomizer(environment, serverProperties) { + @Override + public void customize(NettyReactiveWebServerFactory factory) { + factory.addServerCustomizers(httpServer -> httpServer.wiretap(true)); + super.customize(factory); + } + }; + } + @Bean @ConditionalOnMissingBean public HttpClient gatewayHttpClient(HttpClientProperties properties) { @@ -596,8 +612,9 @@ public class GatewayAutoConfiguration { }); } - // TODO: add configuration to turn on wiretap - // httpClient = httpClient.wiretap(true); + if (properties.isWiretap()) { + httpClient = httpClient.wiretap(true); + } return httpClient; } diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/HttpClientProperties.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/HttpClientProperties.java index fe9a2498..e2d0c475 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/HttpClientProperties.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/HttpClientProperties.java @@ -60,6 +60,9 @@ public class HttpClientProperties { /** Websocket configuration for Netty HttpClient. */ private Websocket websocket = new Websocket(); + /** Enables wiretap debugging for Netty HttpClient. */ + private boolean wiretap; + public Integer getConnectTimeout() { return connectTimeout; } @@ -108,6 +111,14 @@ public class HttpClientProperties { this.websocket = websocket; } + public boolean isWiretap() { + return this.wiretap; + } + + public void setWiretap(boolean wiretap) { + this.wiretap = wiretap; + } + @Override public String toString() { // @formatter:off @@ -118,6 +129,7 @@ public class HttpClientProperties { .append("proxy", proxy) .append("ssl", ssl) .append("websocket", websocket) + .append("wiretap", wiretap) .toString(); // @formatter:on diff --git a/spring-cloud-gateway-core/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-gateway-core/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 0cd1a91b..94badd07 100644 --- a/spring-cloud-gateway-core/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-cloud-gateway-core/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -17,6 +17,12 @@ "type": "java.lang.Boolean", "description": "Enables the collection of metrics data.", "defaultValue": "true" + }, + { + "name": "spring.cloud.gateway.httpserver.wiretap", + "type": "java.lang.Boolean", + "description": "Enables wiretap debugging for Netty HttpServer.", + "defaultValue": "false" } ] }