Skip to content

Instantly share code, notes, and snippets.

@gspncr
Last active January 24, 2021 14:48
Show Gist options
  • Save gspncr/f76127ac2714b01ff880b8b2a73f9d8f to your computer and use it in GitHub Desktop.
Save gspncr/f76127ac2714b01ff880b8b2a73f9d8f to your computer and use it in GitHub Desktop.
nerdpack demo

NR1 Programmability Demo

inspired by Lew's demo at AWS re:Invent 2020 because that was ✨awesome✨ and building on it.

Intro

Thanks for joining. Most of you will know New Relic perhaps for our Observability platform, for APM, but you might not know that you can build applications right on top of of our platform to make the most out of the telemetry that we collect. You can do this using the very same API's and components that our developers themselves use to build our products views.

So in this demo I am going to build an application in New Relic from scratch. All you need to know to build an app on NR1 is React.

It is super easy getting started. All you do is go to one.newrelic.com and click Build your own app. You're then taken to the quick start guide. From here you can get your API key and download the CLI. I've already done that so let's go and get started building an app.

So I do nr1: create I can create a number of things. A NerdPack is what we call an application in New Relic, and I am going to select that.

It suggests a name for me in case I can't think of one. I am going to roll with that.

So now we have an application and it is sitting on my laptop.

cd nerdlet

ls

So looking inside, you can see that this is just an NPM package. Inside the package is just React components.

npm i

I am going to install the dependencies. You can also add whatever other packages you want to make this more powerful.

code . Let's open this in VS Code and take a look at the source

npm start I will also run this from my laptop.

I can see my app is running and I am given a URL to go to. What you see here is the regular New Relic One URL but with nerdpacks = local which allows me to run the normal NR1 but my local application is put inside there.

So I'll go to that URL and open apps, and find my app. We can see what is running on my laptop is put in this UI.

import React from 'react';
import {LineChart, TextField} from 'nr1'
// https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction
export default class DisgustedSecretaryNerdletNerdlet extends React.Component {
render() {
return <div style={{padding: "12px", height: "600px"}}>
<LineChart fullWidth fullHeight accountId={1147177} query={`SELECT count(*) from PageView since 1 week ago timeseries facet city`}></LineChart>
</div>
}
}

Part 1: LineChart PageView data by city

Now let's take a look at the code. I am going to open this file nerdlets/index.js and this is the running code in my NR1 application. Like I mention, this is really just a React component.

So let me do something pretty simple to get started with.

proceed to change the "Hello world!" to something else, and show in browser the change.

Basically, as fast as I can hit save, that UI will update with my program code.

Let's do something like a real application using components.

And now I am going to import a few of our NR1 components to build the visualisations, and interact with the Telemetry Data Platform in NR1. We will give it some inline styling for quickness here. Our components require two things, one is an accountId and the other is a query. I am going to add my accountId and provide the query to select all of the page view data.

proceed to make the changes per part-1.js

import React from 'react';
import {AreaChart, LineChart, TextField} from 'nr1'
// https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction
export default class DisgustedSecretaryNerdletNerdlet extends React.Component {
render() {
return <div style={{padding: "12px", height: "600px"}}>
<AreaChart fullWidth fullHeight accountId={1147177} query={`SELECT count(*) from PageView since 1 week ago timeseries facet city`}></AreaChart>
</div>
}
}

Part 2: AreaChart by city

Maybe I will think this looks better as an area chart. This is super easy to change.

I am going to bring in that component and change my LineChart to type AreaChart.

proceed to make the changes per part-2.js - updating LineChart to AreaChart

So now I get an Area Chart, great. And this is showing me all of the page views by each city. But this can be easily done in a dashboard, so what can we do unique to an app? I can do more powerful things and control them programmatically.

Let's try something.

import React from 'react';
import {AreaChart, LineChart, TextField} from 'nr1'
// https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction
export default class DisgustedSecretaryNerdletNerdlet extends React.Component {
state = {text: ""}
render() {
const {text} = this.state
return <div style={{padding: "12px", height: "600px"}}>
<TextField value={text} onChange={e => this.setState({text: e.target.value})} type="search" autoFocus />
<AreaChart fullWidth fullHeight accountId={1147177} query={`SELECT count(*) from PageView since 1 week ago timeseries facet city`}></AreaChart>
</div>
}
}

Part 3: TextField

In this instance I am going to bring in a TextField to allow me to search.

I am also going to let it take focus so that I can start typing straight away without having to click it first.

proceed to make the changes per part-3.js - including a TextField component.

