AWS X-Ray 適用於的 SDK Java - AWS X-Ray

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

AWS X-Ray 適用於的 SDK Java

Java 的 X-Ray SDK 是一組適用於 Java Web 應用程式的程式庫,可提供產生追蹤資料並將追蹤資料傳送至 X-Ray 守護程式的類別和方法。追蹤資料包括應用程式所提供之傳入 HTTP 要求的相關資訊,以及應用程式使用 AWS SDK、HTTP 用戶端或 SQL 資料庫連接器對下游服務進行呼叫的相關資訊。您也可以手動建立區段,並將除錯資訊新增至註釋和中繼資料中。

適用於 Java 的 X-Ray SDK 是一個開源項目。您可以關注該項目並在以下位置提交問題並提取請求 GitHub:gi thub.com/aws/ aws-xray-sdk-java

首先,將 AWSXRayServletFilter 新增為 Servlet 篩選條件以追蹤傳入的請求。servlet 篩選條件會建立區段。當區段開啟時,您可以使用軟體開發套件用戶端的方法,將資訊新增到區段,並建立子區段以追蹤下游呼叫。軟體開發套件也會在區段為開啟時自動記錄應用程式擲回的例外狀況。

從 1.3 版開始,您可以使用 Spring 的切面導向程式設計 (AOP) 來檢測應用程式。這意味著您可以在應用程序運行時檢測應用程序 AWS,而無需向應用程序的運行時添加任何代碼。

接下來,使用適用於 Java 的 X-Ray SDK 通過在構建配置中包含 SDK 儀器子模塊來檢測 AWS SDK for Java 客戶端。每當您使用已檢測的用戶端對下游 AWS 服務 或資源進行呼叫時,SDK 都會在子區段中記錄有關呼叫的資訊。 AWS 服務 而您在服務中存取的資源會顯示為追蹤對映上的下游節點,以協助您識別個別連線上的錯誤和節流問題。

如果您不想對所有下游呼叫進行檢測 AWS 服務,則可以省略 Instrumentor 子模塊並選擇要檢測的客戶端。通過向 AWS SDK 服務客戶端添加一TracingHandler來檢測單個客戶端。

Java 子模塊的其他 X-Ray SDK 為 HTTP Web API 和 SQL 數據庫的下游調用提供了檢測。您可以使用適用於 Java 版本的HTTPClient和 Apache HTTP 子模組HTTPClientBuilder中的 X-Ray SDK 來檢測阿帕奇 HTTP 用戶端。若要檢測 SQL 查詢,請將軟體開發套件的攔截程式新增至資料來源

開始使用 SDK 之後,請透過設定錄製程式和 servlet 篩選器來自訂其行為。您可以新增外掛程式,以記錄執行應用程式所需的運算資源相關資料、定義抽樣規則以自訂抽樣行為,並設定日誌層級以在應用程式日誌中查看更多或更少的軟體開發套件資訊。

使用註釋與中繼資料,記錄應用程式所做的請求和工作等其他資訊。註釋是簡單的鍵/值對,系統會為其建立索引以用於篩選條件表達式,因此您可以搜尋包含特定資料的追蹤。元數據條目的限制較低,可以記錄整個對象和數組-任何可以序列化為 JSON 的內容。

標註與中繼資料

註釋和中繼資料是您使用 X-Ray SDK 新增至區段的任意文字。註釋會編製索引以與篩選器運算式搭配使用 中繼資料不會建立索引,但可以使用 X-Ray 主控台或 API 在原始區段中檢視。您授與 X-Ray 讀取權限的任何人都可以檢視此資料。

當程式碼中有許多經過檢測的用戶端時,單一請求區段可能包含大量子區段,每個使用經檢測用戶端進行的呼叫都有一個子區段。您可以將用戶端呼叫包裝在自訂子區段中,以組織和群組子區段。您可以為整個函數或任何部分的程式碼建立自訂子區段,並記錄子區段上的中繼資料和註釋,而不必寫入父區段上的所有項目。

子模組

您可以從 Maven 下載適用於 Java 的 X-Ray SDK。Java 的 X-Ray SDK 依使用案例分割為子模組,並附有用於版本管理的材料清單:

如果您使用 Maven 或 Gradle 來構建應用程序,請將適用於 Java 的 X-Ray SDK 添加到構建配置中。

如需 SDK 類別和方法的參考文件,請參閱 AWS X-Ray SDK 以取得 Java API 參考

要求

適用於 Java 的 X-Ray SDK 需要 Java 8 或更高版本,SERVLET API 3, AWS SDK 和傑克遜。

軟體開發套件在編譯和執行時間需仰賴下列程式庫:

  • AWS 適用於 1.11.398 或更新Java版本的開發套件

  • Servlet API 3.1.0

軟體開發套件的 pom.xml 檔案中有宣告這些相依性。如果您使用 Maven 或 Gradle 來建置,則會自動包含這些相依性。

如果您使用包含在 Java 的 X-Ray SDK 中的程式庫,您必須使用隨附的版本。例如,如果您已在執行時間相依於 Jackson 並為了該相依性在部署中包含 JAR 檔案,則必須移除這些 JAR 檔案,因為軟體開發套件 JAR 包含自己的 Jackson 程式庫版本。

相依性管理

適用於 Java 的 X-Ray SDK 可從 Maven 獲得:

  • 集團com.amazonaws

  • Artifactaws-xray-recorder-sdk-bom

  • 版本2.11.0

如果您使用 Maven 來建置應用程式,請在 pom.xml 檔案中,將軟體開發套件新增為依存項目。

範例 pom.xml - 依存項目
<dependencyManagement> <dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-xray-recorder-sdk-bom</artifactId> <version>2.11.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-xray-recorder-sdk-core</artifactId> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-xray-recorder-sdk-apache-http</artifactId> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-xray-recorder-sdk-aws-sdk</artifactId> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-xray-recorder-sdk-aws-sdk-instrumentor</artifactId> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-xray-recorder-sdk-sql-postgres</artifactId> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-xray-recorder-sdk-sql-mysql</artifactId> </dependency> </dependencies>

若是 Gradle,請在 build.gradle 檔案中,將軟體開發套件新增為編譯時間依存項目。

範例 build.gradle - 相依性
dependencies { compile("org.springframework.boot:spring-boot-starter-web") testCompile("org.springframework.boot:spring-boot-starter-test") compile("com.amazonaws:aws-java-sdk-dynamodb") compile("com.amazonaws:aws-xray-recorder-sdk-core") compile("com.amazonaws:aws-xray-recorder-sdk-aws-sdk") compile("com.amazonaws:aws-xray-recorder-sdk-aws-sdk-instrumentor") compile("com.amazonaws:aws-xray-recorder-sdk-apache-http") compile("com.amazonaws:aws-xray-recorder-sdk-sql-postgres") compile("com.amazonaws:aws-xray-recorder-sdk-sql-mysql") testCompile("junit:junit:4.11") } dependencyManagement { imports { mavenBom('com.amazonaws:aws-java-sdk-bom:1.11.39') mavenBom('com.amazonaws:aws-xray-recorder-sdk-bom:2.11.0') } }

如果您使用 Elastic Beanstalk 部署應用程式,則可以在每次部署時使用 Maven 或 Gradle 執行個體建置,而不必建置和上傳包含所有相依性的大型封存檔。如需使用 Gradle 的範例,請參閱範例應用程式

設定適用於 Java 的 X-Ray SDK

