Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Log Request/Response headers/body #1003

Closed
vborcea opened this issue Apr 9, 2019 · 6 comments
Closed

Log Request/Response headers/body #1003

vborcea opened this issue Apr 9, 2019 · 6 comments
Labels

Comments

@vborcea
Copy link

vborcea commented Apr 9, 2019

Question

Hi guys I want to create a simple filter to log request and responses, their headers and body for all requests(GET/POST/PUT/DELETE) passing through the gateway.
Is it possible to do this?
I cannot find a good solution to read the request/response body

@vborcea
Copy link
Author

vborcea commented Apr 10, 2019

Please note that I have a working function for this:

@Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String requestMethod = exchange.getRequest().getMethod().toString();
        String path = exchange.getRequest().getPath().toString();
        String headers = exchange.getRequest().getHeaders().toSingleValueMap().toString();
        //TODO: propper read request body when available
        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            String responseHeaders = exchange.getRequest().getHeaders().toSingleValueMap().toString();
            int status = exchange.getResponse().getStatusCode().value();
            //TODO: propper read response body when available
        }));
    }

@spencergibb
Copy link
Member

What you have looks fine for headers (though you'll loose multi value headers).

For the request/response body I wouldn't recommend doing it 100% of the time since you'll have to buffer all requests/responses into memory. See the Modify filters here https://github.com/spring-cloud/spring-cloud-gateway/tree/master/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/rewrite

@chenggangpro
Copy link

I custom a plugin project for spring-cloud-gateway.

You can take a look at it . Issues and PR welcome.

https://github.com/chenggangpro/spring-cloud-gateway-plugin

BTW: Read Request And Response cost a lot of memory.Wouldn't recommend doing it 100% of the time.

@vborcea
Copy link
Author

vborcea commented Apr 12, 2019

@chenggangpro I will take a look at it in the weekend :) thanks
@spencergibb thanks for the feedback.
We can close this topic

@vborcea vborcea closed this as completed Apr 12, 2019
@matzegebbe
Copy link

Hi!

I need to get the request body content for routes defined in the application.yml
If I use a custom RouteLocator the

exchange.getAttribute("cachedRequestBodyObject")

is filled for all requests (also the one out of the yml)

you can find the code here

https://gist.github.com/matzegebbe/bf631b2d3ab6d55f58f4b6c1d3511189

curl -H "x-debug: /nginx/" -X POST -d "{'data':'fooBar'}" http://localhost:8080/nginx/ 

with application.yml

- id: nginx
  uri: http://localhost:8082
  predicates:
    - Path=/nginx/**
  filters:
    - StripPrefix=1

gives me the log

n.h.apigateway.ApiGatewayApplication     : Started ApiGatewayApplication in 3.666 seconds (JVM running for 4.311)
n.h.a.filter.RequestResponseLogFilter    : Request Scheme:http,Path:/nginx/
n.h.a.filter.RequestResponseLogFilter    : Request Method:POST,IP:/0:0:0:0:0:0:0:1%0:48774,Host:localhost
n.h.a.filter.RequestResponseLogFilter    : Request ContentType:application/x-www-form-urlencoded,Content Length:17
n.h.a.filter.RequestResponseLogFilter    : Request Body:{'data':'fooBar'}
n.h.a.filter.RequestResponseLogFilter    : Response HttpStatus:200 OK
n.h.a.filter.RequestResponseLogFilter    : Response ContentType:null,Content Length:-1
n.h.a.filter.RequestResponseLogFilter    : Response Original Path:/nginx/,Cost:15 ms
n.h.a.filter.RequestResponseLogFilter    : Response:<html>
<head><title>405 Not Allowed</title></head>
<body>
<center><h1>405 Not Allowed</h1></center>
<hr><center>nginx/1.17.2</center>
</body>
</html>

@gberche-orange
Copy link
Contributor

Here is a variant that use modify filters to capture and log request and response body

@Bean
    public RouteLocator myRouteSavingRequestBody(RouteLocatorBuilder builder) {
        return builder.routes()
            .route("my-route-id",
                p -> p
                    .path("/v2/**") //your own path filter
                    .filters(f -> f
                        .modifyResponseBody(String.class, String.class,
                            (webExchange, originalBody) -> {
                                if (originalBody != null) {
                                    logger.debug("Response body {}", originalBody);
                                    return Mono.just(originalBody);
                                } else {
                                    return Mono.empty();
                                }
                            })
                        .modifyRequestBody(String.class, String.class,
                            (webExchange, originalBody) -> {
                                if (originalBody != null) {
                                    logger.debug("Request body {}", originalBody);
                                    return Mono.just(originalBody);
                                } else {
                                    return Mono.empty();
                                }
                            })

                    )
                    .uri("https://myuri.org")
            )
            .build();
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants