Java 追蹤 SDK

透過使用 Instana Java 追蹤 SDK (github) ,可以手動檢測 Instana 尚不知道的項目和結束程式,以及標記自訂程式碼的感興趣區段。 它也支援跨二進位通訊協定建立自訂相關性,並將自訂定義的鍵值組新增至跨距 (用於擷取相關資訊)。

配置

若要使用配置型 Java 追蹤 SDK ,您需要啟用 Java 追蹤 SDK ,如 啟用及停用 Java 追蹤中所述。

自訂二進位通訊協定的結束程式和項目

已發佈的範例應用程式 (https://github.com/instana/instana-java-sdk/tree/master/instana-java-sdk-sample) 包含 CustomTCP 伺服器及用戶端,說明如何使用 SDK 來標示項目、結束及執行相關性。

使用 instana-java-sdk

Java 追蹤 SDK 需要您將小型 Jar 檔新增至應用程式。 這個 Jar 檔包含註釋和 Helper 類別,用來標記 Instana 應該處理的程式碼區段。 使用 Maven 時,可以輕鬆新增相依關係:

<dependency>
  <groupId>com.instana</groupId>
  <artifactId>instana-java-sdk</artifactId>
  <version>1.2.0</version>
</dependency>

instana-java-sdk 構件可從預設 Maven 中央儲存庫取得。

當沒有任何代理程式在監視 JVM 時 (包括上述程式庫並具有標示註釋的區段) ,則它們會充當 No-Op。 使用註釋是安全的,只要沒有代理程式在監視 JVM ,它們就不會有任何影響。 若要讓 Instana 代理程式實際使用註釋,您必須告訴它哪些 Java 套件名稱具有那些註釋。 這是因為掃描註釋是一項權重的程序,掃描大型應用程式的完整類別路徑可能需要很長時間。

必要的 configuration.yaml 區段如下所示:

# Java Tracing
com.instana.plugin.javatrace:
  instrumentation:
    # By default no packages are scanned for SDK annotations.
    sdk:
      packages:
        - 'com.mycompany.backend'
        - 'com.mycompany.frontend'

會遞迴地掃描套件。 也就是說,如果配置 com.mycompany.backend 來掃描註釋,也會掃描 com.mycompany.backend.impl 和其他子套件。

標示中間項目

如果要在 Intermediat 跨距中標示方法,只需新增下列註釋:

@Span(value = "custom-tcp-server")

Intermediate 是 SDK 跨距的預設類型,如果未指定,則會使用它。 這類跨距在您的應用程式中標示「感興趣」方法,您想要對這些方法有更好的可見性。 請記住,這不會替代實際側寫程式,例如我們的 Instana AutoProfile™

標示項目

如果要在項目跨距中標示方法,只要新增下列註釋即可,如下列 範例所示:

@Span(type = Type.ENTRY, value = "custom-tcp-server")

只要 Instana 看到程式碼進入此方法,即會啟動追蹤。 項目跨距通常指出來自外部系統或排定作業的送入呼叫。

標示結束

如果要在結束文字段中標示方法,只需新增下列註釋,如下列 範例所示:

@Span(type = Type.EXIT, value = "custom-tcp-client", capturedStackFrames = 5)

每當發現此方法時, Instana 會記錄一個將此標示為「結束」呼叫的文字段。 結束程式會標示對外部系統的送出呼叫。

使結束程式與進入項目產生關聯

在許多 Instana 還不知道「結束」和「進入」的情況下,應用程式會使用它們來執行某種遠端通訊。 當發現「結束」且未執行任何相關性時,追蹤會「岔斷」,表示會觀察到兩個追蹤,一個在「結束」結束,另一個在「進入」開始。

您可以透過手動透過遠端通訊傳輸相關性資訊,來協助 Instana 執行相關性。 在結束端,結束註釋將確定必要的相關性 ID 存在。 您可以直接呼叫 (https://github.com/instana/instana-java-sdk/blob/master/instana-java-sdk/src/main/java/com/instana/sdk/support/SpanSupport.java#L182):

SpanSupport.addTraceHeadersIfTracing(Type.EXIT, params);

以必要的 ID 來填入給定的參數對映。 如果通訊協定支援其他傳輸其他資料的方法,則可以使用下列方式來取得 ID:

currentTraceId(type)

currentSpanId(type)

在項目端,在註釋建立跨距之前,請務必先讀取參數並為「項目跨距」設定它們:

(https://github.com/instana/instana-java-sdk/blob/master/instana-java-sdk-sample/custom-http-sample/src/main/java/com/instana/sample/GreetingHandler.java#L52):

SpanSupport.inheritNext(SpanSupport.stringAsId(trace), SpanSupport.stringAsId(span));

這樣做,「進入跨距」會自動結合遠端追蹤,並將本身新增為呼叫「結束程式」的子項跨距。

轉換及命名

在某些狀況下,將 SDK 文字段轉換成不同的類型 (例如 HTTP 或 RPC) 可能有助於更好地代表這些文字段的來源。 這可以透過將轉換標籤新增至文字段來完成,如 自訂追蹤的最佳作法處理標籤 小節中所述。

可以使用 SpanSupport.annotate(type, name, key, value) 方法來設定這些標籤。

Instana 會將這些標籤視為自動代理程式檢測的運作方式,只要這些欄位巢狀內嵌在 tags. 索引鍵下。 因此,舉例來說,如果要設定 http.url 欄位,方法呼叫看起來如下:

SpanSupport.annotate(<type>, <name>, "tags.http.url", "service://my-awesome-service/some/path")

同樣地,也可以依照 自訂追蹤的最佳作法 頁面上的說明來變更服務、端點和呼叫名稱。

當未提供任何特定欄位時,所有 SDK 文字段的服務名稱將會是 SDK。 端點和呼叫名稱將是 @Span 註釋或 SpanSupport.annotate() 方法中的給定 name

儲存及還原追蹤環境定義

ContextSupport 類別可讓您儲存及還原現行追蹤環境定義。 takeSnapshot() 方法會將追蹤環境定義資訊 (例如追蹤 ID 和跨距 ID) 儲存在內部對映中。 restoreSnapshot() 方法會讀取 takeSnapshot() 方法所儲存的資訊,並使用它來設定現行追蹤環境定義。 當應用程式使用非同步處理來完成作業,且需要在另一個執行緒中繼續追蹤時,這些方法很有用。

例如,現行追蹤環境定義可以使用下列項目來儲存:

snapShotKey = ContextSupport.takeSnapshot();

然後,可以使用下列指令在另一個執行緒中還原追蹤環境定義:

ContextSupport.restoreSnapshot(snapShotKey);

指導教學

下列指導教學將引導您完成 Java 追蹤 SDK 的部分一般使用案例:

疑難排解

如果 SDK 追蹤資料未顯示在使用者介面中,則數個項目值得檢查:

  • instana-java-sdk jar 是否隨附於應用程式? 否則,代理程式將不執行任何動作,因為它處於 no-op 模式。
  • configuration.yaml 檔案 會參照具有註釋的所有套件嗎?
  • 追蹤是否在作用中?
  • YAML 語法是否正確?
  • 其他 APM 代理程式是否在作用中? 已知大部分其他 APM 代理程式會干擾 Instana ,因此 Instana 的代理程式不會在偵測到其他代理程式時執行追蹤。 如果是這種情況,日誌中會出現下列情況:
    JVM <PID> is running the <3rdParty> agent, which is known to be causing problems for the Instana Agent. Tracing will not be enabled for this JVM.
    
  • 開啟 DEBUG 記載 ,並尋找類似如下的訊息:
    2016-09-05T08:26:14.094+0200 | DEBUG | na-http-thread-1 | LoggerEndpoint                   | 48 - com.instana.agent - 1.1.194 | JVM (11403). Successfully instrumented class com.acme.resources.HelloWorldResource [sun.misc.Launcher$AppClassLoader@3d4eac69]`
    2016-09-05T08:26:14.145+0200 | DEBUG | na-http-thread-1 | LoggerEndpoint                   | 48 - com.instana.agent - 1.1.194 | JVM (11403) - Spent 188ms and 124kb transforming SDK classes. 
    
  • 註釋方法實際上是否由使用者/載入驅動程式所命中? Instana 代理程式會在啟動之後立即與每一個 JVM 互動。 因此,不會擷取在附加代理程式之前發生的交易。 請確保註釋在應用程式生命期限期間通常命中的方法。

常見問題 (FAQ)

為何擷取的參數及回覆值只會顯示類別名稱及雜湊記憶體位址?

檢測將對每一個擷取的參數及回覆值呼叫 toString() 。 這表示 Instana 中可見的值,直接取決於參數和回覆值類別的特定 toString() 方法實作。

未置換 toString() 時,最終會使用 java.lang.Object#toString() 。 此方法會以您看到的格式傳回 getClass().getName() + '@' + Integer.toHexString(hashCode()) 及結果。

若要改善所擷取參數及回覆值的可見性,建議適當地置換 toString()

為何有時無法使用回覆值?

在下列情況下,即使已設定 captureReturn=true ,也可能無法使用回覆值 ...

  • 方法擲出異常狀況,
  • 方法具有 void 傳回類型或當
  • 此方法會傳回 null