Git Product home page Git Product logo

logger-java's Introduction

resurfaceio-logger-java

Easily log API requests and responses to your own security data lake.

Maven Central CodeFactor License Contributing

Contents

Requires Java 8+ and Java servlet classes, which are not included. No other dependencies to conflict with your app.

Add this section to pom.xml:

<dependency>
    <groupId>io.resurface</groupId>
    <artifactId>resurfaceio-logger</artifactId>
    <version>2.2.0</version>
</dependency>

Add this section too if servlet classes are not already available.

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>RELEASE</version>
</dependency>

After installing the library, add a logging filter to web.xml.

<filter>
    <filter-name>HttpLoggerForServlets</filter-name>
    <filter-class>io.resurface.HttpLoggerForServlets</filter-class>
    <init-param>
        <param-name>url</param-name>
        <param-value>http://localhost:7701/message</param-value>
    </init-param>
    <init-param>
        <param-name>rules</param-name>
        <param-value>include debug</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>HttpLoggerForServlets</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Add a CDATA section when specifying multiple rules at once like this:

    <init-param>
        <param-name>rules</param-name>
        <param-value><![CDATA[
            include debug
            sample 10
        ]]></param-value>
    </init-param>

After installing the library, configure a FilterRegistrationBean to add a logging servlet filter.

@Bean
public FilterRegistrationBean httpLoggerFilter() {
    FilterRegistrationBean frb = new FilterRegistrationBean();
    frb.setFilter(new io.resurface.HttpLoggerForServlets());
    frb.setName("HttpLoggerForServlets");
    frb.addUrlPatterns("/*");
    frb.addInitParameter("url", "http://localhost:7701/message");
    frb.addInitParameter("rules", "include debug");
    return frb;
}

After installing the library, create a logger and call it from the routes of interest.

import io.resurface.*;

HttpLogger logger = new HttpLogger("http://localhost:7701/message", "include debug");

get("/hello", (request, response) -> {
    String response_body = "Hello World";
    HttpMessage.send(logger, request.raw(), response.raw(), response_body);
    return response_body;
});

post("/hello_post", (request, response) -> {
    String response_body = "POSTED: " + request.body();
    HttpMessage.send(logger, request.raw(), response.raw(), response_body, request.body());
    return response_body;
});

Alternatively configure an after filter to log across multiple routes at once.

after((request, response) -> {
    if (response.body() != null) {  // log successful responses only, not 404/500s
        HttpMessage.send(logger, request.raw(), response.raw(), response.body(), request.body());
    }
});

After installing the library, register a logger as a Jersey filter/interceptor. Note this will only log usage when a response body is returned.

ResourceConfig resourceConfig = new ResourceConfig(...);
resourceConfig.register(new io.resurface.HttpLoggerForJersey("http://localhost:7701/message", "include debug"));
HttpServer server = GrizzlyHttpServerFactory.createHttpServer(BASE_URI, resourceConfig, false);

Loggers can be directly integrated into your application using our API. This requires the most effort compared with the options described above, but also offers the greatest flexibility and control.

API documentation

Loggers always have an active set of rules that control what data is logged and how sensitive data is masked. All of the examples above apply a predefined set of rules (include debug), but logging rules are easily customized to meet the needs of any application.

Logging rules documentation


ยฉ 2016-2024 Graylog, Inc.

logger-java's People

Contributors

anyesh avatar dependabot[bot] avatar monrax avatar robdickinson avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Forkers

njari

logger-java's Issues

Validate json in unit tests

Unit tests currently include formatting, so they break if fields are reordered, and it's too easy to introduce a formatting error (like missing a comma or having an extra comma).

Use colon as separator in JSON keys

Using periods as separators in JSON keys makes parsing with regular expressions more difficult than it needs to be (since period is a special character and has to be escaped).

Test case-sensitivity for key headers

Headers are supposed to be case-insensitive, but these cases aren't all being tested. Give special attention to cases where special headers like content type are read.

