easy-trace - 用于跟蹤應用中所有方法的執行,可以用于調試,也可以用于收集性能數據等

jopen 8年前發布 | 16K 次閱讀 Java開發 easy-trace

easy-trace

用于跟蹤應用中所有方法的執行,可以用于調試,也可以用于收集性能數據等(需擴展)

原理

通過java.lang.instrument提供的premain攔截Class的字節碼, 通過javassist對字節碼進行修改,在需要的方法中插入trace點。 目前支持的trace點:1、before (static)method execute; 2、after (static)method execute; 3、after constructor execute。 為了盡量減少依賴,該項目只依賴javassist 3.20.0-GA版本,該版本支持java8。

目前主要有三個trace的實現類:

ConsoleTraceRecord:trace信息打印到控制臺,默認的方式

FileTraceRecord: trace信息寫入到同一個文件,路徑為./logs/trace.log

FilePerThreadTraceRecord: 每個線程記錄自己的trace信息,路徑為./log/trace_{thread_name}.log

使用方式

1、將easy-trace和javassist的包加入的你class path;

2、在源碼目錄(如src/main/resources)下增加easy-trace.xml文件,并根據你要分析的應用進行配置;

3、啟動應用時:java -javaagent:{easy trace jar path}\easy-trace-0.0.1-SNAPSHOT.jar -jar {your jar}。

注意:該版本目前主要用來查看執行路徑,方便源碼分析,如果需要收集性能數據需要進行擴展。

配置文件說明

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 類和方法的過濾配置 -->
    <class-methods>
        <!-- 排除的系統類 -->
        <exclude-system-class>
        </exclude-system-class>
        <!-- 包括的系統類,優先級高于exclude-system-class -->
        <include-system-class>
        </include-system-class>
        <!-- 排除的用戶類,優先級高于include-user-class -->
        <exclude-user-class>
        </exclude-user-class>
        <!-- 包含的用戶類 -->
        <include-user-class>
            <class-method>
                <class-regex>^io/netty/</class-regex>
                <!-- 不配置則所有方法都可以 -->
                <method-regex></method-regex>
                <!-- 不配置表示所有點都關注,半角逗號分隔,可以配置的范圍: CONSTRUCTOR,METHOD_BEFORE,METHOD_AFTER,STATIC_BEFORE,STATIC_AFTER -->
                <interst>ONSTRUCTOR,METHOD_BEFORE,METHOD_AFTER,STATIC_BEFORE,STATIC_AFTER</interst>
                <!-- 可以將生產的class輸出到該目錄下,用反編譯工具查看: 如D:\code -->
                <wirte-file></wirte-file>
            </class-method>
        </include-user-class>
    </class-methods>

    <!-- trace記錄類 -->
    <trace-records>
        <!-- 不配置默認為ConsoleTraceRecord,可以根據情況配置 -->
        <record-class>com.yam.trace.core.trace.record.ConsoleTraceRecord</record-class>
        <record-class>com.yam.trace.core.trace.record.FileTraceRecord</record-class>
        <!-- 第二種配置方式,默認的消息格式化類是StringMessageFormatter -->
        <record-class-info>
            <record-class>com.yam.trace.core.trace.record.FilePerThreadTraceRecord</record-class>
            <message-formatter-class>com.yam.trace.core.formatter.StringMessageFormatter</message-formatter-class>
        </record-class-info>
    </trace-records>

    <message-filters>
        <!-- 檢測消息的合法性,只能配一項,默認為DefaultMessageCheck -->
        <message-check>com.yam.trace.core.intercept.DefaultMessageCheck</message-check>
        <!-- 后面的幾個配置可以配置多項,內容為正則表達式,exclude優先級高于include -->
        <include-thread-name></include-thread-name>
        <exclude-thread-name></exclude-thread-name>
        <include-message></include-message>
        <exclude-message></exclude-message>
    </message-filters>
</configuration>

輸出示例

以下是netty MpscLinkedQueue類的poll方法執行流程:

2016-01-02 17:10:24.024 nioEventLoopGroup-0-0 ----------------------->begin io.netty.util.internal.MpscLinkedQueue.poll ()Ljava/lang/Object;
2016-01-02 17:10:24.024 nioEventLoopGroup-0-0 ------------------------->begin   io.netty.util.internal.MpscLinkedQueue.peekNode ()Lio/netty/util/internal/MpscLinkedQueueNode;
2016-01-02 17:10:24.024 nioEventLoopGroup-0-0 --------------------------->begin io.netty.util.internal.MpscLinkedQueue.headRef ()Lio/netty/util/internal/MpscLinkedQueueNode;
2016-01-02 17:10:24.024 nioEventLoopGroup-0-0 --------------------------->end   io.netty.util.internal.MpscLinkedQueue.headRef ()Lio/netty/util/internal/MpscLinkedQueueNode; return io.netty.util.internal.MpscLinkedQueue$DefaultNode
2016-01-02 17:10:24.024 nioEventLoopGroup-0-0 --------------------------->begin io.netty.util.internal.MpscLinkedQueue$DefaultNode.next ()Lio/netty/util/internal/MpscLinkedQueueNode;
2016-01-02 17:10:24.024 nioEventLoopGroup-0-0 --------------------------->end   io.netty.util.internal.MpscLinkedQueue$DefaultNode.next ()Lio/netty/util/internal/MpscLinkedQueueNode; return null
2016-01-02 17:10:24.024 nioEventLoopGroup-0-0 --------------------------->begin io.netty.util.internal.MpscLinkedQueue.tailRef ()Lio/netty/util/internal/MpscLinkedQueueNode;
2016-01-02 17:10:24.024 nioEventLoopGroup-0-0 --------------------------->end   io.netty.util.internal.MpscLinkedQueue.tailRef ()Lio/netty/util/internal/MpscLinkedQueueNode; return io.netty.util.internal.MpscLinkedQueue$DefaultNode
2016-01-02 17:10:24.024 nioEventLoopGroup-0-0 ------------------------->end io.netty.util.internal.MpscLinkedQueue.peekNode ()Lio/netty/util/internal/MpscLinkedQueueNode; return null
2016-01-02 17:10:24.024 nioEventLoopGroup-0-0 ----------------------->end   io.netty.util.internal.MpscLinkedQueue.poll ()Ljava/lang/Object; return null


項目地址:
https://github.com/youaremoon/easy-trace

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!