From UI to REST API

This page is a short tutorial on how to use the Application Performance Monitoring UI as a quick-start tool to enable you to run REST API queries. The UI itself uses the same REST API operations that are described on the other pages of this document. Using the documented REST API operations you should be able build a robust performance analysis tool.

The goal of this page is to help you write syntactically and functionally correct cURL commands that use the REST API queries to retrieve application metrics. This tutorial assumes you have some basic knowledge of how to log into and use the APMCS UI, and how to use cURL.

The steps followed in this tutorial are:
  1. Record your UI login credentials for later use with cURL.
  2. Display the first page of data in the UI.
  3. Open the web browser Developer Tools. Here we use the Google Chrome web browser and developer tool; other web browsers should have equivalent developer tool functionality.
  4. Find and capture a REST API URL and query, and inspect its JSON response output.
  5. Update the URL and query.
  6. Paste the query into and execute a cURL command.

Login to the UI

The first step is logging into the UI. Let's assume the following credentials were used:
  • Tenant name: cloudTenant1
  • User name: omc_admin
  • Password: Welcome1!
The cURL command we'll use later will require the same credentials; on this page, and in our operation examples we use clear-text credentials.

The UI is up and the first data page appears. For this tutorial we'll go no further than that first UI page, but you are free to drill into the UI and apply the following steps on any of its pages.

We'll focus on the lower part of that page, listing the recent activity:

Figure - UI First Page Lower View

UI First Page Lower View

Open Web Browser Developer Tools

We want to find the REST API queries that the UI uses to extract the data it's displaying. In order to do this we'll use the Google Chrome Developer Tools available to the browser. To open those tools you can click the More Tools, and then Developer Tools menu, or Control-Shift-I. Notice the empty Network tab pane below the UI data activity overview:

Figure - UI First Page with Developer Tools

UI First Page with Developer Tools

If the Developer Tools Network tab is not in view, click on the tab in the Developer Tools pane to bring it into view. Also in the Network tab, two menus down, confirm the view mode All is selected and grayed out. Sometimes, by default, All is not selected, and if so, you won't see the REST API queries that are executed. If All is not grayed out then click it.

Find and Inspect REST API URL and Query

Now refresh the page by clicking Control-R (or F5). This should populate the left column of the Network tab pane with name and URL information. Scroll down the left column until you find a series of URLs with "?" in them. Most of these are the REST API queries. In our example, the parts of the URL that are in view (highlighted in the red box) begin with ?since=timestamp, which are some of our queries of interest.

Figure - UI First Page with Queries

UI First Page with Queries
Hover over each REST API query until you find the one that retrieves server requests. The query may look something like the following (note the /api/v1/requests resource path):
https://slc04bap.us.oracle.com:4443/sso.static/apm.dataserver/api/v1/requests/?since=2016-02-02T00:00:00.000Z&until=2016-02-09T01:24:00.000Z&orderBy=completedCount:desc

You can then inspect the actual query and the JSON response by clicking on the Developer Tools Headers and Response tabs.

Figure - UI First Page with JSON Response

UI First Page with JSON Response

Update the REST API Query URL

Copy the query from the UI and paste it into an editor. Replace the path identifier /sso.static/ with /serviceapi/. When used, /serviceapi/ will send the query to the REST API server via a different route. Your query should now look like:
https://slc04bap.us.oracle.com:4443/serviceapi/apm.dataserver/api/v1/requests/?since=2016-02-02T00:00:00.000Z&until=2016-02-09T01:24:00.000Z&orderBy=completedCount:desc

Use cURL to execute REST API Query

Using the credentials we used to log into the UI earlier, the start of the cURL command will be something like the following:
curl -i -H "X-USER-IDENTITY-DOMAIN-NAME: cloudTenant1" -u "cloudTenant1.omc_admin:Welcome1!" -X GET --insecure
It may differ slightly but if you know how to use cURL you are aware of what is needed.
Now add the updated query URL to the cURL command we just started, and execute:
curl -i -H "X-USER-IDENTITY-DOMAIN-NAME: cloudTenant1" -u "cloudTenant1.omc_admin:Welcome1!" -X GET --insecure
    'https://slc04bap.us.oracle.com:4443/serviceapi/apm.dataserver/api/v1/requests/?since=2016-02-02T00:00:00.000Z&until=2016-02-09T01:24:00.000Z&orderBy=completedCount:desc'

