Git Product home page Git Product logo

spring-boot-logging's Introduction

Logging with Spring Boot and Elastic Stack Twitter

Maven Central CircleCI

SonarCloud Bugs Coverage Lines of Code

Main purpose

This library is created for logging incoming HTTP requests and outgoing HTTP responses and send these logs automatically to Logstash.

Articles

Detailed description can be found here:

  1. Logging with Spring Boot and Elastic Stack
  2. Using logstash-logging-spring-boot-starter for logging with Spring Boot and Logstash

Features

In short, let’s begin from a brief review of main features provided by logstash-logging-spring-boot-starter:

  1. It is able to log all incoming HTTP requests and outgoing HTTP responses with full body, and send those logs to Logstash with the proper tags
  2. It is able to calculate and store an execution time for each request
  3. It generates and propagates correlationId for downstream services calling with Spring RestTemplate or OpenFeign
  4. It is auto-configurable Spring Boot library – you don’t have to do anything more than including it as a dependency to your application to make it work

Getting started

The current version of library is 2.0.3.
For logging with Spring WebMvc and Logstash:

<dependency>
  <groupId>com.github.piomin</groupId>
  <artifactId>logstash-logging-spring-boot-starter</artifactId>
  <version>2.0.3</version>
</dependency>

For logging with Spring WebMvc and Loki:

<dependency>
  <groupId>com.github.piomin</groupId>
  <artifactId>loki-logging-spring-boot-starter</artifactId>
  <version>2.0.3</version>
</dependency>

For logging with Spring WebFlux:

<dependency>
  <groupId>com.github.piomin</groupId>
  <artifactId>reactive-logstash-logging-spring-boot-starter</artifactId>
  <version>2.0.3</version>
</dependency>

By default, the library is enabled, but tries to locate Logback configuration inside your application to settings for Logstash appender. If such appender won’t be found, the library uses Spring Boot default logging configuration, which does not include Logstash appender. To force it use auto-configured appender definition inside library we have to set property logging.logstash.enabled to true.

logging.logstash:
  enabled: true
  url: loki.example.com:5000

Manual add jar to pom.xml

Add reactive-logstash-logging-spring-boot-starter-2.0.3.pom to ${basedir}/dependencies

Add pom.xml to ${basedir}/dependencies and rename to reactive-logstash-logging-spring-boot-starter-2.0.3.pom

Add this script to pom.xml in plugins section.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-install-plugin</artifactId>
  <version>2.5.1</version>
  <configuration>
      <groupId>com.github.piomin</groupId>
      <artifactId>reactive-logstash-logging-spring-boot-starter</artifactId>
      <version>2.0.3</version>
      <packaging>jar</packaging>
      <file>${basedir}/dependencies/reactive-logstash-logging-spring-boot-starter-1.3.1.RELEASE.jar</file>
      <generatePom>false</generatePom>
      <pomFile>${basedir}/dependencies/reactive-logstash-logging-spring-boot-starter-1.3.1.RELEASE.pom</pomFile>
  </configuration>
  <executions>
      <execution>
      <id>install-jar-lib</id>
      <goals>
        <goal>install-file</goal>
      </goals>
      <phase>validate</phase>
      </execution>
  </executions>
  </plugin>

spring-boot-logging's People

Contributors

ashraful-islam-rafi avatar dependabot[bot] avatar piomin avatar renovate[bot] avatar taleb-dev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spring-boot-logging's Issues

Spring does not send to Logstash

Hi, I really liked your library first.

I verified that the Spring application is showing the log in and out of requests, however they are not arriving in logstash. I did some tests and saw that everything is normal in Logtstash, could you tell me all the necessary settings?

I saw the blog post but I didn't find it very clear.

Thanks.

Is this project discontinued?

I would like to know if this project is discontinued? and if it's it would be awesome if you could point me in the direction of a proper alternative.

WebTestClient fails when integrated with reactive-logstash-logging-spring-boot-starter

The test which started failing after integration:

@SpringBootTest
@ExtendWith(SpringExtension.class)
@AutoConfigureWebTestClient(timeout = "2000")
public class HealthCheckHandlerTest {

  @Autowired WebTestClient webTestClient;

  @Test
  public void shouldGetOnline() {
    webTestClient
        .get()
        .uri("/status")
        .exchange()
        .expectStatus()
        .isOk()
        .expectBody(StatusCheckResponse.class);
  }
}

Integration Details:
Just added the following line in the dependencies
compile group: 'com.github.piomin', name: 'reactive-logstash-logging-spring-boot-starter', version: '1.3.0.RELEASE'

No changes were made in the application.properties file.

Error:

> GET /status
> WebTestClient-Request-Id: [1]

No content

< 500 INTERNAL_SERVER_ERROR Internal Server Error
< Content-Type: [application/json]
< Content-Length: [143]

{"timestamp":"2020-11-23T10:47:38.059+00:00","path":"/status","status":500,"error":"Internal Server Error","message":"","requestId":"2a16f81b"}

Error Log:

