ARMS提供了從調用鏈路中提取特定屬性的能力,無侵入地提取請求和響應中的指定參數,進一步協助您定位問題根因和追蹤請求資訊。您可以配置業務參數擷取規則,並根據提取出的參數配置自訂錯誤。
該功能目前僅支援Java應用。
由於業務參數擷取規則中存在反射和序列化/還原序列化過程,可能會對您的業務帶來一定的額外開銷,關於開銷的詳細說明請參見效能開銷。
前提條件
已為應用安裝4.1.0或以上版本探針,具體操作,請參見應用監控接入概述。如果您的探針版本低於4.1.0,本功能配置後將不會有任何作用和影響。
4.2.0及更高版本探針支援為一條業務參數擷取規則添加多條介面匹配及參數擷取規則。如果您的探針版本在4.1.0~4.2.0之間,僅第一條匹配規則會生效。
功能入口
登入ARMS控制台,在左側導覽列選擇 。
在應用列表頁面頂部選擇目標地區,然後單擊目標應用程式名稱。
說明語言列的表徵圖含義如下:
:接入應用監控的Java應用。
:接入應用監控的Golang應用。
:接入應用監控的Python應用。
-:接入Managed Service for OpenTelemetry的應用。
在上方導覽列選擇
。在業務參數擷取規則地區,您可以建立、查看和修改當前應用的業務參數擷取規則。
ARMS應用監控探針會動態識別規則變化,並依照所有已啟動的規則將業務參數提取出來。
在自訂錯誤設定地區,您可以配置自訂錯誤規則,對提取出來的業務參數值進行過濾。
業務參數擷取規則
支援範圍說明
業務參數擷取規則對架構和實際用法有一定要求,支援的類型和來源如下:
參數提取類型 | 參數提取來源 | 支援的架構 | 備忘 |
HTTP服務端請求 |
|
| - |
Body | SpringMVC 4.2.0+ | 類名需使用@Controller註解標註,且方法入參被@RequestBody註解標註。 | |
HTTP服務端響應 |
|
| - |
Body | SpringMVC 4.2.0+ | 類名需使用@Controller註解標註,且方法被@ResponseBody註解標註。 | |
異常資訊 | Message | - | 對應類需要繼承 java.lang.Exception。 |
新增規則
規則建立完成並啟用後將即時下發至用戶端探針側,無需重啟應用,預計1~2分鐘後開始生效。
業務參數被提取後將記錄至對應調用鏈Span的屬性Attributes中,可在調用鏈分析頁面按需篩選查詢。
Attribute名稱會預設具有
biz.
首碼,不允許重複。Span資料是否上報會受到採樣策略影響,您可以通過調整採樣策略來保證重要訊息被正確上報,更多資訊請參見調用鏈取樣模式選擇(3.2.8以下探針版本)。
如果調用鏈中無對應的業務參數資訊,請檢查擷取規則的參數是否配置正確。
在業務參數擷取規則地區單擊新增規則,填寫規則資訊並儲存。
規則名稱:該條規則的可讀名稱。
Attribute名稱:該條規則提取出的值在Span中對應的Attribute名稱,預設以biz.開頭,後續由多個單片語成,每個單詞僅允許由大小寫字母、數字、短劃線(-)、底線(_)組成,單詞與單詞之間必須有一個半形句號(.)分隔。最多允許存在10個單詞。
參數提取類型:需要提取的參數類型。
生效介面(HTTP類型):該條規則作用的HTTP介面範圍,探針僅對匹配成功的介面提取相應參數。
異常類名(異常類型):該條規則作用的異常類名範圍,探針僅對匹配成功的異常提取相應參數。
文本編碼類別型:待提取參數文本的編碼類別型。
參數擷取規則:定義待提取參數所在的實際載體來源和提取後的處理方式,支援配置多個參數來源和提取步驟。若多個來源均可提取到參數,排序在前的參數提取步驟優先順序高於後者。更多資訊,請參見參數擷取規則樣本。
參數來源:待提取參數所在的實際載體來源,對於Header、Cookie、Parameter,需要您填寫相應的Key來初步提取,對於Body、Message,則代表載體為整個對象。
參數處理步驟:流式的參數處理步驟,用於從參數載體中逐步解析出最終的參數值。您可以添加多條參數處理步驟,前者的解析結果會成為後者的輸入。如果不添加處理步驟,則提取到的參數值為載體對象的Json文本。更多資訊,請參見參數處理步驟最佳實務。
支援的參數處理方式:
Ognl:入參要求為Object,支援點標記法的Ognl語句,樣本:
#this.data.getCode()
。JsonPath:入參要求為JsonString,支援點標記法的JsonPath語句,樣本:
$.data.code
。Regex:入參要求為String,支援基於命名分組的Regex語句,待提取的子串對應名為res的分組,樣本:
.*from:(?<res>[a-z]+).*
。
是否啟用:該條規則是否啟用。
生效驗證
參數擷取規則配置完成後,無需重啟應用即可生效。跳轉到調用鏈分析頁面查看相關調用鏈,如果對應介面的Span Attribute有自訂的Attribute被寫入,說明擷取規則生效。
找到新增的規則對應的Attribute名稱。
在調用鏈分析頁面添加
attributes.$attributesName
作為查詢條件,過濾相關Span。單擊任意一條Trace,在對應的Span下可以看到自訂的Attributes。
管理規則
啟用/禁用規則:在目標規則右側設定是否啟用開關。
編輯和刪除:在目標規則右側單擊編輯和刪除,可以修改或刪除對應規則。
大量刪除:選中需要刪除的擷取規則,並單擊大量刪除。
批量複製:選中需要複製的擷取規則,並單擊批量複製至其他應用,在彈窗中選擇複製到其他所有應用或者選擇指定應用。
說明批量複製至其他應用需要1~2分鐘時間生效。
該功能僅複製參數擷取規則,其配套的自訂錯誤不會被複製到目標應用。
參數擷取規則要求Attribute名稱唯一,如果目標應用已經存在同樣的Attribute名稱,則該條規則不會被複製到目標應用。
參數擷取規則樣本
Ognl
Ognl語句是一種對象訪問語言,允許使用者通過運算式擷取Java對象中的屬性,或者執行Java對象的方法。Ognl作為參數處理方法,允許您對使用了@ResponseBody或者@RequestBody註解標註的Java對象進行提取。提取結果會被轉為一個String(如果是對象會被轉為Json字串),便於您做進一步提取。樣本:
@RestController
@RequestMapping("/components/api/v1/mall")
public class MallController {
@RequestMapping("/product")
@ResponseBody
public ResponseBody product(@RequestBody RequestBody req) {
// 您的業務代碼
}
static class RequestBody {
String requestId;
Map<String, String> queryParam;
public String getQueryJsonStr() {
return JSON.toJsonString(queryParam);
}
}
static class ResponseBody {
int code;
boolean success;
String message;
}
}
如果您希望提取RequestBody中的requestId欄位,可以將擷取規則設定如下。
如果您希望提取ResponseBody中的code欄位,可以將擷取規則設定如下。
Ognl支援您調用對象中的get方法來擷取欄位,如果您希望提取RequestBody中getQueryJsonStr()方法的執行結果,可以將擷取規則設定如下。
在使用前請保證該類存在該方法。
JsonPath
JsonPath語句是一種Json字串提取語言,允許使用者通過運算式擷取Json String中的屬性。JsonPath作為參數處理方法,允許您對Json字串進行提取。樣本:
{
"code": 200,
"message": "Query success.",
"success": true,
"data": {
"name": "John",
"age": 21
}
}
如果您希望提取上述JSON中data.age欄位,可以將擷取規則設定如下。
Regex
Regex語句即Regex,用於描述、匹配一系列符合某個句法規則的字串。Regex作為參數處理方法,允許您對待提取字串進行正則匹配,並將匹配到的名稱為res的分組作為提取結果。樣本:
Regex預設為從頭匹配,如果為任意匹配,請在語句前後添加.*
。
https://test.aliyun.com/v2/workitem#requestId=0c978f115b6f7&cityCode=34&env=online
如果您希望提取上述URL中的cityCode部分,可以將擷取規則設定如下。
實際範例
如下樣本為HTTP應用的響應Body對象。
class DemoResponse {
int code = 200;
boolean success = true;
String message = "text content";
String extraInfo = "{\"id\": 15, \"cityInfo\": \"from:hangzhou,to:beijing\"}";
public String getExtraInfo() {
return this.extraInfo;
}
}
如果希望從extraInfo欄位中提取cityInfo的from城市名,可以將擷取規則設定如下。
探針實際的提取與處理過程如下:
從響應中擷取到DemoResponse對象。
執行
#this.getExtraInfo()
語句,擷取到extraInfo欄位。執行
$.cityInfo
語句,將extraInfo欄位的值當作JsonString解析,並擷取到其中的cityInfo欄位。執行
^from:(?<res>[a-z]+).*
語句,將cityInfo欄位的值當做String解析,匹配到res命名的分組,即hangzhou
子串。把
hangzhou
作為提取結果寫入Span的Attribute。
參數處理步驟最佳實務
參數處理原理
參數處理步驟支援您從參數載體中進一步檢索和過濾需要的資訊,可以理解為一種流式映射規則,上一步的輸出會作為下一步的輸入。
不同的參數處理方法對輸入有一定的要求,如果輸入不滿足要求,則會直接中止後續流程,把當前結果作為最終值記錄下來。
參數處理方法 | 輸入 | 輸出 |
Ognl | 任意的Java對象 | String(如果處理結果為一個對象,會序列化為Json字串) |
JsonPath | JSON字串 | String |
Regex | String | String |
效能開銷
參數處理步驟涉及序列化/還原序列化、Java反射、正則匹配等邏輯,是整個業務參數提取環節中效能損耗佔比最高的部分,不建議對RT要求高和效能要求高的介面配置過多參數處理步驟。如果您需要對這樣的介面進行提取,可以考慮適當地對業務進行改造。
如果安全合規允許,可以考慮在業務中把對應參數直接寫入Header等位置。
採用OTelSDK手動為把相關參數寫入Span的Attribute,具體操作請參見通過OpenTelemetry Java SDK為調用鏈增加自訂埋點。
參數處理語句合法性
為了保證提取邏輯的安全性,參數處理語句相比開源實現有更嚴格的限制,詳情如下:
參數處理方法 | 文法參考 | 額外文法限制 | 正確樣本 |
Ognl | 僅支援點標記法的欄位/方法訪問,且調用方法必須為get開頭。最大支援的訪問深度為10。 | #this.extraInfo.getPid() | |
JsonPath | 僅支援點標記法的欄位訪問。最大支援的訪問深度為10。 | $.cityInfo | |
Regex | 必須有且僅有一個名為res的分組表示被提取的結果。 | ^from:(?<res>[a-z]+).* |
自訂錯誤規則
如果提取到的參數命中了自訂錯誤規則,該參數所在Span會被標記為錯誤Span。如果錯誤發生在某次服務訪問中,該次錯誤會被統計到arms_$callType_requests_error_count
指標中,您可以對該規則配置警示。
自訂錯誤指標統計不受採樣策略影響,未被採樣的錯Span也會被正常統計。
服務訪問類型及可用維度請參見應用監控指標說明。
設定自訂錯誤規則
在自訂錯誤設定地區開啟自訂錯誤碼開關,開啟自訂錯誤碼功能。
單擊添加匹配規則,新增一條匹配規則。
指定對應的業務參數擷取規則,並設定錯誤過濾規則。
單擊儲存,無需重啟應用,規則會在1~2分鐘後生效。
生效驗證
自訂錯誤配置完成後,無需重啟應用即可生效。跳轉到調用鏈分析頁面查看錯誤Span中是否有符合自訂錯誤條件的Span。
確認錯誤匹配規則對應的Attribute名稱與條件。
在調用鏈分析頁面選擇所有錯誤Span作為查詢條件,查看所有錯誤Span。
單擊任意一條Trace,查看Attribute是否與配置的規則相匹配。
下圖樣本中biz.resp.body的值為670,滿足大於499的錯誤匹配規則。
進入應用概覽頁面,可以看到錯誤數被正確納入總錯誤數大盤。
效能開銷
業務參數提取功能會給您的應用帶來一定的額外開銷,開銷的主要來源為提取過程的序列化/還原序列化及反射操作。本文構建了一個測試Demo來驗證業務參數提取功能的基本開銷,Demo啟動並執行基本情況如下:
Pod規格:1c2g × 1
服務端存在5個HTTP介面,施壓機按照2000 QPS分別調用5個服務端介面產生Span,每個介面對應一種參數提取來源。
測試組態:每100次調用會提取出240個自訂參數,執行20次正則處理,40次JsonPath處理,40次Ognl處理。
開啟擷取規則後的開銷對比:
消耗對象 | 基準(不開啟該功能) | 開啟該功能 | 開銷增幅 |
CPU | 0.230 c | 0.257 c | +0.027 c |
記憶體(啟動後20分鐘) | 575 MB | 693 MB | +118 MB |
RT | 101 ms | 101 ms | +0 ms |
常見問題
什麼情況下會導致參數提取失敗?
如果您的提取來源為Body,請確認您的應用是否使用了SpringMVC,方法所在類添加了@Controller註解,以及對對應方法和參數添加了@RequestBody和@ResponseBody註解。
如果您的提取來源為Response中的Cookie,目前僅支援Tomcat 7.0.4-9.x版本、Undertow 1.4.0.Final+版本擷取,建議您將提取來源替換為Request中的Cookie。
異常的提取生效範圍?
Java探針僅會對拋到Span外部的自訂異常進行攔截,對於內部的關鍵方法,如果需要提取其中的異常資訊並標識為錯誤,可以通過監控方法自訂功能為該方法建立埋點,具體操作請參見監控方法自訂。
SpringMVC應用中常見註解的參數提取應該如何配置?
當前已支援的SpringMVC註解與相關配置的對應關係如下所示:
註解 | 參數提取類型 | 參數 |
@RequestParam | HTTP服務端請求 | Parameter |
@RequestHeader | HTTP服務端請求 | Header |
@CookieValue | HTTP服務端請求 | Cookie |
@RequestBody | HTTP服務端請求 | Body |
@ResponseBody | HTTP服務端響應 | Body |
目前不支援的業務參數來源應該如何提取?
您可以通過引入OpenTelemetry SDK為應用添加自訂埋點,並將希望提取的業務參數作為Attributes寫入Span。詳情請參見通過OpenTelemetry Java SDK為調用鏈增加自訂埋點。
自訂參數擷取規則是否支援從RequestBodyAdvice和ResponseBodyAdvice修飾過的Body對象中提取?
支援。ARMS探針對Body的提取時機發生在使用者定義的BodyAdvice之後,Spring內建的BodyAdvice之前。