Reading the REST API Result

After running the cURL command above the result may look something like the following. First notice that the result begins with the HTTP response header because we included the -i command line parameter to include that header, and that the result code is 200 OK (see Status Codes for more information about that). For brevity, many of the examples in this document do not include the HTTP header, but it's shown here to demonstrate its use.

Following the HTTP header is a JSON array of server requests which is the object type returned from the /requests resource (these are explained in more detail in the Server Requests overview). In our case 278 server requests were returned, though below we just show the first one.

Across the REST API, as in the example output below, a returned JSON object will typically contain a "links" array. These are links to related resources, which can be used for further data retrieval and are described in more detail in the next section:
HTTP/1.1 200 OK
Date: Wed, 17 Feb 2016 20:00:47 GMT
X-Frame-Options: SAMEORIGIN
Content-Type: application/json
X-ORACLE-DMS-ECID: 005BHPMMAde8DwK5IVh8if00079u0001ty
Set-Cookie: EMCS_JSESSIONID=xik46yLzjUj0w2DDhW_gyszYyFpk8D4C2uXICI8KEWFQy6Q1YLCi!-2138026826; expires=Wed, 17-Feb-2016 20:01:00 GMT; path=/apmcs/data; secure; HttpOnly
Set-Cookie: _WL_AUTHCOOKIE_EMCS_JSESSIONID=LU1Xrey9WODee0guQF2T; path=/apmcs/data; secure; HttpOnly
Vary: Accept-Encoding
Cache-Control: no-cache,no-store
Transfer-Encoding: chunked
Content-Language: en
{
  "returnedItemCount" : 278,
  "items" : [ {
    "appServerName" : "node",
    "appServerPort" : 80,
    "appServerSslPort" : 443,
    "appServerPortsList" : null,
    "links" : [ {
      "href" : "api/v1/requests/201099?since=2016-02-02T00:00:00.000Z&until=2016-02-09T01:24:00.000Z",
      "rel" : "self"
    }, {
      "href" : "api/v1/requests/201099/timeSeries?since=2016-02-02T00:00:00.000Z&until=2016-02-09T01:24:00.000Z",
      "rel" : "timeSeries"
    }, {
      "href" : "api/v1/requests/201099/instances?since=2016-02-02T00:00:00.000Z&until=2016-02-09T01:24:00.000Z",
      "rel" : "instances"
    }, {
      "href" : "api/v1/requests/201099/operationLinks?since=2016-02-02T00:00:00.000Z&until=2016-02-09T01:24:00.000Z",
      "rel" : "operationLinks"
    }, {
      "href" : "api/v1/appservers/201099-02-02T00:00:00.000Z&until=2016-02-09T01:24:00.000Z",
      "rel" : "appServerDetails"
    }, {
      "href" : "api/v1/operations/201099",
      "rel" : "operationType"
    }, {
      "href" : "api/v1/requests/201099/browserCallers?since=2016-02-02T00:00:00.000Z&until=2016-02-09T01:24:00.000Z",
      "rel" : "browserCallers"
    } ],
    "requestId" : 201099,
    "deploymentName" : "node",
    "serverName" : "adc00ozm",
    "agentName" : "adc00ozm:80 - APM Node.js Agent",
    "operationName" : "/american",
    "operationGenre" : "SERVLET",
    "maxResponseTime" : 42,
    "minResponseTime" : 1,
    "totalResponseTime" : 50340,
    "averageResponseTime" : 6.3,
    "maxSelfTime" : 42,
    "minSelfTime" : 1,
    "totalSelfTime" : 50340,
    "averageSelfTime" : 6.3,
    "maxAppServerTime" : 42,
    "minAppServerTime" : 1,
    "totalAppServerTime" : 50340,
    "averageAppServerTime" : 6.3,
    "maxDatabaseTime" : 0,
    "minDatabaseTime" : 0,
    "totalDatabaseTime" : 0,
    "averageDatabaseTime" : 0,
    "maxExternalTime" : 0,
    "minExternalTime" : 0,
    "totalExternalTime" : 0,
    "averageExternalTime" : 0,
    "completedCount" : 7996,
    "failureCount" : 0,
    "hasCallerInfo" : false,
    "isFlowStart" : true,
    "loadRate" : 0.79,
    "errorPercentage" : 0,
    "appserverVersionId" : 201079,
    "appServerAdminHost" : "127.0.0.1",
    "appServerAdminPort" : 80,
    "meId" : "SR_WqnwEQZD+NiIG9/7AhuOQaFULP8="
  },
  ...
}
            

Drilling Deeper via a Link

Continuing to use our example above, we're going to drill deeper into the first server request, and retrieve metric data from one of the linked related resources. Again, notice that each server request returned (only the first is shown above) is populated with a set of links (the "links" array) which are related resources that can be useful for further navigation and retrieval. These related resources are preconstructed queries to assist you with the retrieval of metric data that is directly or indirectly related to the object containing the link. Most of the objects returned in the JSON response from this REST API (for example /pages, /ajaxCalls, /agents, etc) contain an array of related resource links (see Links to Related Resources for more information). The APMCS UI itself navigates through different objects using these same links.

In our example, the first server request ID returned (shown above as "requestId" : 201099), has a related resource:
api/v1/requests/201099/operationLinks?since=2016-02-02T00:00:00.000Z&until=2016-02-09T01:24:00.000Z
We can retrieve the operationLinks by executing the same cURL command as above with the new query that we extracted from the links array:
curl -i -H "X-USER-IDENTITY-DOMAIN-NAME: cloudTenant1" -u "cloudTenant1.omc_admin:Welcome1!" -X GET --insecure
    'https://slc04bap.us.oracle.com:4443/serviceapi/apm.dataserver/api/v1/requests/201099/operationLinks?since=2016-02-02T00:00:00.000Z&until=2016-02-09T01:24:00.000Z'
Now the result may look something like the following (the HTTP header was deleted):
...
{
  "returnedItemCount" : 1,
  "items" : [ {
    "isExternal" : true,
    "callType" : "SYNC",
    "links" : [ {
      "href" : "api/v1/requests/201099/operationLinks/caller/201099/called/201091/isExternal/false/callType/SYNC?since=2016-02-02T00:00:00.000Z&until=2016-02-09T01:24:00.000Z",
      "rel" : "self"
    }, {
      "href" : "api/v1/operations/201099",
      "rel" : "callerOperationType"
    }, {
      "href" : "api/v1/operations/201091",
      "rel" : "calledOperationType"
    }, {
      "href" : "api/v1/requests/201099/operationLinks/caller/201099/called/201091/isExternal/false/callType/SYNC/timeSeries?since=2016-02-02T00:00:00.000Z&until=2016-02-09T01:24:00.000Z",
      "rel" : "timeSeries"
    } ],
    "requestId" : 201099,
    "callerOperationId" : 201099,
    "callerOperationName" : "/american",
    "calledOperationId" : 201091,
    "calledOperationName" : "/american_backend",
    "calledOperationGenre" : "SERVLET",
    "appserverVersionId" : 201079,
    "maxSelfTime" : 42,
    "minSelfTime" : 1,
    "totalSelfTime" : 48459,
    "averageSelfTime" : 6.06,
    "maxResponseTime" : 42,
    "minResponseTime" : 1,
    "totalResponseTime" : 48459,
    "averageResponseTime" : 6.06,
    "completedCount" : 7996,
    "failureCount" : 0,
    "maxOperationResponseTime" : 42,
    "minOperationResponseTime" : 1,
    "totalOperationResponseTime" : 48459,
    "averageOperationResponseTime" : 6.06,
    "operationTier" : "external",
    "loadRate" : 0.79,
    "errorPercentage" : 0
  } 
  ...
}
            

You now can continue looking at other REST API operations used by the UI (try other UI pages or follow more related resource links), or you can construct and try out your own REST API operations.