java.lang.NullPointerException: null
at pl.piomin.logging.reactive.interceptor.ResponseLoggingInterceptor.lambda$writeWith$2(ResponseLoggingInterceptor.java:45)
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Assembly trace from producer [reactor.core.publisher.FluxLiftFuseable] :
reactor.core.publisher.Flux.doOnNext
pl.piomin.logging.reactive.interceptor.ResponseLoggingInterceptor.writeWith(ResponseLoggingInterceptor.java:35)
Error has been observed at the following site(s):
|_          Flux.doOnNext ⇢ at pl.piomin.logging.reactive.interceptor.ResponseLoggingInterceptor.writeWith(ResponseLoggingInterceptor.java:35)
|_              Flux.from ⇢ at org.springframework.http.server.reactive.ChannelSendOperator.<init>(ChannelSendOperator.java:57)
|_                        ⇢ at org.springframework.http.server.reactive.ServerHttpResponseDecorator.writeWith(ServerHttpResponseDecorator.java:99)
|_           Mono.flatMap ⇢ at org.springframework.http.codec.EncoderHttpMessageWriter.write(EncoderHttpMessageWriter.java:127)
|_                        ⇢ at org.springframework.http.codec.EncoderHttpMessageWriter.write(EncoderHttpMessageWriter.java:203)
|_                        ⇢ at org.springframework.web.reactive.result.method.annotation.AbstractMessageWriterResultHandler.writeBody(AbstractMessageWriterResultHandler.java:107)
|_                        ⇢ at org.springframework.web.reactive.result.method.annotation.ResponseBodyResultHandler.handleResult(ResponseBodyResultHandler.java:86)
|_             checkpoint ⇢ Handler com.pharmeasy.splitservice.controllers.HealthCheckHandler#checkStatus() [DispatcherHandler]
|_             Mono.error ⇢ at org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter.handleException(RequestMappingHandlerAdapter.java:235)
|_                        ⇢ at org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter.lambda$handle$0(RequestMappingHandlerAdapter.java:195)
|_                        ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.lambda$filter$0(DefaultWebFilterChain.java:120)
|_             Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:119)
|_       Mono.doOnSuccess ⇢ at pl.piomin.logging.reactive.filter.ReactiveSpringLoggingFilter.filter(ReactiveSpringLoggingFilter.java:63)
|_         Mono.doOnError ⇢ at pl.piomin.logging.reactive.filter.ReactiveSpringLoggingFilter.filter(ReactiveSpringLoggingFilter.java:66)
|_             checkpoint ⇢ pl.piomin.logging.reactive.filter.ReactiveSpringLoggingFilter [DefaultWebFilterChain]
|_                        ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.lambda$filter$0(DefaultWebFilterChain.java:120)
|_             Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:119)
|_ Mono.subscriberContext ⇢ at com.pharmeasy.core.reactive.web.filters.CommonHeadersWebFilter.filter(CommonHeadersWebFilter.java:40)
|_             checkpoint ⇢ com.pharmeasy.core.reactive.web.filters.CommonHeadersWebFilter [DefaultWebFilterChain]
|_                        ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.lambda$filter$0(DefaultWebFilterChain.java:120)
|_             Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:119)
|_ Mono.subscriberContext ⇢ at com.pharmeasy.core.reactive.web.filters.RequestIdWebFilter.filter(RequestIdWebFilter.java:46)
|_             checkpoint ⇢ com.pharmeasy.core.reactive.web.filters.RequestIdWebFilter [DefaultWebFilterChain]
|_                        ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.lambda$filter$0(DefaultWebFilterChain.java:120)
|_             Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:119)
|_       Mono.doOnSuccess ⇢ at org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter.filter(MetricsWebFilter.java:78)
|_         Mono.doOnError ⇢ at org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter.filter(MetricsWebFilter.java:79)
|_ Mono.transformDeferred ⇢ at org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter.filter(MetricsWebFilter.java:73)
|_             checkpoint ⇢ org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]
|_                        ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.lambda$filter$0(DefaultWebFilterChain.java:120)
|_             Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:119)
|_                        ⇢ at org.springframework.web.server.handler.FilteringWebHandler.handle(FilteringWebHandler.java:59)
|_                        ⇢ at org.springframework.web.server.handler.WebHandlerDecorator.handle(WebHandlerDecorator.java:56)
|_             Mono.error ⇢ at org.springframework.web.server.handler.ExceptionHandlingWebHandler$CheckpointInsertingHandler.handle(ExceptionHandlingWebHandler.java:98)
|_             checkpoint ⇢ HTTP GET \"/status\" [ExceptionHandlingWebHandler]
|_                        ⇢ at org.springframework.web.server.handler.ExceptionHandlingWebHandler.lambda$handle$0(ExceptionHandlingWebHandler.java:77)
|_     Mono.onErrorResume ⇢ at org.springframework.web.server.handler.ExceptionHandlingWebHandler.handle(ExceptionHandlingWebHandler.java:77)
Stack trace:
	at pl.piomin.logging.reactive.interceptor.ResponseLoggingInterceptor.lambda$writeWith$2(ResponseLoggingInterceptor.java:45)
	at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:189)
	at reactor.core.publisher.FluxContextStart$ContextStartSubscriber.onNext(FluxContextStart.java:96)
	at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2344)
	at reactor.core.publisher.FluxContextStart$ContextStartSubscriber.request(FluxContextStart.java:125)
	at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.request(FluxPeekFuseable.java:137)
	at org.springframework.http.server.reactive.ChannelSendOperator$WriteBarrier.onSubscribe(ChannelSendOperator.java:166)
	at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onSubscribe(FluxPeekFuseable.java:171)
	at reactor.core.publisher.FluxContextStart$ContextStartSubscriber.onSubscribe(FluxContextStart.java:90)
	at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:54)
	at reactor.core.publisher.InternalFluxOperator.subscribe(InternalFluxOperator.java:62)
	at org.springframework.http.server.reactive.ChannelSendOperator.subscribe(ChannelSendOperator.java:77)
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:150)
	at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:67)
	at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1782)
	at reactor.core.publisher.MonoSingle$SingleSubscriber.onComplete(MonoSingle.java:171)
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onComplete(FluxMapFuseable.java:144)
	at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2346)
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:162)
	at reactor.core.publisher.MonoSingle$SingleSubscriber.request(MonoSingle.java:94)
	at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2152)
	at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2026)
	at reactor.core.publisher.MonoSingle$SingleSubscriber.onSubscribe(MonoSingle.java:114)
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:90)
	at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:54)
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:150)
	at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1782)
	at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:241)
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:73)
	at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:203)
	at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:203)
	at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1782)
	at reactor.core.publisher.MonoIgnoreThen$ThenAcceptInner.onNext(MonoIgnoreThen.java:296)
	at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1782)
	at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:241)
	at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2344)
	at reactor.core.publisher.MonoFlatMap$FlatMapInner.onSubscribe(MonoFlatMap.java:230)
	at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:54)
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:150)
	at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2344)
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.onSubscribe(MonoFlatMap.java:103)
	at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:54)
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
	at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
	at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:153)
	at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56)
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:150)
	at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:67)
	at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:76)
	at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.innerNext(FluxConcatMap.java:274)
	at reactor.core.publisher.FluxConcatMap$ConcatMapInner.onNext(FluxConcatMap.java:851)
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:121)
	at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onNext(MonoPeekTerminal.java:173)
	at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2344)
	at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.request(MonoPeekTerminal.java:132)
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:162)
	at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2152)
	at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2026)
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:90)
	at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onSubscribe(MonoPeekTerminal.java:145)
	at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:54)
	at reactor.core.publisher.Mono.subscribe(Mono.java:4213)
	at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.drain(FluxConcatMap.java:441)
	at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.onSubscribe(FluxConcatMap.java:211)
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:161)
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:86)
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
	at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
	at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
	at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
	at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
	at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
	at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
	at reactor.core.publisher.Mono.subscribe(Mono.java:4213)
	at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:172)
	at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56)
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
	at org.springframework.test.web.reactive.server.HttpHandlerConnector.lambda$doConnect$1(HttpHandlerConnector.java:97)
	at org.springframework.mock.http.client.reactive.MockClientHttpRequest.lambda$null$2(MockClientHttpRequest.java:121)
	at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:44)
	at reactor.core.publisher.Mono.subscribe(Mono.java:4213)
	at reactor.core.publisher.FluxConcatIterable$ConcatIterableSubscriber.onComplete(FluxConcatIterable.java:146)
	at reactor.core.publisher.FluxConcatIterable.subscribe(FluxConcatIterable.java:60)
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
	at org.springframework.test.web.reactive.server.HttpHandlerConnector.doConnect(HttpHandlerConnector.java:108)
	at org.springframework.test.web.reactive.server.HttpHandlerConnector.lambda$connect$0(HttpHandlerConnector.java:79)
	at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:44)
	at reactor.core.publisher.Mono.subscribe(Mono.java:4213)
	at reactor.core.publisher.MonoSubscribeOn$SubscribeOnSubscriber.run(MonoSubscribeOn.java:124)
	at reactor.core.scheduler.WorkerTask.call(WorkerTask.java:84)
	at reactor.core.scheduler.WorkerTask.call(WorkerTask.java:37)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)

