btrace简介,拦截函数和异常
动态地向目标应用程序的代码注入追踪代码。
JavaComplierApi、JVMTI、Agent、Instrumentation
btrace安装
- 下载
https://github.com/btraceio/btrace/releases/tag/v1.3.11.2 - 解压,设置BTRACE_HOME,添加bin到PATH目录。
btrace拦截一个url参数。
controller代码:
@RestController
@RequestMapping("/btrace")
public class BtraceController {
@RequestMapping("/hello")
public String hello(@RequestParam("name") String name){
return "hello:"+name;
}
}
创建一个java文件,这个btrace命令可以直接运行。
import com.sun.btrace.AnyType;
import com.sun.btrace.BTraceUtils;
import com.sun.btrace.annotations.*;
@BTrace
public class PrintArgsSimple {
@OnMethod(
clazz = "mooc.birdsky.java.performance.Controller.BtraceController" ,
method = "hello",
location = @Location(Kind.ENTRY)
)
public static void anyRead(@ProbeClassName String pcn, @ProbeMethodName String pmn, AnyType[] args){
BTraceUtils.printArray(args);
BTraceUtils.println("pcn"+pcn);
BTraceUtils.println("pmn"+pmn);
}
}
命令行运行这个java文件:btrace pid 脚本文件
btrace 99834 /Users/wangsen/java/performance/src/main/java/mooc/birdsky/java/performance/btrace/PrintArgsSimple.java
在浏览器中访问
http://localhost:8080/btrace/hello?name=tianjing
http://localhost:8080/btrace/hello?name=tianjing2
>btrace 99834 /Users/wangsen/java/performance/src/main/java/mooc/birdsky/java/performance/btrace/PrintArgsSimple.java
[tianjing, ]
pcn:mooc.birdsky.java.performance.Controller.BtraceController
pmn:hello
[tianjing2, ]
pcnmooc.birdsky.java.performance.Controller.BtraceController
btrace 使用方法详解
- 拦截方法
- 拦截时机
- 拦截this、参数、返回值
拦截方法
- 普通方法 @OnMethod(clazz="",method="")
- 构造方法 @OnMethod(clazz="",method="<init>")
拦截时机
- Kind.ENTRY:入口,默认值
- Kind.RETURN:返回
- Kind.THROW:异常
- Kind.Line:行
拦截返回
import com.sun.btrace.AnyType;
import com.sun.btrace.BTraceUtils;
import com.sun.btrace.annotations.*;
@BTrace
public class PrintArgsSimple {
@OnMethod(
clazz = "mooc.birdsky.java.performance.Controller.BtraceController" ,
method = "hello",
location = @Location(Kind.RETURN)
)
public static void ret(@ProbeClassName String pcn, @ProbeMethodName String pmn,@Return String retString)
{
BTraceUtils.println(retString);
BTraceUtils.println("pcn"+pcn);
BTraceUtils.println("pmn"+pmn);
}
}
拦截异常
构造一个异常,try catch捕获,但是没有打印日志,继续执行返回finished。
@RequestMapping("/exception")
public String exception()
{
try{
System.out.println("begin");
System.out.println(1/0);
System.out.println("end");
}catch (Exception e){
}
return "finished";
}
curl localhost8080/btrace/exception
finished
console
begin
此时,相当于这个Exception被吞掉了。下面构造一个btrace脚本,拦截进程中的异常。
package mooc.birdsky.java.performance.btrace;
import com.sun.btrace.BTraceUtils;
import com.sun.btrace.annotations.*;
@BTrace
public class PrintException {
static Throwable currentException;
@OnMethod(
clazz ="java.lang.Throwable",
method="<init>"
)
public static void onthrow1(@Self Throwable self)
{
currentException = self;
}
@OnMethod(
clazz ="java.lang.Throwable",
method="<init>"
)
public static void onthrow1(@Self Throwable self,String s)
{
currentException = self;
}
@OnMethod(
clazz ="java.lang.Throwable",
method="<init>"
)
public static void onthrow1(@Self Throwable self,String s,Throwable cause)
{
currentException = self;
}
@OnMethod(
clazz ="java.lang.Throwable",
method="<init>",
location = @Location(Kind.RETURN)
)
public static void onthrowreturn()
{
if(currentException!=null){
BTraceUtils.jstack(currentException);
BTraceUtils.println("=======================");
currentException=null;
}
}
}
运行btrace命令
btrace 311 /Users/wangsen/java/performance/src/main/java/mooc/birdsky/java/performance/btrace/PrintException.java
输出结果,捕获了java.lang.ArithmeticException: / by zero
。
java.lang.ClassNotFoundException: org.apache.catalina.webresources.WarResourceSet
java.net.URLClassLoader.findClass(URLClassLoader.java:382)
java.lang.ClassLoader.loadClass(ClassLoader.java:424)
java.lang.ClassLoader.loadClass(ClassLoader.java:411)
sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
java.lang.ClassLoader.loadClass(ClassLoader.java:357)
org.apache.catalina.webresources.StandardRoot.isPackedWarFile(StandardRoot.java:656)
org.apache.catalina.webresources.CachedResource.validateResource(CachedResource.java:109)
org.apache.catalina.webresources.Cache.getResource(Cache.java:69)
org.apache.catalina.webresources.StandardRoot.getResource(StandardRoot.java:216)
org.apache.catalina.webresources.StandardRoot.getResource(StandardRoot.java:206)
org.apache.catalina.mapper.Mapper.internalMapWrapper(Mapper.java:1036)
org.apache.catalina.mapper.Mapper.internalMap(Mapper.java:851)
org.apache.catalina.mapper.Mapper.map(Mapper.java:703)
org.apache.catalina.connector.CoyoteAdapter.postParseRequest(CoyoteAdapter.java:695)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:337)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:791)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1417)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:748)
=======================
java.lang.ClassNotFoundException: org.apache.catalina.webresources.AbstractSingleArchiveResourceSet
java.net.URLClassLoader.findClass(URLClassLoader.java:382)
java.lang.ClassLoader.loadClass(ClassLoader.java:424)
java.lang.ClassLoader.loadClass(ClassLoader.java:411)
sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
java.lang.ClassLoader.loadClass(ClassLoader.java:357)
java.lang.ClassLoader.defineClass1(Native Method)
java.lang.ClassLoader.defineClass(ClassLoader.java:763)
java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
java.net.URLClassLoader.access$100(URLClassLoader.java:74)
java.net.URLClassLoader$1.run(URLClassLoader.java:369)
java.net.URLClassLoader$1.run(URLClassLoader.java:363)
java.security.AccessController.doPrivileged(Native Method)
java.net.URLClassLoader.findClass(URLClassLoader.java:362)
java.lang.ClassLoader.loadClass(ClassLoader.java:424)
sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
java.lang.ClassLoader.loadClass(ClassLoader.java:357)
org.apache.catalina.webresources.StandardRoot.isPackedWarFile(StandardRoot.java:656)
org.apache.catalina.webresources.CachedResource.validateResource(CachedResource.java:109)
org.apache.catalina.webresources.Cache.getResource(Cache.java:69)
org.apache.catalina.webresources.StandardRoot.getResource(StandardRoot.java:216)
org.apache.catalina.webresources.StandardRoot.getResource(StandardRoot.java:206)
org.apache.catalina.mapper.Mapper.internalMapWrapper(Mapper.java:1036)
org.apache.catalina.mapper.Mapper.internalMap(Mapper.java:851)
org.apache.catalina.mapper.Mapper.map(Mapper.java:703)
org.apache.catalina.connector.CoyoteAdapter.postParseRequest(CoyoteAdapter.java:695)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:337)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:791)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1417)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:748)
=======================
java.lang.ClassNotFoundException: org.apache.catalina.webresources.AbstractArchiveResourceSet
java.net.URLClassLoader.findClass(URLClassLoader.java:382)
java.lang.ClassLoader.loadClass(ClassLoader.java:424)
java.lang.ClassLoader.loadClass(ClassLoader.java:411)
sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
java.lang.ClassLoader.loadClass(ClassLoader.java:357)
java.lang.ClassLoader.defineClass1(Native Method)
java.lang.ClassLoader.defineClass(ClassLoader.java:763)
java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
java.net.URLClassLoader.access$100(URLClassLoader.java:74)
java.net.URLClassLoader$1.run(URLClassLoader.java:369)
java.net.URLClassLoader$1.run(URLClassLoader.java:363)
java.security.AccessController.doPrivileged(Native Method)
java.net.URLClassLoader.findClass(URLClassLoader.java:362)
java.lang.ClassLoader.loadClass(ClassLoader.java:424)
sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
java.lang.ClassLoader.loadClass(ClassLoader.java:357)
java.lang.ClassLoader.defineClass1(Native Method)
java.lang.ClassLoader.defineClass(ClassLoader.java:763)
java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
java.net.URLClassLoader.access$100(URLClassLoader.java:74)
java.net.URLClassLoader$1.run(URLClassLoader.java:369)
java.net.URLClassLoader$1.run(URLClassLoader.java:363)
java.security.AccessController.doPrivileged(Native Method)
java.net.URLClassLoader.findClass(URLClassLoader.java:362)
java.lang.ClassLoader.loadClass(ClassLoader.java:424)
sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
java.lang.ClassLoader.loadClass(ClassLoader.java:357)
org.apache.catalina.webresources.StandardRoot.isPackedWarFile(StandardRoot.java:656)
org.apache.catalina.webresources.CachedResource.validateResource(CachedResource.java:109)
org.apache.catalina.webresources.Cache.getResource(Cache.java:69)
org.apache.catalina.webresources.StandardRoot.getResource(StandardRoot.java:216)
org.apache.catalina.webresources.StandardRoot.getResource(StandardRoot.java:206)
org.apache.catalina.mapper.Mapper.internalMapWrapper(Mapper.java:1036)
org.apache.catalina.mapper.Mapper.internalMap(Mapper.java:851)
org.apache.catalina.mapper.Mapper.map(Mapper.java:703)
org.apache.catalina.connector.CoyoteAdapter.postParseRequest(CoyoteAdapter.java:695)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:337)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:791)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1417)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:748)
=======================
java.lang.ArithmeticException: / by zero
mooc.birdsky.java.performance.Controller.BtraceController.exception(BtraceController.java:20)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897)
javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:791)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1417)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:748)
=======================
java.io.EOFException
org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1208)
org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.read(NioEndpoint.java:1142)
org.apache.coyote.http11.Http11InputBuffer.fill(Http11InputBuffer.java:729)
org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:352)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:294)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:791)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1417)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:748)
=======================
java.io.EOFException
org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1208)
org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.read(NioEndpoint.java:1142)
org.apache.coyote.http11.Http11InputBuffer.fill(Http11InputBuffer.java:729)
org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:352)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:294)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:791)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1417)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:748)
网友评论