Remote environment data
With code tiles (in Dashboards) and code sections (in Notebooks), you can consolidate data from multiple Dynatrace environments.
The example JavaScript code described below uses the credential vault for secure token storage, and OAuth for authentication, to offer a robust and secure way to fetch data from a remote Dynatrace environment.
Prerequisites
Before you create the code for your dashboard tile or notebook section:
- Create an OAuth client. For details, see Authentication.
- Create a Dynatrace credential vault entry on the primary environment to store the OAuth token that is later used in the code tile or section for authentication. For details, see Credential vault.
You will use these in the JavaScript that you add to your code tile or section.
Code overview
Before you start coding, review the skeleton code in this section to see how the three main functions are used.
-
authenticateToDynatrace(clientId = '', clientSecret = '')
To authenticate against SSO, this function:
- Takes two parameters:
clientId
andclientSecret
. - Returns an access token.
- Takes two parameters:
-
fetchFromDynatrace(credentialId = "", url = "", query = "")
To fetch data from Dynatrace, this function:
- Retrieves the credentials from the credential vault entry on the primary tenant.
- Gets an access token for the secondary tenant via SSO.
- Makes the API call on the APIs of the secondary/remote tenant.
-
async function()
This is the main function. It calls
fetchFromDynatrace
(see above) with the necessary parameters.
import { credentialVaultClient } from "@dynatrace-sdk/client-classic-environment-v2";async function authenticateToDynatrace(clientId = '', clientSecret = '') {// authentication against SSO// ...}async function fetchFromDynatrace(credentialId = "", url = "", query = "") {// gets the credentials from the credential vault entry on the primary tenant (this tenant)// gets access token for the secondary tenant via SSO, needed for the subsequent API call below// the actual API call on the APIs of the secondary/remote tenant// ...}export default async function() {// dev stage -> CREDENTIALS_VAULT-XXXXXXXXXXXXXXXX// prod stage -> CREDENTIALS_VAULT-XXXXXXXXXXXXXXXX// ...}
Code details
Now that you have completed the prerequisites and reviewed the general code structure, you're ready to code.
-
Base your code on the example below.
-
Read the comments in the code example for code details.
-
Replace
CREDENTIALS_VAULT-XXXXXXXXXXXXXXXX
with your own credential ID. -
Replace
https://remote-environment-id.apps.dynatrace.com/platform/storage/query/v1/query:execute?enrich:metric-metadata
with your own URL. -
Customize the
"fetch logs | limit 1"
query according to your needs. -
Run your code in a code tile (Dashboards) or code section (Notebooks).
If you encounter errors when you run your code, they will be caught and logged with the prefixes
[DynatraceAuthError]
,[CredentialVaultError]
, or[ExecutionError]
for easier debugging.
import { credentialVaultClient } from "@dynatrace-sdk/client-classic-environment-v2";// 1 authentication against SSOasync function authenticateToDynatrace(clientId = '', clientSecret = '') {const scopes = ["environment-api","storage:buckets:read","storage:bizevents:read","storage:logs:read","storage:metrics:read","storage:entities:read"].join(" ")const {access_token} = await fetch("https://sso.dynatrace.com/sso/oauth2/token", {method: "POST",headers: {"Content-Type": "application/x-www-form-urlencoded",},body: `grant_type=client_credentials&client_id=${clientId}&client_secret=${clientSecret}&scopes=${scopes}`,}).then((resp) => resp.json()).catch(error => `[DynatraceAuthError] ${error}`)return access_token}async function fetchFromDynatrace(credentialId = "", url = "", query = "") {// 1 - gets the credentials from the credential vault entry on the primary tenant (this tenant)const {password, username } = await credentialVaultClient.getCredentialsDetails({ id: credentialId }).catch((e) => console.error(`[CredentialVaultError] ${e}`));// 2 - gets an access token for the secondary tenant via SSO, needed for the subsequent API call belowconst accessToken = await authenticateToDynatrace(username, password)// 3 - the actual API call on the APIs of the secondary/remote tenantreturn await fetch(url, {method: "POST",headers: {"Content-Type": "application/json",Accept: "application/json",Authorization: `Bearer ${accessToken}`,},body: JSON.stringify({query,requestTimeoutMilliseconds: 60000,enablePreview: true,}),}).then((res) => res.json()).catch(e => `[ExecutionError] ${e}`);}export default async function() {const { result } = await fetchFromDynatrace("CREDENTIALS_VAULT-XXXXXXXXXXXXXXXX","https://remote-environment-id.apps.dynatrace.com/platform/storage/query/v1/query:execute?enrich:metric-metadata","fetch logs | limit 1");return result}