New Relic Reports is an engine for automating the generation of custom reports built using telemetry in the New Relic Telemetry Data Platform and the delivery of those reports via a variety of channels.
The New Relic Reports engine supports several different report types.
Template reports provide a mechanism for building custom reports using templates. Templates are text-based, user-defined documents that can contain both content and logic. Templates are processed when a template report is run to produce text-based output. Special bits of logic called extensions are provided that make it easy to use New Relic data in template reports. By default, the output is rendered in a browser to produce PDF output, but it is just as easy to disable rendering and deliver the template output in a variety of ways.
Dashboard reports use Nerdgraph to collect snapshot URLs from one or more user specified dashboard GUIDs. Snapshot URLs are downloaded as PDFs. When more than one dashboard is specified, the PDFs can optionally be concatenated into a single PDF.
Query reports provide a mechanism to export the results of running a NRQL query by simply specifying a query and one or more account IDs to run the query against. No additional configuration is required. By default, query results are exported to CSV but query results can also be formatted using a Nunjucks template.
A variety of mechanisms are supported for delivering report output. These mechanisms are referred to as channels. The following types of channels are supported.
- File: Report output is saved to a file and copied to a destination directory on the local filesystem. Mostly meant for development and testing purposes.
- Email: Report output is included inline or as attachments to an email using a user defined email template and sent via SMTP.
- S3: Report output is saved to a file and uploaded to an S3 bucket.
- Slack: Report output is posted to a Slack channel via a Slack webhook.
There are three ways to run reports.
-
Using the command line interface (CLI)
Ad-hoc reports can be run directly from a terminal after cloning or downloading the repository and installing dependencies. This is useful primarily for testing and debugging reports.
-
Packaged as a Docker image
Dockerfile
s are provided to package the reporting engine, along with your templates and manifest files as a docker image that runs reports on a schedule usingCRON
or that provides a CLI basedENTRYPOINT
that can be run via external scheduled task mechanisms such as AWS ECS Scheduled Tasks. -
Packaged as an AWS Lambda function
A Dockerfile is provided to package the reporting engine, along with your templates and manifest files as an AWS Lambda function. The Lambda can be deployed withthe provided CloudFormation template and the provided helper scripts.
To develop reports and run them locally, you will need the following.
- Node >= 14.0.0
- A terminal application that supports Bash scripts
- Your favorite IDE
- For the email channel, SMTP server settings (for testing locally try Mailhog)
- For the S3 channel, AWS credentials and an S3 bucket
- For the Slack channel, an Incoming Webhook URL.
To build and deploy CRON based images, you will need the following.
- Docker
- A Docker repository
To build and deploy Lambda based images, you will need the following.
- Docker
- An ECS repository
- The AWS CLI
- AWS credentials
git clone git@github.com:newrelic/nr-reports.git
cd nr-reports
npm install
Here's how to build a simple "Hello, world!" HTML template that displays a basic
throughput chart for an application named Shop Service
.
NOTE: For this simple tutorial, we will be generating reports interactively from the command line. While this is convenient for testing things out, one of the main features of New Relic Reports is the automation support for report generation and delivery.
If you haven't already, make sure you have checked the prerequisites and installed the repo. You will also need a New Relic User key.
Then open a terminal that supports Bash scripts and execute the following
commands, making sure to replace path/to/nr-reports
with the path to the
directory where you cloned the nr-reports
repository AND YOUR_USER_KEY
with your New Relic User key.
cd path/to/nr-reports
export NEW_RELIC_API_KEY="[YOUR USER KEY]"
Next, make a copy of the example hello-world.html
template in the include
directory.
cp ./examples/hello-world.html ./include/hello-world.html
Next, edit the new template and replace the string Shop Service
with an
appropriate APM service name and the account ID 1234567
with the account ID
for the service. Then save the template.
Don't worry for now what all the rest of the content in the file means. It looks more complicated than it is and will be explained in the usage section.
Now run the report using the following command.
./nr-reports-cli/bin/nr-reports.sh -n hello-world.html
That's it!
There should now be a PDF file in the current directory called
hello-world.pdf
. Open it up and it should look something like the image below.
The above template is nice, but it only works for one service because we
hard-coded the application name in the query and the account ID on the chart
tag. That isn't very "templatish". Let's see how to templatize the example
above.
First, load hello-world.html
back into an editor. Now replace the name
of your application with the string {{ appName }}
(curly braces and all) and
completely remove the accountId
parameter (and the ,
after
type="AREA"
). Also, change the type
from AREA
to LINE
just so we are
sure we are really running a new example.
The chart
tag should now look something like the following.
<div>
{% chart "FROM Transaction SELECT rate(count(*), 1 minute) as 'Requests Per Minute' where appName = '{{ appName }}' SINCE last week UNTIL this week TIMESERIES",
type="AREA"
%}{% endchart %}
</div>
Now we will create a values file. The values file is a JSON or YAML file with a flat structure that is a set of key/value pairs. It let's us separate out specific values from the template so that we can use the same template with different values without having to change the template.
Copy the example values file to a new file named hello-world.json
.
cp ./examples/values.json ./include/hello-world.json
Next, edit the new file and replace the string Shop Service
and the account
ID 1234567
with the values you removed from the template in the previous step.
Then save the file.
First, delete the previous report so we can be sure this run re-creates a new one.
rm ./hello-world.pdf
Now, run the report using the following command, noting the addition of the -v
option that is used to specify the path to the values file.
./nr-reports-cli/bin/nr-reports.sh -n hello-world.html -v include/hello-world.json
Now there should be a new PDF file in the current directory called
hello-world.pdf
. Open it up and it should look exactly the same as before.
That is because all we've done above is separate out the account ID and
application name so it isn't hardcoded in the template. We didn't actually
change the values.
So far we have been running template reports, i.e. reports based on a template file. New Relic Reports supports another report type called dashboard reports. Dashboard reports are much simpler. You specify a list of dashboard GUIDs and the reporting engine will use Nerdgraph to download a dashboard snapshot PDF for each dashboard and optionally combine multiple snapshots in a single PDF.
Here's how you run a dashboard report.
The easiest way to find the GUID for a dashboard is via the NR1 UI.
- Navigate to your dashboard
- Locate the dashboard name above the filter bar
- On one side of the dashboard name, locate the box that contains the account name and a "tag" icon followed by a number. Click anywhere in the box.
- In the "drawer" that slides out from the side of the screen, locate the label "Entity guid" followed by a long string of numbers and letters (this is the dashboard GUID).
- Hover over the string of numbers and letters and click on the clipboard icon that appears. The dashboard GUID will now be copied in the clipboard.
Now run the report using the following command, replacing the string
ABCDEF123456
with your dashboard GUID.
./nr-reports-cli/bin/nr-reports.sh -d ABCDEF123456
Now there should be a new PDF file in the current directory called
dashboard-[DASHBOARD_GUID].pdf
where [DASHBOARD_GUID]
is the GUID of your
dashboard. Open it up and it should look like a snapshot of dashboard for the
last 60 minutes.
Now let's see how to run another report type called a query report. Query
reports let you export the results of running a NRQL query without all the
complexity of creating a template, using the nrql
tag, and running the
report. Instead, you just specify an NRQL query and the reporting engine will
automatically run the query and, by default, write the results to a CSV file.
Let's see how that works by running a simple query report to show the average latency of all APM services in your account grouped by application name and URL using the following NRQL.
SELECT average(duration) as 'Duration' FROM Transaction FACET appName as 'Application Name', request.uri AS 'URL'
To do that, run the following command, replacing the string 1234567
with your
account ID.
./nr-reports-cli/bin/nr-reports.sh -a 1234567 -q "SELECT average(duration) as 'Duration' FROM Transaction FACET appName as 'Application Name', request.uri AS 'URL'"
Now there should be a new CSV file in the current directory called
query-report.csv
. Open it up in a text editor and you should see something
like the following.
Application Name,URL,Duration
Shop Service,/api/v1/checkout,1.5191369267857142
Shop Service,/api/v1/products,1.5092493357575756
Shop Service,/api/v1/products/1234,1.4948035056074764
Now let's see how we can run multiple reports at once using a manifest file. A manifest file is a JSON or YAML file containing an array of report definitions. We will use a manifest file to run the template report and dashboard report from above all at once.
First, delete the previous report so we can be sure this run re-creates a new one.
rm hello-world.pdf dashboard-[DASHBOARD_GUID].pdf query-report.csv
Make sure to replace [DASHBOARD_GUID]
with the GUID of your dashboard.
Copy the example manifest file to a new manifest file named manifest.json
.
cp ./examples/manifest.json ./include/manifest.json
Next, edit the new file and replace the string Shop Service
and the account
ID 1234567
and the string ABCDEF123456
with the values you used in the
previous steps. Then save the file.
Again, don't worry for now what all that means. It looks more complicated than it is and will be explained in the section manifest file.
Now run the report using the following command.
./nr-reports-cli/bin/nr-reports.sh
Now there should be both a hello-world.pdf
file in the current directory
and a PDF file called dashboard-[DASHBOARD_GUID].pdf
in the current
directory. Using the manifest file we were able to generate both reports at
once!
Notice that we did not specify any arguments to the command! That is because the
reporting engine will load the manifest file located at
include/manifest.json
by default.
Here's what we just did.
- Created a basic HTML template using the Nunjucks templating syntax that displays a header, a paragraph, and a New Relic timeseries chart for the given NRQL query.
- Modifed the template to use template parameters as placeholders for the values that we hardcoded in step 1 by creating a values file.
- Used the CLI script to run a report at the command line using the template and the values file from steps 1 and 2.
- Without knowing it, used the
file
channel to store the resulting PDF report in the current directory. - Used the CLI script to run a report at the command line using a dashboard entity GUID.
- Without knowing it, used the
file
channel to store the resulting PDF report in the current directory. - Used the CLI script to run a query report at the command line using a simple NRQL query.
- Without knowing it, used the
file
channel to store the query results as a CSV file in the current directory. - Created a manifest file with report definitions for the HTML template report and dashboard report from the previous steps.
- Used the CLI script to run a report at the command line using the default
manifest file located at
include/manifest.json
. - Without knowing it, used the
file
channel to store the resulting PDF reports in the current directory.
Though useful during template development, in most cases, you won't be generating reports by running the CLI directly. Instead, you will use one of the provided mechanisms for automating the generation and delivery of reports. See the usage section for more details.
Template reports are created from templates. Templates are stored in template files. Template files are text files that contain text mixed with template "instructions". Template "instructions" are written using a special syntax that is understood by the the Nunjucks template "engine". Reports are produced from a template file by passing the content of the file through the template engine. The template engine evaluates the "instructions" to transform the original content into the raw report output. By default, the raw output is rendered using a headless Chrome instance and saved as a PDF. But you can also tell the New Relic Reports engine not to do so. You might do this if you are producing a CSV file or you want to deliver raw HTML instead of rendered HTML.
The following JSON shows an example of a template report definition in a manifest file. You might recognize this from the section Update the example manifest file in the Getting Started tutorial.
{
"name": "hello-world",
"templateName": "hello-world.html",
"parameters": {
"accountId": 1234567,
"appName": "Shop Service"
},
"channels": []
}
When the reporting engine runs this report, it will invoke the templating
engine with the template name hello-world.html
and the parameters accountId
set to 1234567
and appName
set to Shop Service
. The template output will
be rendered to a PDF file named hello-world.pdf
using a headless Chrome
instance and this file will be copied to the current working directory since the
default channel is the file
channel and no destDir
channel parameter is set.
See the section Template Report Properties for more information on the available dashboard report properties.
Nunjucks does not sandbox execution so it is not safe to run untrusted templates or inject user-defined content into template definitions. Doing so can expose attack vectors for accessing sensitive data and remote code execution.
See this issue for more information.
Here is a very basic template.
{% for fruit in ['banana', 'orange'] -%}
I want a {{ fruit }}.
{% endfor -%}
This template contains three instructions.
- The text in between the first
{%
and%}
pair is an example of a tag. In particular, this is the opening of the for tag. - The text
{{ fruit }}
is an example of a variable lookup. - The text in between the second
{%
and%}
pair signals the closing of thefor
tag.
The for
tag defines a loop. Any content (including other instructions) in
between the text for
and the text endfor
will be evaluated for each item
of the loop. In this case, the loop will be executed twice. Once for each value
of the list specified by the expression ['banana', 'orange']
. Because the
string I want a {{ fruit }}.
is placed in between the opening and closing of
the for
tag, the following output will be produced when this template is
passed through the Nunjucks template engine.
I want a banana.
I want a orange.
Notice that the final output does not include any Nunjucks "instructions". All instructions have been replaced with the content produced as a result of evaluating each instruction.
See the section Templating of the Nunjucks documentation for detailed information on how to build templates.
Template reports are built out of text. The template engine does not care about the semantics of the text that it processes. In other words, the template engine does not care if the text represents CSV data or HTML data. Just that it is text.
There is one special case which applies to the default behavior of the reporting
engine. In this case, the output of the template engine will be loaded into a
headless Chrome instance and the rendered page will be saved as a PDF file.
While just about any text-based document can be rendered by Chrome in one way or
another, the reporting engine applies special handling if, and only if, the
isMarkdown
flag is present and set to true
in
the report definition or if the template name has a .md
extension.
In either of these conditions are met, the reporting engine assumes that the
template contains GitHub Flavored Markdown.
This will result in two passes through the template engine. The first pass is
the standard pass the templating engine makes over any template. The additional
second pass renders the report.md.html
template and inserts the output from the first pass into the content
section
after converting the output to HTML using
the showdown Markdown converter.
Following is an example of an HTML template. You might recognize this from the section Update the example template in the Getting Started tutorial.
{% extends "base/report.html" %}
{% block content %}
<h1>My Application Throughput</h1>
<p>
This is our application throughput for last week.
</p>
<div>
{% chart "FROM Transaction SELECT rate(count(*), 1 minute) as 'Requests Per Minute' where appName = 'Shop Service' SINCE last week UNTIL this week TIMESERIES",
type="AREA",
accountId=1234567
%}{% endchart %}
</div>
{% endblock %}
Following is an example of a Markdown template that will produce something very similar to the example HTML template above.
# My Application Throughput
This is our application throughput for last week.
{% chart "FROM Transaction SELECT rate(count(*), 1 minute) as 'Requests Per Minute' where appName = 'Shop Service' SINCE last week UNTIL this week TIMESERIES",
type="AREA",
accountId=1234567
%}{% endchart %}
As mentioned, template reports can be built from any text-based content and
produce any text-based output. A report could produce CSV, XML, or JSON output.
For example, following is a template that produces a CSV file from the result of
running a NRQL query using the nrql
tag.
App Name,Duration
{%- nrql "SELECT average(duration) AS 'duration' FROM Transaction FACET appName",
accountId=1234567
-%}
{%- for item in result %}
{{ item.facet[0] }},{{ item.duration }}
{%- endfor -%}
{%- endnrql -%}
In the above case, the output from the template engine is probably not meant to
be rendered in a browser. The render
report parameter is provided to allow you
to inform the reporting engine to skip the rendering step. In some cases, this
may even be desirable for HTML-based templates. For example, if the output is
meant to be included inline in an email or sent as a Slack message.
When processing a template, the template engine uses
the Nunjucks FileSystemLoader
to load template files from the local filesystem. The FileSystemLoader
resolves the template name passed to the engine into the template file very
much like a shell resolves executables using the PATH
environment variable.
That is, given a template name and a template "path", the FileSystemLoader
resolves the template name to a template file to load by searching each
directory on the template path for the a file matching the template name. For
example, consider the following directory structure.
/app/my-reports
|- templates
|- hello-world.html
Given the template name hello-world.html
and the template path
/app/my-reports/templates
, the FileSystemLoader
would load the template
from the file /app/my-reports/templates/hello-world.html
. However, if the
template path were /app/my-reports
, the FileSystemLoader
would fail to
find a matching template and the engine would throw an exception.
The template name may include segments separated by the system path separator,
in which case, the FileSystemLoader
will treat the template name like a
relative path and match it against each directory in the path. For example,
specifying the template name templates/hello-world.html
would make the failing
case above work fine.
The default template path will always include the current working directory and
the directories include
and templates
relative to the current working
directory. In addition, the TEMPLATE_PATH
environment variable may be set to
a list of additional directories separated by the system path separator. These
directories will also be added to the template path. Finally, the templatePath
engine option, may also be used to specify additional
directories separated by the system path separator.
When building any of the docker images, all templates (and all other files)
in the include
directory are copied into the include
directory
of the image (/app/nr-reports-cli/include
). Note that files in the include
directory are git
ignored. To include files in this directory in git
, either
remove the line include/*
from the gitignore
file or add
negation patterns for the files to be committed.
New Relic Reports provides several custom tags that make it easy to integrate New Relic charts and data in your reports.
The chart
tag is used to include a New Relic chart
in a report. It should only be used with HTML or markdown based templates that
will be rendered in Chrome to produce a PDF. For an HTML based template, the
chart
tag will inject an HTML <img />
tag into the generated output. For a
markdown based template, the chart
tag will inject
the markdown to create an image
into the generated output.
For example, recall the snippet from the example template in the Getting Started tutorial.
{% chart "FROM Transaction SELECT rate(count(*), 1 minute) as 'Requests Per Minute' where appName = 'Shop Service' SINCE last week UNTIL this week TIMESERIES",
type="AREA",
accountId=1234567
%}{% endchart %}
When the template engine evaluates this tag, it will invoke the chart
extension. The chart
extension retrieves a static chart URL for the given account ID, NRQL, and chart
options using the following GraphQL query.
{
actor {
account(id: $accountId) {
nrql(query: $query, timeout: $timeout) {
staticChartUrl(chartType: $chartType, format: $chartFormat, width: $chartWidth, height: $chartHeigh)
}
}
}
}
The chart
extension takes the returned URL and injects the appropriate markup
to display the chart image in the report.
Unless the template contains markdown, the chart
tag is replaced with an
HTML img
tag with the src
value set to the static chart URL, like the one
below.
<img src="STATIC_CHART_URL" ... />
For markdown, the chart
tag is replaced with the markdown to show an image,
like below.
![](STATIC_CHART_URL)
The chart
tag supports the following options.
Option Name | Description | Type | Required | Default |
---|---|---|---|---|
accountId | An account ID to run the query with | Y | ||
query or first argument | The NRQL query to run | string | Y | |
type | The chart type. A valid value for the chartType argument of the staticChartUrl field of the NrdbResultContainer GraphQL type, e.g. AREA , LINE , etc. |
string | N | LINE |
format | The chart format. A valid value for the format argument of the staticChartUrl field of the NrdbResultContainer GraphQL type, e.g. PNG or PDF . |
string | N | PNG |
width | The width of the image | number | N | 640 |
height | The height of the image | number | N | 480 |
class | CSS class name(s) to add to the HTML img tag. Unused for markdown templates. |
string | N | '' |
NOTE: The NRQL query can either be specified as the first argument after the
opening of the chart
tag as shown in the example above or using the query
keyword argument as shown below.
{% chart
accountId=1234567,
query="FROM Transaction SELECT rate(count(*), 1 minute) as 'Requests Per Minute' where appName = 'Shop Service' SINCE last week UNTIL this week TIMESERIES",
type="AREA"
%}{% endchart %}
The nrql
tag is used to run a NRQL query. The results of the query are stored
in a template variable for further processing by your templates. We saw
an example of this in the Template Content section section.
It is repeated below for convenience.
App Name,Duration
{%- nrql "SELECT average(duration) AS 'duration' FROM Transaction FACET appName",
accountId=1234567
-%}
{%- for item in result %}
{{ item.facet[0] }},{{ item.duration }}
{%- endfor -%}
{%- endnrql -%}
When the template engine evaluates the nrql
tag, it will invoke the nrql
extension. The nrql
extension runs the given NRQL query using the given account ID(s) using the
following GraphQL query.
{
actor {
nrql(accounts: $accountIds, query: $query, timeout: $timeout) {
results
metadata {
facets
eventTypes
}
}
}
}
The extension stores an object containing the results
and metadata
fields
into the variable with the name specified by the var
option on the nrql
tag or into a variable named result
. The results
field is an array of
objects whose structure matches the query submitted. The facets
field is an
array containing the names of the facets in the query submitted and the
eventTypes
field is an array of the names of the event types in the query
submitted. Following is an example JSON object that would be returned as the
result of running the query
SELECT average(cpuPercent) FROM SystemSample FACET hostname
.
{
"metadata": {
"eventTypes": [
"SystemSample"
],
"facets": [
"hostname"
]
},
"results": [
{
"facet": "my.local.test",
"average.cpuPercent": 1.5432042784889708,
"hostname": "my.local.test"
}
]
}
For more information on the structure of these fields, see the type definition
for the CrossResultsNrdbResultContainer
type at https://api.newrelic.com/graphiql
.
The nrql
tag supports the following options.
Option Name | Description | Type | Required | Default |
---|---|---|---|---|
accountId | Account ID to run the query with. Multiple account IDs an be specified separated by commas. One of the this option or the accountIds option must be specified. |
Y | ||
accountIds | A list of account IDs to run the query with. A maximum of 5 account IDs is allowed. One of the this option or the accountId option must be specified. |
array | Y | |
query or first argument | The NRQL query to run. This option supports template parameter interpolation. That is, the query string is interpolated using the template engine prior to being run. | string | Y | |
var | The name of the variable to hold the query result | string | N | result |
NOTE: The NRQL query can either be specified as the first argument after the
opening of the chart
tag as shown in the example above or using the query
keyword argument as shown below.
{% nrql
accountId=1234567,
query="FROM Transaction SELECT rate(count(*), 1 minute) as 'Requests Per Minute' where appName = 'Shop Service' SINCE last week UNTIL this week TIMESERIES",
%}
<h2>{{ result.facet[0] }}<h2>
{% endnrql %}
Template parameters are key-value pairs that are passed to the template engine when processing a template. Template parameters are used to customize the processing of a template file and in turn, customize the output from the template engine.
During processing, a template "variable" is created for each template parameter using the key of the parameter as the variable name and the value of the parameter as the value of the variable. Within a template file, template parameters are referenced by key, just like any other template variable. Here is a simple example of a template file that references two template variables: one that is set directly in the template and another that is populated from a template parameter. Note how the same syntax is used to reference both.
{% set my_name = "Taylor" -%}
{# Output the my_name variable set from this template -#}
Hello, my name is {{ my_name }}.
{#- Output the your_name variable set from a template parameter #}
Nice to meet you, {{ your_name }}.
When the above template is processed by the template engine without any template parameters, it will produce the following output.
Hello, my name is Taylor.
Nice to meet you, .
Since no template parameters were specified, no variable existed with the
key your_name
and so there was no one to meet. However, if the above
template is processed with the template parameter your_name
set to Jan
,
it will produce the following output.
Hello, my name is Taylor.
Nice to meet you, Jan.
To output nothing when no your_name
parameter is passed, the template can
be modified as follows.
{% set my_name = "Taylor" -%}
{# Output the my_name variable set from this template -#}
Hello, my name is {{ my_name }}.
{#- Output the your_name variable set from a template parameter #}
{% if your_name -%}
Nice to meet you, {{ your_name }}.
{%- endif %}
Template parameters are specified as a JSON or YAML object. For example, the following JSON specifies 3 template parameters: 1 string, 1 number, and 1 array of strings.
{
"accountId": 123456,
"title": "New Relic Weekly Report",
"appNames": [ "app1", "app2" ],
}
When processing a template, the reporting engine makes all properties in the report execution context available as template parameters.
Dashboard reports provide a way to easily capture PDFs of one or more dashboards. When more than one dashboard GUIDs is specified, each dashboard is captured as a separate PDF file. These files can optionally be combined into a single file.
The following JSON shows an example of a dashboard report definition in a manifest file. You might recognize this from the section Update the example manifest file in the Getting Started tutorial.
{
"name": "performance-summary-dashboard",
"dashboards": [
"ABCDEF123456"
],
"channels": []
}
When the reporting engine runs this report, it will execute the
dashboardCreateSnapshotUrl
GraphQL mutation with the GUID ABCDEF123456
in
order to create a URL to download a PDF snapshot of the dashboard with the given
GUID. It will then download the PDF to a file named dashboard-ABCDEF123456.pdf
since no outputFileName
is specified. The PDF file will be copied to the
current working directory since the default channel is the
file
channel and no destDir
channel parameter is set.
See the section Dashboard Report Properties for more information on the available dashboard report properties.
Query reports provide a simple way to run a NRQL query and export the results of the query to a file. By default, the results are exported to a CSV file.
The following JSON shows an example of a query report definition in a manifest file that will run the example query from the section Run a query report in the Getting Started tutorial.
{
"name": "transactions"
"accountIds":
- 1234567
"query": "SELECT average(duration) as 'Duration' FROM Transaction FACET appName as 'Application Name', request.uri AS 'URL'"
"timeout": 10
"channels": []
}
When the reporting engine runs this report, it will execute the following
GraphQL query using the given NRQL query for the $query
argument, the given
account ID (in a 1 member array) for the $accountIds
argument, and the given
timeout for the $timeout
argument.
{
actor {
nrql(accounts: $accountIds, query: $query, timeout: $timeout) {
results
metadata {
facets
eventTypes
}
}
}
}
The results will be tabulated into a CSV file where the rows in the CSV file
correspond to the each item in the returned results
array and the columns in
the CSV file correspond to the facets in the query (in this case
Application Name
and URL
) followed by the fields selected by the query
(in this case Duration
), just like you'd see in a TABLE
widget on a
dashboard. Following is an example CSV that might be generated from this query.
Application Name,URL,Duration
Shop Service,/api/v1/checkout,1.5191369267857142
Shop Service,/api/v1/products,1.5092493357575756
Shop Service,/api/v1/products/1234,1.4948035056074764
Multiple account IDs can be specified for a query report. The reporting engine
supports three different modes for executing queries against multiple accounts.
The query mode is specified using the multiAccountMode
option in a query
report definition in the manifest. Specifying the
multi-account mode at the CLI is not supported and therefore will always use
the default multi-account mode cross-account
.
By default, a multi-account query will be run using a cross-account query. With cross-account queries, a query is run against each of the accounts (up to a maximum of 5) using a query like the following.
{
actor {
nrql(
accounts: [ACCOUNT_ID_1, ACCOUNT_ID_2, ACCOUNT_ID_3]
options: {}
query: "NRQL_QUERY"
timeout: 70
) {
results
}
}
}
The results are aggregated and returned as a single set of results.
To specify that the reporting engine should run a multi-account query using a
cross-account query, either set the multiAccountMode
option in the manifest
to cross-account
or leave it out entirely, as cross-account
is the default.
Sometimes you really want to run a query individually against multiple accounts
and get each set of results individually rather than aggregating the set of
results across all account. For example, if you want to find the top 5
transactions of each of 5 different accounts and export them to a CSV file with
each row including the account ID, using a cross-account query won't suffice. To
account for this, the reporting engine provides two multi-account modes that
execute queries separately against each account: per-account
and
per-account-concurrent
.
In the per-account
case, a single GraphQL query is run that utilizes
GraphQL aliases to run multiple
GraphQL queries in a single GraphQL call, as in the following example.
{
NrqlQuery1: {
actor {
nrql(
accounts: [ACCOUNT_ID_1, ACCOUNT_ID_2, ACCOUNT_ID_3]
options: {}
query: "NRQL_QUERY_1"
timeout: 70
) {
results
}
}
}
NrqlQuery2: {
actor {
nrql(
accounts: [ACCOUNT_ID_1, ACCOUNT_ID_2, ACCOUNT_ID_3]
options: {}
query: "NRQL_QUERY_2"
timeout: 70
) {
results
}
}
}
}
In the per-account-concurrent
case, multiple GraphQL queries are run
concurrently, one query per account.
NOTE:
The per-account
and per-account-concurrent
modes are not "native" query
types like cross-account
. Rather, they are implemented in the reporting
engine.
The reporting engine creates an "execution context" each time it runs a report. The execution context is a collection of properties that can be used by the components that generate the report. When the execution context is created, the reporting engine populates it as follows.
- If a manifest file is specified:
- Add all properties from the
variables
section at the top-level - Add properties from the
report
definition - If the report is a template report:
- Add all properties from the
parameters
property from the report definition - If the report is being run from a Lambda
function:
- If a
body
property is present in theevent
object passed to the handler function, add all properties from thebody
property - If a
body
property is not present in theevent
object passed to the handler function, add all properties from theevent
object
- If a
- Add all properties from the
- Add all properties from the
- If no manifest file is specified:
- Add report name and the
outputFileName
if one is specified - If the report is a template report:
- Add the template name
- If a values file is specified, add all properties from the top-level object
- If the report is being run from a Lambda
function:
- If a
body
property is present in theevent
object passed to the handler function, add all properties from thebody
property - If a
body
property is not present in theevent
object passed to the handler function, add all properties from theevent
object
- If a
- If the report is a dashboard report, add an array
property named
dashboards
containing all dashboard GUIDs - If the report is a query report, add the query and the
account ID
property named
dashboards
containing all dashboard GUIDs
- Add report name and the
NOTE: When populating the context, if two properties with the same name are added by different steps, the later property will overwrite the earlier property.
Every report produces output. The output can either be a text buffer stored in local memory or a file stored in the temporary work directory created when the reporting engine starts.
The type of output depends on the type of report.
Report Type | Output Type |
---|---|
Template Report (default / render == true ) |
File |
Template Report (render == false ) |
Text |
Dashboard Report | File |
Query Report | Text |
Note that the type of output generated for a given report type is not always the same as the format used to send the output via a particular channel. For example, the default output of a query report is a string of text that contains CSV data. But this data can be sent via the email channel as the body of the email or in a file attached to the email.
After a report has been run, the generated outputs are distributed via channels. A channel provides an implementation that sends report outputs to one or more destinations. The following channels are supported:
- File (the default when running from the CLI)
- S3 (the default when running from a Lambda)
- Slack
All channels support configuration parameters that are used by the channel
implementation to distribute reports via that channel. For example, the file
channel supports a destDir
configuration parameter that specifies the
destination directory that the report outputs should be copied into. The email
channel supports configuration parameters that specify the SMTP information to
be used to connect to the SMTP server.
Channel configuration parameters can be specified via a manifest file, via environment variables, or using a combination of both. The recommended way is to use a manifest file as it makes it very clear what values will be used and it allows for multiple channels of the same type to use different values. Additionally, all channel configuration parameters specified via a manifest file are automatically added to the report execution context.
For more details on the supported channel configuration parameters see the specific sections below.
Some channel parameters support template parameter
interpolation. That is, the value of the channel parameter is interpolated
using the template engine prior to being used by the channel implementation.
The interpolated string may reference any channel configuration parameter as
well as any report parameter. For example, the "Subject" property of the
email channel is interpolated prior to passing it to the
Nodemailer transport. Consequently, the from
channel parameter could be included in the "Subject" property by setting the
subject
channel parameter to Report generated for {{ from }}
. If the value
of the from
channel parameter was alice@newrelic.com
, the resulting subject
would be Report generated for alice@newrelic.com
.
When the reporting engine is run using a manifest file, the channels to use for a given report are part of the channel definition for the report as specified in the manifest file.
If the reporting engine is run without a manifest file, the
reporting engine will use the value of the CHANNEL_IDS
environment variable.
If a non-empty value is specified, it is interpreted as a comma-separated list
of channel IDs. For example, the value s3,email
specifies that the report
output(s) should be published to the S3 and
Email channels.
If no value is specified for the CHANNEL_IDS
environment variable and the
reporting engine was run from the CLI, the value of the -c
option will be used. It will be interpreted in the same way as the value of the
CHANNEL_IDS
environment variable.
If no channel is specified using any of the above mechanisms, report output(s) will be published to the file channel when running from the CLI or the s3 channel when running from a Lambda
As an example, the CLI command used in the Run the template report section could have explicitly specified the file channel as follows.
./nr-reports-cli/bin/nr-reports.sh -n hello-world.html -c file
This is not necessary since the file channel is the default. However, to use the email channel instead, it would be specified as follows.
./nr-reports-cli/bin/nr-reports.sh -n hello-world.html -c email
NOTE:
Channel parameters can not be specified when using the
CHANNEL_IDS
environment variable or the -c
CLI option, or when using the
default file
channel. In these cases, the respective channel implementation
will attempt to locate the configuration parameters it needs in the environment
(where supported) and will default any optional parameters.
For report types that produce file output, file names are calculated as follows.
- For template reports where the
render
parameter is not set or is set totrue
, the rendered page will be saved to a file named<REPORTNAME>.pdf
. If a manifest file is used to run the report,<REPORTNAME>
will be the value of thename
attribute of the report definition. Otherwise,<REPORTNAME>
will be the same as the name of the template minus any extension, i.e. if the template name ishello-world.html
,<REPORTNAME>
will behello-world.
. - For dashboard reports where the
combinePdfs
is not set or set tofalse
, the snapshot for each dashboard GUID specified in the report definition will be saved to a file nameddashboard-<GUID>.pdf
. - For dashboard reports where the
combinePdfs
is set totrue
, the snapshots for all dashboards will be saved in a file calledconsolidated_dashboards.pdf
.
For report types that produce text output, most of the channel implementations support the option to save the output to a file and to use the file in place of or in conjuction with the assets published by the channel. For example, in addition to being able to copy file(s) from report types that produce file(s), the file channel supports the ability to save text data to a file from report types that produce text.
In such cases, the name of the file to which the text data is written is determined as follows.
- If a property named
outputFileName
exists in the report execution context, it will be used as the file name. - Otherwise, the file name will be set to
<REPORTNAME>.<EXT>
, calculated as follows:- If a manifest file is used to run the
report,
<REPORTNAME>
will be the value of thename
attribute of the report definition. Otherwise, for template reports<REPORTNAME>
will be the same as the name of the template minus any extension. For query reports,<REPORTNAME>
will bequery-report
. <EXT>
will be set to the value of the property namedfileExtension
in the report execution context. If no such property exists, it will be set to the value of theFILE_EXTENSION
environment variable. If no value is specified for theFILE_EXTENSION
environment variable, the extensiontxt
will be used.
- If a manifest file is used to run the
report,
The file
channel writes generated report outputs to a destination directory on
the local filesystem. It is mostly meant for development and testing although it
could be used to copy reports to volumes locally attached to a docker container.
For report types that produce file output, all generated files are moved from the temporary work directory created when the reporting engine starts into the destination directory.
For report types that produce text, the text will be written to a file. The file name will be calculated as specified in the section Output File Name. If the calculated file name is absolute, the file will be written at the specified location. Otherwise, the file will be written to the destination directory.
The destination directory to use will be determined as follows, listed in order of decreasing precedence.
- The
destDir
property in the report execution context - The
FILE_DEST_DIR
environment variable - The current working directory
Here is an example of specifying a file channel configuration in a manifest file.
[
{
"template": "template.html",
...
"channels": [
{
"type": "file",
"destDir": "/tmp"
}
]
}
]
The file
channel is the default channel when running from the CLI.
The email
channel delivers report outputs via email.
Messages are constructed based on output type and channel configuration parameters using the following process.
- A new message is created using the Recipient(s), Sender, and Subject values specified in the channel configuration or the corresponding environment variables. Prior to being set, the Subject is also run through the template engine using the current report execution context.
- If the report type produces file output:
- All generated files are added to the message as attachments.
- The body of the message is generated by processing a template with the
template engine using the current report execution context.
The template used to generate the message body may either be specified
inline in the
emailTemplate
parameter in the channel configuration or via a template file using theemailTemplateName
parameter in the channel configuration or theEMAIL_TEMPLATE
environment variable. If no template was specified, the default attachments template is used.
- If the report type produces text:
- If the
attachOutput
channel configuration parameter is set totrue
, the text will be written to a file. The file name will be calculated as specified in the section Output File Name. The file name must NOT be absolute. Message construction will continue as if the report type produces file output with the generated file as the output. - If the
passThrough
parameter in the channel configuration is set totrue
, the body of the message is set to the raw text output. - Otherwise, the body of the message is generated using the same method specified above, except that the default message template will be used if not template was specified.
- If the
- The content type for the message is set using the
format
parameter in the channel configuration. If no format was specified, the content type is set tohtml
by default. If theformat
parameter is set but is anything other thanhtml
ortext
, an error is raised.
The following configuration parameters are supported for the email channel. These options can be specified both via channel configuration in a manifest file and as environment variables.
Name | Environment Variable | Description | Required | Default |
---|---|---|---|---|
to |
EMAIL_TO |
Recipient emails; Multiple email addresses can be specified separated by commas. | Y | |
cc |
EMAIL_CC |
CC recipient emails; Multiple email addresses can be specified separated by commas. | N | |
from |
EMAIL_FROM |
Sender email | Y | |
subject |
EMAIL_SUBJECT |
Subject line | N | '' |
emailTemplate |
Inline email template for generating body | N | ||
emailTemplateName |
EMAIL_TEMPLATE |
Template name for generating body; Resolved against the template path at run time. | N | '' |
Messages are sent using the Nodemailer module. SMTP is the only protocol currently supported. The SMTP server configuration can be set only via environment variables for security purposes. The following parameters are supported.
Environment Variable | Description | Required | Default |
---|---|---|---|
EMAIL_SMTP_SERVER |
SMTP server hostname | Y | |
EMAIL_SMTP_PORT |
SMTP server port | N | 587 |
EMAIL_SMTP_SECURE |
SMTP TLS option; true /yes /on /1 forces TLS, anything else defaults to no TLS unless the server upgrades with STARTTLS |
N | true |
EMAIL_SMTP_USER |
Username for SMTP authentication | N | |
EMAIL_SMTP_PASS |
Password for SMTP authentication; only used if EMAIL_SMTP_USER is also specified |
N |
Here is an example of specifying an email channel configuration in a manifest file.
reports:
- name: chart
templateName: hello-world.html
parameters:
accountId: 1234567
appName: Shop Service
channels:
- type: email
from: "me@nowhere.local"
to: "you@nowhere.local"
cc: "them@nowhere.local,them-too@nowhere.local"
subject: "{{ title }}"
emailTemplateName: "email-template.html"
Here is an example of specifying an email channel configuration in a manifest file that specifies the email template inline.
reports:
- name: chart
templateName: hello-world.html
parameters:
accountId: 1234567
appName: Shop Service
channels:
- type: email
from: "me@nowhere.local"
to: "you@nowhere.local"
cc: "them@nowhere.local,them-too@nowhere.local"
subject: "{{ title }}"
format: text
emailTemplate: |
{{ title }}
Please find the attached report which shows average transaction duration
by application.
Because why not? Everyone needs more email.
The s3
channel uploads generated report outputs to an S3 bucket.
For report types that produce file output, all generated files are uploaded from the temporary work directory created when the reporting engine starts into the S3 bucket.
For report types that produce text, the text will be uploaded to the S3 bucket. The key for the object will be calculated as specified in the section Output File Name. The calculated file name must be a valid key name.
The destination bucket to use will be determined as follows, listed in order of decreasing precedence.
- The
bucket
property in the report execution context - The value of the
S3_DEST_BUCKET
environment variable - If the report is being run from a Lambda
function:
- The
sourceBucket
property of the engine options - The value of the
S3_SOURCE_BUCKET
environment variable
- The
- If the report is being run from the CLI:
- The value of the
S3_SOURCE_BUCKET
environment variable
- The value of the
Here is an example of specifying an s3 channel configuration in a manifest file.
[
{
"template": "template.html",
...
"channels": [
{
"type": "s3",
"bucket": "my-bucket"
}
]
}
]
The s3
channel is the default channel when running from a Lambda.
The slack
channel posts report output to a Slack channel via a
Slack webhook. A Slack webhook URL
must be specified using the SLACK_WEBHOOK_URL
environment variable.
Because Slack webhooks do not support transferring files, the slack
channel
only supports report types that produce text. Specifying a slack
channel for a
report type that produces file output will cause a warning message to be logged.
Messages are constructed based using the following process.
- If the
passThrough
parameter in the channel configuration is set totrue
, the body of the message is set to the raw text output. In this case, the text output must be a JSON string that conforms to the Incoming Webhook JSON payload format. This method can be used to send messages containing BlockKit visual components. - Otherwise, the body of the message is set to a JSON object with a single
property named
text
with the text output as it's value. The text output is automatically escaped so that it may safely include all mrkdwn formatting options.
The recommended way to specify reports to run when invoking the engine is via a manifest file. A manifest file is a JSON or YAML file with the one of the following formats.
A standard manifest file contains a single top-level object with the following properties.
Property Name | Description | Type | Required | Default |
---|---|---|---|---|
config | A map of well defined configuration properties with specific meaning to the reporting engine. | object | N | {} |
variables | A map of "global" properties that are added to the execution context of all reports. | object | N | {} |
reports | An array of report definitions. | array | N | [] |
A YAML example is shown below.
config:
email:
from: me@nowhere.local
variables:
accountId: 9999999
accountName: NEWRELIC_ACCOUNT_NAME
appName: NEWRELIC_APPLICATION_NAME
reports:
- name: golden-signals
templateName: golden-signals.html
parameters:
title: New Relic Golden Signals Weekly Report
author: Alice Reli
authorTitle: SRE
channels:
- type: email
to: you@nowhere.local
subject: "{{ title }}"
The config
map contains a set of properties that can be used to configure
certain aspects of the reporting engine. The following properties are
recognized. All other properties are ignored.
Property Name | Description | Type | Required | Default |
---|---|---|---|---|
Default email channel configuration properties. Excludes those that can only be set via environment variables. | object | N | {} | |
file | Default email channel configuration properties. Excludes those that can only be set via environment variables. | object | N | {} |
s3 | An array of report definitions. Excludes those that can only be set via environment variables. | array | N | [] |
The variable
map can contain any properties. These properties are added to the
execution context of all reports. This means they are available during the
processing of any templates, including the processing of email
templates.
A simplified manifest file simply contains an array of report definitions. It is
the equivalent of the value of the reports
property in a
standard manifest file.
A report definition is an object with a set of common properties and one or more additional properties that are particular to the report type. The following sections show the supported common properties and the properties supported by each report type.
An example manifest file is provided in the
examples
directory that shows how to define both a template report and a
dashboard report.
The following properties are common to all report types.
Property Name | Description | Type | Required | Default |
---|---|---|---|---|
name | The report name/identifier | string | Y | |
channels | The list of channel configurations to use to distribute report outputs. See the individual sections above for supported configuration values for each channel. | object | N | [ { "type": "file" }] |
Property Name | Description | Type | Required | Default |
---|---|---|---|---|
templateName | The template name. Must be available on the template path | string | Y | |
parameters | The template parameters to use for this report | object | N | {} |
isMarkdown | true if the template is written in Markdown, false if the template is any other content type, or omit for "auto" detection by file extension of the template name |
boolean | N | undefined (auto detect) |
render | true if the report output should be rendered using headless chrome, otherwise false |
boolean | true |
Property Name | Description | Type | Required | Default |
---|---|---|---|---|
dashboards | An array of dashboard entity GUIDs | array | Y | |
combinePdfs | true to combine all PDFs whan more than one dashboard is specified or false to use separate PDFs. |
boolean | N | undefined |
Property Name | Description | Type | Required | Default |
---|---|---|---|---|
accountId | An account ID to run the query with. One of the this property or the accountIds property must be specified. |
number | Y | |
accountIds | A list of account IDs to run the query with. A maximum of 5 account IDs is allowed if multiAccountMode is set to cross-account . One of the this property or the accountId property must be specified. |
array | Y | |
query | The NRQL query to run. | string | Y | |
multiAccountMode | The method used to query multiple accounts when multiple account IDs are specified. Valid values are cross-account , per-account , and per-account-concurrent |
string | N | cross-account |
A values file is a JSON or YAML file containing template parameters to use when processing a template report. Values files are only used when a manifest file is not specified. If both a values file and manifest file are specified, the values file is ignored.
The reporting engine supports several options which control various aspects of
it's behavior. When running from the CLI, these options can be
specified using the CLI options. When running
from a Lambda, these options can
be specified in the options
object in the event
object (or event.body
object) passed to the handler function. In both cases, these options can also
be specified via environment variables. Options specified via CLI options or the
event payload take precedence over environment variables.
The following options are supported. For more information on the CLI options, see the section Using the CLI. For more information on the Lambda options, see the section Using the AWS Lambda Function.
Option | Description | CLI Option | Lambda Option | Environment Variable |
---|---|---|---|---|
Log Level | Engine log verbosity | -v / -d |
logLevel |
LOG_LEVEL |
Manifest file | Path to a manifest file | -f |
manifestFilePath |
MANIFEST_FILE |
Report names | List of report names to run | -r |
reportNames |
REPORT_NAMES |
Template name | A template name | -n |
templateName |
TEMPLATE_NAME |
Values file | Path to a manifest file | -v |
valuesFilePath |
VALUES_FILE |
Template path | Additional paths to search during template resolution | -p |
templatePath |
TEMPLATE_PATH |
Dashboard IDs | List of dashboard entity GUIDs | -d |
dashboardIds |
DASHBOARD_IDS |
NRQL Query | An NRQL query | -q |
nrqlQuery |
NRQL_QUERY |
Account ID | The account ID to use with a query report. Multiple account IDs can be specified separated by commas (see note below). | -a |
accountId |
NEW_RELIC_ACCOUNT_ID |
Channel IDs | List of channel IDs | -c |
channelIds |
CHANNEL_IDS |
S3 Source Bucket | Name of S3 bucket to read manifest file/template from. Unsupported in CLI. | Unsupported | sourceBucket |
SOURCE_BUCKET |
NOTE: As mentioned above, multiple account IDs can be specified via the -a
CLI option and the accountId
Lambda option by separating each ID with a ,
.
You should not do this with the NEW_RELIC_ACCOUNT_ID
environment variable
when running using the AWS Lambda function
as this value is used by the New Relic Lambda extension.
The New Relic Reports CLI runs reports using the New Relic Reports engine. It is used by the CLI image and by the CRON image. Reports can also be run directly from the command line using the provided wrapper script. However, usage at the command line is mostly meant to be used locally for development and testing purposes.
The reports to run can be specified via the CLI options or environment variables. When the engine starts, it resolves the set of reports to process in the following order of precedence.
- The
-f
option orMANIFEST_FILE_PATH
environment variable - The
-n
option orTEMPLATE_NAME
environment variable - The
-d
option orDASHBOARD_IDS
environment variable - The
-q
option orNRQL_QUERY
environment variable
If none of the options or environment variables are specified, the engine will attempt to load a manifest file at the path "include/manifest.json".
Refer to the Options section or for additional options and details.
index.js -f <manifest-file>
index.js -n <name> [-v <values-file>] [-p <template-path>] [--skip-render] [-c <channel-ids>] [-o <output-file>] [--full-chrome]
index.js -d <dashboard-ids> [-c <channel-ids>]
index.js -q <nrql-query> -a <account-id> [-c <channel-ids>] [-o <output-file>]
-
--help
Show help
-
--version
Show version number
-
-f, --manifest
Run all reports defined in the manifest file
<manifest-file>
. Takes precedence over-n
,-d
, and-q
and their corresponding environment variables.The
MANIFEST_FILE_PATH
environment variable may also be used to specify a manifest file. If both are specified, the-f
option takes precedence. -
-n, --template-name
Run a template report using the template named
<name>
. Takes precedence over-d
and-a
and their corresponding environment variables. Ignored if a manifest file is specified.The
TEMPLATE_NAME
environment variable may also be used to specify a template name. If both are specified, the-n
option takes precedence. -
-v, --values-file
Use the template parameters defined in
<values-file>
when running a template report. TheVALUES_FILE_PATH
environment variable may also be used to specify a values file. -
-p, --template-path
Include paths in
<template-path>
on the template search path when running a template report. Multiple paths are separated by the OS path separator character.The
TEMPLATE_PATH
environment variable may also be used to specify the template search path. -
--skip-render
Skip template rendering when running a template report.
When specified, the raw output of the template report will be passed through to the channels. The engine will not launch a headless Chrome instance and will not render a PDF using the browser.
-
-d, --dashboard-ids
Run a dashboard report with the dashboard GUIDs listed in<dashboard-ids>
. Dashboard GUIDs are separated by commas. Takes precedence over-q
. Ignored if a manifest file or a template name is specified.The
DASHBOARD_IDS
environment variable may also be used to specify the dashboard GUIDs. If both are specified, the-d
option takes precedence. -
-q, --nrql-query
Run a query report with the NRQL query
<nrql-query>
. Requires-a
. Ignored if a manifest file, template name, or a dashboard GUID string is specified.The
NRQL_QUERY
environment variable may also be used to specify the a NRQL query. If both are specified, the-q
option takes precedence. -
-a, --account-id
Use the account
<account-id>
when running a query report with-q
. Multiple account IDs can be specified separated by commas. Required with-q
. -
-c, --channel-ids
Publish report output to the channels listed in
<channel-ids>
. Channel IDs are separated by commas. Ignored if a manifest file is specified. -
-o, --output-file
Use
<output-file>
as the name of the PDF file when running a template report and--skip-render
is not specified or when saving output to a file when using thefile
ors3
channels. Ignored if a manifest file or dashbuard GUID string is specified. -
--verbose
Enable verbose mode.
-
--debug
Enable debug mode (be very verbose).
-
--full-chrome
Don't launch Chromium in headless mode. Use only for testing purposes when rendering a template report with
-n
.
The examples shown below use the ./nr-reports-cli/bin/nr-reports.sh
wrapper.
-
Run a template report using the template named
chart.html
and save it to a file../nr-reports-cli/bin/nr-reports.sh -n chart.html
In this example, the reporting engine will process the template using the template engine, render the output using the browser, export the rendered output as a PDF, and publish the PDF to the default file channel. The file channel will copy the PDF to the current working directory as a file named
chart.pdf
. -
Run a template report using the template named
chart.html
and the template parameters specified in the values filechart-values.json
and save it to a file../nr-reports-cli/bin/nr-reports.sh -n chart.html -v chart-values.json
In this example the reporting engine proceeds the same as the above except that the template engine will pass the template parameters defined in the
chart-values.json
file as template variables when it processes the template. -
Run a template report using the template named
chart.html
and the template path/tmp/templates
and save it to a file../nr-reports-cli/bin/nr-reports.sh -n chart.html -p /tmp/templates
This example proceeds the same as the first except that the template engine will search for templates in the directory
/tmp/templates
in addition to the default directories. -
Run a template report using the template named
errors.csv
and the template parameters specified in the values fileapps.json
and save the raw template output to a file../nr-reports-cli/bin/nr-reports.sh -n errors.csv -v apps.json -o errors-by-app.csv --skip-render
In this example, the reporting engine will process the template using the template engine passing in the template parameters defined in the
apps.json
file and then publish the raw template output directly to the to the default file channel. The file channel will save the output in a file namederrors-by-app.csv
in the current working directory. -
Run a dashboard report to export a snapshot of the dashboard with the GUID
ABCDEF123456
and save it to a file../nr-reports-cli/bin/nr-reports.sh -d ABCDEF123456
In this example, the reporting engine will export the dashboard snapshot as a PDF and publish the PDF to the default file channel. The file channel will copy the PDF to the current working directory as a file named
dashboard-ABCDEF123456.pdf
. -
Run a query report that executes the specified NRQL query against account
12345
and saves the query result in a CSV file../nr-reports-cli/bin/nr-reports.sh \ -a 12345 \ -q "SELECT average(duration) as 'Duration' FROM Transaction FACET appName as 'Application Name', request.uri"
In this example, the reporting engine will run the given NRQL query against account
12345
, convert the query result to CSV data and publish the CSV data to the default file channel. The file channel will copy the CSV file to the current working directory as a file namedquery-report.csv
. -
Run all reports specified in the given manifest file.
./nr-reports-cli/bin/nr-reports.sh -f include/tests/manifest/manifest.yaml
In this example, the reporting engine will read all report definitions from the specified manifest file and run each report in turn.
A Dockerfile is provided to build a Docker
image that provides an ENTRYPOINT
that runs the CLI with no arguments.
Arguments can be passed to the the CLI via arguments to the docker run
command. Engine options can also be specified as environment
variables. This image is meant to be used in conjuction with external scheduled
task mechanisms such as AWS ECS Scheduled Tasks
to run reports on a schedule without the need to keep the CRON image running
all the time, since most reports likely run infrequently. It can also be used
as a base image. It can also be used as a way to test and debug reports
locally without needing to have everything required to run the CLI available on
the local machnine. This can be more inconvenient than running the CLI directly
on the local machine but has the benefit that it will produce reports in the
exact environment they will be run when the image is deployed.
As mentioned in the section template-resolution, all
files in theinclude
directory are copied into the application
root of the image (/app/nr-reports-cli
).
In addition to the CLI Dockerfile
, the build.sh
script is provided to simplify building the CLI image. It supports the
following options.
Option | Description | Example |
---|---|---|
--image-repo image-repository |
The repository to use when tagging the image. Defaults to nr-reports . |
--image-repo nr-reports |
--image-tag image-tag |
The tag to use when tagging the image. Defaults to latest . |
--image-tag 1.0 |
You can either run the script directly or use the npm run build
command while
in the ./nr-reports-cli
directory.
Here are a few examples.
-
Build an image using all the defaults. The image will be tagged with
nr-reports:latest
in the local Docker registry.cd ./nr-reports-cli npm run build
-
Build an image with a custom image name. The image will be tagged with
my-great-reports:1.1
in the local Docker registry.cd ./nr-reports-cli npm run build -- --image-repo my-great-reports --image-tag 1.1
The following examples show how you can run reports using the CLI image. Though the image is intended to be used in conjuction with a scheduled task mechanism, it can be helpful for testing and debugging reports in the exact environment they will be run when the image is deployed rather than running in a local environment which may not be consistent with the deployed image.
NOTE: The Docker option --cap-add=SYS_ADMIN
is used in the examples below
to work around the Error: Failed to launch the browser process!
message.
This option would only be necessary if you are running template reports and you
encounter this error message. The option should be used carefully as it
provides root
access to the underlying host OS. In general it should
only be used locally when testing and developing templates.
NOTE: In the examples below, the AWS configuration and credential files
in the local .aws
directory are mounted into the home directory of the
pptruser
in the container so that the AWS SDK for Node.js
has access to the AWS configuration and credentials without having to pass those
via arguments on the command line.
The example below uses the email
and s3
channels. The example specifies the channel IDs engine option
and the channel parmeters via environment variables and
runs a simple template report that does not use a manifest file and assumes the
template hello-world.html
is available on the template path.
docker run --rm -e NEW_RELIC_API_KEY='[YOUR_USER_API_KEY]' \
--cap-add=SYS_ADMIN \
--name nr-reports \
-e CHANNEL_IDS='email,s3' \
-e EMAIL_SMTP_SERVER='[YOUR_SMTP_SERVER]' \
-e EMAIL_SMTP_PORT=YOUR_SMTP_SERVER_PORT \
-e EMAIL_SMTP_SECURE='true or false' \
-e EMAIL_FROM='[YOUR_FROM_EMAIL]' \
-e EMAIL_TO='[YOUR_TO_EMAIL]' \
-e S3_DEST_BUCKET='[A_S3_BUCKET_NAME]' \
-v /path/to/.aws:/home/pptruser/.aws \
nr-reports -n hello-world.html
The example below uses the default manifest file located at
include/manifest.json
. The channels and the channel configuration parameters
are specified in the manifest file, except for the ones that are only supported
via environment variables.
docker run --rm -e NEW_RELIC_API_KEY='[YOUR_USER_API_KEY]' \
--cap-add=SYS_ADMIN \
--name nr-reports \
-e EMAIL_SMTP_SERVER='[YOUR_SMTP_SERVER]' \
-e EMAIL_SMTP_PORT=YOUR_SMTP_SERVER_PORT \
-e EMAIL_SMTP_SECURE='true or false' \
-v /path/to/.aws:/home/pptruser/.aws \
nr-reports
The example below uses a custom manifest file located at
include/custom-manifest.json
. The channels and the channel configuration
parameters are specified in the manifest file, except for the ones that are only
supported via environment variables.
docker run --rm -e NEW_RELIC_API_KEY='[YOUR_USER_API_KEY]' \
--cap-add=SYS_ADMIN \
--name nr-reports \
-e EMAIL_SMTP_SERVER='[YOUR_SMTP_SERVER]' \
-e EMAIL_SMTP_PORT=YOUR_SMTP_SERVER_PORT \
-e EMAIL_SMTP_SECURE='true or false' \
-v /path/to/.aws:/home/pptruser/.aws \
nr-reports -f include/custom-manifest.json
The Dockerfile Dockerfile-cron
is
provided to build a Docker image that runs the CLI on a
schedule using cron
. The containers CMD
runs crond
with the -f
flag to
keep it in the foreground, which keeps the container up and running. Because
of this, arguments can only be passed to the the CLI when
the container is built. Arguments are specified
by invoking the build-cron.sh
script (or npm run build-cron
)
with the --cli-args
option. If the --cli-args
option is not specified, the
default Engine options are used when running the container
unless overriden by Engine options specified as environment
variables.
As mentioned in the section template-resolution, all
files in theinclude
directory are copied into the application
root of the image (/app/nr-reports-cli
).
The build-cron.sh
script is
provided to simplify building a CRON image. It supports the following options.
Option | Description | Example |
---|---|---|
--cli-args 'arguments' |
Arguments to pass to the CLI on each invocation by crond . Make sure to quote the arguments string. |
--cli-args '-n hello-world.html' |
--cron-entry crontab-entry |
A crontab instruction specifying the cron schedule. Defaults to 0 * * * * . Make sure to quote the entry string. |
--cron-entry "* * * * *" |
--image-repo image-repository |
The repository to use when tagging the image. Defaults to nr-reports-cron . |
--image-repo nr-reports-cron |
--image-tag image-tag |
The tag to use when tagging the image. Defaults to latest . |
--image-tag 1.0 |
You can either run the script directly or use the npm run build-cron
command
while in the ./nr-reports-cli
directory.
Here are a few examples.
-
Build an image using all the defaults. The image will be tagged with
nr-reports-cron:latest
in the local Docker registry.cd ./nr-reports-cli npm run build-cron
-
Build an image that will run all reports in the
include/custom-manifest.json
every day at 04:00. The image will be tagged withnr-reports-cron:latest
in the local Docker registry.cd ./nr-reports-cli npm run build-cron -- --cli-args '-f include/custom-manifest.json' --cron-entry "0 4 * * *`
The following examples show how you can run reports using the CRON image. Because CLI arguments can be passed to the container when it is built, and because engine options specified via CLI options take precedence over environment variables, the behavior of the reporting engine when a container is run depends both on the environment variables specified when the container is launched and the CLI arguments specified to build the image used to run the container. Use of both could make it difficult to determine what options are actually being used by the reporting engine. Therefore, in the examples below, both the way the containers are run and the way the images used by those containers are built are called out.
NOTE: The Docker option --cap-add=SYS_ADMIN
is used in the examples below
to work around the Error: Failed to launch the browser process!
message.
This option would only be necessary if you are running template reports and you
encounter this error message. The option should be used carefully as it
provides root
access to the underlying host OS. In general it should
only be used locally when testing and developing templates.
NOTE: In the examples below, the AWS configuration and credential files
in the local .aws
directory are mounted into the home directory of the
pptruser
in the container so that the AWS SDK for Node.js
has access to the AWS configuration and credentials without having to pass those
via arguments on the command line.
This example runs a simple template report that does not use a manifest
file. The report is run using an image built with all defaults. The template
name and channel IDs engine options are specified via
environment variables. The channel parmeters for both
channels are also specified via environment variables. The generated report
is published to the email
and s3
channels.
Finally, it assumes that the template hello-world.html
is available on
the template path.
Build command:
npm run build-cron
Run command:
docker run --rm -e NEW_RELIC_API_KEY='[YOUR_USER_API_KEY]' \
--cap-add=SYS_ADMIN \
--name nr-reports \
-e TEMPLATE_NAME='hello-world.html' \
-e CHANNEL_IDS='email,s3' \
-e EMAIL_SMTP_SERVER='[YOUR_SMTP_SERVER]' \
-e EMAIL_SMTP_PORT=YOUR_SMTP_SERVER_PORT \
-e EMAIL_SMTP_SECURE='true or false' \
-e EMAIL_FROM='[YOUR_FROM_EMAIL]' \
-e EMAIL_TO='[YOUR_TO_EMAIL]' \
-e S3_DEST_BUCKET='[A_S3_BUCKET_NAME]' \
-v /path/to/.aws:/home/pptruser/.aws \
nr-reports-cron
This example runs a simple template report that does not use a manifest
file. The report is run using an image built with CLI arguments for the template
name and channels specified via the --cli-args
option. The generated report
is published to the email
and s3
channels.
The channel parmeters for both channels are specified via
environment variables since these cannot be specified at the command line.
Finally, it assumes that the template hello-world.html
is available on
the template path.
Build command:
npm run build-cron -- --cli-args '-n hello-world.html -c email,s3'
Run command:
docker run --rm -e NEW_RELIC_API_KEY='[YOUR_USER_API_KEY]' \
--cap-add=SYS_ADMIN \
--name nr-reports \
-e EMAIL_SMTP_SERVER='[YOUR_SMTP_SERVER]' \
-e EMAIL_SMTP_PORT=YOUR_SMTP_SERVER_PORT \
-e EMAIL_SMTP_SECURE='true or false' \
-e EMAIL_FROM='[YOUR_FROM_EMAIL]' \
-e EMAIL_TO='[YOUR_TO_EMAIL]' \
-e S3_DEST_BUCKET='[A_S3_BUCKET_NAME]' \
-v /path/to/.aws:/home/pptruser/.aws \
nr-reports-cron
There are no major differences between CRON images built to run reports using the default manifest file. This is because no option or environment variable is needed to run the CLI with the default manifest file.
This example runs reports using a custom manifest file located
at include/custom-manifest.json
. Reports are run using an image built with all
defaults. The manifest file is specified via an environment variables. All
other values are specified in the manifest file, except for the ones that are
only supported via environment variables.
Build command:
npm run build-cron
Run command:
docker run --rm -e NEW_RELIC_API_KEY='[YOUR_USER_API_KEY]' \
--cap-add=SYS_ADMIN \
--name nr-reports \
-e MANIFEST_FILE='include/custom-manifest.json' \
-e EMAIL_SMTP_SERVER='[YOUR_SMTP_SERVER]' \
-e EMAIL_SMTP_PORT=YOUR_SMTP_SERVER_PORT \
-e EMAIL_SMTP_SECURE='true or false' \
-v /path/to/.aws:/home/pptruser/.aws \
nr-reports-cron
This example runs reports using a custom manifest file located
at include/custom-manifest.json
. Reports are run using an image that is built
using the --cli-args
option to specify the manifest file. All other values are
specified in the manifest file, except for the ones that are only supported via
environment variables.
Build command:
npm run build-cron -- --cli-args '-f include/custom-manifest.json'
Run command:
docker run --rm -e NEW_RELIC_API_KEY='[YOUR_USER_API_KEY]' \
--cap-add=SYS_ADMIN \
--name nr-reports \
-e EMAIL_SMTP_SERVER='[YOUR_SMTP_SERVER]' \
-e EMAIL_SMTP_PORT=YOUR_SMTP_SERVER_PORT \
-e EMAIL_SMTP_SECURE='true or false' \
-v /path/to/.aws:/home/pptruser/.aws \
nr-reports-cron
The reporting engine can be also be deployed as an AWS Lambda function. The Lambda function can be combined with other AWS services to trigger report generation in a variety of ways. For example, an AWS EventBridge trigger can be used to run reports on a schedule. Or, an Application Load Balancer trigger can be used to expose an HTTP endpoint for generating reports on demand by making a request to the endpoint.
The AWS Lambda function is deployed and managed as a CloudFormation stack. using the scripts provided in the scripts directory. These scripts require the AWS CLI to be installed as it is used to create and manage the CloudFormation stack.
Each of the scripts in in the scripts directory
require the --package-name
argument to be specified. The "package name" serves
a dual purpose. First, it is used as the name of the CloudFormation stack that
includes the AWS Lambda function and associated resources. Second, it is used
as the name for the AWS Lambda function Docker image in your local Docker
registry.
NOTE: The image version used as the image tag in your local Docker
registry is taken from the ImageTag
parameter specified in your
cf-params.json
file. This value is also used to tag the image when it is
pushed to the ECR container registry during deployment of the Lambda function.
The AWS Lambda function supports reading manifest, template, and values files
from Amazon S3 if the sourceBucket
engine option is set.
For example, if the sourceBucket
option is set to my-in-bucket
and the
manifestFile
option is set to my-manifest.json
, the AWS Lambda function will
load the object with the key my-manifest.json
in the S3 bucket my-in-bucket
.
In addition, if a source bucket is specified and no channel is specified for a
report, the default being s3
, or s3
is specified as a channel without a
destination bucket, the AWS Lambda function will default the destination bucket
to the source bucket.
A Dockerfile Dockerfile
is
provided to build a Docker image that can be
deployed as a Lambda container image.
The image is built from an AWS base image for Node.js.
By default, version 14
is used but this can be customized by specifying the AWS_LAMBDA_VER
argument
when building the image. The image automatically includes the
New Relic Lambda Extension Layer
corresponding to the version of the base image that is specified. Like the
CLI image and the CRON image,
all files in theinclude
directory are also included in the Lambda
container image.
The build.sh
script is
provided to simplify building the AWS Lambda image image. It supports the
following options.
Option | Description | Example |
---|---|---|
--package-name package-name |
The name used as the stack name as well as the name used to tag the image in your local Docker registry. | --package-name nr-reports-lambda |
You can either run the script directly or use the npm run build
command
while in the ./nr-reports-lambda
directory. For example, to build the image
using the NPM script, you would run the following command.
npm run build -- --package-name nr-reports-lambda
NOTE: While the build.sh
can be
invoked on it's own, the deploy.sh
and
the update.sh
scripts invoke it for
you prior to deployment.
Prior to working with the Lambda function, you will need to ensure that you have the following.
- An ECR container registry to host the container image built with the Lambda Dockerfile
- A function execution role that the Lambda function will assume when the function is invoked
- Optionally, a Secrets Manager secret in which to store the New Relic User API key used by the Lambda
The Lambda function is deployed using a CloudFormation template. The CloudFormation template accepts a number of parameters which must be specified when deploying. Parameters are specified using a JSON file with the following format.
[
{
"ParameterKey": "Key1",
"ParameterValue": "Value1"
},
{
"ParameterKey": "Key2",
"ParameterValue": "Value2"
}
]
A sample template parameter file
is provided the shows an example of using each of the parameters supported by
the template. Documentation for each parameter is provided inline in
the CloudFormation template as
comments. For example, here is the documentation for the UserApiKey
parameter.
#
# New Relic User API key used for GraphQL Nerdstorage queries and mutations.
#
# NOTE: It is not recommended to use this. Instead, specify a secret ARN via
# the UserApiKeySecret parameter.
#
UserApiKey:
Type: String
Description: The New Relic User API key to use.
AllowedPattern: '[a-zA-Z0-9._\-]*'
Default: ''
The deploy.sh
script is used
to deploy the Lambda function. This script will first invoke the build.sh
script
to build the Lambda Docker image using the Lambda Dockerfile.
The script will then push the image from the local Docker registry to the
registry defined in the ./nr-reports-lambda/cf-params.json
file and use the
aws cloudformation deploy
command to create the stack using
the CloudFormation template.
You can either run the script directly or use the npm run deploy
command
while in the ./nr-reports-lambda
directory. For example, to deploy the AWS
Lambda function using the NPM script, you would run the following command.
npm run deploy -- --package-name nr-reports-lambda
To deploy the AWS Lambda function, perform the following steps.
-
Ensure you are logged into AWS ECR using
aws ecr get-login-password
. -
Copy the ./nr-reports-lambda/cf-params.sample.json file to
./nr-reports-lambda/cf-params.json
cp ./nr-reports-lambda/cf-params.sample.json ./nr-reports-lambda/cf-params.json
Note: This file does not exist by default, so make sure to do this step.
-
Update the values in the file
./nr-reports-lambda/cf-params.json
as appropriate for your environment. -
Run the
deploy
script.npm run deploy -- --package-name nr-reports-lambda
You should now have a Lambda function named RunNewRelicReport
(unless you
customized it in the cf-params.json
file). You can confirm this by looking
in the AWS Lambda console or running the following command in your terminal.
aws lambda get-function --function-name RunNewRelicReport \
--output table \
--no-cli-pager \
--color on
The update.sh
script is used
to update the Lambda function. This script first invokes the build.sh
script
to build the Lambda Docker image using the Lambda Dockerfile.
The script will then push the image from the local Docker registry to the
registry defined in the ./nr-reports-lambda/cf-params.json
file and use the
aws lambda update-function-code
command to update the Lambda to point to the
new image. Note that you must increment the value of the ImageTag
parameter
specified in your ./nr-reports-lambda/cf-params.json
file.
This script can be used to update the Lambda function image to include new or updated manifest files, template files, and/or values files.
You can either run the script directly or use the npm run update
command
while in the ./nr-reports-lambda
directory. For example, to update the AWS
Lambda function using the NPM script, you would run the following command.
npm run update -- --package-name nr-reports-lambda
The delete.sh
script is used
to delete the Reports Lambda function and the associated CloudFormation stack.
You can either run the script directly or use the npm run delete
command
while in the ./nr-reports-lambda
directory. For example, to delete the AWS
Lambda function using the NPM script, you would run the following command.
npm run delete -- --package-name nr-reports-lambda
The reporting engine can be monitored using the New Relic APM agent for Node.js if you are using the CLI, the CLI image, or the CRON image; or using Serverless monitoring for AWS Lambda if you are using the AWS Lambda function
To enable the APM agent for the CLI, the CLI image, or the CRON image, simply
update the Node.js agent configuration
just as you would for any other application. If you plan to use the
agent configuration file method,
you can find the agent configuration file at nr-reports-cli/newrelic.js
.
If you plan to use environment variables
(recommended), refer to the appropriate documentation for setting
environment variables for your runtime environment (shell versus local Docker
image versus container service, etc).
To enable serverless monitoring for AWS Lambda, refer to our official documentation and the Deploying the AWS Lambda function section of this document.
Once enabled, an APM or Lambda function entity will be created with the name specified in the agent configuration and the reporting engine performance metrics, logs, and traces will be collected and associated with the entity.
If you get the error below while running the Docker CLI or CRON image, you
need to ensure that the container has privileged access. Granting the container
privileged access can vary depending on where the container is being run. For
example, on ECS, the container must have the privileged container capability,
i.e. com.amazonaws.ecs.capability.privileged-container
. When running locally,
you may need to add --cap-add=SYS_ADMIN
. See
this documentation
for more details. Note that this option should be used carefully as it provides
root
access to the underlying host OS. In general it should only be used
locally when testing and developing templates.
Error: Failed to launch the browser process!
Failed to move to new namespace: PID namespaces supported, Network namespace supported, but failed: errno = Operation not permitted
[0311/215738.145277:FATAL:zygote_host_impl_linux.cc(191)] Check failed: ReceiveFixedMessage(fds[0], kZygoteBootMessage, sizeof(kZygoteBootMessage), &boot_pid).
Received signal 6
r8: 00007ffe9021d000 r9: 00007fc18b8aefdc r10: 0000000000000008 r11: 0000000000000246
r12: 00007ffe9021d650 r13: 00007ffe9021d56c r14: 00007fc189afbe20 r15: 00000000000000a0
di: 0000000000000002 si: 00007ffe9021ce90 bp: 00007ffe9021ce90 bx: 0000000000000000
dx: 0000000000000000 ax: 0000000000000000 cx: 00007fc18e3ef3f2 sp: 00007ffe9021ce88
ip: 00007fc18e3ef3f2 efl: 0000000000000246 cgf: 002b000000000033 erf: 0000000000000000
trp: 0000000000000000 msk: 0000000000000000 cr2: 0000000000000000
[end of stack trace]
TROUBLESHOOTING: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md
at onClose (/app/nr-storybook-cli/node_modules/puppeteer/lib/cjs/puppeteer/node/BrowserRunner.js:229:20)
at ChildProcess.<anonymous> (/app/nr-storybook-cli/node_modules/puppeteer/lib/cjs/puppeteer/node/BrowserRunner.js:220:79)
at ChildProcess.emit (events.js:412:35)
at ChildProcess.emit (domain.js:475:12)
at Process.ChildProcess._handle.onexit (internal/child_process.js:282:12)
New Relic has open-sourced this project. This project is provided AS-IS WITHOUT WARRANTY OR DEDICATED SUPPORT. Issues and contributions should be reported to the project here on GitHub.
We encourage you to bring your experiences and questions to the Explorers Hub where our community members collaborate on solutions and new ideas.
We encourage your contributions to improve Reports! Keep in mind when you submit your pull request, you'll need to sign the CLA via the click-through using CLA-Assistant. You only have to sign the CLA one time per project. If you have any questions, or to execute our corporate CLA, required if your contribution is on behalf of a company, please drop us an email at opensource@newrelic.com.
A note about vulnerabilities:
As noted in our security policy, New Relic is committed to the privacy and security of our customers and their data. We believe that providing coordinated disclosure by security researchers and engaging with the security community are important means to achieve our security goals.
If you believe you have found a security vulnerability in this project or any of New Relic's products or websites, we welcome and greatly appreciate you reporting it to New Relic through HackerOne.
New Relic Reports is licensed under the Apache 2.0 License.
New Relic Reports also uses source code from third-party libraries. You can find full details on which libraries are used and the terms under which they are licensed in the third-party notices document.