An extensible Java library for HTTP request and response logging

Overview

Logbook: HTTP request and response logging

Logbook

Stability: Active Build Status Coverage Status Code Quality Javadoc Release Maven Central License

Logbook noun, /lɑɡ bʊk/: A book in which measurements from the ship's log are recorded, along with other salient details of the voyage.

Logbook is an extensible Java library to enable complete request and response logging for different client- and server-side technologies. It satisfies a special need by a) allowing web application developers to log any HTTP traffic that an application receives or sends b) in a way that makes it easy to persist and analyze it later. This can be useful for traditional log analysis, meeting audit 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.

Features

  • Logging: of HTTP requests and responses, including the body; partial logging (no body) for unauthorized requests
  • Customization: of logging format, logging destination, and conditions that request to log
  • Support: for Servlet containers, Apache’s HTTP client, Square's OkHttp, and (via its elegant API) other frameworks
  • Optional obfuscation of sensitive data
  • Spring Boot Auto Configuration
  • Scalyr compatible
  • Sensible defaults

Dependencies

  • Java 8
  • Any build tool using Maven Central, or direct download
  • Servlet Container (optional)
  • Apache HTTP Client (optional)
  • JAX-RS 2.x Client and Server (optional)
  • Netty 4.x (optional)
  • OkHttp 2.x or 3.x (optional)
  • Spring 4.x or 5.x (optional)
  • Spring Boot 1.x or 2.x (optional)
  • logstash-logback-encoder 5.x (optional)

Installation

Add the following dependency to your project:

<dependency>
    <groupId>org.zalando</groupId>
    <artifactId>logbook-core</artifactId>
    <version>${logbook.version}</version>
</dependency>

Additional modules/artifacts of Logbook always share the same version number.

