`
足至迹留
  • 浏览: 497123 次
  • 性别: Icon_minigender_1
  • 来自: OnePiece
社区版块
存档分类
最新评论

slf4j 的MDC (附带主动获取方法堆栈)

阅读更多
1. 主动获取方法调用链
本来是想能在打印日志时获取关键方法的调用链,比如Dao层是关键点,那能获取这个方法是被哪个Service调用,这个Service又是被哪个Controller调用,并且这些调用传递的参数分别是什么,这样对定位问题就很方便了。
初步设想是通过主动获取调用堆栈:
public static void test()
    {
        // 这个ex定义在哪里,打印出来的就是哪个方法被调用的堆栈
        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());
            }
        }
    }


在idea里直接run main,打印:
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
-----------------------------------


如果只是debug main, 则打印:
2
com.dd.domain.template.Template
Template.java
194
test
-----------------------------------
com.dd.domain.template.Template
Template.java
165
main
-----------------------------------

这也说明idea里debug和run时的启动类不一样。
这种方式有两个问题:
1)能获取到这个堆栈,但不能获取到调用参数,
2)另外这个ex必须定义在“关键方法”里才能获取到方法调用链


2. 使用slf4j的MDC为一个调用链设置唯一标识UUID
后来确定通过MDC来为一个调用流程设置一个唯一UUID,出现问题时返回这个UUID,搜索日志UUID,则可以获取一个业务调用流程所有的日志信息。

但是要注意:
1)这只能保证一个线程内的调用是同一个UUID,如果主线程里又启动了其他子线程,则子线程不会被跟踪。
2)MDC是通过web.xml的Filter来实现过滤页面请求,但这种也会拦截到对静态资源的请求,比如js,css等,根据需要做单独过滤,比如:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
    {
        // 排除.js,.css,.png等资源文件进入Filter。只拦截Controller请求,Controller请求url不带"."
        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");
        }
    }

具体操作详情可以参考:
http://veerasundar.com/blog/2009/11/log4j-mdc-mapped-diagnostic-context-example-code/
http://logback.qos.ch/manual/mdc.html
1
3
分享到:
评论

相关推荐

    slf4j jar包

    org.slf4j.MDC.class org.slf4j.Marker.class org.slf4j.MarkerFactory.class org.slf4j.helpers.BasicMDCAdapter.class org.slf4j.helpers.BasicMarker.class org.slf4j.helpers.BasicMarkerFactory.class org.slf4...

    log4j + slf4j-api + slf4j-log4j12

    SLF4J API的使用则是在代码中引入相应的依赖,并通过SLF4J的LoggerFactory获取Logger对象进行日志记录。 总的来说,`log4j`、`SLF4J`和`slf4j-log4j12`的结合,为Java应用程序提供了一种高效、可扩展且灵活的日志...

    开发工具 slf4j-api-1.7.22

    开发工具 slf4j-api-1.7.22开发工具 slf4j-api-1.7.22开发工具 slf4j-api-1.7.22开发工具 slf4j-api-1.7.22开发工具 slf4j-api-1.7.22开发工具 slf4j-api-1.7.22开发工具 slf4j-api-1.7.22开发工具 slf4j-api-1.7.22...

    slf4j中的MDC

    MDC,全称Mapped Diagnostic Context,是SLF4J提供的一种上下文诊断功能,用于存储线程相关的诊断信息。在多线程环境中,MDC能够帮助我们跟踪和记录每个请求或事务的相关信息,这对于调试和监控非常有用。 MDC的...

    slf4j-1.7.21所有相关jar包

    该压缩包中包含以下内容: 1、jcl-over-slf4j-1.7.21.jar 2、jcl-over-slf4j-1.7.21-sources.jar 3、jul-to-slf4j-1.7.21.jar 4、jul-to-slf4j-1.7.21-sources.jar 5、log4j-over-slf4j-1.7.21.jar 6、log4j-over-...

    最新slf4j-1.7.21.zip源码和jar包

    1、jcl-over-slf4j-1.7.21.jar 2、jcl-over-slf4j-1.7.21-sources.jar 3、jul-to-slf4j-1.7.21.jar 4、jul-to-slf4j-1.7.21-sources.jar 5、log4j-over-slf4j-1.7.21.jar 6、log4j-over-slf4j-1.7.21-sources....

    slf4j-log4j12-1.7.12.jar、slf4j-api-1.7.12.jar

    "slf4j-api-1.7.12.jar"则是SLF4J的核心API库,包含了所有SLF4J的日志记录方法和接口,但不包含任何实际的日志实现。 在Java项目中,通常需要同时包含这两个JAR文件:slf4j-api-1.7.12.jar(提供接口)和slf4j-log4...

    slf4j-api.jar和slf4j-nop.jar打包下载

    压缩包内的文件名称列表中,"slf4j-api-1.5.8.jar"是SLF4J API的1.5.8版本,而"slf4j-nop-1.5.8.jar"则是SLF4J NOP实现的同版本。这两个JAR文件通常会一起使用,API JAR提供日志接口,NOP JAR作为默认的日志实现。...

    最新slf4j-1.7.25.zip源码和jar包

    1.7.21-sources.jar 7、osgi-over-slf4j-1.7.21.jar 8、osgi-over-slf4j-1.7.21-sources.jar 9、slf4j-android-1.7.21.jar 10、slf4j-android-1.7.21-sources.jar 11、slf4j-api-1.7.21.jar 12、slf4j-api-1.7.21-...

    slf4j-api-1.7.12.jar slf4j-log4j12-1.7.12.jar

    SLF4J(Simple Logging Facade for...`slf4j-api-1.7.12.jar`和`slf4j-log4j12-1.7.12.jar`分别是SLF4J API和SLF4J到Log4j的绑定,它们共同工作,使开发者能够利用Log4j的强大功能,同时保持代码与具体日志系统的分离。

    slf4j 1.7 所有jar包

    2. **slf4j-ext**:这个模块扩展了SLF4J的基本功能,添加了一些特殊的功能,例如MDC(Mapped Diagnostic Context)、NDC(Nested Diagnostic Context)和异步日志记录。MDC用于存储与日志事件相关的键值对,便于过滤...

    SLF4j中文使用手册

    SLF4J中文使用手册详细地介绍了SLF4J的使用方法、版本更新以及与其他日志框架的集成方式。手册中提到的slf4j-api-1.7.19.jar是一个必须包含在类路径中的依赖库,以支持SLF4J运行。从1.6.0版本开始,如果SLF4J在类...

    slf4j最新jar包下载和jar包

    SLF4J(Simple Logging Facade for Java)是Java中的一种日志抽象层,它提供了一个接口,允许用户在运行时动态地绑定到各种具体的日志框架,如Log4j、Java内置的日志或者Logback等。这个设计使得开发者可以在不修改...

    slf4j-1.7.12

    7. **调试和诊断**:SLF4J提供了方便的调试工具,如`MDC`(Mapped Diagnostic Context)和`NDC`(Nested Diagnostic Context),它们可以存储上下文相关的数据,帮助开发者更好地跟踪和理解日志信息。 8. **最佳...

    Java Slf4j依赖包

    Java Slf4j,全称为Simple Logging Facade for Java,是一个为各种日志框架提供一个简单统一的接口,使得最终用户能够在部署时配置他们希望的日志框架。Slf4j允许开发者在部署应用时插入所需的日志实现,无需修改...

    slf4j的jar包(54个)

    1. **slf4j-api.jar**:这是SLF4J的核心API,包含了所有用于日志记录的方法,如`org.slf4j.Logger`和`org.slf4j.LoggerFactory`。 2. **slf4j-log4j12.jar**:这是一个绑定库,它将SLF4J API与Log4j日志实现连接...

    slf4j-api-1.7.26.zip

    描述中提到的"slf4j-api-1.7.26.jar"是SLF4J API的核心库,它包含所有开发者需要使用的接口和类,例如`org.slf4j.Logger`和`org.slf4j.LoggerFactory`。`Logger`接口提供了不同级别的日志记录方法,如`trace()`, `...

    slf4j-1.6.0全套jar包资源,slf4j-api-1.6.0.jar,slf4j-jdk14-1.6.0.jar...

    slf4j-api-1.6.0.jar,slf4j-jdk14-1.6.0.jar,slf4j-log4j12-1.6.0-rc0.jar,slf4j-nop-1.6.0.jar,slf4j-simple-1.6.0.jar

    slf4j-api-1.7.7,slf4j-log4j12-1.7.7

    标题中的"slf4j-api-1.7.7"指的是SLF4J API的1.7.7版本,它是SLF4J的核心组件,包含了SLF4J的日志API定义。这个库提供了日志记录的基本方法,如`Logger logger = LoggerFactory.getLogger(MyClass.class);`和`logger...

Global site tag (gtag.js) - Google Analytics