How to configure spring-cloud-gateway to use sleuth to log request/response body
Asked Answered
H

1

7

I am looking to develop a gateway server based on spring-cloud-gateway:2.0.2-RELEASE and would like to utilize sleuth for logging purposes. I have sleuth running since when I write to the log I see the Sleuth details (span Id, etc), but I an hoping to see the body of messages being logged automatically. Is there something I need to do to get Sleuth to log request/response out of the box with Spring-Cloud-Gateway?

Here is the request headers that arrive at my downstream service


    headers:
       { 'x-request-foo': '2a9c5e36-2c0f-4ad3-926c-cb20d4428462',
         forwarded: 'proto=http;host=localhost;for="0:0:0:0:0:0:0:1:51720"',
         'x-forwarded-for': '0:0:0:0:0:0:0:1',
         'x-forwarded-proto': 'http',
         'x-forwarded-port': '80',
         'x-forwarded-host': 'localhost',
         'x-b3-traceid': '5bd33eb8050c7a32dfce6adfe68b06ca',
         'x-b3-spanid': 'ba202a6d6f3e2893',
         'x-b3-parentspanid': 'dfce6adfe68b06ca',
         'x-b3-sampled': '0',
         host: 'localhost:8080' },

Gradle file in the gateway service..


    buildscript {
        ext {
            kotlinVersion = '1.2.61'
            springBootVersion = '2.0.6.RELEASE'
            springCloudVersion = 'Finchley.RELEASE'
        }
    }
    dependencyManagement {
        imports {
            mavenBom "org.springframework.cloud:spring-cloud-sleuth:2.0.2.RELEASE"
            mavenBom 'org.springframework.cloud:spring-cloud-gateway:2.0.2.RELEASE'
            mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
        }
    }
    dependencies {
        implementation('org.springframework.cloud:spring-cloud-starter-sleuth')
        implementation('org.springframework.cloud:spring-cloud-starter-gateway')
        implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
        implementation("org.jetbrains.kotlin:kotlin-reflect")
        testImplementation('org.springframework.boot:spring-boot-starter-test')
    }

and finally the application.yml file for the gateway service...


    server:
      servlet:
        contextPath: /
      port: 80
    spring:
      application:
        name: api.gateway.ben.com
      sleuth:
        trace-id128: true
        sampler:
          probability: 1.0
      cloud:
        gateway:
          routes:
          - id: admin-ui-2
            predicates:
            - Path=/admin-ui-2/echo/*
            filters:
            - SetPath=/fred
            - AddRequestHeader=X-Request-Foo, 2a9c5e36-2c0f-4ad3-926c-cb20d4428462
            - AddResponseHeader=X-Response-Foo, Bar
            uri: http://localhost:8080
    logging:
      pattern:
        level: "[%X{X-B3-TraceId}/%X{X-B3-SpanId}] %-5p [%t] %C{2} - %m%n"
      level:
        org.springframework.web: DEBUG

Harmonious answered 26/10, 2018 at 16:38 Comment(3)
what it means level:enter code here?. I tried your log settings I am able to view the logs.Frustrated
Sorry, it is a typo. It has been removed.Harmonious
Ben, I tried and it is good for me. Share the code to the link and let me know your expectations? just to enable root level logging and see whether you are able to see itFrustrated
E
4

Spring Cloud Gateway already can log the request and response, you just need to change your log level to TRACE.

logging:
  level:
    org.springframework: TRACE

or to be more precise to just log req/resp:

logging:
  level:
    org.springframework.core.codec.StringDecoder: TRACE

Other option is to use a Filter in Spring Cloud Gateway and log req/resp etc with any loggers like Log4j:

routeBuilder.route(id,
                            r -> {
                                return r.path(path).and().method(requestmethod).and()
                                        .header(routmap.getRequestheaderkey(), routmap.getRequestheadervalue()).and()
                                        .readBody(String.class, requestBody -> {
                                            return true;
                                        }).filters(f -> {
                                            f.rewritePath(rewritepathregex, replacement);
                                            f.prefixPath(perfixpath);

                                            f.filter(LogFilter);
                                            return f;
                                        }).uri(uri);
                            });

This filer "LogFilter" you need to define which would have logging logic.

Elianore answered 16/5, 2019 at 2:22 Comment(2)
Only the requests are been logged .. How about the response ?Dwt
Ok if anybody finds a reasonable understandable Filter to log Responses, for an experienced developer, rookie about reactive programming, please let us know, it's kind of impossible to understand all the things I found around, and that's the problem of this Question, without the Filter implementation the answer is useless, sorry.Feoffee

© 2022 - 2024 — McMap. All rights reserved.