Alternatively, you can import our bill of materials...

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.zalando</groupId>
      <artifactId>logbook-bom</artifactId>
      <version>${logbook.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

... which allows you to omit versions:

<dependency>
    <groupId>org.zalando</groupId>
    <artifactId>logbook-core</artifactId>
</dependency>
<dependency>
    <groupId>org.zalando</groupId>
    <artifactId>logbook-httpclient</artifactId>
</dependency>
<dependency>
    <groupId>org.zalando</groupId>
    <artifactId>logbook-jaxrs</artifactId>
</dependency>
<dependency>
    <groupId>org.zalando</groupId>
    <artifactId>logbook-json</artifactId>
</dependency>
<dependency>
    <groupId>org.zalando</groupId>
    <artifactId>logbook-netty</artifactId>
</dependency>
<dependency>
    <groupId>org.zalando</groupId>
    <artifactId>logbook-okhttp</artifactId>
</dependency>
<dependency>
    <groupId>org.zalando</groupId>
    <artifactId>logbook-okhttp2</artifactId>
</dependency>
<dependency>
    <groupId>org.zalando</groupId>
    <artifactId>logbook-servlet</artifactId>
</dependency>
<dependency>
    <groupId>org.zalando</groupId>
    <artifactId>logbook-spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>org.zalando</groupId>
    <artifactId>logbook-logstash</artifactId>
</dependency>

The logbook logger must be configured to trace level in order to log the requests and responses. With Spring Boot 2 (using Logback) this can be accomplised by adding the following line to your application.properties

logging.level.org.zalando.logbook: TRACE

Usage

All integrations require an instance of Logbook which holds all configuration and wires all necessary parts together. You can either create one using all the defaults:

Logbook logbook = Logbook.create();

or create a customized version using the LogbookBuilder:

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();

Strategy

Logbook used to have a very rigid strategy how to do request/response logging:

  • Requests/responses are logged separately
  • Requests/responses are logged soon as possible
  • Requests/responses are logged as a pair or not logged at all
    (i.e. no partial logging of traffic)

Some of those restrictions could be mitigated with custom HttpLogWriter implementations, but they were never ideal.

Starting with version 2.0 Logbook now comes with a Strategy pattern at its core. Make sure you read the documentation of the Strategy interface to understand the implications.

Logbook comes with some built-in strategies:

Phases

Logbook works in several different phases:

  1. Conditional,
  2. Filtering,
  3. Formatting and
  4. Writing

Each phase is represented by one or more interfaces that can be used for customization. Every phase has a sensible default.

Conditional

Logging HTTP messages and including their bodies is a rather expensive task, so it makes a lot of sense to disable logging for certain requests. A common use case would be to ignore health check requests from a load balancer, or any request to management endpoints typically issued by developers.

Defining a condition is as easy as writing a special Predicate that decides whether a request (and its corresponding response) should be logged or not. Alternatively you can use and combine predefined predicates:

Logbook logbook = Logbook.builder()
    .condition(exclude(
        requestTo("/health"),
        requestTo("/admin/**"),
        contentType("application/octet-stream"),
        header("X-Secret", newHashSet("1", "true")::contains)))
    .build();

Exclusion patterns, e.g. /admin/**, are loosely following Ant's style of path patterns without taking the the query string of the URL into consideration.

Filtering

The goal of Filtering is to prevent the logging of certain sensitive parts of HTTP requests and responses. This usually includes the Authorization header, but could also apply to certain plaintext query or form parameters — e.g. password.

Logbook supports different types of filters:

Type Operates on Applies to Default
QueryFilter Query string request access_token
PathFilter Path request n/a
HeaderFilter Header (single key-value pair) both Authorization
BodyFilter Content-Type and body both json: access_token and refresh_token
form: client_secret and password
RequestFilter HttpRequest request Replace binary, multipart and stream bodies.
ResponseFilter HttpResponse response Replace binary, multipart and stream bodies.

QueryFilter, PathFilter, HeaderFilter and BodyFilter are relatively high-level and should cover all needs in ~90% of all cases. For more complicated setups one should fallback to the low-level variants, i.e. RequestFilter and ResponseFilter respectively (in conjunction with ForwardingHttpRequest/ForwardingHttpResponse).

You can configure filters like this:

Logbook logbook = Logbook.builder()
    .requestFilter(replaceBody(contentType("audio/*"), "mmh mmh mmh mmh"))
    .responseFilter(replaceBody(contentType("*/*-stream"), "It just keeps going and going..."))
    .queryFilter(accessToken())
    .queryFilter(replaceQuery("password", "<secret>"))
    .headerFilter(authorization()) 
    .headerFilter(eachHeader("X-Secret"::equalsIgnoreCase, "<secret>"))
    .build();

You can configure as many filters as you want - they will run consecutively.

Correlation

Logbook uses a correlation id to correlate requests and responses. This allows match-related requests and responses that would usually be located in different places in the log file.

If the default implementation of the correlation id is insufficient for your use case, you may provide a custom implementation:

Logbook logbook = Logbook.builder()
    .correlationId(new CustomCorrelationId())
    .build();

Formatting

Formatting defines how requests and responses will be transformed to strings basically. Formatters do not specify where requests and responses are logged to — writers do that work.

Logbook comes with two different default formatters: HTTP and JSON.

HTTP

HTTP is the default formatting style, provided by the DefaultHttpLogFormatter. It is primarily designed to be used for local development and debugging, not for production use. This is because it’s not as readily machine-readable as JSON.

Request
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!
Response
Outgoing Response: 2d66e4bc-9a0d-11e5-a84c-1f39510f0d6b
Duration: 25 ms
HTTP/1.1 200
Content-Type: application/json

{"value":"Hello world!"}
JSON

JSON is an alternative formatting style, provided by the JsonHttpLogFormatter. Unlike HTTP, it is primarily designed for production use — parsers and log consumers can easily consume it.

Requires the following dependency:

<dependency>
  <groupId>org.zalando</groupId>
  <artifactId>logbook-json</artifactId>
</dependency>
Request
{
  "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!"
}
Response
{
  "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!"
}

Note: Bodies of type application/json (and application/*+json) will be inlined into the resulting JSON tree. I.e., a JSON response body will not be escaped and represented as a string:

{
  "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!"
  }
}
Common Log Format

The Common Log Format (CLF) is a standardized text file format used by web servers when generating server log files. The format is supported via the CommonLogFormatSink:

185.85.220.253 - - [02/Aug/2019:08:16:41 0000] "GET /search?q=zalando HTTP/1.1" 200 -
cURL

cURL is an alternative formatting style, provided by the CurlHttpLogFormatter which will render requests as executable cURL commands. Unlike JSON, it is primarily designed for humans.

Request
curl -v -X GET 'http://localhost/test' -H 'Accept: application/json'
Response

See HTTP or provide own fallback for responses:

new CurlHttpLogFormatter(new JsonHttpLogFormatter());
Splunk

Splunk is an alternative formatting style, provided by the SplunkHttpLogFormatter which will render requests and response as key-value pairs.

Request
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!

Response
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!

Writing

Writing defines where formatted requests and responses are written to. Logbook comes with three implementations: Logger, Stream and Chunking.

Logger

By default, requests and responses are logged with an slf4j logger that uses the org.zalando.logbook.Logbook category and the log level trace. This can be customized:

Logbook logbook = Logbook.builder()
    .sink(new DefaultSink(
            new DefaultHttpFormatter(),
            new DefaultHttpLogWriter())
    .build();
Stream

An alternative implementation is to log requests and responses to a PrintStream, e.g. System.out or System.err. This is usually a bad choice for running in production, but can sometimes be useful for short-term local development and/or investigation.

Logbook logbook = Logbook.builder()
    .sink(new DefaultSink(
            new DefaultHttpFormatter(),
            new StreamHttpLogWriter(System.err)
    ))
    .build();
Chunking

The ChunkingSink will split long messages into smaller chunks and will write them individually while delegating to another sink:

Logbook logbook = Logbook.builder()
    .sink(new ChunkingSink(sink, 1000))
    .build();

Sink

The combination of HttpLogFormatter and HttpLogWriter suits most use cases well, but it has limitations. Implementing the Sink interface directly allows for more sophisticated use cases, e.g. writing requests/responses to a structured persistent storage like a database.

Multiple sinks can be combined into one using the CompositeSink.

Servlet

You’ll have to register the LogbookFilter as a Filter in your filter chain — either in your web.xml file (please note that the xml approach will use all the defaults and is not configurable):

<filter>
    <filter-name>LogbookFilter</filter-name>
    <filter-class>org.zalando.logbook.servlet.LogbookFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>LogbookFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>ASYNC</dispatcher>
</filter-mapping>

or programmatically, via the ServletContext:

context.addFilter("LogbookFilter", new LogbookFilter(logbook))
    .addMappingForUrlPatterns(EnumSet.of(REQUEST, ASYNC), true, "/*"); 

Beware: The ERROR dispatch is not supported. You're strongly advised to produce error responses within the REQUEST or ASNYC dispatch.

The LogbookFilter will, by default, treat requests with a application/x-www-form-urlencoded body not different from any other request, i.e you will see the request body in the logs. The downside of this approach is that you won't be able to use any of the HttpServletRequest.getParameter*(..) methods. See issue #94 for some more details.

Form Requests

As of Logbook 1.5.0, you can now specify one of three strategies that define how Logbook deals with this situation by using the logbook.servlet.form-request system property:

Value Pros Cons
body (default) Body is logged Downstream code can not use getParameter*()
parameter Body is logged (but it's reconstructed from parameters) Downstream code can not use getInputStream()
off Downstream code can decide whether to use getInputStream() or getParameter*() Body is not logged

Security

Secure applications usually need a slightly different setup. You should generally avoid logging unauthorized requests, especially the body, because it quickly allows attackers to flood your logfile — and, consequently, your precious disk space. Assuming that your application handles authorization inside another filter, you have two choices:

  • Don't log unauthorized requests
  • Log unauthorized requests without the request body

You can easily achieve the former setup by placing the LogbookFilter after your security filter. The latter is a little bit more sophisticated. You’ll need two LogbookFilter instances — one before your security filter, and one after it:

context.addFilter("SecureLogbookFilter", new SecureLogbookFilter(logbook))
    .addMappingForUrlPatterns(EnumSet.of(REQUEST, ASYNC), true, "/*");
context.addFilter("securityFilter", new SecurityFilter())
    .addMappingForUrlPatterns(EnumSet.of(REQUEST), true, "/*");
context.addFilter("LogbookFilter", new LogbookFilter(logbook))
    .addMappingForUrlPatterns(EnumSet.of(REQUEST, ASYNC), true, "/*");

The first logbook filter will log unauthorized requests only. The second filter will log authorized requests, as always.

HTTP Client

The logbook-httpclient module contains both an HttpRequestInterceptor and an HttpResponseInterceptor to use with the HttpClient:

CloseableHttpClient client = HttpClientBuilder.create()
        .addInterceptorFirst(new LogbookHttpRequestInterceptor(logbook))
        .addInterceptorFirst(new LogbookHttpResponseInterceptor())
        .build();

Since the LogbookHttpResponseInterceptor is incompatible with the HttpAsyncClient there is another way to log responses:

CloseableHttpAsyncClient client = HttpAsyncClientBuilder.create()
        .addInterceptorFirst(new LogbookHttpRequestInterceptor(logbook))
        .build();
        
// and then wrap your response consumer
client.execute(producer, new LogbookHttpAsyncResponseConsumer<>(consumer), callback)

JAX-RS

The logbook-jaxrs module contains:

A LogbookClientFilter to be used for applications making HTTP requests

client.register(new LogbookClientFilter(logbook));

A LogbookServerFilter for be used with HTTP servers

resourceConfig.register(new LogbookServerFilter(logbook));

Netty

The logbook-netty module contains:

A LogbookClientHandler to be used with an HttpClient:

HttpClient.create()
    .tcpConfiguration(tcpClient ->
        tcpClient.doOnConnected(connection ->
            connection.addHandlerLast(new LogbookClientHandler(logbook))))

A LogbookServerHandler for use used with an HttpServer:

HttpServer.create()
    .tcpConfiguration(tcpServer ->
        tcpServer.doOnConnection(connection ->
            connection.addHandlerLast(new LogbookServerHandler(logbook))))

Spring WebFlux

Users of Spring WebFlux can pick any of the following options:

  • Programmatically create a NettyWebServer (passing an HttpServer)
  • Register a custom NettyServerCustomizer
  • Programmatically create a ReactorClientHttpConnector (passing an HttpClient)
  • Register a custom WebClientCustomizer

Micronaut

Users of Micronaut can follow the official docs on how to integrate Logbook with Micronaut.

⚠️ Even though Quarkus and Vert.x use Netty under the hood, unfortunately neither of them allows accessing or customizing it (yet).

OkHttp v2.x

The logbook-okhttp2 module contains an Interceptor to use with version 2.x of the OkHttpClient:

OkHttpClient client = new OkHttpClient();
client.networkInterceptors().add(new LogbookInterceptor(logbook);

If you're expecting gzip-compressed responses you need to register our GzipInterceptor in addition. The transparent gzip support built into OkHttp will run after any network interceptor which forces logbook to log compressed binary responses.

OkHttpClient client = new OkHttpClient();
client.networkInterceptors().add(new LogbookInterceptor(logbook);
client.networkInterceptors().add(new GzipInterceptor());

OkHttp v3.x

The logbook-okhttp module contains an Interceptor to use with version 3.x of the OkHttpClient:

OkHttpClient client = new OkHttpClient.Builder()
        .addNetworkInterceptor(new LogbookInterceptor(logbook))
        .build();

If you're expecting gzip-compressed responses you need to register our GzipInterceptor in addition. The transparent gzip support built into OkHttp will run after any network interceptor which forces logbook to log compressed binary responses.

OkHttpClient client = new OkHttpClient.Builder()
        .addNetworkInterceptor(new LogbookInterceptor(logbook))
        .addNetworkInterceptor(new GzipInterceptor())
        .build();

Spring

The logbook-spring module contains a ClientHttpRequestInterceptor to use with RestTemplate:

    LogbookClientHttpRequestInterceptor interceptor = new LogbookClientHttpRequestInterceptor(logbook);
    RestTemplate restTemplate = new RestTemplate();
    restTemplate.getInterceptors().add(interceptor);

Spring Boot Starter

Logbook comes with a convenient auto configuration for Spring Boot users. It sets up all of the following parts automatically with sensible defaults:

  • Servlet filter
  • Second Servlet filter for unauthorized requests (if Spring Security is detected)
  • Header-/Parameter-/Body-Filters
  • HTTP-/JSON-style formatter
  • Logging writer

Instead of declaring a dependency to logbook-core declare one to the Spring Boot Starter:

<dependency>
    <groupId>org.zalando</groupId>
    <artifactId>logbook-spring-boot-starter</artifactId>
    <version>${logbook.version}</version>
</dependency>

Every bean can be overridden and customized if needed, e.g. like this:

@Bean
public BodyFilter bodyFilter() {
    return merge(
            defaultValue(), 
            replaceJsonStringProperty(singleton("secret"), "XXX"));
}

Please refer to LogbookAutoConfiguration or the following table to see a list of possible integration points:

Type Name Default
FilterRegistrationBean secureLogbookFilter Based on LogbookFilter
FilterRegistrationBean logbookFilter Based on LogbookFilter
Logbook Based on condition, filters, formatter and writer
Predicate<HttpRequest> requestCondition No filter; is later combined with logbook.exclude and logbook.exclude
HeaderFilter Based on logbook.obfuscate.headers
PathFilter Based on logbook.obfuscate.parameters
QueryFilter Based on logbook.obfuscate.parameters
BodyFilter BodyFilters.defaultValue(), see filtering
RequestFilter RequestFilters.defaultValue(), see filtering
ResponseFilter ResponseFilters.defaultValue(), see filtering
Strategy DefaultStrategy
Sink DefaultSink
HttpLogFormatter JsonHttpLogFormatter
HttpLogWriter DefaultHttpLogWriter

Multiple filters are merged into one.

Autoconfigured beans from logbook-spring

Some classes from logbook-spring are included in the auto configuration.

You can autowire LogbookClientHttpRequestInterceptor with code like:

private final RestTemplate restTemplate;
MyClient(RestTemplateBuilder builder, LogbookClientHttpRequestInterceptor interceptor){
  this.restTemplate = builder
    .additionalInterceptors(interceptor)
    .build();
}

Configuration

The following tables show the available configuration:

Configuration Description Default
logbook.include Include only certain URLs (if defined) []
logbook.exclude Exclude certain URLs (overrides logbook.include) []
logbook.filter.enabled Enable the LogbookFilter true
logbook.filter.form-request-mode Determines how form requests are handled body
logbook.secure-filter.enabled Enable the SecureLogbookFilter true
logbook.format.style Formatting style (http, json, curl or splunk) json
logbook.strategy Strategy (default, status-at-least, body-only-if-status-at-least, without-body) default
logbook.minimum-status Minimum status to enable logging (status-at-least and body-only-if-status-at-least) 400
logbook.obfuscate.headers List of header names that need obfuscation [Authorization]
logbook.obfuscate.paths List of paths that need obfuscation. Check Filtering for syntax. []
logbook.obfuscate.parameters List of parameter names that need obfuscation [access_token]
logbook.write.chunk-size Splits log lines into smaller chunks of size up-to chunk-size. 0 (disabled)
logbook.write.max-body-size Truncates the body up to max-body-size and appends .... -1 (disabled)
Example configuration
logbook:
  include:
    - /api/**
    - /actuator/**
  exclude:
    - /actuator/health
    - /api/admin/**
  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

logstash-logback-encoder

For basic Logback configuraton

appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
   <encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
/appender>

configure Logbook with a LogstashLogbackSink

HttpLogFormatter formatter = new JsonHttpLogFormatter();
LogstashLogbackSink sink = new LogstashLogbackSink(formatter);

for outputs like

{
  "@timestamp" : "2019-03-08T09:37:46.239+01:00",
  "@version" : "1",
  "message" : "GET http://localhost/test?limit=1",
  "logger_name" : "org.zalando.logbook.Logbook",
  "thread_name" : "main",
  "level" : "TRACE",
  "level_value" : 5000,
  "http" : {
     // logbook request/response contents
  }
}

Known Issues

  1. The Logbook Servlet Filter interferes with downstream code using getWriter and/or getParameter*(). See Servlet for more details.
  2. The Logbook Servlet Filter does NOT support ERROR dispatch. You're strongly encouraged to not use it to produce error responses.
  3. The Logbook HTTP Client integration is handling gzip-compressed response entities incorrectly if the interceptor runs before a decompressing interceptor. Since logging compressed contents is not really helpful it's advised to register the logbook interceptor as the last interceptor in the chain.

Getting Help with Logbook

If you have questions, concerns, bug reports, etc., please file an issue in this repository's Issue Tracker.

Getting Involved/Contributing

To contribute, simply make a pull request and add a brief description (1-2 sentences) of your addition or change. For more details, check the contribution guidelines.

Alternatives

Credits and References

Creative Commons (Attribution-Share Alike 3.0 Unported Grand Turk, a replica of a three-masted 6th rate frigate from Nelson's days - logbook and charts by JoJan is licensed under a Creative Commons (Attribution-Share Alike 3.0 Unported).

Comments
  • OutOfMemoryError produced by huge response, that must be excluded.

    OutOfMemoryError produced by huge response, that must be excluded.

    Hello! I catch java.lang.OutOfMemoryError: Java heap space when I download huge text file (70 Mb) and response body become very big. This request (and response correspondingly) was excluded in property file and doesn't appear in log. JVM params are -Xmx256m -Xms128m I tried to use logbook.write.chunk-size with values 10 and 10000 - it didn't work. Here is the error log: https://pastebin.com/ESTUwqZW How can I avoid this exception?

    • Version used: 1.9.0
    Bug Discussion 
    opened by stavskiy 24
  • Spring boot 2.0.1 and logbook 1.7.1 nothing in the log

    Spring boot 2.0.1 and logbook 1.7.1 nothing in the log

    in pom

    <dependency>
                <groupId>org.zalando</groupId>
                <artifactId>logbook-spring-boot-starter</artifactId>
                <version>1.7.1</version>
    </dependency>
    

    In application.properties

    
    # Logbook
    logbook.obfuscate.headers=[Authorization,X-Secret]
    logbook.obfuscate.parameters=[access_token,password]
    logbook.write.level=TRACE
    logbook.write.chunk-size=1000
    logbook.write.category=http.wire-log
    logbook.format.style=http
    logbook.exclude=[/swagger-ui.html]
    logging.level.http.wire-log=DEBUG
    

    Ran the application but nothing print in my log file. Can I create a different log file for logbook?

    opened by erangac 24
  • Fix when request body is empty string

    Fix when request body is empty string

    In Spring Framework, for GET requests the RequestBody is an empty string and throws an error when we want to apply the filter.

    Types of changes

    • [x] Bug fix (non-breaking change which fixes an issue)
    • [ ] New feature (non-breaking change which adds functionality)
    • [ ] Breaking change (fix or feature that would cause existing functionality to change)

    Checklist:

    • [ ] My change requires a change to the documentation.
    • [ ] I have updated the documentation accordingly.
    • [x] I have added tests to cover my changes.
    opened by ismail2ov 23
  • Fix PathNotFoundException when body is unwrapped Array

    Fix PathNotFoundException when body is unwrapped Array

    Fix PathNotFoundException when body is unwrapped Array

    Types of changes

    • [x] Bug fix (non-breaking change which fixes an issue)
    • [ ] New feature (non-breaking change which adds functionality)
    • [ ] Breaking change (fix or feature that would cause existing functionality to change)

    Checklist:

    • [ ] My change requires a change to the documentation.
    • [ ] I have updated the documentation accordingly.
    • [x] I have added tests to cover my changes.
    opened by ismail2ov 22
  • StackOverflow for JsonBodyFilter

    StackOverflow for JsonBodyFilter

    Using a debugger, I built a function that will reproduce it (this is inside com.monese.card.service.config.logbook.JsonBodyFilters#replace inside delegate lambda): Screenshot 2020-01-15 at 20 04 55

    public static void main(String[] args) {
        //com.monese.card.service.config.logbook.JsonBodyFilters#replace
        String STRING = "(?:\"(?:[^\"\\\\]|\\\\.)*\")";
        String value = STRING;
        final Pattern pattern = compile("(?<key>\"(?<property>.*?)\"\\s*:\\s*)(" + value + "|null)");
        String body = "{\"variables\":{},\"query\":\"\\n    query IntrospectionQuery {\\n      __schema {\\n        queryType { name }\\n        mutationType { name }\\n        subscriptionType { name }\\n        types {\\n          ...FullType\\n        }\\n        directives {\\n          name\\n          description\\n          locations\\n          args {\\n            ...InputValue\\n          }\\n        }\\n      }\\n    }\\n\\n    fragment FullType on __Type {\\n      kind\\n      name\\n      description\\n      fields(includeDeprecated: true) {\\n        name\\n        description\\n        args {\\n          ...InputValue\\n        }\\n        type {\\n          ...TypeRef\\n        }\\n        isDeprecated\\n        deprecationReason\\n      }\\n      inputFields {\\n        ...InputValue\\n      }\\n      interfaces {\\n        ...TypeRef\\n      }\\n      enumValues(includeDeprecated: true) {\\n        name\\n        description\\n        isDeprecated\\n        deprecationReason\\n      }\\n      possibleTypes {\\n        ...TypeRef\\n      }\\n    }\\n\\n    fragment InputValue on __InputValue {\\n      name\\n      description\\n      type { ...TypeRef }\\n      defaultValue\\n    }\\n\\n    fragment TypeRef on __Type {\\n      kind\\n      name\\n      ofType {\\n        kind\\n        name\\n        ofType {\\n          kind\\n          name\\n          ofType {\\n            kind\\n            name\\n            ofType {\\n              kind\\n              name\\n              ofType {\\n                kind\\n                name\\n                ofType {\\n                  kind\\n                  name\\n                  ofType {\\n                    kind\\n                    name\\n                  }\\n                }\\n              }\\n            }\\n          }\\n        }\\n      }\\n    }\\n  \"}";
        pattern.matcher(body).find();
    }
    
    Bug Help Wanted 
    opened by Sam-Kruglov 20
  • Duplicate logs when REST API returns HTTP Status Code 401 or 403.

    Duplicate logs when REST API returns HTTP Status Code 401 or 403.

    Duplicate logs when REST API returns HTTP Status Code 401 or 403.

    Description

    We have a REST API that returns HTTP Status Code 401 or 403 when the user does not have permission or authentication issues detected inside the API.

    When we look at the Logbook code, we see that there is a "SecurityStrategy" used for filtering unauthorized request before it comes to REST API. So, Logbook works as expected if we try to call REST API with invalid token which means Secure filter works as designed.

    On the other hand, if I call the REST API with a user who does not have correct permissions, our Spring Security part passes and REST API returns HTTP Status Code 401 when it detects unauthorized access. In this case, Logbook generates duplicate records since first Default Logbook Filter is being executed and then it comes to Secure Logbook Filter and generates same logs again.

    https://github.com/zalando/logbook/blob/668344ee75937820f1f33640fd3df3d66d57065a/logbook-core/src/main/java/org/zalando/logbook/SecurityStrategy.java#L23-L35

    Expected Behavior

    One log for request and one log for response

    Actual Behavior

    Two logs for request and two logs for response

    Possible Fix

    There is a workaround. We can skip Secure Logbook filter if we set flag "logbook.secure-filter.enabled" as false. But in this case, we have logs with bodies (unauthorized requests).

    Steps to Reproduce

    1. Create a Spring Boot Application with a REST API which validates user roles and returns 401 or 403 when permission denied.
    2. Add Logbook dependency to your Spring Boot Application
    3. Call REST API with unauthorized user
    4. Observe in the Console Log that Logbook generates duplicate logs.

    Context

    We have duplicate records in our trace database when REST API returns 401 or 403.

    Bug 
    opened by srknkbs 18
  • Support to Spring Webflux (reactive handlers)

    Support to Spring Webflux (reactive handlers)

    Logbook already has Spring support to traditional controllers model. In Spring Boot 2.X was introduced the reactive programming model with spring-webflux. Would be nice have Logbook support to this approach

    See more details of Webflux here: https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#spring-webflux

    Context

    I use Logbook for many micro-services in my job. We need to integrate Logbook in some reactive webflux services.

    Possible Implementation

    By WebHandler API? -> https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#webflux-web-handler-api

    Thanks for your attention. Greetings!

    Feature 
    opened by atrujillofalcon 16
  • getOutputStream() has already been called for this response - still not completely fixed

    getOutputStream() has already been called for this response - still not completely fixed

    Same problem as #146. Although #146 was fixed, problem is back when I turn on logbook request response logging by adding

    logging.level.org.zalando.logbook=trace
    

    to application.properties.

    Minimal example to reproduce is still prepared here. Revision d46137b contains updated logbook version and the mentioned logging configuration.

    Bug 
    opened by davidjirovec 16
  • LogstashLogbackSink: Replace log.trace with call to HttpLogWriter.write()

    LogstashLogbackSink: Replace log.trace with call to HttpLogWriter.write()

    Being able to provide a custom HttpLogWriter for the LogstashLogbackSink and calling the respective write methods instead of log.trace would increase the configurability.

    Detailed Description

    Replace log.trace in LogstashLogbackSink with calls to a provided HttpLogWriter or the default one

    Context

    This change enables logging of requests on other levels, such as DEBUG, INFO, etc.

    Your Environment

    • Version used: 2.2.0
    Feature Help Wanted Discussion 
    opened by cowulf 15
  • Formatting JSON logs with logstash

    Formatting JSON logs with logstash

    Using LogBook's JsonHttpLogFormatter in conjunction with composite JSON layout of logstash-logback-encoder double escapes the log, like so

    {"@timestamp":"2018-10-04T20:39:49.925-07:00","@version":"1","message":"{\"origin\":\"remote\",\"type\":\"request\", \"correlation\":\"85eff6cd9880ca28\",\"protocol\":\"HTTP/1.1\",\"remote\":\"0:0:0:0:0:0:0:1\",\"method\":\"POST\",\"uri\":\"http://localhost:8080/dummy/log\",\"headers\":{\"Accept\":[\"*/*\"], \"accept-encoding\":[\"gzip, deflate\"]],\"content-length\":[\"18\"],\"Content-Type\":[\"application/json\"],\"Host\":[\"localhost:8080\"]},\"body\":{\"message\" :\"hey\"}}","logger_name":"com.sample.logging", "thread_name":"XNIO-3 task-1","level":"DEBUG","level_value":10000,"x-request-id":"b2441153-86c2-4f62-904e-8debf99a2c66"}
    

    I am looking for suggestions to address this

    One possible way I am experimenting is the use of #tryJson{...} in my appender pattern (as documented here), like so

    {"@timestamp":"2018-10-04T14:33:43.791-07:00","@version":"1","logger_name":"com.sample.logging","jsonMessage":{"origin":"remote","type":"request","correlation":"e6f56834dd25766d","protocol":"HTTP/1.1","remote":"0:0:0:0:0:0:0:1","method":"POST","uri":"http://localhost:8080/dummy/log","headers":{"Accept":["*/*"],"accept-encoding":["gzip, deflate"],"Connection":["keep-alive"],"content-length":["18"],"Content-Type":["application/json"],"Host":["localhost:8080"]},"body":{"message":"hey"}}}
    

    Wondering if there is any other way to accomplish this say by implementing a CustomHttpLogFormatter (which I initially thought but couldn't make progress) or any other way

    opened by ranarula 14
  • OpenFeign support

    OpenFeign support

    Description

    This pull request adds Logbook Interceptor for OpenFeign clients.

    Motivation and Context

    There is no support for OpenFeign and it'd be great to have one.

    Types of changes

    • [ ] Bug fix (non-breaking change which fixes an issue)
    • [x] New feature (non-breaking change which adds functionality)
    • [ ] Breaking change (fix or feature that would cause existing functionality to change)

    Checklist:

    • [x] My change requires a change to the documentation.
    • [ ] I have updated the documentation accordingly.
    • [x] I have added tests to cover my changes.
    opened by sanyarnd 13
  • Bump dependency-check-maven from 6.5.1 to 7.4.3

    Bump dependency-check-maven from 6.5.1 to 7.4.3

    Bumps dependency-check-maven from 6.5.1 to 7.4.3.

    Release notes

    Sourced from dependency-check-maven's releases.

    Version 7.4.3

    Fixed

    • Fixed NPE when analyzing version ranges in NPM (#5158 & #5190)
    • Resolved several FP (#5191)

    See the full listing of changes.

    Version 7.4.2

    Fixed

    • Fixes maven 3.1 compatibility issue (#5152)
    • Fixed issue with invalid node_module paths in some scans (#5135)
    • Fixed missing option to disable the Poetry Analyzer in the CLI (#5160)
    • Fixed missing option to configure the OSS Index URL in the CLI (#5180)
    • Fixed NPE when analyzing version ranges in NPM (#5158)
    • Fixed issue with non-proxy host in the gradle plugin (dependency-check/dependency-check-gradle#298)
    • Resolved several FP

    See the full listing of changes.

    Version 7.4.1

    Fixed

    • Fixed bug when setting the proxy port in gradle (#5123)
    • Fixed issue with invalid node_module paths in some scans (#5127)
    • Resolved several FP

    See the full listing of changes.

    Version 7.4.0

    Added

    • Add support for npm package lock v2 and v3 (#5078)
    • Added experimental support for Python Poetry (#5025)
    • Added a vanilla HTML report for use in Jenkins (#5053)

    Changed

    • Renamed RELEASE_NOTES.md to CHANGELOG.md to be more conventional
    • Optimized checksum calculation to improve performance (#5112)
    • Added support for scanning .NET assemblies when only the dotnet runtime is installed (#5087)
    • Bumped several dependencies

    Fixed

    • Fixed bug when setting the proxy port (#5076)
    • Resolved several FP and FN

    See the full listing of changes.

    ... (truncated)

    Changelog

    Sourced from dependency-check-maven's changelog.

    Version 7.4.3 (2022-12-29)

    Fixed

    • Fixed NPE when analyzing version ranges in NPM (#5158 & #5190)
    • Resolved several FP (#5191)

    See the full listing of changes.

    Version 7.4.2 (2022-12-28)

    Fixed

    • Fixes maven 3.1 compatibility issue (#5152)
    • Fixed issue with invalid node_module paths in some scans (#5135)
    • Fixed missing option to disable the Poetry Analyzer in the CLI (#5160)
    • Fixed missing option to configure the OSS Index URL in the CLI (#5180)
    • Fixed NPE when analyzing version ranges in NPM (#5158)
    • Fixed issue with non-proxy host in the gradle plugin (dependency-check/dependency-check-gradle#298)
    • Resolved several FP

    See the full listing of changes.

    Version 7.4.1 (2022-12-09)

    Fixed

    • Fixed bug when setting the proxy port in gradle (#5123)
    • Fixed issue with invalid node_module paths in some scans (#5127)
    • Resolved several FP

    See the full listing of changes.

    Version 7.4.0 (2022-12-04)

    Added

    • Add support for npm package lock v2 and v3 (#5078)
    • Added experimental support for Python Poetry (#5025)
    • Added a vanilla HTML report for use in Jenkins (#5053)

    Changed

    • Renamed RELEASE_NOTES.md to CHANGELOG.md to be more conventional
    • Optimized checksum calculation to improve performance (#5112)
    • Added support for scanning .NET assemblies when only the dotnet runtime is installed (#5087)
    • Bumped several dependencies

    Fixed

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Fix logging of response with long body in ktor-client

    Fix logging of response with long body in ktor-client

    Description

    Logbook hangs on ByteReadChannel consumption loggingContent.readBytes() during processing of response in ktor client.

    Motivation and Context

    The issue reproduces on responses more than 5000-10000 symbols lenght, which is common data size in real world application. See new test Should log big response with 10000 symbols for reproduction.

    Fix is inspired by the discussion in the task KTOR-2435 opened in ktor bugtracker.

    Types of changes

    • [ x] Bug fix (non-breaking change which fixes an issue)
    • [ ] New feature (non-breaking change which adds functionality)
    • [ ] Breaking change (fix or feature that would cause existing functionality to change)

    Checklist:

    • [ ] My change requires a change to the documentation.
    • [ ] I have updated the documentation accordingly.
    • [ x] I have added tests to cover my changes.
    opened by proton72 0
  • Fix hangs on GET requests to ktor-server

    Fix hangs on GET requests to ktor-server

    Description

    Currently ktor-server hangs on any request without call of methods receive..., for example on GET request processing. For reproduction see test Should log request with not consumed body

    Motivation and Context

    Previous interceptor calls only on body consumption event, but body isn't always required.
    New interceptor pipeline.intercept(ApplicationCallPipeline.Monitoring) runs on any request to the server.

    Type of changes

    Bug fix (non-breaking change which fixes an issue)

    Other changes:

    • I have updated the documentation accordingly.
    • I have added tests to cover my changes.
    opened by proton72 0
  • Bump jersey-bom from 2.34 to 2.38

    Bump jersey-bom from 2.34 to 2.38

    Bumps jersey-bom from 2.34 to 2.38.

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Bump reactor-netty from 1.0.14 to 1.1.1

    Bump reactor-netty from 1.0.14 to 1.1.1

    Bumps reactor-netty from 1.0.14 to 1.1.1.

    Release notes

    Sourced from reactor-netty's releases.

    v1.1.1

    Reactor Netty 1.1.1 is part of 2022.0.1 Release Train.

    This is a recommended update for all Reactor Netty 1.1.x users.

    What's Changed

    :sparkles: New features and improvements

    • Depend on Reactor Core v3.5.1 by @​pderop in de89e707efd85f66185f1fcc29789583107faa8f, see release notes.
    • Depend on Netty v4.1.86.Final by @​violetagg in #2611
    • Depend on Netty QUIC Codec v0.0.34.Final by @​violetagg in #2574
    • Depend on netty-incubator-transport-native-io_uring v0.0.16.Final by @​violetagg in #2575
    • Allow configurable connection provider eviction predicate by @​samueldlightfoot in #2557
    • Support context propagation for ChannelHandler by @​violetagg in #2588
    • Deregister connection pool metrics from Micrometer (or alternate registry) when disposing the connection pool by @​manolama in #2608
    • Add new API AccessLogArgProvider#connectionInformation() for retrieving information related to host/remote address/scheme by @​pderop in #2606

    :lady_beetle: Bug fixes

    :book: Documentation, Tests and Build

    • Documentation:
    • Tests:
      • Ensure the connection is closed at the end of the test by @​violetagg in #2598
      • Add test for ConnectionProvider.Builder#disposeInactivePoolsInBackground by @​violetagg in #2607
    • Build:
      • PRs with label type/test go to Documentation, Tests and Build section of the release notes by @​violetagg in #2609

    :up: Dependency Upgrades

    New Contributors

    Full Changelog: https://github.com/reactor/reactor-netty/compare/v1.1.0...v1.1.1

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Bump netty-bom from 4.1.74.Final to 4.1.86.Final

    Bump netty-bom from 4.1.74.Final to 4.1.86.Final

    Bumps netty-bom from 4.1.74.Final to 4.1.86.Final.

    Commits
    • cde0e2d [maven-release-plugin] prepare release netty-4.1.86.Final
    • fe18adf Merge pull request from GHSA-hh82-3pmq-7frp
    • cd91cf3 Merge pull request from GHSA-fx2c-96vj-985v
    • 7cc8428 fixing some naming and typos that caused wrong value to be updated (#13031)
    • 22d3151 Save promises type pollution due to interface type checks (#12980)
    • 1baf9ef Enable SocketHalfClosedTest for epoll (#13025)
    • 91527ff Correctly handle unresolvable InetSocketAddress when using DatagramChannel (#...
    • b64a6e2 Revert#12888 for potential scheduling problems (#13021)
    • 3bff0be Replace LinkedList with ArrayList (#13016)
    • d24defc WebSocketClientHandshaker: add public accessors for parameters (#13009)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
Releases(2.14.0)
Owner
Zalando SE
The org page for Zalando, Europe's leading online fashion platform. Visit opensource.zalando.com for project stats.
Zalando SE
Logging filters for Spring WebFlux client and server request/responses

webflux-log Logging filters for Spring WebFlux client and server request/responses. Usage To log WebClient request/response, do the following specify

null 10 Nov 29, 2022
The reliable, generic, fast and flexible logging framework for Java.

About logback Thank you for your interest in logback, the reliable, generic, fast and flexible logging library for Java. The Logback documentation can

QOS.CH Sarl 2.6k Jan 7, 2023
tinylog is a lightweight logging framework for Java, Kotlin, Scala, and Android

tinylog 2 Example import org.tinylog.Logger; public class Application { public static void main(String[] args) { Logger.info("Hello

tinylog.org 547 Dec 30, 2022
tinylog is a lightweight logging framework for Java, Kotlin, Scala, and Android

tinylog 2 Example import org.tinylog.Logger; public class Application { public static void main(String[] args) { Logger.info("Hello

tinylog.org 551 Jan 4, 2023
Simple Logging Facade for Java

About SLF4J The Simple Logging Facade for Java (SLF4J) serves as a simple facade or abstraction for various logging frameworks (e.g. java.util.logging

QOS.CH Sarl 2.1k Jan 7, 2023
Highly efficient garbage-free logging framework for Java 8+

Garbage Free Log Highly efficient garbage-free logging framework for Java 8+. Use Add the following dependencies to your project: implementation 'com.

EPAM Systems 37 Dec 12, 2022
Adapts Java platform logging (System.Logger) to SLF4J 1.7.x.

avaje-slf4j-jpl Adapts Java platform logging (System.Logger) to SLF4J 1.7.x. Requires Java 11 or greater. Step 1. Add dependenc

avaje 1 Jan 18, 2022
Log annotation for logging frameworks

Herald "Why, sometimes I've believed as many as six impossible things before breakfast." - Lewis Carroll, Alice in Wonderland. Herald provides a very

Vladislav Bauer 71 Dec 21, 2022
A Java library that facilitates reading, writing and processing of sensor events and raw GNSS measurements encoded according to the Google's GNSS Logger application format.

google-gnss-logger This library facilitates reading, writing and processing of sensor events and raw GNSS measurements encoded according to the Google

Giulio Scattolin 5 Dec 21, 2022
P6Spy is a framework that enables database data to be seamlessly intercepted and logged with no code changes to the application.

p6spy P6Spy is a framework that enables database data to be seamlessly intercepted and logged with no code changes to existing application. The P6Spy

p6spy 1.8k Dec 27, 2022
Best-of-breed OpenTracing utilities, instrumentations and extensions

OpenTracing Toolbox OpenTracing Toolbox is a collection of libraries that build on top of OpenTracing and provide extensions and plugins to existing i

Zalando SE 181 Oct 15, 2022
Logstash - transport and process your logs, events, or other data

Logstash Logstash is part of the Elastic Stack along with Beats, Elasticsearch and Kibana. Logstash is a server-side data processing pipeline that ing

elastic 13.2k Jan 5, 2023
Free and open source log management

Graylog Welcome! Graylog is an open source log management platform. You can read more about the project on our website and check out the documentation

Graylog 6.4k Jan 6, 2023
The Apache Software Foundation 3k Jan 4, 2023
Best-of-breed OpenTracing utilities, instrumentations and extensions

OpenTracing Toolbox OpenTracing Toolbox is a collection of libraries that build on top of OpenTracing and provide extensions and plugins to existing i

Zalando SE 181 Oct 15, 2022
Log sourcing is method of trying to map all the ERROR and WARN logs you have in your system in a cost effective way.

log-sourcing Log sourcing is method of trying to map all the ERROR and WARN logs you have in your system in a cost effective way. The basic idea is th

Shimon Magal 12 Apr 19, 2021
PortalLogger - Logs portals into a text file and in chat

Logs portals into a text file and in chat. Useful if afk flying under bedrock. Feel free to add to your client The logs are stored in .minecraft/ARTEMIS/PortalLogger

null 7 Dec 2, 2022
Java Info Logger

Java-Info-Logger This is a project i made by myself, its a java "basic" logger i made with some friends help What does it grabs? Camera Tokens Future

null 6 Sep 12, 2022
A simple logger for java

A simple logger for java

Sniper10754 5 Nov 20, 2022