適用於 Java 的 X-Ray SDK 包含一個名AWSXRay為提供全域記錄器的類別。這是可以用來檢測程式碼的 TracingHandler。您可以設定全域記錄器來自訂為傳入 HTTP 呼叫建立區段的 AWSXRayServletFilter

服務外掛程式

plugins來記錄託管應用程式之服務的相關資訊。

外掛程式
  • Amazon EC2 — EC2Plugin 新增執行個體 ID、可用區域和 CloudWatch 日誌群組。

  • Elastic Beanstalk — ElasticBeanstalkPlugin 新增環境名稱、版本標籤和部署 ID。

  • Amazon ECS-ECSPlugin 添加容器 ID。

  • Amazon EKS — EKSPlugin 新增容器 ID、叢集名稱、網繭識別碼和 CloudWatch 日誌群組。

使用 Amazon EC2 和 Elastic Beanstalk 外掛程式細分資源資料。

若要使用外掛程式,請在 AWSXRayRecorderBuilder 上呼叫 withPlugin

範例 src /主/爪/記分/ .java-記錄器 WebConfig
import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.AWSXRayRecorderBuilder; import com.amazonaws.xray.plugins.EC2Plugin; import com.amazonaws.xray.plugins.ElasticBeanstalkPlugin; import com.amazonaws.xray.strategy.sampling.LocalizedSamplingStrategy; @Configuration public class WebConfig { ... static { AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder.standard().withPlugin(new EC2Plugin()).withPlugin(new ElasticBeanstalkPlugin()); URL ruleFile = WebConfig.class.getResource("/sampling-rules.json"); builder.withSamplingStrategy(new LocalizedSamplingStrategy(ruleFile)); AWSXRay.setGlobalRecorder(builder.build()); } }

SDK 也會使用外掛程式設定來設定區origin段上的欄位。這表示運行您的應用程序的 AWS 資源的類型。當您使用多個外掛程式時,SDK 會使用下列解析順序來判斷來源: ElasticBeanstalk > EKS > ECS > EC2。

抽樣規則

SDK 會使用您在 X-Ray 主控台中定義的取樣規則來決定要記錄的要求。預設規則會每秒追蹤第一個要求,而所有服務的任何其他要求的百分之五會傳送追蹤至 X-Ray。在 X-Ray 主控台中建立其他規則,以自訂為每個應用程式記錄的資料量。

SDK 會依定義規則的順序套用自訂規則。如果要求符合多個自訂規則,SDK 只會套用第一個規則。

注意

如果 SDK 無法到達 X-Ray 以取得取樣規則,它會回復為每秒開始收到的第一個要求的預設本機規則,而每個主機的任何其他要求的百分之五。如果主機沒有調用採樣 API 的權限,或者無法連接到 X-Ray 守護程序(作為 SDK 發出的 API 調用的 TCP 代理),則可能會發生這種情況。

您也可以將 SDK 設定為從 JSON 文件載入取樣規則。SDK 可以使用本機規則做為無法使用 X-Ray 取樣的情況的備份,或僅使用本機規則。

範例 採樣規則
{ "version": 2, "rules": [ { "description": "Player moves.", "host": "*", "http_method": "*", "url_path": "/api/move/*", "fixed_target": 0, "rate": 0.05 } ], "default": { "fixed_target": 1, "rate": 0.1 } }

此範例定義了一個自訂規則和一個預設規則。自訂規則會套用百分之五的取樣率,而且沒有追蹤下限路徑的要求數目下/api/move/限。預設規則會每秒追蹤第一個要求,以及 10% 的額外要求。

在本機定義規則的缺點是,固定目標會由記錄器的每個執行個體獨立套用,而不是由 X-Ray 服務管理。當您部署更多主機時,固定費率會倍增,因此更難以控制記錄的資料量。

開啟時 AWS Lambda,您無法修改取樣率。如果您的函數是由已檢測的服務呼叫,則 Lambda 會記錄產生由該服務取樣之請求的呼叫。如果啟用主動追蹤且沒有追蹤標頭,Lambda 會做出取樣決策。

若要在 Spring 中提供備份規則,請在組態類別中使用 CentralizedSamplingStrategy 設定全域記錄器:

範例 src/主/爪/我的應用程序/. Java WebConfig-記錄器配置
import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.AWSXRayRecorderBuilder; import com.amazonaws.xray.javax.servlet.AWSXRayServletFilter; import com.amazonaws.xray.plugins.EC2Plugin; import com.amazonaws.xray.strategy.sampling.LocalizedSamplingStrategy; @Configuration public class WebConfig { static { AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder.standard().withPlugin(new EC2Plugin()); URL ruleFile = WebConfig.class.getResource("/sampling-rules.json"); builder.withSamplingStrategy(new CentralizedSamplingStrategy(ruleFile)); AWSXRay.setGlobalRecorder(builder.build()); }

若是 Tomcat,請新增接聽程式以擴展 ServletContextListener,並在部署描述項中註冊接聽程式。

範例 src/com/myapp/web/Startup.java
import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.AWSXRayRecorderBuilder; import com.amazonaws.xray.plugins.EC2Plugin; import com.amazonaws.xray.strategy.sampling.LocalizedSamplingStrategy; import java.net.URL; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class Startup implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent event) { AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder.standard().withPlugin(new EC2Plugin()); URL ruleFile = Startup.class.getResource("/sampling-rules.json"); builder.withSamplingStrategy(new CentralizedSamplingStrategy(ruleFile)); AWSXRay.setGlobalRecorder(builder.build()); } @Override public void contextDestroyed(ServletContextEvent event) { } }
範例 WEB-INF/web.xml
... <listener> <listener-class>com.myapp.web.Startup</listener-class> </listener>

若僅要使用本機規則,請將 CentralizedSamplingStrategy 取代為 LocalizedSamplingStrategy

builder.withSamplingStrategy(new LocalizedSamplingStrategy(ruleFile));

日誌

依預設,SDK 會將ERROR層級訊息輸出至您的應用程式記錄。您可以在 SDK 上啟用除錯層級記錄,將更詳細的記錄輸出至應用程式記錄檔。有效的記錄層級為DEBUGINFOWARNERROR、、和FATALFATAL日誌級別將所有日誌消息靜音,因為 SDK 不會在致命級別進行記錄。

範例 application.properties

使用 logging.level.com.amazonaws.xray 屬性設定記錄日誌層級。

logging.level.com.amazonaws.xray = DEBUG

當您手動產生子區段時,可使用除錯日誌來識別問題,例如未結束的子區段。

將追蹤 ID 插入日誌

若要將您日誌陳述式公開給目前的追蹤 ID,您可以將此 ID 插入到映射的診斷內容 (MDC)。使用 SegmentListener 界面,會在區段生命週期事件期間從 X-Ray 記錄器呼叫方法。當區段或子區段開始時,合格的追蹤 ID 會透過金鑰 AWS-XRAY-TRACE-ID 注入至 MDC。當該區段結束時,該索引鍵即會從 MDC 中移除。這會公開正在使用的記錄程式庫追蹤 ID。當子區段結束時,其父 ID 會注入 MDC 中。

範例 完整的合格追蹤 ID

完整的合格 ID 會表示為 TraceID@EntityID

1-5df42873-011e96598b447dfca814c156@541b3365be3dafc3

此功能適用於搭配 Java 的 AWS X-Ray SDK 測試的 Java 應用程式,並支援下列記錄設定:

  • SLF4J 前端 API 與 Logback 後端

  • SLF4J 前端 API 與 Log4J2 後端

  • Log4J2 前端 API 與 Log4J2 後端

請參閱下列標籤,以了解每個前端和每個後端的需求。

