简体   繁体   中英

How to wrap variable over Log4j2 with SL4J

Currently, my app needs some values that should be appended to the log message. Since it's using Log4J2 under SL4J, my first thought was to do a wrapper to the Log4J logger where I could add the new value to the output.

Some blogs pointed I should write a Logger, a LoggerFactory and a Binder. But they are pretty outdated (2011) and no hope to have those codes working with current lib.

I saw also something regarding a ThreadContext that look like what I want to build this test.

So my question is what is the most practical (easy) way to extend the logging mechanism and have some variable I can put/or recover from ThreadContext through this wrapper right in the beginning of log message.

logger.info("this is a message"); // Custom logger looks the same as usual

but internally it work with some ThreadContext to increment the log message.

@Override
public void info(final String format) {
    // get some value from ThreadContext
    // add some value that not exist on ThreadContext
    // use it on format string
    // format = container_name + " - " + GUUID + " - " + format;
    logger.logIfEnabled(FQCN, Level.INFO, null, format);
}

CODE

package hello;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.stereotype.*;
import org.springframework.web.bind.annotation.*;

@Controller
@EnableAutoConfiguration
public class SampleController {

    final static Logger logger = LoggerFactory.getLogger(SampleController.class);

    @RequestMapping("/")
    @ResponseBody
    String home() {
        logger.info("this is a message");
        return "Hello World!";
    }

    public static void main(String[] args) throws Exception {
        SpringApplication.run(SampleController.class, args);
    }

}

OUTPUT

17:22:13.718 [http-nio-8080-exec-1] INFO  hello.SampleController - this is a message

DESIRED OUTPUT

17:22:13.718 [http-nio-8080-exec-1] INFO  hello.SampleController - CONTAINERXPTO - 0284-8576-9376-8376 - this is a message

references

http://poth-chola.blogspot.com.br/2015/08/custom-slf4j-logger-adapter.html http://binkley.blogspot.com.br/2010/12/correct-slf4j-logger-wrapping.html http://javaeenotes.blogspot.com.br/2011/12/custom-slf4j-logger-adapter.html

The following blog-post

http://veerasundar.com/blog/2009/11/log4j-mdc-mapped-diagnostic-context-example-code/

describes a solution for transparently adding additional - request releated - information to logging calls.

Edit:

In short, you'll need to add a servlet-filter to your web app which is used to pick up the information you need on a per-request basis.

Inside this filter you can put the informations in a threadlocal map called MDC (Mapped Diagnostic Context)/ThreadContext. An implementation may look like this:

public class RequestInformationFilter implements Filter {

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

        try {
            MDC.put("variableName", "variableValue");

            chain.doFilter(request, response);

        } finally {
            MDC.remove("variableName");
        }

    }

}

Afterwards you can use %X{variableName} in your log pattern to print the value of variableName.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM