You might be familiar with one or more of the New Relic APIs, but are you using them to get the most done with the least effort?
We build the New Relic APIs to be simple to use, and if you have a workflow within your New Relic account that you want to automate, chances are we have an API that can help.
To demonstrate, let’s look at two examples of how to nest some simple API calls together to streamline and automate common workflows you may encounter in New Relic:
- Labeling an application or service based on its name
- Setting your Apdex threshold based on response time percentiles
For each example, we’ve included Node.js scripts that you can use in your own environments.
(This post assumes some familiarity with the basics of New Relic API keys, the API explorer, application labels and Apdex. To learn about those topics, you can also check out the New Relic APIs course in New Relic University.)
Using API automation to label an application
Labels are a handy way to increase your application’s searchability, categorization, and alerting configuration in New Relic. Though it is easiest to apply labels when configuring your New Relic agent for the first time, your labeling strategy may change over time, or in some cases, it may not be possible to add labels during the agent’s original configuration. This example addresses how to add labels to your applications or services after New Relic is already deployed.
Let’s say you started with a naming convention that calls for adding the environment to the service or application’s name; for example, Prod-My Application
or Staging-My Application
. Now, however, after reviewing your alerting guidelines, you realize that using Environment:Production
and Environment:Staging
labels would make it easier to search and target your applications for alerts.
At this point, you could manually apply the new labels to your applications or update the applications’ configurations. If you have enough application or service instances, though, that could quickly become laborious. Instead, avoid that needless toil by automating the relabeling with an API?
The required steps
In the rest of the process, you’ll:
- Gather the details for all your service or application instances.
- Determine if the names contain a specific string; in this example, we’re looking for the string “prod”.
- Create a label—in this case,
Environment:Production
—and apply it to all service or application instances that contain the string “prod”. - Relish the glory of API automation.
The example script
TheNode.js script below retrieves a list of your services or applications, checks if the name contains the string “prod”, and then applies the label Environment:Production.
Note: To use this script in your environment, you’ll need to replace YOUR_ADMIN_KEY_HERE
with your actual New Relic admin API key.
var request = require("request");
var adminKey = "YOUR_ADMIN_KEY_HERE";
var headers = {
"Content-Type": "json/application",
"X-Api-Key": adminKey
};
var options = {
url: "https://api.newrelic.com/v2/applications.json",
method: 'GET',
headers: headers
};
request(options,
function(error, response, body) {
if (error) return onErr(error);
if (!error && response.statusCode == 200) {
var result = JSON.parse(body);
console.log('Number of applications found:'+result["applications"].length);
for (var i = 0; i < result["applications"].length; ++i) {
var application = result["applications"][i]
var appName = application["name"];
var lowerCaseName = appName.toLowerCase();
if (lowerCaseName.indexOf('prod')==-1) {
console.log ('application name: '+application["name"]+' does not contain prod');
}
else{
console.log('application name: '+application["name"]+' contains prod');
addLabel(application);
}
}
}
});
function addLabel(application){
console.log ('application name: '+application["name"]+ ' application ID '+application["id"]);
var request = require("request");
var options = { method: 'PUT',
url: 'https://api.newrelic.com/v2/labels.json',
headers:
{
'X-Api-Key': adminKey,
'Content-Type': 'application/json' },
body:
{ label:
{ category: 'Environment',
name: 'Production',
links: { applications: [ application["id"] ] } } },
json: true };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
}
function onErr(err) {
console.log(err);
return 1;
}
Use API automation to set your Apdex threshold
Apdex is a useful way to understand how well your application or service is performing, but if complex systems may comprise hundreds or even thousands of services or application instances.
As in our first example, you could manually change the Apdex settings for each application or service (which would take quite a bit of time), or you could leave everything at the default value and hope for the best (which is also not a great idea).
The alternative, of course, is API automation!
The required steps
First, you want to choose an appropriate Apdex threshold. Without diving into the math, you can use a specific percentile response time for your Apdex threshold to get a specific Apdex score, as shown in this chart:
Target Adex score | Percentile to use |
---|---|
Target Adex score0.85 | Percentile to use70% |
Target Adex score0.88 | Percentile to use76% |
Target Adex score0.9 | Percentile to use80% |
Target Adex score0.92 | Percentile to use84% |
Target Adex score0.94 | Percentile to use88% |
Target Adex score0.95 | Percentile to use90% |
Target Adex score0.96 | Percentile to use92% |
Target Adex score0.98 | Percentile to use96% |
Simply choose the Apdex score you want and use the corresponding percentile.
In the rest of the process, you’ll:
- Gather the details for all your service or application instances.
- For each application or service, use the New Relic Insights API to query New Relic to determine the percentile response time you desire.
- Update the service or application’s Apdex setting with that new threshold.
- Relish the glory of API automation.
The example script
The Node.js script below retrieves a list of your services or applications, queries the application’s percentile response time using the Insights API, and then applies the appropriate Apdex threshold.
Note: To use this script in your environment, you’ll need to replace the following:
YOUR_ADMIN_KEY
with New Relic admin API key.YOUR_ACCOUNT_I
D with the ID of the account you want to use.YOUR_QUERY_KEY
with your Insights API query key.YOUR_VALUE
with whatever value you have chosen from the table above.
var request = require("request");
var adminKey = "YOUR_ADMIN_KEY";
var ACCOUNT_ID = "YOUR_ACCOUNT_ID"
var QUERY_KEY = "YOUR_QUERY_KEY"
var desiredPercentile = “YOUR_VALUE”;
var headers = {
"Content-Type": "json/application",
"X-Api-Key": adminKey
};
var options = {
url: "https://api.newrelic.com/v2/applications.json",
method: 'GET',
headers: headers
};
request(options,
function(error, response, body) {
if (error) return onErr(error);
if (!error && response.statusCode == 200) {
var result = JSON.parse(body);
console.log('Number of applications found:'+result["applications"].length);
for (var i = 0; i < result["applications"].length; ++i) {
var application = result["applications"][i];
console.log("App Settings: "+JSON.stringify(application["settings"]["end_user_apdex_threshold"]));
var appName = application["name"];
var appId = application["id"];
var browserApdexT = application["settings"]["end_user_apdex_threshold"];
var RUMEnabled = application["settings"]["enable_real_user_monitoring"];
console.log("RUM Enabled: "+RUMEnabled);
var QUERY ='SELECT percentile(duration,'+desiredPercentile+') FROM Transaction WHERE appId =' +application["id"]+' SINCE 1 DAY AGO'
console.log('QUERY is: '+QUERY);
getResponseTime(QUERY,appId, appName, browserApdexT, RUMEnabled);
}
}
});
function getResponseTime(QUERY, appId, appName,browserApdexT,RUMEnabled) {
request({
uri: `https://insights-api.newrelic.com/v1/accounts/${ACCOUNT_ID}/query?nrql=${QUERY}`,
json: true,
headers: {
'X-Query-Key': QUERY_KEY
}
}, (error, response, body) => {
if (error) {
isError = true
lastError = error.toString()
isRunning = false
return console.log(error)
}
if (response.statusCode !== 200) {
isError = true
lastError = JSON.stringify(body)
isRunning = false
return console.log(body, response.statusCode)
}
var result = JSON.stringify(body["results"]);
console.log('Result:'+result);
var duration = result.slice(result.lastIndexOf(":"),result.indexOf("}"));
duration = duration.replace( /^\D+/g, ''); // replace all leading non-digits with nothing
if(duration < 0.01){
//duration = 0.01;
}
console.log('Duration:'+duration);
setApdexT(duration,appId,appName,browserApdexT,RUMEnabled);
});
}
function setApdexT(duration,appId,appName,browserApdexT,RUMEnabled){
console.log("DURATION PASSED: "+duration);
var ApdexT = duration;
console.log("DURATION ROUNDED: "+ApdexT);
var EUApdexT = parseFloat(browserApdexT);
var data = JSON.stringify( {
application:
{ name: appName,
settings: {
"app_apdex_threshold": ApdexT,
"end_user_apdex_threshold": EUApdexT,
"enable_real_user_monitoring": RUMEnabled
}
}
});
console.log("+++***Settings Payload***+++: "+data);
var options = { method: 'PUT',
url: 'https://api.newrelic.com/v2/applications/'+appId+'.json',
headers:
{
'X-Api-Key': adminKey,
'Content-Type': 'application/json' },
body: data
};
request(options,
function(error, response, body) {
if (error) return onErr(error);
if (!error) {
var result = JSON.parse(body);
console.log("ERROR: "+response.statusCode+ " Message: "+response.body);
}
});
}
function onErr(err) {
console.log(err);
return 1;
}
Happy automating!
We’d love to hear your thoughts on automating New Relic’s API, and we encourage you to share what you’ve done with New Relic APIs on the New Relic Explorers Hub. And if you’re interested in learning more about our APIs, check out the New Relic Developers Hub at developer.newrelic.com.
The views expressed on this blog are those of the author and do not necessarily reflect the views of New Relic. Any solutions offered by the author are environment-specific and not part of the commercial solutions or support offered by New Relic. Please join us exclusively at the Explorers Hub (discuss.newrelic.com) for questions and support related to this blog post. This blog may contain links to content on third-party sites. By providing such links, New Relic does not adopt, guarantee, approve or endorse the information, views or products available on such sites.