### Precorrelation getStart() Method Example
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Correlation.md
Shows how to get the timestamp indicating when the HTTP request began.
```java
Instant requestStart = precorr.getStart();
```
--------------------------------
### Robust Logbook Initialization with Error Handling
Source: https://github.com/zalando/logbook/blob/main/_autodocs/errors.md
Configure Logbook with robust error handling during initialization. This example includes a safe condition predicate and catches general exceptions during builder setup, falling back to a default Logbook instance if creation fails.
```java
@Configuration
public class RobustLogbookConfiguration {
private static final Logger logger = LoggerFactory.getLogger(
RobustLogbookConfiguration.class);
@Bean
public Logbook logbook() {
try {
return Logbook.builder()
.condition(request -> {
try {
return !request.getPath().startsWith("/health");
} catch (Exception e) {
logger.warn("Condition evaluation failed", e);
return true;
}
})
.bodyFilter(BodyFilters.oauthRequest())
.build();
} catch (Exception e) {
logger.error("Failed to create Logbook, using default", e);
return Logbook.create();
}
}
}
```
--------------------------------
### Accessing the Logbook Builder
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/LogbookBuilder.md
Get an instance of the Logbook builder to start configuring logging.
```java
LogbookCreator.Builder builder = Logbook.builder();
Logbook logbook = builder.build();
```
--------------------------------
### Logbook Configuration Example
Source: https://github.com/zalando/logbook/blob/main/README.md
Example of Logbook configuration using YAML, specifying predicates for including/excluding requests, obfuscation rules, and formatting strategies.
```yaml
logbook:
predicate:
include:
- path: /api/**
methods:
- GET
- POST
- path: /actuator/**
exclude:
- path: /actuator/health
- path: /api/admin/**
methods:
- POST
filter.enabled: true
secure-filter.enabled: true
format.style: http
strategy: body-only-if-status-at-least
minimum-status: 400
obfuscate:
headers:
- Authorization
- X-Secret
parameters:
- access_token
- password
write:
chunk-size: 1000
attribute-extractors:
- type: JwtFirstMatchingClaimExtractor
claim-names: [ "sub", "subject" ]
claim-key: Principal
- type: JwtAllMatchingClaimsExtractor
claim-names: [ "sub", "iat" ]
```
--------------------------------
### cURL Request Example
Source: https://github.com/zalando/logbook/blob/main/README.md
An example of an HTTP request formatted as an executable cURL command.
```bash
curl -v -X GET 'http://localhost/test' -H 'Accept: application/json'
```
--------------------------------
### Filter Hierarchy Example
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/CoreConcepts.md
Illustrates the sequential application of filters in Logbook, starting from header filtering and progressing through body, query, path, and finally request/response filters.
```text
Original request/response
↓
HeaderFilter (remove/mask headers)
↓
BodyFilter (transform body)
↓
QueryFilter (mask query parameters)
↓
PathFilter (mask path segments)
↓
RequestFilter/ResponseFilter (transform entire object)
↓
Filtered request/response
```
--------------------------------
### Ktor Server with LogbookServer
Source: https://github.com/zalando/logbook/blob/main/README.md
Install LogbookServer for logging HTTP server requests in Ktor.
```kotlin
private val server = embeddedServer(CIO) {
install(LogbookServer) {
logbook = logbook
}
}
```
--------------------------------
### HTTP Logbook Request Example
Source: https://github.com/zalando/logbook/blob/main/README.md
Example of an incoming HTTP request formatted for local development and debugging.
```http
Incoming Request: 2d66e4bc-9a0d-11e5-a84c-1f39510f0d6b
GET http://example.org/test HTTP/1.1
Accept: application/json
Host: localhost
Content-Type: text/plain
Hello world!
```
--------------------------------
### Ktor Logbook Feature Installation
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/OtherIntegrations.md
Installs the Logbook feature in a Ktor application. This is the simplest way to enable logging for Ktor.
```kotlin
install(LogbookFeature) {
logbook = Logbook.create()
}
```
--------------------------------
### Ktor Client with LogbookClient
Source: https://github.com/zalando/logbook/blob/main/README.md
Install LogbookClient for logging HTTP client requests in Ktor.
```kotlin
private val client = HttpClient(CIO) {
install(LogbookClient) {
logbook = logbook
}
}
```
--------------------------------
### Logbook Setup with FastJson and Logstash Writer
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Formatters.md
Demonstrates configuring Logbook for structured logging with FastJsonHttpLogFormatter and LogstashLogbookWriter.
```java
import org.zalando.logbook.Logbook;
import org.zalando.logbook.HttpLogFormatter;
import org.zalando.logbook.HttpLogWriter;
import org.zalando.logbook.json.FastJsonHttpLogFormatter;
import org.zalando.logbook.core.DefaultSink;
import org.zalando.logbook.LogstashLogbookWriter;
HttpLogFormatter formatter = new FastJsonHttpLogFormatter();
HttpLogWriter writer = new LogstashLogbookWriter();
Logbook logbook = Logbook.builder()
.sink(new DefaultSink(formatter, writer))
.build();
```
--------------------------------
### JSON Logbook Request Example
Source: https://github.com/zalando/logbook/blob/main/README.md
Example of a JSON formatted incoming request, suitable for production use and machine readability.
```json
{
"origin": "remote",
"type": "request",
"correlation": "2d66e4bc-9a0d-11e5-a84c-1f39510f0d6b",
"protocol": "HTTP/1.1",
"sender": "127.0.0.1",
"method": "GET",
"uri": "http://example.org/test",
"host": "example.org",
"path": "/test",
"scheme": "http",
"port": null,
"headers": {
"Accept": ["application/json"],
"Content-Type": ["text/plain"]
},
"body": "Hello world!"
}
```
--------------------------------
### Curl Command Output Example
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Formatters.md
An example of the output generated by CurlHttpLogFormatter, showing a curl command.
```shell
curl -X GET \
-H 'Accept: application/json' \
-H 'Host: api.example.com' \
'https://api.example.com/api/users?page=1'
```
--------------------------------
### HTTP Logbook Response Example
Source: https://github.com/zalando/logbook/blob/main/README.md
Example of an outgoing HTTP response formatted for local development and debugging.
```http
Outgoing Response: 2d66e4bc-9a0d-11e5-a84c-1f39510f0d6b
Duration: 25 ms
HTTP/1.1 200
Content-Type: application/json
{"value":"Hello world!"}
```
--------------------------------
### Create Logbook Instance with Defaults
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Logbook.md
Creates a Logbook instance with default configuration. Use this for a quick setup with sensible defaults.
```java
Logbook logbook = Logbook.create();
```
--------------------------------
### Sink and Formatting Example
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/CoreConcepts.md
Shows the flow from request/response objects through the HttpLogFormatter to the Sink, and finally to the HttpLogWriter for persistent storage.
```text
Request/Response objects
↓
HttpLogFormatter (formats to string)
↓
Sink (receives string)
↓
HttpLogWriter (writes to file/network/etc)
```
--------------------------------
### Basic Logbook Setup with Default Formatter and Writer
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Formatters.md
Demonstrates how to create a Logbook instance using the default HttpLogFormatter and HttpLogWriter, combined into a composite sink.
```java
import org.zalando.logbook.Logbook;
import org.zalando.logbook.HttpLogFormatter;
import org.zalando.logbook.HttpLogWriter;
import org.zalando.logbook.Sink;
import org.zalando.logbook.DefaultHttpLogFormatter;
import org.zalando.logbook.DefaultHttpLogWriter;
import org.zalando.logbook.core.DefaultSink;
HttpLogFormatter formatter = new DefaultHttpLogFormatter();
HttpLogWriter writer = new DefaultHttpLogWriter();
// Create composite sink using formatter and writer
Sink sink = new DefaultSink(formatter, writer);
Logbook logbook = Logbook.builder()
.sink(sink)
.build();
```
--------------------------------
### Logbook Orchestration Example
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/CoreConcepts.md
Demonstrates the chaining of methods in the Logbook entry point to orchestrate the request-response lifecycle, from initial processing to final writing.
```text
logbook.process(request) → RequestWritingStage
.write() → ResponseProcessingStage
.process(response) → ResponseWritingStage
.write() → void (complete)
```
--------------------------------
### Custom HttpLogFormatter for Request Logging
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Correlation.md
Provides an example of a custom `HttpLogFormatter` to format log output for incoming requests, including correlation ID, start time, method, and path.
```java
HttpLogFormatter formatter = new HttpLogFormatter() {
@Override
public String format(Precorrelation precorrelation, HttpRequest request)
throws IOException {
StringBuilder sb = new StringBuilder();
sb.append("Request: ").append(precorrelation.getId()).append("\n");
sb.append("Started: ").append(precorrelation.getStart()).append("\n");
sb.append(request.getMethod()).append(" ").append(request.getPath());
return sb.toString();
}
@Override
public String format(Correlation correlation, HttpResponse response)
throws IOException {
StringBuilder sb = new StringBuilder();
sb.append("Response: ").append(correlation.getId()).append("\n");
sb.append("Duration: ").append(correlation.getDuration()).append("\n");
sb.append("Status: ").append(response.getStatus());
return sb.toString();
}
};
```
--------------------------------
### Filter Composition Example
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/CoreConcepts.md
Demonstrates how multiple filters can be composed sequentially. Filters are applied from left to right.
```plaintext
Filter1 + Filter2 + Filter3 = ComposedFilter
Composed filters are applied left-to-right:
Input → Filter1 → Filter2 → Filter3 → Output
```
--------------------------------
### Correlation getDuration() Method Example
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Correlation.md
Shows how to obtain the total elapsed time between the request start and response end, represented as a `Duration` object.
```java
Correlation corr = /* ... */;
Duration elapsed = corr.getDuration();
long millis = elapsed.toMillis(); // e.g., 245
```
--------------------------------
### Logbook configuration with header filtering
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/HttpHeaders.md
Example demonstrating how to configure Logbook with a custom HeaderFilter to sanitize sensitive headers before logging.
```java
HeaderFilter securityFilter = headers -> headers
.delete("Authorization", "X-API-Key", "Cookie")
.apply(
(name, values) -> name.equalsIgnoreCase("Set-Cookie"),
(name, values) -> List.of("***"));
Logbook logbook = Logbook.builder()
.headerFilter(securityFilter)
.build();
```
--------------------------------
### Splunk Request Log Example
Source: https://github.com/zalando/logbook/blob/main/README.md
An HTTP request formatted for Splunk as key-value pairs.
```text
origin=remote type=request correlation=2d66e4bc-9a0d-11e5-a84c-1f39510f0d6b protocol=HTTP/1.1 sender=127.0.0.1 method=POST uri=http://example.org/test host=example.org scheme=http port=null path=/test headers={Accept=[application/json], Content-Type=[text/plain]} body=Hello world!
```
--------------------------------
### Splunk Response Log Example
Source: https://github.com/zalando/logbook/blob/main/README.md
An HTTP response formatted for Splunk as key-value pairs.
```text
origin=local type=response correlation=2d66e4bc-9a0d-11e5-a84c-1f39510f0d6b duration=25 protocol=HTTP/1.1 status=200 headers={Content-Type=[text/plain]} body=Hello world!
```
--------------------------------
### Logbook Filter Composition Example
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Filters.md
Demonstrates how to configure a Logbook instance with various pre-built and custom filters for body, headers, path, query, request, and response.
```java
import org.zalando.logbook.Logbook;
import org.zalando.logbook.BodyFilters;
Logbook logbook = Logbook.builder()
// Body filters
.bodyFilter(BodyFilters.oauthRequest())
.bodyFilter(BodyFilters.truncate(1000))
// Header filters
.headerFilter(headers -> headers.delete("Authorization"))
// Path filters
.pathFilter(path -> path.replaceAll("/\\d+/", "/{id}/"))
// Query filters
.queryFilter(query -> query.replaceAll("key=[^&]*", "key=***"))
// Request filters
.requestFilter(request -> request.withoutBody())
// Response filters
.responseFilter(response -> response.withoutBody())
.build();
```
--------------------------------
### FastJsonHttpLogFormatter JSON Output Example
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Formatters.md
An example of the structured JSON output produced by FastJsonHttpLogFormatter, suitable for log aggregation systems.
```json
{
"origin": "REMOTE",
"type": "request",
"correlation": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"protocol": "HTTP/1.1",
"remote": "192.168.1.100",
"method": "GET",
"uri": "https://api.example.com/api/users?page=1",
"headers": {
"Accept": ["application/json"],
"Host": ["api.example.com"]
}
}
```
--------------------------------
### Logbook Usage Example
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/HttpRequest.md
Demonstrates how to configure Logbook with a custom strategy to conditionally buffer the request body based on the HTTP method.
```java
Strategy strategy = (request) -> {
// Access request details
String method = request.getMethod();
String path = request.getPath();
String query = request.getQuery();
String host = request.getHost();
// Conditionally buffer body
if ("POST".equals(method) || "PUT".equals(method)) {
return request.withBody();
} else {
return request.withoutBody();
}
};
Logbook logbook = Logbook.builder()
.build();
```
--------------------------------
### Logbook Core Dependency Installation
Source: https://github.com/zalando/logbook/blob/main/README.md
Add this dependency to your project to include the core functionality of Logbook.
```xml
org.zalandologbook-core${logbook.version}
```
--------------------------------
### Common Log Format Example
Source: https://github.com/zalando/logbook/blob/main/README.md
A log entry formatted using the Common Log Format (CLF).
```text
185.85.220.253 - - [02/Aug/2019:08:16:41 0000] "GET /search?q=zalando HTTP/1.1" 200 -
```
--------------------------------
### Java Example: Sanitizing Headers by Deleting and Modifying
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Filters.md
An example HeaderFilter that deletes specific headers like 'Authorization' and 'X-API-Key', and modifies 'Cookie' headers to mask values. This is useful for security and privacy.
```java
HeaderFilter sanitizeHeaders = headers -> headers
.delete("Authorization", "X-API-Key")
.apply(
(name, values) -> name.equalsIgnoreCase("Cookie"),
(name, values) -> List.of("***"));
```
--------------------------------
### Precorrelation correlate() Method Example
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Correlation.md
Illustrates upgrading a `Precorrelation` object to a full `Correlation` object once the HTTP response has been received.
```java
Precorrelation precorr = /* ... */;
// Later, when response is available
Correlation full = precorr.correlate();
```
--------------------------------
### Correlation getEnd() Method Example
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Correlation.md
Demonstrates how to retrieve the timestamp when the HTTP response was received.
```java
Correlation corr = /* ... */;
Instant responseEnd = corr.getEnd();
```
--------------------------------
### Example Usage of RestTemplate with Logbook
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/SpringIntegration.md
Demonstrates how a service can use an auto-configured RestTemplate to make HTTP requests, which are then automatically logged by the Logbook interceptor.
```java
@Service
public class UserService {
@Autowired
private RestTemplate restTemplate;
public User fetchUser(String userId) {
// HTTP requests are automatically logged
ResponseEntity response = restTemplate.getForEntity(
"https://api.example.com/users/{id}",
User.class,
userId);
return response.getBody();
}
}
```
--------------------------------
### Filter Composition Example
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Filters.md
Demonstrates how to compose various filters, including body, header, path, query, request, and response filters, when building a Logbook instance.
```APIDOC
## Filter Composition in Logbook
```java
Logbook logbook = Logbook.builder()
// Body filters
.bodyFilter(BodyFilters.oauthRequest())
.bodyFilter(BodyFilters.truncate(1000))
// Header filters
.headerFilter(headers -> headers.delete("Authorization"))
// Path filters
.pathFilter(path -> path.replaceAll("/\\d+/", "/{id}/"))
// Query filters
.queryFilter(query -> query.replaceAll("key=[^&]*", "key=***"))
// Request filters
.requestFilter(request -> request.withoutBody())
// Response filters
.responseFilter(response -> response.withoutBody())
.build();
```
```
--------------------------------
### Extended Log Format Example
Source: https://github.com/zalando/logbook/blob/main/README.md
A log entry formatted using the Extended Log Format (ELF) with default fields.
```text
2019-08-02 08:16:41 185.85.220.253 localhost POST /search ?q=zalando 200 21 20 0.125 HTTP/1.1 "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0" "name=value" "https://example.com/page?q=123"
```
--------------------------------
### Origin Enum Usage Example
Source: https://github.com/zalando/logbook/blob/main/_autodocs/types.md
Demonstrates how to check the origin of an HTTP message using the Origin enum.
```java
Origin origin = message.getOrigin();
if (origin == Origin.LOCAL) {
// This is a request we sent or response we received
} else {
// This is a request from a client or response to a client
}
```
--------------------------------
### JDK HTTP Server Integration
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/OtherIntegrations.md
Integrates Logbook with Java's built-in `com.sun.net.httpserver.HttpServer`. This example shows how to create a server and add the LogbookHttpHandler.
```java
HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
server.createContext("/api", new LogbookHttpHandler(
logbook,
actualHandler));
server.start();
```
--------------------------------
### Example Log Output for Outgoing Requests
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/SpringIntegration.md
Illustrates the typical log format for outgoing HTTP client requests and their corresponding incoming responses as captured by Logbook.
```text
Outgoing Request: f47ac10b-58cc-4372-a567-0e02b2c3d479
Remote: api.example.com
GET /api/users/123 HTTP/1.1
Host: api.example.com
Accept: application/json
User-Agent: Spring-Framework/6.1
---
Incoming Response: f47ac10b-58cc-4372-a567-0e02b2c3d479
Duration: 245 ms
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 456
Cache-Control: no-cache
```
--------------------------------
### Configuring Request and Response Filters
Source: https://github.com/zalando/logbook/blob/main/README.md
Set up Logbook to filter sensitive parts of HTTP requests and responses. This example replaces binary/stream bodies and specific query/header values.
```java
import static org.zalando.logbook.core.HeaderFilters.authorization;
import static org.zalando.logbook.core.HeaderFilters.eachHeader;
import static org.zalando.logbook.core.QueryFilters.accessToken;
import static org.zalando.logbook.core.QueryFilters.replaceQuery;
Logbook logbook = Logbook.builder()
.requestFilter(RequestFilters.replaceBody(message -> contentType("audio/*").test(message) ? "mmh mmh mmh mmh" : null))
.responseFilter(ResponseFilters.replaceBody(message -> contentType("*/*-stream").test(message) ? "It just keeps going and going..." : null))
.queryFilter(accessToken())
.queryFilter(replaceQuery("password", ""))
.headerFilter(authorization())
.headerFilter(eachHeader("X-Secret"::equalsIgnoreCase, ""))
.build();
```
--------------------------------
### Registering Default LogbookFilter with Spring Boot
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/ServletIntegration.md
Example of how to register the default LogbookFilter using Spring Boot's FilterRegistrationBean.
```java
@WebListener
public class LogbookConfiguration {
@Bean
public FilterRegistrationBean logbookFilter() {
return new FilterRegistrationBean<>(new LogbookFilter());
}
}
```
--------------------------------
### Attribute Extractor Example
Source: https://github.com/zalando/logbook/blob/main/README.md
Implement AttributeExtractor to extract custom attributes from requests. Logbook must be configured with this extractor.
```java
final class OriginExtractor implements AttributeExtractor {
@Override
public HttpAttributes extract(final HttpRequest request) {
return HttpAttributes.of("origin", request.getOrigin());
}
}
```
--------------------------------
### Charset Detection Examples
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/CoreConcepts.md
Demonstrates how Logbook automatically detects character encoding from the Content-Type header. It shows default encodings for common types and specific encodings when provided.
```plaintext
application/json; charset=utf-8 → UTF-8
application/json → UTF-8 (JSON default)
text/html; charset=iso-8859-1 → ISO-8859-1
application/octet-stream → UTF-8 (default)
```
--------------------------------
### Java FileSink Implementation
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Sink.md
An example implementation of the Sink interface for writing logs to a file. It formats and writes request or response logs using a PrintWriter.
```java
public class FileSink implements Sink {
private final HttpLogFormatter formatter;
private final PrintWriter writer;
@Override
public void write(Precorrelation precorrelation, HttpRequest request)
throws IOException {
writer.println(formatter.format(precorrelation, request));
writer.flush();
}
@Override
public void write(Correlation correlation, HttpRequest request,
HttpResponse response) throws IOException {
writer.println(formatter.format(correlation, response));
writer.flush();
}
}
```
--------------------------------
### Precorrelation Interface Definition
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Correlation.md
Defines the preliminary correlation information available before a response is received. It includes methods to get the unique ID and the start time of the request.
```java
public interface Precorrelation {
String getId();
Instant getStart();
Correlation correlate();
}
```
--------------------------------
### File-Based Sink Configuration
Source: https://github.com/zalando/logbook/blob/main/_autodocs/configuration.md
Configure Logbook to write HTTP request and response logs to a file. This example uses a custom HttpLogWriter to append logs to 'requests.log'.
```java
HttpLogFormatter formatter = new DefaultHttpLogFormatter();
HttpLogWriter fileWriter = new HttpLogWriter() {
private final PrintWriter writer = new PrintWriter(
new FileWriter("requests.log", true));
@Override
public void write(Precorrelation precorrelation, String request)
throws IOException {
writer.println(request);
writer.flush();
}
@Override
public void write(Correlation correlation, String response)
throws IOException {
writer.println(response);
writer.flush();
}
};
Logbook logbook = Logbook.builder()
.sink(new DefaultSink(formatter, fileWriter))
.build();
```
--------------------------------
### Setting a Request Logging Condition
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/LogbookBuilder.md
Use a predicate to specify which HTTP requests should be logged. This example excludes requests to the /health endpoint.
```java
Logbook logbook = Logbook.builder()
.condition(request -> !request.getPath().startsWith("/health"))
.build();
```
--------------------------------
### Java Example: Merging BodyFilters for OAuth and Truncation
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Filters.md
Demonstrates merging two BodyFilters: one for OAuth requests and another for truncating content. This creates a composite filter.
```java
BodyFilter combined = BodyFilter.merge(
BodyFilters.oauthRequest(),
BodyFilters.truncate(1000)
);
```
--------------------------------
### Create an empty HttpHeaders instance
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/HttpHeaders.md
Factory method to create a new, empty HttpHeaders object. Useful for starting with a clean slate.
```java
static HttpHeaders empty();
```
```java
HttpHeaders headers = HttpHeaders.empty()
.update("Content-Type", "application/json");
```
--------------------------------
### BodyFilter Usage Example
Source: https://github.com/zalando/logbook/blob/main/_autodocs/types.md
An example of a BodyFilter that replaces sensitive password information with asterisks.
```java
BodyFilter filter = (contentType, body) ->
body.replaceAll("password=[^&]*", "password=***");
```
--------------------------------
### Custom HttpLogFormatter Implementation
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Formatters.md
Example of a custom HttpLogFormatter that formats logs based on request and response details. It checks for an Authorization header.
```java
import org.zalando.logbook.Correlation;
import org.zalando.logbook.HttpRequest;
import org.zalando.logbook.HttpLogFormatter;
import org.zalando.logbook.Precorrelation;
import java.io.IOException;
public class CustomFormatter implements HttpLogFormatter {
@Override
public String format(Precorrelation precorrelation, HttpRequest request)
throws IOException {
return String.format(
"[%s] %s %s %s",
precorrelation.getId(),
request.getMethod(),
request.getPath(),
request.getHeaders().getFirst("Authorization") != null ? "AUTHENTICATED" : "ANONYMOUS"
);
}
@Override
public String format(Correlation correlation, HttpResponse response)
throws IOException {
return String.format(
"[%s] %d %dms",
correlation.getId(),
response.getStatus(),
correlation.getDuration().toMillis()
);
}
}
```
--------------------------------
### Basic Sink Usage with Logbook
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Sink.md
Demonstrates how to create and configure a default sink and integrate it into a Logbook instance. Ensure you have HttpLogFormatter and HttpLogWriter implementations available.
```java
HttpLogFormatter formatter = new DefaultHttpLogFormatter();
HttpLogWriter writer = new DefaultHttpLogWriter();
Sink sink = new DefaultSink(formatter, writer);
Logbook logbook = Logbook.builder()
.sink(sink)
.build();
```
--------------------------------
### Get HTTP Method
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/HttpRequest.md
Retrieves the HTTP method of the request, such as GET, POST, PUT, etc.
```java
String getMethod();
```
```java
String method = request.getMethod();
// e.g., "GET", "POST"
```
--------------------------------
### Strategy Composition with Builder
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Strategy.md
Demonstrates how to create a custom strategy using a lambda expression and integrate it into Logbook using its builder pattern.
```java
Strategy customStrategy = request -> {
// Perform checks and return modified request
return request.withBody();
};
Logbook logbook = Logbook.builder()
.strategy(customStrategy)
.build();
```
--------------------------------
### Complete Logbook Configuration Example
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/LogbookBuilder.md
This snippet demonstrates a comprehensive configuration of the LogbookBuilder, including excluding specific requests, generating correlation IDs, filtering sensitive headers and query parameters, filtering body content, defining custom logging strategies, extracting attributes, and configuring the sink.
```java
Logbook logbook = Logbook.builder()
// Exclude health checks and actuator endpoints
.condition(Conditions.exclude(
Conditions.requestTo("/health/**"),
Conditions.requestTo("/actuator/**")
))
// Generate correlation IDs from headers or UUID
.correlationId(request -> {
String header = request.getHeaders().getFirst("X-Correlation-ID");
return header != null ? header : UUID.randomUUID().toString();
})
// Filter sensitive headers
.headerFilter(headers -> headers
.delete("Authorization", "X-API-Key", "Cookie")
.delete((name, values) -> name.equalsIgnoreCase("Set-Cookie")))
// Filter query parameters
.queryFilter(query -> query
.replaceAll("password=[^&]*", "password=***")
.replaceAll("token=[^&]*", "token=***"))
// Filter body content
.bodyFilter(BodyFilters.oauthRequest())
.bodyFilter(BodyFilters.truncate(1000))
.bodyFilter((contentType, body) ->
"application/json".equals(contentType) ?
// Custom JSON processing
body :
body)
// Custom strategy for conditional logging
.strategy(new Strategy() {
@Override
public HttpResponse process(HttpRequest request, HttpResponse response)
throws IOException {
return response.getStatus() >= 400 ?
response.withBody() :
response.withoutBody();
}
})
// Add custom attributes
.attributeExtractor(request ->
HttpAttributes.of("service", "my-service"))
// Configure sink
.sink(new DefaultSink(
new DefaultHttpLogFormatter(),
new DefaultHttpLogWriter()))
.build();
```
--------------------------------
### Netty HTTP Server Integration
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/OtherIntegrations.md
Integrates Logbook with Netty HTTP servers using LogbookHttpServerHandler. This example shows how to add the handler to the Netty pipeline.
```java
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer() {
@Override
public void initChannel(SocketChannel ch) {
ch.pipeline().addLast(
new HttpServerCodec(),
new LogbookHttpServerHandler(logbook)
);
}
})
.bind(8080);
```
--------------------------------
### Example ResponseFilter: Remove Body
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Filters.md
An example of a ResponseFilter that removes the response body. This can be used to prevent sensitive data from being logged.
```java
ResponseFilter removeBody = response -> response.withoutBody();
```
--------------------------------
### Creating and Using LogbookFilter with Custom Logbook and Strategy
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/ServletIntegration.md
Shows how to define a custom logging strategy and use it with a custom Logbook instance to create a LogbookFilter.
```java
Strategy strategy = request ->
request.getPath().startsWith("/api") ? request.withBody() : request.withoutBody();
LogbookFilter filter = new LogbookFilter(logbook, strategy);
```
--------------------------------
### Example RequestFilter: Remove Body
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Filters.md
An example of a RequestFilter that removes the request body. This is useful for reducing log size or removing sensitive information.
```java
RequestFilter removeBody = request -> request.withoutBody();
```
--------------------------------
### Custom CorrelationId Generation Example
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Correlation.md
Provides an example implementation of the CorrelationId interface that generates a correlation ID based on a custom header and a UUID.
```java
CorrelationId idGenerator = request -> {
String userId = request.getHeaders().getFirst("X-User-ID");
return userId + "-" + UUID.randomUUID();
};
```
--------------------------------
### Java Example: Masking IDs in Request Paths
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Filters.md
An example PathFilter that replaces numerical IDs in a path with a placeholder like '{id}'. This is useful for anonymizing URLs.
```java
PathFilter maskIds = path -> path.replaceAll("/\\d+/", "/{id}/");
```
--------------------------------
### Logbook.create()
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Logbook.md
Creates a Logbook instance with default configuration. This is a factory method for obtaining a ready-to-use Logbook object.
```APIDOC
## Logbook.create()
### Description
Creates a `Logbook` instance with default configuration. This is a factory method for obtaining a ready-to-use Logbook object.
### Method
`create`
### Parameters
None
### Returns
`Logbook` - A new Logbook instance with sensible defaults
### Example
```java
Logbook logbook = Logbook.create();
```
```
--------------------------------
### Java Example: Masking API Keys in Query Strings
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Filters.md
An example QueryFilter that masks API key values in a query string. This is useful for preventing sensitive information from being logged or exposed.
```java
QueryFilter maskApiKey = query ->
query.replaceAll("api_key=[^&]*", "api_key=***");
```
--------------------------------
### Create Logbook with Custom Configuration
Source: https://github.com/zalando/logbook/blob/main/_autodocs/README.md
Configure Logbook with custom header filters, body filters, and conditions.
```java
Logbook logbook = Logbook.builder()
.headerFilter(headers -> headers.delete("Authorization"))
.bodyFilter(BodyFilters.oauthRequest())
.condition(Conditions.exclude(Conditions.requestTo("/health")))
.build();
```
--------------------------------
### Java Example: Masking Passwords in Form Data
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Filters.md
An example of a BodyFilter that masks password values in URL-encoded form data. This filter is useful for sanitizing sensitive information in request bodies.
```java
BodyFilter maskPasswords = (contentType, body) -> {
if ("application/x-www-form-urlencoded".equals(contentType)) {
return body.replaceAll("password=[^&]*", "password=***");
}
return body;
};
```
--------------------------------
### Creating and Using LogbookFilter with Custom Logbook
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/ServletIntegration.md
Demonstrates creating a custom Logbook instance with header and body filters, then using it to instantiate LogbookFilter.
```java
Logbook logbook = Logbook.builder()
.headerFilter(headers -> headers.delete("Authorization"))
.bodyFilter(BodyFilters.truncate(1000))
.build();
LogbookFilter filter = new LogbookFilter(logbook);
```
--------------------------------
### Integration Testing with Logbook
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/CoreConcepts.md
Demonstrates how to set up and use Logbook in an integration test to verify header filtering. Ensure Logbook is built with the necessary filters before processing requests.
```java
import org.junit.jupiter.api.Test;
import org.zalando.logbook.HttpRequest;
import org.zalando.logbook.Logbook;
class IntegrationTest {
@Test
void testIntegration() {
Logbook logbook = Logbook.builder()
.headerFilter(headers -> headers.delete("Authorization"))
.build();
HttpRequest request = /* test request */;
logbook.process(request).write();
// Verify authorization header filtered
}
}
```
--------------------------------
### Async Servlet Support
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/ServletIntegration.md
Demonstrates how to use Logbook with asynchronous Servlets. Logbook automatically handles async completion, ensuring logs are captured even with asynchronous processing.
```java
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(asyncSupported = true)
public class AsyncServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
AsyncContext context = request.startAsync();
// Logbook automatically handles async completion
context.start(() -> {
try {
// Your async processing
response.getWriter().print("Response");
} catch (IOException e) {
// Handle error
}
});
}
}
```
--------------------------------
### Get Request Attributes
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/HttpRequest.md
Retrieves custom attributes associated with the request, defaulting to an empty map.
```java
default HttpAttributes getAttributes();
```
```java
HttpAttributes attrs = request.getAttributes();
Object userId = attrs.get("userId");
```
--------------------------------
### Configure WebClient for WebFlux Logging
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/SpringIntegration.md
Illustrates the basic setup for configuring Logbook with Spring WebFlux's WebClient. This involves building a WebClient and potentially applying Logbook configurations.
```java
@Configuration
public class WebFluxLogbookConfiguration {
@Bean
public WebClient webClient(Logbook logbook) {
return WebClient.builder()
// Configure logbook for WebFlux
.build();
}
}
```
--------------------------------
### Get Path Component
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/HttpRequest.md
Retrieves the path component of the request URI, such as "/api/users/123".
```java
String getPath();
```
```java
String path = request.getPath();
// e.g., "/users/123"
```
--------------------------------
### Get Host Component
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/HttpRequest.md
Retrieves the host component of the request URI, which can be a hostname or IP address.
```java
String getHost();
```
```java
String host = request.getHost();
// e.g., "api.example.com"
```
--------------------------------
### Get Remote Client Address
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/HttpRequest.md
Retrieves the IP address or hostname of the client making the request.
```java
String getRemote();
```
```java
String remoteAddress = request.getRemote();
// e.g., "192.168.1.100" or "client.example.com"
```
--------------------------------
### Get Message Origin
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/HttpMessage.md
Determines if the message was sent locally by the application or received from a remote source.
```java
Origin origin = message.getOrigin();
if (origin == Origin.LOCAL) {
// This is a request we sent
}
```
--------------------------------
### Unit Testing Formatters in Java
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/CoreConcepts.md
Provides a JUnit test example for unit testing Logbook's HTTP formatters. It shows how to instantiate a formatter, provide mock data for Precorrelation and HttpRequest, and assert the formatted output.
```java
@Test
void testFormatter() {
HttpLogFormatter formatter = new DefaultHttpLogFormatter();
Precorrelation precorr = /* test data */;
HttpRequest request = /* mock */;
String result = formatter.format(precorr, request);
assertThat(result).contains("GET");
assertThat(result).contains("/api/users");
}
```
--------------------------------
### Spring Boot Starter Maven Dependency
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/OtherIntegrations.md
Include the logbook-spring-boot-starter dependency for simplified Spring Boot integration.
```xml
org.zalandologbook-spring-boot-starter
```
--------------------------------
### JSON Response with Plain Text Body
Source: https://github.com/zalando/logbook/blob/main/README.md
Example of a JSON response log where the body is plain text.
```json
{
"origin": "local",
"type": "response",
"correlation": "2d66e4bc-9a0d-11e5-a84c-1f39510f0d6b",
"duration": 25,
"protocol": "HTTP/1.1",
"status": 200,
"headers": {
"Content-Type": ["text/plain"]
},
"body": "Hello world!"
}
```
--------------------------------
### Get Charset
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/HttpMessage.md
Extracts the character encoding from the Content-Type header. Defaults to UTF-8 for JSON, otherwise UTF-8.
```java
Charset charset = message.getCharset();
// e.g., StandardCharsets.UTF_8
```
--------------------------------
### Execute Logbook JMH Benchmark
Source: https://github.com/zalando/logbook/blob/main/logbook-jmh/README.md
Run the Logbook JMH benchmark from the command line and output results in JSON format. Ensure you have Maven installed and the benchmark JAR is built.
```bash
mvn clean package && java -jar logbook-jmh/target/benchmark.jar LogbookBenchmark -rf json
```
--------------------------------
### DefaultCorrelationId Generator Example
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Correlation.md
Illustrates the default implementation for generating unique correlation IDs, typically based on UUIDs.
```java
CorrelationId generator = new DefaultCorrelationId();
String id = generator.generate(request);
// Returns UUID-based ID
```
--------------------------------
### LogstashLogbackSink with Custom Level
Source: https://github.com/zalando/logbook/blob/main/README.md
Java code demonstrating how to initialize LogstashLogbackSink with a specific logging level, such as INFO.
```java
LogstashLogbackSink sink = new LogstashLogbackSink(formatter, Level.INFO);
```
--------------------------------
### DefaultHttpLogFormatter Output Example
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Formatters.md
Demonstrates the typical output format produced by the DefaultHttpLogFormatter for both outgoing requests and incoming responses. This format is line-separated and includes key details like correlation ID, headers, and duration.
```text
Outgoing Request: 3fa85f64-5717-4562-b3fc-2c963f66afa6
Remote: 192.168.1.100
GET /api/users?page=1 HTTP/1.1
Host: api.example.com
Accept: application/json
---
Incoming Response: 3fa85f64-5717-4562-b3fc-2c963f66afa6
Duration: 245 ms
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 456
{...}
```
--------------------------------
### Get Query String
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/HttpRequest.md
Retrieves the query string of the request URI, or an empty string if no query parameters are present.
```java
String getQuery();
```
```java
String query = request.getQuery();
// e.g., "user_id=42&format=json"
```
--------------------------------
### Get HTTP Headers
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/HttpMessage.md
Retrieves the immutable multimap of HTTP headers. Allows access to individual header values.
```java
HttpHeaders headers = message.getHeaders();
String contentType = headers.getFirst("Content-Type");
List acceptValues = headers.get("Accept");
```
--------------------------------
### Get HTTP Protocol Version
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/HttpMessage.md
Retrieves the HTTP protocol version of the message. Defaults to "HTTP/1.1".
```java
String version = message.getProtocolVersion();
// e.g., "HTTP/1.1", "HTTP/2"
```
--------------------------------
### Create LogbookClientHttpRequestInterceptor
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/SpringIntegration.md
Creates an interceptor with a Logbook instance. Use this to initialize the interceptor with a basic Logbook configuration.
```java
Logbook logbook = Logbook.create();
LogbookClientHttpRequestInterceptor interceptor =
new LogbookClientHttpRequestInterceptor(logbook);
```
--------------------------------
### JSON Response with JSON Body Inlined
Source: https://github.com/zalando/logbook/blob/main/README.md
Example of a JSON response log where the body is a JSON object, which is inlined into the log.
```json
{
"origin": "local",
"type": "response",
"correlation": "2d66e4bc-9a0d-11e5-a84c-1f39510f0d6b",
"duration": 25,
"protocol": "HTTP/1.1",
"status": 200,
"headers": {
"Content-Type": ["application/json"]
},
"body": {
"greeting": "Hello, world!"
}
}
```
--------------------------------
### Scalyr Query for Local Requests to Tokeninfo
Source: https://github.com/zalando/logbook/blob/main/docs/scalyr.md
Example Scalyr query to find local requests directed to the 'tokeninfo' endpoint.
```text
$httpOrigin = 'local' $httpUri matches '.*/tokeninfo'
```
--------------------------------
### getScheme()
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/HttpRequest.md
Returns the URI scheme.
```APIDOC
## getScheme()
### Description
Returns the URI scheme.
### Method
```java
String getScheme();
```
### Returns
`String` — Scheme component (e.g., "http" or "https")
### Example
```java
String scheme = request.getScheme();
// e.g., "https"
```
```
--------------------------------
### Create Customized Logbook Instance
Source: https://github.com/zalando/logbook/blob/main/README.md
Use LogbookBuilder to create a customized Logbook instance with specific conditions, filters, and sinks.
```java
Logbook logbook = Logbook.builder()
.condition(new CustomCondition())
.queryFilter(new CustomQueryFilter())
.pathFilter(new CustomPathFilter())
.headerFilter(new CustomHeaderFilter())
.bodyFilter(new CustomBodyFilter())
.requestFilter(new CustomRequestFilter())
.responseFilter(new CustomResponseFilter())
.sink(new DefaultSink(
new CustomHttpLogFormatter(),
new CustomHttpLogWriter()
))
.build();
```
--------------------------------
### Safe Sink Implementation in Java
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/CoreConcepts.md
Provides an example of implementing a 'fail-safe' logging sink. This pattern ensures that logging failures do not disrupt the application's normal operation, logging the error but continuing execution.
```java
// Example: Write safely
Sink safeSink = new Sink() {
@Override
public void write(Precorrelation precorr, HttpRequest req) {
try {
delegate.write(precorr, req);
} catch (IOException e) {
logger.warn("Logging failed, continuing", e);
}
}
};
```
--------------------------------
### Get Content Type
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/HttpMessage.md
Extracts the MIME type from the Content-Type header, excluding the charset. Returns null if the header is absent.
```java
String contentType = message.getContentType();
// For "application/json; charset=utf-8", returns "application/json"
```
--------------------------------
### Create Logbook Instance with Custom Builder
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/Logbook.md
Creates a builder for customizing Logbook configuration. Use this to specify custom sinks, conditions, or body filters.
```java
Logbook logbook = Logbook.builder()
.sink(/* custom sink */)
.condition(/* condition */)
.bodyFilter(/* filter */)
.build();
```
--------------------------------
### Precorrelation Interface
Source: https://github.com/zalando/logbook/blob/main/_autodocs/types.md
Represents correlation information available before a response is received. It provides a unique ID and the start time of the correlation.
```java
@API(status = STABLE)
public interface Precorrelation {
String getId();
Instant getStart();
Correlation correlate();
}
```
--------------------------------
### Applying a Path Filter for Normalization
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/LogbookBuilder.md
Use a path filter to normalize request paths, for example, by replacing specific IDs with a placeholder.
```java
Logbook logbook = Logbook.builder()
.pathFilter(path -> path.replaceAll("/\d+/", "/{id}/"))
.build();
```
--------------------------------
### Body Buffering Trade-off Comparison
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/CoreConcepts.md
Compares the trade-offs between buffering a request body with `withBody()` versus not buffering with `withoutBody()`, highlighting memory footprint, processing speed, and body availability.
```text
withBody() withoutBody()
├─ Request body available ├─ No buffering overhead
├─ Larger memory footprint ├─ Faster processing
├─ Slower initial processing ├─ Body not logged
└─ Body can be logged └─ Suitable for GET/HEAD
```
--------------------------------
### Handling Strategy Processing Failures
Source: https://github.com/zalando/logbook/blob/main/_autodocs/errors.md
Demonstrates how to catch exceptions, such as IOExceptions, that may occur during custom strategy processing in Logbook. This ensures that strategy failures do not halt the application's integration layer.
```java
try {
logbook.process(request, strategy);
} catch (IOException e) {
logger.error("Strategy processing failed", e);
}
```
--------------------------------
### JAX-RS Application Registration
Source: https://github.com/zalando/logbook/blob/main/_autodocs/api-reference/OtherIntegrations.md
Registers Logbook filters for JAX-RS 3.x applications. This example shows how to register both server and client-side filters.
```java
@ApplicationPath("/api")
public class RestApplication extends Application {
@Override
public Set