簡體   English   中英

如何在帶有附加信息(如參數)的Java中創建自定義stacktrace?

[英]how to create a custom stacktrace in java with additional info (like parameters)?

我被分配了一個任務來創建自定義的堆棧跟蹤,例如將輸出輸出到某些指定函數的日志文件中,但是我不僅要使用類和方法名,還必須輸出參數及其值。

之后,這應該是可以在任何Java項目上運行的單獨的jar。

我什至不知道這種事情是否可能,更不用說從哪里開始了。 任何幫助,將不勝感激。

編輯:還有其他庫通過使用本機VM API來做到這一點: https : //github.com/cretz/stackparam它還修改了Throwable類以始終打印修改后的stacktrace。

我能想到的唯一可能的方法是使用代理和工具化,但是需要將代理添加到啟動命令行中。
然后,我將注冊轉換器以使用ASM庫轉換每個類(記住一些基本的Java類可能已經加載),並將代碼添加到每個方法調用的開頭,以手動跟蹤每個方法類並將其傳遞給將跟蹤它們的我的庫:

// note that parameters names might not exist in runtime if code was compiled without a flag to include them.
public void doSomething(String name, int something) {
    MyLib.enterMethod(ThisClass.class, new MethodSignature(void.class, String.class, int.class), new Argument("name", name), new Argument("something", something));
    try {
        // original code
    } finally { // so we don't need to care about return in the middle of original code or exceptions
        MyLib.exitMethod();
    }
}

enterMethod將調用幀添加到某些隊列中,而exitMethod將刪除最后添加的幀。 請注意,每個線程應該有單獨的隊列,請使用一些Map<Thread, MyFrame>ThreadLocal ,對線程使用一些弱引用可能是個好主意。

然后,您可以使用該隊列中的幀來創建自己的堆棧跟蹤。
但是執行類似的操作可能會大大降低性能-不僅是因為這段代碼的成本,而且將其添加到每個setter / getter中可能會導致這些方法永遠不會被內聯,甚至會進一步影響性能。

因此有可能,但我真的不建議您這樣做。
另外,其他庫添加的其他一些轉換器也可能會影響結果,最好將您的堆棧跟蹤與原始堆棧跟蹤進行比較,以查找所有未轉換的缺失方法(例如本機方法),然后將其添加到堆棧跟蹤中,但沒有這些附加數據。

如果您確實還需要支持本機方法-那么可以創建更高級的轉換器,在調用本機方法之前和之后添加enterMethod / exitMethod

另外,如果這僅用於調試,則可以使用調試API,因此它只能用作調試器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM