0

I am using the sl4j Logger throughout my spring application.

I would like to append a custom string to all log entries (info/trace/debug etc) done throughout the application. This would ideally be done using an Aspect however I am not sure what format the aspect would have. I am assuming something along the lines of

 @Around("org.slf4j.Logger.info(*)")

however i cannot find any reliable way to make this apply to all the methods involved correctly.

mangusbrother
  • 3,988
  • 11
  • 51
  • 103
  • 1
    This is job for [mapped](http://www.slf4j.org/manual.html#mdc) [diagnostic](https://logging.apache.org/log4j/2.x/manual/thread-context.html) [context](http://logback.qos.ch/manual/mdc.html) rather than aspect wrapping. – Pavel Horal Nov 03 '15 at 09:29
  • I need the string to be resolved at the time of the log being made, rather than beforehand as the string would need to change depending on who is calling the log. Can this still be done? – mangusbrother Nov 03 '15 at 10:32
  • 1
    MDC is usually initialized in servlet filter just after you initialize security context. Just google [MDC servlet filter](https://www.google.cz/search?q=mdc+servlet+filter) for some inspiration. Exact configuration depends on what security framework you are using... – Pavel Horal Nov 03 '15 at 17:42
  • @PavelHoral i have posted an answer based on your suggestion. I still have some missing information probably however, I'd be glad if you could help with it :) – mangusbrother Nov 03 '15 at 20:15

1 Answers1

0

As @PavelHoral mentioned The following was the solution using MDC

Create your own filter

import org.slf4j.MDC;

import javax.servlet.*;
import java.io.IOException;

public class MDCLoggingFilter implements Filter {

    @Override
    public void init(final FilterConfig filterConfig) throws ServletException {}

    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {

        MDC.put("myKey", "myValue");

        try {
            chain.doFilter(request, response);
        } finally {
            // remove the key once you are done with it
            MDC.remove("myKey");
        }
    }

    @Override
    public void destroy() {}

}

Then add your filter to your web.xml as follows

<filter>
    <filter-name>mdcLoggingFilter</filter-name>
    <filter-class>path.to.MDCLoggingFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>mdcLoggingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

However, this does not seem to be applying to all my messages. some warnings seem to not be displaying the field. currently investigating.

mangusbrother
  • 3,988
  • 11
  • 51
  • 103
  • Regarding your comment - MDC is implemented via ThreadLocal variables. Can you verify that missing MDC is not in case of ASYNC request (or not related to a request in other way - e.g. scheduled task)? Also be aware that `filter-mapping` is AFAIK just for REQUEST dispatch (if not explicitly specified) and for example it will not be applied in case of ERROR dispatch. And I hope you realize that anything logged before ("above" from the call stack point of view) the filter won't have MDC. – Pavel Horal Nov 03 '15 at 20:55
  • In fact the issue was that some logs are being called from the system not upon request. Hence they are not caught by a filter. An aspect to wrap around uncaught exceptions is present but not around normal log entries carried out by the system. How can these be also tackled? – mangusbrother Nov 04 '15 at 09:36
  • "not upon request" => depends on what is your MDC and what are those logs we are talking about. If these are for example log entries logged during application startup, then there is probably little to no benefit having MDC. If it is authenticated scheduled tasks, you should set up MDC as soon as you set up authentication... etc. – Pavel Horal Nov 04 '15 at 10:19