MDC for slf4j (with active get method stack)

1. Actively obtaining the method call chain
originally wanted to obtain the call chain of the key method when printing the log. For example, the Dao layer is the key point, then it is possible to obtain which service the method is called by, which controller the service is called by, and What are the parameters passed by these calls, so it is very convenient to locate the problem.
The initial idea is to actively obtain the call stack:
public static void test()
    {
        // Where is this ex defined, what is printed is the stack of which method is called
        Throwable ex = new Throwable();

        StackTraceElement[] stackElements = ex.getStackTrace();

        if(stackElements != null)
        {
            System.out.println(stackElements.length);
            for(int i = 0; i < stackElements.length; i++)
            {
                System.out.println(stackElements[i].getClassName());
                System.out.println(stackElements[i].getFileName());
                System.out.println(stackElements[i].getLineNumber());
                System.out.println(stackElements[i].getMethodName());
            }
        }
    }


Run main directly in the idea and print:
7
com.dd.domain.template.Template
Template.java
194
test
-----------------------------------
com.dd.domain.template.Template
Template.java
165
main
-----------------------------------
sun.reflect.NativeMethodAccessorImpl
NativeMethodAccessorImpl.java
-2
invoke0
-----------------------------------
sun.reflect.NativeMethodAccessorImpl
NativeMethodAccessorImpl.java
39
invoke
-----------------------------------
sun.reflect.DelegatingMethodAccessorImpl
DelegatingMethodAccessorImpl.java
25
invoke
-----------------------------------
java.lang.reflect.Method
Method.java
597
invoke
-----------------------------------
com.intellij.rt.execution.application.AppMain
AppMain.java
134
main
-----------------------------------


If just debug main, print:
2
com.dd.domain.template.Template
Template.java
194
test
-----------------------------------
com.dd.domain.template.Template
Template.java
165
main
-----------------------------------

This also shows that the debug and run startup classes in the idea are different.
There are two problems with this method:
1) The stack can be obtained, but the call parameters cannot be obtained,
2) In addition, the ex must be defined in the "key method" to obtain the method call chain


2. The MDC using slf4j is a After setting the unique UUID in the call chain
, it is determined that a unique UUID is set for a call process through MDC. When a problem occurs, this UUID is returned. Search the log UUID to obtain all the log information of a business call process.

But pay attention:
1) This can only guarantee that the calls in one thread are the same UUID. If other sub-threads are started in the main thread, the sub-threads will not be tracked.
2) MDC uses the Filter of web.xml to filter page requests, but this will also intercept requests for static resources, such as js, css, etc., and do separate filtering as needed, such as:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
    {
        // Exclude .js, .css, .png and other resource files from entering the Filter. Only intercept Controller requests, Controller request url without "."
        if (((HttpServletRequest) request).getRequestURI().contains(".") || ROOT_URL.equals(((HttpServletRequest) request).getRequestURI()))
        {
            chain.doFilter(request, response);
            return;
        }

        try
        {
            /*
             * This code puts the value "UUID" to the Mapped Diagnostic context.
             * Since MDc is a static class, we can directly access it without creating a new object from it.
             * Here, instead of hard coding the user name, the value can be retrieved from a HTTP Request object.
             */
            String uuid = UUID.randomUUID().toString();
            MDC.put("requestUUID", uuid.replaceAll("-", "").toUpperCase());
            chain.doFilter(request, response);
        }
        finally
        {
            MDC.remove("requestUUID");
        }
    }

For specific operation details, please refer to:
http://veerasundar.com/blog/2009/11/log4j-mdc-mapped-diagnostic-context-example-code/
http://logback.qos.ch/manual/mdc.html

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326890445&siteId=291194637
Recommended