天天看點

【Azure 應用程式見解】Application Insights Java Agent 3.1.0的使用實驗,通過修改單個URL的采樣率來減少請求及依賴項的資料采集

問題描述

近日好消息,如果是一個Java Spring Cloud的項目,想使用Azure Applicaiton Insights來收集日志及一些應用程式見解。但是有不願意內建SDK來修改代碼或者配置,有沒有一種更好的辦法呢? 答案是有。

在2020年,微軟推出了“Java 無代碼應用程式監視 Azure Monitor Application Insights” 代理工具 Application Insights Agent 3.x。它 無需更改代碼,隻需更改幾個配置即可啟用 Java 代理。官方的宣傳語為:

Java 代理可在任何環境中正常工作,并允許你監視所有 Java 應用程式。 換句話說,無論你是在 VM 上、本地、AKS 中還是在 Windows、Linux 上運作 Java 應用,不管什麼位置,Java 3.0 代理都可以監視你的應用。

不再需要将 Application Insights Java SDK 添加到你的應用程式,因為 3.0 代理會自動收集請求、依賴項并自行記錄所有内容。

你仍可以從應用程式發送自定義遙測。 3.0 代理會跟蹤它并将它與所有自動收集的遙測資料相關聯。

3.0 代理支援 Java 8 及更高版本。

使用方法也非常的簡單,三個步驟:下載下傳代理到本地項目,配置Application Insights連接配接字元串,在java啟動指令中添加代理參數( -javaagent:agent/applicationinsights-agent-3.1.0.jar ) 

快速啟用Java Agent:

1.下載下傳代理 applicationinsights-agent-3.1.0.jar

2.将 JVM 指向該代理,将 

-javaagent:path/to/applicationinsights-agent-3.1.0.jar

 添加到應用程式的 JVM 參數。如

java  -javaagent:agent/applicationinsights-agent-3.1.0.jar -jar target/spring-boot-0.0.1-snapshot.jar      

3.将代理指向 Application Insights 資源

通過設定環境變量,将代理指向 Application Insights 資源:

APPLICATIONINSIGHTS_CONNECTION_STRING=InstrumentationKey=...

另一種方法是建立一個名為 

applicationinsights.json

 的配置檔案,并将其置于 

applicationinsights-agent-3.1.0.jar

 所在的目錄中,該檔案包含以下内容:

{
  "connectionString": "InstrumentationKey=..."
}      

可以在 Application Insights 資源中找到連接配接字元串:

【Azure 應用程式見解】Application Insights Java Agent 3.1.0的使用實驗,通過修改單個URL的采樣率來減少請求及依賴項的資料采集

4.就這麼簡單!

現在啟動應用程式,并通路 Azure 門戶中的 Application Insights 資源以檢視監視資料。

 備注:監視資料可能需要幾分鐘時間才能在門戶中顯示。

效果展示:

【Azure 應用程式見解】Application Insights Java Agent 3.1.0的使用實驗,通過修改單個URL的采樣率來減少請求及依賴項的資料采集

以上展示成功的采集到Java應用的所有請求及請求所産生的兩個外部依賴,一個通路azure blob檔案,一個是請求部落格園文章位址。

但是,當站點的請求量巨大時候,Agent也将發送大量的請求,日志,依賴等等監控資料。 那是不是有什麼友善的辦法來解決資料量問題呢?是的。同樣可以通過采樣率(sampling)設定來實作這個目的。

Sampling有兩種方式:一種是應用的所有請求采樣率都下降,不要100%采集。 修改方式為在 

applicationinsights.json

 檔案中設定sampling的值。如下修改采樣率為50%.

{
   "connectionString": "InstrumentationKey=xxxxxxxxxxxxxx;EndpointSuffix=applicationinsights.azure.cn;IngestionEndpoint=https://xxxxxxxx.in.applicationinsights.azure.cn/",
   "role": {
      "name": "my test 3"
   },
   "sampling": {
      "percentage": 50
    }
}      

第二種方式,就是本文中将介紹的。采用指定特定的URL來修改次采樣率。

問題解決

使用Agent 3.0.3版本之後才支援的采樣代替(sampling overrides)功能。采樣替代允許替代預設采樣百分比,例如:

  • 将采樣百分比設定為 0(或某個小的值)以進行幹擾狀況檢查。
  • 将采樣百分比設定為 0(或某個小的值)以進行幹擾依賴項調用。
  • 針對重要請求類型(例如,

    /login

    ),将采樣百分比設定為 100,即使将預設采樣配置為低于此值也是如此。

 采樣代替的作用範圍為:

  • 傳入的請求。
  • 傳出的依賴項(例如,對另一個服務的遠端調用)。
  • 程序内依賴項(例如,服務的子元件所做的工作)。

