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.
NoteThe 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.
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
Log on to the ARMS console.
-
In the left-side navigation pane, choose , and then select your region in the top navigation bar.
-
Click the name of your application, and then click Application Settings.
-
In the Request Management section, configure your service domain.
ImportantDo 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.
NoteEnsure your backend application is already instrumented for tracing in ARMS. For more information, see Integration guide.
Format name
Format
sw8: {sample}-{trace-id}-{segment-id}-{0}-{service}-{instance}-{endpoint}-{peer}
traceparent : {version}-{trace-id}-{parent-id}-{trace-flags}
tracestate: rum={version}&{appType}&{pid}&{sessionId}
-
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 .
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.
NoteFor 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
traceparentandtracestateheaders of frontend requests. The following code provides an example for a SpringBoot application:-
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> -
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")); -
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.