How can I monitor the health of the Oracle B2C Service application?
Environment:
Oracle B2C Service
Resolution:
Service Health Metrics
Service Health Metrics in B2C Service
REST APIs are now available so your organization can monitor the overall health of the Oracle B2C Service application. The Service Health Metrics REST APIs fetch the current health status for various services and features available within the Oracle B2C Service application.
Quick Start
You can use Oracle REST APIs to monitor the health of your Oracle B2C Service Site. This answer provides:
- A quick start that walks you through a request example.
- Use cases with real-world solutions with code examples.
- Detailed descriptions for each REST resource.
This document describes features available to users under Oracle B2C Service, Oracle Service Cloud, and Oracle RightNow Service Cloud licensing agreements.
Additionally, we have a helpful blog here: Monitoring Your Oracle B2C Service Health: Introducing Service Health Metrics
Step 1: Consider Before You Start
Review the basics. If you're new to REST APIs, make sure you understand the basics of REST and JSON, and scan our list of important terms.
Choose a REST client. REST APIs connect software programs over the HTTP protocol. You need a software client to send the HTTP requests. In our examples, we use Postman, however, Postman isn't the only tool you can use. To help you choose one, see Work with your REST Client.
Validate Access. The one-time setup/enablement of Service Health Metrics needs to be done via Configuration Assistant. Hence, this task needs to be performed by site administrators who have access to Configuration Assistant.
Step 2: Get Your Service Health Metrics Account Info
To make a REST HTTP request, you need to gather a few bits of information:
- REST Server URL. Service Health Metrics endpoint for all your sites can be accessible at one endpoint: https://monitoring.custhelp.com/v1/sitemetrics
- Authentication. Service Health Metrics uses JWT Bearer token for authentication. If you have not configured the Service Health Metrics for your sites, then you go to step 3. However, if you already have public and private certificate, which you have configured for Service Health Metrics in Configuration Assistant you, can skip step 3 and go to step 4.
Step 3: Configure your Account
The first step is to enable the Service Health Metrics integration within Configuration Assistant. If this is your first time accessing the Configuration Assistant, more information can be found here in Answer ID 12490: Accessing My Services and Configuration Assistant
Generate a private key
openssl genpkey -out rsakey.pem -algorithm RSA -pkeyopt rsa_keygen_bits:2048
Extract the public key from the private key
openssl pkey -in rsakey.pem -pubout -out rsapubkey.pem
- Follow the steps below to upload the Public Key in Configuration Assistant, in order to enable Service Health Integration for your site
- Click on the site name tile, which you want to enable this integration.
- Go to the Integrations section.
- Under the Site Health Metrics section, click on New (or Edit if SHM has been enabled for the site previously).
- Upload the certificate and click on Save.
The actions above create the appropriate JWK for the site against which the JWT is validated.
Step 4: Authentication Options
To orchestrate a GET API on Service Health Metrics, you need a JSON Web Token (JWT) for authentication, and you must specify this JWT as a Bearer Authorization header in your request to GET API.
You can manually generate or programmatically generate the JWT:
4.1 Manually generate the JWT
To manually generate the JWT token, use the following template:
header { "kid": "customersite02",//customer B2C site name "alg": "RS256" } payload { "name": "Customer1", //name of the customer "site": "customersite02", // should match value of kid in header "iss": "customer1", //name of the customer "exp": 1718096080, //expiry timestamp "iat": 1686560080, //issued at timestamp "sub": "health-service", // subject should be health-service "upn": "health-service", // principal should be health-service "aud": [ "health-monitor" //audience should be health-monitor ], "jti": "[B@33c7353a" }
|
Make sure that if you are copying and pasting the above, you update the 'exp' timestamp (it is now in the past and will have expired)
With the above template, the required JWT token can be generated using RS256 algorithm:
base64UrlEncode(header)+ "." + base64UrlEncode(payload) + "." + RSASHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), privateCertificate)
There are both offline and online utilities available for the JWT token generation (e.g., https://jwt.io/).
4.2 Programmatically generate a private JWK
You can also generate a JWT token programmatically. To accomplish this, generate a JWK for the private key and then use the JWK to generate the JWT.
Install rasha (npm install -g rasha)
Use the private key to generate the private JWK (rasha rsakey.pem | jq -r '. + {"kid":"my_monitored_site", "use":"sig"}')
Create a JWK file named TestKeys.jwk and paste the content as seen here:
{
"keys": [
{
"kty": "RSA",
"n": "pX3yLP7UcXXqOvLBKHgeinFy_sdknt_BynrEJCYiyOh7ToT1aJsxykHFExj0QA0Ok_z2WfM1ULbemknBR7_aoRVksLceySTqHRfbH5LujWkMunEbVm-z1opHf-7tNI9fs9l4Kop82ttrd5rMcKrNs5hoOUyW2o91F_kSHZFaVD2LxMzIEXmt8vlmjEspfBNBGElkb4H3xRWMU7e5QFXyPVK1ZROgKtIuuTB_cDI0ByN8QmU0rEQjqN0wDRwOXTCT_KxYFqEYlnEuWgODMzRJb9r2hfiM664PzRBr5gMG2gWTRngprHv8gFe77XE73lMPvvOgdstKCmurI0aefwzO5Q",
"e": "AQAB",
"d":"O8Sp0zBRn4ybhKCpvCjttshUZMm0gGCFh9AgyIFxbKfx6KDCVP4_1DE-sLABfqR4kF_6xO--YKE68fQTNwuGNUkZrWzlVHXdi5ZTECsrtqyq6SbyXZxIEgKs4fpzdtkVEkpHSO3tO8mlHXQtw78cPXGcqp0LmnHXM0pEDaOyQNvIuUZi41w5DoDR8WdlVDROM3l1HD1yNF_LM_FH5pUqntIA9itHTnZbiD0i4TCIJMfGh_yHxnNHdqR0i-1rQSz4KO86ucOxZiHCvu3UbjktrLJQIFN-sTskAuMGlKvQvgBbi0slRzRyZoGl-ylao_DeavrWw12v1Nxz2gpie1Pv3Q",
"p":"1YjV4yO25S4AjYpX4yI5F2mn-8rA3E0hG1zUM_VO_ZxYKkU-MuM1g1XtG4eYaiLoNYHDuxBuA8sbO71sIl6NIB4H8JVhRS67OJPLlftsqTyOeqvQdPJYN-5fY2-G3113vHBxHF7fZ6c3E8q9vmIKPDstj9-tWz07syVpjEv6zLc",
"q": "xmc8xgqdx13HjhsEii5w_v6S89X4nsORgKk5z6SBfy4INMpdR4kHoJkQlkZAJ3pCRVaR7KgwAUeoBthxZ4QSLncseKBcqLeHqKZhmJ2oiswVWLnrMIHaxy5GKB_CY0dI9UPHeGXUznFnNsmj0fb8D_dRBMQxRPcgzBW4ggcLnUM",
"dp":"aV1VvPiYfMmQOEc1SrxOU4EtBI9tTsc4ONo7U1AOJBILZwA3ysBWXXH-x4DG8kg7MHvRavKWdoS38WhsfSEOnfRzkoEDODHw69_xqxYe7fsViu5QtAQJB8A1jUkw0fK67F7HUWp27hySjs-RhOm3hzTkLIQAdG7okGM7i6DKJk0",
"dq": "kZHruE7PxxiaszxFj3FVvPJiNf_3o91QI7uGTECiNwM6SCl2WWdELmRAFFJE_fIpL6C9_orEdhvyP9uNEWuIv4j3GyZl9fB625YAI68Bm5zzyJ7Y3kVYlS3xkb0Drj3-XN43O7JTeokgNsWpqgNym_BVBI9Cqxw7dyI0t0qeDes",
"qi": "GNAz09Nlp6MNcbeOg4EPGuQpnXSJ3dgbuRyxRQYfKrUhgj4BD_G9lRiy1SnqbIyGqHssjeiG-fzBralh0k6H8EMuwQrrZb7ZWFWr-Yehh6BT_qqb1jCKPVIFF3Ic49vl5DkniFuMu0vweTq1xTdzSpCVwCXl02E64CV-ZjnXFLw",
"kid": "my_monitored_site",
"use": "sig"
}
]
}
Sample java code is provided to help you create a JWT token for the given TestKeys.jwk file:
package com.oracle.cx.health.utils; import io.helidon.common.configurable.Resource; import io.helidon.security.jwt.Jwt; import io.helidon.security.jwt.SignedJwt; import io.helidon.security.jwt.jwk.JwkKeys; import java.io.InputStream; import java.time.Instant; import java.time.temporal.ChronoUnit; public class JwtUtils { private static InputStream in = JwtUtils.class.getClassLoader().getResourceAsStream("TestKeys.jwk"); private static JwkKeys jwtKeys = JwkKeys.builder().resource(Resource.create("TestKeys", in)).build(); private static final String KEY_ID = "osvc-dev"; private static final String SUBJECT = "health-service"; private static final Instant EXP = Instant.now().plus(1, ChronoUnit.DAYS); private static final String ISSUER = "customer1"; private static final String JWT_ID = "[B@33c7353a"; private static final String ALGO = "RS256"; public static final String SITE = "testSite"; private static final String AUD = "health-monitor"; public static String generateJwtTokenForGivenSite(String siteName) { Jwt = Jwt.builder() .keyId(siteName) .addAudience(AUD) .subject(SUBJECT) .expirationTime(EXP) .issueTime(Instant.now()) .issuer(ISSUER) .jwtId(JWT_ID) .algorithm(ALGO) .addPayloadClaim("site",siteName) .addPayloadClaim("name", "Customer1") .build(); SignedJwt signedJwt = SignedJwt.sign(jwt, jwtKeys); String token = "Bearer " + signedJwt.tokenContent(); return token; } public static void main(String[] args) { System.out.println(generateJwtTokenForGivenSite(SITE)); } } |
Step 5.0: Fetch Your B2C Site Health Data - For non-Chat services
In order to make a REST HTTP request, gather the following information:
- REST Server URL. Service Health metrics for all sites are accessible at https://monitoring.custhelp.com/v1/sitemetrics
- ERROR Metrics URL. Error Metrics for all sites are accessible at
- https://monitoring.custhelp.com /v1/errormetrics/[4XX|5XX]
- https://monitoring.custhelp.com /v1/errormetrics/[4XX|5XX]/<servicename>
- JWT Token. A JWT bearer token is required to use these REST APIs. The public key created within the Configuration Assistant and is described above in Step 2. A JWT is also required and the steps to create the JWT are provided above in Step 3.
- A <resource-path> is the relative path or endpoint for Service Health Metrics. For e.g., /v1/sitemetrics is to be used for Service Health Metrics.
- Using the REST Server URL appended with resource path and specifying JWT token as Bearer Token in Authorization header you should be able to query the B2C site health data. Refer below snapshot:
Step 5.1: Fetch Your B2C Site Health Data - For Chat services
The REST API retrieves data for the Chat Service, including Chat sub-services and their subServicesL2 (up to the second level).
- Go to CX Support Site
- Submit a Service Request
- Please include the following information in the SR
- Subject (copy & paste): Service Health Metrics: Enable Chat Service Metrics
- Within the request: Please include the name(s) of your site(s)
- Request Example (you can copy & paste this information into the field):
- Our organization plans to utilize Service Health Metrics. Please enable Chat Service Metrics for this site: <site name>
- Our organization plans to utilize Service Health Metrics. Please enable Chat Service Metrics for these sites: <site name 01>, <site name 02>, <site name 03>, etc
- Additional Safeguards:
- Submitting this request, changes the routing for chat traffic. There is no downtime expected with this change, however, this update should be made after hours.
- Submitting this request, changes the routing for chat traffic from 'common domain' based routing to 'site specific custom domain' based routing. This update enables the collection of metrics for each chat site.
In order to make REST HTTP request, gather the following information:
REST Server URL. Service Health metrics for all sites are accessible at https://monitoring.custhelp.com/v1/sitemetrics/chat
JWT Token. A JWT bearer token is required to use these REST APIs. The publish key created within the Configuration Assistant and is described above in Step 2. A JWT is also required and the steps to create the JWT are provided above in Step 3.
A <resource-path> is the relative path or endpoint for Service Health Metrics. For e.g., /v1/sitemetrics/chat is to be used for Service Health Metrics.
Using the REST Server URL appended with resource path and specifying JWT token as Bearer Token in Authorization header you should be able to query the B2C site health data. Refer to the snapshot below:
Step 6.0: Understanding the REST API response - For non-Chat services
Now that your site is configured and authorized for Service Health Metrics, you can begin to review the data provided by the REST APIs. Below is sample response and an explanation of the sub-components:
{
"serviceMetrics": [
{"widgetserver": {
"totalRequests": 2261,
"averageLatency": 16,
"totalPercentage": 3.85,
"successRequests": {
"totalRequests": 2261,
"averageLatency": 16,
"totalPercentage": 100,
"metricData": [
{"200": {
"totalRequests": 2212,
"averageLatency": 16,
"totalPercentage": 97.83
}},
{"304": {
"totalRequests": 49,
"averageLatency": 9,
"totalPercentage": 2.17
}}
]
},
"errorRequests": {
"totalRequests": 0,
"averageLatency": 0,
"totalPercentage": 0,
"metricData": []
},
"subServices": [{"other": {
"totalRequests": 2261,
"averageLatency": 16,
"totalPercentage": 100,
"successRequests": {
"totalRequests": 2261,
"averageLatency": 16,
"totalPercentage": 100,
"metricData": [
{"200": {
"totalRequests": 2212,
"averageLatency": 16,
"totalPercentage": 97.83
}},
{"304": {
"totalRequests": 49,
"averageLatency": 9,
"totalPercentage": 2.17
}}
]
},
"errorRequests": {
"totalRequests": 0,
"averageLatency": 0,
"totalPercentage": 0,
"metricData": []
}
}}]
}},
{"Browser_UI": {
"totalRequests": 1560,
"averageLatency": 215,
"totalPercentage": 2.66,
"successRequests": {
"totalRequests": 1554,
"averageLatency": 205,
"totalPercentage": 99.62,
"metricData": [
{"200": {
"totalRequests": 1265,
"averageLatency": 243,
"totalPercentage": 81.09
}},
{"302": {
"totalRequests": 135,
"averageLatency": 15,
"totalPercentage": 8.65
}},
{"304": {
"totalRequests": 74,
"averageLatency": 98,
"totalPercentage": 4.74
}},
{"401": {
"totalRequests": 58,
"averageLatency": 24,
"totalPercentage": 3.72
}},
{"204": {
"totalRequests": 22,
"averageLatency": 55,
"totalPercentage": 1.41
}}
]
},
"errorRequests": {
"totalRequests": 6,
"averageLatency": 2730,
"totalPercentage": 0.38,
"metricData": [
{"503": {
"totalRequests": 5,
"averageLatency": 230,
"totalPercentage": 0.32
}},
{"520": {
"totalRequests": 1,
"averageLatency": 15225,
"totalPercentage": 0.06
}}
]
},
"subServices": [
{"other": {
"totalRequests": 1543,
"averageLatency": 204,
"totalPercentage": 98.91,
"successRequests": {
"totalRequests": 1537,
"averageLatency": 194,
"totalPercentage": 99.61,
"metricData": [
{"200": {
"totalRequests": 1248,
"averageLatency": 230,
"totalPercentage": 80.88
}},
{"302": {
"totalRequests": 135,
"averageLatency": 15,
"totalPercentage": 8.75
}},
{"304": {
"totalRequests": 74,
"averageLatency": 98,
"totalPercentage": 4.8
}},
{"401": {
"totalRequests": 58,
"averageLatency": 24,
"totalPercentage": 3.76
}},
{"204": {
"totalRequests": 22,
"averageLatency": 55,
"totalPercentage": 1.43
}}
]
},
"errorRequests": {
"totalRequests": 6,
"averageLatency": 2730,
"totalPercentage": 0.39,
"metricData": [
{"503": {
"totalRequests": 5,
"averageLatency": 230,
"totalPercentage": 0.32
}},
{"520": {
"totalRequests": 1,
"averageLatency": 15225,
"totalPercentage": 0.06
}}
]
}
}},
{"xo": {
"totalRequests": 17,
"averageLatency": 1202,
"totalPercentage": 1.09,
"successRequests": {
"totalRequests": 17,
"averageLatency": 1202,
"totalPercentage": 100,
"metricData": [{"200": {
"totalRequests": 17,
"averageLatency": 1202,
"totalPercentage": 100
}}]
},
"errorRequests": {
"totalRequests": 0,
"averageLatency": 0,
"totalPercentage": 0,
"metricData": []
}
}}
]
}},
{"webserver": {
"totalRequests": 54895,
"averageLatency": 194,
"totalPercentage": 93.49,
"successRequests": {
"totalRequests": 54894,
"averageLatency": 194,
"totalPercentage": 100,
"metricData": [
{"200": {
"totalRequests": 41187,
"averageLatency": 244,
"totalPercentage": 75.03
}},
{"404": {
"totalRequests": 11047,
"averageLatency": 28,
"totalPercentage": 20.12
}},
{"304": {
"totalRequests": 1444,
"averageLatency": 5,
"totalPercentage": 2.63
}},
{"302": {
"totalRequests": 1210,
"averageLatency": 210,
"totalPercentage": 2.2
}},
{"403": {
"totalRequests": 4,
"averageLatency": 28,
"totalPercentage": 0.01
}},
{"408": {
"totalRequests": 1,
"averageLatency": 5000,
"totalPercentage": 0
}},
{"301": {
"totalRequests": 1,
"averageLatency": 238,
"totalPercentage": 0
}}
]
},
"errorRequests": {
"totalRequests": 1,
"averageLatency": 15468,
"totalPercentage": 0,
"metricData": [{"504": {
"totalRequests": 1,
"averageLatency": 15468,
"totalPercentage": 0
}}]
},
"subServices": [
{"customer_portal": {
"totalRequests": 9550,
"averageLatency": 720,
"totalPercentage": 17.4,
"successRequests": {
"totalRequests": 9549,
"averageLatency": 718,
"totalPercentage": 99.99,
"metricData": [
{"200": {
"totalRequests": 8413,
"averageLatency": 786,
"totalPercentage": 88.09
}},
{"302": {
"totalRequests": 1135,
"averageLatency": 213,
"totalPercentage": 11.88
}},
{"301": {
"totalRequests": 1,
"averageLatency": 238,
"totalPercentage": 0.01
}}
]
},
"errorRequests": {
"totalRequests": 1,
"averageLatency": 15468,
"totalPercentage": 0.01,
"metricData": [{"504": {
"totalRequests": 1,
"averageLatency": 15468,
"totalPercentage": 0.01
}}]
}
}},
{"other": {
"totalRequests": 29622,
"averageLatency": 40,
"totalPercentage": 53.96,
"successRequests": {
"totalRequests": 29622,
"averageLatency": 40,
"totalPercentage": 100,
"metricData": [
{"200": {
"totalRequests": 17055,
"averageLatency": 51,
"totalPercentage": 57.58
}},
{"404": {
"totalRequests": 11047,
"averageLatency": 28,
"totalPercentage": 37.29
}},
{"304": {
"totalRequests": 1444,
"averageLatency": 5,
"totalPercentage": 4.87
}},
{"302": {
"totalRequests": 72,
"averageLatency": 157,
"totalPercentage": 0.24
}},
{"403": {
"totalRequests": 4,
"averageLatency": 28,
"totalPercentage": 0.01
}}
]
},
"errorRequests": {
"totalRequests": 0,
"averageLatency": 0,
"totalPercentage": 0,
"metricData": []
}
}},
{"connect_ws_soap": {
"totalRequests": 15411,
"averageLatency": 163,
"totalPercentage": 28.07,
"successRequests": {
"totalRequests": 15411,
"averageLatency": 163,
"totalPercentage": 100,
"metricData": [
{"200": {
"totalRequests": 15410,
"averageLatency": 163,
"totalPercentage": 99.99
}},
{"408": {
"totalRequests": 1,
"averageLatency": 5000,
"totalPercentage": 0.01
}}
]
},
"errorRequests": {
"totalRequests": 0,
"averageLatency": 0,
"totalPercentage": 0,
"metricData": []
}
}},
{"custom_php": {
"totalRequests": 240,
"averageLatency": 212,
"totalPercentage": 0.44,
"successRequests": {
"totalRequests": 240,
"averageLatency": 212,
"totalPercentage": 100,
"metricData": [
{"200": {
"totalRequests": 237,
"averageLatency": 212,
"totalPercentage": 98.75
}},
{"302": {
"totalRequests": 3,
"averageLatency": 198,
"totalPercentage": 1.25
}}
]
},
"errorRequests": {
"totalRequests": 0,
"averageLatency": 0,
"totalPercentage": 0,
"metricData": []
}
}},
{"connectRest": {
"totalRequests": 69,
"averageLatency": 141,
"totalPercentage": 0.13,
"successRequests": {
"totalRequests": 69,
"averageLatency": 141,
"totalPercentage": 100,
"metricData": [{"200": {
"totalRequests": 69,
"averageLatency": 141,
"totalPercentage": 100
}}]
},
"errorRequests": {
"totalRequests": 0,
"averageLatency": 0,
"totalPercentage": 0,
"metricData": []
}
}},
{"kf_soap": {
"totalRequests": 3,
"averageLatency": 456,
"totalPercentage": 0.01,
"successRequests": {
"totalRequests": 3,
"averageLatency": 456,
"totalPercentage": 100,
"metricData": [{"200": {
"totalRequests": 3,
"averageLatency": 456,
"totalPercentage": 100
}}]
},
"errorRequests": {
"totalRequests": 0,
"averageLatency": 0,
"totalPercentage": 0,
"metricData": []
}
}}
]
}}
],
"siteMetrics": {
"totalRequests": 58716,
"averageLatency": 188,
"successPercentage": 99.99
},
"siteName": "my_monitored_site",
"updatedTime": "2024-06-28T05:19:00Z",
"timeInterval": 120
}
The above JSON response has various attributes defined. The next table describes the exposed attributes:
Sr. No. | Element | Description |
1 | siteName | The name of the site for which the metrics are retrieved. |
2 | updatedTime | The last update time for which the events are received |
3 | timeInterval | The duration for which the metrics are displayed. For more information, refer to the "timeInterval Details & Sample Use Cases" section below. |
4 | siteMetrics->totalRequests | Total number of requests received for this site |
5 | siteMetrics->successPercentage | Percentage of totalRequests which were success. Here success is any request which received a status not in 5xx bucket. |
6 | serviceMetrics | The array containing individual service metrics. We have two services currently Browser_UI and webserver. |
7 | serviceMetrics->Browser_UI | The metrics for Browser_UI component. |
8 | serviceMetrics->webserver | The metrics for webserver component |
9 | serviceMetrics->Browser_UI->totalRequests | Total requests received by Browser_UI component. |
10 | serviceMetrics->Browser_UI->totalPercentage | Percentage of requests received for Browser_UI from the totalRequests for the site. |
11 | serviceMetrics->Browser_UI->successRequests | Successful requests metrics from the total requests received by Browser_UI. Here successful requests are with HTTP status 2xx, 3xx and 4xx requests. |
12 | serviceMetrics->Browser_UI->successRequests->metricData | The metric data for successful requests. Here metricData includes the HTTP Status and the count of totalRequests and its percentage (totalPercentage) in the total successful requests. |
13 | serviceMetrics->Browser_UI->errorRequests | Error requests metrics from the total requests received for Browser_UI. Here error requests are with HTTP status 5xx |
14 | serviceMetrics->Browser_UI->subServices | SubServices metrics for subServices of Browser_UI. Currently we do not have any subservice for Browser_UI Service. |
15 | serviceMetrics->webserver->totalRequests | Total requests received by webserver component. |
16 | serviceMetrics->webserver-> totalPercentage | Percentage of requests received for webserver from the totalRequests for the site. |
17 | serviceMetrics->webserver->successRequests | Successful requests metrics from the total requests received by webserver. Here successful requests are with HTTP status 2xx, 3xx and 4xx requests. |
18 | serviceMetrics->webserver->successRequests->metricData | The metric data for successful requests. Here metricData includes the HTTP Status and the count of totalRequests and its percentage (totalPercentage) in the total successful requests. |
19 | serviceMetrics->webserver->errorRequests | Error requests metrics from the total requests received for webserver. Here error requests are with HTTP status 5xx |
20 | serviceMetrics->webserver->subServices | SubServices metrics for subServices of webserver. Currently sub-services for webserver are connectREST, connect_ws_soap, kf_soap, chat_soap, custom_php and customer_portal. The sub-services further expose successful and error metrics for the specific sub-service. |
21 | serviceMetrics->webserver->averageLatency | Average Latency for all the API requests served by webserver service. |
22 | serviceMetrics->xo | Metrics for the External Objects (XO) service component. |
23 | serviceMetrics->xo-> totalRequests | Total requests served by the External Objects (XO) service component. |
24 | serviceMetrics->xo-> successRequests | Successful requests metrics from the total requests received by the External Objects (XO) service. Here successful requests are with HTTP status 2xx, 3xx and 4xx requests. |
25 | serviceMetrics->xo-> successRequests-> averageLatency | Average latency for the successful requests served by the External Objects (XO) service component. |
26 | serviceMetrics->widgetserver | Metrics for widgetserver component |
27 | serviceMetrics->widgetserver-> subServices | Metrics data for sub-services for widgetserver. In case of no specific subservice, data will be collated under ‘other’. |
Step 6.1: Understanding the REST API response – For chat services
Now that your site is configured and authorized for Service Health Metrics, you can begin to review the data provided by the REST APIs for chat.
In the sample response below, the following is true:
- Service name: chat
- Sub Service name: Chat_REST
- SubServicesL2 are
- 'agent'
- 'agent_fetch_message'
- 'consumer'
- 'consumer_fetch_message'
- 'third_party'
- 'third_party_fetch_message'
- 'universal_queue'
- 'universal_queue_fetch_message'
- SubServicesL2 are
- Sub Service name: Chat_SOAP
- SubServicesL2 are
- 'universal_queue'
- 'consumer'
- 'legacy'
- SubServicesL2 are
{
"serviceMetrics": [
{
"chat": {
"totalRequests": 350,
"averageLatency": 1500,
"totalPercentage": 100.0,
"successRequests": {
"totalRequests": 200,
"averageLatency": 1500,
"totalPercentage": 57.14,
"metricData": [
{
"200": {
"totalRequests": 200,
"averageLatency": 1500,
"totalPercentage": 57.14
}
}
]
},
"errorRequests": {
"totalRequests": 150,
"averageLatency": 1500,
"totalPercentage": 42.86,
"metricData": [
{
"500": {
"totalRequests": 120,
"averageLatency": 1500,
"totalPercentage": 34.29
}
},
{
"501": {
"totalRequests": 20,
"averageLatency": 1500,
"totalPercentage": 5.71
}
},
{
"503": {
"totalRequests": 10,
"averageLatency": 1500,
"totalPercentage": 2.86
}
}
]
},
"subServices": [
{
"Chat_REST": {
"totalRequests": 220,
"averageLatency": 1500,
"totalPercentage": 62.86,
"successRequests": {
"totalRequests": 130,
"averageLatency": 1500,
"totalPercentage": 59.09,
"metricData": [
{
"200": {
"totalRequests": 130,
"averageLatency": 1500,
"totalPercentage": 59.09
}
}
]
},
"errorRequests": {
"totalRequests": 90,
"averageLatency": 1500,
"totalPercentage": 40.91,
"metricData": [
{
"500": {
"totalRequests": 60,
"averageLatency": 1500,
"totalPercentage": 27.27
}
},
{
"501": {
"totalRequests": 20,
"averageLatency": 1500,
"totalPercentage": 9.09
}
},
{
"503": {
"totalRequests": 10,
"averageLatency": 1500,
"totalPercentage": 4.55
}
}
]
},
"subServicesL2": [
{
"agent": {
"totalRequests": 30,
"averageLatency": 50,
"totalPercentage": 8.57,
"successRequests": {
"totalRequests": 30,
"averageLatency": 1500,
"totalPercentage": 100.0,
"metricData": [
{
"200": {
"totalRequests": 30,
"averageLatency": 1500,
"totalPercentage": 100.0
}
}
]
},
"errorRequests": {
"totalRequests": 0,
"averageLatency": 0,
"totalPercentage": 0.0,
"metricData": []
}
}
},
{
"agent_fetch_message": {
"totalRequests": 40,
"averageLatency": 38,
"totalPercentage": 11.43,
"successRequests": {
"totalRequests": 20,
"averageLatency": 1500,
"totalPercentage": 50.0,
"metricData": [
{
"200": {
"totalRequests": 20,
"averageLatency": 1500,
"totalPercentage": 50.0
}
}
]
},
"errorRequests": {
"totalRequests": 20,
"averageLatency": 1500,
"totalPercentage": 50.0,
"metricData": [
{
"500": {
"totalRequests": 20,
"averageLatency": 1500,
"totalPercentage": 50.0
}
}
]
}
}
},
{
"consumer": {
"totalRequests": 40,
"averageLatency": 38,
"totalPercentage": 11.43,
"successRequests": {
"totalRequests": 30,
"averageLatency": 1500,
"totalPercentage": 75.0,
"metricData": [
{
"200": {
"totalRequests": 30,
"averageLatency": 1500,
"totalPercentage": 75.0
}
}
]
},
"errorRequests": {
"totalRequests": 10,
"averageLatency": 1500,
"totalPercentage": 25.0,
"metricData": [
{
"500": {
"totalRequests": 10,
"averageLatency": 1500,
"totalPercentage": 25.0
}
}
]
}
}
},
{
"consumer_fetch_message": {
"totalRequests": 20,
"averageLatency": 75,
"totalPercentage": 5.71,
"successRequests": {
"totalRequests": 20,
"averageLatency": 1500,
"totalPercentage": 100.0,
"metricData": [
{
"200": {
"totalRequests": 20,
"averageLatency": 1500,
"totalPercentage": 100.0
}
}
]
},
"errorRequests": {
"totalRequests": 0,
"averageLatency": 0,
"totalPercentage": 0.0,
"metricData": []
}
}
},
{
"third_party": {
"totalRequests": 10,
"averageLatency": 150,
"totalPercentage": 2.86,
"successRequests": {
"totalRequests": 10,
"averageLatency": 1500,
"totalPercentage": 100.0,
"metricData": [
{
"200": {
"totalRequests": 10,
"averageLatency": 1500,
"totalPercentage": 100.0
}
}
]
},
"errorRequests": {
"totalRequests": 0,
"averageLatency": 0,
"totalPercentage": 0.0,
"metricData": []
}
}
]
}
}
},
{
"third_party_fetch_message": {
"totalRequests": 20,
"averageLatency": 75,
"totalPercentage": 5.71,
"successRequests": {
"totalRequests": 20,
"averageLatency": 1500,
"totalPercentage": 100.0,
"metricData": [
{
"200": {
"totalRequests": 20,
"averageLatency": 1500,
"totalPercentage": 100.0
}
}
]
},
"errorRequests": {
"totalRequests": 0,
"averageLatency": 0,
"totalPercentage": 0.0,
"metricData": []
}
}
},
{
"universal_queue": {
"totalRequests": 70,
"averageLatency": 21,
"totalPercentage": 20.0,
"successRequests": {
"totalRequests": 20,
"averageLatency": 1500,
"totalPercentage": 28.57,
"metricData": [
{
"200": {
"totalRequests": 20,
"averageLatency": 1500,
"totalPercentage": 28.57
}
}
]
},
"errorRequests": {
"totalRequests": 50,
"averageLatency": 1500,
"totalPercentage": 71.43,
"metricData": [
{
"500": {
"totalRequests": 30,
"averageLatency": 1500,
"totalPercentage": 42.86
}
},
{
"501": {
"totalRequests": 20,
"averageLatency": 1500,
"totalPercentage": 28.57
}
}
]
}
}
},
{
"universal_queue_fetch_message": {
"totalRequests": 70,
"averageLatency": 21,
"totalPercentage": 20.0,
"successRequests": {
"totalRequests": 20,
"averageLatency": 1500,
"totalPercentage": 28.57,
"metricData": [
{
"200": {
"totalRequests": 20,
"averageLatency": 1500,
"totalPercentage": 28.57
}
}
]
},
"errorRequests": {
"totalRequests": 50,
"averageLatency": 1500,
"totalPercentage": 71.43,
"metricData": [
{
"500": {
"totalRequests": 30,
"averageLatency": 1500,
"totalPercentage": 42.86
}
},
{
"501": {
"totalRequests": 20,
"averageLatency": 1500,
"totalPercentage": 28.57
}
}
]
}
}
}
]
}
},
{
"Chat_SOAP": {
"totalRequests": 130,
"averageLatency": 1500,
"totalPercentage": 37.14,
"successRequests": {
"totalRequests": 70,
"averageLatency": 1500,
"totalPercentage": 53.85,
"metricData": [
{
"200": {
"totalRequests": 70,
"averageLatency": 1500,
"totalPercentage": 53.85
}
}
]
},
"errorRequests": {
"totalRequests": 60,
"averageLatency": 1500,
"totalPercentage": 46.15,
"metricData": [
{
"500": {
"totalRequests": 60,
"averageLatency": 1500,
"totalPercentage": 46.15
}
}
]
},
"subServicesL2": [
{
"universal_queue": {
"totalRequests": 60,
"averageLatency": 25,
"totalPercentage": 17.14,
"successRequests": {
"totalRequests": 30,
"averageLatency": 1500,
"totalPercentage": 50.0,
"metricData": [
{
"200": {
"totalRequests": 30,
"averageLatency": 1500,
"totalPercentage": 50.0
}
}
]
},
"errorRequests": {
"totalRequests": 30,
"averageLatency": 1500,
"totalPercentage": 50.0,
"metricData": [
{
"500": {
"totalRequests": 30,
"averageLatency": 1500,
"totalPercentage": 50.0
}
}
]
}
}
},
{
"consumer": {
"totalRequests": 30,
"averageLatency": 50,
"totalPercentage": 8.57,
"successRequests": {
"totalRequests": 0,
"averageLatency": 0,
"totalPercentage": 0.0,
"metricData": []
},
"errorRequests": {
"totalRequests": 30,
"averageLatency": 1500,
"totalPercentage": 100.0,
"metricData": [
{
"500": {
"totalRequests": 30,
"averageLatency": 1500,
"totalPercentage": 100.0
}
}
]
}
}
},
{
"legacy": {
"totalRequests": 40,
"averageLatency": 38,
"totalPercentage": 11.43,
"successRequests": {
"totalRequests": 40,
"averageLatency": 1500,
"totalPercentage": 100.0,
"metricData": [
{
"200": {
"totalRequests": 40,
"averageLatency": 1500,
"totalPercentage": 100.0
}
}
]
},
"errorRequests": {
"totalRequests": 0,
"averageLatency": 0,
"totalPercentage": 0.0,
"metricData": []
}
}
}
]
}
}
]
}
}
],
"siteMetrics": {
"totalRequests": 350,
"averageLatency": 1500,
"successPercentage": 57.14
},
"siteName": "testSiteChat81",
"updatedTime": "2024-10-21T08:01:00Z",
"timeInterval": 120
}
Sr. No. | Element | Description |
1 | siteName | The name of the site for which the metrics are retrieved |
2 | updatedTime | The last updated time for which the events are received |
3 | timeInterval | The duration for which the metrics are displayed. For more information, refer to the “timeInterval Details & Sample Use Cases” in Step 7.0 |
4 | siteMetrics->totalRequests | The total number of requests received for this site |
5 | siteMetrics->successPercentage | Percentage of totalRequests which were success. Here success is any request which received a status not in 5xx bucket |
6 | serviceMetrics | The array containing individual service metrics for chat metrics |
7 | serviceMetrics->chat | The metrics for the chat component |
8 | serviceMetrics->chat->totalRequests | Total requests received by the chat component |
9 | serviceMetrics->chat->totalPercentage | Percentage of requests received for chat from the totalRequests for the site |
10 | serviceMetrics->chat->successRequests | Successful requests metrics from the total requests received by chat. Here successful requests are with HTTP status 2xx, 3xx and 4xx requests |
11 | serviceMetrics->chat->successRequests->metricData | The metric data for successful requests. Here metricData includes the HTTP Status and the count of totalRequests and its percentage (totalPercentage) in the total successful requests |
12 | serviceMetrics->chat->errorRequests | Error requests metrics from the total requests received for chat. Here error requests are with HTTP status 5xx |
13 | serviceMetrics->chat->subServices | SubServices metrics for subServices of chat. Currently sub-services for chat are Chat_REST and Chat_SOAP. The sub-services further expose successful and error metrics for the specific sub-service |
14 | serviceMetrics->chat->averageLatency | Average Latency for all the API requests served by chat service |
15 | serviceMetrics->Chat_REST | Metrics for the CHAT_REST subservice |
16 | serviceMetrics->Chat_REST-> totalRequests | Total requests served by the CHAT_REST subservice |
17 | serviceMetrics->Chat_REST-> successRequests | Successful requests metrics from the total requests received by the CHAT_REST subservice. Here successful requests are with HTTP status 2xx, 3xx and 4xx requests |
18 | serviceMetrics->Chat_REST-> successRequests-> averageLatency | Average latency for the successful requests served by the CHAT_REST subservice |
19 | serviceMetrics->Chat_REST->subServicesL2 | SubServicesL2 metrics for Chat_REST. Currently subServicesL2 for Chat_REST are agent, consumer, fetch_mesage, monitoring, provisioning, third_party, universal_queue. The subServicesL2 further expose successful and error metrics for the specific subservice |
20 | serviceMetrics->Chat_REST->subServicesL2->agent | Agent metrics for the subServicesL2 for Chat_REST service |
21 | serviceMetrics->Chat_SOAP | Metrics for the CHAT_SOAP subservice |
22 | serviceMetrics->Chat_SOAP-> totalRequests | Total requests served by the CHAT_SOAP subservice |
23 | serviceMetrics->Chat_SOAP-> successRequests | Successful requests metrics from the total requests received by the CHAT_SOAP subservice. Here successful requests are with HTTP status 2xx, 3xx and 4xx requests |
24 | serviceMetrics->Chat_SOAP-> successRequests-> averageLatency | Average latency for the successful requests served by the CHAT_SOAP subservice |
25 | serviceMetrics->Chat_SOAP->subServicesL2 | SubServicesL2 metrics for Chat_SOAP. Currently subServicesL2 for Chat_SOAP are universal_queue, consumer, legacy. The subServicesL2 further expose successful and error metrics for the specific subservice |
26 | serviceMetrics->Chat_REST->subServicesL2-> consumer | Consumer metrics for the subServicesL2 for Chat_REST subservice |
- The data in the JSON returned by the Service Health Metrics API is a 120-minute aggregated data
- The data points for totalRequests, totalPercentage, errorRequests are all aggregated for the last 120 minutes
- It is possible to aggregate the data for a shorter time interval
- The API accepts “timeInterval” (the interval is minutes, from 1 to 120) as a HTTP request header parameter
- The “timeInterval” parameter can accept any numerical value ranging from 1 to 120
- Within the “timeInterval” parameter, define the “fromDate” and “toDate” in order to filter the data by time
- Note: The HTTP request headers should be in UTC format (YYYY-MM-DDTHH:MM:SSZ)