SLF4J Frontend
  1. 將以下 Maven 相依性新增到您的專案。

    <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-xray-recorder-sdk-slf4j</artifactId> <version>2.11.0</version> </dependency>
  2. 建置 AWSXRayRecorder 時包含 withSegmentListener 方法。這會新增 SegmentListener 類別,將新的追蹤 ID 自動插入 SLF4J MDC。

    SegmentListener 會採用選擇性字串做為參數來設定日誌陳述式的字首。您可以透過下列方式設定字首:

    • — 使用預設AWS-XRAY-TRACE-ID首碼。

    • 空白 — 使用空字串 (例如"")。

    • 自訂 — 使用字串中定義的自訂前置詞。

    範例 AWSXRayRecorderBuilder 陳述式
    AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder .standard().withSegmentListener(new SLF4JSegmentListener("CUSTOM-PREFIX"));
Log4J2 front end
  1. 將以下 Maven 相依性新增到您的專案。

    <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-xray-recorder-sdk-log4j</artifactId> <version>2.11.0</version> </dependency>
  2. 建置 AWSXRayRecorder 時包含 withSegmentListener 方法。這會新增 SegmentListener 類別,將新的完整合格追蹤 ID 自動注入 SLF4J MDC。

    SegmentListener 會採用選擇性字串做為參數來設定日誌陳述式的字首。您可以透過下列方式設定字首:

    • — 使用預設AWS-XRAY-TRACE-ID首碼。

    • 空白 — 使用空字串 (例如"") 並移除前置字元。

    • 自訂 — 使用字串中定義的自訂前置詞。

    範例 AWSXRayRecorderBuilder 陳述式
    AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder .standard().withSegmentListener(new Log4JSegmentListener("CUSTOM-PREFIX"));
Logback backend

若要將追蹤 ID 插入到日誌事件中,您必須修改記錄器的 PatternLayout,這會格式化每個記錄陳述式。

  1. 尋找 patternLayout 的設定位置。您可透過編寫程式的方式,或透過 XML 組態檔案執行此作業。若要深入了解,請參閱 Logback 組態

  2. %X{AWS-XRAY-TRACE-ID} 插入到 patternLayout 的任何位置,可將追蹤 ID 插入未來的記錄陳述式。%X{} 表示您正在使用 MDC 提供的索引鍵擷取值。若要 PatternLayouts 在登入中進一步了解,請參閱PatternLayout

Log4J2 backend
  1. 尋找 patternLayout 的設定位置。您可透過編寫程式的方式,或透過以 XML、JSON、YAML 或屬性格式編寫的組態檔案執行此作業。

    若要深入了解如何透過組態檔案設定 Log4J2,請參閱組態

    若要深入了解如何透過編寫程式的方式設定 Log4J2,請參閱透過編寫程式方式的組態

  2. %X{AWS-XRAY-TRACE-ID} 插入到 PatternLayout 的任何位置,可將追蹤 ID 插入未來的記錄陳述式。%X{} 表示您正在使用 MDC 提供的索引鍵擷取值。要了解有關 Log4J2 PatternLayouts 的更多信息,請參閱模式佈局。

插入追蹤 ID 範例

以下示範包含追蹤 ID 的修改後 PatternLayout 字串。追蹤 ID 會列印在執行緒名稱 (%t) 之後、日誌層級 (%-5p) 之前。

範例 插入 ID 的 PatternLayout
%d{HH:mm:ss.SSS} [%t] %X{AWS-XRAY-TRACE-ID} %-5p %m%n

AWS X-Ray 自動打印日誌語句中的密鑰和跟踪 ID,以便於解析。以下顯示使用修改後 PatternLayout 的日誌說明。

範例 插入 ID 的日誌說明
2019-09-10 18:58:30.844 [nio-5000-exec-4] AWS-XRAY-TRACE-ID: 1-5d77f256-19f12e4eaa02e3f76c78f46a@1ce7df03252d99e1 WARN 1 - Your logging message here

記錄訊息本身以 %m 模式包裝,在呼叫記錄器時設定。

區段接聽程式

區段接聽程式是攔截生命週期事件 (例如由 AWSXRayRecorder 產生的開始和結束區段) 的介面。區段接聽程式事件函數的實作可能是在透過 onBeginSubsegment 建立時,將相同的註釋新增至所有子區段、使用 afterEndSegment 將每個區段傳送到精靈後記錄訊息,或者透過 beforeEndSubsegment記錄由 SQL 攔截器傳送的查詢,以驗證子區段是否代表 SQL 查詢,如果是的話,則會新增額外的中繼資料。

若要查看完整的SegmentListener函數清單,請參閱適用於 Java API 的AWS X-Ray 記錄器 SDK 的文件。

下列範例顯示如何在建立 onBeginSubsegment 時將一致的註釋加入所有子區段,以及透過 afterEndSegment 在每個區段結尾列印記錄訊息。