NullPointerException

The following error appears to me:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'logstashAppender' defined in class path resource [pl/piomin/logging/config/SpringLoggingAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [net.logstash.logback.appender.LogstashTcpSocketAppender]: Factory method 'logstashAppender' threw exception; nested exception is java.lang.NullPointerException

Once you have enabled:
logging.logstash.enabled = true

I added Breakpoint and verified that it shows the error when arriving here:

trustStoreLocation.ifPresent(it -> { //Line 71

reactive-logstash-logging-spring-boot-starter. ResponseLoggingInterceptor changes java.time.LocalDate.LocalDate and OffsetDateTime incorrectly

Hey,

I find that ResponseLoggingInterceptor of reactive-logstash-logging-spring-boot-starter changes variable values of java.time.LocalDate and OffsetDateTime type incorrectly on the way back to ... Repo -> Service -> [ Controller ->http json response. ]

I add the below dependency to my Spring boot webflux + r2dbc project:

<dependency>
   <groupId>com.github.piomin</groupId>
   <artifactId>reactive-logstash-logging-spring-boot-starter</artifactId>
   <version>1.3.0.RELEASE</version>
</dependency>

I have tried 2 versions, 1.3.0.RELEASE and 1.0.0.RELEASE. Both happen.


Below are my logs, be aware that:

  • field effectiveDt is in java.time.LocalDate type; field effectiveStart and effectiveEnd are OffsetDateTime.
  • They are in correct format( like effectiveDt=2022-03-01, effectiveStart=2022-03-01T00:00Z, effectiveEnd=9999-12-31T23:59:59.999900Z), until the the last log section: "effectiveDt":[2022,3,1] , "effectiveStart":1646092800.000000000, "effectiveEnd":253402300799.999900000 <-- wrong.
  • the most error is that my Postman response is changed to the wrong format!

{
    "@timestamp": "2022-03-21T20:53:04.463-07:00",
    "message": "Request: method=POST, uri=/common/workforcemgmt-capacitymgmt-update/v1/jobdemandstreams, payload={\r\n    \"demandStreamId\": 1,\r\n    \"jobId\": 1,\r\n    \"effectiveDt\": \"2022-03-01\",\r\n    \"estimatedDurationHrs\": 1,\r\n    \"statusTxt\": \"ok-0301\",\r\n    \"effectiveStart\": \"2022-03-01T00:00:00.000000-00:00\",\r\n    \"effectiveEnd\": \"9999-12-31T23:59:59.9999-00:00\"\r\n}, audit=true",
    "logger_name": "pl.piomin.logging.reactive.interceptor.RequestLoggingInterceptor",
    "thread_name": "reactor-http-nio-6",
    "level": "INFO",
    "level_value": 20000,
    "X-Request-ID": "74c0db5a-d03e-4bc5-9fda-45a61a6a630d",
    "X-Correlation-ID": "03532028-759f-4a0a-ac06-d4fc7d3bfc8a",
    "audit": true
}{
    "@timestamp": "2022-03-21T20:53:04.469-07:00",
    "message": "pass in to insert: JobDemandStreamEntity(jobDemandStreamId=null, demandStreamId=1, jobId=1, effectiveDt=2022-03-01, estimatedDurationHrs=1.0, statusTxt=ok-0301, effectiveStart=2022-03-01T00:00Z, effectiveEnd=9999-12-31T23:59:59.999900Z, creat=2022-03-21T20:53:03.898174700-07:00, createUserId=userId, lastUpdt=2022-03-21T20:53:03.898174700-07:00, lastUpdtUserId=userId)",
    "logger_name": "com.telus.workforcemgmt.capacitymgmt.update.service.JobDemandStreamService",
    "thread_name": "reactor-http-nio-6",
    "level": "DEBUG",
    "level_value": 10000,
    "X-Request-ID": "74c0db5a-d03e-4bc5-9fda-45a61a6a630d",
    "X-Correlation-ID": "03532028-759f-4a0a-ac06-d4fc7d3bfc8a"
}{
    "@timestamp": "2022-03-21T20:53:04.477-07:00",
    "message": "Executing SQL statement [INSERT INTO job_demand_stream (demand_stream_id, job_id, effective_dt, estimated_duration_hrs, status_txt, effective_start_ts, effective_end_ts, create_ts, create_user_id, last_updt_ts, last_updt_user_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)]",
    "logger_name": "org.springframework.r2dbc.core.DefaultDatabaseClient",
    "thread_name": "reactor-http-nio-6",
    "level": "DEBUG",
    "level_value": 10000,
    "X-Request-ID": "74c0db5a-d03e-4bc5-9fda-45a61a6a630d",
    "X-Correlation-ID": "03532028-759f-4a0a-ac06-d4fc7d3bfc8a"
}{
    "@timestamp": "2022-03-21T20:53:04.645-07:00",
    "message": "insert returned: JobDemandStreamEntity(jobDemandStreamId=55, demandStreamId=1, jobId=1, effectiveDt=2022-03-01, estimatedDurationHrs=1.0, statusTxt=ok-0301, effectiveStart=2022-03-01T00:00Z, effectiveEnd=9999-12-31T23:59:59.999900Z, creat=2022-03-21T20:53:03.898174700-07:00, createUserId=userId, lastUpdt=2022-03-21T20:53:03.898174700-07:00, lastUpdtUserId=userId)",
    "logger_name": "com.telus.workforcemgmt.capacitymgmt.update.service.JobDemandStreamService",
    "thread_name": "reactor-tcp-nio-3",
    "level": "DEBUG",
    "level_value": 10000
}{
    "@timestamp": "2022-03-21T20:53:04.646-07:00",
    "message": "converted: JobDemandStream(jobDemandStreamId=55, demandStreamId=1, jobId=1, effectiveDt=2022-03-01, estimatedDurationHrs=1.0, statusTxt=ok-0301, effectiveStart=2022-03-01T00:00Z, effectiveEnd=9999-12-31T23:59:59.999900Z)",
    "logger_name": "com.telus.workforcemgmt.capacitymgmt.update.service.JobDemandStreamService",
    "thread_name": "reactor-tcp-nio-3",
    "level": "DEBUG",
    "level_value": 10000
}{
    "@timestamp": "2022-03-21T20:53:04.646-07:00",
    "message": "Response(752 ms): status=200, payload={\"jobDemandStreamId\":55,\"demandStreamId\":1,\"jobId\":1,\"effectiveDt\":[2022,3,1],\"estimatedDurationHrs\":1.0,\"statusTxt\":\"ok-0301\",\"effectiveStart\":1646092800.000000000,\"effectiveEnd\":253402300799.999900000}, audit=true",
    "logger_name": "pl.piomin.logging.reactive.interceptor.ResponseLoggingInterceptor",
    "thread_name": "reactor-tcp-nio-3",
    "level": "INFO",
    "level_value": 20000,
    "X-Response-Time": 752,
    "X-Response-Status": 200,
    "audit": true
}

Below are my Postman Request body: we can see effectiveDt, effectiveStart, effectiveEnd are in correct format

{
    "demandStreamId": 1,
    "jobId": 1,
    "effectiveDt": "2022-03-01",
    "estimatedDurationHrs": 1,
    "statusTxt": "ok-0301",
    "effectiveStart": "2022-03-01T00:00:00.000000-00:00",
    "effectiveEnd": "9999-12-31T23:59:59.9999-00:00"
}

Below are my Postman Response: effectiveDt, effectiveStart, effectiveEnd are in wrong format

{
    "jobDemandStreamId": 55,
    "demandStreamId": 1,
    "jobId": 1,
    "effectiveDt": [
        2022,
        3,
        1
    ],
    "estimatedDurationHrs": 1.0,
    "statusTxt": "ok-0301",
    "effectiveStart": 1646092800.000000000,
    "effectiveEnd": 253402300799.999900000
}

Thanks,
Chen Wang

When Using spring-cloud-starter-bus-amqp along with logstash-logging-spring-boot-starter, logs are not showing in Kibana.

Backgroud

I have a rest-api in which I am using

  • spring-cloud-starter-config
  • spring-cloud-starter-bus-amqp
    and then I used
  • logstash-logging-spring-boot-starter

Now I cannot see the logs in Kibana dashboard. When I remove spring-cloud-starter-bus-amqp then logs are being showed in Kibana dashboard.

I guess there is something wrong in between spring-cloud-starter-bus-amqp and logstash-logging-spring-boot-starter

Expected Result

I should able to use logstash-logging-spring-boot-starter with spring-cloud-starter-bus-amqp and logs should have shown.

Prerequisite

  • Java 15
  • Maven 3.6.3
  • Docker 19

How to reproduce the problem:

  • git clone https://github.com/UbaidurRehman1/Cloud-Native-App-Spring-Boot.git
  • cd Cloud-Native-App-Spring-Boot
  • git checkout issues/#146
  • mvn clean install -DskipTests
  • cd envcn
  • ./run.sh (this will up all tools which are required for our services like ELK stack, config server, zipkin and rabbit-mq)
  • cd ..
  • ./run.sh (this will up our services like rest-api)
  • Go to Kibana Dashboard
  • First setupt the kibana dashboard
  • Now go to Swagger UI
  • Execute this controller by putting in from field USD, in to field PKR and in quantity field 10
  • Now check the logs, there are only logs of services. There is no log about rest-api. (I have added this combination logstash-logging-spring-boot-starter with spring-cloud-starter-bus-amqp only in rest-api)

Profile

MDC vs Reactor's "Context"

While setting an MDC value at the beginning of a request might seem straightforward, in a reactive context, I think it's essential to ensure that the MDC values are propagated across any thread switches that might occur during the request's lifecycle. Without proper propagation, you might end up with missing or incorrect log context in parts of your request processing. When you set a value in the MDC at the beginning of a reactive request, you're indeed setting it for the thread that initially handles the request. However, due to the nature of reactive programming, the processing of that request might get handed off to another thread at some point, especially if there are asynchronous operations involved, an I/O call, a delay, etc. I think even if the code/method itself doesn't contain asynchronous operations, external factors might cause thread switches. For instance, if the system is under heavy load, or if there are other tasks queued up in the event loop, the framework might decide to switch threads to optimize throughput. The MDC works by storing data in a ThreadLocal variable. This means the data is specific to the current thread. If the reactive processing switches to another thread, the MDC values set in the initial thread won't be available in the new thread, leading to potential issues or missing log context. Am I missing something?

So to optimize this I think we should use something like this:
return chain.filter(exchangeDecorator).contextWrite(ctx -> ctx.put("key", value))
...........................

But in the logback.xml we can add values to the pattern only if they are already in MDC, using %X{key} where key is the name of the value you've set in the MDC:

   <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %X{key} - %msg%n</pattern>

So, I think if we want to use the %X{key} pattern in Logback to log a value, that value must be present in the MDC. Even if the value is in the Reactor Context, you'll need to transfer it to the MDC before logging. But how to do that, what is the best way to implement this? Honestly I don't know, maybe:

  1. use a utility yo set the values to MDC

    public static void setContextToMDC(Context ctx, String key, String value) {
    MDC.clear();
    ctx.stream().forEach(entry -> MDC.put(key, value));
    }

  2. use reactor's doOnEach"
    return chain.filter(exchangeDecorator)
    .contextWrite(ctx -> ctx.put("key", "value"))
    .doOnEach(signal -> {
    if (signal.isOnNext() || signal.isOnError()) {
    setContextToMDC(signal.getContext(),"key","value");
    }
    });

Or maybe I'm wrong?!?
Thanks a lot

Not Logging

Hello,

I added the reactive logging library to a Spring Boot 3.1.0 project and it's not working. I followed the readme/tutorial, added the dependencies to the pom, created the dependencies directory and added the pom and jar, and added the plugin as provided. In application.properties, I added the logging.logstash.enable=true property along with the others (url, trustStorePassword/location).

I'd done everything I can think of including providing a separate AutoConfig.imports file in the META-INF folder, a new logging config, etc.

It simply... isn't logging. When I run the main in the test module, it logs fine. There are no logs being written to the console nor to the log file.

If there's any help anyone can offer, I'd appreciate it.

customise names for X-Request-ID and X-Correlation-ID

My project uses another names for request id and correlation id and would like to keep it that way. I need a way to pick these ones instead of the headers with default name.

Happy to contribute for this change.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

This repository currently has no open or pending branches.

Detected dependencies

circleci
.circleci/config.yml
  • cimg/openjdk 21.0.2
  • cimg/openjdk 21.0.2
  • maven 1.4.1
github-actions
.github/workflows/maven-publish.yml
  • actions/checkout v4
  • actions/setup-java v4
maven
logging-spring-commons/pom.xml
  • org.apache.maven.plugins:maven-compiler-plugin 3.13.0
  • org.apache.maven.plugins:maven-gpg-plugin 3.2.4
  • org.apache.maven.plugins:maven-source-plugin 3.3.1
  • org.apache.maven.plugins:maven-javadoc-plugin 3.6.3
logging-spring-tests/pom.xml
logstash-logging-spring-boot-starter/pom.xml
  • org.springframework:spring-context 6.1.6
  • org.springframework:spring-web 6.1.6
  • org.springframework:spring-webmvc 6.1.6
  • org.springframework.boot:spring-boot-autoconfigure 3.2.5
  • net.logstash.logback:logstash-logback-encoder 7.4
  • jakarta.servlet:jakarta.servlet-api 6.0.0
  • commons-io:commons-io 2.16.1
  • org.slf4j:slf4j-api 2.0.13
  • ch.qos.logback:logback-classic 1.5.6
  • org.springframework.boot:spring-boot-starter-test 3.2.5
  • org.apache.maven.plugins:maven-compiler-plugin 3.13.0
  • org.apache.maven.plugins:maven-gpg-plugin 3.2.4
  • org.apache.maven.plugins:maven-source-plugin 3.3.1
  • org.apache.maven.plugins:maven-javadoc-plugin 3.6.3
loki-logging-spring-boot-starter/pom.xml
  • org.springframework:spring-context 6.1.6
  • org.springframework:spring-web 6.1.6
  • org.springframework:spring-webmvc 6.1.6
  • org.springframework.boot:spring-boot-autoconfigure 3.2.5
  • com.github.loki4j:loki-logback-appender 1.5.1
  • jakarta.servlet:jakarta.servlet-api 6.0.0
  • commons-io:commons-io 2.16.1
  • org.slf4j:slf4j-api 2.0.13
  • ch.qos.logback:logback-classic 1.5.6
  • org.springframework.boot:spring-boot-starter-test 3.2.5
  • org.apache.maven.plugins:maven-compiler-plugin 3.13.0
  • org.apache.maven.plugins:maven-gpg-plugin 3.2.4
  • org.apache.maven.plugins:maven-source-plugin 3.3.1
  • org.apache.maven.plugins:maven-javadoc-plugin 3.6.3
pom.xml
  • org.springframework:spring-web 6.1.6
  • jakarta.servlet:jakarta.servlet-api 6.0.0
  • commons-io:commons-io 2.16.1
  • org.slf4j:slf4j-api 2.0.13
  • org.springframework.boot:spring-boot-dependencies 3.2.5
  • org.springframework.boot:spring-boot-dependencies 3.2.5
reactive-logging-spring-tests/pom.xml
reactive-logstash-logging-spring-boot-starter/pom.xml
  • org.springframework:spring-context 6.1.6
  • org.springframework:spring-webflux 6.1.6
  • org.springframework.boot:spring-boot-autoconfigure 3.2.5
  • net.logstash.logback:logstash-logback-encoder 7.4
  • commons-io:commons-io 2.16.1
  • org.slf4j:slf4j-api 2.0.13
  • ch.qos.logback:logback-classic 1.5.6
  • io.projectreactor:reactor-core 3.6.6
  • org.springframework.boot:spring-boot-starter-test 3.2.5
  • org.apache.maven.plugins:maven-compiler-plugin 3.13.0
  • org.apache.maven.plugins:maven-gpg-plugin 3.2.4
  • org.apache.maven.plugins:maven-source-plugin 3.3.1
  • org.apache.maven.plugins:maven-javadoc-plugin 3.6.3

  • Check this box to trigger a request for Renovate to run again on this repository

Spring boot app crashes after enabling logstash logging

I have a spring boot with thymeleaf template engine which has a controller to upload a csv file.
As soon as I enable the logstash logging support, all the REST endpoints for uploading file crashes with exception.
It works fine once support is disabled.

This application has no explicit mapping for /error, so you are seeing this as a fallback.

Tue Aug 04 17:47:42 CEST 2020
There was an unexpected error (type=Bad Request, status=400).
Required request part 'file' is not present
org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present
	at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:199)
	at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:114)
	at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)
	at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:167)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:134)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:652)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at pl.piomin.logging.filter.SpringLoggingFilter.doFilterInternal(SpringLoggingFilter.java:69)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.base/java.lang.Thread.run(Thread.java:834)

