All Products
Search
Document Center

Application Real-Time Monitoring Service:Connect frontend and backend traces

Last Updated:Jun 20, 2026

ARMS Real User Monitoring (RUM) allows you to use a user session as a starting point to track errors, slow performance, and exceptions during user interactions. By integrating with ARMS Application Monitoring, you can achieve end-to-end tracing to streamline your issue analysis workflow. This topic describes how to connect frontend and backend traces for mobile applications.

Prerequisites

  • Your mobile application (Android or iOS) is instrumented with the latest RUM SDK. For more information, see Monitor Android apps.

    Note

    The SDK version must be 0.2.0 or later for Android and 0.2.0 or later for iOS.

  • Your backend application is monitored by ARMS Application Monitoring or Managed Service for OpenTelemetry. For more information, see Integration guide.

  • Your backend application provides a web service (HTTP) to parse headers and correlate the trace context.

Important

Connecting traces between frontend and backend applications across different regions is no longer supported. If your frontend and backend applications are in different regions, go to the CloudMonitor 2.0 console and instrument your frontend application in the same region and workspace as your backend application.

Supported trace protocols

  • SkyWalking: v3 (for SkyWalking 8.x agents)

  • OpenTelemetry (W3C)

Procedure

Add service domains and enable trace propagation

  1. Log on to the ARMS console.

  2. In the left-side navigation pane, choose Real User Monitoring > Application List, and then select your region in the top navigation bar.

  3. Click the name of your application, and then click Application Settings.

  4. In the Request Management section, configure your service domain.

    Important

    Do not add third-party service domains as your own. Otherwise, trace propagation may fail.

    Add your service domain, turn on the Trace Propagation switch, and select the propagation protocol that corresponds to your backend service.

    Note

    Ensure your backend application is already instrumented for tracing in ARMS. For more information, see Integration guide.

    Format name

    Format

    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. Click Confirm. The trace propagation configuration is automatically pushed to your mobile application.

    Important
    • The configuration may take a few minutes to apply on the client side, depending on user behavior. By default, the SDK pulls the configuration once when the app is cold-started. It also pulls the configuration again if the app is reopened after running in the background for more than 30 seconds.

    • Although mobile applications are not subject to the cross-origin resource sharing (CORS) policy of web applications, your server-side gateway must support the propagation of request headers for each protocol. Otherwise, the backend service cannot receive the headers, and the connection between RUM and backend traces will fail.

Verify the configuration

This section uses the SkyWalking v3 propagation protocol as an example to verify the configuration.

Android

Use the App Inspection tool in Android Studio to check for sw8 protocol information in network request headers. The presence of this information confirms a successful configuration.

iOS

Use the Xcode Profile tool to check for sw8 protocol information in network request headers. To do this, in the Xcode toolbar, choose Product > Profile > Network.

In the Instruments interface, select the HTTP Traffic track. From the drop-down list in the lower-left corner, switch to the List: HTTP Transactions view. Select the target request and check for the injected sw8 header in the Request Headers section of the details pane on the right.

Configure backend trace correlation

To establish a complete end-to-end trace, you must also configure your backend application. The supported backend application types and instrumentation methods are as follows:

Java application

Application Monitoring agent

The ARMS Application Monitoring agent has built-in support for the OpenTelemetry protocol. Therefore, you can correlate traces with RUM without extra configuration. However, you must ensure the following:

  • The Application Monitoring agent must be version 2.x, 3.x, or 4.x. For the best experience, we recommend upgrading to version 4.x.

  • A mainstream web container, such as Tomcat, Jetty, WebLogic, or Undertow, and a supported framework, such as SpringBoot or SpringMVC, must be used. For a complete list of supported components and frameworks, see Java components and frameworks supported by Application Monitoring.

For instructions on how to install the Application Monitoring agent, see Monitor Java applications.

OpenTelemetry

