SAP/cf-java-logging-support

How to add Request Context fields (such as remote_user) on all log message performed in the context of a Request?

Rmulorm opened this issue · 2 comments

Hi.

I would like the logs performed in a context of a request processing to log some fields from the Request Context (such as remote_user).

Let's say I have a controller that calls a service that performs some operation and in the middle of this operation, I want to log if something went wrong. I would like this log on the Kibana to have the field remote_user filled with the user that called the endpoint defined in the controller.
In this project I'm using Spring Security and the authentication is done using JWT tokens from SAP XSUAA.

Is there a configuration that I can make to add this information (and maybe others in the future) to all logs done this way?

Hi Rmulorm,

thank you for reaching out with this issue. Integration with Spring Security is currently not part of cf-java-logging-support. It needs to be implemented by your application. You can leverage the AbstractLoggingFilter from the cf-java-logging-support-servlet. Here is a simple example, how to add a remote user.

public class RemoteUserFilter extends AbstractLoggingFilter {

	@Override
	protected void beforeFilter(HttpServletRequest request, HttpServletResponse response) {
		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

		if (authentication.getPrincipal() instanceof Principal) {
			String currentUser = ((Principal) authentication.getPrincipal()).getName();
			LogContext.add(Fields.REMOTE_USER, currentUser);
		}
	}

	@Override
	protected void cleanup(HttpServletRequest request, HttpServletResponse response) {
		LogContext.remove(Fields.REMOTE_USER);
	}
}

Such an implementation needs to be registered as a servlet filter. See the wiki on customizing request filtering for details: https://github.com/SAP/cf-java-logging-support/wiki/Instrumenting-Servlets#customizing-request-filtering. Note, that the GenerateRequestLogFilter might overwrite that field. So you need to register this filter afterwards.

Great!

I was already following an approach of creating a new Filter to do basically what you suggested, but since you already have this abstract class that enables a standard approach to this I changed my implementation to use it. Thanks!

The only thing a bit different that I've done is instead of using the Authentication from the SecurityContextHolder I've got the remoteUser from the request object, and also implemented logic to read the LOG_REMOTE_USER environment variable to log "redacted" if the variable doesn't exist or is false, so having the same behavior from the remote_user in the request logs.

I'll close the issue.

Thanks again for the quick response and help in this matter.