Classes using headers:

  • HttpLoggerForServlets.java
  • HttpServletRequestImpl.java
  • HttpServletResponseImpl.java
  • LoggedRequestWrapper.java

Move junit tests to separate package

Seeing a lot of "xxx can be packagelocal" warnings in IntelliJ for what are intended to be public methods. Would be preferable to have junit tests in a io.resurface.tests package so that automated tests aren't package local. Then anything showing up with a "packagelocal" warning indicates that the variable or method isn't being touched by automated tests.

Skip servlet filter processing if logger disabled

HttpLoggerForServlets should check logger.isEnabled before creating a LoggedResponseWrapper instance. If the logger is disabled, the original request and response should be passed through the filter chain without any further processing.

Response PrintWriter not working properly

The LoggedResponseWrapper seems to be working for streams, but not for writer cases.

This works:

    LoggedResponseWrapper w = new LoggedResponseWrapper(Mocks.mockResponse());
    w.getOutputStream().write(1);
    assertTrue("output stream wrote stuff", w.logged().length > 0);

This fails:

    LoggedResponseWrapper w = new LoggedResponseWrapper(Mocks.mockResponse());
    w.getWriter().println("asdf1234");
    assertTrue("print writer wrote stuff", w.logged().length > 0);

Optimize performance for servlet logger

  • Logger returned by HttpLoggerFactory.get can be cached as an instance variable
  • If logger is not active, pass request/response through to chain without using LoggedResponseWrapper (and no buffering via LoggedOutputStream)

NOTE: Should require no changes to APIs or test cases to complete.

Send compressed messages

Use raw deflate compression by default, add getSkipCompression/setSkipCompression runtime property

New format & log method signatures

Order params based on frequency of data:
request, response
request, response, response_body
request, response, response_body, request_body
request, response, response_body, request_body, now

JsonMessage should check for null params

JsonMessage should protect against any null data sourced from the application request/response, specifically the key & value params. Other params like the json buffer and those sourced from fields maintained by the logger (category, agent, version) don't need additional null checks.

Exception after form post

http://localhost:8080/examples/servlets/servlet/RequestParamExample

Works fine as long as a value is supplied for both first and last name. If either is left blank, then the following exception occurs:

java.lang.ArrayIndexOutOfBoundsException: 1
	io.resurface.LoggedRequestWrapper.parseParameters(LoggedRequestWrapper.java:116)
	io.resurface.LoggedRequestWrapper.getParameter(LoggedRequestWrapper.java:43)
	RequestParamExample.doGet(RequestParamExample.java:75)
	RequestParamExample.doPost(RequestParamExample.java:108)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	io.resurface.HttpLoggerForServlets.process(HttpLoggerForServlets.java:79)
	io.resurface.HttpLoggerForServlets.doFilter(HttpLoggerForServlets.java:59)
	org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:108)

Servlet filter not assuming correct default character encoding

In HttpLoggerForServlets.process() and LoggedRequestWrapper.parseParameters(), the character encoding is defaulted to null when the encoding is not explicitly specified. According to the servlet specification, the default character encoding should be assumed to be ISO-8859-1 by default.

https://wiki.apache.org/tomcat/FAQ/CharacterEncoding

This was found when testing on Tomcat -- when the SetCharacterEncodingFilter is disabled, HttpLoggerForServlets misses logging request bodies, since when no character encoding is present, no LoggedRequestWrapper is applied. This defect is relatively harmless since this doesn't prevent the application from working properly, nor other details besides request body from being logged properly.

Spark 404 captured as 200

Using test-spark-heroku, configured with an after filter, make an invalid request resulting in a 404. This is logged as a 200.

Recommend Projects

  • React photo React

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

  • Vue.js photo Vue.js

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

  • Typescript photo Typescript

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

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

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

  • web

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

  • server

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

  • Machine learning

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

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

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

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.