背景介绍:公司使用的网络容器是tomcat,引入了log4j,研发的代码中记录了详细的日志。所有的网页行为包括后套的job定时任务等,都会把日志按定义的级别写入tomcat/log/catalina.out文件中。那么监控该文件,就能捕获可视页面无法感知到的错误。
Linux下使用命令:

1
tail -f catalina.out |grep -C 36 ERROR

该命令实时读取日志文件,把出现“ERROR”行的日志前后各36日志打印出来。

也可以把日志记录到文本中:

1
tail -f catalina.out |grep -C 36 ERROR >>error.log

下面是改命令捕获的一个错误日志,在页面上测试时候,没有弹出任何错误提示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at com.mk.security.SSOFilter.doFilter(SSOFilter.java:221)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:522)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:1110)
<!-- more -->
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:785)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1425)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)

2017-02-07 16:45:14.183 [catalina-exec-80] INFO com.mk.shop.service.ShopService - selectTradeStatisticsMapcom.mk.vo.StatisticsItemVo@3427a14c[date=02-06,ymddate=<null>,num=0,rate=0,ratestr=<null>,uv=0]
2017-02-07 16:45:14.189 [catalina-exec-80] INFO com.mk.shop.service.ShopService - selectTradeStatisticsMapcom.mk.vo.StatisticsItemVo@363f3a3a[date=02-05,ymddate=<null>,num=0,rate=0,ratestr=<null>,uv=0]
2017-02-07 16:45:14.196 [catalina-exec-80] INFO com.mk.shop.service.ShopService - selectTradeStatisticsMapcom.mk.vo.StatisticsItemVo@719b7a9e[date=02-04,ymddate=<null>,num=0,rate=0,ratestr=<null>,uv=0]
2017-02-07 16:45:14.201 [catalina-exec-80] INFO com.mk.shop.service.ShopService - selectTradeStatisticsMapcom.mk.vo.StatisticsItemVo@c80b0d6[date=02-03,ymddate=<null>,num=0,rate=0,ratestr=<null>,uv=0]
2017-02-07 16:45:14.207 [catalina-exec-80] INFO com.mk.shop.service.ShopService - selectTradeStatisticsMapcom.mk.vo.StatisticsItemVo@706dab29[date=02-02,ymddate=<null>,num=0,rate=0,ratestr=<null>,uv=0]
2017-02-07 16:45:14.212 [catalina-exec-80] INFO com.mk.shop.service.ShopService - selectTradeStatisticsMapcom.mk.vo.StatisticsItemVo@6161143e[date=02-01,ymddate=<null>,num=0,rate=0,ratestr=<null>,uv=0]
2017-02-07 16:45:14.219 [catalina-exec-80] ERROR c.m.b.controller.ExceptionResolver - java.lang.NullPointerException
at com.mk.shop.service.ShopService.lambda$selectTradeStatisticsMap$4(ShopService.java:241)
at java.util.TimSort.countRunAndMakeAscending(TimSort.java:355)
at java.util.TimSort.sort(TimSort.java:220)
at java.util.Arrays.sort(Arrays.java:1512)
at java.util.ArrayList.sort(ArrayList.java:1454)
at java.util.Collections.sort(Collections.java:175)
at com.mk.shop.service.ShopService.selectTradeStatisticsMap(ShopService.java:241)
at com.mk.shop.service.ShopService$$FastClassBySpringCGLIB$$99569971.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:711)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
at com.mk.web.aspect.CacheAspect.doArround(CacheAspect.java:61)
at sun.reflect.GeneratedMethodAccessor442.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:68)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644)
at com.mk.shop.service.ShopService$$EnhancerBySpringCGLIB$$6790a1c6.selectTradeStatisticsMap(<generated>)
at com.mk.shop.controller.ShopController.selectTradeStatisticsMap(ShopController.java:161)
at com.mk.shop.controller.ShopController$$FastClassBySpringCGLIB$$8bbcf00f.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:711)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:52)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)

找到日志,提供给开发同学,那么他自然就知道错误是怎么来的。
这个,是研发开发中,调试代码跟踪日志,自然而然发展出来追踪错误的一种办法。对于不懂代码或者对代码一知半解的测试来说,是发现错误一个不错的选择。