- 浏览: 495886 次
- 性别:
- 来自: OnePiece
文章分类
- 全部博客 (196)
- --------- 基础----------- (0)
- java 碎碎念 (12)
- java 并行编程 (11)
- java I/O (6)
- java Charset & Encoding (2)
- spring学习笔记 (8)
- 正则表达式 (5)
- web前端-javascript (11)
- web前端-jQuery (7)
- web前端-碎碎念 (1)
- mybatis (0)
- 数据库-通用 (8)
- 数据库-oracle (20)
- nosql-redis (11)
- nosql-mongoDB (1)
- xml (2)
- log4j (2)
- uml (3)
- web services: soap/wsdl (6)
- soa-tuscany (2)
- linux (6)
- ----------修养----------- (0)
- 深入理解java虚拟机 (7)
- java 设计模式 (9)
- 数据结构和算法 (2)
- 读书笔记--代码整洁之道 (2)
- 计算机基础 (1)
- -----------践行---------- (0)
- 重构(refactor) (7)
- jvm-诊断 (4)
- 数据库-让oracle跑得更快 (7)
- Nginx (6)
- ehcache (2)
- 短信开发 (1)
- Servlet+Filter+Listener (2)
- 运维 (6)
- 问题记录 (38)
- 杂七杂八 (12)
最新评论
-
zhanggang807:
第二种方法比较好
<spring> 定时任务每次都执行两次的问题,慎用new ClassPathXmlApplicationContext() -
assasszt:
谢谢分享,很清楚的讲明了原理。
字符集与字符编码简介 -
su0nils000:
难得的笔记
<进阶-2> 打造高效正则表达式 -
足至迹留:
mini188 写道用MD5来解决碰撞是不是也是可行的呢?个人 ...
Hash简介 -
mini188:
用MD5来解决碰撞是不是也是可行的呢?
Hash简介
1. 主动获取方法调用链
本来是想能在打印日志时获取关键方法的调用链,比如Dao层是关键点,那能获取这个方法是被哪个Service调用,这个Service又是被哪个Controller调用,并且这些调用传递的参数分别是什么,这样对定位问题就很方便了。
初步设想是通过主动获取调用堆栈:
在idea里直接run main,打印:
如果只是debug main, 则打印:
这也说明idea里debug和run时的启动类不一样。
这种方式有两个问题:
1)能获取到这个堆栈,但不能获取到调用参数,
2)另外这个ex必须定义在“关键方法”里才能获取到方法调用链
2. 使用slf4j的MDC为一个调用链设置唯一标识UUID
后来确定通过MDC来为一个调用流程设置一个唯一UUID,出现问题时返回这个UUID,搜索日志UUID,则可以获取一个业务调用流程所有的日志信息。
但是要注意:
1)这只能保证一个线程内的调用是同一个UUID,如果主线程里又启动了其他子线程,则子线程不会被跟踪。
2)MDC是通过web.xml的Filter来实现过滤页面请求,但这种也会拦截到对静态资源的请求,比如js,css等,根据需要做单独过滤,比如:
具体操作详情可以参考:
http://veerasundar.com/blog/2009/11/log4j-mdc-mapped-diagnostic-context-example-code/
http://logback.qos.ch/manual/mdc.html
本来是想能在打印日志时获取关键方法的调用链,比如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
发表评论
-
修改第三方源码并重新打包
2017-02-14 17:05 29561.场景 很多时候需要下载第三方源码修改并重新编译打包,比如m ... -
内部类引发的cglib创建失败
2016-11-22 14:48 15551. 问题描述 使用cglib库 ... -
super用在了匿名内部类里
2016-07-06 09:47 12881.问题描述 本来是重构时在父类里增加了一个protected ... -
<spring-expected at least 1 matching bean> 缺少bean定义
2016-03-04 10:37 14531. 问题描述 ... Error creating bean ... -
《IDEA 循环依赖》Annotation processing is not supported for module cycles.
2015-11-04 16:30 371391. 错误现象 Error:java: Annotation ... -
数据库小问题集合
2015-09-23 14:58 6951. mysql默认查询时,不区分字母大小写。 比如:sele ... -
<spring-aop> BeanNotOfRequiredTypeException 切面异常
2015-07-24 17:59 67201. 问题描述 往工程里添加切面,定义了<aop:asp ... -
【slf+log4j】基础+不同级别日志分别打到不同文件
2015-07-23 11:46 6347通常日志都是基于slf4j+log4j或slf4j+logba ... -
<Spring-Aspect> 切面类(@Aspect)首先必须是bean
2015-07-20 14:08 37291. 问题描述 今天发现老工程里有个日志切面但是总是也没有执行 ... -
<tomcat> 启动报错 Error listenerStart
2015-07-10 09:32 3413今天同事遇到一个tomcat启动失败的问题,日志信息很少,不知 ... -
Intellij IDEA--can't use subversion command line client : svn
2015-06-04 10:45 172361. 错误描述 初用IDEA,暂时感到的还是不适应。导入工程报 ... -
<myeclipse> 修改Source Folder
2015-04-27 16:25 1672MyEclipse工程里新增文件夹时有普通Folder和Sou ... -
<maven> 新工程打包遇到Access restriction
2015-04-27 16:17 11831、错误描述 Access restriction: The ... -
<线程池-定时任务> ScheduledExecutorService之shutdown引发的RejectedExecutionException问题
2015-03-20 21:32 5563一、 问题描述 先来看一下异常信息,启动tomcat时就报错: ... -
<windows, tomcat> tomcat安装为windows服务,查看windows服务器启动时间
2015-03-12 10:47 1648一、tomcat安装为windows服务 1.已经安装好的to ... -
<spring> 定时任务每次都执行两次的问题,慎用new ClassPathXmlApplicationContext()
2015-02-26 14:17 58101.问题描述 singleton的bean,spring配置定 ... -
<java 序列化&反序列化> serialVersionUID的作用(转)
2015-02-11 18:12 1210参考: http://www.strutshome.com/i ... -
<ajax> 给$.post()的回调方法传递多个参数
2015-01-16 14:10 38311.问题描述 想给$.post()的回调方法传递多个参数,如果 ... -
<js,jquery>正则表达式不需要用引号包围
2015-01-04 16:20 1105js或jquery里的正则表达式不能用"" ... -
<js,jquery> each里的continue和break效果
2015-01-04 16:17 750通常js或jquery里each比for用的更多,for循环里 ...
相关推荐
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...
SLF4J API的使用则是在代码中引入相应的依赖,并通过SLF4J的LoggerFactory获取Logger对象进行日志记录。 总的来说,`log4j`、`SLF4J`和`slf4j-log4j12`的结合,为Java应用程序提供了一种高效、可扩展且灵活的日志...
MDC,全称Mapped Diagnostic Context,是SLF4J提供的一种上下文诊断功能,用于存储线程相关的诊断信息。在多线程环境中,MDC能够帮助我们跟踪和记录每个请求或事务的相关信息,这对于调试和监控非常有用。 MDC的...
该压缩包中包含以下内容: 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-...
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-api-1.5.8.jar"是SLF4J API的1.5.8版本,而"slf4j-nop-1.5.8.jar"则是SLF4J NOP实现的同版本。这两个JAR文件通常会一起使用,API JAR提供日志接口,NOP JAR作为默认的日志实现。...
"slf4j-api-1.7.12.jar"则是SLF4J的核心API库,包含了所有SLF4J的日志记录方法和接口,但不包含任何实际的日志实现。 在Java项目中,通常需要同时包含这两个JAR文件:slf4j-api-1.7.12.jar(提供接口)和slf4j-log4...
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(Simple Logging Facade for...`slf4j-api-1.7.12.jar`和`slf4j-log4j12-1.7.12.jar`分别是SLF4J API和SLF4J到Log4j的绑定,它们共同工作,使开发者能够利用Log4j的强大功能,同时保持代码与具体日志系统的分离。
2. **slf4j-ext**:这个模块扩展了SLF4J的基本功能,添加了一些特殊的功能,例如MDC(Mapped Diagnostic Context)、NDC(Nested Diagnostic Context)和异步日志记录。MDC用于存储与日志事件相关的键值对,便于过滤...
SLF4J中文使用手册详细地介绍了SLF4J的使用方法、版本更新以及与其他日志框架的集成方式。手册中提到的slf4j-api-1.7.19.jar是一个必须包含在类路径中的依赖库,以支持SLF4J运行。从1.6.0版本开始,如果SLF4J在类...
SLF4J(Simple Logging Facade for Java)是Java中的一种日志抽象层,它提供了一个接口,允许用户在运行时动态地绑定到各种具体的日志框架,如Log4j、Java内置的日志或者Logback等。这个设计使得开发者可以在不修改...
7. **调试和诊断**:SLF4J提供了方便的调试工具,如`MDC`(Mapped Diagnostic Context)和`NDC`(Nested Diagnostic Context),它们可以存储上下文相关的数据,帮助开发者更好地跟踪和理解日志信息。 8. **最佳...
Java Slf4j,全称为Simple Logging Facade for Java,是一个为各种日志框架提供一个简单统一的接口,使得最终用户能够在部署时配置他们希望的日志框架。Slf4j允许开发者在部署应用时插入所需的日志实现,无需修改...
1. **slf4j-api.jar**:这是SLF4J的核心API,包含了所有用于日志记录的方法,如`org.slf4j.Logger`和`org.slf4j.LoggerFactory`。 2. **slf4j-log4j12.jar**:这是一个绑定库,它将SLF4J API与Log4j日志实现连接...
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 API的1.7.7版本,它是SLF4J的核心组件,包含了SLF4J的日志API定义。这个库提供了日志记录的基本方法,如`Logger logger = LoggerFactory.getLogger(MyClass.class);`和`logger...
描述中提到的"slf4j-api-1.7.26.jar"是SLF4J API的核心库,它包含所有开发者需要使用的接口和类,例如`org.slf4j.Logger`和`org.slf4j.LoggerFactory`。`Logger`接口提供了不同级别的日志记录方法,如`trace()`, `...
SLF4J(Simple Logging Facade for Java)与Log4j12的结合是Java日志处理中的一个常见组合。SLF4J提供了一个抽象层,允许开发人员在不修改代码的情况下切换不同的日志框架,如Log4j、Logback等。而Log4j12则是Apache...