對于采樣替代而言,屬性是一個非常重要的概念,它表示給定請求或依賴項的标準屬性和自定義屬性。對于一個URL請求而言,可以用以下的屬性值來作為配置條件:

HTTP 範圍

屬性 類型 說明

http.method

string HTTP 請求方法。

http.url

完整的 HTTP 請求 URL(采用 

scheme://host[:port]/path?query[#fragment]

 格式)。 例如:http://localhost:8080/out

http.status_code

數值 HTTP 響應狀态代碼。

http.flavor

HTTP 協定類型。

http.user_agent

用戶端發送的 HTTP User-Agent 标頭的值。

在本示例中,本Java應用有三個請求。http://localhost:8080, http://localhost:8080/blob 和http://localhost:8080/out。 三個請求的依賴項如下圖:

【Azure 應用程式見解】Application Insights Java Agent 3.1.0的使用實驗,通過修改單個URL的采樣率來減少請求及依賴項的資料采集

 為了把blob的請求以及它的依賴的所有請求都排除在請求之外。使用采樣代替功能,可以參考如下設定:

{
   "connectionString":"InstrumentationKey=xxxxxxxxxxxxxx;EndpointSuffix=applicationinsights.azure.cn;IngestionEndpoint=https://xxxxxxxx.in.applicationinsights.azure.cn/",
   "role": {
      "name": "my test 3"
   },
   "preview": {
      "sampling": {
         "overrides": [
            {
               "attributes": [
                  {
                     "key": "http.url",
                     "value": "https?://[^/]+/blob",
                     "matchType": "regexp"
                  }
               ],
               "percentage": 0
            }
         ]
      }
   }
}      

修改完 

applicationinsights.json

 檔案後,重新開機應用。驗證結果:

【Azure 應用程式見解】Application Insights Java Agent 3.1.0的使用實驗,通過修改單個URL的采樣率來減少請求及依賴項的資料采集

附件一:如果需要對多個請求URL進行采樣率修改。在節點overrides中的數組中不停加入attributes内容即可。如:

{
   "connectionString":"InstrumentationKey=xxxxxxxxxxxxxx;EndpointSuffix=applicationinsights.azure.cn;IngestionEndpoint=https://xxxxxxxx.in.applicationinsights.azure.cn/",
   "role": {
      "name": "my test 3"
   },
   "preview": {
      "sampling": {
         "overrides": [
            {
               "attributes": [
                  {
                     "key": "http.url",
                     "value": "https?://[^/]+/blob",
                     "matchType": "regexp"
                  }
               ],
               "percentage": 0
            },
            {
               "attributes": [
                  {
                     "key": "http.url",
                     "value": "https?://[^/]+/lulight/",
                     "matchType": "regexp"
                  }
               ],
               "percentage": 0
            }
         ]
      }
   }
}      

附件二:對整體采樣率設定為非常小,如1,但是對一些重點的URL則設定為100. 

{
   "connectionString": "InstrumentationKey=xxxxxxxxxxxxxx;EndpointSuffix=applicationinsights.azure.cn;IngestionEndpoint=https://xxxxxxxx.in.applicationinsights.azure.cn/",
   "role": {
      "name": "Java App Test 16"
   },
   "sampling": {
      "percentage": 1
   },
   "preview": {
      "sampling": {
         "overrides": [
            {
               "attributes": [
                  {
                     "key": "http.url",
                     "value": "http?://[^/]+/v1/member+(/[\\w-./?%&=]*)?$",
                     "matchType": "regexp"
                  }
               ],
               "percentage": 100
            },
            {
               "attributes": [
                  {
                     "key": "http.url",
                     "value": "http?://[^/]+/blob",
                     "matchType": "regexp"
                  }
               ],
               "percentage": 0
            },
            {
               "attributes": [
                  {
                     "key": "http.url",
                     "value": "http?://[^/]+/out",
                     "matchType": "regexp"
                  }
               ],
               "percentage": 100
            },
            {
               "attributes": [
                  {
                     "key": "http.url",
                     "value": "https?://[^/]+/lulight/p/14978216.html",
                     "matchType": "regexp"
                  }
               ],
               "percentage": 0
            }
         ]
      }
   }
}      

附件三:如何驗證正規表達式的正确性及在JAVA中的正确字元串(需要注意轉義)

驗證站點:https://c.runoob.com/front-end/854

【Azure 應用程式見解】Application Insights Java Agent 3.1.0的使用實驗,通過修改單個URL的采樣率來減少請求及依賴項的資料采集

 然後點選生成代碼,發現Java部分中所使用的字元串,COPY出來放入applicationinsights.json檔案中。

