nrql.el
nrql.el is a library that offers the ability to run NewRelic NRQL (NewRelic Query Language) queries from within Emacs.
It is currently intended for, and best used, within org-babel code blocks. Made with org-mode.
Installation
Manual
- Clone this repo
- Run the following pointed at wherever you cloned this repo to
(package-install-file "~/code/nrql.el/nrql.el")
MELPA
Maybe if there is interest
Usage
This package is currently best used within org-mode. It was developed to make writing investigations into tickets by allowing the results of NRQL queries to be easily exportable. A typical work flow might look something like the following:
- Start investigating a bug in NewRelic
- Find the appropriate information, and obtain an NRQL query (either you wrote it, or can sometimes be captured from https://one.newrelic.com UI)
- Paste it into an
nrql
org-babel block. It can now be run locally on your machine, and have the result exported if properly configured (add:exports results
or:exports both
to yournrql
block’s header arguments
select timestamp, message from Log where message like '%readiness%' since 1 minute ago limit 10
timestamp | message |
---|---|
2021-10-10 Sun 17:28:47.791 | complete: GET /api/readiness 200 |
2021-10-10 Sun 17:28:47.043 | complete: GET /api/readiness 200 |
2021-10-10 Sun 17:28:46.259 | complete: GET /api/readiness 200 |
2021-10-10 Sun 17:28:46.249 | complete: GET /api/readiness 200 |
2021-10-10 Sun 17:28:46.171 | complete: GET /api/readiness 200 |
2021-10-10 Sun 17:28:45.982 | complete: GET /api/readiness 200 |
2021-10-10 Sun 17:28:45.640 | complete: GET /api/readiness 200 |
2021-10-10 Sun 17:28:45.509 | complete: GET /api/readiness 200 |
2021-10-10 Sun 17:28:45.424 | complete: GET /api/readiness 200 |
2021-10-10 Sun 17:28:45.244 | complete: GET /api/readiness 200 |
Sample Queries
Queries Resulting in Tables
You can also explicitly specify what fields you want to return. Timestamps will be parsed to a human readable format by default.
from Log select timestamp, response_status where response_status is not null
timestamp | response_status |
---|---|
2021-10-11 Mon 21:55:32.005 | 200 |
2021-10-11 Mon 21:55:30.761 | 200 |
2021-10-11 Mon 21:55:30.614 | 200 |
2021-10-11 Mon 21:55:30.563 | 200 |
2021-10-11 Mon 21:55:30.460 | 200 |
2021-10-11 Mon 21:55:30.406 | 200 |
2021-10-11 Mon 21:55:30.324 | 200 |
2021-10-11 Mon 21:55:30.263 | 200 |
2021-10-11 Mon 21:55:30.110 | 200 |
2021-10-11 Mon 21:55:30.082 | 200 |
You can run star queries against your transactions.
select * from Transaction limit 9
appId | appName | containerId | duration | entityGuid | error | host | name | port | priority | realAgentId | tags.account | tags.accountId | tags.guid | tags.trustedAccountId | timestamp | totalTime | transactionSubType | transactionType | apdexPerfZone | httpResponseCode | request.headers.contentLength | request.headers.host | request.headers.userAgent | request.method | response.headers.contentType |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
111111 | tacocloud-com | container_id123 | 0.04863817 | entity_456 | :false | tacocloud-0 | WebTransaction/Filter/TacoRequestFilter | 8983 | 0.886877 | 111 | taco.com | 999 | entity_456 | 999 | 2021-10-11 Mon 21:22:38.542 | 0.04863817 | Filter | Web | S | 200 | 130 | tacocloud-0.tacocloud-hs.tacocloud:8983 | Taco[org.apache.solr.client.solrj.impl.Http2TacoClient] 2.0 | POST | application/octet-stream |
111111 | tacocloud-com | container_id123 | 0.044141483 | entity_456 | :false | tacocloud-0 | WebTransaction/Filter/TacoRequestFilter | 8983 | 0.767033 | 111 | taco.com | 999 | entity_456 | 999 | 2021-10-11 Mon 21:22:38.541 | 0.044141483 | Filter | Web | S | 200 | 131 | tacocloud-0.tacocloud-hs.tacocloud:8983 | Taco[org.apache.solr.client.solrj.impl.Http2TacoClient] 2.0 | POST | application/octet-stream |
111111 | tacocloud-com | container_id123 | 3.5762e-05 | entity_456 | :false | tacocloud-0 | OtherTransaction/Taco/org.apache.solr.search.TacoIndexSearcher/warm | 8983 | 0.33727 | 111 | taco.com | 999 | entity_456 | 999 | 2021-10-11 Mon 21:22:38.540 | 3.5762e-05 | Taco | Other | nil | nil | nil | nil | nil | nil | nil |
111111 | tacocloud-com | container_id123 | 0.05570143 | entity_456 | :false | tacocloud-0 | WebTransaction/Filter/TacoRequestFilter | 8983 | 0.26771 | 111 | taco.com | 999 | entity_456 | 999 | 2021-10-11 Mon 21:22:38.531 | 0.05570143 | Filter | Web | S | 200 | 130 | tacocloud-0.tacocloud-hs.tacocloud:8983 | Taco[org.apache.solr.client.solrj.impl.Http2TacoClient] 2.0 | POST | application/octet-stream |
111111 | tacocloud-com | container_id123 | 0.013076241 | entity_456 | :false | tacocloud-0 | WebTransaction/Filter/TacoRequestFilter | 8983 | 0.072284 | 111 | taco.com | 999 | entity_456 | 999 | 2021-10-11 Mon 21:22:38.529 | 0.013076241 | Filter | Web | S | 200 | 130 | tacocloud-0.tacocloud-hs.tacocloud:8983 | Taco[org.apache.solr.client.solrj.impl.Http2TacoClient] 2.0 | POST | application/octet-stream |
111111 | tacocloud-com | container_id123 | 0.001776847 | entity_456 | :false | tacocloud-0 | WebTransaction/Filter/TacoRequestFilter | 8983 | 0.785038 | 111 | taco.com | 999 | entity_456 | 999 | 2021-10-11 Mon 21:22:38.519 | 0.001776847 | Filter | Web | S | 200 | nil | tacocloud-0.tacocloud-hs.tacocloud:8983 | Taco[org.apache.solr.client.solrj.impl.Http2TacoClient] 2.0 | POST | application/octet-stream |
111111 | tacocloud-com | container_id123 | 0.014840841 | entity_456 | :false | tacocloud-0 | WebTransaction/Filter/TacoRequestFilter | 8983 | 0.286713 | 111 | taco.com | 999 | entity_456 | 999 | 2021-10-11 Mon 21:22:38.516 | 0.014840841 | Filter | Web | S | 200 | 815 | tacocloud-0.tacocloud-hs.tacocloud:8983 | Taco[org.apache.solr.client.solrj.impl.Http2TacoClient] 2.0 | POST | application/octet-stream |
111111 | tacocloud-com | container_id123 | 0.010820628 | entity_456 | :false | tacocloud-0 | WebTransaction/Filter/TacoRequestFilter | 8983 | 0.026765 | 111 | taco.com | 999 | entity_456 | 999 | 2021-10-11 Mon 21:22:38.514 | 0.010820628 | Filter | Web | S | 200 | nil | tacocloud-0.tacocloud-hs.tacocloud:8983 | Taco[org.apache.solr.client.solrj.impl.Http2TacoClient] 2.0 | POST | application/octet-stream |
111111 | tacocloud-com | container_id123 | 0.000699507 | entity_456 | :false | tacocloud-0 | WebTransaction/Filter/TacoRequestFilter | 8983 | 0.285022 | 111 | taco.com | 999 | entity_456 | 999 | 2021-10-11 Mon 21:22:38.509 | 0.000699507 | Filter | Web | S | 200 | 460 | tacocloud-0.tacocloud-hs.tacocloud:8983 | Taco[org.apache.solr.client.solrj.impl.Http2TacoClient] 2.0 | POST | application/octet-stream |
You can basically query newRelic however you want.
SELECT rate(count(`com.taco.createTaco.counter`),1 minute) FROM Metric WHERE app = 'turo-com-dunlop' TIMESERIES LIMIT 10 SINCE 1 week ago EXTRAPOLATE
beginTimeSeconds | endTimeSeconds | rate.count.com.taco.createTaco.counter |
---|---|---|
1633407300 | 1633428900 | 4.352777777777778 |
1633428900 | 1633450500 | 6.644444444444445 |
1633450500 | 1633472100 | 7.863888888888889 |
1633472100 | 1633493700 | 8.272222222222222 |
1633493700 | 1633515300 | 6.816666666666666 |
1633515300 | 1633536900 | 6.158333333333333 |
1633536900 | 1633558500 | 10.519444444444444 |
1633558500 | 1633580100 | 11.725 |
1633580100 | 1633601700 | 4.705555555555556 |
1633601700 | 1633623300 | 7.386111111111111 |
1633623300 | 1633644900 | 9.644444444444444 |
1633644900 | 1633666500 | 8.969444444444445 |
1633666500 | 1633688100 | 6.411111111111111 |
1633688100 | 1633709700 | 8.13888888888889 |
1633709700 | 1633731300 | 11.005555555555556 |
1633731300 | 1633752900 | 7.386111111111111 |
1633752900 | 1633774500 | 5.902777777777778 |
1633774500 | 1633796100 | 8.625 |
1633796100 | 1633817700 | 12.575 |
1633817700 | 1633839300 | 11.805555555555555 |
1633839300 | 1633860900 | 9.591666666666667 |
1633860900 | 1633882500 | 10.555555555555555 |
1633882500 | 1633904100 | 13.936111111111112 |
1633904100 | 1633925700 | 14.841666666666667 |
1633925700 | 1633947300 | 10.675 |
1633947300 | 1633968900 | 12.405555555555555 |
1633968900 | 1633990500 | 11.863888888888889 |
1633990500 | 1634012100 | 10.325 |
Function Based Queries
NewRelic supports many types of queries with functions as a parameter. These are some examples
FROM Log SELECT apdex(response_status) since 1 day ago
apdex.response_status | count | f | s | score | t |
---|---|---|---|---|---|
(“count” 5798595 “f” 5798595 “s” 0 “score” 0.0 “t” 0) | 5798595 | 5798595 | 0 | 0.0 | 0 |
Compute median: the first value returned is the percentile
FROM Log SELECT median(response_status) where response_status is not null since 1 day ago
median |
---|
(“50” 200.0) |
Compute percentile: the first parameter in a pair is the percentile
FROM Log SELECT percentile(response_status, 91, 80) where response_status is not null since 1 day ago
percentile.response_status |
---|
(“80” 200.0 “91” 200.0) |
Compute median:
FROM Log SELECT median(response_size)
median |
---|
(50 192.0) |
Customization
nrql-timestamp-format-string
can be used to customize what format times display
to. Any format must comply with Emacs’ format-time-string function.
nrql-api-keys-file
can be used to customize what file api keys are stored
in.
nrql.el-dir
can be used to customize what directory api keys are stored in.
Contributions
Contributions are more than welcome! TODOs are currently being tracked within
the nrql.el
file. However there are a few specific areas that need some focus:
faces
: the faces (how syntax is highlighted) is currently very rudimentary- HTTP Error handling: currently there is no error handling for HTTP errors.
- Supporting more features from NerdGraph like embedded chart URLs for data visualization.
- Improved readability of function query results involving percentiles.
- Improved testing