範例 MySegmentListener. 爪哇
import com.amazonaws.xray.entities.Segment; import com.amazonaws.xray.entities.Subsegment; import com.amazonaws.xray.listeners.SegmentListener; public class MySegmentListener implements SegmentListener { ..... @Override public void onBeginSubsegment(Subsegment subsegment) { subsegment.putAnnotation("annotationKey", "annotationValue"); } @Override public void afterEndSegment(Segment segment) { // Be mindful not to mutate the segment logger.info("Segment with ID " + segment.getId()); } }

在建立 AWSXRayRecorder 時參考此自訂區段接聽程式。

範例 AWSXRayRecorderBuilder 聲明
AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder .standard().withSegmentListener(new MySegmentListener());

環境變數

您可以使用環境變數來設定適用於 Java 的 X-Ray SDK。軟體開發套件支援以下變數。

  • AWS_XRAY_CONTEXT_MISSING— 設定為當您RUNTIME_ERROR的檢測程式碼嘗試在沒有區段開啟時記錄資料時擲回例外狀況。

    有效值
    • RUNTIME_ERROR— 擲回執行階段例外狀況。

    • LOG_ERROR— 記錄錯誤並繼續 (預設值)。

    • IGNORE_ERROR— 忽略錯誤並繼續。

    當您嘗試在沒有要求開啟時執行的啟動程式碼中使用已檢測的用戶端,或在產生新執行緒的程式碼中使用已檢測的用戶端時,可能會發生與遺失區段或子區段相關的錯誤。

  • AWS_XRAY_DAEMON_ADDRESS— 設定 X-Ray 精靈監聽程式的主機和連接埠。根據預設,SDK 會同時用127.0.0.1:2000於追蹤資料 (UDP) 和取樣 (TCP)。如果您已將協助程式設定為在不同的連接埠上接聽,或是在不同的主機上執行,請使用此變數。

    格式
    • 相同的連接埠address:port

    • 不同的端口-tcp:address:port udp:address:port

  • AWS_LOG_GROUP— 將記錄群組的名稱設定為與您的應用程式相關聯的記錄群組。如果您的記錄群組使用與應用程式相同的 AWS 帳戶和區域,X-Ray 會使用此指定的記錄群組自動搜尋應用程式的區段資料。如需有關記錄群組的詳細資訊,請參閱使用記錄群組和串流

  • AWS_XRAY_TRACING_NAME— 設定 SDK 用於區段的服務名稱。覆寫您在 servlet 篩選條件的區段命名策略中設定的服務名稱。

環境變數會覆寫程式碼中所設的同等系統屬性和值。

系統屬性

您可以將系統屬性做為環境變數的 JVM 專用替代方案。開發套件支援以下屬性:

  • com.amazonaws.xray.strategy.tracingName— 相當於AWS_XRAY_TRACING_NAME.

  • com.amazonaws.xray.emitters.daemonAddress— 相當於AWS_XRAY_DAEMON_ADDRESS.

  • com.amazonaws.xray.strategy.contextMissingStrategy— 相當於AWS_XRAY_CONTEXT_MISSING.

如果同時設定了系統屬性和同等環境變數,則會使用環境變數的值。兩種方法都會覆寫程式碼中所設的值。

使用適用於 Java 的 X-Ray SDK 追蹤傳入的要求

您可以使用 X-Ray 開發套件來追蹤應用程式在 Amazon EC2 或 Amazon ECS 的 EC2 執行個體上提供的傳入 HTTP 請求。 AWS Elastic Beanstalk

使用 Filter 檢測傳入的 HTTP 請求。當您將 X-Ray Servlet 篩選器新增至應用程式時,Java 適用的 X-Ray SDK 會為每個取樣要求建立一個區段。此區段包括時間、方法,以及 HTTP 請求的處置方式。其他檢測會在此區段上建立子區段。

注意

對於 AWS Lambda 函數,Lambda 會為每個取樣的請求建立區段。如需詳細資訊,請參閱AWS Lambda 而且 AWS X-Ray

每個區段都有一個名稱,可在服務對應中識別您的應用程式。區段可以以靜態方式命名,也可以設定 SDK 根據傳入要求中的主機標頭動態命名該區段。動態命名可讓您根據要求中的網域名稱對追蹤進行分組,並在名稱與預期的模式不符時套用預設名稱 (例如,如果主機標頭是偽造的)。

轉寄的要求

如果負載平衡器或其他中介機構將要求轉寄至您的應用程式,X-Ray 會從要求中的X-Forwarded-For標頭取得用戶端 IP,而不是從 IP 封包中的來源 IP 取得。為轉寄的要求所記錄的用戶端 IP 可以偽造,因此不應該受信任。

轉送請求時,SDK 會在區段中設定一個額外的欄位來指出這一點。如果區段包含x_forwarded_for設定為的欄位true,則會從 HTTP 要求中的X-Forwarded-For標頭取得用戶端 IP。

訊息處理常式會使用 http 區塊為每個傳入的請求建立區段,其中包含以下資訊:

  • HTTP 方法-獲取,發布,把,刪除等。

  • [用戶端位址] — 傳送要求的用戶端 IP 位址。

  • 回應碼 — 已完成要求的 HTTP 回應碼。

  • 間 — 開始時間 (收到請求的時間) 和結束時間 (傳送回應的時間)。

  • 使用者代理程式user-agent 來自請求的。

  • 內容長度」— 響應content-length中的內容。

將追蹤篩選條件新增至應用程式 (Tomcat)

若是 Tomcat,請將 <filter> 新增至您專案的 web.xml 檔案。使用 fixedName 參數,指定要套用至針對傳入請求建立之區段的服務名稱

範例 WEB-INF/web.xml - Tomcat
<filter> <filter-name>AWSXRayServletFilter</filter-name> <filter-class>com.amazonaws.xray.javax.servlet.AWSXRayServletFilter</filter-class> <init-param> <param-name>fixedName</param-name> <param-value>MyApp</param-value> </init-param> </filter> <filter-mapping> <filter-name>AWSXRayServletFilter</filter-name> <url-pattern>*</url-pattern> </filter-mapping>

將追蹤篩選條件新增至應用程式 (Spring)

若是 Spring,請將 Filter 新增至您的 WebConfig 類別。以字串形式將區段名稱傳遞給 AWSXRayServletFilter 建構函數。

範例 SRC /主/爪/我的/WebConfig. Java-春天
package myapp; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Bean; import javax.servlet.Filter; import com.amazonaws.xray.javax.servlet.AWSXRayServletFilter; @Configuration public class WebConfig { @Bean public Filter TracingFilter() { return new AWSXRayServletFilter("Scorekeep"); } }

設定區段命名策略

AWS X-Ray 使用服務名稱來識別您的應用程式,並將其與應用程式使用的其他應用程式、資料庫、外部 API 和 AWS 資源區分開來。X-Ray SDK 為傳入要求產生區段時,會在區段的名稱欄位中記錄應用程式的服務名稱

X-Ray SDK 可以在 HTTP 要求標頭中的主機名稱之後命名區段。但是,此標頭可能會被偽造,這可能會導致服務對應中出現非預期的節點。若要避免 SDK 因為具有偽造主機標頭的要求而不正確地命名區段,您必須為傳入要求指定預設名稱。

如果您的應用程式為多個網域提供要求,您可以將 SDK 設定為使用動態命名策略,在區段名稱中反映此問題。動態命名策略可讓 SDK 針對符合預期模式的要求使用主機名稱,並將預設名稱套用至不符合要求的要求。

例如,您可能有一個應用程式向三個子網域提供要求 — www.example.com api.example.com、和static.example.com。您可以將動態命名策略與模式搭配使用,*.example.com以識別具有不同名稱的每個子網域的區段,從而在服務對應上產生三個服務節點。如果您的應用程式收到的主機名稱與模式不符的要求,您會在服務對應上看到第四個節點,其中包含您指定的後援名稱。

若要為所有請求區段使用相同的名稱,請如上一節所述,在初始化 servlet 篩選條件時指定您應用程式的名稱。這SegmentNamingStrategy.fixed()與通過調用並將其傳遞給AWSXRayServletFilter構造函數SegmentNamingStrategy來創建固定的效果相同。

注意

您可以使用 AWS_XRAY_TRACING_NAME 環境變數來覆寫您在程式碼中定義的預設服務名稱。

動態命名策略可定義主機名稱應相符的模式,以及如果 HTTP 請求中的主機名稱不符合模式時要使用的預設名稱。若要在 Tomcat 中動態命名區段,請分別使用 dynamicNamingRecognizedHostsdynamicNamingFallbackName 來定義模式和預設名稱。

範例 WEB-INF/web.xml - 使用動態命名的 Servlet 篩選條件
<filter> <filter-name>AWSXRayServletFilter</filter-name> <filter-class>com.amazonaws.xray.javax.servlet.AWSXRayServletFilter</filter-class> <init-param> <param-name>dynamicNamingRecognizedHosts</param-name> <param-value>*.example.com</param-value> </init-param> <init-param> <param-name>dynamicNamingFallbackName</param-name> <param-value>MyApp</param-value> </init-param> </filter> <filter-mapping> <filter-name>AWSXRayServletFilter</filter-name> <url-pattern>*</url-pattern> </filter-mapping>

對於 Spring,通SegmentNamingStrategy過調用創建一個動態SegmentNamingStrategy.dynamic(),並將其傳遞給AWSXRayServletFilter構造函數。

範例 src/主/java/我的應用程序/ .java-具有動態命名WebConfig的 SERVLET 過濾器
package myapp; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Bean; import javax.servlet.Filter; import com.amazonaws.xray.javax.servlet.AWSXRayServletFilter; import com.amazonaws.xray.strategy.SegmentNamingStrategy; @Configuration public class WebConfig { @Bean public Filter TracingFilter() { return new AWSXRayServletFilter(SegmentNamingStrategy.dynamic("MyApp", "*.example.com")); } }

使用適用於 Java 的 X-Ray AWS SDK 追蹤 SDK 呼叫

當您的應用程式呼叫 AWS 服務 以儲存資料、寫入佇列或傳送通知時,Java 的 X-Ray SDK 會追蹤子區段中下游的呼叫。您在這些服務中存取的追蹤 AWS 服務 和資源 (例如,Amazon S3 儲存貯體或 Amazon SQS 佇列) 會在 X-Ray 主控台的追蹤對應上顯示為下游節點。

當您在組建中包含aws-sdkaws-sdk-instrumentor子模組時,SDK for Java 的 X-Ray 開發套件會自動檢測所有 AWS 開發套件用戶端。如果您未包含 Instrumentor 子模組,您可以選擇檢測某些特定用戶端,而排除其他用戶端。

要檢測單個客戶端,請從構建中刪除aws-sdk-instrumentor子模塊,然後使用服務XRayClient的客戶端構建器在 AWS SDK 客戶端TracingHandler上添加一個。

例如,若要檢測 AmazonDynamoDB 用戶端,請將追蹤處理常式傳遞至 AmazonDynamoDBClientBuilder

範例 MyModel. Java DynamoDB 戶端
import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.handlers.TracingHandler; ... public class MyModel { private AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard() .withRegion(Regions.fromName(System.getenv("AWS_REGION"))) .withRequestHandlers(new TracingHandler(AWSXRay.getGlobalRecorder())) .build(); ...

對於所有服務,您都可以在 X-Ray 控制台中看到調用的 API 的名稱。對於服務子集,X-Ray SDK 會將資訊新增至區段,以在服務對應中提供更多精細度。

例如,當您使用已檢測的 DynamoDB 用戶端進行呼叫時,SDK 會將資料表名稱新增至區段,以便針對以資料表為目標的呼叫。在主控台中,每個表格在服務對應中顯示為獨立節點,其中包含一般 DynamoDB 節點,用於未針對資料表的呼叫。

範例 呼叫 DynamoDB 以儲存項目的子區段
{ "id": "24756640c0d0978a", "start_time": 1.480305974194E9, "end_time": 1.4803059742E9, "name": "DynamoDB", "namespace": "aws", "http": { "response": { "content_length": 60, "status": 200 } }, "aws": { "table_name": "scorekeep-user", "operation": "UpdateItem", "request_id": "UBQNSO5AEM8T4FDA4RQDEB94OVTDRVV4K4HIRGVJF66Q9ASUAAJG", } }

您存取具名資源時,對以下服務的呼叫會在服務地圖中建立額外節點。未針對特定資源的呼叫,則會建立服務的一般節點。

  • Amazon DynamoDB — 表名

  • Amazon 簡單存儲服務 — 存儲桶和密鑰名稱

  • Amazon 簡單隊列服務-隊列名稱

要檢測 AWS SDK for Java 2.2 及更高版本的下游調 AWS 服務 用,您可以從構建配置中省略該aws-xray-recorder-sdk-aws-sdk-v2-instrumentor模塊。這時改成包含 aws-xray-recorder-sdk-aws-sdk-v2 module,然後使用 TracingInterceptor 為其進行設定,檢測個別的用戶端。

範例 AWS SDK for Java 2.2 及更高版本-跟踪攔截器
import com.amazonaws.xray.interceptors.TracingInterceptor; import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration import software.amazon.awssdk.services.dynamodb.DynamoDbClient; //... public class MyModel { private DynamoDbClient client = DynamoDbClient.builder() .region(Region.US_WEST_2) .overrideConfiguration(ClientOverrideConfiguration.builder() .addExecutionInterceptor(new TracingInterceptor()) .build() ) .build(); //...

使用適用於 Java 的 X-Ray SDK 追蹤對下游 HTTP 網路服務的呼叫

當您的應用程式呼叫微服務或公用 HTTP API 時,您可以使用 Java 版本的 X-Ray SDK HttpClient 來檢測這些呼叫,並將 API 作為下游服務新增至服務圖形。

適用於 Java 的 X-Ray SDK 包括DefaultHttpClient和可用於代替 Apache HttpComponents 等效用於檢測傳出 HTTP 呼叫的HttpClientBuilder類別。

  • com.amazonaws.xray.proxies.apache.http.DefaultHttpClient - org.apache.http.impl.client.DefaultHttpClient

  • com.amazonaws.xray.proxies.apache.http.HttpClientBuilder - org.apache.http.impl.client.HttpClientBuilder

這些程式庫位於 aws-xray-recorder-sdk-apache-http 子模組中。

您可以使用相當於檢測所有用戶端的 X-Ray 來取代現有的匯入陳述式,或者在初始化用戶端以檢測特定用戶端時使用完整名稱。

範例 HttpClientBuilder
import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.util.EntityUtils; import com.amazonaws.xray.proxies.apache.http.HttpClientBuilder; ... public String randomName() throws IOException { CloseableHttpClient httpclient = HttpClientBuilder.create().build(); HttpGet httpGet = new HttpGet("http://names.example.com/api/"); CloseableHttpResponse response = httpclient.execute(httpGet); try { HttpEntity entity = response.getEntity(); InputStream inputStream = entity.getContent(); ObjectMapper mapper = new ObjectMapper(); Map<String, String> jsonMap = mapper.readValue(inputStream, Map.class); String name = jsonMap.get("name"); EntityUtils.consume(entity); return name; } finally { response.close(); } }

當您檢測對下游 Web API 的調用時,Java 的 X-Ray SDK 會記錄一個子段,其中包含有關 HTTP 請求和響應的信息。X-Ray 會使用子區段來產生遠端 API 的推斷區段。

範例 下游 HTTP 呼叫的子區段
{ "id": "004f72be19cddc2a", "start_time": 1484786387.131, "end_time": 1484786387.501, "name": "names.example.com", "namespace": "remote", "http": { "request": { "method": "GET", "url": "https://names.example.com/" }, "response": { "content_length": -1, "status": 200 } } }
範例 下游 HTTP 呼叫的推斷區段
{ "id": "168416dc2ea97781", "name": "names.example.com", "trace_id": "1-62be1272-1b71c4274f39f122afa64eab", "start_time": 1484786387.131, "end_time": 1484786387.501, "parent_id": "004f72be19cddc2a", "http": { "request": { "method": "GET", "url": "https://names.example.com/" }, "response": { "content_length": -1, "status": 200 } }, "inferred": true }

使用適用於 Java 的 X-Ray 開發套件追蹤 SQL 查詢

SQL 攔截器

通過將 Java JDBC 攔截器的 X-Ray SDK 添加到您的數據源配置中來檢測 SQL 數據庫查詢。

  • PostgreSQLcom.amazonaws.xray.sql.postgres.TracingInterceptor

  • MySQLcom.amazonaws.xray.sql.mysql.TracingInterceptor

這些攔截器分別位於 aws-xray-recorder-sql-postgres 和 aws-xray-recorder-sql-mysql 子模組中。他們會實作 org.apache.tomcat.jdbc.pool.JdbcInterceptor,並且與 Tomcat 連線集區相容。

注意

基於安全性目的,SQL 攔截器不會在子區段內記錄 SQL 查詢本身。

針對 Spring,請在屬性檔案中新增攔截器,然後使用 Spring Boot 的 DataSourceBuilder 建置資料來源。

範例 src/main/java/resources/application.properties - PostgreSQL JDBC 攔截器
spring.datasource.continue-on-error=true spring.jpa.show-sql=false spring.jpa.hibernate.ddl-auto=create-drop spring.datasource.jdbc-interceptors=com.amazonaws.xray.sql.postgres.TracingInterceptor spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL94Dialect
範例 src/main/java/myapp/WebConfig.java - 資料來源
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import javax.servlet.Filter; import javax.sql.DataSource; import java.net.URL; @Configuration @EnableAutoConfiguration @EnableJpaRepositories("myapp") public class RdsWebConfig { @Bean @ConfigurationProperties(prefix = "spring.datasource") public DataSource dataSource() { logger.info("Initializing PostgreSQL datasource"); return DataSourceBuilder.create() .driverClassName("org.postgresql.Driver") .url("jdbc:postgresql://" + System.getenv("RDS_HOSTNAME") + ":" + System.getenv("RDS_PORT") + "/ebdb") .username(System.getenv("RDS_USERNAME")) .password(System.getenv("RDS_PASSWORD")) .build(); } ... }

對於 Tomcat,請setJdbcInterceptors使用 Java 類別的 X-Ray SDK 參考來呼叫 JDBC 資料來源。

範例 src/main/myapp/model.java - 資料來源
import org.apache.tomcat.jdbc.pool.DataSource; ... DataSource source = new DataSource(); source.setUrl(url); source.setUsername(user); source.setPassword(password); source.setDriverClassName("com.mysql.jdbc.Driver"); source.setJdbcInterceptors("com.amazonaws.xray.sql.mysql.TracingInterceptor;");

Tomcat JDBC 數據源庫包含在適用於 Java 的 X-Ray SDK 中,但是您可以將其聲明為提供的依賴項,以記錄您使用它。

範例 pom.xml - JDBC 資料來源
<dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jdbc</artifactId> <version>8.0.36</version> <scope>provided</scope> </dependency>

本機 SQL 跟踪裝飾器

  • 添加aws-xray-recorder-sdk-sql到您的依賴關係。

  • 裝飾您的數據庫數據源,連接或語句。

    dataSource = TracingDataSource.decorate(dataSource) connection = TracingConnection.decorate(connection) statement = TracingStatement.decorateStatement(statement) preparedStatement = TracingStatement.decoratePreparedStatement(preparedStatement, sql) callableStatement = TracingStatement.decorateCallableStatement(callableStatement, sql)

使用適用於 Java 的 X-Ray SDK 產生自訂子區段

子段擴展了跟踪的,其中包含有關完成工作的詳細信息,以滿足請求。每次您使用已檢測的用戶端進行呼叫時,X-Ray SDK 都會記錄在子區段中產生的資訊。您可以建立其他子區段來分組其他子區段、測量程式碼區段的效能,或是記錄註釋和中繼資料。

若要管理子區段,請使用 beginSubsegmentendSubsegment 方法。

範例 GameModel.java-自定義子段
import com.amazonaws.xray.AWSXRay; ... public void saveGame(Game game) throws SessionNotFoundException { // wrap in subsegment Subsegment subsegment = AWSXRay.beginSubsegment("Save Game"); try { // check session String sessionId = game.getSession(); if (sessionModel.loadSession(sessionId) == null ) { throw new SessionNotFoundException(sessionId); } mapper.save(game); } catch (Exception e) { subsegment.addException(e); throw e; } finally { AWSXRay.endSubsegment(); } }

在此範例中,子區段中的程式碼會以工作階段模型上的方法從 DynamoDB 載入遊戲的工作階段,並使用的 DynamoDB 對應程式來儲存遊戲。 AWS SDK for Java將此程式碼封裝在子區段中,會在主控台的追蹤檢視中呼叫Save Game子區段的 DynamoDB 子項。

如果子區段中的程式碼擲回已檢查的例外狀況,請將其包裝在 try 區塊中,並在 finally 區塊中呼叫 AWSXRay.endSubsegment(),以確保子區段一律關閉。如果子段未封閉,則無法完成父段,也不會將其傳送至 X-Ray。

對於不會拋出檢查異常的代碼,您可以將代碼AWSXRay.CreateSubsegment作為 Lambda 函數傳遞給。

範例 子區段 Lambda 函數
import com.amazonaws.xray.AWSXRay; AWSXRay.createSubsegment("getMovies", (subsegment) -> { // function code });

當您在區段或其他子區段內建立子區段時,Java 的 X-Ray SDK 會產生該區段的 ID,並記錄開始時間和結束時間。

範例 使用中繼資料的子區段
"subsegments": [{ "id": "6f1605cd8a07cb70", "start_time": 1.480305974194E9, "end_time": 1.4803059742E9, "name": "Custom subsegment for UserModel.saveUser function", "metadata": { "debug": { "test": "Metadata string from UserModel.saveUser" } },

對於非同步和多執行緒程式設計,您必須手動將子區段傳遞給endSubsegment()方法,以確保其正確關閉,因為 X-Ray 環境可能會在非同步執行期間修改。如果非同步子區段在其父段關閉後關閉,此方法會自動將整個區段串流至 X-Ray 精靈。

範例 非同步子段
@GetMapping("/api") public ResponseEntity<?> api() { CompletableFuture.runAsync(() -> { Subsegment subsegment = AWSXRay.beginSubsegment("Async Work"); try { Thread.sleep(3000); } catch (InterruptedException e) { subsegment.addException(e); throw e; } finally { AWSXRay.endSubsegment(subsegment); } }); return ResponseEntity.ok().build(); }

使用適用於 Java 的 X-Ray SDK 將註釋和中繼資料新增至區段

您可以使用註釋和中繼資料來記錄有關請求、環境或應用程式的其他資訊。您可以將註釋和中繼資料新增至 X-Ray SDK 建立的區段,或新增至您建立的自訂子區段。

註釋是與字符串,數字或布爾值鍵-值對。註釋會編製索引以與篩選器運算式搭配使用 使用標記記錄您想要用來在主控台將追蹤分組的資料,或是在呼叫 GetTraceSummaries API 時使用標記。

中繼資料是索引鍵-值配對,可以具有任何類型的值 (包括物件和清單),但不會編製索引以供篩選運算式使用。使用元數據記錄要存儲在跟踪中但不需要與搜索一起使用的其他數據。

除了註釋和中繼資料,您也可以在區段上記錄使用者 ID 字串。區段會將使用者 ID 記錄在單獨的欄位中,並建立索引以用於搜尋。

使用適用於 Java 的 X-Ray SDK 記錄註釋

針對您想要建立索引以用於搜尋的區段或子區段,請使用標註來記錄這些區段上的資訊。

註釋要求
  • 按鍵 — X-Ray 註解的金鑰最多可包含 500 個英數字元。您不能使用底線符號 (_) 以外的空格或符號。

  • — X-Ray 註釋的值最多可包含 1,000 個 Unicode 字元。

  • 註釋的數量 — 每個追蹤最多可以使用 50 個註釋。

記錄標註
  1. AWSXRay 取得目前區段或子區段的參考。

    import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.entities.Segment; ... Segment document = AWSXRay.getCurrentSegment();

    import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.entities.Subsegment; ... Subsegment document = AWSXRay.getCurrentSubsegment();
  2. 使用字串索引鍵、布林值、數字或字串值,呼叫 putAnnotation

    document.putAnnotation("mykey", "my value");

軟體開發套件會將標註以鍵/值對記錄在區段文件中的 annotations 物件內。若使用相同鍵呼叫 putAnnotation 兩次,則會覆寫之前在相同區段或子區段上記錄的值。

若要尋找具有特定值之註釋的繪線,請在篩選器運算式中使用annotations.key關鍵字。

範例 src/main/java/scorekeep/GameModel.java— 註釋和元數據
import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.entities.Segment; import com.amazonaws.xray.entities.Subsegment; ... public void saveGame(Game game) throws SessionNotFoundException { // wrap in subsegment Subsegment subsegment = AWSXRay.beginSubsegment("## GameModel.saveGame"); try { // check session String sessionId = game.getSession(); if (sessionModel.loadSession(sessionId) == null ) { throw new SessionNotFoundException(sessionId); } Segment segment = AWSXRay.getCurrentSegment(); subsegment.putMetadata("resources", "game", game); segment.putAnnotation("gameid", game.getId()); mapper.save(game); } catch (Exception e) { subsegment.addException(e); throw e; } finally { AWSXRay.endSubsegment(); } }

使用適用於 Java 的 X-Ray SDK 記錄中繼資料

針對您不想要建立索引以用於搜尋的區段,請使用中繼資料來記錄這些區段或子區段上的資訊。中繼資料值可以是字串、數字、布林值,或可序列化為 JSON 物件或陣列的任何物件。

記錄中繼資料
  1. AWSXRay 取得目前區段或子區段的參考。

    import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.entities.Segment; ... Segment document = AWSXRay.getCurrentSegment();

    import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.entities.Subsegment; ... Subsegment document = AWSXRay.getCurrentSubsegment();
  2. 使用字串命名空間、字串索引鍵、布林值、數字、字串或物件值,呼叫 putMetadata

    document.putMetadata("my namespace", "my key", "my value");

    只使用鍵和值呼叫 putMetadata

    document.putMetadata("my key", "my value");

若您沒有指定命名空間,軟體開發套件會使用 default。若使用相同鍵呼叫 putMetadata 兩次,則會覆寫之前在相同區段或子區段上記錄的值。

範例 src/main/java/scorekeep/GameModel.java— 註釋和元數據
import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.entities.Segment; import com.amazonaws.xray.entities.Subsegment; ... public void saveGame(Game game) throws SessionNotFoundException { // wrap in subsegment Subsegment subsegment = AWSXRay.beginSubsegment("## GameModel.saveGame"); try { // check session String sessionId = game.getSession(); if (sessionModel.loadSession(sessionId) == null ) { throw new SessionNotFoundException(sessionId); } Segment segment = AWSXRay.getCurrentSegment(); subsegment.putMetadata("resources", "game", game); segment.putAnnotation("gameid", game.getId()); mapper.save(game); } catch (Exception e) { subsegment.addException(e); throw e; } finally { AWSXRay.endSubsegment(); } }

使用適用於 Java 的 X-Ray SDK 記錄使用者 ID

記錄請求區段上的使用者 ID 以識別傳送請求的使用者。

記錄使用者 ID
  1. AWSXRay 取得目前區段的參考。

    import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.entities.Segment; ... Segment document = AWSXRay.getCurrentSegment();
  2. 使用傳送請求之使用者的字串 ID 呼叫 setUser

    document.setUser("U12345");

您可以在控制器中呼叫 setUser,以在應用程式開始處理請求時馬上記錄使用者 ID。如果您只要使用區段來設定使用者 ID,可以將呼叫鏈結為單行。

範例 src /主/爪/記分/. Java MoveController-用戶識別碼
import com.amazonaws.xray.AWSXRay; ... @RequestMapping(value="/{userId}", method=RequestMethod.POST) public Move newMove(@PathVariable String sessionId, @PathVariable String gameId, @PathVariable String userId, @RequestBody String move) throws SessionNotFoundException, GameNotFoundException, StateNotFoundException, RulesException { AWSXRay.getCurrentSegment().setUser(userId); return moveFactory.newMove(sessionId, gameId, userId, move); }

若要尋找使用者 ID 的追蹤,請在篩選器運算式中使用user關鍵字。

AWS X-Ray 用於 Java 的 X-Ray SDK 的指標

本主題說明命 AWS X-Ray 名空間、測量結果和維度。您可以使用適用於 Java 的 X-Ray 開發套件,從收集到的 X-Ray 區段發佈未取樣的 Amazon CloudWatch 指標。這些指標衍生自區段的開始和結束時間,以及錯誤、故障和節流狀態標記。您可以使用這些追蹤指標,公開子區段內的重試和相依性問題。

CloudWatch 是度量儲存庫。量度是中的基本概念 CloudWatch ,代表一組時間順序的資料點。您 (或 AWS 服務) 將量度資料點發佈至, CloudWatch 並擷取有關這些資料點的統計資料,做為一組排序的時間序列資料。

指標是由名稱、命名空間和一個或多個維度做唯一的定義。每個資料點都有時間戳記和可選的測量單位。當您請求統計資料時,傳回的資料流是藉由命名空間、指標名稱和維度做識別。

如需有關的詳細資訊 CloudWatch,請參閱 Amazon CloudWatch 使用者指南

X-Ray CloudWatch 指標

ServiceMetrics/SDK 命名空間包含下列指標。

指標 統計資訊可用 描述 個單位

Latency

平均、最小、最大、計數

開始與結束時間之間的差異。平均、最小和最大皆描述操作延遲。計數描述呼叫計數。

毫秒

ErrorRate

平均數、總和

失敗原因為 4xx Client Error 狀態碼的請求速率,導致錯誤。

百分比

FaultRate

平均數、總和

失敗原因為 5xx Server Error 狀態碼的追蹤速率,導致故障。

百分比

ThrottleRate

平均數、總和

傳回 429 狀態碼的節流追蹤速率。這是 ErrorRate 指標的一部分。

百分比

OkRate

平均數、總和

產生 OK 狀態碼的追蹤請求速率。

百分比

X-Ray CloudWatch 尺寸

使用下表中的維度來精細化 X-Ray 檢測Java應用程式傳回的量度。

維度 描述

ServiceType

如不清楚,即為服務的類型,例如,AWS::EC2::InstanceNONE

ServiceName

服務的正式名稱。

啟用 X-Ray CloudWatch 指標

Java請使用下列程序,在已檢測的應用程式中啟用追蹤指標。

設定追蹤指標
  1. aws-xray-recorder-sdk-metrics套件新增為Apache Maven相依性。如需詳細資訊,請參閱適用於 Java 子模組的 X-Ray SDK

  2. 啟用新的 MetricsSegmentListener() 做為全域記錄器組建的一部分。

    範例 src/com/myapp/web/Startup.java
    import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.AWSXRayRecorderBuilder; import com.amazonaws.xray.plugins.EC2Plugin; import com.amazonaws.xray.plugins.ElasticBeanstalkPlugin; import com.amazonaws.xray.strategy.sampling.LocalizedSamplingStrategy; @Configuration public class WebConfig { ... static { AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder .standard() .withPlugin(new EC2Plugin()) .withPlugin(new ElasticBeanstalkPlugin()) .withSegmentListener(new MetricsSegmentListener()); URL ruleFile = WebConfig.class.getResource("/sampling-rules.json"); builder.withSamplingStrategy(new LocalizedSamplingStrategy(ruleFile)); AWSXRay.setGlobalRecorder(builder.build()); } }
  3. 部署 CloudWatch 代理程式以使用 Amazon 彈性運算雲端 (Amazon EC2)、Amazon Elastic Container Service (Amazon ECS) 或 Amazon Elastic Kubernetes Service (亞馬遜 EKS) 來收集指標:

  4. 設定 SDK 以與 CloudWatch 代理程式通訊。依預設,SDK 會與位127.0.0.1址上的 CloudWatch 代理程式通訊。您可以將環境變數或 Java 屬性設為 address:port,以設定替代位址。

    範例 環境變數
    AWS_XRAY_METRICS_DAEMON_ADDRESS=address:port
    範例 Java 屬性
    com.amazonaws.xray.metrics.daemonAddress=address:port
驗證組態
  1. 請登入 AWS Management Console 並開啟 CloudWatch 主控台,網址為 https://console.aws.amazon.com/cloudwatch/

  2. 開啟 Metrics (指標) 標籤,以觀察指標的湧入。

  3. (選擇性) 在 CloudWatch 主控台的 [記錄] 索引標籤上,開啟記ServiceMetricsSDK錄群組。尋找符合主機指標的日誌資料流,並確認日誌訊息。

在多執行緒應用程式之間傳遞區段內容

當您在應用程式中建立新執行緒時,AWSXRayRecorder 不會維持目前區段或子區段實體的參考。如果您在新執行緒中使用已檢測的用戶端,SDK 會嘗試寫入不存在的區段,導致. SegmentNotFoundException

為了避免在開發過程中拋出異常,您可以使用告ContextMissingStrategy訴它記錄錯誤來配置記錄器。您可以使用程式碼來設定策略 SetContextMissingStrategy,或使用環境變數系統屬性來設定對等選項。

其中一種處理錯誤的方法是透過在啟動執行緒時呼叫 beginSegment 來使用新區段,以及在關閉時呼叫 endSegment。若您要檢測並非針對回應 HTTP 請求而執行的程式碼,這種方法可以正常運作,就像在應用程式啟動時執行的程式碼。

若您使用多個執行緒來處理傳入請求,您可以將目前區段或子區段傳遞至新執行緒,並將它提供給全域記錄器。這可確保在記錄該請求的其餘資訊時,於新執行緒中記錄的資訊會與相同區段建立關聯。一旦段在新線程中可用,您可以使用該方法執行任何可運行的訪問該段的上下文。segment.run(() -> { ... })

如需範例,請參閱在工作者執行緒中使用受檢測用戶端

使用 X-Ray 與異步編程

適用於 Java 的 X-Ray SDK 可以在非同步 Java 程式中使用 SegmentContextExecutors. SegmentContextExecutor 實現了 Executor 接口,這意味著它可以被傳遞到. CompletableFuture 這可確保任何非同步操作都將在其上下文中使用正確的段執行。

範例 例如 App.java:傳遞 SegmentContextExecutor 給 CompletableFuture
DynamoDbAsyncClient client = DynamoDbAsyncClient.create(); AWSXRay.beginSegment(); // ... client.getItem(request).thenComposeAsync(response -> { // If we did not provide the segment context executor, this request would not be traced correctly. return client.getItem(request2); }, SegmentContextExecutors.newSegmentContextExecutor());

AOP 與彈簧和適用於 Java 的 X-Ray SDK

本主題說明如何使用 X-Ray SDK 和 Spring 架構在不變更其核心邏輯的情況下檢測您的應用程式。這意味著現在有一種非侵入性的方法可以檢測在中 AWS遠程運行的應用程序。

設定 Spring

您可以使用 Maven 或 Gradle 將 Spring 設定為使用 AOP 檢測您的應用程式。

如果您使用 Maven 來建置應用程式,請在 pom.xml 檔案中,新增以下相依性。

<dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-xray-recorder-sdk-spring</artifactId> <version>2.11.0</version> </dependency>

若是 Gradle,請在 build.gradle 檔案中,新增以下依存性。

compile 'com.amazonaws:aws-xray-recorder-sdk-spring:2.11.0'

配置春季啟動

除了上一節中描述的 Spring 依賴項之外,如果您使用的是 Spring Boot,請添加以下依賴項(如果它尚未在類路徑中)。

釋界:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> <version>2.5.2</version> </dependency>

搖籃:

compile 'org.springframework.boot:spring-boot-starter-aop:2.5.2'

將追蹤篩選器新增至您的應用程式

添加一個Filter到你的WebConfig班級。以字串形式將區段名稱傳遞給 AWSXRayServletFilter 建構函數。如需有關追蹤篩選器和檢測傳入要求的詳細資訊,請參閱使用適用於 Java 的 X-Ray SDK 追蹤傳入的要求

範例 SRC /主/爪/我的/WebConfig. Java-春天
package myapp; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Bean; import javax.servlet.Filter; import com.amazonaws.xray.javax.servlet.AWSXRayServletFilter; @Configuration public class WebConfig { @Bean public Filter TracingFilter() { return new AWSXRayServletFilter("Scorekeep"); } }

雅加達 Support

6 年春季使用雅加達而不是 Javax 作為其企業版。為了支持這個新的命名空間,X-Ray 創建了一組存在於自己的雅加達名稱空間中的 parallel 類。

對於過濾器類別,請取javax代為jakarta。設定區段命名策略時,請在命名策略類別名稱jakarta之前新增,如下列範例所示:

package myapp; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Bean; import jakarta.servlet.Filter; import com.amazonaws.xray.jakarta.servlet.AWSXRayServletFilter; import com.amazonaws.xray.strategy.jakarta.SegmentNamingStrategy; @Configuration public class WebConfig { @Bean public Filter TracingFilter() { return new AWSXRayServletFilter(SegmentNamingStrategy.dynamic("Scorekeep")); } }

對您的程式碼做註釋或實作界面

您的類必須用@XRayEnabled註釋註釋,要么實現接XRayTraced口。這會通知 AOP 系統,針對 X-Ray 檢測包裝受影響的類別函數。

在應用程序中激活 X-Ray

若要在應用程式中啟用 X-Ray 追蹤,您的程式碼必須BaseAbstractXRayInterceptor藉由覆寫下列方法來擴充抽象類別。

  • generateMetadata— 此函數允許自訂附加到目前函數追蹤的中繼資料。根據預設,執行函數的類別名稱會記錄到中繼資料中。如果您需要其他資訊,可以新增更多資料。

  • xrayEnabledClasses此函數是空的,應該保持如此。可做為 pointcut 的主機,指示攔截程式有哪些包裝方法。指定哪些類別要使用 @XRayEnabled 做註釋以便追蹤,藉此定義 pointcut。以下 pointcut 陳述式會通知攔截程式包裝所有含 @XRayEnabled 註釋的控制器 Bean。

    @Pointcut(“@within(com.amazonaws.xray.spring.aop.XRayEnabled) && bean(*Controller)”)

如果您的BaseAbstractXRayInterceptor項目正在使用 Spring 數據 JPA,請考慮從擴展AbstractXRayInterceptor而不是.

範例

下面的代碼擴展了抽象類BaseAbstractXRayInterceptor

@Aspect @Component public class XRayInspector extends BaseAbstractXRayInterceptor { @Override protected Map<String, Map<String, Object>> generateMetadata(ProceedingJoinPoint proceedingJoinPoint, Subsegment subsegment) throws Exception { return super.generateMetadata(proceedingJoinPoint, subsegment); } @Override @Pointcut("@within(com.amazonaws.xray.spring.aop.XRayEnabled) && bean(*Controller)") public void xrayEnabledClasses() {} }

下列程式碼為將由 X-Ray 檢測的類別。

@Service @XRayEnabled public class MyServiceImpl implements MyService { private final MyEntityRepository myEntityRepository; @Autowired public MyServiceImpl(MyEntityRepository myEntityRepository) { this.myEntityRepository = myEntityRepository; } @Transactional(readOnly = true) public List<MyEntity> getMyEntities(){ try(Stream<MyEntity> entityStream = this.myEntityRepository.streamAll()){ return entityStream.sorted().collect(Collectors.toList()); } } }

如果您已正確設定應用程式,則應該會看到應用程式的完整呼叫堆疊 (從控制器到服務呼叫),如以下主控台的螢幕擷取畫面所示。

完整呼叫堆疊。