Elastic log

Screenshot 2020-08-04 at 17 49 30

Maven Repository

I'd like to download and use your library by maven. You specify maven dependency in your article, but I cannot find information about online repository it is available. Can you add this information in readme or show me if I just overlooked it.

java.lang.NoClassDefFoundError: javax/servlet/Filter

Tools information

  • OS

Distributor ID:	Ubuntu
Description:	Ubuntu 20.10
Release:	20.10
Codename:	groovy
  • Maven

Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 15, vendor: Oracle Corporation, runtime: /usr/lib/jvm/java-15-oracle
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "5.8.0-25-generic", arch: "amd64", family: "unix"

Backgroud

I just migrated my API Gateway Service from netflix-zuul-api-gateway-server to spring-cloud-starter-gateway. Then I tried to run my gateway service, then it threws the following exception:

Exception

java.lang.IllegalStateException: Error processing condition on pl.piomin.logging.config.SpringLoggingAutoConfiguration.restTemplate
	at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:60) ~[spring-boot-autoconfigure-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:184) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:144) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:120) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:331) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:236) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:280) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:96) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:707) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:533) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:62) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at com.ubaid.ms.NetflixZuulApiGatewayServerApplication.main(NetflixZuulApiGatewayServerApplication.java:17) ~[classes/:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.3.4.RELEASE.jar:2.3.4.RELEASE]
