全部產品
Search
文件中心

Application Real-Time Monitoring Service:App監控關聯前後端Trace

更新時間:Aug 09, 2024

ARMS使用者體驗監控支援以使用者會話作為切入點,追蹤使用者與應用互動過程中的錯誤、緩慢、異常問題,通過與ARMS應用監控聯動,實現端到端分析,協助您打通問題分析鏈路。本文介紹移動端監控如何?端到端Trace打通。

前提條件

  • 確保您的移動端應用(包含Android、iOS)已接入RUM新版SDK。具體操作,請參見接入行動裝置 App

    說明

    Android SDK版本號碼≥0.2.0 ,iOS SDK版本號碼≥0.2.0。

  • 確保您的後端應用,已接入ARMS應用監控或Managed Service for OpenTelemetry。具體操作,請參見接入指南

  • 確保您的後端應用,有提供Web服務(HTTP),用於解析Header,關聯Trace上下文。

支援的Trace協議類型

  • Skywalking:v3版本(Skywalking 8.*)

  • OpenTelemetry(w3c)

接入操作

添加自身服務網域名稱並開啟Trace透傳

  1. 登入ARMS控制台
  2. 在左側導覽列選擇使用者體驗監控 > 應用列表,並在頂部功能表列選擇目標地區。

  3. 單擊目標應用程式名稱,然後單擊應用設定

  4. 要求管理地區配置自身服務網域名稱。

    重要

    請勿將第三方服務網域名稱添加為自身服務,否則Trace打通可能不會生效。

    添加自身服務網域名稱,開啟鏈路打通開關,並選擇後端服務對應的透傳協議。

    說明

    後端應用需要先接入ARMS鏈路追蹤,具體操作,請參見接入指南

    image

    透傳格式名稱

    格式

    sw8(Skywalking v3)

    sw8: {sample}-{trace-id}-{segment-id}-{0}-{service}-{instance}-{endpoint}-{peer}

    tracecontext

    traceparent : {version}-{trace-id}-{parent-id}-{trace-flags}

    tracestate: rum={version}&{appType}&{pid}&{sessionId}

  5. 單擊確認,系統將會自動推送Trace打通配置到移動端。

    重要
    • 端側配置的生效,可能會有分鐘級延遲,具體取決於使用者側行為,SDK預設在App冷啟動時會拉取一次配置,切至後台超過30s後再次開啟時,也會重新拉取。

    • 需要注意,雖然移動端不存在Web的CORS策略限制,但各協議透傳的Request Header需要服務端網關支援透傳,否則後端服務無法接受Header,也就無法實現RUM與Trace打通。

驗證是否配置成功

此處以SkyWalking V3版本透傳協議為例驗證Trace是否配置成功。

Android

可通過Android Studio內建的App Inspection工具查看網路請求的Request Headers中是否攜帶了sw8協議資訊判斷是否接入成功。image

iOS

可通過Xcode Profile工具(在Xcode工具列選擇Product > Profile > Network)查看網路請求的Request Headers中是否攜帶了sw8協議資訊判斷是否接入成功。

image

配置後端應用Trace串聯

為了打通完整Trace鏈路,還需要對後端應用進行配置,目前支援的後端應用類型以及接入方式如下:

Java應用

使用ARMS應用監控探針接入

ARMS應用監控探針預設整合了對OpenTelemetry協議的支援,因此無需額外配置,即可實現與RUM Trace關聯,但需要確保以下兩點:

  • 支援的ARMS應用監控探針版本:2.x、3.x、4.x,為了獲得更好的使用體驗,推薦升級到4.x版本。

  • 支援的Web容器和架構:支援Tomcat、Jetty、WebLogic、Undertow等主流Web容器,以及SpringBoot、SpringMVC等架構。支援的完整組件和架構請參見ARMS應用監控支援的Java組件和架構

ARMS應用監控探針接入操作請參見開始監控Java應用

使用OpenTelemetry接入

