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.
- Clone this repo
- Run the following pointed at wherever you cloned this repo to
(package-install-file "~/code/nrql.el/nrql.el")
Maybe if there is interest
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 |
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 |
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) |
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 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