Spring Boot REST app here. I'm trying to configure Spring Boot request auditing to log each and every HTTP request that any resources/controllers receive with the following info:
- I need to see in the logs the exact HTTP URL (path) that was requested by the client, including the HTTP method and any query string parameters; and
- If there is a request body (such as with a POST or PUT) I need to see the contents of that body in the logs as well
My best attempt so far:
@Component
public class MyAppAuditor {
private Logger logger;
@EventListener
public void handleAuditEvent(AuditApplicationEvent auditApplicationEvent) {
logger.info(auditApplicationEvent.auditEvent);
}
}
public class AuditingTraceRepository implements TraceRepository {
@Autowired
private ApplicationEventPublisher applicationEventPublisher
@Override
List<Trace> findAll() {
throw new UnsupportedOperationException("We don't expose trace information via /trace!");
}
@Override
void add(Map<String, Object> traceInfo) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
AuditEvent traceRequestEvent = new AuditEvent(new Date(), "SomeUser", 'http.request.trace', traceInfo);
AuditApplicationEvent traceRequestAppEvent = new AuditApplicationEvent(traceRequestEvent);
applicationEventPublisher.publishEvent(traceRequestAppEvent);
}
}
However at runtime if I use the following curl command:
curl -i -H "Content-Type: application/json" -X GET 'http://localhost:9200/v1/data/profiles?continent=NA&country=US&isMale=0&height=1.5&dob=range('1980-01-01','1990-01-01')'
Then I only see the following log messages (where MyAppAuditor send audit events):
{ "timestamp" : "14:09:50.516", "thread" : "qtp1293252487-17", "level" : "INFO", "logger" : "com.myapp.ws.shared.auditing.MyAppAuditor", "message" : {"timestamp":"2018-06-29T18:09:50+0000","principal":"SomeUser","type":"http.request.trace","data":{"method":"GET","path":"/v1/data/profiles","headers":{"request":{"User-Agent":"curl/7.54.0","Host":"localhost:9200","Accept":"*/*","Content-Type":"application/json"},"response":{"X-Frame-Options":"DENY","Cache-Control":"no-cache, no-store, max-age=0, must-revalidate","X-Content-Type-Options":"nosniff","Pragma":"no-cache","Expires":"0","X-XSS-Protection":"1; mode=block","X-Application-Context":"application:9200","Date":"Fri, 29 Jun 2018 18:09:50 GMT","Content-Type":"application/json;charset=utf-8","status":"200"}},"timeTaken":"89"}} }
So as you can see, the auditor is picking up the base path (/v1/data/profiles) but is not logging any of the query string parameters. I also see a similar absence of request body info when I hit POST or PUT endpoints that do require a request body (JSON).
What do I need to do to configure these classes (or other Spring classes/configs) so that I get the level of request auditing that I'm looking for?
Fortunately, Actuator makes it very easy to configure those
Traceevents.Adding parameters to Trace info
You can take a look at all of the options. You'll notice the defaults (
line 42) are:So you'll need to also add
Include.PARAMETERSand anything else you'd like to have in the trace. To configure that, there's a configuration property for thatmanagement.trace.include.So to get what you want (i.e.
parameters), plus the defaults, you'd have:management.trace.include = parameters, request-headers, response-headers, cookies, errors, time-takenAdding request body to Trace info
In order to get the
body, you're going to have to add in thisBeanto yourContext:The above code will override the
AutoConfigure'dWebRequestTraceFilterbean (which, because it is@ConditionalOnMissingBeanwill give deference to your custom bean), and pull the extra payload property off of therequestthen add it to to theMapproperties that get published to yourTraceRepository!Summary
TraceRepository trace eventsby via themanagement.trace.includepropertyTraceRepository trace eventsby creating an extendedBeanto read thebodyoff of the HTTP request and supplementing the trace events