Caused by: java.lang.IllegalStateException: Failed to introspect Class [pl.piomin.logging.config.SpringLoggingAutoConfiguration] from ClassLoader [jdk.internal.loader.ClassLoaders$AppClassLoader@659e0bfd]
	at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:481) ~[spring-core-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:358) ~[spring-core-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:414) ~[spring-core-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.lambda$getTypeForFactoryMethod$2(AbstractAutowireCapableBeanFactory.java:742) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708) ~[na:na]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:741) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:680) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:648) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1614) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:523) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:495) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition.collectBeanNamesForType(OnBeanCondition.java:238) ~[spring-boot-autoconfigure-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType(OnBeanCondition.java:231) ~[spring-boot-autoconfigure-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType(OnBeanCondition.java:221) ~[spring-boot-autoconfigure-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchingBeans(OnBeanCondition.java:169) ~[spring-boot-autoconfigure-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchOutcome(OnBeanCondition.java:144) ~[spring-boot-autoconfigure-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47) ~[spring-boot-autoconfigure-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	... 23 common frames omitted
Caused by: java.lang.NoClassDefFoundError: javax/servlet/Filter
	at java.base/java.lang.ClassLoader.defineClass1(Native Method) ~[na:na]
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016) ~[na:na]
	at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:151) ~[na:na]
	at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:825) ~[na:na]
	at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:723) ~[na:na]
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:646) ~[na:na]
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:604) ~[na:na]
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168) ~[na:na]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522) ~[na:na]
	at java.base/java.lang.ClassLoader.defineClass1(Native Method) ~[na:na]
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016) ~[na:na]
	at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:151) ~[na:na]
	at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:825) ~[na:na]
	at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:723) ~[na:na]
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:646) ~[na:na]
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:604) ~[na:na]
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168) ~[na:na]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522) ~[na:na]
	at java.base/java.lang.ClassLoader.defineClass1(Native Method) ~[na:na]
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016) ~[na:na]
	at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:151) ~[na:na]
	at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:825) ~[na:na]
	at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:723) ~[na:na]
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:646) ~[na:na]
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:604) ~[na:na]
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168) ~[na:na]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522) ~[na:na]
	at java.base/java.lang.Class.getDeclaredMethods0(Native Method) ~[na:na]
	at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3325) ~[na:na]
	at java.base/java.lang.Class.getDeclaredMethods(Class.java:2466) ~[na:na]
	at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:463) ~[spring-core-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	... 39 common frames omitted
Caused by: java.lang.ClassNotFoundException: javax.servlet.Filter
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:606) ~[na:na]
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168) ~[na:na]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522) ~[na:na]
	... 70 common frames omitted

