簡體   English   中英

使用 ByteBuddy 檢測另一個 java 代理

[英]Using ByteBuddy to instrument another java agent

我使用Elastic APM 代理作為 Java 代理來監控 spring 引導微服務中各種方法的使用情況。 這一切都很好,我們能夠在 Kibana 中繪制各種指標。 不幸的是,它沒有做的是始終將相同的標簽附加到事務中的所有跨度,例如發出原始請求的用戶的詳細信息。

為了解決這個問題,我認為我可以使用 ByteBuddy(我以前從未使用過)來包裝 APM Span class 的任何用法,並將該信息(因為它可以從 ThreadLocal 輕松獲得)附加到每個實例。 但是,我在訪問 Span class 時遇到問題,因為它位於 APM Java 代理中,並且使用以下代碼我得到以下日志,其中似乎無法找到 Span ZA2F2ED4F8EBC2CBB4C21A29DC4...

        Instrumentation instrumentation = ByteBuddyAgent.install();
        new AgentBuilder.Default()
                .with(debuggingListener)
                .ignore(ElementMatchers.nameStartsWith("net.bytebuddy."))
                .type(ElementMatchers.named("co.elastic.apm.agent.impl.transaction.Span"), ElementMatchers.isBootstrapClassLoader())
                .transform((builder, type, classLoader, module) -> builder.visit(Advice.to(SpanAdvice.class).on(ElementMatchers.hasMethodName("start"))))
                .installOn(instrumentation);
[Byte Buddy] DISCOVERY co.elastic.apm.agent.impl.transaction.Transaction [null, unnamed module @758a34ce, loaded=false]
[Byte Buddy] IGNORE co.elastic.apm.agent.impl.transaction.Transaction [null, unnamed module @758a34ce, loaded=false]
[Byte Buddy] COMPLETE co.elastic.apm.agent.impl.transaction.Transaction [null, unnamed module @758a34ce, loaded=false]
[Byte Buddy] DISCOVERY co.elastic.apm.agent.impl.transaction.Transaction$1 [null, unnamed module @758a34ce, loaded=false]
[Byte Buddy] IGNORE co.elastic.apm.agent.impl.transaction.Transaction$1 [null, unnamed module @758a34ce, loaded=false]
[Byte Buddy] COMPLETE co.elastic.apm.agent.impl.transaction.Transaction$1 [null, unnamed module @758a34ce, loaded=false]
[Byte Buddy] DISCOVERY co.elastic.apm.agent.impl.transaction.AbstractSpan$ChildDurationTimer [null, unnamed module @758a34ce, loaded=false]
[Byte Buddy] IGNORE co.elastic.apm.agent.impl.transaction.AbstractSpan$ChildDurationTimer [null, unnamed module @758a34ce, loaded=false]
[Byte Buddy] COMPLETE co.elastic.apm.agent.impl.transaction.AbstractSpan$ChildDurationTimer [null, unnamed module @758a34ce, loaded=false]
[Byte Buddy] DISCOVERY co.elastic.apm.agent.impl.transaction.SpanCount [null, unnamed module @758a34ce, loaded=false]
[Byte Buddy] IGNORE co.elastic.apm.agent.impl.transaction.SpanCount [null, unnamed module @758a34ce, loaded=false]
[Byte Buddy] COMPLETE co.elastic.apm.agent.impl.transaction.SpanCount [null, unnamed module @758a34ce, loaded=false]
[Byte Buddy] DISCOVERY co.elastic.apm.agent.impl.transaction.TraceState$TextTracestateAppender [null, unnamed module @758a34ce, loaded=false]
[Byte Buddy] IGNORE co.elastic.apm.agent.impl.transaction.TraceState$TextTracestateAppender [null, unnamed module @758a34ce, loaded=false]
[Byte Buddy] COMPLETE co.elastic.apm.agent.impl.transaction.TraceState$TextTracestateAppender [null, unnamed module @758a34ce, loaded=false]

我已經嘗試將 ByteBuddy 用於我自己的類,並且一切正常,但我對哪個類加載器加載了什么以及如何將 ByteBuddy 指向它們感到非常困惑。

如果目標是將標簽附加到多個跨度的事務,則使用Elastic APM 中的公共 API 用於 Java是更好的選擇,而不是使用 ByteBuddy 檢測 JVM。 您將有更多的自由來做您想做的事,而無需依賴黑客攻擊。 僅供參考,Java 的 Elastic APM 代理已經為 JVM 配備了額外的字節碼,因此您正在做的事情可能會因此變得更加混亂。

或者,您也可以使用OpenTracing Bridge在事務中設置標簽。

免責聲明:這個答案現在是一個存根。

您應該首先嘗試像里卡多建議的那樣探索一種更規范的做事方式。 如果由於某種原因不起作用,那么我們可以探索檢測您的代理 class 的方法 - 不是因為我認為這是一個好主意,而是因為它在技術上很有趣。

基本上,我們必須確定在您的 ByteBuddy 代理激活之前,您想要檢測的 class 是否已經加載。 那么你將不得不使用 class 重新轉換而不是重新定義。 您必須確保您應用的建議可以完成其工作,而無需更改 class 結構的方法簽名和字段。

  .disableClassFormatChanges()
  .with(RETRANSFORMATION)

您還需要確保通知和 ByteBuddy 對其他代理的類加載器可見,例如,將兩者都放在引導 class 路徑上。 但是,我們不要超越自己。 請先探索里卡多的想法。

暫無
暫無

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

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