Step 8.0: Understanding the ERROR METRICS REST API response
Now that your site is configured and authorized for Service Health Metrics, you can also review the data provided by the ERROR METRICS REST APIs. Error metrics can be retrieved for the 4XX & 5XX status groups:
- https://monitoring.custhelp.com/v1/errormetrics/[4XX|5XX]
- https://monitoring.custhelp.com/v1/errormetrics/[4XX|5XX]/<serviceName>
Below are sample responses and an explanation of the sub-components:
Sample Use Case 1: For https://monitoring.custhelp.com/v1/errormetrics/4XX
{
"errorMetrics": {
"totalRequests": 37,
"averageLatency": 1500,
"topRequests": [
{
"401": {
"totalRequests": 17,
"averageLatency": 1500,
"totalPercentage": 45.95,
"Urls": [
{
"url": "/services/soap/connect/soap",
"count": 6
},
{
"url": "/AgentWeb/api/contextmanager/v.32404290001/externalObjectServiceContext/reportData",
"count": 5
},
{
"url": "/services/different/connect/soap",
"count": 4
},
{
"url": "/AgentWeb/api/different/v.32404290001/externalObjectServiceContext/reportData",
"count": 2
}
]
}
},
{
"404": {
"totalRequests": 20,
"averageLatency": 1500,
"totalPercentage": 54.05,
"Urls": [
{
"url": "/AgentWeb/api/different/v.32404290001/externalObjectServiceContext/reportData",
"count": 6
},
{
"url": "/services/soap/connect/soap",
"count": 5
},
{
"url": "/AgentWeb/api/contextmanager/v.32404290001/externalObjectServiceContext/reportData",
"count": 5
},
{
"url": "/services/different/connect/soap",
"count": 4
}
]
}
}
],
"subComponents": [
{
"Browser_UI": {
"totalRequests": 18,
"averageLatency": 1500,
"totalPercentage": 48.65
}
},
{
"webserver": {
"totalRequests": 19,
"averageLatency": 1500,
"totalPercentage": 51.35
}
}
]
},
"serviceName": "ALL",
"siteName": "siteMetrics3",
"updatedTime": "2024-09-12T03:47:00Z",
"timeInterval": 120
}
Sample Use Case 2: For https://monitoring.custhelp.com/v1/errormetrics/4XX/webserver
{
"errorMetrics": {
"totalRequests": 19,
"averageLatency": 1500,
"topRequests": [
{
"401": {
"totalRequests": 10,
"averageLatency": 1500,
"totalPercentage": 52.63,
"Urls": [
{
"url": "/services/soap/connect/soap",
"count": 6
},
{
"url": "/services/different/connect/soap",
"count": 4
}
]
}
},
{
"404": {
"totalRequests": 9,
"averageLatency": 1500,
"totalPercentage": 47.37,
"Urls": [
{
"url": "/services/soap/connect/soap",
"count": 5
},
{
"url": "/services/different/connect/soap",
"count": 4
}
]
}
}
],
"subComponents": [
{
"other": {
"totalRequests": 8,
"averageLatency": 1500,
"totalPercentage": 42.11
}
},
{
"connect_ws_soap": {
"totalRequests": 11,
"averageLatency": 1500,
"totalPercentage": 57.89
}
}
]
},
"serviceName": "webserver",
"siteName": "siteMetrics3",
"updatedTime": "2024-09-12T03:47:00Z",
"timeInterval": 120
}
The above JSON responses have various attributes defined. The next table describes the exposed attributes:
Sr. No. | Element | Description |
1 | siteName | The name of the site for which the metrics are retrieved. |
2 | updatedTime | The last update time for which the events are received. |
3 | timeInterval | The duration for which the metrics are displayed. For more information, refer to the “timeInterval Details & Sample Use Cases” in Step 7.0 |
4 | serviceName | The name of the service for which metrics are retrieved. This shows the specific service name if retrieved for a particular service, eg. https://monitoring.custhelp.com/v1/errormetrics/4XX/webserver. If the metrics is retrieved for a status group, it shows “ALL” services, eg. https://monitoring.custhelp.com/v1/errormetrics/4XX. |
5 | errorMetrics > totalRequests | Total errors received from all the services or the specified service. |
6 | errorMetrics > topRequests | Top requests for each status code in the status group with total percentage of the total errors. |
7 | errorMetrics > topRequests > [status code] > Urls | Top 10 urls and their respective error counts for the defined status code. |
8 | errorMetrics > subComponents | Metrics for the subcomponents of the specified service. Subcomponent metrics may include data for all services, as shown in Sample Use Case 1. Subcomponent metrics may include data for a specific service, as shown in Sample Use Case 2. |
Additional information about the Service Health Metrics Endpoint
- The REST API hits to the Service Health Metrics endpoint are not billable.
- Currently, the Service Health Metrics REST API endpoint maintains data for 120 minutes (two hours). Making the data retention time configurable, is something we plan to include in a subsequent release. If you plan to retain this data for more than two hours, it is recommended to persist these metrics in your datastore. Persisting the metrics in your datastore also allows you to build historical trend reports.
- Please explain “average latency” and provide the unit by which it is measured
- Average latency is the average time required to serve a request, by specific service or subservice. The unit of measurement is milliseconds(ms)
- Please explain when a request is directed to the Widget Server
- The Widget Server handles static content required for interactive web UIs in the Customer Portal
- Please explain when a request is tracked on the Web Server
- The Web Server handles all API requests, Custom Script requests and Customer Portal requests. These API requests are Connect-REST, Connect-SOAP & Internal product APIs
- Monitoring Your Oracle B2C Service Health: Introducing Service Health Metrics
- Monitoring Your Oracle B2C Service Health: A Deep Dive into the Chat APIs available within Service Health Metrics