26 Mar 2025
12:32 PM
- last edited on
27 Mar 2025
08:06 AM
by
MaciejNeumann
Hi Dynatrace Community,
I wanted to share my experience with querying USQL in a Dynatrace Notebook using JavaScript to fetch Real User Monitoring (RUM) data for a Grail dashboard, as Grail doesn’t have built-in RUM metrics. My goal was to display the number of active users in a dashboard tile, but I encountered an issue with making the timeframe dynamic.
I used the following USQL query in a Notebook to count distinct users for my application, xxx:
SELECT COUNT(DISTINCT userId)
FROM usersession
WHERE useraction.application = 'xxx'
AND userType = 'REAL_USER'
AND applicationType = 'MOBILE_APPLICATION'
Initially, I hardcoded the timeframe in my JavaScript code (e.g., using a default of the last 7 days or a specific date like March 25, 2025). While this worked to fetch the data, the tile was not dynamic when pinned to a Grail dashboard—it didn’t update when I changed the dashboard’s timeframe (e.g., to “Yesterday” or “Last 30 days”). The console log showed Context object: { "$": null }, indicating that the dashboard’s timeframe wasn’t being passed to the Notebook code.
Here’s an example of the hardcoded approach I tried:
javascript
Hardcoding the timeframe means the tile is static and won’t reflect the dashboard’s selected timeframe. This approach is fine for testing but fails for dynamic dashboard integration, which is essential for real-time monitoring and reporting in Grail dashboards. For example, if the dashboard timeframe is set to “Last 30 days,” a hardcoded tile will still show data for the hardcoded date (e.g., March 25, 2025), leading to incorrect or outdated insights.
javscript code
let startTimestamp, endTimestamp;
if (context?.timeframe?.start && context?.timeframe?.end) {
// Use the dashboard's timeframe (already in UTC milliseconds)
startTimestamp = context.timeframe.start;
endTimestamp = context.timeframe.end;
console.log("Using dashboard timeframe:", {
start: new Date(startTimestamp).toISOString(),
end: new Date(endTimestamp).toISOString()
});
} else {
// Fallback to default timeframe (last 7 days)
console.warn("Dashboard timeframe not available. Falling back to default timeframe (last 7 days).");
startTimestamp = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).getTime();
endTimestamp = new Date().getTime();
console.log("Using default timeframe:", {
start: new Date(startTimestamp).toISOString(),
end: new Date(endTimestamp).toISOString()
});
}