【Azure 應用程式見解】Application Insights Java Agent 3.1.0的使用實驗,通過修改單個URL的采樣率來減少請求及依賴項的資料采集

附件四:如果在啟動AI Java Agent 出現 “java.util.regex.PatternSyntaxException: Unclosed character class near index 28”, 則一定要根據#3中的方式來檢查 applicationinsights.json 中正規表達式是否正确

2021-07-27 15:47:46.936+08 ERROR c.m.applicationinsights.agent - ApplicationInsights Java Agent 3.1.0 failed to start
java.util.regex.PatternSyntaxException: Unclosed character class near index 28
http?://[^/]+/v1/member?/[^]+
                            ^
    at java.util.regex.Pattern.error(Pattern.java:1969)
    at java.util.regex.Pattern.clazz(Pattern.java:2562)
    at java.util.regex.Pattern.sequence(Pattern.java:2077)
    at java.util.regex.Pattern.expr(Pattern.java:2010)
    at java.util.regex.Pattern.compile(Pattern.java:1702)
    at java.util.regex.Pattern.<init>(Pattern.java:1352)
    at java.util.regex.Pattern.compile(Pattern.java:1028)
    at com.microsoft.applicationinsights.agent.internal.sampling.SamplingOverrides$RegexpMatcher.<init>(SamplingOverrides.java:179)
    at com.microsoft.applicationinsights.agent.internal.sampling.SamplingOverrides$RegexpMatcher.<init>(SamplingOverrides.java:173)
    at com.microsoft.applicationinsights.agent.internal.sampling.SamplingOverrides$MatcherGroup.toPredicate(SamplingOverrides.java:150)
    at com.microsoft.applicationinsights.agent.internal.sampling.SamplingOverrides$MatcherGroup.<init>(SamplingOverrides.java:123)
    at com.microsoft.applicationinsights.agent.internal.sampling.SamplingOverrides$MatcherGroup.<init>(SamplingOverrides.java:115)
    at com.microsoft.applicationinsights.agent.internal.sampling.SamplingOverrides.<init>(SamplingOverrides.java:28)
    at com.microsoft.applicationinsights.agent.internal.sampling.Samplers.getSampler(Samplers.java:9)
    at com.microsoft.applicationinsights.agent.internal.wasbootstrap.OpenTelemetryConfigurer.configure(OpenTelemetryConfigurer.java:39)
    at io.opentelemetry.sdk.autoconfigure.TracerProviderConfiguration.configureTracerProvider(TracerProviderConfiguration.java:40)
    at io.opentelemetry.sdk.autoconfigure.OpenTelemetrySdkAutoConfiguration.initialize(OpenTelemetrySdkAutoConfiguration.java:45)
    at io.opentelemetry.javaagent.tooling.OpenTelemetryInstaller.installAgentTracer(OpenTelemetryInstaller.java:36)
    at io.opentelemetry.javaagent.tooling.OpenTelemetryInstaller.beforeByteBuddyAgent(OpenTelemetryInstaller.java:27)
    at io.opentelemetry.javaagent.tooling.AgentInstaller.installComponentsBeforeByteBuddy(AgentInstaller.java:180)
    at io.opentelemetry.javaagent.tooling.AgentInstaller.installBytebuddyAgent(AgentInstaller.java:114)
    at io.opentelemetry.javaagent.tooling.AgentInstaller.installBytebuddyAgent(AgentInstaller.java:98)
    at com.microsoft.applicationinsights.agent.internal.wasbootstrap.MainEntryPoint.start(MainEntryPoint.java:89)
    at io.opentelemetry.javaagent.tooling.AgentInstallerOverride.installBytebuddyAgent(AgentInstallerOverride.java:11)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at io.opentelemetry.javaagent.bootstrap.AgentInitializer.startAgent(AgentInitializer.java:50)
    at io.opentelemetry.javaagent.bootstrap.AgentInitializer.initialize(AgentInitializer.java:30)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at io.opentelemetry.javaagent.OpenTelemetryAgent.premain(OpenTelemetryAgent.java:66)
    at com.microsoft.applicationinsights.agent.Agent.premain(Agent.java:41)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:386)
    at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:401)      

參考資料

Java 無代碼應用程式監視 Azure Monitor Application Insights:https://docs.azure.cn/zh-cn/azure-monitor/app/java-in-process-agent

采樣替代(預覽版)- 适用于 Java 的 Azure Monitor Application Insights:https://docs.azure.cn/zh-cn/azure-monitor/app/java-standalone-sampling-overrides

【完】

當在複雜的環境中面臨問題,格物之道需:濁而靜之徐清,安以動之徐生。 雲中,恰是如此!