Skip to content

liyj144/controller-logger

 
 

Repository files navigation

Controller Logger

createUser() called with arguments: id: [4], name: [Foo] called via url [http://localhost:8080/createUser], username [admin]

CircleCI codecov FOSSA Status

Upcoming release features

  1. Performance improvements
  2. Dependency updates

What is it?

A Java library to ease the life of web developers by providing automatic logging of input-output for controllers. Logged items include all parameters, returned value and some context data such as web request URL and user's username.

Features

  1. Automatically logs all APIs including input and output.
  2. Automatically logs errors occurring in API.
  3. No side-effect in actual API implementation due to AOP logic.
  4. Automatically binds to new APIs thanks to AOP weaving.
  5. Scrubs sensitive information in logs to maintain security and privacy.
  6. Displays file size if one of the API input or output is any file object.
  7. Works with io.github.logger.controller.aspect.integration testing.
  8. Detects mocked objects in input and output and displays them accordingly, as can happen during io.github.logger.controller.aspect.integration testing.
  9. Logging behaviour is easily customizable.

Performance

The code has been through multiple profiling cycles. Each part of the code is intended for maximum performance. No object it serialized if it didn't need to.

Why does it exist?

While working on a project, a Spring-based web application, it quickly became annoying adding the same log statements for each new controller method being created. Working in a team made it inconsistent too with people forgetting or adding unformatted logs. This was the perfect use case for AOP (Aspect Oriented Programming). This library is re-built based on experience gained during my original implementation of AOP based logging.

How can I use this awesome library?

Requirements -

  • Java 8
  • Spring Boot

Through requirements specify Spring Boot, you will be able to use it with classic Spring Framework as well but you'll have to implement weaving manually. This StackOverflow question of mine will be helpful in doing so.

Usage

Example usage of this library can be found here - https://github.com/harshilsharma63/controller-logger-example

Setup

  1. Add dependency from http://www.mvnrepository.com/artifact/io.github.harshilsharma63/controller-logger
  • Gradle

    compile group: 'io.github.harshilsharma63', name: 'controller-logger', version: '1.2.0'
    
  • Maven

    <dependency>
        <groupId>io.github.harshilsharma63</groupId>
        <artifactId>controller-logger</artifactId>
        <version>1.2.0</version>
    </dependency>
    
  1. Add aspect bean in one of the @Configuration classes

     @Bean
     public GenericControllerAspect genericControllerAspect() {
         return new GenericControllerAspect();
     }
    
  2. Enable logging by adding @Logging annotation on controller classes(s)

     @RestController
     @Logging
     public class MyController {
         ...
     }
    

Data Scrubbing

This library supports hiding sensitive information from being logged. As of now, this works only with method arguments but support for arbitrary fields in objects is on the way.

Data scrubbing is enabled by default and it's recommended to keep it that way.

A method parameter is scrubbed if its name falls withing following criteria:

  • Is one of following values (case insensitive):

    • password
    • passwd
    • secret
    • authorization
    • api_key
    • apikey
    • access_token
    • accesstoken
  • Is contained in custom blacklist provided to setCustomParamBlacklist()

  • Matches custom regex provided to setParamBlacklistRegex()

Value of any param matching above mentioned criteria is scrubbed and replaced by "xxxxx". The scrubbed value can be customized as well by passing in the desired value to setDefaultScrubbedValue() method.

A full example with all customization options used:

@Bean
public GenericControllerAspect genericControllerAspect() {
    GenericControllerAspect aspect = new GenericControllerAspect();

    aspect.setEnableDataScrubbing(true);
    aspect.setDefaultScrubbedValue("*******");
    aspect.setParamBlacklistRegex("account.*");
    aspect.setCustomParamBlacklist(new HashSet<>(Arrays.asList("securityProtocol")));
    return aspect;
}

Customization

Logging is controlled by two annotations @Logging and @NoLogging. The two can be used together to achieve fine-grain control over which methods are logged and which aren't.

Both @Logging and @NoLogging annotations can be used on class as well as methods. Method-level annotation takes priority over class-level annotation. This can be used to enable logging for all controller methods and exclude some, or vice-versa.

    @RestController
    @Logging
    public class MyController {
        
        @RequestMapping("/hello")
        public String hello() {
            // logging will work for this method
        }
        
        @RequestMapping("/bye")
        @NoLogging
        public String bye() {
            // logging will not work for this method
        }
        
    }

Further customizations can be done by extending GenericControllerAspect class, or create your own aspect by implementing ControllerAspect interface.

Future Scope

  • Avoid logging sensitive information such as passwords, cookie data, session information.
  • Test with Spring 5
  • Test with Java 9
  • Add unit tests

Packages

No packages published

Languages

  • Java 100.0%