2020-10-25 14:15:18.831  WARN [netflix-zuul-api-gateway-server,,,] 138876 --- [  restartedMain] o.s.boot.SpringApplication               : Unable to close ApplicationContext

java.lang.IllegalStateException: Failed to introspect Class [pl.piomin.logging.config.SpringLoggingAutoConfiguration] from ClassLoader [jdk.internal.loader.ClassLoaders$AppClassLoader@659e0bfd]
	at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:481) ~[spring-core-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:358) ~[spring-core-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:414) ~[spring-core-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.lambda$getTypeForFactoryMethod$2(AbstractAutowireCapableBeanFactory.java:742) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708) ~[na:na]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:741) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:680) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:648) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1614) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:523) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:495) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:620) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:612) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.getBeansOfType(AbstractApplicationContext.java:1243) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	at org.springframework.boot.SpringApplication.getExitCodeFromMappedException(SpringApplication.java:880) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.getExitCodeFromException(SpringApplication.java:868) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.handleExitCode(SpringApplication.java:855) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:806) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:325) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
	at com.ubaid.ms.NetflixZuulApiGatewayServerApplication.main(NetflixZuulApiGatewayServerApplication.java:17) ~[classes/:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.3.4.RELEASE.jar:2.3.4.RELEASE]
Caused by: java.lang.NoClassDefFoundError: javax/servlet/Filter
	at java.base/java.lang.ClassLoader.defineClass1(Native Method) ~[na:na]
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016) ~[na:na]
	at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:151) ~[na:na]
	at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:825) ~[na:na]
	at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:723) ~[na:na]
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:646) ~[na:na]
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:604) ~[na:na]
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168) ~[na:na]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522) ~[na:na]
	at java.base/java.lang.ClassLoader.defineClass1(Native Method) ~[na:na]
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016) ~[na:na]
	at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:151) ~[na:na]
	at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:825) ~[na:na]
	at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:723) ~[na:na]
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:646) ~[na:na]
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:604) ~[na:na]
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168) ~[na:na]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522) ~[na:na]
	at java.base/java.lang.ClassLoader.defineClass1(Native Method) ~[na:na]
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016) ~[na:na]
	at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:151) ~[na:na]
	at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:825) ~[na:na]
	at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:723) ~[na:na]
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:646) ~[na:na]
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:604) ~[na:na]
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168) ~[na:na]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522) ~[na:na]
	at java.base/java.lang.Class.getDeclaredMethods0(Native Method) ~[na:na]
	at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3325) ~[na:na]
	at java.base/java.lang.Class.getDeclaredMethods(Class.java:2466) ~[na:na]
	at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:463) ~[spring-core-5.2.9.RELEASE.jar:5.2.9.RELEASE]
	... 26 common frames omitted
