Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 45 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,38 +19,38 @@ requirements or investigating individual historic traffic issues.
Logbook is ready to use out of the box for most common setups. Even for uncommon applications and technologies, it should be simple to implement the necessary interfaces to connect a
library/framework/etc. to it.

**Contents:**

<!-- toc -->

- [Features](#features)
- [Dependencies](#dependencies)
* [Jackson Version Support](#jackson-version-support)
- [Installation](#installation)
- [Usage](#usage)
* [Strategy](#strategy)
* [Attribute Extractor](#attribute-extractor)
* [Phases](#phases)
* [Servlet](#servlet)
* [HTTP Client](#http-client)
* [HTTP Client 5](#http-client-5)
* [JAX-RS 3.x (aka Jakarta RESTful Web Services)](#jax-rs-3x-aka-jakarta-restful-web-services)
* [JDK HTTP Server](#jdk-http-server)
* [Netty](#netty)
* [OkHttp v2.x](#okhttp-v2x)
* [OkHttp v3.x](#okhttp-v3x)
* [Ktor](#ktor)
* [Spring](#spring)
* [Spring Boot Starter](#spring-boot-starter)
* [logstash-logback-encoder](#logstash-logback-encoder)
- [Known Issues](#known-issues)
- [Getting Help with Logbook](#getting-help-with-logbook)
- [Getting Involved/Contributing](#getting-involvedcontributing)
- [Alternatives](#alternatives)
- [Credits and References](#credits-and-references)

<!-- tocstop -->

**Contents:**
<!-- toc -->
- [Features](#features)
- [Dependencies](#dependencies)
* [Jackson Version Support](#jackson-version-support)
- [Installation](#installation)
- [Usage](#usage)
* [Strategy](#strategy)
* [Attribute Extractor](#attribute-extractor)
* [Phases](#phases)
* [Servlet](#servlet)
* [HTTP Client](#http-client)
* [HTTP Client 5](#http-client-5)
* [JAX-RS 3.x (aka Jakarta RESTful Web Services)](#jax-rs-3x-aka-jakarta-restful-web-services)
* [JDK HTTP Server](#jdk-http-server)
* [Netty](#netty)
* [OkHttp v2.x](#okhttp-v2x)
* [OkHttp v3.x](#okhttp-v3x)
* [Ktor](#ktor)
* [Spring](#spring)
* [Spring Boot Starter](#spring-boot-starter)
* [logstash-logback-encoder](#logstash-logback-encoder)
- [Known Issues](#known-issues)
- [Getting Help with Logbook](#getting-help-with-logbook)
- [Getting Involved/Contributing](#getting-involvedcontributing)
- [Alternatives](#alternatives)
- [Credits and References](#credits-and-references)
<!-- tocstop -->
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, intellij automatically made these changes. Are they ok, or shall I revert them?

## Features

- **Logging**: of HTTP requests and responses, including the body; partial logging (no body) for unauthorized requests
Expand Down Expand Up @@ -1036,6 +1036,18 @@ public BodyFilter bodyFilter() {
}
```

If extra custom configuration is wanted, it is possible to implement a LogbookCustomizer bean, for example:

```java
@Bean
public LogbookCustomizer customizer(Environment env) {
if (env.matchesProfiles("test")) {
return builder -> builder.strategy(new StatusAtLeastStrategy(0));
}
return builder -> {};
}
```

Please refer to [`LogbookAutoConfiguration`](logbook-spring-boot-autoconfigure/src/main/java/org/zalando/logbook/autoconfigure/LogbookAutoConfiguration.java)
or the following table to see a list of possible integration points:

Expand Down Expand Up @@ -1216,4 +1228,4 @@ more details, check the [contribution guidelines](.github/CONTRIBUTING.md).
![Creative Commons (Attribution-Share Alike 3.0 Unported](https://licensebuttons.net/l/by-sa/3.0/80x15.png)
[*Grand Turk, a replica of a three-masted 6th rate frigate from Nelson's days - logbook and charts*](https://commons.wikimedia.org/wiki/File:Grand_Turk(34).jpg)
by [JoJan](https://commons.wikimedia.org/wiki/User:JoJan) is licensed under a
[Creative Commons (Attribution-Share Alike 3.0 Unported)](http://creativecommons.org/licenses/by-sa/3.0/).
[Creative Commons (Attribution-Share Alike 3.0 Unported)](http://creativecommons.org/licenses/by-sa/3.0/).
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.zalando.logbook.Logbook;
import org.zalando.logbook.Sink;
import org.zalando.logbook.autoconfigure.LogbookAutoConfiguration;
import org.zalando.logbook.autoconfigure.LogbookCustomizer;
import org.zalando.logbook.autoconfigure.LogbookProperties;
import org.zalando.logbook.json.CompactingJsonBodyFilter;
import org.zalando.logbook.logstash.LogstashLogbackSink;
Expand All @@ -28,15 +29,20 @@ public void setUp(final HttpLogFormatterState state) {
final LogbookProperties properties = new LogbookProperties();
final LogbookAutoConfiguration ac = new LogbookAutoConfiguration(properties);

autoconfigurationLogbook = ac.logbook(ac.requestCondition(), ac.correlationId(), Collections.singletonList(ac.headerFilter()), Collections.singletonList(ac.pathFilter()), Collections.singletonList(ac.queryFilter()), Collections.singletonList(ac.bodyFilter()), Collections.singletonList(ac.requestFilter()), Collections.singletonList(ac.responseFilter()), ac.strategy(), null, ac.sink(ac.httpFormatter(), ac.writer()));

autoconfigurationLogbook = setup(ac.defaultLogbookConfiguration(ac.requestCondition(), ac.correlationId(), Collections.singletonList(ac.headerFilter()), Collections.singletonList(ac.pathFilter()), Collections.singletonList(ac.queryFilter()), Collections.singletonList(ac.bodyFilter()), Collections.singletonList(ac.requestFilter()), Collections.singletonList(ac.responseFilter()), ac.strategy(), null, ac.sink(ac.httpFormatter(), ac.writer())));
final Sink sink = new LogstashLogbackSink(state.getJsonHttpLogFormatter());

autoconfigurationLogstashLogbook = ac.logbook(ac.requestCondition(), ac.correlationId(), Collections.singletonList(ac.headerFilter()), Collections.singletonList(ac.pathFilter()), Collections.singletonList(ac.queryFilter()), List.of(ac.bodyFilter(), new CompactingJsonBodyFilter()), Collections.singletonList(ac.requestFilter()), Collections.singletonList(ac.responseFilter()), ac.strategy(), null, sink);
autoconfigurationLogstashLogbook = setup(ac.defaultLogbookConfiguration(ac.requestCondition(), ac.correlationId(), Collections.singletonList(ac.headerFilter()), Collections.singletonList(ac.pathFilter()), Collections.singletonList(ac.queryFilter()), List.of(ac.bodyFilter(), new CompactingJsonBodyFilter()), Collections.singletonList(ac.requestFilter()), Collections.singletonList(ac.responseFilter()), ac.strategy(), null, sink));

final Sink noop = new LogstashLogbackSink(state.getNoopHttpLogFormatter());

noopHttpLogFormatterLogbook = ac.logbook(ac.requestCondition(), ac.correlationId(), Collections.singletonList(ac.headerFilter()), Collections.singletonList(ac.pathFilter()), Collections.singletonList(ac.queryFilter()), List.of(ac.bodyFilter(), new CompactingJsonBodyFilter()), Collections.singletonList(ac.requestFilter()), Collections.singletonList(ac.responseFilter()), ac.strategy(), null, noop);
noopHttpLogFormatterLogbook = setup(ac.defaultLogbookConfiguration(ac.requestCondition(), ac.correlationId(), Collections.singletonList(ac.headerFilter()), Collections.singletonList(ac.pathFilter()), Collections.singletonList(ac.queryFilter()), List.of(ac.bodyFilter(), new CompactingJsonBodyFilter()), Collections.singletonList(ac.requestFilter()), Collections.singletonList(ac.responseFilter()), ac.strategy(), null, noop));
}

private Logbook setup(LogbookCustomizer customizer) {
var builder = Logbook.builder();
customizer.customize(builder);
return builder.build();
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import lombok.Generated;
import org.apache.http.client.HttpClient;
import org.apiguardian.api.API;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
Expand All @@ -22,21 +23,11 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.web.SecurityFilterChain;
import org.zalando.logbook.BodyFilter;
import org.zalando.logbook.CorrelationId;
import org.zalando.logbook.HeaderFilter;
import org.zalando.logbook.HttpLogFormatter;
import org.zalando.logbook.HttpLogWriter;
import org.zalando.logbook.HttpRequest;
import org.zalando.logbook.Logbook;
import org.zalando.logbook.PathFilter;
import org.zalando.logbook.QueryFilter;
import org.zalando.logbook.RequestFilter;
import org.zalando.logbook.ResponseFilter;
import org.zalando.logbook.Sink;
import org.zalando.logbook.Strategy;
import org.zalando.logbook.*;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we tend to not use start imports, could you please change it?

import org.zalando.logbook.attributes.AttributeExtractor;
import org.zalando.logbook.core.attributes.CompositeAttributeExtractor;
import org.zalando.logbook.attributes.NoOpAttributeExtractor;
Expand Down Expand Up @@ -76,7 +67,6 @@
import java.util.Set;
import java.util.TreeSet;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static jakarta.servlet.DispatcherType.ASYNC;
Expand Down Expand Up @@ -111,7 +101,24 @@ public LogbookAutoConfiguration(final LogbookProperties properties) {
@API(status = INTERNAL)
@Bean
@ConditionalOnMissingBean(Logbook.class)
public Logbook logbook(
public Logbook logbook(LogbookCreator.Builder builder) {
return builder.build();
}

@API(status = INTERNAL)
@Bean
@ConditionalOnMissingBean(LogbookCreator.Builder.class)
@Scope("prototype")
public LogbookCreator.Builder logbookBuilder(final ObjectProvider<LogbookCustomizer> customizers) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we even need this prototype bean. Wouldn't it work the same if logbook bean would accept customizers and apply them?

e.g.

    @API(status = INTERNAL)
    @Bean
    @ConditionalOnMissingBean(Logbook.class)
    public Logbook logbook(List<LogbookCustomizer> customizers) {
        var builder = Logbook.builder();
        customizers.forEach(customizer -> customizer.customize(builder));
        return builder.build();
    }

var builder = Logbook.builder();
customizers.orderedStream().forEach(customizer -> customizer.customize(builder));
return builder;
}

@Bean
@Order(0)
@ConditionalOnMissingBean(name = "defaultLogbookConfiguration")
public LogbookCustomizer defaultLogbookConfiguration(
final Predicate<HttpRequest> condition,
final CorrelationId correlationId,
final List<HeaderFilter> headerFilters,
Expand All @@ -123,8 +130,7 @@ public Logbook logbook(
final Strategy strategy,
final AttributeExtractor attributeExtractor,
final Sink sink) {

return Logbook.builder()
return builder -> builder
.condition(mergeWithExcludes(mergeWithIncludes(condition)))
.correlationId(correlationId)
.headerFilters(headerFilters)
Expand All @@ -135,8 +141,7 @@ public Logbook logbook(
.responseFilters(responseFilters)
.strategy(strategy)
.attributeExtractor(attributeExtractor)
.sink(sink)
.build();
.sink(sink);
}

private Collection<BodyFilter> mergeWithTruncation(List<BodyFilter> bodyFilters) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.zalando.logbook.autoconfigure;

import org.zalando.logbook.LogbookCreator;

@FunctionalInterface
public interface LogbookCustomizer {
void customize(LogbookCreator.Builder builder);
}
Loading