Audit your services with Python and the NerdGraph API

Part 1 of 5: Automating common DevOps tasks in New Relic

Published 5 min read

As you instrument more apps and hosts with New Relic, there's a good chance you'll want to automate common tasks such as auditing your services and exporting telemetry data. Automation is an important part of DevOps and streamlining your workflows—and the good news is that there are many tasks you can automate with New Relic to make your observability practices more efficient.

These tasks can be performed via the prebuilt UI or can be automated through NerdGraph, our GraphQL API.

In this post, the first in a five-part series, you’ll how to use can use API calls in Python to automate auditing your instrumented services. In future parts of the series, you'll learn how to:

  • Manage your tags
  • Export telemetry for data analysis
  • Export dashboards as files
  • Rotate your license keys

While the sample API code uses Python, you can also make API calls from your preferred programming languages and tools.

What is NerdGraph?

NerdGraph is built using GraphQL, an open-source API format that allows you to request the exact data you need from New Relic’s various APIs and microservices without over-fetching or under-fetching. New Relic’s NerdGraph API is recommended for performing some specific actions such as querying selective data, or configuring additional features in New Relic.

Prerequisites

If you plan to follow along with this tutorial and use Python to make your API calls, you need:

The next video walks through the process of making an API call to the NerdGraph API with Python.

The sample app in this guide uses WordPress packaged by Bitnami deployed in AWS Singapore, instrumented with New Relic. You don’t need to use the sample application to follow along with this tutorial.

Using Python to make an API call

Here’s the Python starter code we’ll use to make an API call to NerdGraph with a simple GraphQL query. You can skip this section if you’re using another tool to make API calls to NerdGraph endpoints.

import requests
import json
from license import user_key

def nerdgraph_requests(key):
  # GraphQL query to NerdGraph
  query = """{ requestContext { userId } }"""

  # NerdGraph endpoint
  endpoint = "https://api.newrelic.com/graphql"
  headers = {'API-Key': f'{key}'}
  response = requests.post(endpoint, headers=headers, json={"query": query})
  
  if response.status_code == 200:
    # convert a JSON into an equivalent python dictionary
    json_dictionary = json.loads(response.content)
    print(json_dictionary)

    # optional - serialize object as a JSON formatted stream
    # json_response = json.dumps(response.json(), indent=2)
    # print(json_response) 
  else:
    # raise an exepction with a HTTP response code, if there is an error
    raise Exception(f'Nerdgraph query failed with a {response.status_code}.')

nerdgraph_requests(user_key)

First, you need to import the requests and json Python modules into the code. These modules allow you to make an API call.

import requests

import json

Next, import the external module license into your code. The license module is a separate file where the USER API key is stored.

from license import personal_key

From there, you can use a simple GraphQL query to validate that your query is successful. This example requests information about the userId parameter. Throughout this tutorial guide, you’ll build queries similar to this one to automate tasks.

query = """{ requestContext { userId } }"""

This is where you can customize your URL and authorization headers. This example uses f-strings to include your USER API key.

endpoint = "https://api.newrelic.com/graphql"

headers = {'API-Key': f'{key}'}

response = requests.post(endpoint, headers=headers, json={"query": query})

Next, you'll convert the JSON response from NerdGraph into a Dictionary using the json module. Optionally, you can use Pandas with Dataframes.

json_dictionary = json.loads(response.content)

Occasionally, it's beneficial to see your query response as a JSON-formatted stream. You can optionally decide if you want to include it in your output.

json_response = json.dumps(response.json(), indent=2)

Lastly, if there is an error, you want to raise an exception with an HTTP response code. 

raise Exception(f'Nerdgraph query failed with a {response.status_code}.')

You’ll see the following results if your query is successful:

{
  "data": {
    "requestContext": {
      "userId": "XXXXX"
    }
  }
}

Audit your instrumented services

Platform teams often need to perform an inventory audit and track their instrumented applications and hosts. While you can manually track instrumented services in the UI, that becomes much more challenging once you have hundreds or thousands of objects to track in a large environment. You can use a simple search with the NerdGraph API to list all entities in New Relic. 

Every object recorded in New Relic has a unique Globally Unique Identifier (GUID) that recognizes an entity. An entity provides a useful entry point to explore data about specific metrics and events and to contextualize data related to other entities.

The following video and code show you how you can use the NerdGraph API to audit your instrumented services.

import requests
import json
from license import user_key

def nerdgraph_inventory(key):
  # GraphQL query to NerdGraph
  query = """
  {
    actor {
      entitySearch(queryBuilder: {domain: APM}) {
        query
        results {
          entities {
            name
            guid
          }
        }
      }
    }
  }"""
  
  # NerdGraph endpoint 
  endpoint = "https://api.newrelic.com/graphql"
  headers = {'API-Key': f'{key}'}
  response = requests.post(endpoint, headers=headers, json={"query": query})

  if response.status_code == 200:
    # convert a JSON into an equivalent python dictionary
    # dict_response = json.loads(response.content)
    # print(dict_response['data']['actor']['entitySearch']['results']['entities'])

    # optional - serialize object as a JSON formatted stream    
    json_response = json.dumps(response.json(), indent=2)
    print(json_response)
  else:
    # raise an exepction with a HTTP response code, if there is an error
    raise Exception(f'Nerdgraph query failed with a {response.status_code}.')

nerdgraph_inventory(user_key)

If you're using another language or tool to make an API call, you can take the query in the previous code sample and apply it to your use case as needed.

To learn more, see the NerdGraph tutorial on viewing entity data.

And that's it. Stay tuned for the rest of the series, where you'll learn how to automate other common tasks in New Relic.