Caused by: java.lang.ClassNotFoundException: javax.servlet.Filter
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:606) ~[na:na]
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168) ~[na:na]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522) ~[na:na]
	... 57 common frames omitted

Hints

  • spring-cloud-starter-gateway used netty server instead of tomcat
  • logstash-logging-spring-boot-starter has dependency on spring-web

How to produce

How to handle Request Form Data?

When I using this package, I've no issue about Request body from json, but I got some issue when Request Form Data

When I send a request with form data, the data displays in string form

I have tried to override RequestLoggingInterceptor, but data still flows into RequestLoggingInterceptor

public class RequestLogging extends RequestLoggingInterceptor {

    private static final Logger LOGGER = LoggerFactory.getLogger(RequestLoggingInterceptor.class);
    public RequestLogging(ServerHttpRequest delegate, boolean logHeaders, String requestId) {
        super(delegate, logHeaders, requestId);
    }

    @Override
    public Flux<DataBuffer> getBody() {
        MediaType contentType = getDelegate().getHeaders().getContentType();
        boolean isFormData = contentType != null && contentType.isCompatibleWith(MediaType.MULTIPART_FORM_DATA);
        boolean isJson = contentType != null && contentType.isCompatibleWith(MediaType.APPLICATION_JSON);
        if (isFormData) {
            LOGGER.info("Request: method={}, uri={}, payload={}, audit={}", getDelegate().getMethod(),
                    getDelegate().getPath(), "[Form Data]", StructuredArguments.value("audit", true));
            return super.getBody();
        } else if (isJson) {
            return super.getBody().publishOn(Schedulers.boundedElastic()).map(dataBuffer -> {
                byte[] bytes = new byte[dataBuffer.readableByteCount()];
                dataBuffer.read(bytes);
                DataBufferUtils.release(dataBuffer);

                String body = new String(bytes, StandardCharsets.UTF_8);
                LOGGER.info("Request: method={}, uri={}, payload={}, audit={}", getDelegate().getMethod(),
                        getDelegate().getPath(), body, StructuredArguments.value("audit", true));
                return dataBuffer;
            });
        } else {
            LOGGER.info("Request: method={}, uri={}, unsupported content type={}, audit={}", getDelegate().getMethod(),
                    getDelegate().getPath(), contentType, StructuredArguments.value("audit", true));
            return super.getBody();
        }
    }
}

image

SpringResponseWrapper question ,response message loss on interceptor!

add interceptor the example, response message loss (no {"msg": "error"})

public class MainInterceptor implements AsyncHandlerInterceptor {
    final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
        Map<String, Object> map = new HashMap<>();
        map.put("msg", "error");
        response.setStatus(200);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().append(objectMapper.writeValueAsString(map));
        return false;
    }
}

`@Configuration
public class MainMvcConfig implements WebMvcConfigurer {

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new MainInterceptor())
            .addPathPatterns("/**")
            .excludePathPatterns("/req-param");
}

}`

>curl http://localhost:8080/

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.