So let us type something. Nothing is happening with that text. This is where we can start doing something more powerful. I am going to take that text, and modify the query on every keystroke to search for the text field value. In my case this will be a city name, you could also do this for things like an email address or any other attribute on an event.

import React from 'react';
import {AreaChart, LineChart, TextField} from 'nr1'
// https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction
export default class DisgustedSecretaryNerdletNerdlet extends React.Component {
state = {text: ""}
render() {
const {text} = this.state
return <div style={{padding: "12px", height: "600px"}}>
<TextField value={text} onChange={e => this.setState({text: e.target.value})} type="search" autoFocus />
<AreaChart fullWidth fullHeight accountId={1147177} query={`SELECT count(*) from PageView since 1 week ago timeseries facet city where city like '%${text}%'`}></AreaChart>
</div>
}
}

Part 4: Modified query

So all I am going to have to change here is modify the query to include the variable of the text field.

It is already stored in a variable so I can extend my NRQL query by referencing it.

proceed to make the changes per part-4.js - extending the NRQL call to reference the textfield value, using %wilcard% operators

Now I can search by the value in this field.

So you can see I can build further use cases on top of this data like searching usernames, and I can begin to pursue other use cases as quickly as I can write React code.

If you're looking for some use cases and examples, check out opensource.newrelic.com where we have a tonne of open source example projects on GitHub. Some very powerful examples such as Cloud Optimize, which can be used to right-size your cloud environment.

Hopefully that has given you a quick showcase into getting started with New Relic One programmability - I encourage you to give it a try for yourselves!

import React from 'react';
import {AreaChart, LineChart, TextField} from 'nr1'
// https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction
export default class DisgustedSecretaryNerdletNerdlet extends React.Component {
state = {text: ""}
render() {
const {text} = this.state
return <div style={{padding: "12px", height: "600px"}}>
<h1>Page Views for: {text}</h1>
<TextField value={text} onChange={e => this.setState({text: e.target.value})} type="search" autoFocus />
<AreaChart fullWidth fullHeight accountId={1147177} query={`SELECT count(*) from PageView since 1 week ago timeseries facet city where city like '%${text}%'`}></AreaChart>
</div>
}
}

Stretch 1: Adding a h1 header

In this stretch activity we are going to give the page a title and reference the search field value.

proceed to make the changes per stretch-1.js - including a h1 tag and referencing the {text} variable.

So this is great, but it looks a bit ugly if users have not typed anything. An idea would be that if nothing is typed into the search field, that I can prompt a user with what exactly they can do.

import React from 'react';
import {AreaChart, LineChart, TextField} from 'nr1'
// https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction
export default class DisgustedSecretaryNerdletNerdlet extends React.Component {
state = {text: ""}
render() {
const {text} = this.state
//conditional ternary operator operator to show placeholder title if the searchbox is empty
let title = this.state.text ? "Page views for: " + this.state.text : "Type a city name to start searching"
console.log(title)
return <div style={{padding: "12px", height: "600px"}}>
<h1>{title}</h1>
<TextField value={text} onChange={e => this.setState({text: e.target.value})} type="search" autoFocus />
<AreaChart fullWidth fullHeight accountId={1147177} query={`SELECT count(*) from PageView since 1 week ago timeseries facet city where city like '%${text}%'`}></AreaChart>
</div>
}
}

Stretch 2: Conditional (ternary) operator for guiding users

In this stretch activity we are going to use a conditional ternary operator.

It is going to give the title variable the value of a prompt for what they can use the search text field for if they have not typed anything It is going to give the value of what has been searched for after something is typed in the search text field.

A conditional ternary operator is basically an if statement, but in a single line.

proceed to make the changes per stretch-2.js - including a ternary operator for the h1 title

import React from 'react';
import {AreaChart, LineChart, TextField} from 'nr1'
// https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction
export default class DisgustedSecretaryNerdletNerdlet extends React.Component {
state = {text: ""}
render() {
const {text} = this.state
let title = this.state.text ? "Page views for: " + this.state.text : "Type a city name to start searching"
console.log(title)
return <div style={{padding: "12px", height: "600px"}}>
<h1>{title}</h1>
<TextField value={text} onChange={e => this.setState({text: e.target.value})} type="search" autoFocus placeholder="e.g. London" style={{width: "100%"}}/>
<AreaChart fullWidth fullHeight accountId={1147177} query={`SELECT count(*) from PageView since 1 week ago timeseries facet city where city like '%${text}%'`}></AreaChart>
</div>
}
}

Stretch 3: Extending the TextField component

In this stretch activity we are going to decorate the TextField component by giving it a placeholder text, and styling it inline.

proceed to make the changes per stretch-3.js - placeholder, style

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment