Developer

Add Tracing to your Windows Application

Add tracing to your native Windows OData app, upload the BTX that contains all collected trace data to the server, and view the trace information.

End-to-End Tracing

The E2ETracing component collects end-to-end step and request trace data including performance measurements and user actions. SDK libraries are instrumented for E2ETrace enablement. Furthermore, the E2ETrace component exposes APIs which allows developers to perform various, E2E tracing related tasks on the client.

  • E2E Transactions, Steps and Requests
    To perform E2E tracing, start an end-to-end transaction. A transaction defines the boundaries of an E2E tracing session.

    Within the context of an active E2E trace transaction, you can start several E2E steps. Steps can be logically mapped to a given use case or business scenarios. For example, an E2E step might be assigned to the phase of presenting your main screen and populating it with data.

    Steps can in turn consist of one to many E2E requests. An E2E request is an atomic logical entity generally bound to one network request. An E2E request could be mapped, for example, a GET request for fetching data, or a POST request that updates an entity on the server.

    A Business Transaction XML is generated as a result of running an E2E trace session. This XML file contains E2E trace relevant step and request data in a standard format. The framework allows for uploading the generated BTX to the SAP Mobile Platform Server, where BTX files are archived for further analysis.

  • Basic E2E Tracing
    These steps enable basic E2E trace enablement of an app. Custom E2E tracing is described later.
    1. Instantiate the E2E trace manager instance:
      //get the E2ETraceManager instance
      IE2ETraceManager traceManager = SupportabilityFacade.Instance.E2ETraceManager;
      
      Start a transaction; which is mandatory because E2E steps and requests must start within the context of an E2E transaction. Only one E2E transaction can be active at a time.
      IE2ETraceTransaction transaction = await traceManager.StartTransactionAsync("test.transaction.win");
      The call to E2ETraceManager StartTransaction creates and starts an E2E transaction. If there was an active transaction when calling the API, the old transaction ends and a new instance is created. You can query the active transaction (if any) using the E2ETraceManager ActiveTransaction API.
      var activeTransaction = SAP.Supportability.SupportabilityFacade.Instance.E2ETraceManager.ActiveTransaction;
      An E2E transaction can have two states: Started or Ended.
      An easy way to send out a traced request is to use the SAP HttpClient as this code illustrates:
      using (var tracedClient = new SAP.Net.Http.HttpClient()) {
      tracedClient.TracingControl.IsEnabled = true;
      await tracedClient.SendAsync(
      	() => new HttpRequestMessage(window.Context.Method, window.Context.Url) {
      		Content = ((window.Context.Content != null) ? new 
      		StringContent(window.Context.Content, Encoding.UTF8) : null)
      		}, HttpCompletionOption.ResponseContentRead, tokenSource.Token);
      	}
      }
      
    2. Start an E2E step and start a request. The request needs to be set up with it’s public API methods. The following code shows a basic scenario for a request within a step
      IE2ETraceStep step02 = transaction.StartStep();
      IE2ETraceRequest request0201 = step02.StartRequest();
      string passportHeader0201 = request0201.PassportHttpHeader;
      string correlationId0201 = request0201.CorrelationIdHttpHeader;
      request0201.SetRequestLine("GET http//www.test.com HTTP/1.1");
      requestHeaders = new Dictionary<string, string> { 
      	{"SAP-PASSPORT",passportHeader0201} ,
      	{"X-CorrelationID","correlationID0201"} 
      };
      request0201.SetRequestHeaders(requestHeaders);
      request0201.MarkSending();
      request0201.MarkSent();
      request0201.SetByteCountSent(102L);
      request0201.MarkReceiving();
      request0201.MarkReceived();
      request0201.SetByteCountReceived(202L);
      request0201.SetReturnCode("202");
      responseHeders = new Dictionary<string, string>() { 
      	{"Content-Length", "222"},
      	{"Content-Type", "application/xml"}
      };
      request0201.SetResponseHeaders(responseHeders);
      request0201.EndRequest();
      string earlyBTX = traceManager.Btx;
      step02.EndStep();
      traceManager.ActiveTransaction.EndTransaction();
      string btx = traceManager.Btx;
      
    3. The request can be stopped afterwards by calling the EndRequest() method just as the step after the request stopped by calling the EndStep() method by ending the transaction it implicitly gets called. Invoke E2ETraceManager EndTransaction() to close the E2E trace session:
      traceManager.ActiveTransaction.EndTransaction();
    4. This call ends the active steps and their running requests; additionally, the BTX document is generated and persisted in the applications sandbox. You can also call EndTransaction on the transaction instance itself:
      transaction.EndTransaction();
  • Custom E2E Tracing
    Although basic E2E tracing is sufficient in most cases, some apps may need to generate custom E2E trace data, which the Supportability framework provides. In this case, along with starting and ending an E2E transaction and E2E steps, the developer must also manage requests.
    1. Perform the steps in "Basic E2E Tracing".
    2. Start a step by calling E2ETransaction StartStep on a valid E2ETransaction instance. The transaction must be in status started in to start new steps; if the transaction is ended, attempts to start new steps will fail.
      var transaction = await 
      SAP.Supportability.SupportabilityFacade.Instance.E2ETraceManager.StartTransactionAsync("Transaction");
      transaction.StartStep();
      
      You can also call E2ETraceManager’s GetActiveTransaction API to retrieve the active transaction, and start the step using this one-line:
      SAP.Supportability.SupportabilityFacade.Instance.E2ETraceManager.ActiveTransaction.StartStep();
    3. Within an active step, create and start an E2E trace request:
      IE2ETraceStep step01 = transaction.StartStep();
      IE2ETraceRequest request0101 = step01.StartRequest();
      
    The E2ETraceRequest exposes APIs that allow setting properties required for E2E tracing:
    //Should be called as soon as the data was sent. Timestamp generated internally, hence no additional parameter required.
    void MarkSent()
    //Should be called before data is sent. Timestamp generated internally, hence no additional parameter required.
    void MarkSending() 
    //Should be called upon receiving first data bytes. Timestamp generated internally, hence no additional parameter required.
    void MarkReceiving()  
    //Should be called as soon as data was completely received. Timestamp generated internally, hence no additional parameter required
    void MarkReceived() 
    //Sets the size of sent data in bytes.
    void SetByteCountSent(ulong count) 
    //Sets the size of received data in bytes.
    void SetByteCountReceived(ulong count)
    //Sets the request headers.
    void SetRequestHeaders(string headers)
    //Sets the response headers.
    void SetResponseHeaders(IReadOnlyDictionary<string, string> headers)
    //Sets the HTTP request line. 
    void SetRequestLine(string requestLine)
    1. For example, set up the E2E trace request when starting a network request:
      traceManager.TraceLevel = E2ETraceLevel.Low;
      IE2ETraceTransaction transaction = await TraceManager.StartTransactionAsync("test.transaction.win");
      IE2ETraceStep step01 = transaction.StartStep();
      IE2ETraceRequest request0101 = step01.StartRequest();
      string passportHeader0101 = request0101.PassportHttpHeader;
      string correlationId0101 = request0101.CorrelationIdHttpHeader;    
      request0101.SetByteCountSent(100L);
      request0101.MarkSending();
      request0101.MarkSent();
      Dictionary<string, string> requestHeaders = new Dictionary<string, string> { 
      	{"SAP-PASSPORT",passportHeader0101} ,
      	{"X-CorrelationID",correlationId0101} 
      };
      
      request0101.SetRequestHeaders(requestHeaders);
      request0101.SetRequestLine("GET http//www.test.com HTTP/1.1");
      
    2. After the network request completes, the response is processed:
      request0101.MarkReceiving();
      request0101.MarkReceived();
      Dictionary<string, string> responseHeders = new Dictionary<string, string>() { 
         {"Content-Length", "111"},
         {"Content-Type", "application/xml"}
      };
      request0101.SetResponseHeaders(responseHeders);
      request0101.SetReturnCode("200");
      request0101.SetByteCountReceived(200L);
      
    3. Close the trace request:
      request0101.EndRequest();
      Calling the E2ETraceRequest EndRequest method causes the E2ETrace request to be marked as ended.
      E2ETraceSteps can be ended by invoking their EndStep method, which also ends all their active requests automatically:
      step01.EndStep();
    4. End the active ETE trace transaction:
      traceManager.ActiveTransaction.EndTransaction();
      This call also traverses down and ends all active steps and their requests.
  • Client-Side BTX Persistence
    The end result of an E2E trace session is the Business Transaction XML (BTX), which is temporarily stored in the app’s file system. The BTX is automatically removed when one of the following conditions are met:
    • the BTX is successfully uploaded to the server, or
    • a new E2E trace session starts
  • Uploading the BTX

    SAP Mobile Platform Server supports uploading E2E trace results ( BTX). Access is controlled by the security configuration associated with the given application. Therefore, prior to uploading the BTX, the Server Administrator must perform some administrative tasks. For detailed instructions on E2E trace and log related settings and configuration see http://help.sap.com/saphelp_smp307svr/helpdata/en/e6/46aa8668a64efb94ec30e198a0b009/content.htm (or perform a Web search for for “SMP” “Defining Client Log and Trace Policies”). In addition, the application connection ID must be passed as a “X-SMP-APPCID” header field.

    The following code attempts to upload the BTX to the SAP Mobile Platform Server. You must supply a valid SAP Mobile Platform Server log upload URL in the form “http(s)://host:port/btx”, and application E2E tracing must be enabled in Management Cockpit. Seehttp://help.sap.com/saphelp_smp307svr/helpdata/en/e6/46aa8668a64efb94ec30e198a0b009/content.htm for details.
    CancellationTokenSource btxCancellationTokenSource = new CancellationTokenSource();
    await SAP.Supportability.SupportabilityFacade.Instance.E2ETraceManager.UploadBtxAsync(
    new DefaultUploader(httpClient, this.pageContext.ServerUri, UploadType.Btx, this.btxCancellationTokenSource.Token));
    
    
    Normally the E2E trace closes once the BTX is uploaded; however, if this does not happen, the framework performs the necessary cleanup when calling the upload API.
  • E2E Trace Implications
    Enabling E2E tracing is useful to track the functionality of apps; however, it does come at a cost which affects performance and memory usage. When E2E tracing is on, additional housekeeping is done by the various SDK components to insert the required values in the generated BTX. During the E2E session, the BTX document is managed in memory, and only gets persisted to disk if uploading it to the server fails. Additionally, E2E tracing automatically switches all loggers to DEBUG mode, meaning that logs become more verbose compared to the default ERROR mode.

    Use application E2E tracing only if it is required.

  • Examples

    The Supportability framework includes an extensive set of unit tests that cover many use-cases. Additionally, every public API is documented, and includes usage examples for the less obvious use-cases.