問題描述
近日好消息,如果是一個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 資源中找到連接字符串:
4.就這么簡單!
現在啟動應用程序,並訪問 Azure 門戶中的 Application Insights 資源以查看監視數據。
備注:監視數據可能需要幾分鍾時間才能在門戶中顯示。
效果展示:
以上展示成功的采集到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 |
string | 完整的 HTTP 請求 URL(采用 scheme://host[:port]/path?query[#fragment] 格式)。 例如:http://localhost:8080/out |
http.status_code |
數值 | HTTP 響應狀態代碼。 |
http.flavor |
string | HTTP 協議類型。 |
http.user_agent |
string | 客戶端發送的 HTTP User-Agent 標頭的值。 |
在本示例中,本Java應用有三個請求。http://localhost:8080, http://localhost:8080/blob 和http://localhost:8080/out。 三個請求的依賴項如下圖:
為了把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
文件后,重啟應用。驗證結果:
附件一:如果需要對多個請求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
然后點擊生成代碼,發現Java部分中所使用的字符串,COPY出來放入applicationinsights.json文件中。
附件四:如果在啟動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
【完】