zalando/logbook

Logbook doesn't work with spring boot 3

evkaky opened this issue · 17 comments

I'm following the documentation https://github.com/zalando/logbook#spring-boot-starter trying to make WebClient logging all exchanges, but here is a minimal code sample to make sure logbook + spring boot web client = nothing get logged
build.gradle.kts:

plugins {
    java
    id("org.springframework.boot") version "3.0.5"
}

group = "com.example"
version = "0.0.1-SNAPSHOT"

repositories {
    mavenCentral()
}

dependencies {
    implementation(platform("org.springframework.boot:spring-boot-dependencies:3.0.5"))
    implementation("org.springframework.boot:spring-boot-starter-webflux")
    implementation("org.zalando:logbook-spring-boot-starter:2.16.0")
}

java {
    toolchain.languageVersion.set(JavaLanguageVersion.of(17))
}

src/main/resources/application.yml:

spring:
  main.web-application-type: none

logging.level:
  org.zalando.logbook: trace

logbook:
  format.style: http
  filter.enabled: false

SpringApplication.java:

@SpringBootApplication
public class MyApp {
    public static void main(String[] args) {
        SpringApplication.run(MyApp.class);
    }

    @Bean
    public ApplicationRunner onStart(WebClient.Builder webClientBuilder) {
        return args -> {
            var webClient = webClientBuilder
                .baseUrl("https://jsonplaceholder.typicode.com")
                .build();

            Todo resp = webClient
                .get()
                .uri("todos/{id}", 1)
                .retrieve()
                .bodyToMono(Todo.class)
                .block();

            System.out.println(resp.title);
        };
    }
}

class Todo {
    public int id;
    public int userId;
    public String title;
    public boolean completed;
}

image

As you can see, nothing got logged

Hi @evkaky think it will be included in version 3.0.x. See #1344

Hi @willlie1
I just tried to bounce version to org.zalando:logbook-spring-boot-starter:3.0.0-RC.0
Nothing changed. Is it expected the release candidate version 3.0.0-RC.0 doesn't work either?

Hello @evkaky
In order to make logbook work with webflux, you have just to include this dependency logbook-spring-webflux.
And inject LogbookExchangeFilterFunction to your client.
Here is the snippet of SpringApplication.java:

@SpringBootApplication
public class LogbookWebClientApplication {

	public static void main(String[] args) {
		SpringApplication.run(LogbookWebClientApplication.class, args);
	}

	@Bean
	Logbook logbook() {
		return Logbook.create();
	}

	@Bean
	public ApplicationRunner onStart(WebClient.Builder webClientBuilder, Logbook logbook) {
		return args -> {
			var webClient = webClientBuilder
					.baseUrl("https://jsonplaceholder.typicode.com")
					.filter(new LogbookExchangeFilterFunction(logbook))
					.build();

			Todo resp = webClient
					.get()
					.uri("todos/{id}", 1)
					.retrieve()
					.bodyToMono(Todo.class)
					.block();
		};
	}

}

At startup you should have logs for Outgoing and Incoming Response.
Hope that helps you.

For spring-webflux application you'd need to use logbook-spring-boot-webflux-autoconfigure as a dependency.

But it looks like the org.springframework.boot.autoconfigure.AutoConfiguration.imports file is missing in logbook-spring-boot-webflux-autoconfigure module. Without it, the LogbookWebFluxAutoConfiguration class is not loaded by default. Until it's added, you'd need to add the filter directly as @Larkhis suggested or Import LogbookWebFluxAutoConfiguration to your spring boot app.
I'll open a PR for it.

The autoconfiguration part should be fixed in the next release. I'll resolve the issue. Feel free to reopen if you still need support here.

Springboot 3.3.1 with logbook-spring-boot-start version 3.9.0

Thx

For spring-webflux application you'd need to use logbook-spring-boot-webflux-autoconfigure as a dependency.

But it looks like the org.springframework.boot.autoconfigure.AutoConfiguration.imports file is missing in logbook-spring-boot-webflux-autoconfigure module. Without it, the LogbookWebFluxAutoConfiguration class is not loaded by default. Until it's added, you'd need to add the filter directly as @Larkhis suggested or Import LogbookWebFluxAutoConfiguration to your spring boot app. I'll open a PR for it.

In my Spring Boot WebFlux project, I am unable to generate any logs using Logbook.

Here is the relevant section from my pom.xml:

    <dependency>
      <groupId>org.zalando</groupId>
      <artifactId>logbook-spring-boot-autoconfigure</artifactId>
      <version>3.9.0</version>
    </dependency>
    <dependency>
      <groupId>org.zalando</groupId>
      <artifactId>logbook-spring-boot-webflux-autoconfigure</artifactId>
      <version>3.9.0</version>
    </dependency>
    <dependency>
      <groupId>org.zalando</groupId>
      <artifactId>logbook-netty</artifactId>
      <version>3.9.0</version>
    </dependency>

The configuration in application.yml is as follows:

logbook:
 format: json
 strategy: default
 filter:
   enabled: true
   exclude:
     - /swagger
     - /api-docs
     - /actuator
 obfuscate:
   headers:
     - Authorization
     - Cookie
   parameters:
     - password
   body:
     patterns:
       - '"password": ".*"'
 write:
   level: DEBUG
   category: logbook.log
 max-body-size: 1000
 exclude:
   content-types:
     - application/octet-stream   
...

logging:
 level:
   org.zalando: DEBUG

You've missed to post your logging (framework) configuration.

You've missed to post your logging (framework) configuration.

Updated

You configure Logbook to use the category (aka logger name) "category: logbook.log" but then you configure your logging framework to change the log level of "org.zalando". Those need to be aligned. You can just delete the line with "category" and then it should already work.

(This has nothing to do with Logbook, technically. Just logging framework configuration.)

I removed the category entirely, but I'm still not seeing any output. I also set write.level = INFO for both Logbook and the root logger, but nothing.

The full category name is org.zalando.logbook.Logbook (see https://github.com/zalando/logbook?tab=readme-ov-file#writing). Maybe your logging framework needs to configure the full name and not just the prefix. No idea.

Could you provide some advice on how to debug this issue? Specifically, which important classes should I focus on, and where would be the best places to set breakpoints?

DefaultHttpLogWriter

Turns out it works when trace is enabled. It is not picking up this setting:

  write:
    level: DEBUG

I am sure it was. I mean, I hope it was just moved somewhere else.