通過OpenTelemetry接入ARMS(Managed Service for OpenTelemetry),目前分為兩種方式:自動埋點和手動埋點。

  • 自動埋點情境下,由於OpenTelemetry已經支援了絕大多數主流架構,因此,無需額外配置,即可實現與RUM Trace的串聯。

    說明

    OpenTelemetry支援的Java架構,請參見通過OpenTelemetry上報Java應用資料

  • 手動埋點情境下,需要通過OpenTelemetry SDK提供的擴充機制,實現與RUM Trace的串聯,即從前端要求標頭(traceparent、tracesate)中,解析出Trace上下文,以下是Springboot情境程式碼範例:

    1. 引入OpenTelemetry的依賴項。

      <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-api</artifactId>
      </dependency>
      <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-sdk-trace</artifactId>
      </dependency>
      <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-extension-annotations</artifactId>
        <version>1.18.0</version>
      </dependency>
      <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-exporter-otlp</artifactId>
      </dependency>
      <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-sdk</artifactId>
      </dependency>
      <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-semconv</artifactId>
        <version>1.30.1-alpha</version>
      </dependency>
      <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-sdk-extension-autoconfigure</artifactId>
        <version>1.34.1</version>
      </dependency>
      <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-extension-incubator</artifactId>
        <version>1.35.0-alpha</version>
      </dependency>
    2. 在OpenTelemetry初始化時,添加W3C Propagator。

      Resource resource = Resource.getDefault()
              .merge(Resource.create(Attributes.of(
                      ResourceAttributes.SERVICE_NAME, "otel-demo",
                      ResourceAttributes.HOST_NAME, "xxxx"
      )));
      
      SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
              .addSpanProcessor(BatchSpanProcessor.builder(OtlpHttpSpanExporter.builder()
                      .setEndpoint("Your Endpoint")
                      .addHeader("Authentication", "Your Token")
                      .build()).build())
              .setResource(resource)
              .build();
      
      openTelemetry = OpenTelemetrySdk.builder()
              .setTracerProvider(sdkTracerProvider)
              // 這裡添加W3C Propagator
              .setPropagators(ContextPropagators.create(
                      TextMapPropagator.composite(W3CTraceContextPropagator.getInstance(), W3CBaggagePropagator.getInstance()))
               ).buildAndRegisterGlobal();
      // 這裡需要使用擴充的Tracer
      tracer = ExtendedTracer.create(openTelemetry.getTracer("com.example.tracer", "1.0.0"));
    3. 在業務介面中,添加headers參數,並從要求標頭中解析Trace上下文,設定parent。

      // Controller中添加請求header參數,用於解析Trace上下文
      @RequestMapping("/test")
      public String test(@RequestHeader Map<String, String> headers) {
          Span span = OpenTelemetrySupport.getTracer()
                  .spanBuilder("/test")
                  // 從headers中解析parent span
                  .setParentFrom(OpenTelemetrySupport.getContextPropagators(), headers)
                  .setSpanKind(SpanKind.SERVER)
                  .startSpan();
          try (Scope scope = span.makeCurrent()) {
              // do something
          } catch (Throwable t) {
              span.setStatus(StatusCode.ERROR, "handle parent span error");
          } finally {
              span.end();
          }
          return "success";
      }

使用SkyWalking接入

完整接入方式請參見Java Agent外掛程式

SkyWalking目前僅提供了Java Agent接入方式,您只需要按照上述文檔接入,即可實現RUM與後端Trace串聯。

和RUM側配置的協議匹配要求:sw8(v3版本)對應SkyWalking 8.x版本探針。

Go應用

通過OpenTelemetry接入

完整接入方式請參見通過OpenTelemetry上報Go應用資料

按照文檔接入,然後在HTTP請求Handler中,通過request context產生Span,即可實現與RUM Trace串聯。

// 初始化tracer
tracer := otel.Tracer(common.TraceInstrumentationName)
// 通過request context產生span
handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
    ctx := req.Context()
    span := trace.SpanFromContext(ctx)
    // do something
    w.Write([]byte("Hello World"))
})

