Forecast with Dynatrace Intelligence
- How to
- 5 minutes
"Dynatrace Intelligence" is the umbrella term for all AI in Dynatrace, including generative, agentic, causal, and predictive AI. It replaces "Davis AI" and "Davis CoPilot" and expands upon their capabilities. The terms "Davis" and "CoPilot" persist in certain locations, including APIs, Swagger, scopes, and Grail. These references are still relevant for Dynatrace Intelligence.
The latest Dynatrace platform provides general-purpose AI/ML services covering various functionalities. In this guide, you'll learn the intricacies of using the Dynatrace predictive and causal AI platform service from your Dynatrace® Apps.
Get available analyzers
Before getting started, one of the main questions to answer is which data analyzers are available for you to use. To see the available analyzers, you have two options:
-
Check out the
/analyzersendpoint in the . It's the easiest way of accessing every option of the different endpoints. -
Use the Dynatrace data analyzers SDK in your app:
import { analyzersClient } from '@dynatrace-sdk/client-davis-analyzers';
const { analyzers, totalCount, nextPageKey } = await analyzersClient.queryAnalyzers({
filter: "name contains 'statistic'",
addFields: 'baseAnalyzer, type, input',
});TipThis operation requires the scope
davis:analyzers:read. Read more about scopes in this guide.NoteTo use
awaitin React components, you need to wrap the asynchronous invocation in anasyncfunction. Read more about it in this guide.
Once you've chosen the analyzer that best fits your use case, you need to understand its requirements. The next section describes how to do that.
Analyzers input and output
All Dynatrace data analyzers have a basic set of input parameters, like timeframe or logVerbosity. Additionally, each analyzer needs a specific set of input parameters unique to that analyzer. There are a couple ways to get this information:
-
Using the .
-
Use the SDK to get the analyzer definition:
const analyzer = await analyzersClient.getAnalyzer({
analyzerName: 'dt.statistics.GenericForecastAnalyzer',
});TipThis operation requires the scope
davis:analyzers:read. Read more about scopes in this guide.NoteTo use
awaitin React components, you need to wrap the asynchronous invocation in anasyncfunction. Read more about it in this guide.
The output of each analyzer can be very different as well. You need to query the analyzer definition using one of the two methods above to get the output definition.
Time series forecast analysis
At this point, we know which analyzer we want to use and we understand its input parameters and its output definition. Now, we get to use it. Let's look at a complete example of how you would use the dt.statistics.GenericForecastAnalyzer analyzer to get a forecast of any time series metric.
Execute analyzer
This operation requires the scope davis:analyzers:execute. Read more about scopes in this guide.
Let's begin by creating a function that will request the forecast analysis:
import { analyzersClient } from '@dynatrace-sdk/client-davis-analyzers';
export const loadForecast = async (query: string) => {
const analyzerName = 'dt.statistics.GenericForecastAnalyzer';
const response = await analyzersClient.executeAnalyzer({
analyzerName,
body: {
timeSeriesData: {
expression: query,
},
},
});
// ...
};
Depending on the chosen analyzer and the analyzer input, additional scopes might be required, for example, storage:buckets:read and storage:metrics:read to enable the analyzer to read time series data from Grail™.
This function receives a DQL query as a parameter and triggers an async forecast analysis on the results of running said query via the executeAnalyzer function from the analyzersClient. If the analysis takes more than two seconds to finish, the response will contain a requestToken that will allow you to poll until the results are available.
Poll analyzer execution
Let's create a new pollExecution function to handle the polling logic.
import { AnalyzerResult, analyzersClient } from '@dynatrace-sdk/client-davis-analyzers';
export const pollExecution = async (analyzerName: string, requestToken: string): Promise<AnalyzerResult> => {
const MAX_ATTEMPTS = 10;
const INTERVAL_MS = 1000;
let attempts = 0;
while (attempts < MAX_ATTEMPTS) {
await new Promise((resolve) => setTimeout(resolve, INTERVAL_MS));
const { result } = await analyzersClient.pollAnalyzerExecution({
analyzerName,
requestToken,
});
if (result.executionStatus === 'COMPLETED') {
return result;
}
if (result.executionStatus === 'ABORTED') {
throw new Error('The analyzer execution was aborted');
}
attempts++;
}
const cancelResponse = await analyzersClient.cancelAnalyzerExecution({
analyzerName,
requestToken,
});
if (cancelResponse && cancelResponse.result.executionStatus === 'COMPLETED') {
return cancelResponse.result;
}
throw new Error('Max polling retries reached');
};
Aside from the simple polling implementation, we've introduced two new functions:
pollAnalyzerExecution: This function allows you to check the analysis execution status with the analyzer name and the request token you got in the initial request.cancelAnalyzerExecution: Once we've reached the max polling attempts, we recommend canceling the analysis execution. If the analysis finishes between the last poll and the cancellation, this function will return the analysis results. Otherwise, the response will beundefined.
Handle analyzer output
We can now use pollExecution in our main function and extract the forecasting information as a TimeseriesBand from the analysis output:
import { analyzersClient } from '@dynatrace-sdk/client-davis-analyzers';
import { convertToTimeseriesBand, TimeseriesBand } from '@dynatrace/strato-components-preview/charts';
import { pollExecution } from './pollExecution';
export const loadForecast = async (query: string): Promise<TimeseriesBand> => {
const analyzerName = 'dt.statistics.GenericForecastAnalyzer';
const response = await analyzersClient.executeAnalyzer({
analyzerName,
body: {
timeSeriesData: {
expression: query,
},
},
});
const analysisResult = response.requestToken
? await pollExecution(analyzerName, response.requestToken)
: response.result;
if (analysisResult.executionStatus === 'COMPLETED') {
const analyzerOutput = analysisResult.output[0];
const timeseriesBandData = convertToTimeseriesBand(
analyzerOutput.timeSeriesDataWithPredictions.records[0],
analyzerOutput.timeSeriesDataWithPredictions.types[0],
);
if (timeseriesBandData) {
return timeseriesBandData.timeseriesBand;
}
throw new Error('Unexpected error');
}
throw new Error('The analyzer execution was aborted');
};
Your loadForecast function is now ready. You can provide any time series DQL query to this function, and it will handle the forecast analysis and return it in TimeseriesBand format, which you can use to visualize it.
You can learn more about visualizing a TimeseriesBand from the TimeseriesChart reference page.
Troubleshooting
A data analyzer execution can fail for different reasons. If it does fail, the response will contain a log array that you can use to figure out why the analysis was unsuccessful. For instance, if the provided query doesn't return enough data points, the response will look something like this:
{
"result": {
"resultId": "4e1a8a1efd560193",
"resultStatus": "FAILED",
"executionStatus": "COMPLETED",
"input": {
...
},
"logs": [
{
"level": "WARNING",
"message": "More historical data is required to generate a reliable forecast. Increase the timeframe or adapt the resolution to include a minimum of 14 non-NaN observations.",
"analyzerName": "dt.statistics.GenericForecastAnalyzer"
},
{
"level": "SEVERE",
"message": "The analysis of the data was not successful.",
"analyzerName": "dt.statistics.GenericForecastAnalyzer"
}
],
"output": []
}
}
Related links
- Visit the
- Learn more about the Dynatrace Intelligence service
- Learn more about Forecast analysis