You can instrument your application with OpenTelemetry and report data to ARMS (Managed Service for OpenTelemetry). Two methods are available: auto-instrumentation and manual instrumentation.

  • Auto-instrumentation requires no extra configuration to correlate traces with RUM because OpenTelemetry supports most mainstream frameworks.

    Note

    For information about the Java frameworks that OpenTelemetry supports, see Report Java application data by using OpenTelemetry.

  • With manual instrumentation, you must use the OpenTelemetry SDK's extension mechanism to correlate traces. This process involves parsing the trace context from the traceparent and tracestate headers of frontend requests. The following code provides an example for a SpringBoot application:

    1. Add the OpenTelemetry dependencies.

      <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. Add the W3C propagator during OpenTelemetry initialization.

      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)
              // Add the W3C propagator here.
              .setPropagators(ContextPropagators.create(
                      TextMapPropagator.composite(W3CTraceContextPropagator.getInstance(), W3CBaggagePropagator.getInstance()))
               ).buildAndRegisterGlobal();
      // An extended Tracer is required here.
      tracer = ExtendedTracer.create(openTelemetry.getTracer("com.example.tracer", "1.0.0"));
    3. In the business interface, add the headers parameter, parse the trace context from the request header, and set the parent.

      // Add the request header parameter in the Controller to parse the trace context.
      @RequestMapping("/test")
      public String test(@RequestHeader Map<String, String> headers) {
          Span span = OpenTelemetrySupport.getTracer()
                  .spanBuilder("/test")
                  // Parse the parent span from the headers.
                  .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

For the complete instrumentation procedure, see Java Agent plugin.

SkyWalking currently provides only the Java Agent for instrumentation. You only need to follow the instructions in the linked document to correlate RUM and backend traces.

Protocol matching: The sw8 (v3) protocol configured on the RUM side corresponds to the SkyWalking 8.x agent.

Go application

OpenTelemetry

For the complete instrumentation procedure, see Report Go application data by using OpenTelemetry.

Follow the documentation to instrument your application. Then, generate a span from the request context in the HTTP request handler to correlate it with the RUM trace.

// Initialize the tracer.
tracer := otel.Tracer(common.TraceInstrumentationName)
// Generate a span from the request context.
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

For the complete instrumentation procedure, see Report Go application data by using SkyWalking.

Follow the documentation to instrument your application. We recommend using the skywalking-go method, which supports mainstream web frameworks like Gin, go-restful, http, go-kratos v2, go-micro, and go-resty. This allows you to correlate RUM traces without code modification.

To manually parse the trace context from HTTP request headers, use the following code:

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

Python application

OpenTelemetry

For the complete instrumentation procedure, see Report Python application data by using OpenTelemetry.

Follow the documentation to instrument your application. Then, parse the span context from the HTTP request headers to correlate with the RUM trace. The following is a code sample:

// Initialize the 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)

    // Parse the trace context from the headers.
    carrier ={'traceparent': headers['Traceparent'], 'tracestate': headers['Tracestate']}
    ctx = TraceContextTextMapPropagator().extract(carrier=carrier)

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

SkyWalking

For the complete instrumentation procedure, see Report Python application data by using SkyWalking.

Follow the documentation to instrument your application. Then, parse the span context from the HTTP request headers to correlate with the RUM trace. The following is a code sample:

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

# Configure SkyWalking. Adjust parameters as needed.
config.init(agent_collector_backend_services='<endpoint>',
            agent_authentication='<auth-token>')

agent.start()

# Sample HTTP request handler that requires passing in HTTP request headers.
def handle_request(headers):
    # Extract trace information from the request 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)

    # Extract the trace context from the carrier.
    context = get_context().extract(carrier)
    
    # Create a new span to process the request.
    with get_context().new_entry_span(op='operation_name') as span:
        # Process the request here. The span is automatically submitted when finished.
        ...

# Simulate a received HTTP request header that includes sw8.
incoming_headers = {
    'sw8': '1-My40LjU=-MTY1MTcwNDI5OTk5OA==-xxxx-xx-x-x==',  # Sample value. Use the actual value from the request.
    # Other headers...
}

# Call the function to process the request.
handle_request(incoming_headers)

View end-to-end trace data

After you connect the frontend and backend traces, you can view the call chain for frontend requests in the ARMS RUM console.

Click View Call Chain to see the complete call chain and application topology for the request. You can then diagnose slow or erroneous requests by combining the request details from RUM with the backend trace data.

The top-level span represents the entry span from RUM. The entry span is categorized by client-side instrumentation type as follows:

  • Web & H5: Application name is rum-browser, span name prefix is "browser.request:".

  • Mini-programs: Application name is rum-miniapp, span name prefix is "miniapp.request:".

  • Android: Application name is rum-android, span name prefix is "android.request:".

  • iOS: Application name is rum-ios, span name prefix is "ios.request:".

You can also use the topology graph to visualize the upstream and downstream services for the entire request.