使用SkyWalking接入

完整接入方式請參見通過SkyWalking上報Go應用資料

按照文檔接入,推薦採用skywalking-go接入方式,該方式支援了主流的Web服務架構,如gin、go-restful、http、go-kratos v2、go-micro、go-resty等,無需修改代碼即可實現與RUM Trace串聯。

如果您希望手動從HTTP要求標頭中解析出Trace上下文,也可參考以下代碼實現:

//Extract context from HTTP request header `sw8`
span, ctx, err := tracer.CreateEntrySpan(r.Context(), "/api/test", func(key string) (string, error) {
		return r.Header.Get(key), nil
})

Python應用

通過OpenTelemetry接入

完整接入方式請參見通過OpenTelemetry上報Python應用資料

按照文檔接入,然後從HTTP要求標頭中解析Span上下文,實現與RUM Trace串聯,程式碼範例如下:

// 初始化tracer
trace.set_tracer_provider(TracerProvider())
trace.get_tracer_provider().add_span_processor(BatchSpanProcessor(ConsoleSpanExporter()))

tracer = trace.get_tracer(__name__)

@app.route('/test')
def test():
    headers = dict(request.headers)

    // 從headers中解析trace context
    carrier ={'traceparent': headers['Traceparent'], 'tracestate': headers['Tracestate']}
    ctx = TraceContextTextMapPropagator().extract(carrier=carrier)

    with tracer.start_span("test", context=ctx):
        // do something
        return "success"

使用SkyWalking接入

完整接入方式請參見通過SkyWalking上報Python應用資料

按照文檔接入,然後從HTTP要求標頭中解析Span上下文,實現與RUM Trace串聯,程式碼範例如下:

from skywalking import config, agent
from skywalking.trace.context import SpanContext, get_context
from skywalking.trace.carrier import CarrierItem

# 配置 SkyWalking,根據需要調整相關參數
config.init(agent_collector_backend_services='<endpoint>',
            agent_authentication='<auth-token>')

agent.start()

# 樣本 HTTP 要求處理函數,需要傳入 HTTP 要求的 headers
def handle_request(headers):
    # 從要求標頭 headers 中提取追蹤資訊
    carrier_items = []
    for item in SpanContext.make_carrier():
        carrier_header = headers.get(item.key.lower())
        if carrier_header:
            carrier_items.append(CarrierItem(item.key, carrier_header))

    carrier = SpanContext.make_carrier(carrier_items)

    # 從 Carrier 中提取追蹤上下文
    context = get_context().extract(carrier)
    
    # 建立一個新 Span 來處理請求
    with get_context().new_entry_span(op='operation_name') as span:
        # 在這裡處理請求,並在結束時自動認可 Span
        ...

# 類比接收到的 HTTP 要求 header 包含 sw8
incoming_headers = {
    'sw8': '1-My40LjU=-MTY1MTcwNDI5OTk5OA==-xxxx-xx-x-x==',  # 樣本值,實際根據請求填寫
    # 其他 header...
}

# 調用函數處理請求
handle_request(incoming_headers)

查看端到端完整Trace資料

完成前後端Trace打通後,您可以在ARMS使用者體驗控制台查看前端請求對應的調用鏈。

image

單擊查看調用鏈,可以看到請求的完整調用鏈路,以及應用拓撲。此時,可以結合RUM側的請求詳細資料,與後端Trace資料,分析錯慢請求問題。

image

最上面的Span即代表RUM入口Span,根據端側接入類型,分為以下幾種:

  • Web & H5情境:應用程式名稱:rum-browser,Span名稱首碼:"browser.request:"

  • 小程式情境:應用程式名稱:rum-miniapp,Span名稱首碼:"miniapp.request: "

  • 移動端Android情境:應用程式名稱:rum-android,Span名稱首碼:"android.request: "

  • 移動端iOS情境:應用程式名稱:rum-ios,Span名稱首碼:"ios.request: "

同時,也可以通過拓撲圖,直觀地看到整個請求的上下遊服務拓撲。

image