The purpose of this lab is to demonstrate how to incorporate 3rd party data into a standard visualization in New Relic One. To do that, we're going to simulate a set of forecasting data and incorporate that data into a LineChart
that is displaying a timeseries of PageViews
.
After completing this lab you should understand:
- How to generate a data series that can be processed by a chart component.
Note: This lab assumes you have a Browser application instrumented with New Relic.
Load the prequisites and follow the setup instructions in Setup.
Reminder: Make sure that you're ready to go with your lab7
by ensuring you've run the following commands:
# from the nr1-workshop directory
cd lab7
nr1 nerdpack:uuid -gf
npm install
nr1 nerdpack:serve
You'll notice that this Nerdlet
doesn't have a corresponding Launcher
, so we're going to need to find it.
- Open the file
lab7/nerdlets/my-nerdlet/nr1.json
and check out the contents. They look like the following. Pay attention to thecontext
attribute:
{
"schemaType": "NERDLET",
"id": "my-nerdlet",
"description": "Describe me",
"displayName": "Lab 7: Custom Data",
"context": {
"entities": [
{
"domain": "BROWSER",
"type": "APPLICATION"
}
]
}
}
- Open a web browser to
https://one.newrelic.com?nerdpacks=local
- Click on the
Entity Explorer
- Click on
Browswer Applications
category in the left-hand navigation - Click on any browser application from the list
- You should now see a menu option in the left-hand navigation called
Lab 7: Custom Data
- Click on
Lab 7: Custom Data
You should come to screen that looks like the following:
Note: before you become concerned, cats and Star Trek have nothing to do with this exercise. Consider it a fun way to demonstrate what you can do with a Grid
layout in New Relic One.
Our objective is going to be displaying a LineChart
of PageView
events that contrasts the current selected time window, the previous time window, and a made up set of forecasted data. In order to do that, we're going to need to do several things:
- Get access to the
platformUrlState.timeRange
- Get access to the
nerdletUrlState.entityGuid
- Retrieve the entity assigned to that
entityGuid
by means ofEntityByGuidQuery
- Use the
accountId
associated with that entity to run aNrqlQuery
- then manipulate the results, adding in our forecasting data using the helper function we've provided in the
utils.js
file calledgenerateForecastData
Let's start with our Contexts.
- Add the following import statements to the top of your
lab7/nerdlets/my-nerdlet/index.js
import { NrqlQuery, Spinner, LineChart, BlockText, PlatformStateContext, NerdletStateContext, EntityByGuidQuery } from 'nr1';
import { generateForecastData } from './utils';
- Next replace the render method with the following:
render() {
return <PlatformStateContext.Consumer>
{(platformUrlState) => (
<NerdletStateContext.Consumer>
{(nerdletUrlState) => (
<EntityByGuidQuery entityGuid={nerdletUrlState.entityGuid}>
{({data, loading, error}) => {
console.debug("EntityByGuidQuery", [loading, data, error]); //eslint-disable-line
if (loading) {
return <Spinner fillContainer />;
}
if (error) {
return <BlockText>{error.message}</BlockText>
}
const entity = data.entities[0];
const { accountId } = entity;
const { duration } = platformUrlState.timeRange;
const durationInMinutes = duration/1000/60;
//we're going to replace this soon
console.debug("We're ready for our NrqlQuery", [entity, accountId, duration, durationInMinutes]);
return null;
}}
</EntityByGuidQuery>
)}
</NerdletStateContext.Consumer>
)}
</PlatformStateContext.Consumer>;
}
- Save
lab7/nerdlets/my-nerdlet/index.js
and watch the reload. Open the browser'sConsole
and read messages in theDebug
tab. You should see something like the following:
- Take a few minutes to review the code you just added to the
render
method. Does it make sense to you? We're using thePlatformStateContext
andNerdletStateContext
to retrieve contexts we need in order to request the entity using theEntityByGuidQuery
. If that doesn't all make sense, ask for some help.
We're going to use the NrqlQuery
component to populate a LineChart
using its data
attribute.
If you're thinking, "based on what I've already learned, a LineChart
doesn't need a custom data set. It can process a NRQL query on its own." You're correct. However, we're going to eventually add an additional series of data to the result we get back from our NrqlQuery
before the data is passed to the LineChart
, so keep tracking.
- Replace the
return null;
statement in yourrender
method with the following component definition:
return <NrqlQuery accountId={accountId} query={`SELECT uniqueCount(session) FROM PageView WHERE appName = '${entity.name.replace("'", "\\'")}' TIMESERIES SINCE ${durationInMinutes} MINUTES AGO COMPARE WITH ${durationInMinutes*2} MINUTES AGO`}>
{({ loading, data, error }) => {
console.debug("NrqlQuery", [loading, data, error]); //eslint-disable-line
if (loading) {
return <Spinner fillContainer />;
}
if (error) {
return <BlockText>{error.message}</BlockText>;
}
return <LineChart data={data} className="chart"/>;
}}
</NrqlQuery>
Study that code and ensure you've got a solid handle on what's going on there. If you don't, ask questions. Now... Seriously... Do it.
- Save
lab7/nerdlets/my-nerdlet/index.js
and watch the reload. You should see a result like the folllowing:
You should see a current and yesterday, but no Forecast data. Let's make some.
We're only one line of code away from our preferred outcome thanks to the generateForecastData
function we imported earlier. If you haven't looked over the 20+ lines of code, please do so now. It'll give you an appropriate picture of what's needed to generate a chart data series.
- Add the following line to the
render
method of thelab7/nerdlets/my-nerdlet/index.js
, just above thereturn <LineChart...
line.
...
data.push(generateForecastData(data[0]));
return <LineChart data={data} className="chart"/>;
...
The final code in lab7/nerdlets/my-nerdlet/index.js
should look something like this:
import React from 'react';
import { Grid, GridItem } from 'nr1';
import { NrqlQuery, Spinner, LineChart, BlockText, PlatformStateContext, NerdletStateContext, EntityByGuidQuery } from 'nr1';
import { generateForecastData } from './utils';
export default class MyNerdlet extends React.Component {
constructor(props) {
super(props);
console.debug(props); //eslint-disable-line
}
render() {
return <PlatformStateContext.Consumer>
{(platformUrlState) => (
<NerdletStateContext.Consumer>
{(nerdletUrlState) => (
<EntityByGuidQuery entityGuid={nerdletUrlState.entityGuid}>
{({data, loading, error}) => {
console.debug("EntityByGuidQuery", [loading, data, error]); //eslint-disable-line
if (loading) {
return <Spinner fillContainer />;
}
if (error) {
return <BlockText>{error.message}</BlockText>
}
const entity = data.entities[0];
const { accountId } = entity;
const { duration } = platformUrlState.timeRange;
const durationInMinutes = duration/1000/60;
return <NrqlQuery accountId={accountId} query={`SELECT uniqueCount(session) FROM PageView WHERE appName = '${entity.name.replace("'", "\\'")}' TIMESERIES SINCE ${durationInMinutes} MINUTES AGO COMPARE WITH ${durationInMinutes*2} MINUTES AGO`}>
{({ loading, data, error }) => {
console.debug("NrqlQuery", [loading, data, error]); //eslint-disable-line
if (loading) {
return <Spinner fillContainer />;
}
if (error) {
return <BlockText>{error.message}</BlockText>;
}
data.push(generateForecastData(data[0]));
return <LineChart data={data} className="chart"/>;
}}
</NrqlQuery>
}}
</EntityByGuidQuery>
)}
</NerdletStateContext.Consumer>
)}
</PlatformStateContext.Consumer>;
}
}
- What other types of data might you chose to intermingle with performance data?
- Does it make sense why the
Lab 7: Custom Data
Nerdlet was only displaying forBrowser Application
instances? - Read more about how to attach a Nerdlet to your entities in our documentation.