From 2ca8bd0e82062c2b1b27116682018f1024cf95e7 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Tue, 11 Aug 2020 04:53:03 +0000 Subject: [PATCH 01/25] fix: upgrade @mdx-js/mdx from 1.6.10 to 1.6.13 Snyk has created this PR to upgrade @mdx-js/mdx from 1.6.10 to 1.6.13. See this package in npm: https://www.npmjs.com/package/@mdx-js/mdx See this project in Snyk: https://app.snyk.io/org/github-newrelic/project/868cac7a-942a-4cb5-a87b-05381c8ca7ec?utm_source=github&utm_medium=upgrade-pr --- package-lock.json | 127 +++++++++++----------------------------------- package.json | 2 +- 2 files changed, 30 insertions(+), 99 deletions(-) diff --git a/package-lock.json b/package-lock.json index 28b2a476f..4eb18ea86 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3695,23 +3695,23 @@ } }, "@mdx-js/mdx": { - "version": "1.6.10", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.6.10.tgz", - "integrity": "sha512-4IAupGOJxlti/IIfRuiK0gYXw6pLxTR465HmHcEEiGOHPdxOyrK3NssmKBUf9UOWAg6wBqwwSvRF/TrzKzUE/Q==", + "version": "1.6.13", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.6.13.tgz", + "integrity": "sha512-xVZnzSQ/QsP6LnYnV5CC9sc92dzm0VsnFEbpDhB3ahbrCc0j/p4O5+q+OIic9H3AAYLIzoKah3Mj+wTnDpAeWg==", "requires": { "@babel/core": "7.10.5", "@babel/plugin-syntax-jsx": "7.10.4", "@babel/plugin-syntax-object-rest-spread": "7.8.3", - "@mdx-js/util": "^1.6.10", - "babel-plugin-apply-mdx-type-prop": "^1.6.10", - "babel-plugin-extract-import-names": "^1.6.10", + "@mdx-js/util": "1.6.13", + "babel-plugin-apply-mdx-type-prop": "1.6.13", + "babel-plugin-extract-import-names": "1.6.13", "camelcase-css": "2.0.1", "detab": "2.0.3", "hast-util-raw": "6.0.0", "lodash.uniq": "4.5.0", "mdast-util-to-hast": "9.1.0", "remark-footnotes": "1.0.0", - "remark-mdx": "^1.6.10", + "remark-mdx": "1.6.13", "remark-parse": "8.0.2", "remark-squeeze-paragraphs": "4.0.0", "style-to-object": "0.3.0", @@ -3876,9 +3876,9 @@ } }, "@babel/parser": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.2.tgz", - "integrity": "sha512-Vuj/+7vLo6l1Vi7uuO+1ngCDNeVmNbTngcJFKCR/oEtz8tKz0CJxZEGmPt9KcIloZhOZ3Zit6xbpXT2MDlS9Vw==" + "version": "7.11.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.3.tgz", + "integrity": "sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==" }, "@babel/plugin-proposal-object-rest-spread": { "version": "7.10.4", @@ -3944,9 +3944,9 @@ } }, "@mdx-js/util": { - "version": "1.6.16", - "resolved": "https://registry.npmjs.org/@mdx-js/util/-/util-1.6.16.tgz", - "integrity": "sha512-SFtLGIGZummuyMDPRL5KdmpgI8U19Ble28UjEWihPjGxF1Lgj8aDjLWY8KiaUy9eqb9CKiVCqEIrK9jbnANfkw==" + "version": "1.6.13", + "resolved": "https://registry.npmjs.org/@mdx-js/util/-/util-1.6.13.tgz", + "integrity": "sha512-IZP3UDGDaaaw0AchbXDofC//f+08w8FzW8EfTL/ZJNy6nKROe5xFwxnfRo5nL06l0CRCwNDmoReAerLuFMl1jA==" }, "debug": { "version": "4.1.1", @@ -3956,80 +3956,24 @@ "ms": "^2.1.1" } }, - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" - }, "lodash": { "version": "4.17.19", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" }, - "parse-entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", - "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", - "requires": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" - } - }, "remark-mdx": { - "version": "1.6.16", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-1.6.16.tgz", - "integrity": "sha512-xqZhBQ4TonFiSFpVt6SnTLRnxstu7M6pcaOibKZhqzk4zMRVacVenD7iECjfESK+72LkPm/NW+0r5ahJAg7zlQ==", + "version": "1.6.13", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-1.6.13.tgz", + "integrity": "sha512-LlaW2PpGl13THFHajl0EEpAnMkrZO2vmn4PPGJzy7vKfKf2UMioKa7zszfV3cEwKu1aHqqnjH5ZwuZj1hexHJw==", "requires": { "@babel/core": "7.10.5", "@babel/helper-plugin-utils": "7.10.4", "@babel/plugin-proposal-object-rest-spread": "7.10.4", "@babel/plugin-syntax-jsx": "7.10.4", - "@mdx-js/util": "1.6.16", + "@mdx-js/util": "1.6.13", "is-alphabetical": "1.0.4", - "remark-parse": "8.0.3", - "unified": "9.1.0" - }, - "dependencies": { - "remark-parse": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-8.0.3.tgz", - "integrity": "sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q==", - "requires": { - "ccount": "^1.0.0", - "collapse-white-space": "^1.0.2", - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "is-word-character": "^1.0.0", - "markdown-escapes": "^1.0.0", - "parse-entities": "^2.0.0", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "trim": "0.0.1", - "trim-trailing-lines": "^1.0.0", - "unherit": "^1.0.4", - "unist-util-remove-position": "^2.0.0", - "vfile-location": "^3.0.0", - "xtend": "^4.0.1" - } - }, - "unified": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/unified/-/unified-9.1.0.tgz", - "integrity": "sha512-VXOv7Ic6twsKGJDeZQ2wwPqXs2hM0KNu5Hkg9WgAZbSD1pxhZ7p8swqg583nw1Je2fhwHy6U8aEjiI79x1gvag==", - "requires": { - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-buffer": "^2.0.0", - "is-plain-obj": "^2.0.0", - "trough": "^1.0.0", - "vfile": "^4.0.0" - } - } + "remark-parse": "8.0.2", + "unified": "9.0.0" } }, "unist-util-is": { @@ -4037,14 +3981,6 @@ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" }, - "unist-util-remove-position": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz", - "integrity": "sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA==", - "requires": { - "unist-util-visit": "^2.0.0" - } - }, "unist-util-visit": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", @@ -4063,11 +3999,6 @@ "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0" } - }, - "vfile-location": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.0.1.tgz", - "integrity": "sha512-yYBO06eeN/Ki6Kh1QAkgzYpWT1d3Qln+ZCtSbJqFExPl1S3y2qqotJQXoh6qEvl/jDlgpUJolBn3PItVnnZRqQ==" } } }, @@ -5911,12 +5842,12 @@ } }, "babel-plugin-apply-mdx-type-prop": { - "version": "1.6.16", - "resolved": "https://registry.npmjs.org/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.6.16.tgz", - "integrity": "sha512-hjUd24Yhnr5NKtHpC2mcRBGjC6RUKGzSzjN9g5SdjT4WpL/JDlpmjyBf7vWsJJSXFvMIbzRyxF4lT9ukwOnj/w==", + "version": "1.6.13", + "resolved": "https://registry.npmjs.org/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.6.13.tgz", + "integrity": "sha512-G+vyur4OM+2iZih+vUeMzL/Aa0/4s/YZlDo6L0pfslgoX6eNGYT/NmjDZe99VxiaTaODX/bF/kt6oxZJYt8mJw==", "requires": { "@babel/helper-plugin-utils": "7.10.4", - "@mdx-js/util": "1.6.16" + "@mdx-js/util": "1.6.13" }, "dependencies": { "@babel/helper-plugin-utils": { @@ -5925,9 +5856,9 @@ "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" }, "@mdx-js/util": { - "version": "1.6.16", - "resolved": "https://registry.npmjs.org/@mdx-js/util/-/util-1.6.16.tgz", - "integrity": "sha512-SFtLGIGZummuyMDPRL5KdmpgI8U19Ble28UjEWihPjGxF1Lgj8aDjLWY8KiaUy9eqb9CKiVCqEIrK9jbnANfkw==" + "version": "1.6.13", + "resolved": "https://registry.npmjs.org/@mdx-js/util/-/util-1.6.13.tgz", + "integrity": "sha512-IZP3UDGDaaaw0AchbXDofC//f+08w8FzW8EfTL/ZJNy6nKROe5xFwxnfRo5nL06l0CRCwNDmoReAerLuFMl1jA==" } } }, @@ -5957,9 +5888,9 @@ } }, "babel-plugin-extract-import-names": { - "version": "1.6.16", - "resolved": "https://registry.npmjs.org/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.6.16.tgz", - "integrity": "sha512-Da6Ra0sbA/1Iavli8LdMbTjyrsOPaxMm4lrKl8VJN4sJI5F64qy2EpLj3+5INLvNPfW4ddwpStbfP3Rf3jIgcw==", + "version": "1.6.13", + "resolved": "https://registry.npmjs.org/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.6.13.tgz", + "integrity": "sha512-EKqKcGLmbegJji7qB7VRYQ6pJp74MGCjfCu1H6VOYr+ODqVMIsnxixYSvkuYTvwYaO1dWjSho85T4ctGMWpr+A==", "requires": { "@babel/helper-plugin-utils": "7.10.4" }, diff --git a/package.json b/package.json index bb18745c8..0845bf078 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "dependencies": { "@emotion/core": "^10.0.28", "@emotion/styled": "^10.0.27", - "@mdx-js/mdx": "^1.6.10", + "@mdx-js/mdx": "^1.6.13", "@mdx-js/react": "^1.6.10", "@newrelic/gatsby-theme-newrelic": "^1.6.0", "classnames": "^2.2.6", From d194e87ae94a69bef0e5adb885a65c5fb95a65ab Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Wed, 12 Aug 2020 04:53:05 +0000 Subject: [PATCH 02/25] fix: upgrade multiple dependencies with Snyk Snyk has created this PR to upgrade: - gatsby-plugin-manifest from 2.4.19 to 2.4.20. See this package in npm: https://www.npmjs.com/package/gatsby-plugin-manifest - gatsby-plugin-sharp from 2.6.20 to 2.6.21. See this package in npm: https://www.npmjs.com/package/gatsby-plugin-sharp - gatsby-source-filesystem from 2.3.20 to 2.3.21. See this package in npm: https://www.npmjs.com/package/gatsby-source-filesystem - gatsby-transformer-remark from 2.8.25 to 2.8.26. See this package in npm: https://www.npmjs.com/package/gatsby-transformer-remark See this project in Snyk: https://app.snyk.io/org/github-newrelic/project/868cac7a-942a-4cb5-a87b-05381c8ca7ec?utm_source=github&utm_medium=upgrade-pr --- package-lock.json | 38 +++++++++++++++++++------------------- package.json | 8 ++++---- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/package-lock.json b/package-lock.json index c55e1a881..4912b63ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13382,12 +13382,12 @@ } }, "gatsby-plugin-manifest": { - "version": "2.4.19", - "resolved": "https://registry.npmjs.org/gatsby-plugin-manifest/-/gatsby-plugin-manifest-2.4.19.tgz", - "integrity": "sha512-lVLP1m4aBQNC4lhsE3N7VZ6olk5Zb5A2T4jBEus0zxF8RCnfGoCD7Wg0cCMKbKR1n5ZXwHQgZfZI3BSp1/H7sw==", + "version": "2.4.20", + "resolved": "https://registry.npmjs.org/gatsby-plugin-manifest/-/gatsby-plugin-manifest-2.4.20.tgz", + "integrity": "sha512-kfaddU5FZq4+Vj7TklSwluUmuckNAmJvqNMkRruClBe23QE3aMDDAl7A4GWdVl4upId0zGXV1XgVNv58Ze0A1Q==", "requires": { "@babel/runtime": "^7.10.3", - "gatsby-core-utils": "^1.3.12", + "gatsby-core-utils": "^1.3.13", "semver": "^5.7.1", "sharp": "^0.25.1" }, @@ -14586,15 +14586,15 @@ } }, "gatsby-plugin-sharp": { - "version": "2.6.20", - "resolved": "https://registry.npmjs.org/gatsby-plugin-sharp/-/gatsby-plugin-sharp-2.6.20.tgz", - "integrity": "sha512-5M6wYzxer+yWEIhq+eE7XwcDWpJqm2Nr6V14UCfbR5KYmYpkEbDVm2dw1raBFonf/XUQ15idYjPp3U0mY6xfAg==", + "version": "2.6.21", + "resolved": "https://registry.npmjs.org/gatsby-plugin-sharp/-/gatsby-plugin-sharp-2.6.21.tgz", + "integrity": "sha512-KKVdMAysqZe8oPyPyGDC6tyfAKxqK0tDBk2PVp+Y76TjFMniFxCYJ/4LDPGLfQ+r1wkXX6ndK1lO2osTuzHSRA==", "requires": { "@babel/runtime": "^7.10.3", "async": "^2.6.3", "bluebird": "^3.7.2", "fs-extra": "^8.1.0", - "gatsby-core-utils": "^1.3.12", + "gatsby-core-utils": "^1.3.13", "got": "^8.3.2", "imagemin": "^6.1.0", "imagemin-mozjpeg": "^8.0.0", @@ -15541,9 +15541,9 @@ } }, "gatsby-source-filesystem": { - "version": "2.3.20", - "resolved": "https://registry.npmjs.org/gatsby-source-filesystem/-/gatsby-source-filesystem-2.3.20.tgz", - "integrity": "sha512-zwHsOe3BipnGeHvCNz4JSzz9bWbQEFgbpkjCpmOSsPtbNaKKbk7bK8TCLGj268K24x7E5fGuXPTLqXcRfYgEOA==", + "version": "2.3.21", + "resolved": "https://registry.npmjs.org/gatsby-source-filesystem/-/gatsby-source-filesystem-2.3.21.tgz", + "integrity": "sha512-HMCj4TF8hHoh5AwYliVIKNSva1wFjn3l/06TwV2/jvVa26JmLhdE+P24dB9blRpduGwv79tw6j1Ery0LMDeB8Q==", "requires": { "@babel/runtime": "^7.10.3", "better-queue": "^3.8.10", @@ -15551,7 +15551,7 @@ "chokidar": "3.4.0", "file-type": "^12.4.2", "fs-extra": "^8.1.0", - "gatsby-core-utils": "^1.3.12", + "gatsby-core-utils": "^1.3.13", "got": "^9.6.0", "md5-file": "^3.2.3", "mime": "^2.4.6", @@ -15666,13 +15666,13 @@ } }, "gatsby-transformer-remark": { - "version": "2.8.25", - "resolved": "https://registry.npmjs.org/gatsby-transformer-remark/-/gatsby-transformer-remark-2.8.25.tgz", - "integrity": "sha512-RTO741t6eG4lw0WWmZRjN55SLBx225fJr+t+QkqUNTbBdTxRuUfHyAK6gRzVDtIC9Jtr1fQZxK0Hx2M6nj72RQ==", + "version": "2.8.26", + "resolved": "https://registry.npmjs.org/gatsby-transformer-remark/-/gatsby-transformer-remark-2.8.26.tgz", + "integrity": "sha512-MsI590tfgwvQ8U+oTIMM94XLZUAawYsR2Pio/B77lgDVcO8bLR0S4UMhrrnUHD1qkN8eFuu7g0JWzKoMS0hQUw==", "requires": { "@babel/runtime": "^7.10.3", "bluebird": "^3.7.2", - "gatsby-core-utils": "^1.3.12", + "gatsby-core-utils": "^1.3.13", "gray-matter": "^4.0.2", "hast-util-raw": "^4.0.0", "hast-util-to-html": "^4.0.1", @@ -15694,9 +15694,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.0.tgz", - "integrity": "sha512-qArkXsjJq7H+T86WrIFV0Fnu/tNOkZ4cgXmjkzAu3b/58D5mFIO8JH/y77t7C9q0OdDRdh9s7Ue5GasYssxtXw==", + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.2.tgz", + "integrity": "sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==", "requires": { "regenerator-runtime": "^0.13.4" } diff --git a/package.json b/package.json index 30e96e7dc..75977c96c 100644 --- a/package.json +++ b/package.json @@ -15,20 +15,20 @@ "gatsby-image": "^2.4.13", "gatsby-plugin-emotion": "^4.3.10", "gatsby-plugin-layout": "^1.3.10", - "gatsby-plugin-manifest": "^2.4.19", + "gatsby-plugin-manifest": "^2.4.20", "gatsby-plugin-mdx": "^1.2.27", "gatsby-plugin-meta-redirect": "^1.1.1", "gatsby-plugin-offline": "^3.2.17", "gatsby-plugin-react-helmet": "^3.3.10", "gatsby-plugin-robots-txt": "^1.5.1", "gatsby-plugin-sass": "^2.3.12", - "gatsby-plugin-sharp": "^2.6.20", + "gatsby-plugin-sharp": "^2.6.21", "gatsby-plugin-sitemap": "^2.4.11", "gatsby-plugin-use-dark-mode": "^1.1.2", "gatsby-remark-autolink-headers": "^2.3.11", "gatsby-remark-images": "^3.3.17", - "gatsby-source-filesystem": "^2.3.20", - "gatsby-transformer-remark": "^2.8.23", + "gatsby-source-filesystem": "^2.3.21", + "gatsby-transformer-remark": "^2.8.26", "gatsby-transformer-sharp": "^2.5.10", "js-cookie": "^2.2.1", "node-sass": "^4.14.1", From 65e64a8db054f073a3ab78cd8d95c641ebfb261d Mon Sep 17 00:00:00 2001 From: John P Vajda Date: Tue, 18 Aug 2020 19:05:02 -0600 Subject: [PATCH 03/25] added nrql lessons to resources --- STYLE_GUIDE.md | 2 +- .../get-started-nerdgraph-api-explorer.mdx | 12 ++++++------ src/markdown-pages/collect-data/query-data-nrql.mdx | 9 ++++++--- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/STYLE_GUIDE.md b/STYLE_GUIDE.md index ce47b5a52..a94ee7141 100644 --- a/STYLE_GUIDE.md +++ b/STYLE_GUIDE.md @@ -314,7 +314,7 @@ redirects: - /build-tools/new-relic-one-applications/intro-to-sdk - /client-side-sdk/index.html resources: - - title: Introduction to New Relic NerdGraph + - title: 'Introduction to New Relic NerdGraph' url: https://docs.newrelic.com/docs/apis/nerdgraph/get-started/introduction-new-relic-nerdgraph - title: Deploy an app url: /build-apps/publish-deploy diff --git a/src/markdown-pages/collect-data/get-started-nerdgraph-api-explorer.mdx b/src/markdown-pages/collect-data/get-started-nerdgraph-api-explorer.mdx index d8b1d6fa7..d73ea5c8b 100644 --- a/src/markdown-pages/collect-data/get-started-nerdgraph-api-explorer.mdx +++ b/src/markdown-pages/collect-data/get-started-nerdgraph-api-explorer.mdx @@ -10,15 +10,14 @@ tileShorthand: redirects: - /technology/graphql resources: - - title: Introduction to New Relic NerdGraph + - title: 'Introduction to New Relic NerdGraph' url: https://docs.newrelic.com/docs/apis/nerdgraph/get-started/introduction-new-relic-nerdgraph - - - title: NerdGraph tutorials + - title: 'NerdGraph tutorials' url: https://docs.newrelic.com/docs/apis/nerdgraph/tutorials tags: - nerdgraph - mutations - - nerdgraph query terminal + - nerdgraph query terminal --- @@ -27,7 +26,7 @@ NerdGraph is New Relic's [GraphQL](https://graphql.org/) API. It allows you to g With NerdGraph API Explorer you don't need to know the query format: using the Query Builder you can browse our entire graph and compose queries just by selecting the items you want and filling out their required values. - @@ -60,6 +59,7 @@ This GraphQL snippet appears in the editor. } } ``` + @@ -69,7 +69,6 @@ With this query, you're telling NerdGraph to retrieve your name. You're asking f Click the **play** button to see the result: It has almost the same shape as the request. All the fields in the Query Builder make up what's called the GraphQL schema, which describes all the available data types and their attributes. To learn more about each field, click the **Docs** button, or hover over a field in the editor. - ![NerdGraph documentation and tooltips](../../images/graphql-guide/graphql-documentation.png) @@ -144,6 +143,7 @@ newrelic nerdgraph query '{ } ' ``` + diff --git a/src/markdown-pages/collect-data/query-data-nrql.mdx b/src/markdown-pages/collect-data/query-data-nrql.mdx index 285e41598..d6ff024cc 100644 --- a/src/markdown-pages/collect-data/query-data-nrql.mdx +++ b/src/markdown-pages/collect-data/query-data-nrql.mdx @@ -9,10 +9,13 @@ tileShorthand: description: 'Query default event data, custom events, and attributes' redirects: - /technology/nrql +resources: + - title: 'New Relic One NRQL Lessons' + url: https://opensource.newrelic.com/projects/newrelic/nr1-learn-nrql tags: - - NRQL - - NRQL syntax - - calculate data NRQL + - NRQL + - NRQL syntax + - calculate data NRQL --- From 8ea21e83f9df510afa0895342d4f57e795f565c3 Mon Sep 17 00:00:00 2001 From: Stijn Polfliet Date: Wed, 19 Aug 2020 11:43:39 +0200 Subject: [PATCH 04/25] Add helm deployment guide --- src/data/sidenav.json | 4 + .../k8s-cluster-explorer.png | Bin 0 -> 148383 bytes .../kubernetes-helm-deployment.mdx | 150 ++++++++++++++++++ 3 files changed, 154 insertions(+) create mode 100644 src/images/kubernetes-helm-deployment/k8s-cluster-explorer.png create mode 100644 src/markdown-pages/automate-workflows/kubernetes-helm-deployment.mdx diff --git a/src/data/sidenav.json b/src/data/sidenav.json index 71a60f35f..cd1257174 100644 --- a/src/data/sidenav.json +++ b/src/data/sidenav.json @@ -41,6 +41,10 @@ "displayName": "Set up New Relic using the Kubernetes operator", "url": "/automate-workflows/get-started-kubernetes" }, + { + "displayName": "Set up New Relic using Helm charts", + "url": "/automate-workflows/kubernetes-helm-deployment" + }, { "displayName": "Tag a set of resources efficiently", "url": "/automate-workflows/5-mins-tag-resources" diff --git a/src/images/kubernetes-helm-deployment/k8s-cluster-explorer.png b/src/images/kubernetes-helm-deployment/k8s-cluster-explorer.png new file mode 100644 index 0000000000000000000000000000000000000000..d3bd961af162b418e7935a6d4a22a163a477d249 GIT binary patch literal 148383 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 z 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�xRMev z^n2K1eZu>WhZU_LR5ErE+P1S;l}LrRHgQazmx+T3j04wp3zqfC`X{TvDK+zxH|scS zIPUA09J+w*T!Vs-j+GQ;jg8cwog|^8aUZeI-g3)qGTZDIl`boFQ}2If z5<6X_ZtCrPq2UO}3l)y6wTyk=-`^HCGA>uRV4qrcz6!&LpVv@d$NAot;sq6;eshoT zEf4FsRbt&A`=&Mp9G|c)j4D=_ubDY(>3L2nf^BdckF-n*Hha8a zy<*oJl^wr&fm-hxr#^l-aC~EB_c;(F<}*GJc&_CKB93u7I_cxm-xII(_Me?P2ATEwU%_y(MgxQt=Ow$PETpN zA-e&HYq%jqdUu(3aeW^p{A*51aroq%DQO5GEK;_=Cz7j!@INbbYW5hzrHi@^_S~ae z$u8-)sJImVLFfrAIs+~5JC^S{w6}zB&L*Rc9iBaUV>+1k?Zv>~R>9Y9y|p-QwvVHT zzy?+hG_w6pAW4D1gDs*w1(-}BpyZZvaJF*(dYky8k%_Fvg>jnw-ka}DKLk!j#7m(O zdw3WZ+(dl4d~TI+bH2}%r1vrA9Vy+T?+AflLQpT6lYMWbBwbCswdwv%7eGK1$;D)( zr2K9o7Nv#LvEx)#_FYoN$^|8So$W#``3B3)7R^eNE z?TY@VTDz;-RU#IxHzge6-LH@?Hg;D7H{;iF`bS5Tyl*e%Q4Bf5Fyd$=5HP+arvM_0>oAbJ{=s8&4S-%;0BKk|XnF zF>epxng-K-9&~>IA+VI-%@@9<*ws&QTXc%C(qvxBzuPWSTLs=lPL=EH2Hu}$8BD`d zS8%=O025m~J>FER*;;wS;3w~&1LOEv$ITBi%RYaJ-}f`|dw+A^a^D|HSwn_r+&!$Q zt-GVEhd9xcrrzk6G@tFzw5e}@^&BO;wN{Gr%|lu%T?71%A#z)GuCY3`z%lA;FeqkV zaH?#t+S=_r21K8#avu!4z?;cBb;E_hq|t?ZYYaI!zBah=itQ*E`4PnYw#ic}=F<{& z=&7&WIXf&qM<#i8M~fs{q#lq zO2O~RDb*k|c(iraQ%6@c%YsI}ce^=3W`L`AI!EK_AC(8NDRI&>sDpchJ*Sp7*~PrY zW{JAg^~WJnSAxrw>Wx0)S(>a7UU{%1oo_OaL$SO{80Wvx5s+DhfXXD<1C5yZz!@G8&NJLY)FQQch8)l*A@Cy(ZUR$Y!N)Ug1(I z*b%tbGsiqGeSnl_cQHoo(n1WgdTbaq4lKVK_jtBg^K6e{)$5_{uF0!OJ3{8`BsYOg zc`CP%qtxClMb<6Os329!O@~?#dTd&njh~t^u~wq(+*es6bFmN-1k~X^Zc8X!=~AJT z{IEG|NaYGjlmKHvL2;&n%HO%8{)Jb7l$P3;1J#sp*>Y*lvy2OX;EqVV-&KF*y%9dI znV~Ncl^Gx|xe5~>2abX?c^?@OUUWVw>A-OR6mUR8 z?oI|#UL2|vAjKE|N9JKWa3N6R&DA)U#?Lmon{!A0i&bJ_BFJ@-M`#`)&k!YTQtp8hzPRar|2$@CzF5(7$ZzT6q z*kPP$Z+}sikNpjzJ(sc>g&HQDfHArSY>lTfDDrbDZgLaAGC7xzh1 z4=xvluMsCqdU|?H?$w-i2EOJ+?s5s#Trad0JwRzaJC%Y*^Y7KLT%^6JWP9^-Q{#le zgs_G9-N&%p5uWgQ`zRVEDaNgq(HV@He8bn%IMrGAJ8AV(9%nbW8%_vDLP3(t8tPLs z%98de6Ol&}A0hY}evfOe^B#i!hoC{RuQ8RsH{mzI)?ak<=Op4r4}b4t^JcW%BD?DX zj!^NY)|0Wd!N3Uvx%$x-F$O=m4T+T79|ASXc$E9o`nk8}NytuL)E+%10|e8d>FbTI zX1Qt)gSv^(Kcg-KHG!;=8Du-wPE1TtYS2EH^8(AfhT;3HmSw?o3>=QKWsxJ2U-e+M z?ory9XGbIQR&E^c1vc9)wQ64!+vo(yB^1OnN}!jRn60jm780IkGUuc|3KEs*!OZ41aoMwQxOWshtz3iZo zA1%mfSX$@%tN(E66Pr6jar!nyMWa@sLaRyjfZ+9#*_n;^jCO4KsP6lY%S=F_IA1#o zgo6d2Y4wtUQ{95XR&{XKyD*KVQfRmZv1;YZ`pQ+wSGANty*xl2=nMtvv!rfvyMeTPh+D1M}V{= zvJ-IL2bNC>dLHAHT7tQa@;`lZbU%cB#(21EPMQKH0+IV!V2DT3{~P(KPFu6{$VcPb zGJ_TkjWQjYCzUNf=q0N3H>4tdwZ5|ZHBA*7@A{U)sh*K%!W+DxIrgCjFrhWF%PN>I z2q#-W>?=Jw2~X>Mh@zLSx(mws#2G521zcodZ1*_rYu@oRIU=Fabn~Ix}gk{%NRw@E3z7r_H<>M}$ZI;8C0iA8w8psxsN^V7KCqMmybuUi5y)Ph`?SOwU7MHv48R zvT-szF&Bocz2Q3hV-Un`9Qxpc{8p^2`@hq5cYf!T>Qza&+p8cVq>)VQfcy- za?Lu)pe=uPTJw42Gfno=*UD=jcgDL;Z`}v58I&(Gh5z2jN6t1<_Tb_8YD^vfWywFGT9=mgjytez)&xus6^o3~%Z%2#PqizBUqsQ)i zPO?O5Jzd67z>WSS0I~-;8vbm{p3}ahTcMpW9nr&D#k*blg2FV@tES(UHo&*0ce)DYA~$ueLhJOd4!coPhK{B3NeaJy>^2CtpV=HD1k?=n<0gM!>_c z=J~CA21x?7ZY!bw8@SUA>?A{@*9>?;8M%$2@o!ZCXVKVSnS?*;Mnov#WIvWij2%EK z1oOi5xa|b<3!P;q|L3HEQ>Os^5fDEX!FBY+0M2oVfK@1bMU2C#u<^b! z$3HGOC<2mEc(<19BQR?KNbv4`pdCO^A(7r`;N8!pT|=#QB$dwm{4u7$mca$fjE7ZY zo6Fd&xXPE%d@wZ6On%8+d(ob2Q(;##}q9d_jqerW$uTGm4G_RJW<>I4b zZu;VO(x6Dn3`TLCJb4P6T4DJ7<7wJZX^<&RuR?eRs)B)F;!+y0 zBt8Ly6+-SwmI4q4#*ibwI)H@XoR}ol;L-?!EQzl9G76%+MF7(TUmF|vD9gl;ljGth z_sYi?WV44xQ-wy!)J@dz!~7tj$>LX)&V!2`h6<#1&VGK7jtSsrcu4eF3REpwe>g{x zFl7yy(S5|_4#WtNf9-cUW|Dv=SVJyK#Pa=aWKNl!rZ8*QAe5le@VmRa4j*OSUz>yl zK`NYIoN`QhLZyIqAnECtFz{xYQ>f02!g5~1Y7m9#-^0&=JxMjdmBT&V)WxG#URrxs zrg0blO%hlEJ~*A+QPnu6^yQLn8bEUzV}KF2-{YPEdJJ8M9L0XtqU5%j3U-@kj)q{v zK=Dxb5(upBX*@+$qwhp^`d>yHj~~{>#Zp*51M9`COyYUmQc9J-shQJDW>bsa8gU0c zRFQG)PbIznnjnXb!KxJP8w84{065sVL2DLl8=5ag*pFHZ7(3h!(()ci0nlFyas)Q> zo>wYMtmdZ1e2qYlWQ0&-h(~dIE?h=`Brhu~+utaV=!{%rt>t$iP8gqe8JxkdZ?G73 zz9v%28HW8pCxD>!*%-A)Yw+X6z^7ML_ta~z0TR5ia#YI{SZPQ&z6nTv-Q#l9-;K1> znUFjAO~~V+H(hlIG$2m-x0MD$3>_fdQ0Vz{c0pzumB>Ph9(+f7nKgcp4WMkJ=0Y&b zh1DVboz$UD8HLnmK$fI^<*+W#32lI!Af_?+D|QIG@{28g@U=Bo&6^GDy`hl=?9{ra zY}YdKit&bufN4iN`3E#2Gl z^}wcwq5|IumodsBfrGJPOXV;jggqZ6y;Fj?k?<(KxmMyO+3-z_R?tcZTxdP`ut35(}T)fw^5!6+&uX2 z(L`o0+nEDa4sMjMzNiVukCoPW_KN)Ufkrp4rUn5d0vjw+HI8~Q?SCRO9?UgeUt*6C zXTTf;qabL7Kv_kkJUreGzRRIrqXzTNUhZJ{5l|EpF(+uCj&D;ip(7J?VbgievSPTJ z?Ew9y#1TPE-4}34K5GqUiR~8}sgD8DcYsB6yoqH2j1W*M%K-cMM9dY2`OWdeET%}P zwmhNV2U51}uUf(Sm!jJc8l+EEWTJ+9D{YJP1y!i?_Vm=zmJs&B_1FHVqz5nm?I(U9 zGnc+1UPcbsr73_>;`5VLm4S{U;R3sLDw((Mc={C;mH6P8By+`bc#^~&y5(xN;j8!a zCh=5mR{6IEdM$y^qQD60vnkrzfCquGguy#32z)E$Xgm$z>Kc7P>kMm>pRHc%k7<{g zj6uRVCA_a=RPhs$>Z14pSvf@~!$ty?mA;u2g%(~dr^Qh%*1zYO|HS@gQ^xkjS32Z1 zLU=iER{5OdxG-hZBMjcF=> z&ORIq`XhhFaFZwowx{*wc(KLP`%feQ1cwQfN(ZDf5x{C?geasxz4wE2#W?*cyWmz4 z^4A~xwE{bLeCN%U7W4iHoKci{jTQaTJ>v*~EGdBOy$C)$#vE&A;E!33PKUf-?6bx#FJ)nD>yK*R>ZeEG2Jd1BQx<)uL)na>b;x0`8R6V9J*p@k7X8m5 zhz~GJqN!W;l3ewB@Pnh{e@tIDZ*B#??u{nipR^d+`pRWyJ~CTjNlpQKYv7S)Fjtkc z`y*E)jw0ys01&}q8+`u8v~grMEL?QX;3=Gtbh$T|a>miQ*MwTfqxcs_BNF&9fbeS{}Q1YX+2*SvX8+1a=$0E@(iP8EF!cm;SEw%E z;B-Zor4`Q+R;`row~rLkOo~dF9a`Ov7}tESvV1Rc9)`X$WKykYeb>+=Rvi`tjtzuq z#RZWc=L5Rs3`d#zR*Lv)3bA%KUs9aMs{4|Cb}7YLeTh};XB0*Wlbf^1);^Ql%UQNj z;c_`v!ZaLAk!_}(pS@RJ#RB4xGx`7yt?(|#W`q)opyE7=2D>_rR(45ZabHPp20^PmB^kY=so-e z+KKkcIE>+Q{}2~omnD&2#xNiB%CtS<;OQDYvbzBd%a!~ugd1=IB?=o)T-QV%e7+9$ ze#I>f@ixTgL8=$clOty<^K0|inL9ivQ_jl6L!l*7@&~k=eZQOSUqDxZWc!ug% z1o@Ozm&*EGhuQt$nV1lV@TqXseNYy09s!NVBe^C^Ww*|DlN+l!!`G2{G_<lkwGNHmVd>dBB-<%maI3{$J)TuYNRwG}oIH^#*ckIl5 z%CF-z4$c6mbzGXF4d}up7^o0GVTZS=n;+kH85jE{QxGs(C+B4bXoVW8sC(kVW?u!R z-ucYrL(g8&m)I(PhCGr6@#WS5slx}>20UVyzDNC$uJF8zk+k;ITfKD0Dtz%#->Y8C zXFq3ODUagXtu|Rr&|K+PJLPfZg!ZEvc&Sz;m+AN%hjGZu>G3^*qwN78} zO$y?wfK?UCzSetXgk2eT_q_g=TCED1kC#bSp;IU(|7)UmXf$P#Ca4E5tNj5&Pqsp0 zT~qEh{=Nbo%lrZk@QxF`pKk8a9SOd{ME9U{SN49j;$lMWGQMDyvGU;;R*;xyXRUG9 zq}RsV>q=HrioZXycq`>dMPmE&stp_M*VxN65ls(1_n4hM!u}P=tl+yDc78Og42N1w zfP7{rmrgY%q>=z1jbP~}5t~G_;dpxC*$yRPT6bAEOOR%VD{pZ)od*jxvn(s~AIg^y z)sGv4Jnd&kk0{z0A$p}-vS`?SEv5&<`PR-I(g@-@@eP=i5kJ2pQQ9%mu1i6@8u^Ip z&qW7)GI4#v-D!aM50-2ib-$H;X3|i0YdN>Q4J9s&h3`K?LDqjyPKVP+; zrOvfsgs?=FRW*NszLE~PYFhPQI&$dWxz^o`oZp6L_X5>2tjQ(u%`HjbpO-@eb#qJNcG{xMQoGw!XTuvIq=>9xiMxh$?a@>ERd3ak9%q8XN-maCgKhsm5sV6~k1lFNRFL;sA zf>Mo20;S@eE#`wUhXW2P6Ax}5ZQaL-CcrCs6DKP%3!fdEsJ00kv-m9{PfK%mmg*hY zhA@676wki@g{TmP0XjrLGGcxIIKRA1V@ltCgc`n@jxmq3yqEX6x=_AAW-`~`&zA4= z!{1>sG%Vc|U1B#?RY^8NVi*70ZNkKzQ6n!<>*6N%?3`m2?F{<$;s%i7Oq}PaGA5+8&hE zyr^vXrNDi9`m$*}E2ikNL;JOhdeXInYg2K#^k|$FFaGJ!V~P(;4xJ0;E#jrCRb4j& zc#n(v07dJUl)o(Twczjbx{0?KVMm;KjM9ISzt{Nrm=P>hIU2ug`Dk6{AfX!Ro2$*| zba$4#^ca)xOs#s^CP%AN1nV&T?&P=mJe#=h?vtgs5qY4Mby}*IGE%`GYYhNed=$acWdMQi-Vof zQ?ytt5SSdAt6^b&F&vjng)d^Hn^!19<*fMTIHa`(BSI1(&Xa%QC*^Kh*KTRw8@5*) z^boHU+3p!9vtKPG73BczCguyfF6D=#KrsW4vBREB#cD+MJtmFQ#|xYu93)Ono3fo@ zw9%-#kXu=@pEb~P9i*z-21Q<7tNE3V*t6g;Pa} zQziYI=Oc3xscoHS*mU!4iPm=VNtVQ781P~XVe5)`NaZq-^dn5{i0vOOEiKcj7NRND z4bqo^%b?mx{dd7b3+vOHXdcEbMp`UK2>p6#>~~F!!8QgjU+^|y;MABY$&IUS^2*(N~|58t~jMw zKLgHXzC^&8RDMwM`%p0iCePP2v8k$kZn^MNvTo2P5aEiu%lIC;A>AFxf>X8myBVZi zXicy|ZjGh~UPDBYL_m#qv0)x3{2sEeKF3STBJ>Kwx|p~y)0|mz&fWNn4$&^{xN>Fz zzYY^E7AAzKfJ@tK^uJLE!$ZV4uQVGH2)pd#uPuurp8PEoWgM`JUis&V zh7*Edd_y{W5Y%vcsi6l0o9fQki>=MneN9yY_J_mySWs~tX%URb6% z8_v~y@rUW^y(#~_I6-d!>irA>Tp8><*n`7xG_eE~C{Dquo0&k4r4D6X5!cWvb44~n zQz+BXiMM;sz4)Cc#|9`6Kp&23(;l z?0^L}R_WnXmfgaQ;Y)|U3#bhutZQqdC21-D_f&~#C_cK5OA144G54Q?- zjrmu-s-XpY!}{j8E*Om(wHQnMXA_G&KFH0@O+s>(J;03I*dg_PEu;!?rHI5fKx!rc zW{nL}PY^+%mjbA3Sm7Ya5xD0>4z`vBwzaQAXPMsB)k~bRs`eAny7P;J7M1W&J6+nb~bL*5{YCHsAJ=4lZ2Ds52U+SpAkcvU(Qr`_u z1qyfp*7UmIiv{?TO6q_BJGU%nWzUw=U&jmD?uG7 zhui&e+@vhNc=*@9!OOvlhJf+yvS;P@`X>DC){waW{ZLJIMh0pB(`sw@Ll6+b7F0f| z9*^ME_M!na$A^f2PflJd@`2hXb&I6OS#Lh__tMXMAJB< zS56%)&r@xDx+$|goNVTyL=g_>Bh4Xq?riFpd^zk>Hr%~#HC1XdupUn3IK95D4FbD# z!mzGi1jD0Y(XLD?!DS%nAGjnJDy(Owp?dJ$!mdM$46P+0!(3Y7@@-Zls|Q`g>d@7P zWBgA9h;O=)ELU$`eG}vjvy8h4P=4i-$Dg`@4!_T zk20Lop$S1^*+zqIS@MyUv2UJYbG%M%9aCK((>N0T_ynb}v|$La)W@E%ib|--QK>_f z2uPyOKyDS4X#}4473)qu;f8ZPUlOoAi$wV7C;`eY%CzS*wsXUgT4mW>}EKYOH6a`e%ig80)){w%^1g^U_A?D#vDIujkJiK@Mn|ri$hS9 z5atkr{%~c>K|Ec^(o3N;X{@b)!ahU7;d**FsWHCOZBP7D zWhyO3OC!PjdNEaEk~fy!7%Vi%!?<{Z(A`42;jV1n?qCdA^j#5@+ymuEmyHZTX11b zx~{*>VSY*Uvi82_Jx@qJxDQ{S(dQlv&y6+l=}}kIv}e-NOow| zuOzO7-KS2R$EDPHb0W0aiK}w63<`Zf#U;?1ZexeS&1fYLOT1g|U8MW&ObU<$+QsVT z4Yqwe2as(vz>yFhc>6DRE0qzzl1!sa`kc>!CDF)V@55gL2(FNMzStiu^GI*+0kk@_ z!*%t#z26ht2cmwQhjed9Qa5Ka91>ECUtZ}OO`~;2!YS^6TetY}@_sWxQ3>zzO7yzB z?r`p)GFXW}PdCrY1H%-e=eRDx^PPdn7OTw#7sp8i(ctuNd7Z%;Cm$6%czM=;w3QaG z!}S(Jz|kE?>=k3t=p4Oqk6?ADCnOqzv^jJqqy(prMQfg5X6*2#fOFdC2R&Uo@_sxiA+ zw%39-p0v@ytqbt|=s#w}8fm{keDaUh22o=JVilMh{uRVMX3Bs{@mmNG@kkd+6K zNc6hC1SeQ{yi|k%uK|1}cIguUAjCogXav+tCr(ls+l+d>RcG;MccI$k?PTIET*7wcsh&YE_uXR-L1VgTrLU}X#DH%~J1L~|Qc-bWr)~^R z|E>NYEzFB-7{fSQ$cA?I`-2!F3eG>$7~p07Kd?d4uc4jDH#)5o^RK&YzT`+imjD|d zpN5~^m#PE{5d{_SZ^ixwBJJb}2^Q5&o6`gYVsVw4EWkCM7)22c6q}2k?A7FQo1wWT zy&qq~6K#RkI8GhvwCPT|z|{u|bsxQGN_`6fkQ8No8$Au3$e^K_w&exNA0W+&Q^{li z>d1`jfwh9O+?8_9O#k3r`M~>9$D^)<`?Yw8zJ5|-N_{x_a40I(qf-h$=Q0VF_zjb- zPFnC=1C8cJrx-8-et`cn8~wDc=FI3~3`UU;>l68A^O;L3(gte|IG411fk-woQDL+! z>&~W4DHT!lh$HsJnkDMrh0#Xn0}G!9*bciCl%%AmyB%8vKLrJLkpW-s%QBY#p(Tq4 zq|kiN9exH6qGS*dxzgO}ZM+hTP0V@3x{Z*7mD1U*B+Y68T9|} zjzs})>^sef%fAS$yLtSlt(xXMy+$7A@t|UcNWb^9h8%mkKxsqRX;5Faj<;w5#t-;{xQm}nluIRIl864@zqe#pWF`Vq$x`tMwMZvZwlT9b zY9X0WX-TG_nw)>0E^_e1@*F46XJxVD{)R?-SaA z*@~T`bStCJk#T>Q%5kTmL^OM0XpPenw!jD2|M0+PBu5tPD=bh<^w|Vwwj8Xlxr8H- z%uk?KQNJXC?62>FQ#PD79LW}B3qZ*~a5$Z%_at!HMNfb$tqMgH#V0@vF9YkCDY=fo zCY?D&%w7>ugQMmOUum%;nC7G{#vFhKf1yKA#1=;ShkK_Yf$n{zL@#9p1xiryGhs@| z$CSatfrTM-YNoR2s0?$`EAwBQHe#AS?w;A8GKKBG!&O}W`5OBV70IW3T7R2kjap46 zvkMJ{2kyjgYhIbxgmYw-B4#DhMTNL+Luc;HWo8fT`jPydIlAIFPAp)W%Zsk%&rxWJ z5m|;vg3Iak24$;TuGO>B6L5NP^faAOs8~>vvcmBLj&QU?Q5Xf*H$ooha{s8(h0AIR zsOO?4_O^Bu3D<0Bt=m5H=WG~M#5*OVuyM{2>z+9>Y*SjFY1RqFcOpmhsn%i^Go14) z=S1Pp7F$lHc~fVHDHzF8cN)(j9xFSD3JSh`2?$2nKWinye!{l4x6@XBHl*Vi12jzf zr>^@&233#zm$`k6m@E_>19>nM*<2!l+$$7DZP5RiVPRom;4O4Jg~iy2c`pv<1!T4% z%=UYFtg*e9`E#7^d&CJyG~3R=s#%tN_X2dI63>~BViqpi!36!8FA0d|Z+rbN<})%_ z!fnL>u&^B_sTN=M!eDS)OI*$H?rFkYeGR+XdsF~10CKq7im}BZW5dGxe%J+vO0Prmo5;9mT`nGzev8CsQHUYoEp+>sLiJ-BhePdJ>wC0hHEp0eGCNtd zTE%At;$}BhQ&|KBCf%Rw`h`!Vj+z;U@`AZi+#m|b_mgBuK=QB{3miP0y8fdh z6rwb1Gd=qs-11mzj)Gvf=$~#Rcuiv9#myVTD-c4EteGMlzS~Zotn=~Q2LjBa86ry` z$Mva%F7~LW7+$8FAIyxsZR2otH1s^4(HZ$5beg1PJNwZPtNC~(6}1%6=0I@^|P0&6fhWhO+1AD_7hsbIX*{k zrXuez%BnYC3(%ZQWV|p2dbVHd8B{x3Vxc%`2<2a>{!Hc!b&zE>QrAV`k8%sjnv_rl zG?TZv`AUVte9fJrCSDlWmTHw*)~^*D@&E@w7c$F@ zFivSJIPcd20&t)UNTd4fo5H6`$#l`{0#lRsEw*q}GEb+9A1JlLmCqQZRNwiQd_j6y z2p#P3+*9TL*wy9qx-jzM6$Z_==fO8|KKoVHpCiSei@-qi zwH}%z!Vbq(Yf!)k;=(&5@58fTN&KIM76alatrLqt--5yYA>jQ**a8`pMHQ5csqIR5u-DDY*U<2r4>LRQ*=E7aU<)lHaRW(qt5 z+Hu4$ETe0R#h5$AdL~K8Ju|P6#=|JzUKj&OSdl{{>7uG4?DI3al4kY!GYT?+NhnS4 zTp4Iizf5I*t zqp-&R-2=U3Ir8F&CbxxjUv!)Z>b1OW$aMRHa@p$&g4aldXA?imRMp+RrAVS!A2~@D zO2r~9TRfW)+^W7kpPP@<$Oz zm~*D-@}-kv5U9qMYfBH;Mmv*;Idp1^ZE7Z%;x*EFW{_B1ar>j7zLD5|m+)XH%deTw zIR+%Q@xYpUlZQ$~FM+2GD%lO>M2$I&?C>a^k^?grYK!3gSCrz^n{XMi+2?rL!^vG# zyDZV?+*-5+m-9P+{Zq}+W%B0wM^ozOED$j?OIK1$B{+OSJ9$F0IR>n#L;c)XI$!eR zQ1suo`8+PujAgoSCO^juS4HB>y&kMPSm;nBObkR;NCm;e2~#jG?FS|3PlUdYG+(DT z`yE+=eoM$J&!uhDNujJq5Md=V>+qG>KGi7oQRtD46tRhjjP@9+?EPJO?e{peSw@-4 zJ_}rHPH6c@njX6md+?yZ4G5i^7;0t#-+aQCWp;QDPK5goS%B0{=n(j zSj>Jesp^-Y_m+SEz6}|XqY{R|LeXri&1_~+s}N3-lb|j<9n1p}nlawuOcaRGw$&ja zrU;bC33@*b0=<|W#%ed~J0)jn+PAc|ElA%(gXpTgM+i#di;J; z^%_zsvK1Tdiw4u1VX-Mu2VKAh^yvnIS<8h!V{T_&oSS8^!p!aaDRp$^59MT)h;Cj+qk`a!s&F9bs^zzz3xxPisJ+f$Tg4iLyHI-egR#Iq!c?`KlT60+Gk zP=mkNXrFm|+C)}#+GoRI-o@bdg%QntB zw=gq)n86y3NSZD%9%_=%%TtI&>+mo^4D!KxM$j`{5Uny-G1skYe538NdFyW3g?w@F z)w$JJK1S`aEtYP6p>_2h=(`FK**?d}iV+v3L<^156*6u)x2=w~uyJDZ;0+OGy|sUaNb-X(5O*{BtKTxo_}qjTq8KL@ z#)Kp1a<%jE z{ufU(Ptwz&;ew{jYaoTDmLHW+E(}_ zSmO72^CffZ`~v&aQ*;~;0hzP;7V)UqM>^VU^0Bs)ng`GAXgP01&!(rMlVP)u5+akC z6{m1j5~l0j0$J3b!Lm_^G-!$6rrXm7&ckbO9_8M&z@fuJ(d8gQGbN&Frd=iD(B1~+ znnSdJCz6luYhx(scpxww)G`FxHR=Mbv<6}D4}W*F z+z^>=-N?NLMe0Bk6o3=6sW4OBDN>dSkQrCRpZFN z&i(c+_hx|v?G4+;VOTK?$9$}%JU@E$jRF`EY(4X}LA;5aGbvap z6ZnwO=o~<`4~r1;lTgM6fVrTOxnjnjt?6*kN*?TkVMnlWUC`+3fo)5(21dnuO2I5G zVHs}QB!-^>g4|GqY;>>*MC!}%CJ98Kh60t0SOQLI-+Khp$e(5J48FDf%Do;QogT|` zCpTKfrcH9zmDnV(KCHcUF;?M@IFe6Lq6*Xvsl}LMXOoto9?fPP{J&ZNDa%VFir52q z@+XM_6%2teoa=X&<48&=1;TR;0=p}Tb+I^9DAXu;L&WSvW}L`Kp|;(~b_qQOW=a_J zA5D<>kbS?>lLn(BXB@&{dEp_df_e-`*>wV^*()Mf4+=|V0;KfE=So-ScP}Q6M#tTB zbUL(FW-cy_-%&^6VbRNrBS7BM<$e;wZ)~SV4zz=LsfBpaEad7h%1jBTpW*0jsC~x# z)&3e)*@0)938$Db|L<1z{ascN>aM9izAS~-jW?aO^UAXFVDBXEw+?ZC_XJTx|Mv(` zK;rl=^XxE7T@qAw@T4kG)o2Oa@!u;k7t1w>*bme`RUf#}$FL;w7laHezD*9d3N zEApncA3gqai<1e?cP`b zFKj8lYHTf##c0`_Gu$0t=vcB}tbQ%MbE}f=c4yZWIw0fuy$I7eCPumPs?T}pwED2_ zDy!|Px$!bK`EJ2c7K8kpW*A`Tb~LYUA97L18I)BQYHZ_d_4~OG=R0JVJHjwqEOB|+ zyM8I?=;>`=uDPbRjr7IF#;P>+{?gOYc{h88XRdk2xYBWXH%=}ze%rD9a8@?4uBLG^ zqjW>1$^*gQ$q$P&`tIaP1rwtpgtT%UAMH_jS+ak_X{}g3d5rvcr8tHZSAnX@)b?iT z^{Y_NO=hGo%j%|wZcsOL+or%~(`b`4l=I7rmdf#QcjMomii?;3N`@`xM$jyI9Jz^* zKCj@v{$(zQ+^D=3TF*mT{W7Unv$%Z8Jbmfd&Vasa{P(e&Ao!GPl_S+ z``544E!(!L1Et(QW+Q?s#usq!V=phAFg58*FwxMwPEk?NZx;UsKVCt^m1=ZY`|&* zIaSAfQme@R)uzj3RqhJ8RkoW70TG55gb=9xL_D4c^aNFf$@N!Mx2zLEpJ7vF%h5|* zJ&0Nu@uET_!`)saR*N#Jgr=k?GvKDAi4i$VKck#sL!oXNpq;G$>>J_}VbMaNxUCwU zIKbMUZ8uE5Ywzax;dbl!xCQkoXtKJGLKT_Ri7|u-rK(0n94nH+(tCtvT%jOVISt)5 z#2<^~u(Av2%-%;~!P$zchyJNYlZvm84x)6&I5Zfb`hbqO^0b=Ok*{zb8G)#n1XtMKL?Ej)^~j(ZFcvhNNgWnhhzM396G6iYHMYJScUmlRpDL|PcPjeaTx-gz zdIRe-@2tL2CSQ75)A(zt_|Z(%j`!NmYO3o~9)978%1SD&&ad=^Rg8)vgVpU#$C0D< zrE(AX8~A?dpFpvshdV-4x}@>4f&`8l&k(dMyV_KY+H^SZu+| z)?C!p4Jdo*6K>%RHz8*uhIf|>>V2F3Gn5&@L<7_kigm@E-?K!`z8>P^X5_rsRN)wH zFypUh1@erR1W*N3FUF|Hd|dCUU5$B0}o?ytd(YZVI&gjr02Iy$=MK{6a#9 zspqUSXNhkOyraTJ^5t#`urhnYGxr7X59Si@?~Sk)e0tt{Kk{eO6ixUzKEL<5LdiMuGUN2xwT<+QL4KX@rz;FVrw^Y5&5D zSeg!zNO_T3@5Wvwi#K6)8&jP8HR#IVSH@|h)%aFZ=1~&cCqqWknn3R|wyTT@1^)NL zlIl}$-q^ce#GpGkdGVLP7@xyyd}_4nGvb!uhz1~VNkeejt!TP6wv|Fo9#*1g8l_mZ z4IoAOHjT|itfSw5Wl6Z^H_hEoG|aV<;O07X{@6V+@9c zY~g5UYR;K68xk~_-4)dsOY2~79iOpj;sBL@TaOK;&$-sTFGOXn=cIloA zUv?9;a&pGunYI07^|FmQqc$WtG~mP)@^Wx;E1*CE0fLBl5)B3@i2#YG31Gx2IS6;N zbkoqo-Y1iJ>e@5*+=#coDz5tu5s`!2Cu>Cf)mVFjYwy#i4r_tI4&y;=r-Hi%a}L>< zW|u30epk(%xPvR>D?SDj1IjE3BqU@`VVFnHtMGO&GkvlT7plKsWK=t!#`iX^aW%P4 z2vio-+4lQ?y1iZg5&XD)a0ZFPzuMN`)^+eyWFwYLxY-LJE!z=NmLkk#SK=if8=7e( zww?cCQ3@&Xe0+84dUw*=`>Dokj$*Ewbtn3^ryzy0V{vh51(=b|#N!5+mGda$<`@yu zIgi5DRa@Nz9w8Ide0DvtyhbR2rG~3E)+qZn#{}c z2#yk`A`jf(fAjn`3zpl$vYnkh+%EH3e^CGmp$H>UO-zMI^ z8s^VpaykYNnZerEM2EX^L+}K#vGBd{KmRP`{O2js;I{5v_+Jo z6me;J-hMOCB=*QnVr&JJ0&B@Ec#sg zwN~DYu?4ur3+#4@czW^9Z&vZ%B`k*foLG(aakCv*V!#US$MG$)Iz#wzbWzh8s&f{pJ|FY55z6ahi&)K01Z}2V#cGq;(*})T10>x2^Cc z$82JfQOC8KDFS8rE}P-bwi6!b{55y|rPC(F#&&jg-*5fIif;!w9Jy;uhukwh@LP+^ z3$?bcwCoyx@OaTr2Y-P6w9L+~{-7TiRPtT0reI;|Pn`~NbD(J6WvBemG~O;pD+r_r z#zGR#%Mz7TqJ3T_5aWi?#oF!d%PaF8?;1#BdpDvH%c4+{Dif)flcfo}zE#d7rXV@b z79iC=8{9(1W;_2;3;XS`)s*#B6uP|+sufx6%T{>yIQ+e+BcAS^D32Iz% z%dTd(S*)ywq8v_BMzf^|!wV5Bh2=y4|9gxF6^a0ztsgO%5VH6fX#X^qul@sL)qPb` zSYckSi_ZB`FcDkBnv~H)l6^`-VnnVFcebV6RWR!!z4|O5irr(3jpb8GdE=T9?lW5L z<)3vqtxxQ`8XGTX_+Fi@yvJ-El8SNmTw;6PGE&tp$m00On@4yrLDBG`B$3`_`IzGE zMXyd_+alo@8{5f7n8C?O@|EHmiswylrM`U~{u(bIZ`*Hn-(2q)vc_cd0T&!;ZQ7Kb zC(1wKuSR1H+g9jtrPM3>i?Q~Leo@pN(;moq=~smHWgL$Q{g>@bWL6wza;3p}nC>+uQ;V#UqU|_gfi1zu+k`K^+Z)c!Rj) zL#|&7{<<2ce2#|H;f2LT^Q?Dcbp>-la|9B2CC~iX>?=-Agie(X1(MRk*6W0=QALs& zcp_0t5>4Hq8q0U3+pb0 z%E*Rh6&D=U?+c`rj})I;537nQJ_XG|r}BZXm!?BTq1?6DY+;d^wmrE14hFWECg2n7 z7y$yBD52d3Us17)Jj`9$MnD%m8jc$#5|DmvXgn{fS-k4`JJNJT%JKKCi%oIxQ_<$y z6}7wTgZJ1u!EbC~bc5sTPh&HB&$Y~UFv@%S{802GFK?nn&QjQlP9I*~y;MChiCXvS zc}QDLJ*_%+l{ag+ca@jC+jVJI+Gc86!{2&oUxcNonL?T|{fklNWfq%IBzQTxFj$Qw z6%&KK$lT9tDC0)yX;W?5&&*(S{1U&(oXHY{+qo!Ixgx7(sPOJr&!Y3Ben;gii0ff{u+{g|+ zupL&;OQm;s*N&lXDfFmpqF(o>z&~3fu&Vc);7wf-dQAgL^uZ_L_x%kT+o^Ua&<)GR zB?k94y6>VT2sFA54Tj1&UkBwjQr=4(yTPr(=Uo^D=M=>2s1owSZ0>QlC~RA*i7@Y5xT$|mrF zXx@MmxPT>w_cat}3H;d4&@I+S) zmX?Qpepov#&UqMhcXMxZo#>)E_Q!d7(tgkPNtej}nEWI(=YIOaZrPfGV7GAP$jt6Y&?4hCAGOoL!T8zwZLf(MSfgy zwEun^rEIXc_$X+SfZ4GS3HSy%2>C;|#0d~66&3_hSXv@LzgYfuUf3(rynKcEH{SPd zG8XheZ&Fr5Qw8xiF2;QYi!GT~i1mf~&@Ks+5ZXgM9uJI0mgLvwWUslI*TAeD3CMQ{h4` z>)rXfH8XvY$0L}#CoR7*Ncl0FE3?s0+MiJF#R>6qnhY*E=8pzUST)@@E}vX)SI~E& z-SIS?F2C8Xa$`8YmbGggE=lZgm{@i7Gg7}w?DjtWA$d|5fsG^SL6TT)eSmc_PK(-6Xu8ulVP*gCVx9fIi%gC(r_<%@ip}t&TJMU;O7(4JHjL zSMpiT83?#(>&!LVn8lAw=NrUnRW4D^do~@`1A6b_tP2~>c97Ut7;7rOIy~;aJ$k$P z+AmaelS#d{bfX)X7(vKe^^b266`R<)=rRK0lH={5ddZ?6Tk{x3y;#lPmz$7Av|K-S zSFH{i;iMKR8F{bKhJu=Ed~4zfLW<+1cX2ri++3n3JS&nEw6>aC$?i zFRD%WFoRi&rf@ZshorK~hGRxzZ!;vx-cne|;!r{Vr(DYeo=c#@a)*S|s8vz_dK?&n zBZen$-M_15hn~CjDA0mF7cqGQLKSIlsWrsrfWPItpS#(#6hVZCt}}{tWU4mFfkCh0=jN6l)>r`u*);WtAVHP@opse9 z`wEFK`38f&Os32K?l5Vl-7VjL*b}K}GTZJ-a&Q>s^Nomt4eLv=t6->fxK_$@H_tZe zCqG*!AbotgoC`{2*L|f<*keaug4obIoCcurC`}96k{hj9-y>;WMLZ2)OlW5Q)QuJX z7_nHYuOK@=VI;R>>vs}AvjwA!=vD=%T`*O7Gjxk7f1XhHE#yWeOFjoQC4B1iceTU8 z$$BVeLA~~q*$&sU*VzP-RX7Y>%k*I_kp~J*woBfXMJ)n`Ge1ee<(2}wDjhPG2jbcz zls$R|FPo3|Ms{hM5FAMuReH-MuZS2VVI$I-8J$2Bu||6t0opcNE)d4ejcOL9^2$%V zsyQv_(4ksukiTg|+jWZ&sP=wX3mMo;4kiN|V<97!59{F`DOZEz zHbXK4p`fesXCpFnbYdpQ2^+iXSd2nott@nk@L-T_$=u;=1g`hRz6ac+37Q-OcqqS# zwv!rzaBESOuX&jV-Wy2p{vk`fghevtgA7`u#T32gNX%TD4<_X>a~keoT+1tm>lWKL zZ=9bSzsnMGKGM~`W4h0jK@=V%-ny)M{8o0bcH-RhpPG%W zmr%;tZU_$O$WA>$cZ&-E>x{(+MTArk{P)u5VSU!clXm)q@yJn+u9Od_DH&Hm50T_E zW?Xdjt@uzf=bKlo`CvbSyF%q=b+$k;zh@q3KXyrgp3YA@v35<6arf0uP|=qejW=8|=MeDXuba9igE zG3RTuhn`@E?vVHjA&(XUMcbAvevj!(p`%8J)gub;3oVsZ`;L^^&fvS1Zl)#2JC#=i zO=smRTjH1TiLT(TgomtExiqJ$ghmzTwHEL4X|% zgk>I_UOg{$Z)kX=5N|%5)~)9ArOkbW0CH-f_m$yg_W3TMhEOduWz#Z}E?>M+d$1ei z=a2V*Z0$-T$hAR05#==| zm{b6^F1vH#->QkX7ipX;ujh3AWbpD9fXfz7$7%9BF~&n9^3L15j8UCX=P%+mX6S8OX=qPl`1HcXGw@Potcev%{8i4V=Tx9j{CMT|Ao-hm@9=h6KyOV9#~Cbg(HOy>wNh5j;CWqEW?S_9rS2fDA+U|2P<3gnZ9#aV;E5Wo z=!Lur^#^N+WN)v3!2ej{{M5kbgxp^tZdh{l4O^}wXYSDy;s>~Wsi%5kev}B zd!~%YN@iw8BvF#MvS;S+ystjr@8|dU{rc-(-S-)<`FxFY-d}q%(VrGszqYVvTdNQb z7o%TX`|+X@jrrD}gL)y{yey_((<`bC>yE~b1skc=#LT_&`zo3y7=J+3MRoQZ%S}Rq zh>QNbT=vU)rZ<$Pw~-X79^DB@OzPd>QZ=lvdxra%FefA%%`UJ)beO-&L4b&6NHV$` zxh4f1*hQGXzRA1THYk%z@y9(r@}8z><}!tYxT@FvL)|JH|^KgD_T&=Rqq?>PgkZQlWvlb>QiXZ zbV+hKTs#G<6EoXPxi(DW6@ryOfGFf;MkfcHN(rlur*r6IfeLaqBB!8w8JC7R3Adr+ z%9VbylB;l3&p0N`55g7||$8TyzI5}0(iRVxQG zXX&MJ(^|(Tt9M4nFLhSnp87oP5Q!lRiNKvbOM9Wl z2pVv7pE(sxiXR_05R)Aks3#PCtC!Dn+&wj9&**+(Uwk`_@ z1Wg2H9$11b)Jg`rT96DP#nnfghPR9FkJ{m7cvX$ijhzJF+fB6W6;wi(rC_S*T~7_; zwg>I>OC;iF=pYN~2^`p?d&&`DNhHX*_Iv*3S%ExpcWS8%-e8}3MwFB%-Eh3rS#t9| z3j>R(sf=}f%~)8hp7~$ms_25T)o?d;;EwtDszGe~nhkuU;Hbuf3W!4U6LbkyOYqQH z;z4>)={S}b(SE)|FhRUOf`9PKmw8Ty?@|KS^$CCEmUb-Aq81n(J%6}cv^P{?{!5}d zXAU7Ee5$F7?>6?>u_O2Yxx<^eFnEjh0bmvZ_V z%F3>YS!l_j6qfQY(?P?A{8GmTh4pDqhtKq14fi2r1iJEvi>Rltp_qZ7tc=A80>pCy zW*AEzKMPbT0ejUiv=GHn8al>Qe=7sMMMG~WMM7G(IKTAJ^5x6$Xo2htXbV<4 zi=fgMfqk0kAYt&DBh!Z@uir}L$s!Oh2asm4Qi*^*#!;?J{)cw2GNySyf3VFnq0QN? z?+6Pg(GqpXgclDM^jz|(5ongpVO9J1B28TJhyH~OB_(;@{_h-d3FCRsQQXk}rYmM~ zfU_BJx05+svKQbkY^*i=Ag^Hb(EO_~+>Lo_V`Im)qNz!W@^?=C9}J2ysH z=`;+5codjH-rLs~8Ydc_#7{zTxBv2GPcc8EjnjtxrKP21pDm=%P*Bufydn1W>o~bj zAXR?eyx<^6Qea*ck0`uCpS)WHSy;F@;1s7Zlt2k<;|R>hIeWPZ1H*6* zMkT*O({+;Z-P_Ri_Sai?xvgncE|0x+e#tViwY8Z@de7@|!Daea#SRGckIJjgKn)RG z&bRsOVXZVg3xwPUz@Pw<#%2A6Lbhu7M#7Qs(7o4fZ4Y_i!YiqjBp2w;;*~)u^wZ?h z_@aoo=qwr8Da-j04t3#Q#?~78cR2I9Lx%1q6!j?q!P`l4{aAOtdAXk!o-_w?tzn&u zDWa5ejxrW0YxQ13oD#BYMXM7YR37Q^K(06fpW(_{$C$zLlYmlG=Zu{N%F06`pC;va zWho2|^g@rh{u9}+4_vo)%rYg+&oq&XEXtXj_l{Cmef#N?rkDl)NHEz4ZEfuz_bd|G zd%mpIMOX{i2CtFtHGFDiD7_R+`!q0P<4M5YY;W5QZpBN$shu+WmGZjq7C8)$17 zj(f~S0Pgu8Qguh}h@G_IEepX?=_@1gp{MoPT**s$A9b^L= z$+kDDC1f}BvmC45&z}(l%MPo1B~l7Xp&_m2-%?M=$U^Xw1N@ z&mz%3WKVLD-bzHhd|%UgUM<%4DjOLuA0An}?qb+jTPYXs?v_4Pmt+aK9&)u4nmGe< zN&o}`?MV7HLP1G}_eH=nNZ>}jk4?uRKa! z;_XgXTPt%=&th?u@VAE0NdQ39jvKeO+21 z&DGamT0WMC5%$8lWLyD#TF@F7by{*jP8gdx0JpombOKmzH4**!d8MjpdNZJ-tBASh zA5?NY>$_KRggy6j#IOhv4CM2|9VKcaS+{8_#!g;lU(#F)HWyNv65qLIo0HAWNGAfY*0f&*4YT)yM^gUZ;qj@{jL02J7 z4+0@9RT&L1kP~YXz2Q5X;xDhT)+1j;~p@*UqGIvD~aYS_!!HY$szVj z0TeJzVdTTb9OfM>bY17!_M};PVd5QbWt5CJc#Rw?$w)T;67~cjdutA~1o`ChJg5g} zp)k$Ak%wT@QVR%PHoeONr;sZe#(NfE7gt z`2DIg?g|myN%^(I$|%pFY3jq3D@QWSo<>L2f;$)F64P2_SRG*E`EE}0jKt{)3-_uR z`G>#?V*j5NT)K407w-KHV~)~0M^YNfHhL()P;U-c{sXXlu(mBi=#gdWaKiAY{dmc) zKM^nKLD&neQU`uy11As&6MuSCZRX=2xFF_~wq}NDRBm$Rf8??4gjc#1_3_lp$&jVT z%#4f{_Y-RnAxZ!>tJdXE0OrbMex9(or-$dHsa8_Cqs|g+E3CwOq7z9nM>ha^v{B0@{u`-z$3c&4?VD)DLcP;{D403re`>r>UVN4h-=!_c_>SRLQF?|=c6K@Y~`ef zhcUiL#$7&1eik?`_;2M0OEa(ezsdl^Pxu2Wl_2j07TnimA(D-o4D8!NWA?)F+8xRSv}|Og z)8^#t?d^=xLMZb-Vd|JPc6vZZ(8U|NZhdAbZVbuhBH<@-bg^9lFX3i zfcGbcq1!Th1b{ivK-{@=$8+0YIwB-UY&E>Pre-g**g*dz_}vm$rmID3()W?;LDIky z4(HnwB6mHB91wtlgkZrAU@m3Yn=c7xWvThLkgw%SPkkTInASgW0#*ojyH)wM@?ttW z;GJ5a_C0d7gbgsCDx~m~)1VLv6g!AVIJOUy@`Mi$Pyq|S^m`20X7k_Xq6oHZ*OS3O z@RP-<$+QPU{;z+Xd4TRyi-&}g!aXm_@Ob%f~s6LkqdV&la{^( z6Dq-nXGgZ&!TimTf!h2<7&_)0$SvMh9cMg-q(P+w9!{0@(4c2>=aJl@LF4pzU0W(8 z_Ds?8YIVlgoDpB=?qW$JzuIxg>SHsL0ns9q(ky}EWl=U8VuUL(&t)=ubtVS1)-?^I zX@ap-h=S7M-r_||NHI;&=7SuLV3+^p5h?Iwt~Kcy8PRI~T{gZ*H-nfi9(#MZNz{F& zxb;7Xf~aEfJa{@SaQDIHFJk%C0_X{ksB`ow$Tnd!(BuQ{G^rXZaW>@mj~|trcH37v z!&t87?YAl-5-3QF)koT^1|!EM$iOw*1>0S^1SJO0)B5B@!-Rp=4ghgsv?Sju zPqpAm1aIB7RLcCE^yJTeN+!=4yKd=sw-g9R!iVb>kd|wBFyfc-3Pnw3-Ab~X7%)nMh2q#UIOZy zi|%&@{!;@1*Rs)j#7R?+Ne#ss8m1K&l_^|M`VjUaTM5Lc<7MMl!OT<|roF={7F55% zC2#*tM+ao*LG`DMYXXlrtFkZW7w*vehMs_b3*+buox_>i!mf7<$u2_o0ww7(tPJ2VS}VX4h`>3sEd@1E|8o;TH|LOa-i%etdjmU|fIvYshPFO8|)RPSO#aR3Tx7E!DLUeZJc&T{j5 zGLYeKQw=CH*UgWzZfwjC<@S(wga+OZwtHe1Um_?Q%q>E)`H4_WROVbxpv(mN?>omv zoIrR^>h|Exn>SfG>e(PpfrMa4CHRxAD{Tj>204t}rcm@kWykFqyrm2)>-W983ordl znS8r$z=0G{0qn#>>3J5w%@FlWlKZhMY_1_CP@8vcboAM#OTDeFayomjC?N;v==9*h zK#g=2cs*t=Co4bY<|iUSxIwloT!t^^6p$nuSSu}(ls9}NjAr20Rj zMq#Oo2SVDDLe|+e^!4ZK-qjhoYbW0DBG8cNt$*k=u|;qfl#eHkCy%F&Gm?Re-C~}F z?cOCim^+986@^^R&QnBm)2pw8t*Nc8)fnW`M9ipQyR$?MeIJ8#0F$%AT5hL*H?n}Q zP_59hVrI!jeBaa#MtCy9MXjDQEb@L8D9IhzPHFDocOl^UlHfFY4_Y!*E8y1pI`>OX z=T_@m4$*@|TSEuV$H%9nTXt4O#cXW+QzXSTF};11nmVxKB49k^7DJT*8|dQxSC`BD zgA}%-rGG~WC?F4`uXmbw^}gf$Cu)B+zh)?+tGZal)JCakD1+*H#Qc>mKJeVDk3~Xl za(xwm>6f8snIv2deDtIqi1%zjDNGwb{gvUv_obNUTm-3rq@>AGTdprDI28GNxv)`FOpev9z zh9bn3^tIMny(Px3hhn5rD&reA?194OcSc5NI|H&aSJ7f`09(V#(uW$wN9{ zLc0bhLhaYD2l+`0xO6~&ja=rJdIeGaiLmPoMmFQE30~1=U96dPOK-$=zZFvy@R^~) zsPU{xVY_BT(WF5>aF4Jkjo~7~2=Ch>N|B)hJ8=&@;YCG7M){>z20wqERp@A+X#URH zy&d}a-3*U?Q6xdn{hOV8S)DEe5GXMi!F81?+^{s(6oGjHdVJ%wrxNI3;ar)?XGXRL z2LpTV-|}@0;|L^6lgxUSWN~w3YWd{(>dMNiX3^G;Wj&R7^pPnjL0e{YsZP0ZdOEMz zGy|eFByiVYv$j<>Lg`Vg8Um95Bo$fe89{-^P!GJ$FPV#-q0?Zt9uNsvElzFn|%=W&tBNFgDqP!Q>Wu-38KtRlD)4W1@2cvQc}+3ph!-bTVf zPl}L}owsG7O}I&!fm@XQJd$XmZFC9JYc}eEe(rcvYTB=U1%j zPTHTNOF;~D6`Zf75+r1WNtM+H-I>M*hJF?m*Yb5|uo^0)2ZGmm#S@c%nq1grhD~~O z0CBA}>T>G$z&~S0M@Q}sR!sy=S|Hg76J5+3Yp1@bFM)fl;ne=*p%bI_7ap8{C$4jI z(zcj^f{p{ceF`P3)7JV-fGe}ny>DE+;+=&_tQ89k38kWABJz@fCsl^g$Jl(wv3^K& z*x{Un*I%>9U?(5uQ4i6|zf}vgaQSAoN68KxTx#lTJZC)0tQK!Bk}^GdQt|RxlFd@P z-$d(u4YJ;{e6fl|>z!)ypru~Ea)TpwRaROxn}ah`x@KByj>Fjs=^5n*x_jnl^IH6r~tdDd?A+MT^=Kd zC+@-Q7QAg=37U6XojrHXXLO4*O*wQMXKpWP#(4SQ+vI1mpDk$4Dg?F0iz0i9_d)DN zN>(7Jat)y8PW@{;;J^xw9#5BM@?c{6%3M0@W2NE)t0Y}mm{ea}_w+ZDEiu8XT zjo$HJlu_@<@8OlpU|VaZ?BD85TW#+;$K}(O5I7w+$2ex;cpS){htXEwpEajrrB57YhF z&O4_s@}Nm5rZ;c@p)94(l0N)C5YuE^AXXmdO|3Lz9OvfY`R$q-1B2SrleF+6~O6rizdu=xjM8Lq=u=#*|5YYqNE!bzw(;5axU zZxY<4{dxB}JpP2BrA%xc?&(Ao8fVkhHbNzZD(UVLf}*l_V3>E3l!VBQ3cKL zy?jk*$g3NFrhcZ<a?SKZ|{;?@OtZ z&2vGA>JmGQ>ZET8W!e>VJP!Q{%g?vXt4Kw9b!3w@RA%}QAORp52OOQ+>O7K!tm0f7`VOidI) zSX^}P6}>hXcouk!&z!6k*j3>Ta@FaU=W=8|w$=Tgwe6g2aPCB=Y%$CTTQTkn{6H!?0dFdlNfFCmo*x&D_QI6x4JT**T=%LcR z9AaQkF$diVQXU%Ku*6xu?EDWA{Ae*RV9PtB0_8{>Dq$)`q$U@rxa+T(PjXOkZ^U`B z8B*c?yxH!1wXXR)hllfUdk=Kp39IO}JZ^BXc%?2obxJ1ep$5IOkf(Oq4jYN$5xci{ z&ORP14IIv$srmlVpd1_;%C$zQfSlgj`s?&Stes(evxh!FyM<|4dGHu^6Ar8LGYDJ= zj!O>LgQ&j|)PHy+|H)Dt{v=AN}d7WmpD1_V@FJ~xE>5GWeH!YN;CVJ(2uteuR2`_;0 zSOJ&-@%D0PxiyYx-l3K10CZ8v^MD{k{EIVW@PCi9Lr0lx;Hit8>gzfG^;3jJc**{w z`@|+%D5$O{JedH=KY8@P*w|cfyV}_8mym4(q3a3QHnql7L30s-_jq6~Fz_}#=7>13 zfkSwoK)t-oPn8yE4Xh}27=d9#(E|GN5f28wK8&^opJmuIbPX5m76{1-)a1rg;Gic! zPS>agDlcwE5!i_X|H1-FGup)pf+@2oHSQdM+&_!zmCE24Ab`+HSjhnN)AmF2_O)id z?nHwOmJE(G4h6HWuK?kOL86HIpxz>VwdmJlcphi_O#a(Kt$;)d8MqZDz-W3r z*=b>2E#qF{)Byx!BcSD`2Iln^lxw|sOf=sR0e>02O8~wH5fzxk!T5%ueaO`{izzq+ zvWQ^$xvZIuYJQ9=D@j3;9Uw;(0aZ4}TCX#M$>`uki}NW?bc%`!AG0NBV8;YPp){uQ zByagK5z{IYp!AsFL!l)Jcq9zt>+N;=(Q{EuK!9>w0C(Z|0S#3cVQ9Ff@aYGlNI)`4 zWtSodWx6SCYEHO)*phSf_m`}+{EwJrUVsljD^%B-3WYX-BL^JF85aHpRtJPwOY5hB zLyE~aIU>Cw8K%}S&68B~V<5&(Jb*xPw}%p-5<(QV_#2imKi)cHWz)fWEMtM#Wccvo zLVm3m$AeRW!7(GE)<7R**jaUdg6v^P`?F)}fJ;TFWQQLMIC4s~=bQmT^b9QBZ6WkI zSQa?91bUiN`MAHWtUQQxQPcTH&%V=W!iV8!Am0t*3#cF7R^*l!@DT%u9b4hkr=6aU z*vMF_wh%>4Lk~uHGn*``rB{#x7T+2HhA%04(gP@?$u$5>WVVT9K7w^?xEF$i>9P=~th}0cC?IeTigKlTbW-?|Aj9VD(*9>R*VfuT0~8J!{+F z(-ZRW3>C;)K&*s{NAbJdo7zMWmIG2@Lkdw(2E#f!^JOUi z8@ziX6qk}iq(5kWS(HX%yKT9ZV*;w)FPtjR*eVGvFZL-VGrPyoUMS+cpZ4HAdv6=iN9kYH+P zZIOW?o}1TODYLFagw{&~NORm_hZLgudn9~Sp3Ko{8zj2l4{=Eo_Z}FCD0r%AD$7VY zei9mV11Qem`VU>`KS{YDCj^**s5f}<8iOEGi-d$!N89wJ<0cKpD9Pmo19z_{Gir6hJ;g!X?7MI0zkMC{T{ zhhd5*d7u^!DWIGCUn&5eJ%M+pEGQ}25GxH14u+c;pI3T#EQ6F9X4;!PRC2=|z*z%Y z#-yCk?e2*jgKQP>x*(OcOs#;Zr>D0h3N0}1(q`I7G{KOlLa0utg7fhC82RzfY2f9b zf_~U0p7@V1I7hO{Mo>YNq@KIE1!DZT|5AxgluebHr;9r?Gjp_RMkj)(5v{?2yJw+C z{tX`mhIgtTBcdo9_{^Gw&u%4yrF`nZ1){yigFY!qS-(?w?e5aMJRsKBxD43bhVFHS zsA?sh`R2_KsKLKNtI?H=fs6hEv4cpP+>4tR2{-;t@DxnoKQRVU;*b$2DlRg5_HE+q zmx&c{`@BZ9bT*MFr~nv&eOR}kUtd?It6Gk>2Z01DK z09T7_QjnK?R2Et-k#Ye!LOBSaR1$(GAkkWZ(>svjlVIFG~nb<^uVBZ5>cS8F_kF^JC=@3U_JDuWN$-E zgksrpJ!{vt%{#|H0&fLue5NEm*CYPhS?-&FPI`b&kA5lHK^q{ymH8owkVtXv+<6H{ zD&Qr6xOk!vyMdYNVTxs49MJbUFnqW_Q>-ksL4SAr5S`wAH#ZvkW1+bUtJ^9*H=rzZ zjJRl^HVJdDIDj}IWpndzuPp?pP(?-Q{zq1`<;{l6{z6Y3?>2J~S6Ba+4@|JS&+1=9OoPI9|A`nmIB}G-qN)T!Oh{g7%*ux*@;m-0c(phs z921IL9ah)AU{G$~Saxu{yb!2Mkg+TW!XLor0z7h9_@lEkEbVzJ`QkMUa8zKAxonyC z@5)x!P@hDI5#kB_3P_lRbR;Dl^Me(o5E>dfLDPb>c}_GrAZaz1T4sME2v^YsQdUrp zB=DpL>j|Lx5Ox!4&m zLs$1VI81t=CJZJ?KAvO_o&=|Sm$xt;eJqIJR@(@g$3lugxga~}{myIYHP+WNG6W{*{U%%Ls+puDDns<6L)ygJZc1YR>U z$q1kiMA`bQ7V86hr^pbE^z_z5TcB|bMqX58|L~ddJ9moX4P@?sJxBCEX9w;A0!$NS zJ`R$*nWaX}E)7}c$0&6H?7FgSr0%Ye_1$mRl!)pC9iU%R=!k~)4Qd7?yKeC}B_#fE za&o;)QF0-L*7_dq=J;8}VAL+Ci1RI*h8y@36?h7*Nnu5_Rpv+=9>s4CPotwDk!j() zMHFq;7%>v#cz5t*s

@dna)QatOVeaf5e^f}K?&hKGmWI;G`H3JCmYZ*R{|yzWBm z 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 + +[Helm](https://helm.sh/) is like a package manager for Kubernetes. Helm charts help define, install and upgrade your Kubernetes applications. + +In this guide you'll learn how to set up New Relic with the official [New Relic Helm charts](https://github.com/newrelic/helm-charts). +The Helm charts will deploy everything you need to get full observability of your Kubernetes environment. + + + +## Before you begin + +This walkthrough assumes you’ve already deployed a Kubernetes cluster. Or simply use our test environment, by following the interactive tutorial at the bottom of this page. + +To use this guide, you should have some basic knowledge of both New Relic and Kubernetes. To complete the full exercise, you’ll need to: + +- [Get your New Relic license key](https://docs.newrelic.com/docs/accounts/accounts-billing/account-setup/new-relic-license-key) +- Install [Helm 3](https://helm.sh/docs/intro/install/) + + + + +## Adding the New Relic Helm repository + +First, add the official [New Relic Helm repository](https://github.com/newrelic/helm-charts) + +```bash lineNumbers=false +helm repo add newrelic https://helm-charts.newrelic.com +``` +You should see something similar to the following: +```no-highlighting lineNumbers=false +"newrelic" has been added to your repositories +``` + + + + +## Install the New Relic Helm chart + +Follow the instructions to [get your New Relic license key](https://docs.newrelic.com/docs/accounts/accounts-billing/account-setup/new-relic-license-key) + +Replace `YOUR_NEW_RELIC_LICENSE_KEY` and `CLUSTER_NAME` before running the following command: +```bash lineNumbers=false +helm install newrelic-bundle newrelic/nri-bundle \ + --set global.licenseKey=YOUR_NEW_RELIC_LICENSE_KEY \ + --set global.cluster=CLUSTER_NAME \ + --namespace=default \ + --set newrelic-infrastructure.privileged=true \ + --set ksm.enabled=true \ + --set prometheus.enabled=true \ + --set kubeEvents.enabled=true \ + --set logging.enabled=true +``` +You should see something similar to the following: +```no-highlighting lineNumbers=false +NAME: newrelic-bundle +LAST DEPLOYED: Wed Aug 19 09:04:52 2020 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +TEST SUITE: None +``` + +Check if the New Relic agents have been deployed: +```no-highlighting lineNumbers=false +kubectl get daemonsets,pods +``` + +This should look similar to: +```no-highlighting lineNumbers=false +NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE +daemonset.apps/newrelic-bundle-newrelic-infrastructure 1 1 1 1 1 2m53s +daemonset.apps/newrelic-bundle-newrelic-logging 1 1 1 1 1 2m53s +NAME READY STATUS RESTARTS AGE +pod/newrelic-bundle-kube-state-metrics-69ff8cfb74-rgjc5 1/1 Running 0 2m53s +pod/newrelic-bundle-newrelic-infrastructure-z8ddb 1/1 Running 0 2m53s +pod/newrelic-bundle-newrelic-logging-wp22p 1/1 Running 0 2m53s +pod/newrelic-bundle-nri-kube-events-f9d5bb944-kcxxf 2/2 Running 0 2m53s +pod/newrelic-bundle-nri-metadata-injection-66d76c868b-xrcq8 1/1 Running 0 2m53s +pod/newrelic-bundle-nri-metadata-injection-job-rszw5 0/1 Completed 0 2m53s +pod/newrelic-bundle-nri-prometheus-569689b7cb-pnddg 1/1 Running 0 2m53s +``` + + + +## Use the New Relic Kubernetes cluster explorer + +Open the [Kubernetes cluster explorer in New Relic One](https://one.newrelic.com/launcher/k8s-cluster-explorer-nerdlet.cluster-explorer-launcher?pane=eyJuZXJkbGV0SWQiOiJrOHMtY2x1c3Rlci1leHBsb3Jlci1uZXJkbGV0Lms4cy1jbHVzdGVyLWxpc3QifQ==) + +You should see something like: + +![Launcher artifact with icon.png](../../images/kubernetes-helm-deployment/k8s-cluster-explorer.png) + +Want to know more? [Learn how to navigate the Kubernetes cluster explorer](https://docs.newrelic.com/docs/integrations/kubernetes-integration/understand-use-data/kubernetes-cluster-explorer) + + + + +## Try it out now + +We have a Kubernetes test cluster ready for you in 2 minutes. By following this on-line tutorial, you will learn how to deploy the New Relic Helm charts. + +**Some tips to use the on-line tutorial window:** + +- Accept the cookies, so you can see the menu bar. +- Click anywhere in the tutorial window to start. It will take about 2 minutes for your environment to be ready. +- Press CTRL-l or type `clear` to clear the terminal window +- Click on the finish flag icon in the bottom menu to hide or show the instructions + +Good luck! + + + +Some browsers automatically disable the use of iframes. If the module isn't loading +please check your browser settings. + + + + + +## What’s next? + +Nice work — now you can easily deploy New Relic with the official New Relic Helm charts and you can start using the Kubernetes cluster explorer. +The Kubernetes cluster explorer brings full observability to your k8s environment, so you can troubleshoot faster by correlating logs, metrics, events and traces all within the same user experience. From 61a22b08a9f59eac34732188d8a3ed60e2d22403 Mon Sep 17 00:00:00 2001 From: polfliet <45029322+polfliet@users.noreply.github.com> Date: Wed, 19 Aug 2020 19:57:48 +0200 Subject: [PATCH 05/25] Update src/markdown-pages/automate-workflows/kubernetes-helm-deployment.mdx Co-authored-by: John P Vajda --- .../automate-workflows/kubernetes-helm-deployment.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/markdown-pages/automate-workflows/kubernetes-helm-deployment.mdx b/src/markdown-pages/automate-workflows/kubernetes-helm-deployment.mdx index 7bce5de91..08edb05bb 100644 --- a/src/markdown-pages/automate-workflows/kubernetes-helm-deployment.mdx +++ b/src/markdown-pages/automate-workflows/kubernetes-helm-deployment.mdx @@ -27,7 +27,7 @@ The Helm charts will deploy everything you need to get full observability of you ## Before you begin -This walkthrough assumes you’ve already deployed a Kubernetes cluster. Or simply use our test environment, by following the interactive tutorial at the bottom of this page. +This walk through assumes you’ve already deployed a Kubernetes cluster. Or you can simply use our test environment, by following the interactive tutorial at the bottom of this page. To use this guide, you should have some basic knowledge of both New Relic and Kubernetes. To complete the full exercise, you’ll need to: From 0f3f144cebf0def9147c160385812e8a09b0f62f Mon Sep 17 00:00:00 2001 From: polfliet <45029322+polfliet@users.noreply.github.com> Date: Wed, 19 Aug 2020 19:58:15 +0200 Subject: [PATCH 06/25] Update src/markdown-pages/automate-workflows/kubernetes-helm-deployment.mdx Co-authored-by: John P Vajda --- .../automate-workflows/kubernetes-helm-deployment.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/markdown-pages/automate-workflows/kubernetes-helm-deployment.mdx b/src/markdown-pages/automate-workflows/kubernetes-helm-deployment.mdx index 08edb05bb..89048de8e 100644 --- a/src/markdown-pages/automate-workflows/kubernetes-helm-deployment.mdx +++ b/src/markdown-pages/automate-workflows/kubernetes-helm-deployment.mdx @@ -115,7 +115,7 @@ Want to know more? [Learn how to navigate the Kubernetes cluster explorer](https ## Try it out now -We have a Kubernetes test cluster ready for you in 2 minutes. By following this on-line tutorial, you will learn how to deploy the New Relic Helm charts. +We can have a Kubernetes test cluster ready for you in a few minutes. By following this on-line tutorial, you will learn how to deploy the New Relic Helm charts. **Some tips to use the on-line tutorial window:** From b0ca12bab28190169adede0a6fc3af26fd93b04d Mon Sep 17 00:00:00 2001 From: polfliet <45029322+polfliet@users.noreply.github.com> Date: Wed, 19 Aug 2020 19:58:57 +0200 Subject: [PATCH 07/25] Update src/markdown-pages/automate-workflows/kubernetes-helm-deployment.mdx Co-authored-by: John P Vajda --- .../automate-workflows/kubernetes-helm-deployment.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/markdown-pages/automate-workflows/kubernetes-helm-deployment.mdx b/src/markdown-pages/automate-workflows/kubernetes-helm-deployment.mdx index 89048de8e..4d5168930 100644 --- a/src/markdown-pages/automate-workflows/kubernetes-helm-deployment.mdx +++ b/src/markdown-pages/automate-workflows/kubernetes-helm-deployment.mdx @@ -120,7 +120,7 @@ We can have a Kubernetes test cluster ready for you in a few minutes. By followi **Some tips to use the on-line tutorial window:** - Accept the cookies, so you can see the menu bar. -- Click anywhere in the tutorial window to start. It will take about 2 minutes for your environment to be ready. +- Click anywhere in the tutorial window to start. It will take a few minutes for your environment to be ready. - Press CTRL-l or type `clear` to clear the terminal window - Click on the finish flag icon in the bottom menu to hide or show the instructions From 6201c59e161bd98ff4e8dd5ad2f67829ef9672e1 Mon Sep 17 00:00:00 2001 From: Stijn Polfliet Date: Wed, 19 Aug 2020 20:05:26 +0200 Subject: [PATCH 08/25] Update formatting of tutorials tips --- .../automate-workflows/kubernetes-helm-deployment.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/markdown-pages/automate-workflows/kubernetes-helm-deployment.mdx b/src/markdown-pages/automate-workflows/kubernetes-helm-deployment.mdx index 4d5168930..590234bc8 100644 --- a/src/markdown-pages/automate-workflows/kubernetes-helm-deployment.mdx +++ b/src/markdown-pages/automate-workflows/kubernetes-helm-deployment.mdx @@ -117,7 +117,7 @@ Want to know more? [Learn how to navigate the Kubernetes cluster explorer](https We can have a Kubernetes test cluster ready for you in a few minutes. By following this on-line tutorial, you will learn how to deploy the New Relic Helm charts. -**Some tips to use the on-line tutorial window:** +### Some tips to use the on-line tutorial window: - Accept the cookies, so you can see the menu bar. - Click anywhere in the tutorial window to start. It will take a few minutes for your environment to be ready. From e0a2716ecc7edc8a337e548f31ee8774df79d4d9 Mon Sep 17 00:00:00 2001 From: mmfred Date: Wed, 19 Aug 2020 14:11:34 -0700 Subject: [PATCH 09/25] little change part of sweep permission info. --- .../build-apps/build-hello-world-app.mdx | 2 +- .../get-started-nerdgraph-api-explorer.mdx | 2 +- src/markdown-pages/collect-data/query-data-nrql.mdx | 10 +++------- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/markdown-pages/build-apps/build-hello-world-app.mdx b/src/markdown-pages/build-apps/build-hello-world-app.mdx index b9225535b..c6c79e725 100644 --- a/src/markdown-pages/build-apps/build-hello-world-app.mdx +++ b/src/markdown-pages/build-apps/build-hello-world-app.mdx @@ -230,7 +230,7 @@ Return to the catalog and refresh the page to see your new screenshots and metad ## Subscribe accounts to your application -To make sure other users see your application in the catalog, you need to subscribe accounts to the application. Any user with the NerdPack Manager role can subscribe accounts to an application. +To make sure other users see your application in the catalog, you need to subscribe accounts to the application. Any user with the NerdPack manager or admin role can subscribe to an application from accounts that they have permission to manage. diff --git a/src/markdown-pages/collect-data/get-started-nerdgraph-api-explorer.mdx b/src/markdown-pages/collect-data/get-started-nerdgraph-api-explorer.mdx index b35f3f626..d99a790f4 100644 --- a/src/markdown-pages/collect-data/get-started-nerdgraph-api-explorer.mdx +++ b/src/markdown-pages/collect-data/get-started-nerdgraph-api-explorer.mdx @@ -120,7 +120,7 @@ Let's say that you've built a NerdGraph query you're happy with and you want to ![Tools menu](../../images/graphql-guide/tools-menu.png) ```bash lineNumbers=false -# cURL version +# curl version curl https://api.newrelic.com/graphql \ -H 'Content-Type: application/json' \ -H 'API-Key: API_KEY_REDACTED' \ diff --git a/src/markdown-pages/collect-data/query-data-nrql.mdx b/src/markdown-pages/collect-data/query-data-nrql.mdx index 515aaad87..2a3c52aa0 100644 --- a/src/markdown-pages/collect-data/query-data-nrql.mdx +++ b/src/markdown-pages/collect-data/query-data-nrql.mdx @@ -3,17 +3,17 @@ path: '/collect-data/query-data-nrql' duration: '10 min' title: 'Query data with NRQL' template: 'GuideTemplate' -description: 'Query default event data as well as custom events and attributes with our powerful, SQL-like query language. Start querying now.' +description: 'Query default data as well as custom events and attributes with our powerful, SQL-like query language. Start querying now.' tileShorthand: title: 'Query data with NRQL' - description: 'Query default event data, custom events, and attributes' + description: 'Query default data, custom events, and attributes' redirects: - /technology/nrql --- -With NRQL, you can query any of the default event data being reported by New Relic, plus any custom events and attributes you’ve added. +With NRQL, you can query any of the default data being reported by New Relic, plus any custom events and attributes you’ve added. @@ -92,10 +92,6 @@ Using NRQL, you can customize your New Relic experience by crafting diverse dash For an overview of NRQL syntax, see [Introduction to NRQL](https://docs.newrelic.com/docs/insights/nrql-new-relic-query-language/using-nrql/introduction-nrql). For a detailed description of all available functions, see [NRQL syntax, components, and functions](https://docs.newrelic.com/docs/insights/nrql-new-relic-query-language/nrql-resources/nrql-syntax-components-functions). -### NRU Tutorials - -To learn how to query and narrow a large data store by a specific parameter, watch the tutorial on [Filtering queries with NRQL](https://learn.newrelic.com/writing-nrql-queries). - ### Community forum Connect with other developers in the [our Explorers Hub](http://discuss.newrelic.com/tags/developer). From c31dfee8ba2d732bac94be55502dafbb8ee83a9e Mon Sep 17 00:00:00 2001 From: nr-opensource-bot Date: Wed, 19 Aug 2020 23:17:30 +0000 Subject: [PATCH 10/25] chore(release): 1.13.5 ## [1.13.5](https://github.com/newrelic/developer-website/compare/v1.13.4...v1.13.5) (2020-08-19) ### Bug Fixes * Fixed unused var error ([234600a](https://github.com/newrelic/developer-website/commit/234600a579d455c7e829d298068d9d1ebe3161f9)) * merge main into nerd-days branch ([e2c0edf](https://github.com/newrelic/developer-website/commit/e2c0edf4b588d4ba20ae171bac14bcadf2ece5e5)) * update nerd days page to use PageLayout ([e6636f4](https://github.com/newrelic/developer-website/commit/e6636f485dd10ce2534363cb03c4767055c3c319)) * update package-lock.json ([439de7d](https://github.com/newrelic/developer-website/commit/439de7d7e1fcc97837914e18ede7214ec9384d27)) --- CHANGELOG.md | 10 ++++++++++ package-lock.json | 2 +- package.json | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f582379f3..cf06e45d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## [1.13.5](https://github.com/newrelic/developer-website/compare/v1.13.4...v1.13.5) (2020-08-19) + + +### Bug Fixes + +* Fixed unused var error ([234600a](https://github.com/newrelic/developer-website/commit/234600a579d455c7e829d298068d9d1ebe3161f9)) +* merge main into nerd-days branch ([e2c0edf](https://github.com/newrelic/developer-website/commit/e2c0edf4b588d4ba20ae171bac14bcadf2ece5e5)) +* update nerd days page to use PageLayout ([e6636f4](https://github.com/newrelic/developer-website/commit/e6636f485dd10ce2534363cb03c4767055c3c319)) +* update package-lock.json ([439de7d](https://github.com/newrelic/developer-website/commit/439de7d7e1fcc97837914e18ede7214ec9384d27)) + ## [1.13.4](https://github.com/newrelic/developer-website/compare/v1.13.3...v1.13.4) (2020-08-19) diff --git a/package-lock.json b/package-lock.json index 0d49cdedf..3904e3921 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "developer-website", - "version": "1.13.4", + "version": "1.13.5", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 8d01a24aa..f4476b90c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "developer-website", "private": true, - "version": "1.13.4", + "version": "1.13.5", "dependencies": { "@emotion/core": "^10.0.28", "@emotion/styled": "^10.0.27", From bd436fd2d02bbfe1bef3c9b61397199eda66426f Mon Sep 17 00:00:00 2001 From: veextee Date: Wed, 19 Aug 2020 16:34:25 -0700 Subject: [PATCH 11/25] Update nerd-days.js copyediting updates --- src/pages/nerd-days.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/nerd-days.js b/src/pages/nerd-days.js index 8d6417b0c..ff17777fa 100644 --- a/src/pages/nerd-days.js +++ b/src/pages/nerd-days.js @@ -59,7 +59,7 @@ const NerdDaysPage = () => { alt="nerd days header" />

- Nerd Days is a FREE engineering conference that kicks off + Nerd Days is a FREE engineering conference that kicks off October 13 (Dates vary by region). Focused on building more perfect software, our goal is to spend less time looking at slides that tell you what software can do and more time on @@ -80,13 +80,13 @@ const NerdDaysPage = () => { Submit your proposals {' '} by September 1, 2021 at 11:59 PM PT. For more details, check out - the one-pager. proposals will contacted by September 30, 2021 at + the one-pager. proposals will contacted by September 30, 2020 at the latest.

-

REGISTER FOR THIS NERD DAYS

+

REGISTER FOR NERD DAYS

From 1a026fdc35b5b6c74c382350b699ba1efed9bb40 Mon Sep 17 00:00:00 2001 From: veextee Date: Wed, 19 Aug 2020 16:35:48 -0700 Subject: [PATCH 12/25] Update nerd-days.js changing dates from 2021 to 2020 --- src/pages/nerd-days.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/nerd-days.js b/src/pages/nerd-days.js index ff17777fa..bf1d57a39 100644 --- a/src/pages/nerd-days.js +++ b/src/pages/nerd-days.js @@ -79,7 +79,7 @@ const NerdDaysPage = () => { Submit your proposals {' '} - by September 1, 2021 at 11:59 PM PT. For more details, check out + by September 1, 2020 at 11:59 PM PT. For more details, check out the one-pager. proposals will contacted by September 30, 2020 at the latest.

From 7e823e50109d039dd8ac54e91f10fad34b3adead Mon Sep 17 00:00:00 2001 From: veextee Date: Wed, 19 Aug 2020 17:04:55 -0700 Subject: [PATCH 13/25] Update nerd-days.js --- src/pages/nerd-days.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/nerd-days.js b/src/pages/nerd-days.js index bf1d57a39..b1364bfc5 100644 --- a/src/pages/nerd-days.js +++ b/src/pages/nerd-days.js @@ -79,8 +79,7 @@ const NerdDaysPage = () => { Submit your proposals {' '} - by September 1, 2020 at 11:59 PM PT. For more details, check out - the one-pager. proposals will contacted by September 30, 2020 at + by September 1, 2020 at 11:59 PM PT. Accepted proposals will contacted by September 30, 2020 at the latest.

From c4043c76757bb3d492fcadbfb440f30c6fe3b713 Mon Sep 17 00:00:00 2001 From: nr-opensource-bot Date: Thu, 20 Aug 2020 00:45:35 +0000 Subject: [PATCH 14/25] chore(related-content): updated related content data --- src/data/related-pages.json | 7599 ++++++++++++++++++----------------- 1 file changed, 3837 insertions(+), 3762 deletions(-) diff --git a/src/data/related-pages.json b/src/data/related-pages.json index 70350c814..cb26efdaa 100644 --- a/src/data/related-pages.json +++ b/src/data/related-pages.json @@ -1,51 +1,86 @@ { - "/automate-workflows/5-mins-tag-resources": [ + "/automate-workflows/get-started-new-relic-cli": [ { - "body": "Get started with the New Relic CLI 20 min Access the New Relic platform from the comfort of your terminal: you can use the New Relic CLI to manage entity tags, define workloads, record deployment markers, and much more. Our CLI has been designed for automating common tasks in your DevOps workflow. This guide walks you through the essentials of New Relic CLI, from install and configuration to basic usage. Before you begin For this guide you just need: Your New Relic personal API Key, which you can create from the Account settings of your New Relic account An instrumented application in your New Relic account Step 1 of 10 Install the New Relic CLI The New Relic CLI can be downloaded via Homebrew (macOS), Scoop (Windows), and Snapcraft (Linux). You can also download pre-built binaries for all platforms, including .deb and .rpm packages, and our Windows x64 .msi installer. Linux With Snapcraft installed, run: sudo snap install newrelic-cli macOS With Homebrew installed, run: brew install newrelic-cli Windows With Scoop installed, run: scoop bucket add newrelic-cli https://github.com/newrelic/newrelic-cli.git scoop install newrelic-cli Step 2 of 10 Create your New Relic CLI profile Now that you've installed the New Relic CLI, it's time to create your first profile. Profiles contain credentials and settings that you can apply to any CLI command, which is useful when switching between accounts. To create your first CLI profile, run the profiles add command. Note that you need to set the region of your New Relic account: use -r to set either us or eu (this is required). # Create the tutorial account for the US region newrelic profiles add -n tutorial --apiKey YOUR_NEW_RELIC_API_KEY -r YOUR_REGION # Set the profile as defaults newrelic profiles default -n tutorial Copy Step 3 of 10 Get your application details In this example, you are going to add tags to the application you've instrumented with New Relic. Tags are key-value pairs that can help you organize and filter your entities. An entity (for example, an application) can have a maximum of 100 key-value pairs tied to it. Before searching for your application using the New Relic CLI, write down or copy your Account ID and the name of your application in New Relic - you need both to find applications in the New Relic platform. Step 4 of 10 The New Relic CLI can retrieve your application details as a JSON object. To search for your APM application use the apm application search command. If you get an error, check that the account ID and application name you provided are correct. newrelic apm application search --accountId YOUR_ACCOUNT_ID --name NAME_OF_YOUR_APP Copy Step 5 of 10 If the account ID is valid, and the application name exists in your account, apm application search yields data similar to this example. When you've successfully searched for your application, look for the guid value. It's a unique identifier for your application. You should copy it or write it down. [ { accountId: YOUR_ACCOUNT_ID, applicationId: YOUR_APP_ID, domain: 'APM', entityType: 'APM_APPLICATION_ENTITY', guid: 'A_LONG_GUID', name: 'NAME_OF_YOUR_APP', permalink: 'https://one.newrelic.com/redirect/entity/A_LONG_GUID', reporting: true, type: 'APPLICATION', }, ]; Copy Step 6 of 10 Add a simple tag to your application Now that you have the GUID, you can point the New Relic CLI directly at your application. Adding a tag is the simplest way to try out the CLI capabilities (don't worry, tags can be deleted by using entity tags delete). Let's suppose that you want to add an environment tag to your application. Go ahead and add the dev:testing tag⁠ (or any other key-value pair) to your application using the entities tags create command. newrelic entity tags create --guid YOUR_APP_GUID --tag devkit:testing Copy Step 7 of 10 What if you want to add multiple tags? Tag sets come to the rescue! While tags are key-value pairs separated by colons, tag sets are comma separated lists of tags. For example: tag1:value1,tag2:value2 To add multiple tags at once to your application, modify and run the following snippet. newrelic entity tags create --guid YOUR_APP_GUID --tag tag1:test,tag2:test Copy Adding tags is an asynchronous operation: this means it could take a while for the tags to get created. Step 8 of 10 You've created and added some tags to your application, but how do you know they're there? You need to retrieve your application's tags. To retrieve your application's tags, use the entity tags get command. newrelic entity tags get --guid YOUR_APP_GUID All tags associated with your application are retrieved as a JSON array. [ { Key: 'tag1', Values: ['true'], }, { Key: 'tag2', Values: ['test'], }, { Key: 'tag3', Values: ['testing'], }, // ... ]; Copy Step 9 of 10 Bonus step: Create a deployment marker Deployments of applications often go wrong. Deployment markers are labels that, when attached to your application data, help you track deployments and troubleshoot what happened. To create a deployment marker, run the apm deployment create command using the same Application ID from your earlier search. newrelic apm deployment create --applicationId YOUR_APP_ID --revision $(git describe --tags --always) Copy Step 10 of 10 Notice that the JSON response includes the revision and timestamp of the deployment. This workflow could be built into a continuous integration or continuous deployment (CI/CD) system to help indicate changes in your application's behavior after deployments. Here is an example. { \"id\": 37075986, \"links\": { \"application\": 204261368 }, \"revision\": \"v1.2.4\", \"timestamp\": \"2020-03-04T15:11:44-08:00\", \"user\": \"Developer Toolkit Test Account\" } Copy Next steps Have a look at all the available commands. For example, you could create a New Relic workflow using workload create If you'd like to engage with other community members, visit our New Relic Explorers Hub page. We welcome feature requests or bug reports on GitHub.", + "body": "Quickly tag a set of resources 5 min Tags help you group, search, filter, and focus the data about your entities, which can be anything from applications to hosts to services. Tagging entities using the New Relic CLI is a good candidate for automation. In this 5-minute guide, you use the New Relic CLI to add multiple tags to one of your entities. Before you begin For this guide you need your New Relic personal API Key: Create it at the Account settings screen for your account. Step 1 of 6 Install the New Relic CLI You can download the New Relic CLI via Homebrew (macOS), Scoop (Windows), and Snapcraft (Linux). You can also download pre-built binaries for all platforms, including .deb and .rpm packages, and our Windows x64 .msi installer. Linux With Snapcraft installed, run: sudo snap install newrelic-cli macOS With Homebrew installed, run: brew install newrelic-cli Windows With Scoop installed, run: scoop bucket add newrelic-cli https://github.com/newrelic/newrelic-cli.git scoop install newrelic-cli Step 2 of 6 Create your New Relic CLI profile New Relic CLI profiles contain credentials and settings that you can apply to any CLI command. To create your first CLI profile, run the profiles add command. Don't forget to set the region of your New Relic account: use -r to set either us or eu (this is required). # Create the tutorial account for the US region newrelic profiles add -n tutorial --apiKey API_KEY -r us # Set the profile as default newrelic profiles default -n tutorial Copy Step 3 of 6 Search for an entity Your New Relic account might have hundreds of entities: Have a quick look by opening the Entity explorer. In the terminal, run entity search to retrieve a list of entities from your account as JSON. In the example, you're searching for all entities with \"test\" in their name. # Change the `name` to match any of your existing entities newrelic entity search --name \"test\" Copy Step 4 of 6 If there are matching entities in your account, the query yields data in JSON format, similar to this workload example. Select an entity from the results and look for its guid value; the guid is the unique identifier of the entity. Write it down. { \"accountId\": 123456789, \"domain\": \"NR1\", \"entityType\": \"WORKLOAD_ENTITY\", \"guid\": \"F7B7AE59FDED4204B846FB08423DB18E\", \"name\": \"Test workload\", \"reporting\": true, \"type\": \"WORKLOAD\" }, Copy Step 5 of 6 Add tags and tag lists to your entity With your entity guid, you can add tags right away. You can do so by invoking the entities tags create command. What if you want to add multiple tags? You can use tag sets for that: While tags are key-value pairs separated by colons, tag sets are comma-separated lists of tags. For example: tag1:value1,tag2:value2 Note Adding tags is an asynchronous operation: it could take a little while for the tags to get created. # Adding a single tag newrelic entity tags create --guid GUID --tag key:value # Adding multiple tags newrelic entity tags create --guid GUID --tag tag1:test,tag2:test Copy Step 6 of 6 Check that the tags are there To make sure that the tags have been added to your entities, retrieve them using the entity tags get command. All tags associated with your entity are retrieved as a JSON array. newrelic entity tags get --guid GUID Tip Tags can be deleted at any time by invoking the entity tags delete command followed by the same arguments you used to create them. [ { Key: 'tag1', Values: ['true'], }, { Key: 'tag2', Values: ['test'], }, { Key: 'tag3', Values: ['testing'], }, // ... ]; Copy Next steps Have a look at all the New Relic CLI commands. For example, you could create a New Relic workflow using workload create. If you'd like to engage with other community members, visit our New Relic Explorers Hub page. We welcome feature requests or bug reports on GitHub.", "type": "developer", "document_type": "page", - "info": "Learn the essentials of the New Relic CLI, from install and configuration to basic usage.", + "info": "Add tags to applications you instrument for easier filtering and organization.", "sections": [ - "Get started with the New Relic CLI", + "Quickly tag a set of resources", "Before you begin", "Install the New Relic CLI", "Linux", "macOS", "Windows", "Create your New Relic CLI profile", - "Get your application details", - "Add a simple tag to your application", - "Bonus step: Create a deployment marker", + "Search for an entity", + "Add tags and tag lists to your entity", + "Note", + "Check that the tags are there", + "Tip", "Next steps" ], - "title": "Get started with the New Relic CLI", + "title": "Quickly tag a set of resources", "popularity": 1, "tags": [ - "api key", - "New Relic CLI", - "Tags", - "Entity", - "Deployment markers" + "tags", + "new relic CLI" ], - "external_id": "531f2f3985bf64bb0dc92a642445887095048882", + "external_id": "c7c374812f8295e409a9b06d552de51ceefc666b", "image": "", - "url": "https://developer.newrelic.com/automate-workflows/get-started-new-relic-cli/", - "published_at": "2020-08-18T02:06:05Z", - "updated_at": "2020-08-08T01:41:47Z", + "url": "https://developer.newrelic.com/automate-workflows/5-mins-tag-resources/", + "published_at": "2020-08-19T01:44:48Z", + "updated_at": "2020-08-14T01:45:08Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 19.977236, + "_score": 17.596947, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Get started with the New Relic CLI", - "sections": "Get started with the New Relic CLI", - "info": "Learn the essentials of the New Relic CLI, from install and configuration to basic usage.", - "tags": "New Relic CLI", - "body": " Now that you have the GUID, you can point the New Relic CLI directly at your application. Adding a tag is the simplest way to try out the CLI capabilities (don't worry, tags can be deleted by using entity tags delete). Let's suppose that you want to add an environment tag to your application. Go ahead" + "title": "Quickly tag a set of resources", + "sections": "Install the New Relic CLI", + "info": "Add tags to applications you instrument for easier filtering and organization.", + "tags": "new relic CLI", + "body": " by invoking the entity tags delete command followed by the same arguments you used to create them. [ { Key: 'tag1', Values: ['true'], }, { Key: 'tag2', Values: ['test'], }, { Key: 'tag3', Values: ['testing'], }, // ... ]; Copy Next steps Have a look at all the New Relic CLI commands. For example" }, - "id": "5efa999c196a67c4e1766461" + "id": "5efa999d64441fa74a5f7e2d" + }, + { + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app, you might have some additional setup and configuration. This guide covers: Downloading the New Relic One CLI to build or modify apps Contribute content to this website Before you begin You must have: A github account account - While not strictly necessary for building apps, a GitHub account enables you to download and customize our open source apps, and contribute an open source project. A New Relic developer account - if you don't already have one, you can get a free trial account for developing New Relic applications. npm - If you've installed Node.js, then you already have npm, which is used to share, reuse, and update JavaScript code, and is necessary for working with React components that are the framework for New Relic apps and this website. Tip Use the New Relic One VSCode extension to build your apps. Prepare to build or modify apps Step 1 of 2 Download the CLI and API key On the Build New Relic One applications page, complete the Quick start steps. These six Quick start steps get you an API key for use with developing apps, and the New Relic One CLI, for building and deploying apps. At the end of the Quick start, you have a project consisting of the following: A Nerdpack - The package containing all the files required by your application. It contains two types of files that you customize to build your app: Nerdlets, and the launcher. One or more Nerdlet files - A specific UI view or window. A Nerdlet is a React JavaScript package that includes an index.js file, a stylesheet, and a JSON-format config file. It can contain any JS functionality (charts, interactive fields, tooltips, etc.). A launcher file: This is the basis for the launcher, which is used to open your application from New Relic One after you publish your app. Step 2 of 2 Start building If you're ready to code, cd to your Nerdpack and get started. If you want to learn more about building applications, try these step-by-step guides: Build a \"Hello, World!\" application shows how to create a little application, publish it to New Relic One, and share it with others by subscribing accounts to it. Map pageviews by region takes you through the steps to create one of our popular open source apps. You learn to add a custom query to an app and view it in a table, then add that data to a map. Contributing to developer.newrelic.com This site is open source, and we want your input. Create a pull request if you see a mistake you know how to fix. Drop us a GitHub issue if you see some content gaps you want us to work on. Or write up a whole new guide if you have one you'd like to share. Read on to learn how. Step 1 of 3 Fork the developer-website GithHub repo Forking the repo enables you to work on your own copy of the developer.newrelic.com files, and build the site locally. It also enables us to more easily manage incomimg pull requests. On the developer-website page in GitHub, select the Fork button on the top right of the page, choose the account you want to fork to, and wait a few seconds while the fork is created. Sync regularly to keep your fork up to date with changes and additions to the main branch upstream. Step 2 of 3 Make a feature or documentation request On any page, select the GitHub button at the top of the page, and then select the kind of change you want, and fill out the GitHub form. Step 3 of 3 Contribute a new guide Check out our contributors guidelines, which will walk you through the process.", + "type": "developer", + "document_type": "page", + "info": "Prepare to build apps and contribute to this site", + "sections": [ + "Set up your development environment", + "Before you begin", + "Tip", + "Prepare to build or modify apps", + "Start building" + ], + "title": "Set up your development environment", + "popularity": 1, + "tags": [ + "developer account", + "API key", + "New Relic One CLI" + ], + "external_id": "c45638a9cd548d1ffffc9f1c7708f115a92ae04a", + "image": "", + "url": "https://developer.newrelic.com/build-apps/set-up-dev-env/", + "published_at": "2020-08-19T01:44:48Z", + "updated_at": "2020-08-19T01:44:47Z", + "_index": "520d1d5d14cc8a32e600034b", + "_type": "520d1d5d14cc8a32e600034c", + "_score": 8.060457, + "_version": null, + "_explanation": null, + "sort": null, + "highlight": { + "tags": "New Relic One CLI", + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app" + }, + "id": "5efa9973e7b9d242237bab39" }, { "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs in GitHub. Options --format string output text format [YAML, JSON, Text] (default \"JSON\") -h, --help help for newrelic --plain output compact text Copy Commands newrelic apm - Interact with New Relic APM newrelic completion - Generates shell completion functions newrelic config - Manage the configuration of the New Relic CLI newrelic documentation - Generate CLI documentation newrelic entity - Interact with New Relic entities newrelic nerdgraph - Execute GraphQL requests to the NerdGraph API newrelic nerdstorage - Read, write, and delete NerdStorage documents and collections. newrelic nrql - Commands for interacting with the New Relic Database newrelic profile - Manage the authentication profiles for this tool newrelic version - Show the version of the New Relic CLI newrelic workload - Interact with New Relic One workloads", @@ -64,148 +99,145 @@ "external_id": "471ed214caaf80c70e14903ec71411e2a1c03888", "image": "", "url": "https://developer.newrelic.com/explore-docs/newrelic-cli/", - "published_at": "2020-08-18T02:11:50Z", + "published_at": "2020-08-19T01:49:36Z", "updated_at": "2020-08-14T01:47:12Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 16.580233, + "_score": 7.599472, "_version": null, "_explanation": null, "sort": null, "highlight": { "title": "New Relic CLI Reference", "sections": "New Relic CLI Reference", - "info": "The command line tools for performing tasks against New Relic APIs", + "info": "The command line tools for performing tasks against New Relic APIs", "tags": "new relic cli", - "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs" + "body": " the configuration of the New Relic CLI newrelic documentation - Generate CLI documentation newrelic entity - Interact with New Relic entities newrelic nerdgraph - Execute GraphQL requests to the NerdGraph API newrelic nerdstorage - Read, write, and delete NerdStorage documents and collections. newrelic nrql" }, "id": "5efa989ee7b9d2024b7bab97" }, { - "body": "Automate workflows When building today's complex systems, you want an easy, predictable way to verify that your configuration is defined as expected. This concept, Observability as Code, is brought to life through a collection of New Relic-supported orchestration tools, including Terraform, AWS CloudFormation, and a command-line interface. These tools enable you to integrate New Relic into your existing workflows, easing adoption, accelerating deployment, and returning focus to your main job — getting stuff done. In addition to our Terraform and CLI guides below, find more automation solutions in our Developer Toolkit. Guides to automate workflows 5 min Quickly tag resources Add tags to apps for easy filtering 20 min Automate common tasks Use the New Relic CLI to tag apps and create deployment markers 20 min Set up New Relic using the Kubernetes operator Learn how to provision New Relic resources using the Kubernetes operator 20 min Set up New Relic using Terraform Learn how to provision New Relic resources using Terraform", + "body": "Nerdpack file structure A New Relic One application is represented by a Nerdpack folder, which can include one or more Nerdlet files, and (optionally) one or more launcher files. Here we explain: The file structure for a Nerdpack, a Nerdlet, and a launcher How to link a launcher file to a Nerdlet How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create a Nerdpack template that includes a Nerdlet and a launcher. Generate Nerdlet or launcher individually: Use the New Relic One CLI command nr1 create and choose either Nerdlet or launcher. This can be useful when adding Nerdlets to an existing Nerdpack. For documentation on generating and connecting Nerdpack components, see our app building guides and the New Relic One CLI command reference. Nerdpack file structure When you generate a Nerdpack template using the nr1 create command, it has the following file structure: my-nerdlet ├── README.md ├── launchers │   └── my-nerdlet-launcher │   ├── icon.png │   └── nr1.json ├── nerdlets │   └── my-nerdlet-nerdlet │   ├── index.js │   ├── nr1.json │   └── styles.scss ├── node_modules │   ├── js-tokens │   ├── loose-envify │   ├── object-assign │   ├── prop-types │   ├── react │   ├── react-dom │   ├── react-is │   └── scheduler ├── nr1.json ├── package-lock.json └── package.json Copy Nerdlet file structure A Nerdpack can contain one or more Nerdlets. A Nerdlet folder starts out with three default files, index.js, nr1.json, and styles.scss. Here is what the default files look like after being generated using the nr1 create command: index.js The JavaScript code of the Nerdlet. import React from 'react'; export default class MyAwesomeNerdpack extends React.Component { render() { return

Hello, my-awesome-nerdpack Nerdlet!

; } } Copy nr1.json The Nerdlet configuration file. { \"schemaType\": \"NERDLET\", \"id\": \"my-awesome-nerdpack-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\" } Copy Besides using the launcher as the access point for your application, you can also associate the application with a monitored entity to get it to appear in the entity explorer. To do this, add two additional fields to the config file of the first-launched Nerdlet: entities and actionCategory. In the following example, the Nerdlet has been associated with all Browser-monitored applications and will appear under the Monitor UI category : { \"schemaType\": \"NERDLET\", \"id\": \"my-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"Custom Data\", \"entities\": [{ \"domain\": \"BROWSER\", \"type\": \"APPLICATION\" }], \"actionCategory\": \"monitor\" } Copy To see this application in the UI, you would go to the entity explorer, select Browser applications, and select a monitored application. styles.scss An empty SCSS file for styling your application. icon.png The launcher icon that appears on the Apps page in New Relic One when an application is deployed. Launcher file structure Launchers have their own file structure. Note that: A launcher is not required; as an alternative to using a launcher, you can associate your application with a monitored entity. An application can have more than one launcher, which might be desired for an application with multiple Nerdlets. After generating a launcher using the nr1 create command, its folder contains two files: nr1.json The configuration file. { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy To connect a launcher to a Nerdlet, the rootNerdletId must match the id in the launched Nerdlet's nr1.json config file. For Nerdpacks with multiple Nerdlets, this needs to be done only for the first-launched Nerdlet. icon.png The icon displayed on the launcher for the app on the Apps page.", "type": "developer", "document_type": "page", - "info": "", + "info": "An overview of the Nerdpack File Structure", "sections": [ - "Automate workflows", - "Guides to automate workflows", - "Quickly tag resources", - "Automate common tasks", - "Set up New Relic using the Kubernetes operator", - "Set up New Relic using Terraform" + "Nerdpack file structure", + "Generate Nerdpack components", + "Nerdlet file structure", + "index.js", + "nr1.json", + "styles.scss", + "icon.png", + "Launcher file structure" ], - "title": "Automate workflows", + "title": "Nerdpack file structure", "popularity": 1, - "external_id": "d4f408f077ed950dc359ad44829e9cfbd2ca4871", + "tags": [ + "New Relic One CLI", + "nerdpack", + "file structure", + "nerdlets", + "launchers" + ], + "external_id": "c97bcbb0a2b3d32ac93b5b379a1933e7b4e00161", "image": "", - "url": "https://developer.newrelic.com/automate-workflows/", - "published_at": "2020-08-18T02:04:53Z", - "updated_at": "2020-08-17T01:55:15Z", + "url": "https://developer.newrelic.com/explore-docs/nerdpack-file-structure/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:49:25Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.37249726, + "_score": 3.3742404, "_version": null, "_explanation": null, "sort": null, "highlight": { - "sections": "Set up New Relic using the Kubernetes operator", - "body": " solutions in our Developer Toolkit. Guides to automate workflows 5 min Quickly tag resources Add tags to apps for easy filtering 20 min Automate common tasks Use the New Relic CLI to tag apps and create deployment markers 20 min Set up New Relic using the Kubernetes operator Learn how to provision New Relic resources using the Kubernetes operator 20 min Set up New Relic using Terraform Learn how to provision New Relic resources using Terraform" + "tags": "New Relic One CLI", + "body": " How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create" }, - "id": "5efa999c196a67dfb4766445" + "id": "5efa989e196a671300766404" }, { - "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build your own application launcher and follow the quick start instructions. The quick start automatically generates an API key for the account you select, and gives you the pre-populated commands to create a profile, generate your first \"Hello World\" app, and serve it locally. Tip Use the NR1 VS Code extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions. For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). Configure your CLI preferences nr1 config:set Sets a specific configuration value. nr1 config:get Shows a specific configuration. nr1 config:list Lists your configuration choices. nr1 config:delete Removes the value of a specific configuration. Set up your Nerdpacks nr1 nerdpack:clone Clones an open source Nerdpack from our GitHub repository. nr1 nerdpack:serve Serves your Nerdpack for testing and development purposes. nr1 nerdpack:uuid Shows or regenerates the UUID of a Nerdpack. nr1 nerdpack:publish Publishes your Nerdpack to New Relic. nr1 nerdpack:deploy Deploys a Nerdpack version to a specific channel. nr1 nerdpack:undeploy Undeploys a Nerdpack version from a specific channel. Manage your Nerdpack subscriptions nr1 subscription:set Subscribes your account to a Nerdpack and channel. nr1 subscription:list Lists all the Nerdpacks your account is subscribed to. nr1 subscription:unset Unsubscribes your account from a Nerdpack. Install and manage plugins nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin into the CLI for development. nr1 plugins:update Updates your installed plugins. nr1 plugins:uninstall Removes a plugin from the CLI. Manage catalog information nr1 catalog:info Shows the Nerdpack info stored in the catalog. nr1 catalog:submit Gathers and submits the catalog info on the current folder.", + "body": "Automate workflows When building today's complex systems, you want an easy, predictable way to verify that your configuration is defined as expected. This concept, Observability as Code, is brought to life through a collection of New Relic-supported orchestration tools, including Terraform, AWS CloudFormation, and a command-line interface. These tools enable you to integrate New Relic into your existing workflows, easing adoption, accelerating deployment, and returning focus to your main job — getting stuff done. In addition to our Terraform and CLI guides below, find more automation solutions in our Developer Toolkit. Guides to automate workflows 5 min Quickly tag resources Add tags to apps for easy filtering 20 min Set up New Relic using the Kubernetes operator Learn how to provision New Relic resources using the Kubernetes operator 20 min Automate common tasks Use the New Relic CLI to tag apps and create deployment markers 20 min Set up New Relic using Terraform Learn how to provision New Relic resources using Terraform", "type": "developer", "document_type": "page", - "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", + "info": "", "sections": [ - "New Relic One CLI reference", - "Installing the New Relic One CLI", - "Tip", - "New Relic One CLI Commands", - "Get started", - "Configure your CLI preferences", - "Set up your Nerdpacks", - "Manage your Nerdpack subscriptions", - "Install and manage plugins", - "Manage catalog information" + "Automate workflows", + "Guides to automate workflows", + "Quickly tag resources", + "Set up New Relic using the Kubernetes operator", + "Automate common tasks", + "Set up New Relic using Terraform" ], - "title": "New Relic One CLI reference", + "title": "Automate workflows", "popularity": 1, - "tags": [ - "New Relic One app", - "nerdpack commands" - ], - "external_id": "858339a44ead21c83257778ce60b4c352cd30d3b", - "image": "https://developer.newrelic.com/static/2c6d337608b38a3312b4fc740afe6167/7272b/developercenter.png", - "url": "https://developer.newrelic.com/explore-docs/nr1-cli/", - "published_at": "2020-08-18T02:07:10Z", - "updated_at": "2020-08-18T01:50:36Z", + "external_id": "d4f408f077ed950dc359ad44829e9cfbd2ca4871", + "image": "", + "url": "https://developer.newrelic.com/automate-workflows/", + "published_at": "2020-08-19T01:44:47Z", + "updated_at": "2020-08-19T01:44:47Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.25086987, + "_score": 0.3776448, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic One CLI reference", - "sections": "New Relic One CLI reference", - "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", - "tags": "New Relic One app", - "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use" + "sections": "Set up New Relic using the Kubernetes operator", + "body": " solutions in our Developer Toolkit. Guides to automate workflows 5 min Quickly tag resources Add tags to apps for easy filtering 20 min Set up New Relic using the Kubernetes operator Learn how to provision New Relic resources using the Kubernetes operator 20 min Automate common tasks Use the New Relic CLI to tag apps and create deployment markers 20 min Set up New Relic using Terraform Learn how to provision New Relic resources using Terraform" }, - "id": "5efa989e28ccbc535a307dd0" - }, + "id": "5efa999c196a67dfb4766445" + } + ], + "/terms": [ { - "body": "Contain the complexity - Observability made simple New Relic’s Kubernetes cluster explorer empowers Kubernetes nerds to move beyond infrastructure metrics and investigate deeper into applications, traces, logs, and events—with a single click—while staying grounded in a centralized UI. Join us at KubeCon and CloudNativeCon Europe August 17-20 to learn more. Check out the complete schedule of New Relic talks to make the most of your KubeCon experience. Learn more. Get coding Create a free account 5 min Create custom events Define, visualize, and get alerts on the data you want using custom events Start the guide 7 min Add tags to apps Add tags to applications you instrument for easier filtering and organization Start the guide 12 min Build a Hello, World! app Build a Hello, World! app and publish it to your local New Relic One Catalog Start the guide Get inspired 30 min Add a table to your app Add a table to your New Relic One app 15 min Collect data - any source APIs, agents, OS emitters - get any data 20 min Automate common tasks Use the New Relic CLI to tag apps and create deployment markers 30 min Create a custom map view Build an app to show page view data on a map 20 min Add a time picker to your app Add a time picker to a sample application   Add custom attributes Use custom attributes for deeper analysis Show 18 more guides Looking for more inspiration? Check out the open source projects built by the New Relic community. New Relic developer champions New Relic Champions are solving big problems using New Relic as their linchpin and are recognized as experts and leaders in the New Relic technical community. Nominate a developer champion Learn more about developer champions New Relic Podcasts We like to talk, especially to developers about developer things. Join us for conversations on open source, observability, software design and industry news. Listen", + "body": "Set up New Relic using the Kubernetes operator 20 min Kubernetes is an open-source system for automating deployment, scaling, and management of containerized applications. You can use it to provision all kinds of infrastructure and services, including New Relic entities. In this guide you'll learn how to set up New Relic for the first time with the official New Relic Kubernetes operator. More specifically, you'll provision an alert policy with NRQL conditions in your New Relic account using Kubernetes. Before you begin This walkthrough assumes you’ve already deployed a Kubernetes cluster. You could even create a local cluster on your machine with kind. To use this guide, you should have some basic knowledge of both New Relic and Kubernetes. To complete the full exercise, you’ll need to: Deploy a New Relic agent if you haven't done so yet. Install New Relic for your application. Install kubectl and point it at the correct cluster; this determines the cluster where you’ll install the New Relic operator. Install kustomize. Step 1 of 3 Installing the operator on your Kubernetes cluster First, install cert-manager, which automatically provisions and manages TLS certificates in Kubernetes. kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.15.0/cert-manager.yaml Copy Next, install the Kubernetes operator. kustomize build https://github.com/newrelic/newrelic-kubernetes-operator/config/default | kubectl apply -f - Copy To confirm the installation was successful, run a few kubectl commands to check the status of the Kubernetes operator. Ensure the Kubernetes operator's namespace, newrelic-kubernetes-operator-system, has been applied: kubectl get namespaces Copy The output should be similar to the following, which includes the Kubernetes operator's namespace, newrelic-kubernetes-operator-system: NAME STATUS AGE cert-manager Active 4m35s default Active 20m kube-node-lease Active 20m kube-public Active 20m kube-system Active 20m newrelic-kubernetes-operator-system Active 3m48s Copy Now, make sure the Kubernetes operator's controller manager is running: Note: Don't forget to include the --namespace (shorthand -n) option when running kubectl get pods to ensure you're inspecting resources within the correct namespace. kubectl get pods --namespace newrelic-kubernetes-operator-system Copy You should see output similar to the following: NAME READY STATUS RESTARTS AGE newrelic-kubernetes-operator-controller-manager-7b9c64f58crwg9j 2/2 Running 0 157m Copy If your output is similar to the example shown, you’re ready for the next step. If you don’t see a pod named newrelic-kubernetes-operator-controller-manager-, double check your Kubernetes configuration to ensure you’re within the correct context and pointing to the correct cluster. Step 2 of 3 Creating your first alert policy To kick things off, start small. First, create an alert policy with the minimum required configuration, then add a NRQL alert condition to the policy, which will add the condition to the policy in New Relic. A minimal alert policy configuration is represented in the code below. For the sake of this walkthrough, name this file new_relic_alert_policy.yaml. Note: For help locating your personal API key, check out New Relic's personal API key documentation. apiVersion: nr.k8s.newrelic.com/v1 kind: AlertsPolicy metadata: name: my-policy spec: account_id: api_key: name: 'Alert Policy Created With k8s' # Feel free to rename region: 'us' Copy Now run the kubectl apply command to create your alert policy. kubectl apply -f ./new_relic_alert_policy.yaml Copy You'll see output that reads similar to the following: alertspolicy.nr.k8s.newrelic.com/my-policy created Copy Confirm that your alert policy was created by viewing your policies at alerts.newrelic.com/accounts/{your account ID}/policies. You can search for your new policy by its name. In this case, search for \"Alert Policy Created With k8s.\" You should see your new alert policy. Next it’s time to add a NRQL alert condition to the policy using the same configuration file. Step 3 of 3 Add NRQL alert conditions to your alert policy In the previous section you created an alert policy; now, you’ll add some alert conditions to the policy so you can trigger alerts when certain metrics are out of line. In your new_relic_alert_policy.yaml file, add a NRQL alert condition to the policy that will alert you when an application's average overall response time is above five seconds for a three minute period. Note: To receive notifications when an alert is triggered, add notification channels to your alert policy, with this code. # The policy from the previous steps apiVersion: nr.k8s.newrelic.com/v1 kind: AlertsPolicy metadata: name: my-policy spec: account_id: api_key: name: 'Alert Policy Created With k8s' # Feel free to rename region: 'us' # Add a NRQL alert condition to the policy conditions: - spec: type: 'NRQL' name: 'NRQL Alert Condition Created With k8s' nrql: query: \"SELECT average(duration) FROM Transaction WHERE appName = 'YOUR APP NAME'\" evaluationOffset: 3 enabled: true terms: - threshold: '5' threshold_occurrences: 'ALL' threshold_duration: 180 priority: 'CRITICAL' operator: 'ABOVE' violationTimeLimit: 'ONE_HOUR' valueFunction: 'SINGLE_VALUE' Copy With the alert condition added to the configuration, you can apply the update, which will create a NRQL alert condition and add it to your policy. kubectl apply -f ./new_relic_alert_policy.yaml Copy To confirm that the NRQL alert condition was created successfully, refresh your alert policy. If you see a new alert condition added to the alert policy, it was a success. To finish things off, you'll create and add an alert channel to your alert policy. For example, maybe you want to send an email out to your team when your alert condition is triggered. Try it out now We have a Kubernetes test cluster ready for you in 2 minutes. By following this on-line tutorial, you will learn how to: Deploy the New Relic agent in a Kubernetes environment Use the New Relic Kubernetes operator Some tips to use the on-line tutorial window: Accept the cookies, so you can see the menu bar. Click anywhere in the tutorial window to start. It will take about 2 minutes for your environment to be ready. Press CTRL-l or type clear to clear the terminal window Click on the finish flag icon in the bottom menu to hide or show the instructions Good luck! Note Some browsers automatically disable the use of iframes. If the module isn't loading please check your browser settings. Your browser does not support iframes. What’s next? Nice work — now you can manage your New Relic alert policies and NRQL alert conditions with code that integrates seamlessly within your Kubernetes workflow. This provides the ability to configure and manage your alerts with a domain-specific pattern, providing consistency and maintainability. You also gain the benefits of code reviews for any potential changes moving forward. As you and your team move forward, you might need to adjust some of the configuration values to better fit your needs. The New Relic Kubernetes Operator is just one of several tools in the New Relic Developer Toolkit aimed at facilitating observability as code.", "type": "developer", "document_type": "page", - "info": "", + "info": "Learn how to provision New Relic resources using the [Kubernetes operator](https://github.com/newrelic/newrelic-kubernetes-operator).", "sections": [ - "Contain the complexity - Observability made simple", - "Get coding", - "Create custom events", - "Add tags to apps", - "Build a Hello, World! app", - "Get inspired", - "Add a table to your app", - "Collect data - any source", - "Automate common tasks", - "Create a custom map view", - "Add a time picker to your app", - "Add custom attributes", - "New Relic developer champions", - "New Relic Podcasts" + "Set up New Relic using the Kubernetes operator", + "Before you begin", + "Installing the operator on your Kubernetes cluster", + "Creating your first alert policy", + "Add NRQL alert conditions to your alert policy", + "Try it out now", + "Note", + "What’s next?" ], - "title": "New Relic Developers", + "title": "Set up New Relic using the Kubernetes operator", "popularity": 1, - "external_id": "214583cf664ff2645436a1810be3da7a5ab76fab", - "image": "https://developer.newrelic.com/static/dev-champion-badge-0d8ad9c2e9bbfb32349ac4939de1151c.png", - "url": "https://developer.newrelic.com/", - "published_at": "2020-08-18T02:03:42Z", - "updated_at": "2020-08-15T01:36:10Z", + "tags": [ + "kubernetes", + "kubernetes operator", + "nrql alert conditions" + ], + "external_id": "2f9f7c55115d09255ade8f1d3fbcce4bee50d4aa", + "image": "", + "url": "https://developer.newrelic.com/automate-workflows/get-started-kubernetes/", + "published_at": "2020-08-19T01:47:11Z", + "updated_at": "2020-08-19T01:47:11Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.24943998, + "_score": 0.21878569, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic Developers", - "sections": "New Relic developer champions", - "body": " to your app Add a table to your New Relic One app 15 min Collect data - any source APIs, agents, OS emitters - get any data 20 min Automate common tasks Use the New Relic CLI to tag apps and create deployment markers 30 min Create a custom map view Build an app to show page view data on a map 20 min Add" + "sections": "Add NRQL alert conditions to your alert policy", + "tags": "nrql alert conditions", + "body": " how to set up New Relic for the first time with the official New Relic Kubernetes operator. More specifically, you'll provision an alert policy with NRQL conditions in your New Relic account using Kubernetes. Before you begin This walkthrough assumes you’ve already deployed a Kubernetes cluster. You" }, - "id": "5d6fe49a64441f8d6100a50f" - } - ], - "/automate-workflows/get-started-kubernetes": [ + "id": "5f0e5de464441f2734cd74b2" + }, { - "body": "You can create alert conditions using NRQL queries. Create NRQL alert condition To create a NRQL condition: When you start to create a condition, where it prompts you to Select a product, click NRQL. Tips on creating a NRQL condition: NRQL conditions Tips Condition types NRQL condition types include static, baseline, and outlier. Create a description For some condition types, you can create a Description. Query results Queries must return a number. The condition works by evaluating that returned number against the thresholds you set. Time period As with all alert conditions, NRQL conditions evaluate one single minute at a time. The implicit SINCE ... UNTIL clause specifying which minute to evaluate is controlled by your Evaluation offset setting. Since very recent data may be incomplete, you may want to query data from 3 minutes ago or longer, especially for: Applications that run on multiple hosts. SyntheticCheck data: Timeouts can take 3 minutes, so 5 minutes or more is recommended. Also, if a query will generate intermittent data, consider using the sum of query results option. Condition settings Use the Condition settings to: Configure whether and how open violations are force-closed. Adjust the evaluation offset. Create a concise and descriptive condition name. (NerdGraph API Only) Provide a text description for the condition that will be included in violations and notifications. Troubleshooting procedures Optional: To include your organization's procedures for handling the incident, add the runbook URL to the condition. Limits on conditions See the maximum values. Examples For more information, see: Expected NRQL syntax Examples of NRQL condition queries Alert threshold types When you create a NRQL alert, you can choose from different types of thresholds: NRQL alert threshold types Description Static This is the simplest type of NRQL threshold. It allows you to create a condition based on a NRQL query that returns a numeric value. Optional: Include a FACET clause. Baseline Uses a self-adjusting condition based on the past behavior of the monitored values. Uses the same NRQL query form as the static type, except you cannot use a FACET clause. Outlier Looks for group behavior and values that are outliers from those groups. Uses the same NRQL query form as the static type, but requires a FACET clause. NRQL alert syntax Here is the basic syntax for creating all NRQL alert conditions. Depending on the threshold type, also include a FACET clause as applicable. SELECT function(attribute) FROM Event WHERE attribute [comparison] [AND|OR ...] Clause Notes SELECT function(attribute) Required Supported functions that return numbers include: apdex average count latest max min percentage percentile sum uniqueCount If you use the percentile aggregator in a faceted alert condition with many facets, this may cause the following error to appear: An error occurred while fetching chart data. If you see this error, use average instead. FROM data type Required Only one data type can be targeted. Supported data types: Event Metric (RAW data points will be returned) WHERE attribute [comparison] [AND|OR ...] Optional Use the WHERE clause to specify a series of one or more conditions. All the operators are supported. FACET attribute Static: Optional Baseline: Not allowed Outlier: Required Including a FACET clause in your NRQL syntax depends on the threshold type: static, baseline, or outlier. Use the FACET clause to separate your results by attribute and alert on each attribute independently. Faceted queries can return a maximum of 5000 values for static conditions and a maximum of 500 values for outlier conditions. If the query returns more than this number of values, the alert condition cannot be created. If you create the condition and the query returns more than this number later, the alert will fail. Sum of query results (limited or intermittent data) Available only for static (basic) threshold types. If a query returns intermittent or limited data, it may be difficult to set a meaningful threshold. Missing or limited data will sometimes generate false positives or false negatives. To avoid this problem when using the static threshold type, you can set the selector to sum of query results. This lets you set the alert on an aggregated sum instead of a value from a single harvest cycle. Up to two hours of the one-minute data checks can be aggregated. The duration you select determines the width of the rolling sum, and the preview chart will update accordingly. Offset the query time window Every minute, we evaluate the NRQL query in one-minute time windows. The start time depends on the value you select in the NRQL condition's Advanced settings > Evaluation offset. Example: Using the default time window to evaluate violations With the Evaluation offset at the default setting of three minutes, the NRQL time window applied to your query will be: SINCE 3 minutes ago UNTIL 2 minutes ago If the event type is sourced from an APM language agent and aggregated from many app instances (for example, Transactions, TransactionErrors, etc.), we recommend evaluating data from three minutes ago or longer. An offset of less than 3 minutes will trigger violations sooner, but you might see more false positives and negatives due to data latency. For cloud data, such as AWS integrations, you may need an offset longer than 3 minutes. Check our AWS polling intervals documentation to determine your best setting. NRQL alert threshold examples Here are some common use cases for NRQL alert conditions. These queries will work for static and baseline threshold types. The outlier threshold type will require additional FACET clauses. Alert on specific segments of your data Create constrained alerts that target a specific segment of your data, such as a few key customers or a range of data. Use the WHERE clause to define those conditions. SELECT average(duration) FROM Transaction WHERE account_id in (91290, 102021, 20230) SELECT percentile(duration, 95) FROM Transaction WHERE name LIKE 'Controller/checkout/%' Alert on Nth percentile of your data Create alerts when an Nth percentile of your data hits a specified threshold; for example, maintaining SLA service levels. Since we evaluate the NRQL query in one-minute time windows, percentiles will be calculated for each minute separately. SELECT percentile(duration, 95) FROM Transaction SELECT percentile(databaseDuration, 75) FROM Transaction Alert on max, min, avg of your data Create alerts when your data hits a certain maximum, minimum, or average; for example, ensuring that a duration or response time does not pass a certain threshold. SELECT max(duration) FROM Transaction SELECT average(duration) FROM Transaction Alert on a percentage of your data Create alerts when a proportion of your data goes above or below a certain threshold. SELECT percentage(count(*), WHERE duration > 2) FROM Transaction SELECT percentage(count(*), WHERE httpResponseCode = '500') FROM Transaction Alert on Apdex with any T-value Create alerts on Apdex, applying your own T-value for certain transactions. For example, get an alert notification when your Apdex for a T-value of 500ms on transactions for production apps goes below 0.8. SELECT apdex(duration, t:0.5) FROM Transaction WHERE appName like '%prod%' Create a description You can define a description that passes useful information downstream for better violation responses or for use by downstream systems. For details, see Description. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "body": "The REST API endpoints allow you to create conditions for your policies. This glossary contains the names and descriptions of each of the fields that you can use to define or update a condition. Required and optional fields The API includes four types of New Relic Alerts conditions: APM External services Synthetic monitoring Plugins All of the fields used with a specific condition type are required except for these optional fields: enabled (defaults to false) runbook_url user_defined Field definitions Not every field listed in this glossary is required for every condition type. The condition type for which a field must be used is listed in each description. condition_scope This field allows you to scope a condition to either a JVM instance or to a whole application. This may be one of the strings: instance application Used for: Conditions Entity conditions For instance-based and JVM health metrics, see also violation_close_timer. enabled This is the status of your alert condition and is optional. The default is false. This field may be used to enable or disable a condition for maintenance or testing periods. Used for: Conditions External service conditions Synthetic monitoring conditions Plugin conditions entities This is an array of entity IDs identifying the objects which will be monitored with your condition. These may be application IDs, browser IDs, plugin IDs, key transaction IDs, external service IDs, etc. These are entered as a series of comma separated integers if there is more than one. Used for: Conditions External service conditions Plugin conditions expected_groups This is the number of groups you expect to see at any given time. It is used in combination with the ignore_overlap option. Used for: NRQL outlier conditions external_service_url This is the URL of the external service to be monitored. This string must not include the protocol. For example, use example.com, not https://example.com. Used for: External service conditions ignore_overlap If disabled, this looks for a convergence (or overlapping) of groups. If the condition is looking for two or more groups, and the returned values can't be separated into that number of distinct groups, then that will also produce a violation. This type of overlap event is represented on a chart by group bands touching. Used for: NRQL outlier conditions metric The metric field is used for three alert categories. The exact parameters available for use depend on the setting in the type field. These are listed below according to their alert type field. Alerts plugin conditions For Plugin conditions this is the metric, which has been defined in a plugin, that will be used to trigger a notification. Alerts conditions The value specified in the type field controls which of the parameters may be specified. The type field and corresponding available parameter names are listed in the following table. Only one may be specified. type Parameter apm_app_metric apdex error_percentage response_time_web response_time_background throughput_web throughput_background user_defined apm_kt_metric apdex error_percentage error_count response_time throughput browser_metric end_user_apdex total_page_load page_rendering web_application network dom_processing request_queuing ajax_response_time page_views_with_js_errors page_view_throughput ajax_throughput user_defined browser_metric_baseline page_view_throughput average_response_time ajax_response_time ajax_application_time mobile_metric database images json, network view_loading network_error_percentage status_error_percentage user_defined Alerts external service conditions The value specified in the type field controls which of the parameters may be specified. The type field and corresponding available parameter names are listed in the following table. Only one may be specified. type Parameter apm_external_service apdex error_percentage response_time_web response_time_background throughput_web throughput_background user_defined apm_app_metric_baseline external_service_transaction_time error_count database_transaction_time throughput_web response_time_web non_web_transaction_time web_transaction_database_time non_web_transaction_database_time mobile_external_service response_time_average response_time_minimum response_time_maximum throughput network_failure_percentage http_status_error_percentage metric_description This is a title for the metric which is displayed in notifications. Make this descriptive and unique so the reader will understand the nature of plugin metric being used to trigger an alert. Used for: Plugin conditions monitor_id This is the GUID of the Synthetic monitoring to alert on. Used for: Synthetic monitoring conditions name This condition title will allow to you identify it in the UI. Follow the guidelines for making this descriptive but short. Used for: Conditions External service conditions Synthetic monitoring conditions Plugin conditions nrql[query] This is the NRQL query that alerts monitors as part of a NRQL condition. Used for: NRQL conditions nrql[since_value] This is the timeframe (in minutes) in which to evaluate the specified NRQL query. since_value must be between 1 and 20. Used for: NRQL conditions plugin[guid] This is the GUID of the plugin for which the trigger is being defined. Used for: Plugin conditions plugin[id] This is the ID of the plugin for which the trigger is being defined. Used for: Plugin conditions runbook_url The runbook URL to display in notifications. This field is optional. Used for: Conditions External service conditions Synthetic monitoring conditions Plugin conditions terms[duration] This is the time (in minutes) for the condition to persist before triggering an event. It corresponds to the duration set when adding a threshold in the UI. Used for: Conditions terms[operator] This determines what comparison will be used between the value_function and the terms[threshold] value to trigger an event. It corresponds to the operation selected when adding a threshold in the UI. It must be one of the following strings: above below equal Used for: Conditions External service conditions Plugin conditions terms[priority] This corresponds to the severity level selected when setting the threshold values for the condition in the UI. This must be one of the following strings: critical warning Used for: Conditions External service conditions Plugin conditions terms[threshold] This is the threshold that the value_function must be compared to using the terms[operator] for an event to be triggered. It corresponds to the numeric value specified in the UI when adding the threshold values. This is a numeric value and must be 0 (zero) or greater. Used for: Conditions External service conditions Plugin conditions terms[time_function] This corresponds to the settings made in the UI when adding the threshold values. The choices are: all (corresponding to for at least in the UI) any (corresponding to at least once in in the UI) Used for: Conditions External service conditions Plugin conditions type This defines the type of metric that will be used for the alert. Allowable content for the metric field depends on the type value chosen. There are two product categories : Alerts conditions For this category, type is set to one of the following strings indicating the type of alerts condition. type Use apm_app_metric APM application metric will trigger an alert. apm_app_metric_baseline APM application metric will trigger an alert (using a baseline threshold). apm_kt_metric APM key transaction metric will trigger an alert. browser_metric Browser metric will trigger an alert. browser_metric_baseline Browser metric will trigger an alert (using a baseline threshold). mobile_metric Mobile metric will trigger an alert. Used for: Conditions Alerts external service conditions For this category, type is set to one of the following strings indicating the type of external service condition. type Use apm_external_service APM external metric will trigger an alert. mobile_external_service Mobile external metric will trigger an alert. Used for: External service conditions user_defined[metric] (optional) This is the name of a user defined custom metric to be used to determine if an event should be triggered. The user_defined[value_function] associated with the metric is compared with the terms[threshold] value when evaluating if an incident should be triggered. The comparison is performed using the operator defined by terms[operator]. Used for: Conditions External service conditions Synthetic monitoring conditions Plugin conditions user_defined[value_function] (optional) This is the numeric value obtained from the custom metric specified by user_defined[metric]. It is compared with the terms[threshold] value when evaluating if an incident should be triggered. The comparison is performed using the operator defined by terms[operator]. One of these value functions must be specified: average min max total sample_size Used for: Conditions value_function This is the value function used from the plugin metric. This may be one of the strings: min max average sample_size total percent Used for: Plugin conditions When used for a NRQL condition, the options are: single_value (condition is evaluated based on each query's returned value) sum (condition is evaluated based on the sum of each query's returned values over the specified duration) violation_time_limit_seconds Use to automatically close instance-based violations after the number of seconds specified. Must be one of these values: 3600 7200 14400 28800 43200 86400 Used for: Location conditions NRQL conditions violation_close_timer Use to automatically close instance-based violations, including JVM health metric violations, after the number of hours specified. Must be one of these values: 1 2 4 8 12 24 Used for: apm_app_metric (with condition_scope set to instance) apm_jvm_metric For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", "type": "docs", "document_type": "page", - "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / Alert conditions", - "info": "How to define thresholds that trigger alert notifications based on your NRQL queries.", - "nodeid": 9231, + "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / REST API alerts", + "info": "This glossary defines the alerts API fields, and provides links to relevant content to help better understand each one.", + "nodeid": 9276, "sections": [ "New Relic Alerts", "Get started", @@ -218,668 +250,664 @@ "Rules, limits, and glossary", "Alerts and Nerdgraph", "REST API alerts", - "Create NRQL alert conditions", - "Create NRQL alert condition", - "Alert threshold types", - "NRQL alert syntax", - "Sum of query results (limited or intermittent data)", - "Offset the query time window", - "NRQL alert threshold examples", - "Create a description", + "Alerts conditions API field names", + "Required and optional fields", + "Field definitions", "For more help" ], - "title": "Create NRQL alert conditions", - "translation_ja_url": "https://docs.newrelic.co.jp/docs/alerts-applied-intelligence/new-relic-alerts/alert-conditions/create-nrql-alert-conditions", + "title": "Alerts conditions API field names", "popularity": 1, - "external_id": "956a7a0b84d2afac5e6236df3143085ebc4f7459", + "external_id": "08f92bd7e576017eb032cdd843c616c7c04fba11", "category_1": "New Relic Alerts", - "category_2": "Alert conditions", "image": "", - "url": "https://docs.newrelic.com/docs/alerts-applied-intelligence/new-relic-alerts/alert-conditions/create-nrql-alert-conditions", - "published_at": "2020-08-18T21:58:59Z", - "updated_at": "2020-08-15T23:05:02Z", + "url": "https://docs.newrelic.com/docs/alerts-applied-intelligence/new-relic-alerts/rest-api-alerts/alerts-conditions-api-field-names", + "published_at": "2020-08-18T04:25:33Z", + "updated_at": "2020-08-15T13:54:16Z", "category_0": "Alerts and Applied intelligence", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.38054845, + "_score": 0.06362314, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Create NRQL alert conditions", - "sections": "Create NRQL alert conditions", - "info": "How to define thresholds that trigger alert notifications based on your NRQL queries.", - "category_0": "Alerts and Applied intelligence", - "category_1": "New Relic Alerts", - "category_2": "Alert conditions", - "translation_ja_url": "https://docs.newrelic.co.jp/docs/alerts-applied-intelligence/new-relic-alerts/alert-conditions/create-nrql-alert-conditions", - "body": "You can create alert conditions using NRQL queries. Create NRQL alert condition To create a NRQL condition: When you start to create a condition, where it prompts you to Select a product, click NRQL. Tips on creating a NRQL condition: NRQL conditions Tips Condition types NRQL condition types", - "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / Alert conditions" + "title": "Alerts conditions API field names", + "sections": "Alert conditions", + "info": "This glossary defines the alerts API fields, and provides links to relevant content to help better understand each one.", + "category_0": "Alerts and Applied intelligence", + "body": ". Used for: Plugin conditions runbook_url The runbook URL to display in notifications. This field is optional. Used for: Conditions External service conditions Synthetic monitoring conditions Plugin conditions terms[duration] This is the time (in minutes) for the condition to persist before triggering" }, - "id": "5f2d992528ccbc489d88dfc1" + "id": "5f2dee1128ccbc1e7588dff5" }, { - "body": "Automate workflows When building today's complex systems, you want an easy, predictable way to verify that your configuration is defined as expected. This concept, Observability as Code, is brought to life through a collection of New Relic-supported orchestration tools, including Terraform, AWS CloudFormation, and a command-line interface. These tools enable you to integrate New Relic into your existing workflows, easing adoption, accelerating deployment, and returning focus to your main job — getting stuff done. In addition to our Terraform and CLI guides below, find more automation solutions in our Developer Toolkit. Guides to automate workflows 5 min Quickly tag resources Add tags to apps for easy filtering 20 min Automate common tasks Use the New Relic CLI to tag apps and create deployment markers 20 min Set up New Relic using the Kubernetes operator Learn how to provision New Relic resources using the Kubernetes operator 20 min Set up New Relic using Terraform Learn how to provision New Relic resources using Terraform", - "type": "developer", + "body": "As a customer, you are eligible to participate in New Relic’s Developer Program. Additional information and resources are available at New Relic’s Developer Program site. By downloading, accessing, or using the developer resources (including the CLI), you agree that usage of the developer resources is pursuant to the New Relic Developers Terms and Conditions and that you have the authority to bind your organization. Such terms do not have to be signed in order to be binding. If you do not agree to these terms and conditions, your sole remedy is to not use these developer resources. If your use of the New Relic developer resources are covered under a separate agreement, the above does not apply to you. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "type": "docs", "document_type": "page", - "info": "", + "breadcrumb": "Contents / Licenses / Product or service licenses / Developer Edition", + "info": "New Relic Developer edition policy", + "nodeid": 39641, "sections": [ - "Automate workflows", - "Guides to automate workflows", - "Quickly tag resources", - "Automate common tasks", - "Set up New Relic using the Kubernetes operator", - "Set up New Relic using Terraform" + "Product or service licenses", + "New Relic One", + "APM", + "Browser", + "Developer Edition", + "Infrastructure", + "Insights", + "Logs", + "Mobile", + "Synthetics", + "Mobile apps", + "Plugins", + "Miscellaneous", + "Developer Program Resources", + "For more help" ], - "title": "Automate workflows", + "title": "Developer Program Resources", "popularity": 1, - "external_id": "d4f408f077ed950dc359ad44829e9cfbd2ca4871", + "external_id": "98308cfffa652e4c25967e1be5b848b9c28ca410", + "category_1": "Product or service licenses", + "category_2": "Developer Edition", "image": "", - "url": "https://developer.newrelic.com/automate-workflows/", - "published_at": "2020-08-18T02:04:53Z", - "updated_at": "2020-08-17T01:55:15Z", + "url": "https://docs.newrelic.com/docs/licenses/product-or-service-licenses/new-relic-developer-edition/developer-program-resources", + "published_at": "2020-08-19T15:52:44Z", + "updated_at": "2020-08-08T19:17:02Z", + "category_0": "Licenses", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.19427466, + "_score": 0.058064654, "_version": null, "_explanation": null, "sort": null, "highlight": { - "sections": "Set up New Relic using the Kubernetes operator", - "body": " solutions in our Developer Toolkit. Guides to automate workflows 5 min Quickly tag resources Add tags to apps for easy filtering 20 min Automate common tasks Use the New Relic CLI to tag apps and create deployment markers 20 min Set up New Relic using the Kubernetes operator Learn how to provision New Relic resources using the Kubernetes operator 20 min Set up New Relic using Terraform Learn how to provision New Relic resources using Terraform" + "body": " is pursuant to the New Relic Developers Terms and Conditions and that you have the authority to bind your organization. Such terms do not have to be signed in order to be binding. If you do not agree to these terms and conditions, your sole remedy is to not use these developer resources. If your" }, - "id": "5efa999c196a67dfb4766445" + "id": "5f338507e7b9d2f670c9de83" }, { - "body": "You can manage alerts conditions using our GraphQL NerdGraph API. Here are some conditions queries and mutations you can develop in our NerdGraph API explorer. See the NerdGraph introduction for help getting started with NerdGraph API explorer. This document covers the following: Steps to create a NRQL condition NRQL static condition NRQL baseline condition NRQL outlier condition Update a condition Update mutations List and filter NRQL conditions Singular NRQL condition queries Create a description Delete conditions Steps to create a NRQL condition Follow these steps: Decide which condition type you want to create (see NRQL Condition threshold types). Find your relevant policyID by doing one of the following: Use the NerdGraph policies API. Go to one.newrelic.com, in the top nav click Alerts & AI, then click Policies. Choose a policy. Find the ID under the policy name. Provide the appropriate mutation for your NRQL condition type and the relevant values. The NerdGraph GraphiQL explorer is the best place to find up-to-date documentation about the per-field specifics of the NerdGraph NRQL Conditions API. For example, questions like \"What does the valueFunction field accept?\" are best answered with the inline NerdGraph documentation. NRQL static condition Here's an example of creating a static condition: mutation { alertsNrqlConditionStaticCreate(accountId: YOUR_ACCOUNT_ID, policyId: YOUR_POLICY_ID, condition: { name: \"Low Host Count - Catastrophic\" enabled: true nrql: { query: \"SELECT uniqueCount(host) from Transaction where appName='my-app-name'\" evaluationOffset: 3 } terms: { threshold: 2 thresholdOccurrences: AT_LEAST_ONCE thresholdDuration: 600 operator: BELOW priority: CRITICAL } valueFunction: SINGLE_VALUE violationTimeLimit: TWENTY_FOUR_HOURS }) { id name } } NRQL baseline condition Here's an example of creating a baseline condition: mutation { alertsNrqlConditionBaselineCreate(accountId: YOUR_ACCOUNT_ID, policyId: YOUR_POLICY_ID, condition: { name: \"Baseline Condition\" enabled: true baselineDirection: UPPER_ONLY nrql: { query: \"SELECT average(duration) FROM Transaction\" evaluationOffset: 3 } terms: { threshold: 13 thresholdDuration: 180 thresholdOccurrences: ALL operator: ABOVE priority: CRITICAL } violationTimeLimit: TWENTY_FOUR_HOURS }) { id name baselineDirection } } NRQL outlier condition Here's an example of creating an outlier condition: mutation { alertsNrqlConditionOutlierCreate(accountId: YOUR_ACCOUNT_ID, policyId: YOUR_POLICY_ID, condition: { name: \"Outlier Condition\" enabled: true expectedGroups: 4 openViolationOnGroupOverlap: false nrql: { query: \"SELECT average(duration) FROM Transaction FACET httpResponseCode\" evaluationOffset: 3 } terms: { threshold: 1 thresholdDuration: 300 thresholdOccurrences: ALL operator: ABOVE priority: CRITICAL } violationTimeLimit: TWENTY_FOUR_HOURS }) { id name expectedGroups openViolationOnGroupOverlap } } Update a condition Complete the following: Determine the type of your existing condition by requesting the type field in a nrqlConditionsSearch query like this: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditionsSearch { nrqlConditions { id type } } } } } } The type returned is what you use for your update mutation. For example, if the type returned is STATIC, use alertsNrqlConditionStaticUpdate. If the type returned is BASELINE, use alertsNrqlConditionBaselineUpdate. If the type returned is OUTLIER, use alertsNrqlConditionOutlierUpdate. Provide the id of your condition to your relevant condition type mutation. Note that you can only update conditions of the relevant type. Only provide update mutations for the fields you want to update. Fields you don't provide in the update are not touched. Update mutations Only fields that you provide in the update are changed. In the following example, baselineDirection returns unchanged, but name is updated. mutation { alertsNrqlConditionBaselineUpdate(id: YOUR_CONDITION_ID, accountId: YOUR_ACCOUNT_ID, condition: { name: \"Your updated name\" }) { id name baselineDirection } } List and filter NRQL conditions To list or filter your NRQL conditions, use the nrqlConditionsSearch query in NerdGraph. Use cursor pagination The basic of list functionality for NRQL conditions allows you to paginate through your NRQL conditions as well as request the total count of conditions per account. The nrqlConditionsSearch query utilizes cursor pagination to paginate through resources. The idea behind cursor pagination is that the client will request a cursor in a programmatic loop until the cursor comes back empty. An initial list response will look something like this: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditionsSearch { nextCursor nrqlConditions { id name type } totalCount } } } } } This example returns a JSON response like this: { \"data\": { \"actor\": { \"account\": { \"alerts\": { \"nrqlConditionsSearch\": { \"nextCursor\": \"WOwfJ4+TWm9QTFeKMGyg+w==:QqkI8S4+Wwnpno6z+uk8kQ==\", \"nrqlConditions\": [ { \"id\": \"4432\", \"name\": \"Baseline Condition\", \"type\": \"BASELINE\" }, { \"id\": \"443\", \"name\": \"A static condition\", \"type\": \"STATIC\" }, // more conditions here in reality ], \"totalCount\": 435 } } } } }, } In order to paginate through conditions in the response, have the client request the cursor to be returned until the nextCursor returns from the response as null: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditionsSearch(cursor: \"WOwfJ4+TWm9QTFeKMGyg+w==:QqkI8S4+Wwnpno6z+uk8kQ==\", ) { nextCursor nrqlConditions { id name type } totalCount } } } } } Request type-specific fields Certain fields are only available on specific NRQL condition types. The main reason that mutations are split between the different condition types is because they have minor differences between the fields they accept. For example, valueFunction is only relevant for static NRQL conditions and baselineDirection is only relevant on baseline NRQL conditions. But if these fields are only available on these certain condition types, how do we return them in a list of all of our condition types? The answer is a GraphQL convention known as inline fragments. Inline fragments allow you to access the data on a specific type of NRQL condition: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditionsSearch { nrqlConditions { id name type ...on AlertsNrqlStaticCondition { valueFunction } ...on AlertsNrqlBaselineCondition { baselineDirection } ...on AlertsNrqlOutlierCondition { expectedGroups } } } } } } } In the previous example query, we are asking GraphQL to do the hard work for us to determine which NRQL conditions are the correct type. So, when the returned type is a static condition, it will return the valueFunction in the object. When the returned type is a baseline condition, it will return baselineDirection instead, and when the type is an outlier condition, it will return expectedGroups. Here is an example response: { \"data\": { \"actor\": { \"account\": { \"alerts\": { \"nrqlConditionsSearch\": { \"nrqlConditions\": [ { \"baselineDirection\": \"UPPER_ONLY\", \"id\": \"342\", \"name\": \"My baseline condition\", \"type\": \"BASELINE\" }, { \"id\": \"553\", \"name\": \"My static condition\", \"type\": \"STATIC\", \"valueFunction\": \"SINGLE_VALUE\" }, { \"expectedGroups\": 4, \"id\": \"802\", \"name\": \"My outlier condition\", \"type\": \"OUTLIER\" } ] } } } } } } Filter NRQL conditions You can filter NRQL conditions with the searchCriteria argument of the nrqlConditionsSearch query: Here's an example of filtering NRQL conditions with matching by name. This query returns NRQL conditions that match the provided name. Note that this match is case insensitive. { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditionsSearch(searchCriteria: { name: \"Baseline Condition\" }) { nrqlConditions { id name type } } } } } } Singular NRQL condition queries You can use the NRQL condition API to query for a singular condition. Run the nrqlCondition query in the alerts namespace. Similar to type specific fields on the nrqlConditionSearch query, you can also use these inline fragmentsto request fields that are restricted to a NRQL condition type. { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlCondition(id: YOUR_CONDITION_ID) { id name ...on AlertsNrqlStaticCondition { valueFunction } } } } } } Update the description This will walk you through the procedure to create a description for a NRQL alert condition. 1. Get all the conditions for a policy: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditions(policyId: YOUR_POLICY_ID) { nextCursor results { id name description enabled nrql { query sinceValue } policyId runbookUrl terms { duration operator priority timeFunction threshold } type violationTimeLimit } } } } } } 2. Get the details for a single condition: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlCondition(id: \"YOUR_CONDITION_ID\") { description id enabled name nrql { query evaluationOffset } policyId runbookUrl terms { operator priority threshold thresholdDuration thresholdOccurrences } type violationTimeLimit } } } } } 3. Create a mutation with the description. Here's an empty mutation template: mutation { alertsNrqlConditionStaticUpdate(accountId: YOUR_ACCOUNT_ID, id: \"YOUR_CONDITION_ID\", condition: {description: \"\"}) { description } } Here'a an example mutation with an included example description: mutation { alertsNrqlConditionStaticUpdate(accountId: 123456, id: \"123456\", condition: {description: \"timestamp : {{timestamp}} \\n accountId : {{accountId}} \\n type : {{type}} \\n event : {{event}} \\n description : {{description}} \\n policyId : {{policyId}} \\n policyName: {{policyName}} \\n conditionName : {{conditionName}} \\n conditionId : {{conditionId}} \\n product : {{product}} \\n conditionType : {{conditionType}} \\n RunbookUrl : {{runbookUrl}} \\n nrqlQuery : {{nrqlQuery}} \\n nrqlEventType : {{nrqlEventType}} \\n targetID : {{targetId}} \\n targetName : {{targetName}} \\n commandLine : {{tag.commandLine}} \\n entityGuid : {{tag.entityGuid}} \\n entityName : {{tag.entityName}} \\n fullHostname : {{tag.fullHostname}} \\n instanceType : {{tag.instanceType}} \\n processDisplayName : {{tag.processDisplayName}}\"}) { description } } Delete conditions You can use the alertsConditionDelete mutation to delete any type of condition. You can only request the id field on a delete mutation; for example: mutation { alertsConditionDelete(accountId: YOUR_ACCOUNT_ID, id: YOUR_CONDITION_ID) { id } } For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", - "type": "docs", - "document_type": "page", - "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / Alerts and Nerdgraph", - "info": "Examples of how to use the NerdGraph API explorer to create alert conditions, queries, and mutations.", - "nodeid": 37711, + "body": "logo-newrelic Search Products Pricing Solutions Help Center About New Relic for iOS or Android    New Relic Insights App for iOS Search icon Sign Up Log In Products New Relic One Platform Overview Telemetry Data Platform Full-Stack Observability Applied Intelligence Solutions By Topic DevOps Cloud Adoption Cloud Native Digital Customer Experience By Industry E-commerce and Retail Media Public Sector By Technology Amazon Web Services Pivotal Cloud Foundry Microsoft Azure Google Cloud Platform Kubernetes Help Center Learn Docs Build on New Relic Explore open source projects Training Get help Community forum Global technical support Expert services About Our Customers Over 17,000 customers love New Relic, from Fortune 500 enterprises to small businesses around the globe. Our Blog The latest news, tips, and insights from the world of New Relic and digital intelligence. Our Company About Us Leadership Meetups and Events Resources   Investor Relations Newsroom Partner Program Contact Us logo-newrelic Want to use our logo? There's a page for that, including instructions and different styles and formats. Sorry about grabbing your right-click. Just trying to be helpful. You can also go home. Back to top icon New Relic Inc. Terms of Service Paid Accounts Customers that access New Relic’s platform through a paid subscription are governed by the Terms of Service set forth immediately above. Unpaid Accounts Customers that access New Relic’s platform on an unpaid (e.g. trials, proof of concepts, New Relic Developer Edition or ‘lite’) basis are governed by the Terms of Service set forth immediately above. Community Forums Community Forum participants ask and answer questions about New Relic’s platform.  Use of the Community Form is governed by the terms and conditions set forth immediately above. New Relic Data Processing Addendum Customers who currently send, or intend to send, personal data to the New Relic Services for processing should download and complete the Data Processing Addendum set forth immediately above. Data Processing Addendum FAQ  This guide is designed to assist customers in their completion of the New Relic Data Processing Addendum. COMPANY Careers and Culture Partner Program Investor Relations NewRelic.org Suppliers Portal CONNECT Contact Us Request Demo Events international newrelic.co.jp (Japanese) newrelic.fr (French) newrelic.de (German) Terms of Service DMCA Policy Privacy Policy Cookie Policy UK Slavery Act of 2015 ©2008-20 New Relic, Inc. All rights reserved", + "type": "", + "info": "", "sections": [ - "New Relic Alerts", - "Get started", - "Alert policies", - "Alert conditions", - "Alert violations", - "Alert Incidents", - "Alert notifications", - "Troubleshooting", - "Rules, limits, and glossary", - "Alerts and Nerdgraph", - "REST API alerts", - "NerdGraph API: NRQL condition alerts", - "Steps to create a NRQL condition", - "NRQL static condition", - "NRQL baseline condition", - "NRQL outlier condition", - "Update a condition", - "Update mutations", - "List and filter NRQL conditions", - "Singular NRQL condition queries", - "Update the description", - "Delete conditions", - "For more help" + "Terms of Service", + "COMPANY", + "CONNECT", + "international" ], - "title": "NerdGraph API: NRQL condition alerts ", + "title": "Terms of Service Agreement | New Relic", "popularity": 1, - "external_id": "86591bd20017930f1e4eef1b1a76e3806298dbb9", - "category_1": "New Relic Alerts", - "image": "", - "url": "https://docs.newrelic.com/docs/alerts-applied-intelligence/new-relic-alerts/alerts-nerdgraph/nerdgraph-api-nrql-condition-alerts", - "published_at": "2020-08-18T18:15:13Z", - "updated_at": "2020-08-11T04:56:49Z", - "category_0": "Alerts and Applied intelligence", + "external_id": "f1539ad0dbd46a29c243907400c646ed11c33bd1", + "image": "https://newrelic.com/content/dam/new-relic/opengraph/NROG_Image.png", + "url": "https://newrelic.com/termsandconditions/terms", + "published_at": "2020-08-19T01:40:42Z", + "updated_at": "2020-07-30T07:25:28Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.15523642, + "_score": 0.054012053, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "NerdGraph API: NRQL condition alerts ", - "sections": "NerdGraph API: NRQL condition alerts", - "info": "Examples of how to use the NerdGraph API explorer to create alert conditions, queries, and mutations.", - "category_0": "Alerts and Applied intelligence", - "category_1": "New Relic Alerts", - "body": " the conditions for a policy: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditions(policyId: YOUR_POLICY_ID) { nextCursor results { id name description enabled nrql { query sinceValue } policyId runbookUrl terms { duration operator priority timeFunction threshold } type violationTimeLimit" + "title": "Terms of Service Agreement | New Relic", + "sections": "Terms of Service", + "body": " of concepts, New Relic Developer Edition or ‘lite’) basis are governed by the Terms of Service set forth immediately above. Community Forums Community Forum participants ask and answer questions about New Relic’s platform.  Use of the Community Form is governed by the terms and conditions set forth" }, - "id": "5f2dee1128ccbc562e88dfc1" + "id": "5ac68e78c75d077fcb6edc38" }, { - "body": "Use the entity explorer to access the performance data from all your monitored applications, services, and hosts. For more about entities, see What is an entity? View entities To use the entity explorer: Go to one.newrelic.com and select Entity explorer. Your monitored entities are on the left. You may need to scroll your list of entities to see them all. one.newrelic.com > Entity explorer: Use the entity explorer to locate and examine the entities you monitor. The entity explorer brings together data reported from across all of New Relic. Entity categories include: Services: APM-monitored applications and services monitored. Hosts: your monitored infrastructure (your servers and hosts). Mobile applications: your mobile apps. Browser applications: your front-end browser apps. Integration-reported data: data from services monitored by our integrations, including our on-host integrations (like Kubernetes, StatsD, and NGINX), and cloud platform integrations, like Amazon, Microsoft Azure, and Google Cloud Platform (GCP). Health (alert) status The entity explorer shows a color-coded alert status for entities. For example, you may see a red alert status indicating a critical violation in progress. To see what an alert status means, mouse over it. To see details about an entity's alerting status, select the entity. NRQL alert conditions aren't used to determine alert status because they aren't associated with specific entities. Starting June 8, 2020, New Relic One will not continue to display any APM application that hasn't reported data for 93 days. To match our published APM data retention guidelines, applications that have not reported data will be available within the New Relic UI for 90 days. After 90 days, those applications will be removed from the UI; however, key metrics will continue to be available via the New Relic REST API based on subscription level. For more information, see New Relic's Explorers Hub post. Filter by tag or entity name There are a couple ways to filter down to specific types of entities: Filter entities by tags: Use Filter with tags at the top of the page. For example, you may want to filter down to only entities tagged with production, or only entities with a specific AWS region tag. For more about tags, see Tagging. Filter by entity name: Use Search services by name at the top of the page. Entity data retention Availability of data depends on these factors: Scope Data retention Entity explorer and search In the UI, data is available for eight days after an entity no longer exists, with one exception: data reported by integrations, such as Amazon AWS, is only available for one day after an entity ceases to exist. Our database (accessible via NRQL query) For querying our database (for example, via the query builder or data explorer), availability is dependent on the data retention for that data type. As a result of these factors, a short-lived entity (like a cloud host) may not be available in the entity explorer list or via search, but its data may still be available via NRQL query. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "body": "As a customer with a paid subscription to New Relic products, you are eligible to participate in preview access of the New Relic One platform (e.g. Telemetry Data Platform, Full Stack Observability, and Applied Intelligence products) for the period beginning July 31, 2020 and ending December 31, 2020 (“Preview Access”). BY DOWNLOADING, ACCESSING, INDICATING YOUR AGREEMENT TO, OR USING THE PREVIEW ACCESS PRODUCTS, YOU AGREE THAT YOUR PREVIEW ACCESS USAGE IS PURSUANT TO THESE SEPARATE TERMS AND CONDITIONS IN LIEU OF ANY OTHER TERMS. These terms do not have to be signed in order to be binding. If you do not agree to these terms and conditions, your sole remedy is to not participate in Preview Access. New Relic reserves the right to terminate or restrict Preview Access, in whole or in part, at any time. Notwithstanding the foregoing and any other materials provided by New Relic, select customers are ineligible for the Preview Access. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", "type": "docs", "document_type": "page", - "breadcrumb": "Contents / New Relic One / Use New Relic One / UI and data", - "info": "Use New Relic's entity explorer to see all your monitored entities in one place and explore the reported data. ", - "nodeid": 34316, + "breadcrumb": "Contents / Licenses / Product or service licenses / New Relic One", + "info": "", + "nodeid": 39366, "sections": [ - "Use New Relic One", - "Get started", - "Core concepts", - "UI and data", - "Workloads", - "Build on New Relic One", - "Entity explorer: View performance across apps, services, hosts", - "View entities", - "Health (alert) status", - "Filter by tag or entity name", - "Entity data retention", + "Product or service licenses", + "New Relic One", + "APM", + "Browser", + "Developer Edition", + "Infrastructure", + "Insights", + "Logs", + "Mobile", + "Synthetics", + "Mobile apps", + "Plugins", + "Miscellaneous", + "Preview access for New Relic One", "For more help" ], - "title": "Entity explorer: View performance across apps, services, hosts", - "translation_ja_url": "https://docs.newrelic.co.jp/docs/new-relic-one/use-new-relic-one/ui-data/new-relic-one-entity-explorer-view-performance-across-apps-services-hosts", + "title": "Preview access for New Relic One", "popularity": 1, - "external_id": "4a6bab9713737af90dbcc516f3c61501354f15d2", - "category_1": "Use New Relic One", - "category_2": "UI and data", - "image": "https://docs.newrelic.com/sites/default/files/thumbnails/image/new-relic-one-entity-explorer.png", - "url": "https://docs.newrelic.com/docs/new-relic-one/use-new-relic-one/ui-data/new-relic-one-entity-explorer-view-performance-across-apps-services-hosts", - "published_at": "2020-08-18T14:54:15Z", - "updated_at": "2020-08-10T23:54:20Z", - "category_0": "New Relic One", + "external_id": "eae3865081d3bd8ad2dd8b6eaf0fe0147355360c", + "category_1": "Product or service licenses", + "category_2": "New Relic One", + "image": "", + "url": "https://docs.newrelic.com/docs/licenses/product-or-service-licenses/new-relic-one/preview-access-new-relic-one", + "published_at": "2020-08-18T11:19:02Z", + "updated_at": "2020-07-31T04:41:27Z", + "category_0": "Licenses", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.089622304, + "_score": 0.04942697, "_version": null, "_explanation": null, "sort": null, "highlight": { - "sections": "Health (alert) status", - "body": " in progress. To see what an alert status means, mouse over it. To see details about an entity's alerting status, select the entity. NRQL alert conditions aren't used to determine alert status because they aren't associated with specific entities. Starting June 8, 2020, New Relic One will not continue" + "body": ", 2020 (“Preview Access”). BY DOWNLOADING, ACCESSING, INDICATING YOUR AGREEMENT TO, OR USING THE PREVIEW ACCESS PRODUCTS, YOU AGREE THAT YOUR PREVIEW ACCESS USAGE IS PURSUANT TO THESE SEPARATE TERMS AND CONDITIONS IN LIEU OF ANY OTHER TERMS. These terms do not have to be signed in order to be binding" }, - "id": "5d244a5864441fe577a72a1b" - }, + "id": "5f23a0f7e7b9d29da9c82305" + } + ], + "/build-apps/add-query-mutate-data-nerdstorage": [ { - "body": "New Relic's Kubernetes integration can be installed directly on a server or VM, or through several cloud platforms, such as GKE, EKS, AKS, or OpenShift. Each has a different compatibility with our integration. Compatibility Our Kubernetes integration is compatible with the following versions, depending on the installation mode: Install mode or feature Kubernetes versions Kubernetes cluster Currently tested with versions 1.10 to 1.18 Kubernetes cluster GKE Currently tested with versions 1.10 and 1.17 Kubernetes cluster EKS Currently tested with version 1.11 Kubernetes cluster AKS Currently tested with version 1.11 Kubernetes cluster OpenShift Currently tested with versions 3.7, 3.9, 4.2, 4.3, 4.4 and 4.5 Control plane monitoring Compatible with version 1.11 or higher Service monitoring Compatible with version 1.13 or higher Requirements The New Relic Kubernetes integration has the following requirements: Linux distribution compatible with New Relic infrastructure agent. kube-state-metrics version 1.9.5 running on the cluster. Install using Helm For compatibility and requirements when installing the Kubernetes integration using Helm, see Alternative install using Helm. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", - "type": "docs", + "body": "Add the NerdGraphQuery component to an application 20 minutes This guide steps you through the process of adding the `NerdGraphQuery` component to a sample transaction overview application. This allows you to query data from your New Relic account and add it to a dropdown menu. NerdGraph is our GraphQL implementation. GraphQL has some key differences when compared to REST: The client, not the server, determines what data is returned. You can easily collect data from multiple sources. For example, in a single query, you can get account information, infrastructure data, and issue a NRQL request. Note Before completing this exercise, you can experiment with GraphQL queries in our NerdGraph API explorer. We also have a 14-minute video that covers the steps below. Before you begin To develop projects, you need our New Relic One CLI (command line interface). If you haven't already installed it, do the following: Install Node.js. Complete steps 1–4 of our CLI quick start, and be sure to make a copy of your account ID from step 1 because you’ll need it later. Note If you've already installed the New Relic One CLI, but you can't remember your account ID, start the CLI quick start again, and then click the Get your API key down arrow. The account ID is the number preceding your account name. For additional details, see Set up your development environment. Prepare the sample code To get started, complete these steps to update the application UUID (unique ID) and run the sample application locally: Step 1 of 7 If you haven't already done so, clone the example applications from our how-to GitHub repo. Here's an example using HTTPS: git clone https://github.com/newrelic/nr1-how-to.git Copy Step 2 of 7 Change to the directory use-nerdgraph-nerdlet: cd nr1-how-to/use-nerdgraph/nerdlets/use-nerdgraph-nerdlet Copy Step 3 of 7 In your preferred text editor, open index.js. Step 4 of 7 Replace with your account id: Note Your account ID is available in the CLI quick start (see Before you begin). this.accountId = ; Copy Step 5 of 7 Change to the /nr1-howto/use-nerdgraph directory: cd ../.. Copy Step 6 of 7 Execute these commands to update the UUID and serve the sample application: nr1 nerdpack:uuid -gf nr1 nerdpack:serve Copy Step 7 of 7 Once the sample application is successfully served, go to the local New Relic One homepage (https://one.newrelic.com/?nerdpacks=local), click Apps, and then click Use NerdGraph. After launching the Use NerdGraph application, you see a dashboard that gives an overview of the transactions in your account: Add the NerdGraphQuery component Now you can create a dropdown menu for changing the account the application is viewing. The first step is to import the NerdGraphQuery component into the application's index.js file. Note If you need more details about our example below, see the APIs and components page on https://developer.newrelic.com Step 1 of 3 Add the NerdGraphQuery component into the first StackItem inside of the return in the index.js file: {({ loading, error, data }) => { console.log({ loading, error, data }); if (loading) { return ; } if (error) { return 'Error!'; } return null; }} ; Copy Step 2 of 3 The NerdGraphQuery component takes a query object that states the source you want to access and the data you want returned. Add the following code to your index.js file in the render method: Note In the browser console, you can see the data from your query returned in an object that follows the same structure of the object in the initial query. const query = ` query($id: Int!) { actor { account(id: $id) { name } } } `; Copy Step 3 of 3 To take the data returned by the NerdGraph query and display it in the application, replace the return null in the current NerdGraphQuery component with this return statement: return {data.actor.account.name} Apps:; Copy When you go back to the browser and view your application, you see a new headline showing the name of your account returned from NerdGraph: How to use NerdGraphQuery.query At this point, you have implemented the NerdGraphQuery component with the application's render method and displayed the return data within the transaction overview application. Here's what you need to do next: Query NerdGraph inside of the componentDidMount lifecycle method. Save the returned data for later use in the application. Step 1 of 2 This code takes the response from NerdGraph and makes sure the results are processed, stored into the application state, and logged to the browser console for viewing. Add this code into the index.js file just under the constructor: componentDidMount() { const accountId = this.state; const gql = `{ actor { accounts { id name } } }`; const accounts = NerdGraphQuery.query({query: gql}) //The NerdGraphQuery.query method called with the query object to get your account data is stored in the accounts variable. accounts.then(results => { console.log('Nerdgraph Response:', results); const accounts = results.data.actor.accounts.map(account => { return account; }); const account = accounts.length > 0 && accounts[0]; this.setState({ selectedAccount: account, accounts }); }).catch((error) => { console.log('Nerdgraph Error:', error); }) } Copy Step 2 of 2 After the data is stored into state, display a selection so users can change accounts and update the application. To do this, add this code to index.js for the second StackItem in the return statement: { accounts && ( ); } Copy Review the results of the NerdGraph query After you complete these steps, look at the application in your browser, and note the following: The dropdown menu now displays the data returned from the NerdGraphQuery.query and allows you to select an account. After you select a new account, the application shows data from the new selection. The final index.js file should have code similar to the code below. This completed sample is in your nerdlet final.js. import React from 'react'; import { PlatformStateContext, NerdGraphQuery, Spinner, HeadingText, Grid, GridItem, Stack, StackItem, Select, SelectItem, AreaChart, TableChart, PieChart } from 'nr1' import { timeRangeToNrql } from '@newrelic/nr1-community'; // https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction export default class UseNerdgraphNerdletNerdlet extends React.Component { constructor(props){ super(props) this.state = { accountId: , accounts: null, selectedAccount: null, } } componentDidMount() { const accountId = this.state; const gql = `{ actor { accounts { id name } } }`; const accounts = NerdGraphQuery.query({ query: gql }) accounts.then(results => { console.log('Nerdgraph Response:', results); const accounts = results.data.actor.accounts.map(account => { return account; }); const account = accounts.length > 0 && accounts[0]; this.setState({ selectedAccount: account, accounts }); }).catch((error) => { console.log('Nerdgraph Error:', error); }) } selectAccount(option) { this.setState({ accountId: option.id, selectedAccount: option }); } render() { const { accountId, accounts, selectedAccount } = this.state; console.log({ accountId, accounts, selectedAccount }); const query = ` query($id: Int!) { actor { account(id: $id) { name } } } `; const variables = { id: accountId, }; const avgResTime = `SELECT average(duration) FROM Transaction FACET appName TIMESERIES AUTO `; const trxOverview = `FROM Transaction SELECT count(*) as 'Transactions', apdex(duration) as 'apdex', percentile(duration, 99, 95) FACET appName `; const errCount = `FROM TransactionError SELECT count(*) as 'Transaction Errors' FACET error.message `; const responseCodes = `SELECT count(*) as 'Response Code' FROM Transaction FACET httpResponseCode `; return ( {({loading, error, data}) => { if (loading) { return ; } if (error) { return 'Error!'; } return {data.actor.account.name} Apps:; }} {accounts && }
{(PlatformState) => { /* Taking a peek at the PlatformState */ const since = timeRangeToNrql(PlatformState); return ( <>
Transaction Overview
Average Response Time
Response Code
Transaction Errors
); }}
) } } Copy Summary Now that you've completed all the steps in this example, you've successfully queried data from your account using the NerdGraphQuery component in two methods: Using the NerdGraphQuery component inside the application's render method and then passing the returned data into the children's components. Using the NerdGraphQuery.query method to query data before the application renders.", + "type": "developer", "document_type": "page", - "breadcrumb": "Contents / Integrations / Kubernetes integration / Get started", - "info": "Compatibility and requirements of the New Relic Kubernetes integration.", - "nodeid": 38331, + "info": "The NerdGraphQuery component allows you to query data from your account and add it to a dropdown menu in an application", "sections": [ - "Kubernetes integration", - "Get started", - "Installation", - "Understand and use data", - "Link apps and services", - "Kubernetes events", - "Logs", - "Troubleshooting", - "Kubernetes integration: compatibility and requirements", - "Compatibility", - "Requirements", - "Install using Helm", - "For more help" + "Add the NerdGraphQuery component to an application", + "Note", + "Before you begin", + "Prepare the sample code", + "Add the NerdGraphQuery component", + "How to use NerdGraphQuery.query", + "Review the results of the NerdGraph query", + "Summary" ], - "title": "Kubernetes integration: compatibility and requirements", + "title": "Add the NerdGraphQuery component to an application", "popularity": 1, - "external_id": "dd40c3bef40e68d873d909dbff75708e20a1141e", - "category_1": "Kubernetes integration", - "category_2": "Get started", - "image": "", - "url": "https://docs.newrelic.com/docs/integrations/kubernetes-integration/get-started/kubernetes-integration-compatibility-requirements", - "published_at": "2020-08-18T17:13:01Z", - "updated_at": "2020-08-18T17:13:00Z", - "category_0": "Integrations", + "tags": [ + "nerdgraphquery component", + "transaction overview app", + "query account data", + "drop-down menu", + "NerdGraphQuery.query method" + ], + "external_id": "6bd6c8a72eab352a3e8f4332570e286c7831ba84", + "image": "https://developer.newrelic.com/static/5dcf6e45874c1fa40bb6f21151af0c24/b01d9/no-name.png", + "url": "https://developer.newrelic.com/build-apps/add-nerdgraphquery-guide/", + "published_at": "2020-08-19T01:48:31Z", + "updated_at": "2020-08-19T01:48:30Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.08006527, + "_score": 1.4216815, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Kubernetes integration: compatibility and requirements", - "sections": "Kubernetes integration", - "info": "Compatibility and requirements of the New Relic Kubernetes integration.", - "category_1": "Kubernetes integration", - "body": "New Relic's Kubernetes integration can be installed directly on a server or VM, or through several cloud platforms, such as GKE, EKS, AKS, or OpenShift. Each has a different compatibility with our integration. Compatibility Our Kubernetes integration is compatible with the following versions", - "breadcrumb": "Contents / Integrations / Kubernetes integration / Get started" + "title": "Add the NerdGraphQuery component to an application", + "sections": "Add the NerdGraphQuery component to an application", + "info": "The NerdGraphQuery component allows you to query data from your account and add it to a dropdown menu in an application", + "tags": "query account data", + "body": "Add the NerdGraphQuery component to an application 20 minutes This guide steps you through the process of adding the `NerdGraphQuery` component to a sample transaction overview application. This allows you to query data from your New Relic account and add it to a dropdown menu. NerdGraph is our" }, - "id": "5ea87c3be7b9d2c533748090" - } - ], - "/build-apps/map-pageviews-by-region": [ + "id": "5efa993c64441ff4865f7e32" + }, { - "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app, you might have some additional setup and configuration. This guide covers: Downloading the New Relic One CLI to build or modify apps Contribute content to this website Before you begin You must have: A github account account - While not strictly necessary for building apps, a GitHub account enables you to download and customize our open source apps, and contribute an open source project. A New Relic developer account - if you don't already have one, you can get a free trial account for developing New Relic applications. npm - If you've installed Node.js, then you already have npm, which is used to share, reuse, and update JavaScript code, and is necessary for working with React components that are the framework for New Relic apps and this website. Tip Use the NR1 VS Code extension to build your apps. Prepare to build or modify apps Step 1 of 2 Download the CLI and API key On the Build New Relic One applications page, complete the Quick start steps. These six Quick start steps get you an API key for use with developing apps, and the New Relic One CLI, for building and deploying apps. At the end of the Quick start, you have a project consisting of the following: A Nerdpack - The package containing all the files required by your application. It contains two types of files that you customize to build your app: Nerdlets, and the launcher. One or more Nerdlet files - A specific UI view or window. A Nerdlet is a React JavaScript package that includes an index.js file, a stylesheet, and a JSON-format config file. It can contain any JS functionality (charts, interactive fields, tooltips, etc.). A launcher file: This is the basis for the launcher, which is used to open your application from New Relic One after you publish your app. Step 2 of 2 Start building If you're ready to code, cd to your Nerdpack and get started. If you want to learn more about building applications, try these step-by-step guides: Build a \"Hello, World!\" application shows how to create a little application, publish it to New Relic One, and share it with others by subscribing accounts to it. Map pageviews by region takes you through the steps to create one of our popular open source apps. You learn to add a custom query to an app and view it in a table, then add that data to a map. Contributing to developer.newrelic.com This site is open source, and we want your input. Create a pull request if you see a mistake you know how to fix. Drop us a GitHub issue if you see some content gaps you want us to work on. Or write up a whole new guide if you have one you'd like to share. Read on to learn how. Step 1 of 3 Fork the developer-website GithHub repo Forking the repo enables you to work on your own copy of the developer.newrelic.com files, and build the site locally. It also enables us to more easily manage incomimg pull requests. On the developer-website page in GitHub, select the Fork button on the top right of the page, choose the account you want to fork to, and wait a few seconds while the fork is created. Sync regularly to keep your fork up to date with changes and additions to the main branch upstream. Step 2 of 3 Make a feature or documentation request On any page, select the GitHub button at the top of the page, and then select the kind of change you want, and fill out the GitHub form. Step 3 of 3 Contribute a new guide Check out our contributors guidelines, which will walk you through the process.", + "body": "Intro to NerdStorage 30 min To help you build a New Relic One application, we provide you with the New Relic One SDK. On this page, you’ll learn how to use NerdStorage SDK components. Use NerdStorage in your apps NerdStorage is used to store and retrieve simple sets of data, including users's configuration settings and preferences (like favorites), or any other small data sets. This storage is unique per Nerdpack, and can't be shared with any other Nerdpack. NerdStorage can be classified into three categories: User storage: Data that is attached to a particular user. If you’re authenticated as the user the data is attached to, you can read it and write it. Account storage: Data that is attached to a particular account. If you’re authenticated and can access the account, you can read and write to account scoped NerdStorage. Visibility of account data is also determined by master/subaccount rules: If a user has access to the master account, then they also have access to data in all subaccounts. Entity storage: Data that is attached to a particular entity. If you can see the corresponding entity, you can read and write data on that entity. Data model You can imagine NerdStorage as a nested key-value map. Data is inside documents, which are nested inside collections: { 'YourNerdpackUuid': { 'collection-1': { 'document-1-of-collection-1': '{\"lastNumber\": 42, \"another\": [1]}', 'document-2-of-collection-1': '\"userToken\"', // ... }, 'another-collection': { 'fruits': '[\"pear\", \"apple\"]', // ... }, // ... }, } Copy Each NerdStorage level has different properties and purpose: Collections: From a Nerdpack, you can create multiple collections by naming each of them. Inside a collection you can put one or more documents. Think of a collection as key-value storage, where each document is a key-value pair. Documents: A document is formed by an identifier (documentId) and a set of data associated with it. Data associated with a document: NerdStorage accepts any sort of data associated to a documentId. Query and mutation components that are provided work by serializing and deserializing JSON. Limits A Nerdpack can hold up to 1,000 collections and 10,000 documents, plus storage type. A collection can hold up to 1,000 documents, plus storage type. Each document can have a maximum length of 64 KiB when serialized. Data access To access NerdStorage, you can run NerdGraph queries, or use the provided storage queries. Depending on which storage you want to access, you can use a different set of SDK components: User access: UserStorageQuery and UserStorageMutation Account access: AccountStorageQuery and AccountStorageMutation Entity access: EntityStorageQuery and EntityStorageMutation Each of these components can operate declaratively (for example, as part of your React rendering methods) or imperatively (by using the static methods for query and mutation). For more information on this, see Data querying and mutations. Permissions for working with NerdStorage In order to persist changes on NerdStorage, such as creating, updating, and deleting account and entity storage, you must have a user role with permission to persist changes.", "type": "developer", "document_type": "page", - "info": "Prepare to build apps and contribute to this site", + "info": "Intro to NerdStorage on New Relic One", "sections": [ - "Set up your development environment", - "Before you begin", - "Tip", - "Prepare to build or modify apps", - "Download the CLI and API key", - "Start building", - "Contributing to developer.newrelic.com", - "Fork the developer-website GithHub repo", - "Make a feature or documentation request", - "Contribute a new guide" + "Intro to NerdStorage", + "Use NerdStorage in your apps", + "Data model", + "Limits", + "Data access", + "Permissions for working with NerdStorage" ], - "title": "Set up your development environment", + "title": "Intro to NerdStorage", "popularity": 1, - "external_id": "c45638a9cd548d1ffffc9f1c7708f115a92ae04a", + "tags": [ + "nerdstorage", + "nerdstorage components", + "new relic one apps", + "data access" + ], + "external_id": "709e06c25376d98b2191ca369b4d139e5084bd62", "image": "", - "url": "https://developer.newrelic.com/build-apps/set-up-dev-env/", - "published_at": "2020-08-18T02:08:12Z", - "updated_at": "2020-08-18T01:45:02Z", + "url": "https://developer.newrelic.com/explore-docs/nerdstorage/", + "published_at": "2020-08-19T01:49:36Z", + "updated_at": "2020-08-14T01:50:34Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.20750418, + "_score": 0.71296394, "_version": null, "_explanation": null, "sort": null, "highlight": { - "sections": "Prepare to build or modify apps", - "info": "Prepare to build apps and contribute to this site", - "body": " pageviews by region takes you through the steps to create one of our popular open source apps. You learn to add a custom query to an app and view it in a table, then add that data to a map. Contributing to developer.newrelic.com This site is open source, and we want your input. Create a pull request" + "title": "Intro to NerdStorage", + "sections": "Intro to NerdStorage", + "info": "Intro to NerdStorage on New Relic One", + "tags": "nerdstorage", + "body": " document is a key-value pair. Documents: A document is formed by an identifier (documentId) and a set of data associated with it. Data associated with a document: NerdStorage accepts any sort of data associated to a documentId. Query and mutation components that are provided work by serializing" }, - "id": "5efa9973e7b9d242237bab39" + "id": "5efa989ee7b9d2048e7bab92" }, { - "body": "New Relic APM's Summary page provides general information about the selected app, including web transactions and non-web transactions, Apdex score, CPU usage, throughput (requests per minute or rpm), transaction times, error rate, application activity, and hosts. To get a high-level overview of all your applications and services, use the entity explorer. View your app's summary page Here are two ways to reach the Summary page: Entity explorer: Go to one.newrelic.com > Entity explorer > (select an app). APM: Go to one.newrelic.com > APM > (select an app). For more information, see the documentation about navigating core UI components in New Relic One. View app performance Use the Summary page for a quick summary of your website's performance. Overview charts Some charts include links to APM pages where you can drill down into additional details. APM Summary chart Comments Transactions response time This stacked chart represents the response time of web transactions or non-web transactions in your app. Segments in the chart vary depending on which agent you are using. Some charts may have an independent line for response time that represents the relationship between response time and total time. Also, for your external or background services, you may see data labeled as Web external. For more information about these out-of-process services, use the Externals page. Apdex score This chart measures the performance of your app based on its Apdex T value during the selected time window. To view additional details, hover over the question question circle icon or the chart's End user and App server lines. The End user line charts the Apdex for your Browser apps, and the App server line charts the Apdex for your APM apps. Throughput This chart illustrates the requests per minute for either web transactions or non-web transactions. To change the type of transaction, select the Transaction response time chart's dropdown arrow, then select Web or Non-web. Error rate This chart shows the number of errors that have occurred in the current time window. The tooltip that appears when you hover over the Error rate chart shows the combined throughput for both web and non-web transactions. To understand how error rate is calculated, see Application error rate example. Event markers Markers on the main Summary chart indicate events and changes to the app: Black vertical bar: Apdex settings have changed. Blue vertical bar: A deployment marker has been created or another event has occurred, such as a settings change for the app. Yellow or red area: This indicates alert thresholds have been violated. To view additional information, mouse over the marker. Drill-down details Use any of New Relic's standard page functions to drill down into detailed information. Here is a summary of additional options with the APM Summary page. If you want to... Do this... Change how data appears on the main chart Select the chart title's drop-down arrow, and then select your choice of view options, including histograms or percentiles if available. View threshold levels for your app's Apdex score Mouse over the Apdex score ? icon. For non-web transactions, the Apdex chart is blank because Apdex is not applicable to this class of apps. View trends in transaction time, Apdex, and throughput Select the Compare with yesterday and last week checkbox. The checkbox is only available when viewing the Web transaction response time chart with the time picker window Ending now. The checkbox is unavailable if you are viewing histograms, percentiles, or custom dates. View app performance since the last deployment From the time picker, select Performance since the last deployment. For detailed information about all deployments, select the Deployments page. View the Transactions page Select the Transactions table's heading on the APM Summary page. Or, to view details about a specific transaction (including operations, transaction traces, and key transactions), select its name. View the Databases or External services pages Click on a related time band in the Web transactions response time chart. View the Errors page Select the Error rate chart's title on the APM Summary page. You can also view the Errors page from one.newrelic.com > (select an app) > Events > Errors. Browser details In order to view Browser details, you must enable this feature from Browser settings. However, if your app has never reported any browser monitoring data, you must first enable it from the application's settings: Go to one.newrelic.com > (select an app) > Settings > Application. From the New Relic Browser section, select the Enable browser monitoring? checkbox. Select Apdex values for browser monitoring and app server requests, or leave the defaults. Optional: Select up to five countries or regions for browser monitoring to highlight on the Geography page. Select Save application settings. To enable additional features, follow standard procedures from Browser > (selected app) > Settings. After New Relic Browser instrumentation is set up, the APM Summary page provides summary information and direct links to detailed information on the app's corresponding Browser Summary page. To view chart details with browser page load time, select the main chart's Browser link. To view the Apdex score for browsers, select the Apdex chart's Browser link. Link app performance to resources The APM Summary page shows a table with averages about your app's instances on their hosts, including: Apdex Response time Throughput Error rate CPU usage Memory CPU usage percentage is calculated as though the application is running on one CPU core. For more information about this calculation, see CPU usage is over 100%. Examine app performance within system context Use any of these options to examine your app's performance within the context of your system's architecture and resources, such as individual hosts: Select your choice from the table at the bottom of the APM Summary page for infrastructure. Toggle between a table view or breakout metric details. If applicable, select your choice from the drop-down at the top of the APM Summary page for servers or JVMs. Examine details within infrastructure To help you understand the full context of your app's performance within your environment, New Relic APM includes options to view performance from inside the application, as well as from outside the application with the infrastructure agent. To view detailed information from your resources' point of view, click any host link. The link takes you directly to the infrastructure Compute page. When you click, the Compute data may not immediately appear. If that happens, follow the prompt to validate your account and complete the conversion process for the infrastructure agent. If you need additional help, get support at support.newrelic.com. Troubleshoot host link To troubleshoot the host link from the APM Summary page, use these tips: Host link from APM Summary Troubleshooting tips Your infrastructure agent is not installed on the host. Follow standard procedures to install our infrastructure agent. The application is operating within a container, and your infrastructure agent is installed on the container’s host. Set the hostname for the container to be the hostname of the underlying server. Docker containers: Run your Docker container with the argument: --uts=\"host\" This will cause the container to share the UTS Linux Namespace with the underlying host. However, by using this set, a privileged container could change the host's hostname. The application is running on a Windows container, and your infrastructure agent is installed on the Windows host. To get a direct link to infrastructure metric data for your application, enable process metrics in the infrastructure agent's configuration. Your infrastructure agent is installed, but it only reports the short hostname, not the long hostname. Configure your server's hostname settings so that the infrastructure agent and the APM agent return the exact same name string. If possible, do so by editing your server's fully qualified domain name (FQDN) settings. The APM and infrastructure agents both read their hostname from the operating system's FQDN settings, so setting the hostname there ensures both agents share a single hostname. For more information, see the Java agent troubleshooting example. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", - "type": "docs", + "body": "Build apps You know better than anyone what information is crucial to your business, and how best to visualize it. Sometimes, this means going beyond dashboards to creating your own app. With React and GraphQL, you can create custom views tailored to your business. These guides are designed to help you start building apps, and dive into our library of components. We also have a growing number of open source apps that you can use to get started. The rest is up to you. Guides to build apps 15 min Create a \"Hello, World!\" application Build a \"Hello, World!\" app and publish it to New Relic One 20 min Publish and deploy apps Start sharing the apps you build 20 min Set up your development environment Prepare to build apps and contribute to this site 20 minutes Add the NerdGraphQuery component to an application The NerdGraphQuery component allows you to query data from your account and add it to a dropdown menu in an application 45 min Add, query, and mutate data using NerdStorage NerdStorage is a document database accessible within New Relic One. It allows you to modify, save, and retrieve documents from one session to the next. 20 min Add a time picker to your app Add a time picker to a sample application 30 min Add a table to your app Add a table to your New Relic One app 30 min Create a custom map view Build an app to show page view data on a map", + "type": "developer", "document_type": "page", - "breadcrumb": "Contents / APM / APM UI pages / Monitoring", - "info": "New Relic APM's Summary page provides charts and tables that you can drill down into details about your selected app’s performance.", - "nodeid": 3106, + "info": "", "sections": [ - "APM UI pages", - "Monitoring", - "Error analytics", - "Features", - "Events", - "APM Summary page: View transaction, Apdex, usage data", - "View your app's summary page", - "View app performance", - "Link app performance to resources", - "For more help" + "Build apps", + "Guides to build apps", + "Create a \"Hello, World!\" application", + "Publish and deploy apps", + "Set up your development environment", + "Add the NerdGraphQuery component to an application", + "Add, query, and mutate data using NerdStorage", + "Add a time picker to your app", + "Add a table to your app", + "Create a custom map view" ], - "title": "APM Summary page: View transaction, Apdex, usage data", - "translation_ja_url": "https://docs.newrelic.co.jp/docs/apm/apm-ui-pages/monitoring/apm-summary-page-view-transaction-apdex-usage-data", + "title": "Build apps", "popularity": 1, - "external_id": "107da0571b646cfe203af6c1114369e164edb390", - "category_1": "APM UI pages", - "category_2": "Monitoring", - "image": "https://docs.newrelic.com/sites/default/files/thumbnails/image/crop-apm-overview-hosts112116.png", - "url": "https://docs.newrelic.com/docs/apm/apm-ui-pages/monitoring/apm-summary-page-view-transaction-apdex-usage-data", - "published_at": "2020-08-18T12:28:49Z", - "updated_at": "2020-08-15T05:47:46Z", - "category_0": "APM", + "external_id": "abafbb8457d02084a1ca06f3bc68f7ca823edf1d", + "image": "", + "url": "https://developer.newrelic.com/build-apps/", + "published_at": "2020-08-19T01:44:47Z", + "updated_at": "2020-08-19T01:44:47Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.1375314, + "_score": 0.599496, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "APM Summary page: View transaction, Apdex, usage data", - "sections": "View your app's summary page", - "info": "New Relic APM's Summary page provides charts and tables that you can drill down into details about your selected app’s performance.", - "category_1": "APM UI pages", - "translation_ja_url": "https://docs.newrelic.co.jp/docs/apm/apm-ui-pages/monitoring/apm-summary-page-view-transaction-apdex-usage-data", - "body": " your applications and services, use the entity explorer. View your app's summary page Here are two ways to reach the Summary page: Entity explorer: Go to one.newrelic.com > Entity explorer > (select an app). APM: Go to one.newrelic.com > APM > (select an app). For more information, see" + "sections": "Add, query, and mutate data using NerdStorage", + "body": " it to a dropdown menu in an application 45 min Add, query, and mutate data using NerdStorage NerdStorage is a document database accessible within New Relic One. It allows you to modify, save, and retrieve documents from one session to the next. 20 min Add a time picker to your app Add a time picker" }, - "id": "5f377702196a67008755e629" + "id": "5efa999d64441fc0f75f7e21" }, { - "body": "Browser monitoring's Geography page provides a world view with color-coded Apdex scores and other performance information about your end users' experience. You can select specific geographic regions, such as countries or states, and then you can drill down to detailed information about page load performance and historical performance. Contents View performance data by region Firewalls may have an impact on the geographical data collected about your end users. To view or sort the performance information by location: one.newrelic.com > Browser > (select an app) > Geo: This page provides a world view and drill-down details of color-coded performance information for geographic locations. Go to one.newrelic.com > Browser > (select an app) > Geo > Global (for a world view). OR Go to one.newrelic.com > Browser > (select an app) > Geo > (select a location) (for a specific location you identified in the Browser application settings). To drill down to a specific area, select a location from the list, or select any area on the geographical map. To view additional details about the selected location, select the Page load performance or Historical performance links. To return to the main Geography page, select X (Close). one.newrelic.com > Browser > (select an app) > Geo > (select a location): If you selected specific locations from Settings > Application settings, the Geography page includes tabs to view their performance data directly. Use page functions Use any of our standard user interface functions and page functions to drill down into detailed information. Here is a summary of additional options with the Geography page: If you want to... Do this... Change how the performance data appears Select your choice from the Sort by menu. Adjust the amount of information that appears Select or clear the Hide <% throughput checkbox (<1% for global view, <2% for selected locations). View a map of a specific location Do any of these as applicable: Select the location's name from the Geo > Global list. Select its physical location on the map. If you have pre-selected the location from Application settings, select its tab. View summary performance information about a specific location Mouse over any colored area. View drill-down details After you select a specific location, the Page load performance page shows: Average page load time in seconds Number of page views and active sessions as pages per minute (ppm) Recent browser traces if applicable one.newrelic.com > Browser > (select an app) > Geo > (select a location): After you select a specific location, you can view specific details about Page load performance and Historical performance. In addition, the Historical performance page shows comparison data for the selected time period, yesterday, and last week for the selected location. This includes: Response time Apdex Throughput in pages per minute (ppm) For more help Additional documentation resources include the Page views page (details about end users' overall experience with your site). If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", - "type": "docs", + "body": "Query and store data 10 min To help you build a New Relic One application, we provide you with the New Relic One SDK. Here you can learn how to use the SDK query components, which allow you to make queries and mutations via NerdGraph, our GraphQL endpoint. Query-related React components can be identified by the Query suffix. Mutation-related components can be identified by the Mutation prefix. Components overview Our data components are based on React Apollo. The most basic component is NerdGraphQuery, which accepts any GraphQL (or GraphQL AST generated by the graphql-tag library as the query parameter, and a set of query variables passed as variables. Over this query, we have created an additional set of queries, which can be divided into four groups: User queries: These allow you to query the current user and its associated accounts. Components in this category: UserStorageQuery and AccountsQuery. Entities queries: Because New Relic One is entity-centric, we use queries to make access to your entities easier. You can count, search, list, query, and favorite them. Components in this category: EntityCountQuery, EntitySearchQuery, EntitiesByDomainTypeQuery, EntitiesByGuidsQuery, EntityByGuidQuery, EntityByNameQuery. Storage queries: New Relic One provides a simple storage mechanism that we call NerdStorage. This can be used by Nerdpack creators to store application configuration setting data, user-specific data, and other small pieces of data. Components in this category: UserStorageQuery, AccountStorageQuery, EntityStorageQuery, UserStorageMutation, AccountStorageMutation, and EntityStorageMutation. For details, see NerdStorage. NRQL queries: To be able to query your New Relic data via NRQL (New Relic Query Language), we provide a NrqlQuery component. This component can return data in different formats, so that you can use it for charting and not only for querying. Query components All query components accept a function as a children prop where the different statuses can be passed. This callback receives an object with the following properties: loading: Boolean that is set to true when data fetching is happening. Our components use the cache-and-network strategy, meaning that after the data has loaded, subsequent data reloads might be triggered first with stale data, then refreshed when the most recent data has arrived. data: Root property where the data requested is retrieved. The structure matches a root structure based on the NerdGraph schema. This is true even for highly nested data structures, which means you’ll have to traverse down to find the desired data. error: Contains an Error instance when the query fails. Set to undefined when data is loading or the fetch was successful. fetchMore: Callback function that can be called when the query is being loaded in chunks. The function will only be present when it’s feasible to do so, more data is available, and no fetchMore has already been triggered. Data is loaded in batches of 200 by default. Other components provided by the platform (like the Dropdown or the List) are capable of accepting fetchMore, meaning you can combine them easily. Mutation components Mutation components also accept a children as a function, like the query ones. The mutation can be preconfigured at the component level, and a function is passed back that you can use in your component. This is the standard React Apollo approach for performing mutations, but you might find it easier to use our static mutation method added to the component. More on this topic below. Static methods All of the described components also expose a static method so that they can be used imperatively rather than declaratively. All Query components have a static Query method, and all Mutation components have a mutation method. These static methods accept the same props as their query component, but passed as an object. For example: // Declarative way (using components). function renderAccountList() { return (
    ({data, error}) => { if (error) { return
  • Failed to retrieve list: {error.message}
  • ; } return data.map((account) => {
  • {account.name}
  • }); }}
); } // Imperative way (using promises). async function getAccountList() { let data = {}; try { data = await AccountsQuery.query(); } catch (error) { console.log('Failed to retrieve list: ' + error.message); return; } return data.actor.accounts.map((account) => { return account.name; }); } Copy Similarly, a mutation can happen either way; either declaratively or imperatively. NrqlQuery NrqlQuery deserves additional explanation, because there are multiple formats in which you can return data from it. To provide maximum functionality, all three are exposed through a formatType property. You can find its different values under NrqlQuery.formatType: NERD_GRAPH: Returns the format in which it arrives from NerdGraph. RAW: The format exposed by default in Insights and dashboards when being plotted as JSON. This format is useful if you have a pre-existing script in this format that you're willing to migrate to or incorporate with. CHART: The format used by the charting engine that we also expose. You can find a more detailed explanation of how to manipulate this format in the guide to chart components, and some examples. If you are willing to push data, we currently do not expose NrqlMutation. To do that, see the Event API for how to add custom events.", + "type": "developer", "document_type": "page", - "breadcrumb": "Contents / Browser monitoring / Browser monitoring / Additional standard features", - "info": "Browser's Geography feature shows color-coded Apdex scores and page load performance for your end users' experience around the world.", - "nodeid": 1921, + "info": "Reference guide for SDK query components using NerdGraph", "sections": [ - "Browser monitoring", - "Getting started", - "Guides", - "Installation", - "Configuration", - "Browser agent and SPA API", - "Page load timing resources", - "Browser Pro features", - "Additional standard features", - "Performance quality", - "Troubleshooting", - "Browser Geography: Webpage performance by location", - "Contents", - "View performance data by region", - "Use page functions", - "View drill-down details", - "For more help" + "Query and store data", + "Components overview", + "Query components", + "Mutation components", + "Static methods", + "NrqlQuery" ], - "title": "Browser Geography: Webpage performance by location", + "title": "Query and store data", "popularity": 1, - "external_id": "ccbfe8376f2aee5d35b31dbcee84ff1cbff5b094", - "category_1": "Browser monitoring", - "category_2": "Additional standard features", - "image": "https://docs.newrelic.com/sites/default/files/thumbnails/image/geo_overview.png", - "url": "https://docs.newrelic.com/docs/browser/new-relic-browser/additional-standard-features/browser-geography-webpage-performance-location", - "published_at": "2020-08-18T11:30:40Z", - "updated_at": "2020-08-15T09:25:45Z", - "category_0": "Browser monitoring", - "_index": "520d1d5d14cc8a32e600034b", - "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.118906915, - "_version": null, - "_explanation": null, - "sort": null, - "highlight": { - "sections": "View performance data by region", - "info": "Browser's Geography feature shows color-coded Apdex scores and page load performance for your end users' experience around the world.", - "body": " performance and historical performance. Contents View performance data by region Firewalls may have an impact on the geographical data collected about your end users. To view or sort the performance information by location: one.newrelic.com > Browser > (select an app) > Geo: This page provides a world" - }, - "id": "561c8bbc827a6617ad000172" - }, - { - "body": "Browser monitoring supports the uploading of source maps, which are used to un-minify error stack traces on the JS errors page. This document explains how to use the API to publish (upload) source maps to Browser. Prepare for using the source map API In order to upload source maps to Browser via the API, you'll need this information: An admin API key for the New Relic account The New Relic application ID for the deployed app The full JavaScript file URL Optionally, if the JavaScript URL doesn't automatically have release info appended to it, the release name and ID What is the JavaScript URL? Every time the agent captures an error in your code, it's associated with the URL of the JavaScript in which it occurred. This is the src attribute of the script tag in your HTML. This full JavaScript URL is required when sending source maps to Browser. You can find the URL for an error's JavaScript file in Browser, on the JS errors page. See Browser monitoring source maps for more on finding these errors in the UI. Is a release name and ID required? Many organizations include a version number or hash in the JavaScript URL. This is generally added to \"bust\" caches to ensure your users get the most recent version of your code. This type of URL might look something like: https://example.com/assets/application-59.min.js https://example.com/assets/bundle-d6d031.min.js https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js If your app's URLs automatically have the version info appended to it, the Browser agent has everything it needs in order to match errors with your code. You can move ahead to generating source maps. If this doesn't apply to you, and JS URLs do not have version info appended, you’ll have to assist the agent by specifying a release name and ID with the API. Are there limits to source map uploads? There is no limit to the overall number of source maps you can upload. However, the API is rate-limited: You can upload a maximum of 100 source maps per minute You can upload a maximum of 5,000 source maps per day Source map files can be a maximum of 50Mb in size. Push source maps to New Relic Now that you have one or more source maps, you are ready to publish it to Browser. You can use any of these methods to send source maps to Browser: Use the New Relic npm module with the API via the command line or via a client-side JavaScript build/deploy script like Gulp or Grunt. Use API curl commands. Use the Browser UI. Use npm module via command line or client-side script The easiest and recommended way to upload source maps to Browser is to use the our new @newrelic/publish-sourcemap npm module. It provides a command line tool and Javascript API to accomplish this task. More documentation is available in the npm repo. Here are some examples of using the npm module via the command line. The following examples are for US accounts. For EU accounts, the endpoint is https://sourcemaps.service.eu.newrelic.com. For more information, see Introduction to the EU region data center. npm command line: Publish Here's an example of uploading source maps using the npm module via the command line. Note that the source map can come from a local file or a remote URL. npm install -g @newrelic/publish-sourcemap publish-sourcemap PATH_TO_SOURCE_MAP_FILE (local or remote) PATH_TO_ORIGINAL_FILE --nrAdminKey=YOUR_NEW_RELIC_ADMIN_API_KEY --applicationId=YOUR_NEW_RELIC_APP_ID npm command line: List published maps Here's an example of listing published source maps: list-sourcemaps --applicationId=YOUR_APP_ID --nrAdminKey=YOUR_NEW_RELIC_ADMIN_KEY Options: --applicationId Browser application id --nrAdminKey New Relic admin API key npm command line: Delete Here's an example of deleting a source map: delete-sourcemap --applicationId=YOUR_APP_ID --nrAdminKey=YOUR_NEW_RELIC_ADMIN_API_KEY --sourcemapId=YOUR_SOURCE_MAP_ID Options: --applicationId Browser application id --nrAdminKey New Relic admin API key --sourcemapId Unique id generated for a source map Here are some examples of using the npm module to publish from client-side JavaScript: npm via Node.js script: Publish Here's an example of publishing a source map via a Node.js script: var publishSourcemap = require(‘@newrelic/publish-sourcemap’).publishSourcemap publishSourcemap({ sourcemapPath: 'SOURCE_MAP_FULL_PATH', javascriptUrl: 'JS_URL', applicationId: YOUR_NEW_RELIC_APP_ID, nrAdminKey: 'YOUR_NEW_RELIC_ADMIN_API_KEY' }, function (err) { console.log(err || 'Sourcemap upload done')}) npm via Node.js script: List published maps Here's an example of listing all published source maps: var listSourcemaps = require(‘@newrelic/publish-sourcemap’).listSourcemaps listSourcemaps({ sourcemapPath: 'SOURCE_MAP_FULL_PATH', javascriptUrl: 'JS_URL', applicationId: YOUR_NEW_RELIC_APP_ID, nrAdminKey: 'YOUR_NEW_RELIC_ADMIN_API_KEY', }, function (err, res) { console.log(err || res.body)}) npm via Node.js script: Delete Here's an example of deleting a source map file via a Node.js script: var deleteSourcemap = require(‘@newrelic/publish-sourcemap’).deleteSourcemap deleteSourcemap({ sourcemapId: 'SOURCE_MAP_ID', applicationId: YOUR_NEW_RELIC_APP_ID, nrAdminKey: 'YOUR_NEW_RELIC_ADMIN_API_KEY', }, function (err) { console.log(err || 'Deleted source map')}) When you're done, go to the JS errors page in Browser, select an error grouping, and see if your error stack traces have been un-minified. Use API via curl Below are some examples of using curl to publish, list, and delete source maps: curl: Upload maps An example of using API via curl to publish maps to Browser: curl -H \"Newrelic-Api-Key: YOUR_NEW_RELIC_ADMIN_API_KEY\" \\ -F \"sourcemap=@SOURCE_MAP_PATH\" \\ -F \"javascriptUrl=JS_URL\" \\ -F \"releaseId=YOUR_RELEASE_ID\" \\ -F \"releaseName=YOUR_UI_PAGE\" \\ https://sourcemaps.service.newrelic.com/v2/applications/YOUR_NEW_RELIC_APP_ID/sourcemaps curl: List existing maps Below is an example of how to get a list of source maps previously uploaded to New Relic via curl. New Relic returns the source map's unique SOURCEMAP_ID and its components: curl \\ -H \"Newrelic-Api-Key: YOUR_NEW_RELIC_ADMIN_API_KEY\" \\ https://sourcemaps.service.newrelic.com/v2/applications/YOUR_NEW_RELIC_APP_ID/sourcemaps curl: Delete map To delete a source map: Use the GET endpoint to list existing source maps and locate the SOURCEMAP_ID. Run the following command via curl: curl -X DELETE \\ -H \"Newrelic-Api-Key: YOUR_NEW_RELIC_ADMIN_API_KEY\" \\ https://sourcemaps.service.newrelic.com/v2/applications/YOUR_NEW_RELIC_APP_ID/sourcemaps/SOURCEMAP_ID When you're done, go to the JS errors page in Browser, select an error grouping, and see if your error stack traces have been un-minified. Troubleshoot source maps If you are having trouble generating source maps from your build system, or if your errors in Browser are remaining minified, see the source maps troubleshooting documentation. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", - "type": "docs", - "document_type": "page", - "breadcrumb": "Contents / Browser monitoring / Browser monitoring / Browser Pro features", - "info": "For Browser, how to upload and use source maps with the Browser API.", - "nodeid": 11696, - "sections": [ - "Browser monitoring", - "Getting started", - "Guides", - "Installation", - "Configuration", - "Browser agent and SPA API", - "Page load timing resources", - "Browser Pro features", - "Additional standard features", - "Performance quality", - "Troubleshooting", - "Upload source maps via API", - "Prepare for using the source map API", - "Push source maps to New Relic", - "Use npm module via command line or client-side script", - "Use API via curl", - "Troubleshoot source maps", - "For more help" + "tags": [ + "nerdgraph query components", + "mutation components", + "static methods" ], - "title": "Upload source maps via API", - "popularity": 1, - "external_id": "6bc1cf3a1c7f6a2b7bdf464b7a6578b093950182", - "category_1": "Browser monitoring", - "category_2": "Browser Pro features", + "external_id": "cbbf363393edeefbc4c08f9754b43d38fd911026", "image": "", - "url": "https://docs.newrelic.com/docs/browser/new-relic-browser/browser-pro-features/upload-source-maps-api", - "published_at": "2020-08-18T16:05:37Z", - "updated_at": "2020-08-15T08:45:07Z", - "category_0": "Browser monitoring", + "url": "https://developer.newrelic.com/explore-docs/query-and-store-data/", + "published_at": "2020-08-19T01:51:37Z", + "updated_at": "2020-08-01T01:42:02Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.09365238, + "_score": 0.14321977, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Upload source maps via API", - "sections": "Page load timing resources", - "info": "For Browser, how to upload and use source maps with the Browser API.", - "body": ": 'SOURCE_MAP_ID', applicationId: YOUR_NEW_RELIC_APP_ID, nrAdminKey: 'YOUR_NEW_RELIC_ADMIN_API_KEY', }, function (err) { console.log(err || 'Deleted source map')}) When you're done, go to the JS errors page in Browser, select an error grouping, and see if your error stack traces have been un-minified. Use API" + "title": "Query and store data", + "sections": "Query and store data", + "info": "Reference guide for SDK query components using NerdGraph", + "tags": "nerdgraph query components", + "body": ", EntityByGuidQuery, EntityByNameQuery. Storage queries: New Relic One provides a simple storage mechanism that we call NerdStorage. This can be used by Nerdpack creators to store application configuration setting data, user-specific data, and other small pieces of data. Components in this category" }, - "id": "5c6905d607552356e245ca12" + "id": "5efa989e28ccbc2f15307deb" }, { - "body": "Intro to NerdStorage 30 min To help you build a New Relic One application, we provide you with the New Relic One SDK. On this page, you’ll learn how to use NerdStorage SDK components. Use NerdStorage in your apps NerdStorage is used to store and retrieve simple sets of data, including users's configuration settings and preferences (like favorites), or any other small data sets. This storage is unique per Nerdpack, and can't be shared with any other Nerdpack. NerdStorage can be classified into three categories: User storage: Data that is attached to a particular user. If you’re authenticated as the user the data is attached to, you can read it and write it. Account storage: Data that is attached to a particular account. If you’re authenticated and can access the account, you can read and write to account scoped NerdStorage. Visibility of account data is also determined by master/subaccount rules: If a user has access to the master account, then they also have access to data in all subaccounts. Entity storage: Data that is attached to a particular entity. If you can see the corresponding entity, you can read and write data on that entity. Data model You can imagine NerdStorage as a nested key-value map. Data is inside documents, which are nested inside collections: { 'YourNerdpackUuid': { 'collection-1': { 'document-1-of-collection-1': '{\"lastNumber\": 42, \"another\": [1]}', 'document-2-of-collection-1': '\"userToken\"', // ... }, 'another-collection': { 'fruits': '[\"pear\", \"apple\"]', // ... }, // ... }, } Copy Each NerdStorage level has different properties and purpose: Collections: From a Nerdpack, you can create multiple collections by naming each of them. Inside a collection you can put one or more documents. Think of a collection as key-value storage, where each document is a key-value pair. Documents: A document is formed by an identifier (documentId) and a set of data associated with it. Data associated with a document: NerdStorage accepts any sort of data associated to a documentId. Query and mutation components that are provided work by serializing and deserializing JSON. Limits A Nerdpack can hold up to 1,000 collections and 10,000 documents, plus storage type. A collection can hold up to 1,000 documents, plus storage type. Each document can have a maximum length of 64 KiB when serialized. Data access To access NerdStorage, you can run NerdGraph queries, or use the provided storage queries. Depending on which storage you want to access, you can use a different set of SDK components: User access: UserStorageQuery and UserStorageMutation Account access: AccountStorageQuery and AccountStorageMutation Entity access: EntityStorageQuery and EntityStorageMutation Each of these components can operate declaratively (for example, as part of your React rendering methods) or imperatively (by using the static methods for query and mutation). For more information on this, see Data querying and mutations. Permissions for working with NerdStorage In order to persist changes on NerdStorage, such as creating, updating, and deleting account and entity storage, you must have a user role with permission to persist changes.", + "body": "Query data with NRQL 10 min With NRQL, you can query any of the default event data being reported by New Relic, plus any custom events and attributes you’ve added. Step 1 of 4 NRQL syntax is comparable to ANSI SQL. Learn more about NRQL syntax SELECT function(attribute) [AS 'label'][, ...] FROM event [WHERE attribute [comparison] [AND|OR ...]][AS 'label'][, ...] [FACET attribute | function(attribute)] [LIMIT number] [SINCE time] [UNTIL time] [WITH TIMEZONE timezone] [COMPARE WITH time] [TIMESERIES time] Copy Step 2 of 4 NRQL queries can be as simple as fetching rows of data in a raw tabular form to inspect individual events. Learn what events open source agents provide out of the box -- Fetch a list of Browser PageView events SELECT * FROM PageView Copy Step 3 of 4 NRQL queries can also do extremely powerful calculations before the data is presented to you, such as crafting funnels based on the way people actually use your website. Learn more about NRQL funnels -- See how many users visit, signup, browse and purchase from your site as a funnel SELECT funnel(session, WHERE pageUrl='http://www.demotron.com/' AS 'Visited Homepage', WHERE pageUrl='http://www.demotron.com/signup' AS 'Signed Up', WHERE pageUrl='http://www.demotron.com/browse' AS 'Browsed Items', WHERE pageUrl='http://www.demotron.com/checkout' AS 'Made Purchase') FROM PageView SINCE 12 hours ago Copy Step 4 of 4 Using NRQL, you can customize your New Relic experience by crafting diverse dashboards that show your data from multiple angles. You can share these dashboards with technical and non-technical stakeholders alike. Learn more and start building Documentation For an overview of NRQL syntax, see Introduction to NRQL. For a detailed description of all available functions, see NRQL syntax, components, and functions. NRU Tutorials To learn how to query and narrow a large data store by a specific parameter, watch the tutorial on Filtering queries with NRQL. Community forum Connect with other developers in the our Explorers Hub. GitHub For examples of integrations and other technologies, check us out on GitHub.", "type": "developer", "document_type": "page", - "info": "Intro to NerdStorage on New Relic One", + "info": "Query default event data as well as custom events and attributes with our powerful, SQL-like query language. Start querying now.", "sections": [ - "Intro to NerdStorage", - "Use NerdStorage in your apps", - "Data model", - "Limits", - "Data access", - "Permissions for working with NerdStorage" + "Query data with NRQL", + "Learn more and start building", + "Documentation", + "NRU Tutorials", + "Community forum", + "GitHub" ], - "title": "Intro to NerdStorage", + "title": "Query data with NRQL", "popularity": 1, - "external_id": "709e06c25376d98b2191ca369b4d139e5084bd62", - "image": "", - "url": "https://developer.newrelic.com/explore-docs/nerdstorage/", - "published_at": "2020-08-18T02:11:48Z", - "updated_at": "2020-08-14T01:50:34Z", + "tags": [ + "NRQL", + "NRQL syntax", + "calculate data NRQL" + ], + "external_id": "7bb23b086badd7a572964357aad776116f5bfbbe", + "image": "https://developer.newrelic.com/static/eb2adf50e7680e8ba5b7daaf06c203d1/757a2/nr1-dashboard.png", + "url": "https://developer.newrelic.com/collect-data/query-data-nrql/", + "published_at": "2020-08-19T01:44:48Z", + "updated_at": "2020-08-14T01:46:10Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.07781543, + "_score": 0.08821742, "_version": null, "_explanation": null, "sort": null, "highlight": { - "sections": "Use NerdStorage in your apps", - "body": " as a nested key-value map. Data is inside documents, which are nested inside collections: { 'YourNerdpackUuid': { 'collection-1': { 'document-1-of-collection-1': '{"lastNumber": 42, "another": [1]}', 'document-2-of-collection-1': '"userToken"', // ... }, 'another-collection': { 'fruits': '["pear", "apple" + "title": "Query data with NRQL", + "sections": "Query data with NRQL", + "info": "Query default event data as well as custom events and attributes with our powerful, SQL-like query language. Start querying now.", + "tags": "calculate data NRQL", + "body": "Query data with NRQL 10 min With NRQL, you can query any of the default event data being reported by New Relic, plus any custom events and attributes you’ve added. Step 1 of 4 NRQL syntax is comparable to ANSI SQL. Learn more about NRQL syntax SELECT function(attribute) [AS 'label'][, ...] FROM" }, - "id": "5efa989ee7b9d2048e7bab92" + "id": "5efa999ce7b9d29f377bab69" } ], - "/collect-data/custom-attributes": [ + "/automate-workflows/get-started-terraform": [ { - "body": "New Relic allows you to collect custom attributes. For example, you can create a custom attribute to track the user name associated with a slow or failing request. This document contains links to docs on how to do this for APM, infrastructure monitoring, browser monitoring, and mobile monitoring. APM: Record custom attributes Review the list of reserved terms used by NRQL. Using reserved terms can cause issues. To enable and use custom attributes for APM, follow the procedure for your APM agent: C SDK To add custom attributes to applications monitored by the C SDK, call one of the attribute functions; for example, newrelic_add_attribute_double(). The key name for your custom attribute depends on what you specify when you call the function. Go Custom attribute collection is enabled by default in the Go agent. However, you can disable custom attribute collection. Java Custom attribute collection is enabled by default in Java. You can collect custom attributes using XML and the Java agent APIs. These two methods can be used in conjunction with each other. Method How to do it Specify attributes in XML XML allows you to specify custom attributes without changing any of your source code. You can have multiple XML files for custom attributes that are grouped by some logical facet. To set custom attributes for your Java app via XML: Review the New Relic Java agent's documentation about XML file format, methods and classes, and examples. From your Extensions directory within the New Relic Java agent, create a single XML file. Define the methods you want New Relic to monitor by editing your XML file directly. Define an XML instrumentation file using the New Relic UI. This may require additional config in the common: block of your newrelic.yml. See Report custom attributes under Instrumentation options for more detail. Call the agent's API Example 1: Adding custom attributes to transactions To collect custom attributes using the agent's API, call the relevant methods: For each method you want to record an attribute for, call NewRelic.addCustomParameter(...). Optional: Include or exclude certain attributes with attributes.include and attributes.exclude. For example, to record a variable named userId, include this code in the parent method: NewRelic.addCustomParameter(\"userId\", userId); Example 2: Adding custom attributes to spans in distributed traces To collect custom attributes using the agent's API, call the relevant methods: For each span (currently executing method) that you want to record an attribute for, call NewRelic.getAgent().getTracedMethod().addCustomAttribute(...). Optional: Include or exclude certain attributes with span_events.attributes.include and span_events.attributes.exclude. For example, to record a variable named userId on the current span, include this code in the associated method: NewRelic.getAgent().getTracedMethod().addCustomAttribute(\"userId\", userId); Collect user attributes The Java agent also includes a built-in mechanism to enable user attributes and collect user information from HttpServletRequest.getUserPrincipal() as custom attributes. .NET Custom attribute collection is enabled by default in .NET. To collect custom attributes, call the relevant API methods: For each method for which you want to record an attribute, call AddCustomAttribute. Optional: Include or exclude attributes with the include and exclude configuration options. For example, to record attributes for a coupon code (string) and an item ID code (number), you could include this code in the parent method: IAgent agent = NewRelic.Api.Agent.NewRelic.GetAgent(); ITransaction transaction = agent.CurrentTransaction; transaction .AddCustomAttribute(\"Discount Code\", \"Summer Super Sale\") .AddCustomAttribute(\"Item Code\", 31456); Node.js Custom attribute collection is enabled by default in Node.js. To collect custom attributes, call the relevant API method: For each attribute you want to record, call newrelic.addCustomAttribute. To record multiple attributes using a single call, use newrelic.addCustomAttributes. For example, to record attributes for a coupon code and an item ID code, you could include this in the parent method: newrelic.addCustomAttributes({ \"Discount Code\": \"Summer Super Sale\", \"Item Code\": 31456 }); PHP Custom attribute collection is enabled by default in PHP. To collect custom attributes, call the relevant API method for each method that you want to record an attribute; newrelic_add_custom_parameter for transaction events and spans newrelic_add_custom_span_parameter for only spans For example, to record a variable named $userId, include this code in the parent method: newrelic_add_custom_parameter ('userID', $userId) Python Custom attribute collection is enabled by default in Python. To collect custom attributes, call add_custom_parameter for each method that you want to record an attribute. For example, to record a variable named user_id, include this code in the parent method: newrelic.agent.add_custom_parameter('user_id', user_id) Ruby Custom attribute collection is enabled by default in Ruby. To collect custom attributes, call the relevant API methods: For Ruby agent version 3.12.0 or higher, use the add_custom_attributes method. For example, to record a variable named @user_id, include this code in the parent method: ::NewRelic::Agent.add_custom_attributes({ user_id: @user.id }) For Ruby agent version 3.11.2 or lower, use the add_custom_parameters method. For example, to record a variable named @user_id, include this code in the parent method: ::NewRelic::Agent.add_custom_parameters({ user_id: @user.id }) Browser monitoring: Record custom attributes The browser agent provides an API to specify extra details associated with a page view or browser interaction, either by forwarding attributes from APM to browser monitoring or by specifying custom attributes through JavaScript. Values forwarded from the APM agent are encoded and injected into browser attributes by our browser agent. Infrastructure monitoring: Record custom attributes Our Infrastructure monitoring lets you create custom attributes that are used to annotate the data from the infrastructure agent. You can use this metadata to build filter sets, group your results, and annotate your data. Mobile monitoring: Record custom attributes Mobile agents include API calls to record custom attributes: For an overview of mobile monitoring custom data, see Insert custom events and attributes Android method: setAttribute iOS method: setAttribute For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "body": "In order to provide a unified experience, we're deprecating Synthetics monitor alert notifications and alert conditions violations, and replacing these pages with a new synthetic monitor overview experience in New Relic One. This new experience provides visibility into a monitor's open violations and alert conditions with the monitor results in a single view, removing the need to open multiple tabs to view violations or alert conditions. For more information, check the EoL Announcements page. If you want to receive alert notifications when a synthetic monitor fails, you can configure the alert notification either while creating a monitor or after you have created one. You can configure your monitor's alert policy directly from the Synthetics UI or via the Alerts UI for existing monitors. To identify which monitors do not have policies assigned to them, review their color-coded health status. Add a synthetic monitor to alert policies A monitor can be included in multiple alert policies. You can view the alert policies and conditions for the selected monitor from the Synthetics UI or from the Alerts UI. To add an existing monitor to an alert policy: Go to one.newrelic.com > Alerts & AI > Policies. From the list of existing alert policies, use the search box or scroll the list to locate one or more alert policies where the monitor has not already been added. Open the policy, then click Add a condition. Click Synthetics and then select the monitor. Fill out the remaining settings and click Create condition. Existing monitor: Remove from alert policy To remove an existing monitor from an existing alert policy: Go to one.newrelic.com > Alerts & AI > Policies. From the list of existing alert policies, use the search box or scroll the list to locate one or more alert policies where the monitor has not already been added. Select the trash can (delete) icon on the monitor's row. Receive alert notifications on a three-strike basis Synthetic alert notifications operate on a three-strike basis, sending an alert after three monitor attempts from a single location return an error. Your alert policy configuration and notification channel settings will determine when you receive alerts for specific monitors and locations. If you monitor a non-public app and add your selected public minion IPs to your allow list, you may very infrequently receive a false downtime alert. When a synthetic monitoring data center goes down, New Relic may decide to temporarily use an alternate host, which results in the temporary server's IP being blocked by your app. Mute (disable) monitor's alert notifications To temporarily disable alerting for a monitor, mute it: Go to one.newrelic.com > Synthetics > Monitors > (select a monitor). Click General under the Settings menu in the left menu sidebar. Click the Notifications button to Off. Muting a monitor's alert notifications will not mute multi-location alerts or NRQL alerts. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", "type": "docs", "document_type": "page", - "breadcrumb": "Contents / Using New Relic / Cross-product functions / Install and configure", - "info": "How to add custom attributes to data reported from some New Relic products. ", - "nodeid": 2726, + "breadcrumb": "Contents / Synthetic monitoring / Synthetic monitoring / Using monitors", + "info": "New Relic can use alerts to notify you about synthetic monitors's failures.", + "nodeid": 6371, "sections": [ - "Cross-product functions", - "Install and configure", + "Synthetic monitoring", + "Getting started", + "Guides", + "Using monitors", + "Monitor scripting", + "Administration", + "Private locations", + "UI pages", + "Synthetics API", "Troubleshooting", - "Collect custom attributes", - "APM: Record custom attributes", - "Browser monitoring: Record custom attributes", - "Infrastructure monitoring: Record custom attributes", - "Mobile monitoring: Record custom attributes", + "Alerts for synthetic monitoring", + "Add a synthetic monitor to alert policies", + "Existing monitor: Remove from alert policy", + "Receive alert notifications on a three-strike basis", + "Mute (disable) monitor's alert notifications", "For more help" ], - "title": "Collect custom attributes", + "title": "Alerts for synthetic monitoring", + "translation_ja_url": "https://docs.newrelic.co.jp/docs/synthetics/synthetic-monitoring/using-monitors/alerts-synthetic-monitoring", "popularity": 1, - "external_id": "5a43638e8ef969ce9f0b16fedf433317e67bb4a6", - "category_1": "Cross-product functions", - "category_2": "Install and configure", + "external_id": "b69353439d3cc180ca46c64bef5e8470cdda1636", + "category_1": "Synthetic monitoring", + "category_2": "Using monitors", "image": "", - "url": "https://docs.newrelic.com/docs/using-new-relic/data/customize-data/collect-custom-attributes", - "published_at": "2020-08-18T14:20:45Z", - "updated_at": "2020-08-11T00:28:22Z", - "category_0": "Using New Relic", + "url": "https://docs.newrelic.com/docs/synthetics/synthetic-monitoring/using-monitors/alerts-synthetic-monitoring", + "published_at": "2020-08-18T11:09:08Z", + "updated_at": "2020-08-14T00:47:54Z", + "category_0": "Synthetic monitoring", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.73719656, + "_score": 0.5474124, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Collect custom attributes", - "sections": "Collect custom attributes", - "info": "How to add custom attributes to data reported from some New Relic products. ", - "body": ". APM: Record custom attributes Review the list of reserved terms used by NRQL. Using reserved terms can cause issues. To enable and use custom attributes for APM, follow the procedure for your APM agent: C SDK To add custom attributes to applications monitored by the C SDK, call one of the attribute" + "title": "Alerts for synthetic monitoring", + "sections": "Mute (disable) monitor's alert notifications", + "info": "New Relic can use alerts to notify you about synthetic monitors's failures.", + "category_0": "Synthetic monitoring", + "category_1": "Synthetic monitoring", + "category_2": "Using monitors", + "translation_ja_url": "https://docs.newrelic.co.jp/docs/synthetics/synthetic-monitoring/using-monitors/alerts-synthetic-monitoring", + "body": " the alert notification either while creating a monitor or after you have created one. You can configure your monitor's alert policy directly from the Synthetics UI or via the Alerts UI for existing monitors. To identify which monitors do not have policies assigned to them, review their color-coded health", + "breadcrumb": "Contents / Synthetic monitoring / Synthetic monitoring / Using monitors" }, - "id": "5e9a9d9728ccbc90cdd949ca" + "id": "5f31b60e196a6742d2fbd6c8" }, { - "body": "In New Relic, attributes are key-value pairs containing information that determines the properties of an event or transaction. These key-value pairs can help you gain greater insight into your application and query your data. View and use attributes Both default APM attributes and custom attributes for your C application appear in: APM transaction traces and error analytics APM events C-specific attributes Before creating custom attributes, review New Relic's list of reserved terms used by NRQL. Otherwise unexpected results may occur. To add custom attributes to your C application, call one of the attribute functions in the C SDK API; for example, newrelic_add_attribute_double(). The key name for your custom attribute depends on what you specify when you call the function. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "body": "If you delete a channel, you cannot restore it. If you want to keep the notification channel, you can remove it from any associated policy. Delete a channel To delete a channel permanently: Go to one.newrelic.com, in the top nav click Alerts & AI, then click Notification channels. Optional: To find the notification channel easily, search the Notification channels index. From the Notification channels index, select the channel's delete icon, and then select the confirmation prompt to cancel or continue. When you delete (or remove) a channel, any policies associated with it will still remain. You must delete policies separately. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", "type": "docs", "document_type": "page", - "breadcrumb": "Contents / APM agents / C SDK / Instrumentation", - "info": "You can create custom attributes for your C app to supplement the New Relic event data that automatically includes default APM attributes.", - "nodeid": 15891, + "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / Alert notifications", + "info": "You can delete alerts notification channels permanently or you can keep channels but remove them from associated policies.", + "nodeid": 6471, "sections": [ - "C SDK", + "New Relic Alerts", "Get started", - "Install and configure", - "Instrumentation", + "Alert policies", + "Alert conditions", + "Alert violations", + "Alert Incidents", + "Alert notifications", "Troubleshooting", - "Use default or custom attributes (C SDK)", - "View and use attributes", - "C-specific attributes", + "Rules, limits, and glossary", + "Alerts and Nerdgraph", + "REST API alerts", + "Delete alert notification channels", + "Delete a channel", "For more help" ], - "title": "Use default or custom attributes (C SDK)", + "title": "Delete alert notification channels", "popularity": 1, - "external_id": "45876c14a1d258566a824f7c49a50bb8c8fb709d", - "category_1": "C SDK", - "category_2": "Instrumentation", + "external_id": "dcea3b60f23ddeb74a7a0a0f44a5130cd9e2885d", + "category_1": "New Relic Alerts", + "category_2": "Alert notifications", "image": "", - "url": "https://docs.newrelic.com/docs/agents/c-sdk/instrumentation/use-default-or-custom-attributes-c-sdk", - "published_at": "2020-08-18T08:14:25Z", - "updated_at": "2020-08-15T02:11:23Z", - "category_0": "APM agents", + "url": "https://docs.newrelic.com/docs/alerts-applied-intelligence/new-relic-alerts/alert-notifications/delete-alert-notification-channels", + "published_at": "2020-08-18T18:07:05Z", + "updated_at": "2020-08-15T07:46:52Z", + "category_0": "Alerts and Applied intelligence", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.6753373, + "_score": 0.53230405, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Use default or custom attributes (C SDK)", - "sections": "Use default or custom attributes (C SDK)", - "info": "You can create custom attributes for your C app to supplement the New Relic event data that automatically includes default APM attributes.", - "body": " for your C application appear in: APM transaction traces and error analytics APM events C-specific attributes Before creating custom attributes, review New Relic's list of reserved terms used by NRQL. Otherwise unexpected results may occur. To add custom attributes to your C application, call one" + "title": "Delete alert notification channels", + "sections": "Delete alert notification channels", + "info": "You can delete alerts notification channels permanently or you can keep channels but remove them from associated policies.", + "category_2": "Alert notifications", + "body": "If you delete a channel, you cannot restore it. If you want to keep the notification channel, you can remove it from any associated policy. Delete a channel To delete a channel permanently: Go to one.newrelic.com, in the top nav click Alerts & AI, then click Notification channels. Optional: To find" }, - "id": "5cd8abf7e621f45d85a089a9" + "id": "5f2dbb3628ccbc65c788dfcb" }, { - "body": "When adding custom attribute values to transactions, custom events, spans, and errors, the APIs accept an object. This describes how these values are processed and how they will appear in APM. In all cases, NULL values are not recorded. .NET type How the value will be represented byte, Int16, Int32, Int64 sbyte, UInt16, UInt32, UInt64 As an integral value float, double, decimal A decimal-based number string A string truncated after 255-bytes. Empty strings are supported. bool True or false DateTime A string representation following the ISO-8601 format, including time zone information: 2020-02-13T11:31:19.5767650-08:00 TimeSpan A decimal-based number representing number of seconds. everything else the ToString() method will be applied. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "body": "Depending on the selected channel type, different values appear. Reference for updating channels Here's a quick reference for updating channels which also includes links to more detailed information and procedures. Add or remove policies assigned to a channel To add or remove policies assigned to a notification channel: Go to one.newrelic.com, in the top nav click Alerts & AI, click Notification channels. Choose a channel, and then click Alert policies. From the selected policy, use the windows to select, remove, or clear all notification channels. Assign a channel to policies To add a notification channel to one or more policies: Go to one.newrelic.com, in the top nav click Alerts & AI, click Policies. Choose a policy, click Notification channels, and then click Add notification channels. Choose a channel, and then click Update policy. Change a channel's name To rename an existing notification channel: Go to one.newrelic.com, in the top nav click Alerts & AI, click Notification channels, then choose a channel. From the Channel details, change the name (maximum 64 characters) based on the channel type if applicable, and then save. Check for policies assigned to a user To check whether an account user has any policies assigned: Go to one.newrelic.com, in the top nav click Alerts & AI, click Notification channels. Optional: Search by \"user\" to browse users or a specific username or email. Choose the user, then click Alert policies. Check how many policies are assigned to a channel To check whether a notification channel has any policies assigned: Go to one.newrelic.com, in the top nav click Alerts & AI, click Notification channels. The Policy subscriptions column lists how many policies are assigned to the channel. Create more channels To create a new notification channel: Go to one.newrelic.com, in the top nav click Alerts & AI, click Notification channels. Click New notification channel. Delete a channel To delete a notification channel: Go to one.newrelic.com, in the top nav click Alerts & AI, click Notification channels. In the list, click the Delete icon. Test a saved channelView assigned alert policies To view the policies assigned to a notification channel: Go to one.newrelic.com, in the top nav click Alerts & AI, click Notification channels, choose a channel, and then click Alert policies. OR To view the notification channels assigned to a policy: Go to one.newrelic.com, in the top nav click Alerts & AI, click Policies, choose a policy, then click Notification channels. Basic process Go to one.newrelic.com, in the top nav click Alerts & AI, click Notification channels, then choose a channel. From the Channel details page, make any necessary changes, and then save. The user interface shows a Last modified time stamp for any changes to policies, including their conditions and notification channels. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", "type": "docs", "document_type": "page", - "breadcrumb": "Contents / APM agents / .NET agent / Attributes", - "info": "APM's .NET agent: how custom attribute values are processed and how they will appear in APM.", - "nodeid": 37891, + "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / Alert notifications", + "info": "Read about how to update alerts notification channels. ", + "nodeid": 6481, "sections": [ - ".NET agent", - "Getting started", - "Install", - "Azure installation", - "Other installation", - "Configuration", - "Other features", - "Custom instrumentation", - "API guides", - ".NET agent API", - "Attributes", + "New Relic Alerts", + "Get started", + "Alert policies", + "Alert conditions", + "Alert violations", + "Alert Incidents", + "Alert notifications", "Troubleshooting", - "Azure troubleshooting", - "Custom attributes (.NET)", + "Rules, limits, and glossary", + "Alerts and Nerdgraph", + "REST API alerts", + "Update alert notification channels", + "Reference for updating channels", + "Basic process", "For more help" ], - "title": "Custom attributes (.NET)", + "title": "Update alert notification channels", "popularity": 1, - "external_id": "c3b5f5db21c8e5f07ee67eb3b58ab5028e242a9a", - "category_1": ".NET agent", - "category_2": "Attributes", + "external_id": "ee8bce401d0623e8b85d84a6a20bd8a72b9764ef", + "category_1": "New Relic Alerts", + "category_2": "Alert notifications", "image": "", - "url": "https://docs.newrelic.com/docs/agents/net-agent/attributes/custom-attributes-net", - "published_at": "2020-08-18T18:23:33Z", - "updated_at": "2020-08-18T18:23:32Z", - "category_0": "APM agents", + "url": "https://docs.newrelic.com/docs/alerts-applied-intelligence/new-relic-alerts/alert-notifications/update-alert-notification-channels", + "published_at": "2020-08-18T18:07:05Z", + "updated_at": "2020-08-11T06:42:27Z", + "category_0": "Alerts and Applied intelligence", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.529183, + "_score": 0.45489058, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Custom attributes (.NET)", - "sections": "Custom attributes (.NET)", - "info": "APM's .NET agent: how custom attribute values are processed and how they will appear in APM.", - "category_2": "Attributes", - "body": "When adding custom attribute values to transactions, custom events, spans, and errors, the APIs accept an object. This describes how these values are processed and how they will appear in APM. In all cases, NULL values are not recorded. .NET type How the value will be represented byte, Int16, Int32", - "breadcrumb": "Contents / APM agents / .NET agent / Attributes" + "title": "Update alert notification channels", + "sections": "Update alert notification channels", + "info": "Read about how to update alerts notification channels. ", + "category_2": "Alert notifications", + "body": " to a notification channel: Go to one.newrelic.com, in the top nav click Alerts & AI, click Notification channels. Choose a channel, and then click Alert policies. From the selected policy, use the windows to select, remove, or clear all notification channels. Assign a channel to policies To add" }, - "id": "5e7d76e628ccbcb3d13419d6" + "id": "5f2dbad928ccbcb8ca88dfed" }, { - "body": "Collect data Through our opensource agents or APIs, New Relic makes it easy to collect data from any source. The guides in this section provide strategies for collecting and querying data for use in your existing implementation, or in apps you build. The opportunities are endless. Guides to collect data   Add custom attributes Use custom attributes for deeper analysis 5 min Create custom events Define, visualize, and get alerts on the data you want using custom events 25 min Build queries with NerdGraph Try NerdGraph and build the queries you need 10 min Query data with NRQL Query default event data, custom events, and attributes 15 min Collect data - any source APIs, agents, OS emitters - get any data", - "type": "developer", + "body": "You must save a new notification channel or any changes to an existing notification channel before testing it. Alerts will then send a test message to your chosen destination. Request the test To test a notification channel: Go to one.newrelic.com, in the top nav click Alerts & AI, then click Notification channels. Follow standard procedures to add a new notification channel or to update an existing notification channel, and save it. Select a notification channel, and then click Envelope Message Icon Send a test notification. Review the test confirmation message, and then click Got it. Troubleshoot the test results A confirmation message will automatically show up in the user interface that indicates where the test was sent (for example, email) and whether it was successful. Also, the test notification message itself includes detailed information, including: The person who requested the test Links to policies for the channel Links to all notification channels and policies for the account When troubleshooting problems, review the test notification message, and verify the setup requirements for the type of notification channel you selected. If necessary, make additional changes to your notification channel, and test it again as needed. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "type": "docs", "document_type": "page", - "info": "", + "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / Alert notifications", + "info": "Be sure to save your alerts notification channels before testing them to make sure they're working properly.", + "nodeid": 6491, "sections": [ - "Collect data", - "Guides to collect data", - "Add custom attributes", - "Create custom events", - "Build queries with NerdGraph", - "Query data with NRQL", - "Collect data - any source" + "New Relic Alerts", + "Get started", + "Alert policies", + "Alert conditions", + "Alert violations", + "Alert Incidents", + "Alert notifications", + "Troubleshooting", + "Rules, limits, and glossary", + "Alerts and Nerdgraph", + "REST API alerts", + "Test alert notification channels", + "Request the test", + "Troubleshoot the test results", + "For more help" ], - "title": "Collect data", + "title": "Test alert notification channels", "popularity": 1, - "external_id": "fb5d6f75b61858b09e3e8c63f3b2af97813f47b6", + "external_id": "fcea4cf920f099fa1fcf7fab3760d57bdf2e02b7", + "category_1": "New Relic Alerts", + "category_2": "Alert notifications", "image": "", - "url": "https://developer.newrelic.com/collect-data/", - "published_at": "2020-08-18T02:08:12Z", - "updated_at": "2020-08-18T01:45:02Z", + "url": "https://docs.newrelic.com/docs/alerts-applied-intelligence/new-relic-alerts/alert-notifications/test-alert-notification-channels", + "published_at": "2020-08-18T18:08:07Z", + "updated_at": "2020-08-11T04:16:54Z", + "category_0": "Alerts and Applied intelligence", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.46906766, + "_score": 0.4534518, "_version": null, "_explanation": null, "sort": null, "highlight": { - "sections": "Add custom attributes", - "body": " data   Add custom attributes Use custom attributes for deeper analysis 5 min Create custom events Define, visualize, and get alerts on the data you want using custom events 25 min Build queries with NerdGraph Try NerdGraph and build the queries you need 10 min Query data with NRQL Query default event data, custom events, and attributes 15 min Collect data - any source APIs, agents, OS emitters - get any data" + "title": "Test alert notification channels", + "sections": "Test alert notification channels", + "info": "Be sure to save your alerts notification channels before testing them to make sure they're working properly.", + "category_2": "Alert notifications", + "body": "You must save a new notification channel or any changes to an existing notification channel before testing it. Alerts will then send a test message to your chosen destination. Request the test To test a notification channel: Go to one.newrelic.com, in the top nav click Alerts & AI, then click" }, - "id": "5efa997328ccbc768c307de2" + "id": "5f2dbb3664441fd3a556a97c" }, { - "body": "newrelic.agent.add_custom_parameters(items) Adds one or more custom attributes to a transaction. Description This call records one or more custom attributes (a key/value tuple attached to your transaction). The call name is add_custom_parameters because \"custom attributes\" were previously called \"custom parameters\". Attributes may be found in New Relic APM if the transaction is associated with an error or if a transaction trace is generated for that transaction. Attributes can also be found and queried in Insights or New Relic One. Before you create custom attributes, review New Relic's list of reserved terms used by NRQL and Insights. Parameters Parameter Description items list Required. Each item in the list must be a tuple, with the first element being a key, and the second its value. Each key is a string representing the name of an attribute, and each corresponding value is the value to add to the current transaction for this attribute. Values can be int, float, string, or boolean. Only the first 255 characters are retained for both keys and values. Return value(s) Returns True if all attributes were added successfully. Example(s) Adding custom parameters to background task An example of adding custom parameters to a background task: @newrelic.agent.background_task() def send_request(): response = requests.get(\"http://example.com\") newrelic.agent.add_custom_parameters( [(\"url_path_status_code\", response.status_code)] ) Using custom parameters to troubleshoot You can also use custom parameters to troubleshoot performance issues. For example, you might see occasional slow response times from a pool of memcache instances, but you don't know what instance is causing the problem. You might add an attribute to the transaction indicating the server, like so: # Set server_ip to be the current server processing the transaction newrelic.agent.add_custom_parameters([ (\"memcache_query_frontend_lookup\", \"server_ip\") ])", + "body": "You can use alerts to set up notification channels, and attach those channels to policies. Your selected channels provide fast and consistent ways for the right personnel to be notified about incidents. For example, notifications allow you to include charts about the incident to provide context and share them with your team. Alerts offers several notification channels, including webhooks, Slack rooms, email, and more. You'll be notified by your notification channels when incidents are opened, acknowledged, or closed. This document explains the available notification channels and how to set them up. This document is about alerts notifications. For general information about unsubscribing from other New Relic emails, including marketing emails, weekly reports, and announcements, see Unsubscribe from New Relic emails. View notification channels To see all notification channels in your account: Go to one.newrelic.com, in the top nav click Alerts & AI, then click Notification channels. Add or remove notification channels To set up a new notification channel: On the Notification channels, click New notification channel. Select the type of channel and complete other required steps for it. To add or remove a notification policy or channel: Select a specific notification channel, select Alert policies, and add or remove a policy. OR Select a specific policy, select Notification channels, and add or remove a channel. Instructions for specific notification channels These are the available notification channel types. User For your convenience, we automatically load all users and their email addresses for the selected account. If your account has one or more sub-accounts, the notification channel includes only users for the currently selected master or sub-account. Use the User notification channel to select existing account team members and admins. To view the Users list or to add users to alert policies: Go to one.newrelic.com, in the top nav click Alerts & AI, then click Notification channels. A user channel also sends push notifications to any of the user's registered mobile devices. A device is registered if the user has logged into New Relic using the mobile app on the device. Email We automatically add every individual and their email address on the selected account to the User notification channel and you can select them there. You don't need to add existing New Relic accounts to the Email channel. To add an email channel for other users, follow these guidelines: Field Description Email (required) In general, use the Email notification channel to identify user emails or email aliases that are not already on the selected account. For example, if you have a dev-ops@company.com email alias for your DevOps team, add the email alias to the Email channel. Otherwise, use the User notification channel to select specific users on your DevOps team. For easier maintenance, add a single non-user email address or alias to a single alert notification channel. If you want to use the email channel for more than one email, create an email group or alias outside your account. These email addresses can be the same as or different from email addresses already on your account. Users can unsubscribe from general (non-alerts-related) emails, but they cannot unsubscribe from alerts email notifications. Instead, the account Owner, Admin, or add-on manager must remove users from the policy's email notification channel. Include JSON attachment (optional) To include a JSON attachment with the email notification, select this checkbox. OpsGenie You must have an existing OpsGenie account integrated with New Relic in order to provide the following information: Field Description Channel name (required) A meaningful name for the OpsGenie notification channel (maximum 64 characters). API key (required) The API key generated from your OpsGenie integration used to authenticate API requests. Teams (optional) List of team names that are responsible for the alert. OpsGenie runs team escalation policies to calculate which users will receive notifications. Tags (optional) A comma-separated list of labels attached to the alert. To overwrite the OpsGenie Quiet Hours setting for urgent alerts, add an OverwriteQuietHours tag. Recipients (optional) One or more names of users, groups, on-call schedules, escalation policies, etc., that OpsGenie uses to calculate where to send notifications. PagerDuty You must have an existing PagerDuty account in order to provide the following information: Field Description Service name (required) The name of your service integrating with PagerDuty for notifications. Integration key (required) The unique service identifier used by PagerDuty's Integration API to trigger, acknowledge, and resolve incidents for the service. Slack Before adding Slack notifications, you must create a unique webhook integration using Slack's New Relic integration. If you want web, transaction, server, and mobile alerts to be posted in separate channels, you must set up separate integrations for each one. Field Description Channel name (required) A meaningful name for the Slack notification channel (maximum 64 characters); for example, Network Ops Center. URL (required) Copy and paste the New Relic webhook integration URL that you've set up with Slack. For example: https://hooks.slack.com/services/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 Be sure to include https:// in the URL. Do not use http://. Team channel (optional) If used, include # before the name of the Slack channel where alert notifications are sent; for example, #NOC. VictorOps You must have an existing VictorOps account in order to provide the following required information: Field Description Channel name (required) A meaningful name for this notification channel (maximum 64 characters). For example, if the VictorOps Route key is for your Technical Support team, you could name this channel Tech Support - VictorOps. Key (required) VictorOps generates a unique key for each account. It maps the VictorOps account to its associated integrations. Route key (optional) This key maps the alert or incident to a specific team. Webhook Webhooks are HTTP POST messages containing JSON documents delivered to a destination URL. When an incident is opened, acknowledged, or closed, our webhook feature sends a message to your URL with any relevant information, such as a description of the event and a link back to New Relic. You also have the option to customize the payload in the POST message for further integration into your system. If your endpoint does not acknowledge the POST request within 10 seconds, the Alerts UI may indicate a failed notification event for the related incident. Before adding webhook notifications, you must have an endpoint set up to respond with a status code between 200 and 206 after receiving the following required information: Field Description Channel name (required) A meaningful name for the webhook (maximum 64 characters). Base url (required) The endpoint that will receive the POST message and trigger customized behaviors in your system. If you want to include a port number in the webhook URL, make sure the port is available for requests. Otherwise the webhook will not work. Basic auth (optional) To require basic authentication for the webhook, select Add basic auth, and provide the user name and password to authenticate the webhook. Custom headers (optional) To include headers with webhooks, select Add custom headers, and provide the name and value for each header. Use custom payload (optional) To use the default values, leave blank. To view and edit the default values, select Add custom payload. Payload (for custom payloads only) Your customized POST message code. This field includes: A list of variables you can use Syntax highlighting, based on payload type Payload type (for custom payloads only) Specify the message format: JSON (default) or Form. xMatters You must have an existing xMatters account in order to provide the following information: Field Description Channel name (required) Name your channel so you can identify it easily when associating it with a policy. Integration url (required) The unique integration url provided by xMatters pointing to your xMatters account. Receive mobile push notifications In order to receive mobile push notifications, your device must be registered and listed in (account) > User preferences. If the device is not listed in User preferences, log out of the app, log back in, and check again to see if it is listed. To receive mobile push notifications: Log in to your New Relic account via the mobile app at least once to ensure the device is registered. Add the user channel to the alert policy. Switch push notifications On for the device. Acknowledge alert notifications Anyone in your account can acknowledge notifications through the user interface or email notification. Acknowledging an incident in New Relic also acknowledges any associated incident in PagerDuty. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", "type": "docs", - "document_type": "api_doc", - "breadcrumb": "Contents » APM agents / Python agent / Python agent API", - "info": "New Relic Python API: This call adds a custom attribute (key/value tuple) to a transaction.", - "nodeid": 27406, + "document_type": "page", + "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / Alert notifications", + "info": "Read about how to set up alerts notification channels so you can be notified when incidents are opened, acknowledged, or closed.", + "nodeid": 6281, "sections": [ - "Python agent", - "Getting started", - "Installation", - "Configuration", - "Supported features", - "Back-end services", - "Custom instrumentation", - "API guides", - "Python agent API", - "Web frameworks and servers", - "Hosting services", - "Attributes", + "New Relic Alerts", + "Get started", + "Alert policies", + "Alert conditions", + "Alert violations", + "Alert Incidents", + "Alert notifications", "Troubleshooting", - "add_custom_parameters", - "Description", - "Parameters", - "Return value(s)", - "Example(s)", - "Adding custom parameters to background task", - "Using custom parameters to troubleshoot", + "Rules, limits, and glossary", + "Alerts and Nerdgraph", + "REST API alerts", + "Notification channels: Control where to send alerts", + "View notification channels", + "Add or remove notification channels", + "Instructions for specific notification channels", + "Receive mobile push notifications", + "Acknowledge alert notifications", "For more help" ], - "title": "add_custom_parameters (Python agent API)", + "title": "Notification channels: Control where to send alerts", + "translation_ja_url": "https://docs.newrelic.co.jp/docs/alerts-applied-intelligence/new-relic-alerts/alert-notifications/notification-channels-control-where-send-alerts", "popularity": 1, - "external_id": "4a0759cb3bd46dfabe6d34a678cc7c644ff79773", - "category_1": "Python agent", - "category_2": "Python agent API", + "external_id": "65878aca7993877ee748776c87e9225c90687e3f", + "category_1": "New Relic Alerts", + "category_2": "Alert notifications", "image": "", - "url": "https://docs.newrelic.com/docs/agents/python-agent/python-agent-api/addcustomparameters-python-agent-api", - "published_at": "2020-08-18T12:18:44Z", - "updated_at": "2020-08-15T10:25:58Z", - "category_0": "APM agents", + "url": "https://docs.newrelic.com/docs/alerts-applied-intelligence/new-relic-alerts/alert-notifications/notification-channels-control-where-send-alerts", + "published_at": "2020-08-18T18:51:22Z", + "updated_at": "2020-08-15T11:49:29Z", + "category_0": "Alerts and Applied intelligence", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.379156, + "_score": 0.40250543, "_version": null, "_explanation": null, "sort": null, "highlight": { - "sections": "Attributes", - "info": "New Relic Python API: This call adds a custom attribute (key/value tuple) to a transaction.", - "body": "newrelic.agent.add_custom_parameters(items) Adds one or more custom attributes to a transaction. Description This call records one or more custom attributes (a key/value tuple attached to your transaction). The call name is add_custom_parameters because "custom attributes" were previously called" + "title": "Notification channels: Control where to send alerts", + "sections": "Notification channels: Control where to send alerts", + "info": "Read about how to set up alerts notification channels so you can be notified when incidents are opened, acknowledged, or closed.", + "category_2": "Alert notifications", + "translation_ja_url": "https://docs.newrelic.co.jp/docs/alerts-applied-intelligence/new-relic-alerts/alert-notifications/notification-channels-control-where-send-alerts", + "body": " account: Go to one.newrelic.com, in the top nav click Alerts & AI, then click Notification channels. Add or remove notification channels To set up a new notification channel: On the Notification channels, click New notification channel. Select the type of channel and complete other required steps" }, - "id": "5c4055440cc37f4ab32ef6be" + "id": "5f2dbad864441fb7d256a9db" } ], - "/automate-workflows/get-started-new-relic-cli": [ + "/automate-workflows/5-mins-tag-resources": [ + { + "body": "Get started with the New Relic CLI 20 min Access the New Relic platform from the comfort of your terminal: you can use the New Relic CLI to manage entity tags, define workloads, record deployment markers, and much more. Our CLI has been designed for automating common tasks in your DevOps workflow. This guide walks you through the essentials of New Relic CLI, from install and configuration to basic usage. Before you begin For this guide you just need: Your New Relic personal API Key, which you can create from the Account settings of your New Relic account An instrumented application in your New Relic account Step 1 of 10 Install the New Relic CLI The New Relic CLI can be downloaded via Homebrew (macOS), Scoop (Windows), and Snapcraft (Linux). You can also download pre-built binaries for all platforms, including .deb and .rpm packages, and our Windows x64 .msi installer. Linux With Snapcraft installed, run: sudo snap install newrelic-cli macOS With Homebrew installed, run: brew install newrelic-cli Windows With Scoop installed, run: scoop bucket add newrelic-cli https://github.com/newrelic/newrelic-cli.git scoop install newrelic-cli Step 2 of 10 Create your New Relic CLI profile Now that you've installed the New Relic CLI, it's time to create your first profile. Profiles contain credentials and settings that you can apply to any CLI command, which is useful when switching between accounts. To create your first CLI profile, run the profiles add command. Note that you need to set the region of your New Relic account: use -r to set either us or eu (this is required). # Create the tutorial account for the US region newrelic profiles add -n tutorial --apiKey YOUR_NEW_RELIC_API_KEY -r YOUR_REGION # Set the profile as defaults newrelic profiles default -n tutorial Copy Step 3 of 10 Get your application details In this example, you are going to add tags to the application you've instrumented with New Relic. Tags are key-value pairs that can help you organize and filter your entities. An entity (for example, an application) can have a maximum of 100 key-value pairs tied to it. Before searching for your application using the New Relic CLI, write down or copy your Account ID and the name of your application in New Relic - you need both to find applications in the New Relic platform. Step 4 of 10 The New Relic CLI can retrieve your application details as a JSON object. To search for your APM application use the apm application search command. If you get an error, check that the account ID and application name you provided are correct. newrelic apm application search --accountId YOUR_ACCOUNT_ID --name NAME_OF_YOUR_APP Copy Step 5 of 10 If the account ID is valid, and the application name exists in your account, apm application search yields data similar to this example. When you've successfully searched for your application, look for the guid value. It's a unique identifier for your application. You should copy it or write it down. [ { accountId: YOUR_ACCOUNT_ID, applicationId: YOUR_APP_ID, domain: 'APM', entityType: 'APM_APPLICATION_ENTITY', guid: 'A_LONG_GUID', name: 'NAME_OF_YOUR_APP', permalink: 'https://one.newrelic.com/redirect/entity/A_LONG_GUID', reporting: true, type: 'APPLICATION', }, ]; Copy Step 6 of 10 Add a simple tag to your application Now that you have the GUID, you can point the New Relic CLI directly at your application. Adding a tag is the simplest way to try out the CLI capabilities (don't worry, tags can be deleted by using entity tags delete). Let's suppose that you want to add an environment tag to your application. Go ahead and add the dev:testing tag⁠ (or any other key-value pair) to your application using the entities tags create command. newrelic entity tags create --guid YOUR_APP_GUID --tag devkit:testing Copy Step 7 of 10 What if you want to add multiple tags? Tag sets come to the rescue! While tags are key-value pairs separated by colons, tag sets are comma separated lists of tags. For example: tag1:value1,tag2:value2 To add multiple tags at once to your application, modify and run the following snippet. newrelic entity tags create --guid YOUR_APP_GUID --tag tag1:test,tag2:test Copy Adding tags is an asynchronous operation: this means it could take a while for the tags to get created. Step 8 of 10 You've created and added some tags to your application, but how do you know they're there? You need to retrieve your application's tags. To retrieve your application's tags, use the entity tags get command. newrelic entity tags get --guid YOUR_APP_GUID All tags associated with your application are retrieved as a JSON array. [ { Key: 'tag1', Values: ['true'], }, { Key: 'tag2', Values: ['test'], }, { Key: 'tag3', Values: ['testing'], }, // ... ]; Copy Step 9 of 10 Bonus step: Create a deployment marker Deployments of applications often go wrong. Deployment markers are labels that, when attached to your application data, help you track deployments and troubleshoot what happened. To create a deployment marker, run the apm deployment create command using the same Application ID from your earlier search. newrelic apm deployment create --applicationId YOUR_APP_ID --revision $(git describe --tags --always) Copy Step 10 of 10 Notice that the JSON response includes the revision and timestamp of the deployment. This workflow could be built into a continuous integration or continuous deployment (CI/CD) system to help indicate changes in your application's behavior after deployments. Here is an example. { \"id\": 37075986, \"links\": { \"application\": 204261368 }, \"revision\": \"v1.2.4\", \"timestamp\": \"2020-03-04T15:11:44-08:00\", \"user\": \"Developer Toolkit Test Account\" } Copy Next steps Have a look at all the available commands. For example, you could create a New Relic workflow using workload create If you'd like to engage with other community members, visit our New Relic Explorers Hub page. We welcome feature requests or bug reports on GitHub.", + "type": "developer", + "document_type": "page", + "info": "Learn the essentials of the New Relic CLI, from install and configuration to basic usage.", + "sections": [ + "Get started with the New Relic CLI", + "Before you begin", + "Install the New Relic CLI", + "Linux", + "macOS", + "Windows", + "Create your New Relic CLI profile", + "Get your application details", + "Add a simple tag to your application", + "Bonus step: Create a deployment marker", + "Next steps" + ], + "title": "Get started with the New Relic CLI", + "popularity": 1, + "tags": [ + "api key", + "New Relic CLI", + "Tags", + "Entity", + "Deployment markers" + ], + "external_id": "531f2f3985bf64bb0dc92a642445887095048882", + "image": "", + "url": "https://developer.newrelic.com/automate-workflows/get-started-new-relic-cli/", + "published_at": "2020-08-19T01:47:10Z", + "updated_at": "2020-08-08T01:41:47Z", + "_index": "520d1d5d14cc8a32e600034b", + "_type": "520d1d5d14cc8a32e600034c", + "_score": 18.93317, + "_version": null, + "_explanation": null, + "sort": null, + "highlight": { + "title": "Get started with the New Relic CLI", + "sections": "Get started with the New Relic CLI", + "info": "Learn the essentials of the New Relic CLI, from install and configuration to basic usage.", + "tags": "New Relic CLI", + "body": " Now that you have the GUID, you can point the New Relic CLI directly at your application. Adding a tag is the simplest way to try out the CLI capabilities (don't worry, tags can be deleted by using entity tags delete). Let's suppose that you want to add an environment tag to your application. Go ahead" + }, + "id": "5efa999c196a67c4e1766461" + }, { "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs in GitHub. Options --format string output text format [YAML, JSON, Text] (default \"JSON\") -h, --help help for newrelic --plain output compact text Copy Commands newrelic apm - Interact with New Relic APM newrelic completion - Generates shell completion functions newrelic config - Manage the configuration of the New Relic CLI newrelic documentation - Generate CLI documentation newrelic entity - Interact with New Relic entities newrelic nerdgraph - Execute GraphQL requests to the NerdGraph API newrelic nerdstorage - Read, write, and delete NerdStorage documents and collections. newrelic nrql - Commands for interacting with the New Relic Database newrelic profile - Manage the authentication profiles for this tool newrelic version - Show the version of the New Relic CLI newrelic workload - Interact with New Relic One workloads", "type": "developer", @@ -897,66 +925,102 @@ "external_id": "471ed214caaf80c70e14903ec71411e2a1c03888", "image": "", "url": "https://developer.newrelic.com/explore-docs/newrelic-cli/", - "published_at": "2020-08-18T02:11:50Z", + "published_at": "2020-08-19T01:49:36Z", "updated_at": "2020-08-14T01:47:12Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 9.215137, + "_score": 14.182255, "_version": null, "_explanation": null, "sort": null, "highlight": { "title": "New Relic CLI Reference", "sections": "New Relic CLI Reference", - "info": "The command line tools for performing tasks against New Relic APIs", + "info": "The command line tools for performing tasks against New Relic APIs", "tags": "new relic cli", - "body": " the configuration of the New Relic CLI newrelic documentation - Generate CLI documentation newrelic entity - Interact with New Relic entities newrelic nerdgraph - Execute GraphQL requests to the NerdGraph API newrelic nerdstorage - Read, write, and delete NerdStorage documents and collections. newrelic nrql" + "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs" }, "id": "5efa989ee7b9d2024b7bab97" }, { - "body": "Quickly tag a set of resources 5 min Tags help you group, search, filter, and focus the data about your entities, which can be anything from applications to hosts to services. Tagging entities using the New Relic CLI is a good candidate for automation. In this 5-minute guide, you use the New Relic CLI to add multiple tags to one of your entities. Before you begin For this guide you need your New Relic personal API Key: Create it at the Account settings screen for your account. Step 1 of 6 Install the New Relic CLI You can download the New Relic CLI via Homebrew (macOS), Scoop (Windows), and Snapcraft (Linux). You can also download pre-built binaries for all platforms, including .deb and .rpm packages, and our Windows x64 .msi installer. Linux With Snapcraft installed, run: sudo snap install newrelic-cli macOS With Homebrew installed, run: brew install newrelic-cli Windows With Scoop installed, run: scoop bucket add newrelic-cli https://github.com/newrelic/newrelic-cli.git scoop install newrelic-cli Step 2 of 6 Create your New Relic CLI profile New Relic CLI profiles contain credentials and settings that you can apply to any CLI command. To create your first CLI profile, run the profiles add command. Don't forget to set the region of your New Relic account: use -r to set either us or eu (this is required). # Create the tutorial account for the US region newrelic profiles add -n tutorial --apiKey API_KEY -r us # Set the profile as default newrelic profiles default -n tutorial Copy Step 3 of 6 Search for an entity Your New Relic account might have hundreds of entities: Have a quick look by opening the Entity explorer. In the terminal, run entity search to retrieve a list of entities from your account as JSON. In the example, you're searching for all entities with \"test\" in their name. # Change the `name` to match any of your existing entities newrelic entity search --name \"test\" Copy Step 4 of 6 If there are matching entities in your account, the query yields data in JSON format, similar to this workload example. Select an entity from the results and look for its guid value; the guid is the unique identifier of the entity. Write it down. { \"accountId\": 123456789, \"domain\": \"NR1\", \"entityType\": \"WORKLOAD_ENTITY\", \"guid\": \"F7B7AE59FDED4204B846FB08423DB18E\", \"name\": \"Test workload\", \"reporting\": true, \"type\": \"WORKLOAD\" }, Copy Step 5 of 6 Add tags and tag lists to your entity With your entity guid, you can add tags right away. You can do so by invoking the entities tags create command. What if you want to add multiple tags? You can use tag sets for that: While tags are key-value pairs separated by colons, tag sets are comma-separated lists of tags. For example: tag1:value1,tag2:value2 Note Adding tags is an asynchronous operation: it could take a little while for the tags to get created. # Adding a single tag newrelic entity tags create --guid GUID --tag key:value # Adding multiple tags newrelic entity tags create --guid GUID --tag tag1:test,tag2:test Copy Step 6 of 6 Check that the tags are there To make sure that the tags have been added to your entities, retrieve them using the entity tags get command. All tags associated with your entity are retrieved as a JSON array. newrelic entity tags get --guid GUID Tip Tags can be deleted at any time by invoking the entity tags delete command followed by the same arguments you used to create them. [ { Key: 'tag1', Values: ['true'], }, { Key: 'tag2', Values: ['test'], }, { Key: 'tag3', Values: ['testing'], }, // ... ]; Copy Next steps Have a look at all the New Relic CLI commands. For example, you could create a New Relic workflow using workload create. If you'd like to engage with other community members, visit our New Relic Explorers Hub page. We welcome feature requests or bug reports on GitHub.", + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app, you might have some additional setup and configuration. This guide covers: Downloading the New Relic One CLI to build or modify apps Contribute content to this website Before you begin You must have: A github account account - While not strictly necessary for building apps, a GitHub account enables you to download and customize our open source apps, and contribute an open source project. A New Relic developer account - if you don't already have one, you can get a free trial account for developing New Relic applications. npm - If you've installed Node.js, then you already have npm, which is used to share, reuse, and update JavaScript code, and is necessary for working with React components that are the framework for New Relic apps and this website. Tip Use the New Relic One VSCode extension to build your apps. Prepare to build or modify apps Step 1 of 2 Download the CLI and API key On the Build New Relic One applications page, complete the Quick start steps. These six Quick start steps get you an API key for use with developing apps, and the New Relic One CLI, for building and deploying apps. At the end of the Quick start, you have a project consisting of the following: A Nerdpack - The package containing all the files required by your application. It contains two types of files that you customize to build your app: Nerdlets, and the launcher. One or more Nerdlet files - A specific UI view or window. A Nerdlet is a React JavaScript package that includes an index.js file, a stylesheet, and a JSON-format config file. It can contain any JS functionality (charts, interactive fields, tooltips, etc.). A launcher file: This is the basis for the launcher, which is used to open your application from New Relic One after you publish your app. Step 2 of 2 Start building If you're ready to code, cd to your Nerdpack and get started. If you want to learn more about building applications, try these step-by-step guides: Build a \"Hello, World!\" application shows how to create a little application, publish it to New Relic One, and share it with others by subscribing accounts to it. Map pageviews by region takes you through the steps to create one of our popular open source apps. You learn to add a custom query to an app and view it in a table, then add that data to a map. Contributing to developer.newrelic.com This site is open source, and we want your input. Create a pull request if you see a mistake you know how to fix. Drop us a GitHub issue if you see some content gaps you want us to work on. Or write up a whole new guide if you have one you'd like to share. Read on to learn how. Step 1 of 3 Fork the developer-website GithHub repo Forking the repo enables you to work on your own copy of the developer.newrelic.com files, and build the site locally. It also enables us to more easily manage incomimg pull requests. On the developer-website page in GitHub, select the Fork button on the top right of the page, choose the account you want to fork to, and wait a few seconds while the fork is created. Sync regularly to keep your fork up to date with changes and additions to the main branch upstream. Step 2 of 3 Make a feature or documentation request On any page, select the GitHub button at the top of the page, and then select the kind of change you want, and fill out the GitHub form. Step 3 of 3 Contribute a new guide Check out our contributors guidelines, which will walk you through the process.", "type": "developer", "document_type": "page", - "info": "Add tags to applications you instrument for easier filtering and organization.", + "info": "Prepare to build apps and contribute to this site", "sections": [ - "Quickly tag a set of resources", + "Set up your development environment", "Before you begin", - "Install the New Relic CLI", - "Linux", - "macOS", - "Windows", - "Create your New Relic CLI profile", - "Search for an entity", - "Add tags and tag lists to your entity", - "Note", - "Check that the tags are there", "Tip", - "Next steps" + "Prepare to build or modify apps", + "Start building" ], - "title": "Quickly tag a set of resources", + "title": "Set up your development environment", "popularity": 1, - "external_id": "c7c374812f8295e409a9b06d552de51ceefc666b", + "tags": [ + "developer account", + "API key", + "New Relic One CLI" + ], + "external_id": "c45638a9cd548d1ffffc9f1c7708f115a92ae04a", "image": "", - "url": "https://developer.newrelic.com/automate-workflows/5-mins-tag-resources/", - "published_at": "2020-08-18T02:08:12Z", - "updated_at": "2020-08-14T01:45:08Z", + "url": "https://developer.newrelic.com/build-apps/set-up-dev-env/", + "published_at": "2020-08-19T01:44:48Z", + "updated_at": "2020-08-19T01:44:47Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.42740965, + "_score": 8.362153, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Quickly tag a set of resources", - "sections": "Install the New Relic CLI", - "info": "Add tags to applications you instrument for easier filtering and organization.", - "body": " by invoking the entity tags delete command followed by the same arguments you used to create them. [ { Key: 'tag1', Values: ['true'], }, { Key: 'tag2', Values: ['test'], }, { Key: 'tag3', Values: ['testing'], }, // ... ]; Copy Next steps Have a look at all the New Relic CLI commands. For example" + "tags": "New Relic One CLI", + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app" }, - "id": "5efa999d64441fa74a5f7e2d" + "id": "5efa9973e7b9d242237bab39" + }, + { + "body": "Nerdpack file structure A New Relic One application is represented by a Nerdpack folder, which can include one or more Nerdlet files, and (optionally) one or more launcher files. Here we explain: The file structure for a Nerdpack, a Nerdlet, and a launcher How to link a launcher file to a Nerdlet How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create a Nerdpack template that includes a Nerdlet and a launcher. Generate Nerdlet or launcher individually: Use the New Relic One CLI command nr1 create and choose either Nerdlet or launcher. This can be useful when adding Nerdlets to an existing Nerdpack. For documentation on generating and connecting Nerdpack components, see our app building guides and the New Relic One CLI command reference. Nerdpack file structure When you generate a Nerdpack template using the nr1 create command, it has the following file structure: my-nerdlet ├── README.md ├── launchers │   └── my-nerdlet-launcher │   ├── icon.png │   └── nr1.json ├── nerdlets │   └── my-nerdlet-nerdlet │   ├── index.js │   ├── nr1.json │   └── styles.scss ├── node_modules │   ├── js-tokens │   ├── loose-envify │   ├── object-assign │   ├── prop-types │   ├── react │   ├── react-dom │   ├── react-is │   └── scheduler ├── nr1.json ├── package-lock.json └── package.json Copy Nerdlet file structure A Nerdpack can contain one or more Nerdlets. A Nerdlet folder starts out with three default files, index.js, nr1.json, and styles.scss. Here is what the default files look like after being generated using the nr1 create command: index.js The JavaScript code of the Nerdlet. import React from 'react'; export default class MyAwesomeNerdpack extends React.Component { render() { return

Hello, my-awesome-nerdpack Nerdlet!

; } } Copy nr1.json The Nerdlet configuration file. { \"schemaType\": \"NERDLET\", \"id\": \"my-awesome-nerdpack-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\" } Copy Besides using the launcher as the access point for your application, you can also associate the application with a monitored entity to get it to appear in the entity explorer. To do this, add two additional fields to the config file of the first-launched Nerdlet: entities and actionCategory. In the following example, the Nerdlet has been associated with all Browser-monitored applications and will appear under the Monitor UI category : { \"schemaType\": \"NERDLET\", \"id\": \"my-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"Custom Data\", \"entities\": [{ \"domain\": \"BROWSER\", \"type\": \"APPLICATION\" }], \"actionCategory\": \"monitor\" } Copy To see this application in the UI, you would go to the entity explorer, select Browser applications, and select a monitored application. styles.scss An empty SCSS file for styling your application. icon.png The launcher icon that appears on the Apps page in New Relic One when an application is deployed. Launcher file structure Launchers have their own file structure. Note that: A launcher is not required; as an alternative to using a launcher, you can associate your application with a monitored entity. An application can have more than one launcher, which might be desired for an application with multiple Nerdlets. After generating a launcher using the nr1 create command, its folder contains two files: nr1.json The configuration file. { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy To connect a launcher to a Nerdlet, the rootNerdletId must match the id in the launched Nerdlet's nr1.json config file. For Nerdpacks with multiple Nerdlets, this needs to be done only for the first-launched Nerdlet. icon.png The icon displayed on the launcher for the app on the Apps page.", + "type": "developer", + "document_type": "page", + "info": "An overview of the Nerdpack File Structure", + "sections": [ + "Nerdpack file structure", + "Generate Nerdpack components", + "Nerdlet file structure", + "index.js", + "nr1.json", + "styles.scss", + "icon.png", + "Launcher file structure" + ], + "title": "Nerdpack file structure", + "popularity": 1, + "tags": [ + "New Relic One CLI", + "nerdpack", + "file structure", + "nerdlets", + "launchers" + ], + "external_id": "c97bcbb0a2b3d32ac93b5b379a1933e7b4e00161", + "image": "", + "url": "https://developer.newrelic.com/explore-docs/nerdpack-file-structure/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:49:25Z", + "_index": "520d1d5d14cc8a32e600034b", + "_type": "520d1d5d14cc8a32e600034c", + "_score": 6.268132, + "_version": null, + "_explanation": null, + "sort": null, + "highlight": { + "tags": "New Relic One CLI", + "body": " How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create" + }, + "id": "5efa989e196a671300766404" }, { - "body": "Automate workflows When building today's complex systems, you want an easy, predictable way to verify that your configuration is defined as expected. This concept, Observability as Code, is brought to life through a collection of New Relic-supported orchestration tools, including Terraform, AWS CloudFormation, and a command-line interface. These tools enable you to integrate New Relic into your existing workflows, easing adoption, accelerating deployment, and returning focus to your main job — getting stuff done. In addition to our Terraform and CLI guides below, find more automation solutions in our Developer Toolkit. Guides to automate workflows 5 min Quickly tag resources Add tags to apps for easy filtering 20 min Automate common tasks Use the New Relic CLI to tag apps and create deployment markers 20 min Set up New Relic using the Kubernetes operator Learn how to provision New Relic resources using the Kubernetes operator 20 min Set up New Relic using Terraform Learn how to provision New Relic resources using Terraform", + "body": "Automate workflows When building today's complex systems, you want an easy, predictable way to verify that your configuration is defined as expected. This concept, Observability as Code, is brought to life through a collection of New Relic-supported orchestration tools, including Terraform, AWS CloudFormation, and a command-line interface. These tools enable you to integrate New Relic into your existing workflows, easing adoption, accelerating deployment, and returning focus to your main job — getting stuff done. In addition to our Terraform and CLI guides below, find more automation solutions in our Developer Toolkit. Guides to automate workflows 5 min Quickly tag resources Add tags to apps for easy filtering 20 min Set up New Relic using the Kubernetes operator Learn how to provision New Relic resources using the Kubernetes operator 20 min Automate common tasks Use the New Relic CLI to tag apps and create deployment markers 20 min Set up New Relic using Terraform Learn how to provision New Relic resources using Terraform", "type": "developer", "document_type": "page", "info": "", @@ -964,8 +1028,8 @@ "Automate workflows", "Guides to automate workflows", "Quickly tag resources", - "Automate common tasks", "Set up New Relic using the Kubernetes operator", + "Automate common tasks", "Set up New Relic using Terraform" ], "title": "Automate workflows", @@ -973,375 +1037,569 @@ "external_id": "d4f408f077ed950dc359ad44829e9cfbd2ca4871", "image": "", "url": "https://developer.newrelic.com/automate-workflows/", - "published_at": "2020-08-18T02:04:53Z", - "updated_at": "2020-08-17T01:55:15Z", + "published_at": "2020-08-19T01:44:47Z", + "updated_at": "2020-08-19T01:44:47Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.3421702, + "_score": 0.42792115, "_version": null, "_explanation": null, "sort": null, "highlight": { "sections": "Set up New Relic using the Kubernetes operator", - "body": " solutions in our Developer Toolkit. Guides to automate workflows 5 min Quickly tag resources Add tags to apps for easy filtering 20 min Automate common tasks Use the New Relic CLI to tag apps and create deployment markers 20 min Set up New Relic using the Kubernetes operator Learn how to provision New Relic resources using the Kubernetes operator 20 min Set up New Relic using Terraform Learn how to provision New Relic resources using Terraform" + "body": " solutions in our Developer Toolkit. Guides to automate workflows 5 min Quickly tag resources Add tags to apps for easy filtering 20 min Set up New Relic using the Kubernetes operator Learn how to provision New Relic resources using the Kubernetes operator 20 min Automate common tasks Use the New Relic CLI to tag apps and create deployment markers 20 min Set up New Relic using Terraform Learn how to provision New Relic resources using Terraform" }, "id": "5efa999c196a67dfb4766445" - }, + } + ], + "/collect-data/custom-attributes": [ { - "body": "Contain the complexity - Observability made simple New Relic’s Kubernetes cluster explorer empowers Kubernetes nerds to move beyond infrastructure metrics and investigate deeper into applications, traces, logs, and events—with a single click—while staying grounded in a centralized UI. Join us at KubeCon and CloudNativeCon Europe August 17-20 to learn more. Check out the complete schedule of New Relic talks to make the most of your KubeCon experience. Learn more. Get coding Create a free account 5 min Create custom events Define, visualize, and get alerts on the data you want using custom events Start the guide 7 min Add tags to apps Add tags to applications you instrument for easier filtering and organization Start the guide 12 min Build a Hello, World! app Build a Hello, World! app and publish it to your local New Relic One Catalog Start the guide Get inspired 30 min Add a table to your app Add a table to your New Relic One app 15 min Collect data - any source APIs, agents, OS emitters - get any data 20 min Automate common tasks Use the New Relic CLI to tag apps and create deployment markers 30 min Create a custom map view Build an app to show page view data on a map 20 min Add a time picker to your app Add a time picker to a sample application   Add custom attributes Use custom attributes for deeper analysis Show 18 more guides Looking for more inspiration? Check out the open source projects built by the New Relic community. New Relic developer champions New Relic Champions are solving big problems using New Relic as their linchpin and are recognized as experts and leaders in the New Relic technical community. Nominate a developer champion Learn more about developer champions New Relic Podcasts We like to talk, especially to developers about developer things. Join us for conversations on open source, observability, software design and industry news. Listen", + "body": "Query data with NRQL 10 min With NRQL, you can query any of the default event data being reported by New Relic, plus any custom events and attributes you’ve added. Step 1 of 4 NRQL syntax is comparable to ANSI SQL. Learn more about NRQL syntax SELECT function(attribute) [AS 'label'][, ...] FROM event [WHERE attribute [comparison] [AND|OR ...]][AS 'label'][, ...] [FACET attribute | function(attribute)] [LIMIT number] [SINCE time] [UNTIL time] [WITH TIMEZONE timezone] [COMPARE WITH time] [TIMESERIES time] Copy Step 2 of 4 NRQL queries can be as simple as fetching rows of data in a raw tabular form to inspect individual events. Learn what events open source agents provide out of the box -- Fetch a list of Browser PageView events SELECT * FROM PageView Copy Step 3 of 4 NRQL queries can also do extremely powerful calculations before the data is presented to you, such as crafting funnels based on the way people actually use your website. Learn more about NRQL funnels -- See how many users visit, signup, browse and purchase from your site as a funnel SELECT funnel(session, WHERE pageUrl='http://www.demotron.com/' AS 'Visited Homepage', WHERE pageUrl='http://www.demotron.com/signup' AS 'Signed Up', WHERE pageUrl='http://www.demotron.com/browse' AS 'Browsed Items', WHERE pageUrl='http://www.demotron.com/checkout' AS 'Made Purchase') FROM PageView SINCE 12 hours ago Copy Step 4 of 4 Using NRQL, you can customize your New Relic experience by crafting diverse dashboards that show your data from multiple angles. You can share these dashboards with technical and non-technical stakeholders alike. Learn more and start building Documentation For an overview of NRQL syntax, see Introduction to NRQL. For a detailed description of all available functions, see NRQL syntax, components, and functions. NRU Tutorials To learn how to query and narrow a large data store by a specific parameter, watch the tutorial on Filtering queries with NRQL. Community forum Connect with other developers in the our Explorers Hub. GitHub For examples of integrations and other technologies, check us out on GitHub.", "type": "developer", "document_type": "page", - "info": "", + "info": "Query default event data as well as custom events and attributes with our powerful, SQL-like query language. Start querying now.", "sections": [ - "Contain the complexity - Observability made simple", - "Get coding", - "Create custom events", - "Add tags to apps", - "Build a Hello, World! app", - "Get inspired", - "Add a table to your app", - "Collect data - any source", - "Automate common tasks", - "Create a custom map view", - "Add a time picker to your app", - "Add custom attributes", - "New Relic developer champions", - "New Relic Podcasts" + "Query data with NRQL", + "Learn more and start building", + "Documentation", + "NRU Tutorials", + "Community forum", + "GitHub" ], - "title": "New Relic Developers", + "title": "Query data with NRQL", "popularity": 1, - "external_id": "214583cf664ff2645436a1810be3da7a5ab76fab", - "image": "https://developer.newrelic.com/static/dev-champion-badge-0d8ad9c2e9bbfb32349ac4939de1151c.png", - "url": "https://developer.newrelic.com/", - "published_at": "2020-08-18T02:03:42Z", - "updated_at": "2020-08-15T01:36:10Z", + "tags": [ + "NRQL", + "NRQL syntax", + "calculate data NRQL" + ], + "external_id": "7bb23b086badd7a572964357aad776116f5bfbbe", + "image": "https://developer.newrelic.com/static/eb2adf50e7680e8ba5b7daaf06c203d1/757a2/nr1-dashboard.png", + "url": "https://developer.newrelic.com/collect-data/query-data-nrql/", + "published_at": "2020-08-19T01:44:48Z", + "updated_at": "2020-08-14T01:46:10Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.2277025, + "_score": 6.399728, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic Developers", - "sections": "New Relic developer champions", - "body": " to your app Add a table to your New Relic One app 15 min Collect data - any source APIs, agents, OS emitters - get any data 20 min Automate common tasks Use the New Relic CLI to tag apps and create deployment markers 30 min Create a custom map view Build an app to show page view data on a map 20 min Add" + "title": "Query data with NRQL", + "sections": "Query data with NRQL", + "info": "Query default event data as well as custom events and attributes with our powerful, SQL-like query language. Start querying now.", + "tags": "NRQL", + "body": "Query data with NRQL 10 min With NRQL, you can query any of the default event data being reported by New Relic, plus any custom events and attributes you’ve added. Step 1 of 4 NRQL syntax is comparable to ANSI SQL. Learn more about NRQL syntax SELECT function(attribute) [AS 'label'][, ...] FROM" }, - "id": "5d6fe49a64441f8d6100a50f" + "id": "5efa999ce7b9d29f377bab69" }, { - "body": "Explore NerdGraph using the API Explorer 25 min NerdGraph is New Relic's GraphQL API. It allows you to get all the information you need in a single request. With NerdGraph API Explorer you don't need to know the query format: using the Query Builder you can browse our entire graph and compose queries just by selecting the items you want and filling out their required values. Before you begin Go to api.newrelic.com/graphiql and log in using your New Relic user ID and password: the NerdGraph API Explorer loads up. Make sure you have a valid New Relic API key. You can create one directly from the NerdGraph API Explorer. Step 1 of 5 Build a query to retrieve your name Time for your first NerdGraph query. Search for your name in the New Relic database: Erase everything in the query editor. Select the following fields in the query explorer in this order: actor, user, name. This GraphQL snippet appears in the editor. { actor { user { name } } } Copy Step 2 of 5 Click the play button to see the result With this query, you're telling NerdGraph to retrieve your name. You're asking for the name field, which is nested within the user field. This refers to the user who owns the API key, which in turn is nested within actor. Click the play button to see the result: It has almost the same shape as the request. All the fields in the Query Builder make up what's called the GraphQL schema, which describes all the available data types and their attributes. To learn more about each field, click the Docs button, or hover over a field in the editor. Step 3 of 5 Add more fields to your query Now you can try adding more fields to your query. The simplest way is clicking the fields in the Query Builder: The API Explorer knows where the attributes should go in the query. In the example, you add the account id and email fields. Once again, running the GraphQL query results in just the data you need, without over or under-fetching data. Notice that the id field has an argument: passing arguments is a powerful way of customizing your NerdGraph queries. Every field and object can contain arguments, so instead of running multiple queries, you just compose the one that you need. { actor { user { name email } account(id: 12345678) } } Copy Step 4 of 5 Experiment with mutations In GraphQL, mutations are a way to execute queries with side effects that can alter the data by creating, updating, or deleting objects (Commonly referred to as CRUD operations in REST APIs). Ready for your first mutation? Erase what's in the editor. Scroll down the Query Builder and expand mutation. Select the fields in the following screenshot: In this case, you're trying to add a custom tag to an entity. Notice that the editor complains if you don't select errors: mutations must have a way of telling you how the operation performed in the backend (failed requests result in null responses). Tip Unlike REST, GraphQL APIs like NerdGraph can return partial responses. For example, if you try adding tags to multiple entities, some mutations can fail and others succeed; all is logged in the GraphQL response you get. Step 5 of 5 Try your NerdGraph query in the terminal Let's say that you've built a NerdGraph query you're happy with and you want to test it elsewhere. To capture code-ready queries and mutations: Select the Tools menu. Copy the query as a curl call or as a New Relic CLI command. # cURL version curl https://api.newrelic.com/graphql \\ -H 'Content-Type: application/json' \\ -H 'API-Key: API_KEY_REDACTED' \\ --data-binary '{\"query\":\"{\\n actor {\\n user {\\n name\\n email\\n }\\n account(id: 12345678)\\n }\\n}\\n\", \"variables\":\"\"}' # New Relic CLI version newrelic nerdgraph query '{ actor { user { name email } account(id: 12345678) } } ' Copy Next steps Now you know the basics of composing and testing NerdGraph queries, but how do you turn them into client or server code? Solutions such as GraphQL Code Generator can help you turn the NerdGraph queries into code for your implementation. Try creating more complex queries by clicking fields and expanding objects in the Query Builder (be careful with mutations though, since they could write data to your account). For more information on NerdGraph and explore other projects from the developer community, check out the threads on the Explorer’s Hub.", + "body": "Set up New Relic using the Kubernetes operator 20 min Kubernetes is an open-source system for automating deployment, scaling, and management of containerized applications. You can use it to provision all kinds of infrastructure and services, including New Relic entities. In this guide you'll learn how to set up New Relic for the first time with the official New Relic Kubernetes operator. More specifically, you'll provision an alert policy with NRQL conditions in your New Relic account using Kubernetes. Before you begin This walkthrough assumes you’ve already deployed a Kubernetes cluster. You could even create a local cluster on your machine with kind. To use this guide, you should have some basic knowledge of both New Relic and Kubernetes. To complete the full exercise, you’ll need to: Deploy a New Relic agent if you haven't done so yet. Install New Relic for your application. Install kubectl and point it at the correct cluster; this determines the cluster where you’ll install the New Relic operator. Install kustomize. Step 1 of 3 Installing the operator on your Kubernetes cluster First, install cert-manager, which automatically provisions and manages TLS certificates in Kubernetes. kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.15.0/cert-manager.yaml Copy Next, install the Kubernetes operator. kustomize build https://github.com/newrelic/newrelic-kubernetes-operator/config/default | kubectl apply -f - Copy To confirm the installation was successful, run a few kubectl commands to check the status of the Kubernetes operator. Ensure the Kubernetes operator's namespace, newrelic-kubernetes-operator-system, has been applied: kubectl get namespaces Copy The output should be similar to the following, which includes the Kubernetes operator's namespace, newrelic-kubernetes-operator-system: NAME STATUS AGE cert-manager Active 4m35s default Active 20m kube-node-lease Active 20m kube-public Active 20m kube-system Active 20m newrelic-kubernetes-operator-system Active 3m48s Copy Now, make sure the Kubernetes operator's controller manager is running: Note: Don't forget to include the --namespace (shorthand -n) option when running kubectl get pods to ensure you're inspecting resources within the correct namespace. kubectl get pods --namespace newrelic-kubernetes-operator-system Copy You should see output similar to the following: NAME READY STATUS RESTARTS AGE newrelic-kubernetes-operator-controller-manager-7b9c64f58crwg9j 2/2 Running 0 157m Copy If your output is similar to the example shown, you’re ready for the next step. If you don’t see a pod named newrelic-kubernetes-operator-controller-manager-, double check your Kubernetes configuration to ensure you’re within the correct context and pointing to the correct cluster. Step 2 of 3 Creating your first alert policy To kick things off, start small. First, create an alert policy with the minimum required configuration, then add a NRQL alert condition to the policy, which will add the condition to the policy in New Relic. A minimal alert policy configuration is represented in the code below. For the sake of this walkthrough, name this file new_relic_alert_policy.yaml. Note: For help locating your personal API key, check out New Relic's personal API key documentation. apiVersion: nr.k8s.newrelic.com/v1 kind: AlertsPolicy metadata: name: my-policy spec: account_id: api_key: name: 'Alert Policy Created With k8s' # Feel free to rename region: 'us' Copy Now run the kubectl apply command to create your alert policy. kubectl apply -f ./new_relic_alert_policy.yaml Copy You'll see output that reads similar to the following: alertspolicy.nr.k8s.newrelic.com/my-policy created Copy Confirm that your alert policy was created by viewing your policies at alerts.newrelic.com/accounts/{your account ID}/policies. You can search for your new policy by its name. In this case, search for \"Alert Policy Created With k8s.\" You should see your new alert policy. Next it’s time to add a NRQL alert condition to the policy using the same configuration file. Step 3 of 3 Add NRQL alert conditions to your alert policy In the previous section you created an alert policy; now, you’ll add some alert conditions to the policy so you can trigger alerts when certain metrics are out of line. In your new_relic_alert_policy.yaml file, add a NRQL alert condition to the policy that will alert you when an application's average overall response time is above five seconds for a three minute period. Note: To receive notifications when an alert is triggered, add notification channels to your alert policy, with this code. # The policy from the previous steps apiVersion: nr.k8s.newrelic.com/v1 kind: AlertsPolicy metadata: name: my-policy spec: account_id: api_key: name: 'Alert Policy Created With k8s' # Feel free to rename region: 'us' # Add a NRQL alert condition to the policy conditions: - spec: type: 'NRQL' name: 'NRQL Alert Condition Created With k8s' nrql: query: \"SELECT average(duration) FROM Transaction WHERE appName = 'YOUR APP NAME'\" evaluationOffset: 3 enabled: true terms: - threshold: '5' threshold_occurrences: 'ALL' threshold_duration: 180 priority: 'CRITICAL' operator: 'ABOVE' violationTimeLimit: 'ONE_HOUR' valueFunction: 'SINGLE_VALUE' Copy With the alert condition added to the configuration, you can apply the update, which will create a NRQL alert condition and add it to your policy. kubectl apply -f ./new_relic_alert_policy.yaml Copy To confirm that the NRQL alert condition was created successfully, refresh your alert policy. If you see a new alert condition added to the alert policy, it was a success. To finish things off, you'll create and add an alert channel to your alert policy. For example, maybe you want to send an email out to your team when your alert condition is triggered. Try it out now We have a Kubernetes test cluster ready for you in 2 minutes. By following this on-line tutorial, you will learn how to: Deploy the New Relic agent in a Kubernetes environment Use the New Relic Kubernetes operator Some tips to use the on-line tutorial window: Accept the cookies, so you can see the menu bar. Click anywhere in the tutorial window to start. It will take about 2 minutes for your environment to be ready. Press CTRL-l or type clear to clear the terminal window Click on the finish flag icon in the bottom menu to hide or show the instructions Good luck! Note Some browsers automatically disable the use of iframes. If the module isn't loading please check your browser settings. Your browser does not support iframes. What’s next? Nice work — now you can manage your New Relic alert policies and NRQL alert conditions with code that integrates seamlessly within your Kubernetes workflow. This provides the ability to configure and manage your alerts with a domain-specific pattern, providing consistency and maintainability. You also gain the benefits of code reviews for any potential changes moving forward. As you and your team move forward, you might need to adjust some of the configuration values to better fit your needs. The New Relic Kubernetes Operator is just one of several tools in the New Relic Developer Toolkit aimed at facilitating observability as code.", "type": "developer", "document_type": "page", - "info": "Learn to explore NerdGraph, our GraphQL API, and build the queries you need.", + "info": "Learn how to provision New Relic resources using the [Kubernetes operator](https://github.com/newrelic/newrelic-kubernetes-operator).", "sections": [ - "Explore NerdGraph using the API Explorer", + "Set up New Relic using the Kubernetes operator", "Before you begin", - "Build a query to retrieve your name", - "Click the play button to see the result", - "Add more fields to your query", - "Experiment with mutations", - "Tip", - "Try your NerdGraph query in the terminal", - "Next steps" + "Installing the operator on your Kubernetes cluster", + "Creating your first alert policy", + "Add NRQL alert conditions to your alert policy", + "Try it out now", + "Note", + "What’s next?" ], - "title": "Explore NerdGraph using the API Explorer", + "title": "Set up New Relic using the Kubernetes operator", "popularity": 1, - "external_id": "df1f04edc2336c69769d946edbaf263a5339bc92", - "image": "https://developer.newrelic.com/static/0ce8c387a290d7fbd6be155322be9bce/bc8d6/create-account.png", - "url": "https://developer.newrelic.com/collect-data/get-started-nerdgraph-api-explorer/", - "published_at": "2020-08-18T02:08:12Z", - "updated_at": "2020-08-14T01:45:09Z", + "tags": [ + "kubernetes", + "kubernetes operator", + "nrql alert conditions" + ], + "external_id": "2f9f7c55115d09255ade8f1d3fbcce4bee50d4aa", + "image": "", + "url": "https://developer.newrelic.com/automate-workflows/get-started-kubernetes/", + "published_at": "2020-08-19T01:47:11Z", + "updated_at": "2020-08-19T01:47:11Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.19488293, + "_score": 2.6279368, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Explore NerdGraph using the API Explorer", - "sections": "Explore NerdGraph using the API Explorer", - "info": "Learn to explore NerdGraph, our GraphQL API, and build the queries you need.", - "body": " and mutations: Select the Tools menu. Copy the query as a curl call or as a New Relic CLI command. # cURL version curl https://api.newrelic.com/graphql \\ -H 'Content-Type: application/json' \\ -H 'API-Key: API_KEY_REDACTED' \\ --data-binary '{"query":"{\\n actor {\\n user {\\n name\\n email\\n }\\n account(id" + "sections": "Add NRQL alert conditions to your alert policy", + "tags": "nrql alert conditions", + "body": " how to set up New Relic for the first time with the official New Relic Kubernetes operator. More specifically, you'll provision an alert policy with NRQL conditions in your New Relic account using Kubernetes. Before you begin This walkthrough assumes you’ve already deployed a Kubernetes cluster. You" }, - "id": "5efa9973196a6791f4766402" - } - ], - "/explore-docs/newrelic-cli": [ + "id": "5f0e5de464441f2734cd74b2" + }, { - "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build your own application launcher and follow the quick start instructions. The quick start automatically generates an API key for the account you select, and gives you the pre-populated commands to create a profile, generate your first \"Hello World\" app, and serve it locally. Tip Use the NR1 VS Code extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions. For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). Configure your CLI preferences nr1 config:set Sets a specific configuration value. nr1 config:get Shows a specific configuration. nr1 config:list Lists your configuration choices. nr1 config:delete Removes the value of a specific configuration. Set up your Nerdpacks nr1 nerdpack:clone Clones an open source Nerdpack from our GitHub repository. nr1 nerdpack:serve Serves your Nerdpack for testing and development purposes. nr1 nerdpack:uuid Shows or regenerates the UUID of a Nerdpack. nr1 nerdpack:publish Publishes your Nerdpack to New Relic. nr1 nerdpack:deploy Deploys a Nerdpack version to a specific channel. nr1 nerdpack:undeploy Undeploys a Nerdpack version from a specific channel. Manage your Nerdpack subscriptions nr1 subscription:set Subscribes your account to a Nerdpack and channel. nr1 subscription:list Lists all the Nerdpacks your account is subscribed to. nr1 subscription:unset Unsubscribes your account from a Nerdpack. Install and manage plugins nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin into the CLI for development. nr1 plugins:update Updates your installed plugins. nr1 plugins:uninstall Removes a plugin from the CLI. Manage catalog information nr1 catalog:info Shows the Nerdpack info stored in the catalog. nr1 catalog:submit Gathers and submits the catalog info on the current folder.", - "type": "developer", + "body": "New Relic allows you to collect custom attributes. For example, you can create a custom attribute to track the user name associated with a slow or failing request. This document contains links to docs on how to do this for APM, infrastructure monitoring, browser monitoring, and mobile monitoring. APM: Record custom attributes Review the list of reserved terms used by NRQL. Using reserved terms can cause issues. To enable and use custom attributes for APM, follow the procedure for your APM agent: C SDK To add custom attributes to applications monitored by the C SDK, call one of the attribute functions; for example, newrelic_add_attribute_double(). The key name for your custom attribute depends on what you specify when you call the function. Go Custom attribute collection is enabled by default in the Go agent. However, you can disable custom attribute collection. Java Custom attribute collection is enabled by default in Java. You can collect custom attributes using XML and the Java agent APIs. These two methods can be used in conjunction with each other. Method How to do it Specify attributes in XML XML allows you to specify custom attributes without changing any of your source code. You can have multiple XML files for custom attributes that are grouped by some logical facet. To set custom attributes for your Java app via XML: Review the New Relic Java agent's documentation about XML file format, methods and classes, and examples. From your Extensions directory within the New Relic Java agent, create a single XML file. Define the methods you want New Relic to monitor by editing your XML file directly. Define an XML instrumentation file using the New Relic UI. This may require additional config in the common: block of your newrelic.yml. See Report custom attributes under Instrumentation options for more detail. Call the agent's API Example 1: Adding custom attributes to transactions To collect custom attributes using the agent's API, call the relevant methods: For each method you want to record an attribute for, call NewRelic.addCustomParameter(...). Optional: Include or exclude certain attributes with attributes.include and attributes.exclude. For example, to record a variable named userId, include this code in the parent method: NewRelic.addCustomParameter(\"userId\", userId); Example 2: Adding custom attributes to spans in distributed traces To collect custom attributes using the agent's API, call the relevant methods: For each span (currently executing method) that you want to record an attribute for, call NewRelic.getAgent().getTracedMethod().addCustomAttribute(...). Optional: Include or exclude certain attributes with span_events.attributes.include and span_events.attributes.exclude. For example, to record a variable named userId on the current span, include this code in the associated method: NewRelic.getAgent().getTracedMethod().addCustomAttribute(\"userId\", userId); Collect user attributes The Java agent also includes a built-in mechanism to enable user attributes and collect user information from HttpServletRequest.getUserPrincipal() as custom attributes. .NET Custom attribute collection is enabled by default in .NET. To collect custom attributes, call the relevant API methods: For each method for which you want to record an attribute, call AddCustomAttribute. Optional: Include or exclude attributes with the include and exclude configuration options. For example, to record attributes for a coupon code (string) and an item ID code (number), you could include this code in the parent method: IAgent agent = NewRelic.Api.Agent.NewRelic.GetAgent(); ITransaction transaction = agent.CurrentTransaction; transaction .AddCustomAttribute(\"Discount Code\", \"Summer Super Sale\") .AddCustomAttribute(\"Item Code\", 31456); Node.js Custom attribute collection is enabled by default in Node.js. To collect custom attributes, call the relevant API method: For each attribute you want to record, call newrelic.addCustomAttribute. To record multiple attributes using a single call, use newrelic.addCustomAttributes. For example, to record attributes for a coupon code and an item ID code, you could include this in the parent method: newrelic.addCustomAttributes({ \"Discount Code\": \"Summer Super Sale\", \"Item Code\": 31456 }); PHP Custom attribute collection is enabled by default in PHP. To collect custom attributes, call the relevant API method for each method that you want to record an attribute; newrelic_add_custom_parameter for transaction events and spans newrelic_add_custom_span_parameter for only spans For example, to record a variable named $userId, include this code in the parent method: newrelic_add_custom_parameter ('userID', $userId) Python Custom attribute collection is enabled by default in Python. To collect custom attributes, call add_custom_parameter for each method that you want to record an attribute. For example, to record a variable named user_id, include this code in the parent method: newrelic.agent.add_custom_parameter('user_id', user_id) Ruby Custom attribute collection is enabled by default in Ruby. To collect custom attributes, call the relevant API methods: For Ruby agent version 3.12.0 or higher, use the add_custom_attributes method. For example, to record a variable named @user_id, include this code in the parent method: ::NewRelic::Agent.add_custom_attributes({ user_id: @user.id }) For Ruby agent version 3.11.2 or lower, use the add_custom_parameters method. For example, to record a variable named @user_id, include this code in the parent method: ::NewRelic::Agent.add_custom_parameters({ user_id: @user.id }) Browser monitoring: Record custom attributes The browser agent provides an API to specify extra details associated with a page view or browser interaction, either by forwarding attributes from APM to browser monitoring or by specifying custom attributes through JavaScript. Values forwarded from the APM agent are encoded and injected into browser attributes by our browser agent. Infrastructure monitoring: Record custom attributes Our Infrastructure monitoring lets you create custom attributes that are used to annotate the data from the infrastructure agent. You can use this metadata to build filter sets, group your results, and annotate your data. Mobile monitoring: Record custom attributes Mobile agents include API calls to record custom attributes: For an overview of mobile monitoring custom data, see Insert custom events and attributes Android method: setAttribute iOS method: setAttribute For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "type": "docs", "document_type": "page", - "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", + "breadcrumb": "Contents / Using New Relic / Cross-product functions / Install and configure", + "info": "How to add custom attributes to data reported from some New Relic products. ", + "nodeid": 2726, "sections": [ - "New Relic One CLI reference", - "Installing the New Relic One CLI", - "Tip", - "New Relic One CLI Commands", - "Get started", - "Configure your CLI preferences", - "Set up your Nerdpacks", - "Manage your Nerdpack subscriptions", - "Install and manage plugins", - "Manage catalog information" + "Cross-product functions", + "Install and configure", + "Troubleshooting", + "Collect custom attributes", + "APM: Record custom attributes", + "Browser monitoring: Record custom attributes", + "Infrastructure monitoring: Record custom attributes", + "Mobile monitoring: Record custom attributes", + "For more help" ], - "title": "New Relic One CLI reference", + "title": "Collect custom attributes", "popularity": 1, - "tags": [ - "New Relic One app", - "nerdpack commands" - ], - "external_id": "858339a44ead21c83257778ce60b4c352cd30d3b", - "image": "https://developer.newrelic.com/static/2c6d337608b38a3312b4fc740afe6167/7272b/developercenter.png", - "url": "https://developer.newrelic.com/explore-docs/nr1-cli/", - "published_at": "2020-08-18T02:07:10Z", - "updated_at": "2020-08-18T01:50:36Z", + "external_id": "5a43638e8ef969ce9f0b16fedf433317e67bb4a6", + "category_1": "Cross-product functions", + "category_2": "Install and configure", + "image": "", + "url": "https://docs.newrelic.com/docs/using-new-relic/data/customize-data/collect-custom-attributes", + "published_at": "2020-08-18T14:20:45Z", + "updated_at": "2020-08-11T00:28:22Z", + "category_0": "Using New Relic", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.6042674, + "_score": 0.7570324, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic One CLI reference", - "sections": "New Relic One CLI reference", - "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", - "tags": "New Relic One app", - "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use" + "title": "Collect custom attributes", + "sections": "Collect custom attributes", + "info": "How to add custom attributes to data reported from some New Relic products. ", + "body": ". APM: Record custom attributes Review the list of reserved terms used by NRQL. Using reserved terms can cause issues. To enable and use custom attributes for APM, follow the procedure for your APM agent: C SDK To add custom attributes to applications monitored by the C SDK, call one of the attribute" }, - "id": "5efa989e28ccbc535a307dd0" + "id": "5e9a9d9728ccbc90cdd949ca" }, { - "body": "New Relic One CLI common commands Here's a list of common commands to get you started with the New Relic One CLI. You can click any command to see its usage options and additional details about the command. Command Description nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). See our other New Relic One CLI docs for commands specific to Nerdpack set-up, Nerdpack subscriptions, CLI configuration, plugins, or catalogs. Command details nr1 help See commands and get details Shows all nr1 commands by default. To get details about a specific command, run nr1 help COMMAND_NAME. Usage $ nr1 help Arguments COMMAND_NAME The name of a particular command. Examples $ nr1 help $ nr1 help nerdpack $ nr1 help nerdpack:deploy nr1 update Update your CLI Updates to latest version of the CLI. You can specify which channel to update if you'd like. Usage $ nr1 update Arguments CHANNEL The name of a particular channel. Examples $ nr1 update $ nr1 update somechannel nr1 create Create a new component Creates a new component from our template (either a Nerdpack, Nerdlet, launcher, or catalog). The CLI will walk you through this process. To learn more about Nerdpacks and their file structure, see Nerdpack file structure. For more on how to set up your Nerdpacks, see our Nerdpack CLI commands. Usage $ nr1 create Options -f, --force If present, overrides existing files without asking. -n, --name=NAME Names the component. -t, --type=TYPE Specifies the component type. --path=PATH The route to the component. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output. nr1 profiles Manage your profiles keychain Displays a list of commands you can use to manage your profiles. Run nr1 help profiles:COMMAND for more on their specific usages. You can have more than one profile, which is helpful for executing commands on multiple New Relic accounts. To learn more about setting up profiles, see our Github workshop. Usage $ nr1 profiles:COMMAND Commands profiles:add Adds a new profile to your profiles keychain. profiles:default Chooses which profile should be default. profiles:list Lists the profiles on your keychain. profiles:remove Removes a profile from your keychain. nr1 autocomplete See autocomplete installation instructions Displays the autocomplete installation instructions. By default, the command displays the autocomplete instructions for zsh. If you want instructions for bash, run nr1 autocomplete bash. Usage $ nr1 autocomplete Arguments SHELL The shell type you want instructions for. Options -r, --refresh-cache Refreshes cache (ignores displaying instructions). Examples $ nr1 autocomplete $ nr1 autocomplete zsh $ nr1 autocomplete bash $ nr1 autocomplete --refresh-cache nr1 nrql Query using NRQL Fetches data from databases using a NRQL query. To learn more about NRQL and how to use it, see our NRQL docs. Usage $ nr1 nrql OPTION ... Options -a, --account=ACCOUNT The user account ID. required -q, --query=QUERY The NRQL query to run. required -u, --ugly Displays the content without tabs or spaces. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output.", - "type": "developer", + "body": "In New Relic, attributes are key-value pairs containing information that determines the properties of an event or transaction. These key-value pairs can help you gain greater insight into your application and query your data. View and use attributes Both default APM attributes and custom attributes for your C application appear in: APM transaction traces and error analytics APM events C-specific attributes Before creating custom attributes, review New Relic's list of reserved terms used by NRQL. Otherwise unexpected results may occur. To add custom attributes to your C application, call one of the attribute functions in the C SDK API; for example, newrelic_add_attribute_double(). The key name for your custom attribute depends on what you specify when you call the function. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "type": "docs", "document_type": "page", - "info": "An overview of common commands you can use with the New Relic One CLI.", + "breadcrumb": "Contents / APM agents / C SDK / Instrumentation", + "info": "You can create custom attributes for your C app to supplement the New Relic event data that automatically includes default APM attributes.", + "nodeid": 15891, "sections": [ - "New Relic One CLI common commands", - "Command details", - "nr1 help", - "See commands and get details", - "Usage", - "Arguments", - "Examples", - "nr1 update", - "Update your CLI", - "nr1 create", - "Create a new component", - "Options", - "nr1 profiles", - "Manage your profiles keychain", - "Commands", - "nr1 autocomplete", - "See autocomplete installation instructions", - "nr1 nrql", - "Query using NRQL" + "C SDK", + "Get started", + "Install and configure", + "Instrumentation", + "Troubleshooting", + "Use default or custom attributes (C SDK)", + "View and use attributes", + "C-specific attributes", + "For more help" ], - "title": "New Relic One CLI common commands", + "title": "Use default or custom attributes (C SDK)", "popularity": 1, - "external_id": "503e515e1095418f8d19329517344ab209d143a4", + "external_id": "45876c14a1d258566a824f7c49a50bb8c8fb709d", + "category_1": "C SDK", + "category_2": "Instrumentation", "image": "", - "url": "https://developer.newrelic.com/explore-docs/nr1-common/", - "published_at": "2020-08-18T02:06:04Z", - "updated_at": "2020-08-14T01:48:10Z", + "url": "https://docs.newrelic.com/docs/agents/c-sdk/instrumentation/use-default-or-custom-attributes-c-sdk", + "published_at": "2020-08-18T08:14:25Z", + "updated_at": "2020-08-15T02:11:23Z", + "category_0": "APM agents", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.36333603, + "_score": 0.6821897, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic One CLI common commands", - "sections": "New Relic One CLI common commands", - "info": "An overview of common commands you can use with the New Relic One CLI.", - "body": "New Relic One CLI common commands Here's a list of common commands to get you started with the New Relic One CLI. You can click any command to see its usage options and additional details about the command. Command Description nr1 help Shows all nr1 commands or details about each command. nr1" + "title": "Use default or custom attributes (C SDK)", + "sections": "Use default or custom attributes (C SDK)", + "info": "You can create custom attributes for your C app to supplement the New Relic event data that automatically includes default APM attributes.", + "body": " for your C application appear in: APM transaction traces and error analytics APM events C-specific attributes Before creating custom attributes, review New Relic's list of reserved terms used by NRQL. Otherwise unexpected results may occur. To add custom attributes to your C application, call one" }, - "id": "5f28bd6ae7b9d267996ade94" + "id": "5cd8abf7e621f45d85a089a9" }, { - "body": "New Relic One CLI catalog commands To manage your catalog, use the commands below. You can click any command to see its usage options and additional details about the command. Command Description nr1 catalog:info Shows the Nerdpack info stored in the catalog. nr1 catalog:submit Gathers and submits the catalog info on the current folder. Command details nr1 catalog:info Get catalog details Shows the information about your application that's displayed in the catalog. If run within a specific Nerdpack folder, the info from that Nerdpack will be shown. If you don't want to get info from your local Nerdpack, use the --nerdpack-id=NERDPACK_ID option to query from a specific Nerdpack. Usage $ nr1 catalog:info Options -f, --field=FIELD Specifies which field you want info from. -i, --nerdpack-id=NERDPACK_ID Specifies which Nerdpack to get info from. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output. nr1 catalog:submit Send info to the catalog Gathers the information you add to the catalog directory for your application and saves it to the catalog. See our catalog docs for details on adding screenshots and metadata to your applications to make them easy to find, attractive, and informative. This command must be run on a Nerdpack folder. The command will search for specific files using convention names. Usage $ nr1 catalog:submit Options -P, --skip-screenshots Skips upload of screenshot assets. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output.", - "type": "developer", + "body": "When adding custom attribute values to transactions, custom events, spans, and errors, the APIs accept an object. This describes how these values are processed and how they will appear in APM. In all cases, NULL values are not recorded. .NET type How the value will be represented byte, Int16, Int32, Int64 sbyte, UInt16, UInt32, UInt64 As an integral value float, double, decimal A decimal-based number string A string truncated after 255-bytes. Empty strings are supported. bool True or false DateTime A string representation following the ISO-8601 format, including time zone information: 2020-02-13T11:31:19.5767650-08:00 TimeSpan A decimal-based number representing number of seconds. everything else the ToString() method will be applied. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "type": "docs", "document_type": "page", - "info": "An overview of the CLI commands you can use to manage your New Relic One catalog information.", + "breadcrumb": "Contents / APM agents / .NET agent / Attributes", + "info": "APM's .NET agent: how custom attribute values are processed and how they will appear in APM.", + "nodeid": 37891, "sections": [ - "New Relic One CLI catalog commands", - "Command details", - "nr1 catalog:info", - "Get catalog details", - "Usage", - "Options", - "nr1 catalog:submit", - "Send info to the catalog" + ".NET agent", + "Getting started", + "Install", + "Azure installation", + "Other installation", + "Configuration", + "Other features", + "Custom instrumentation", + "API guides", + ".NET agent API", + "Attributes", + "Troubleshooting", + "Azure troubleshooting", + "Custom attributes (.NET)", + "For more help" ], - "title": "New Relic One CLI catalog commands", + "title": "Custom attributes (.NET)", "popularity": 1, - "external_id": "e94d6ad2cd04e2c01aecef526778d341867b3031", + "external_id": "c3b5f5db21c8e5f07ee67eb3b58ab5028e242a9a", + "category_1": ".NET agent", + "category_2": "Attributes", "image": "", - "url": "https://developer.newrelic.com/explore-docs/nr1-catalog/", - "published_at": "2020-08-18T02:06:04Z", - "updated_at": "2020-08-14T01:49:24Z", + "url": "https://docs.newrelic.com/docs/agents/net-agent/attributes/custom-attributes-net", + "published_at": "2020-08-18T18:23:33Z", + "updated_at": "2020-08-18T18:23:32Z", + "category_0": "APM agents", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.3152471, + "_score": 0.5104871, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic One CLI catalog commands", - "sections": "New Relic One CLI catalog commands", - "info": "An overview of the CLI commands you can use to manage your New Relic One catalog information.", - "body": "New Relic One CLI catalog commands To manage your catalog, use the commands below. You can click any command to see its usage options and additional details about the command. Command Description nr1 catalog:info Shows the Nerdpack info stored in the catalog. nr1 catalog:submit Gathers and submits" + "title": "Custom attributes (.NET)", + "sections": "Custom attributes (.NET)", + "info": "APM's .NET agent: how custom attribute values are processed and how they will appear in APM.", + "category_2": "Attributes", + "body": "When adding custom attribute values to transactions, custom events, spans, and errors, the APIs accept an object. This describes how these values are processed and how they will appear in APM. In all cases, NULL values are not recorded. .NET type How the value will be represented byte, Int16, Int32", + "breadcrumb": "Contents / APM agents / .NET agent / Attributes" }, - "id": "5f28bd6a64441f805eb11a26" - }, + "id": "5e7d76e628ccbcb3d13419d6" + } + ], + "/build-apps/add-nerdgraphquery-guide": [ { - "body": "New Relic One CLI plugin commands To install and manage your plugins, use the commands below. You can click any command to see its usage options and additional details about the command. Command Description nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin into the CLI for development. nr1 plugins:update Updates your installed plugins. nr1 plugins:uninstall Removes a plugin from the CLI. Command details nr1 plugins:install Install a plugin Installs a plugin into the CLI. You can install plugins from npm or a Git URL. Please note that installing a plugin will override the core plugin. For example, if you have a core plugin that has a 'hello' command, then installing a plugin with a 'hello' command will override the core plugin implementation. This is useful if you want to update the core plugin functionality without patching and updating the whole CLI. Usage $ nr1 plugins:install PLUGIN Arguments PLUGIN: the name, path, or URL of the plugin you want to install. required Options -f, --force Runs yarn install --force. This forces a re-download of all the plugin's packages. -h, --help Shows CLI help. --verbose Adds extra information to the output. Examples $ nr1 plugins:install myplugin $ nr1 plugins:install https://github.com/someuser/someplugin $ nr1 plugins:install someuser/someplugin Aliases $ nr1 plugins:add nr1 plugins:link Link your plugin Links a local plugin into the CLI for development. Please note that linking a plugin will override your user-installed plugin or core plugin. For example, if you have a user-installed or core plugin that has a 'hello' command, linking a plugin with a 'hello' command will override the user-installed or core plugin implementation. This is useful for development work. Usage $ nr1 plugins:link PLUGIN Arguments PLUGIN: the name, path, or URL of the plugin you want to link. required Options -h, --help Shows CLI help. --verbose Adds extra information to the output. Examples $ nr1 plugins:link myplugin $ nr1 plugins:link someuser/someplugin nr1 plugins:update Update your plugins Updates all of your installed plugins. Usage $ nr1 plugins:update Options -h, --help Shows CLI help. --verbose Adds extra information to the output. nr1 plugins:uninstall Uninstall your plugin Removes a plugin from the CLI. Usage $ nr1 plugins:uninstall PLUGIN Arguments PLUGIN: the name of the plugin you want to uninstall. required Options -h, --help Shows CLI help. --verbose Adds extra information to the output. Aliases $ nr1 plugins:unlink $ nr1 plugins:remove", + "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations, and fetch New Relic or third-party data. Components of the SDK SDK components are located in the Node module package named nr1, which you get when you install the NR1 CLI. The nr1 components can be divided into several categories: UI components Chart components Query and storage components Platform APIs UI components The UI components category of the SDK contains React UI components, including: Text components: These components provide basic font and heading elements. These include HeadingText and BlockText. Layout components: These components give you control over the layout, and help you build complex layout designs without having to deal with the CSS. Layout components include: Grid and GridItem: for organizing more complex, larger scale page content in rows and columns Stack and StackItem: for organizing simpler, smaller scale page content (in column or row) Tabs and TabsItem: group various related pieces of content into separate hideable sections List and ListItem: for providing a basic skeleton of virtualized lists Card, CardHeader and CardBody : used to group similar concepts and tasks together Form components: These components provide the basic building blocks to interact with the UI. These include Button, TextField, Dropdown and DropdownItem, Checkbox, RadioGroup, Radio, and Checkbox. Feedback components: These components are used to provide feedback to users about actions they have taken. These include: Spinnerand Toast. Overlaid components: These components are used to display contextual information and options in the form of an additional child view that appears above other content on screen when an action or event is triggered. They can either require user interaction (like modals), or be augmenting (like a tooltip). These include: Modal and Tooltip. Components suffixed with Item can only operate as direct children of that name without the suffix. For example: GridItem should only be found as a child of Grid. Chart components The Charts category of the SDK contains components representing different types of charts. The ChartGroup component helps a group of related charts share data and be aligned. Some chart components can perform NRQL queries on their own; some accept a customized set of data. Query and storage components The Query components category contains components for fetching and storing New Relic data. The main way to fetch data is with NerdGraph, our GraphQL endpoint. This can be queried using NerdGraphQuery. To simplify use of NerdGraph queries, we provide some components with pre-defined queries. For more on using NerdGraph, see Queries and mutations. We also provide storage for storing small data sets, such as configuration settings data, or user-specific data. For more on this, see NerdStorage. Platform APIs The Platform API components of the SDK enable your application to interact with different parts of the New Relic One platform, by reading and writing state from and to the URL, setting the configuration, etc. They can be divided into these categories: PlatformStateContext: provides read access to the platform URL state variables. Example: timeRange in the time picker. navigation: an object that allows programmatic manipulation of the navigation in New Relic One. Example: opening a new Nerdlet. NerdletStateContext: provides read access to the Nerdlet URL state variables. Example: an entityGuid in the entity explorer. nerdlet: an object that provides write access to the Nerdlet URL state.", "type": "developer", "document_type": "page", - "info": "An overview of the CLI commands you can use to install and manage your plugins.", + "info": "Intro to New Relic One API components", "sections": [ - "New Relic One CLI plugin commands", - "Command details", - "nr1 plugins:install", - "Install a plugin", - "Usage", - "Arguments", - "Options", - "Examples", - "Aliases", - "nr1 plugins:link", - "Link your plugin", - "nr1 plugins:update", - "Update your plugins", - "nr1 plugins:uninstall", - "Uninstall your plugin" + "Intro to New Relic One API components", + "Components of the SDK", + "UI components", + "Chart components", + "Query and storage components", + "Platform APIs" ], - "title": "New Relic One CLI plugin commands", + "title": "Intro to New Relic One API components", "popularity": 1, - "external_id": "6e94c2de165c2b01c2b15c9297a7314f1895112e", + "tags": [ + "SDK components", + "New Relic One apps", + "UI components", + "chart components", + "query and storage components", + "Platform APIs" + ], + "external_id": "3620920c26bcd66c59c810dccb1200931b23b8c2", "image": "", - "url": "https://developer.newrelic.com/explore-docs/nr1-plugins/", - "published_at": "2020-08-18T02:07:10Z", - "updated_at": "2020-08-14T01:50:34Z", + "url": "https://developer.newrelic.com/explore-docs/intro-to-sdk/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:47:12Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.29591545, + "_score": 2.9961529, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic One CLI plugin commands", - "sections": "New Relic One CLI plugin commands", - "info": "An overview of the CLI commands you can use to install and manage your plugins.", - "body": "New Relic One CLI plugin commands To install and manage your plugins, use the commands below. You can click any command to see its usage options and additional details about the command. Command Description nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin" + "title": "Intro to New Relic One API components", + "sections": "Query and storage components", + "info": "Intro to New Relic One API components", + "tags": "query and storage components", + "body": " is with NerdGraph, our GraphQL endpoint. This can be queried using NerdGraphQuery. To simplify use of NerdGraph queries, we provide some components with pre-defined queries. For more on using NerdGraph, see Queries and mutations. We also provide storage for storing small data sets, such as configuration" }, - "id": "5f28bd6a196a670ddd19d000" + "id": "5efa989e28ccbc4071307de5" }, { - "body": "New Relic One CLI config commands To configure your New Relic One CLI preferences, use the commands below. You can click any command to see its usage options and additional details about the command. Run nr1 config:list to see all your existing configurations and their keys. Command Description nr1 config:set Sets a specific configuration value. nr1 config:get Shows a specific configuration. nr1 config:list Lists your configuration choices. nr1 config:delete Removes the value of a specific configuration. Command details nr1 config:set Set a configuration Sets a specific configuration value given a configuration key. By default, the command will prompt you for a new value after providing a key, but you can also use the --k, --key=KEY option to skip this step. Usage $ nr1 config:set OPTION Options -k, --key=KEY The key of the config. (required) -V, --value=VALUE The value of the config. --profile=PROFILE The authentication profile you want to use. -t, --this-profile-only If present, this configuration will only apply while running with the specified profile. --verbose Adds extra information to the output. Examples $ nr1 config:set --key=proxyEnabled $ nr1 config:set --key=proxyEnabled --value=ENABLED nr1 config:get See your configuration Shows the value for a specific configuration. Usage $ nr1 config:get OPTION Options -k, --key=KEY The key of the config. (required) --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output. nr1 config:list See all your configurations Shows a list of all your configuration choices, including the configuration key, value, and origin. Usage $ nr1 config:list Options --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output. Aliases $ nr1 config:ls nr1 config:delete Remove a configuration Removes the value of a specific configuration. Usage $ nr1 config:delete OPTION Options -k, --key=KEY The key of the config. (required) --profile=PROFILE The authentication profile you want to use. -t, --this-profile-only If present, this configuration will only apply while running with the specified profile. --verbose Adds extra information to the output. Aliases nr1 config:remove nr1 config:rm Examples: $ nr1 config:delete --key=proxyHttp", + "body": "Add, query, and mutate data using NerdStorage 45 min NerdStorage is a document database accessible within New Relic One. It allows you to modify, save, and retrieve documents from one session to the next. Using NerdStorage, you can create individual documents of up to 64kb in size, create different collections of documents, and store data by entity, account, or user level. This guide explains how to add data and documents to NerdStorage. For an introduction to what NerdStorage is and how it works, see Intro to NerdStorage. Before you begin This guide requires that you have an API key and the New Relic One CLI as described in Set up your development environment. Get started First, get the NerdStorage app running successfully inside New Relic One. Step 1 of 3 Clone the example applications from the GitHub repo. Step 2 of 3 Use the New Relic One CLI to update the application UUID and run the application locally. In the terminal, switch to the /nr1-how-to/use-nerdstorage directory: cd / nr1 - how - to / use - nerdstorage; Copy Update the UUID and serve the application: nr1 nerdpack:uuid -gf nr1 nerdpack:serve Copy Step 3 of 3 Once the app is successfully served, your terminal will return the URL to view your running application on New Relic One. Load the URL. Click Apps and under Other apps you'll see the Use Nerdstorage app listed. Click to launch the app. Add data to NerdStorage Once the app is up and running on New Relic One, you can prepare the app and start adding data. On the How To Use NerdStorage app screen, there's a Saved to NerdStorage pane with a field for adding data. However, if you type something you'll get an error message. This is because you need to be set up to store data at the User level. You can do this with the help of the UserStorageMutation component. Step 1 of 3 Open the application’s ./nerdlets/use-nerdstorage-nerdlet/index.js file in the text editor of your choice and find the code for the TextField and Button used to enter data. The Button onClick prop makes a call to a helper method called _addToNerdStorage, and you need to update it to add UserStorageMutation The UserStorage NerdStorage components require a collection and documentId. In the constructor method in the application’s index.js file, you can see the variables being provided. In the .js file, it will look something like this: constructor(props) { super(props) this.collectionId = 'mycollection'; this.documentId = 'learning-nerdstorage'; this.state = { isOpen: true, storage: [], text: '', }; this._addToNerdStorage = this._addToNerdStorage.bind(this); this._removeFromNerdStorage = this._removeFromNerdStorage.bind(this); this._deleteDocument = this._deleteDocument.bind(this); } Copy Step 2 of 3 Import the UserStorageMutation by adding it to your import statement at the top of the index.js file: import { UserStorageMutation } from 'nr1'; Copy Then update the helper with this code beginning with _addToNerdStorage: _addToNerdStorage(){ const { text, storage } = this.state; storage.push(text); this.setState({storage}, () => { UserStorageMutation.mutate({ actionType: UserStorageMutation.ACTION_TYPE.WRITE_DOCUMENT, collection: this.collectionId, documentId: this.documentId, document: { storage }, }) .then((res) => { this.setState({text: ''}); Toast.showToast({ title: \"NerdStorage Update.\", type: Toast.TYPE.NORMAL }); }) .catch((err) => console.log(err)); }); } Copy Step 3 of 3 Return to your running How To Use NerdStorage app screen on New Relic One and reload the page. Add some text in the text entry field and click the check button. This will update NerdStorage and trigger a Toast notification inside the app. You should then see the text you typed displayed as a table row below the text entry field. Query data from NerdStorage Once you get data storage working as described in the section above, you also need to get the app properly reading data from NerdStorage, or the app will reload with an empty state every time you navigate away from the app page and back. To do this, add the UserStorageQuery component and update the componentDidMount method. Step 1 of 3 Import the UserStorageQuery by adding it to the import statement in the application’s ./nerdlets/use-nerdstorage-nerdlet/index.js file. import { UserStorageMutation, UserStorageQuery } from 'nr1'; Copy Step 2 of 3 Then, add the following componentDidMount method to your application: componentDidMount(){ UserStorageQuery.query({ collection: this.collectionId, documentId: this.documentId, }) .then(({ data }) => { if(data !== null) { this.setState({storage: data.storage}); } }) .catch(err => console.log(err)); } Copy Step 3 of 3 Back inside the NerdStorage app, test your changes by adding a few more rows using the text entry field. Then exit and relaunch the application. The application should load and show all the data you entered before you navigated away. Mutate data in NerdStorage Each NerdStorage entry displayed in the table inside the app has a trash button that can be used to update a specific entry. The trash button works by making a call to the _removeFromNerdStorage helper method. Step 1 of 1 To get this process working, update the code in _removeFromNerdStorage: _removeFromNerdStorage(index, data){ const { storage } = this.state; storage.pop(data); this.setState({storage}, () => { UserStorageMutation.mutate({ actionType: UserStorageMutation.ACTION_TYPE.WRITE_DOCUMENT, collection: this.collectionId, documentId: this.documentId, document: { storage }, }) .then((res) => { Toast.showToast({ title: \"NerdStorage Update.\", type: Toast.TYPE.NORMAL }); }) .catch((err) => console.log(err)); }); } Copy Once you do this, clicking the trash button removes the item it's associated with, and the app updates to show the change. Delete collection from NerdStorage While the trash button is a good method for removing specific entries one at a time, you may also want the ability to delete a whole NerdStorage document at once. You can do this by adding the Delete Document button to your app. Step 1 of 2 Add a new GridItem to the application immediately before the closing Grid tag. In the new GridItem add the following code to display your new button: ; Copy Step 2 of 2 Because the new Delete Document button will be calling the _deleteDocument helper method, you'll need to update that using this code: _deleteDocument(){ this.setState({storage: []}); UserStorageMutation.mutate({ actionType: UserStorageMutation.ACTION_TYPE.DELETE_DOCUMENT, collection: this.collectionId, documentId: this.documentId, }); Toast.showToast({ title: \"NerdStorage Update.\", type: Toast.TYPE.CRITICAL }); } Copy Back inside the application, you should now see both the individual trash buttons and the newly added Delete Document button. Next steps Now that you’ve successfully implemented NerdStorage into a New Relic One application, you can store and mutate data connected to your User. For more information on the various NerdStorage components, please visit the New Relic developer website API documentation.", "type": "developer", "document_type": "page", - "info": "An overview of the commands you can use to configure your New Relic One CLI preferences.", + "info": "NerdStorage is a document database accessible within New Relic One. It allows you to modify, save, and retrieve documents from one session to the next.", "sections": [ - "New Relic One CLI config commands", - "Command details", - "nr1 config:set", - "Set a configuration", - "Usage", - "Options", - "Examples", - "nr1 config:get", - "See your configuration", - "nr1 config:list", - "See all your configurations", - "Aliases", - "nr1 config:delete", - "Remove a configuration", - "Examples:" - ], - "title": "New Relic One CLI config commands", - "popularity": 1, - "external_id": "a6e1583bae1b92f3fcee75cd8a5196d13f28f08d", - "image": "", - "url": "https://developer.newrelic.com/explore-docs/nr1-config/", - "published_at": "2020-08-18T02:11:49Z", - "updated_at": "2020-08-04T01:44:08Z", + "Add, query, and mutate data using NerdStorage", + "Before you begin", + "Get started", + "Add data to NerdStorage", + "Query data from NerdStorage", + "Mutate data in NerdStorage", + "Delete collection from NerdStorage", + "Next steps" + ], + "title": "Add, query, and mutate data using NerdStorage", + "popularity": 1, + "tags": [ + "add data", + "query data", + "mutate data", + "nerdstorage" + ], + "external_id": "97cc9637edea35ecd68683f1010f67a5f8c79038", + "image": "https://developer.newrelic.com/static/e03456a7ed8556f83bd3329ea38b261d/8f217/add-data-NerdStorage.png", + "url": "https://developer.newrelic.com/build-apps/add-query-mutate-data-nerdstorage/", + "published_at": "2020-08-19T01:48:30Z", + "updated_at": "2020-08-14T01:50:34Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.24779199, + "_score": 2.9697847, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic One CLI config commands", - "sections": "New Relic One CLI config commands", - "info": "An overview of the commands you can use to configure your New Relic One CLI preferences.", - "body": "New Relic One CLI config commands To configure your New Relic One CLI preferences, use the commands below. You can click any command to see its usage options and additional details about the command. Run nr1 config:list to see all your existing configurations and their keys. Command Description nr1" + "title": "Add, query, and mutate data using NerdStorage", + "sections": "Add, query, and mutate data using NerdStorage", + "info": "NerdStorage is a document database accessible within New Relic One. It allows you to modify, save, and retrieve documents from one session to the next.", + "tags": "query data", + "body": " NerdStorage and trigger a Toast notification inside the app. You should then see the text you typed displayed as a table row below the text entry field. Query data from NerdStorage Once you get data storage working as described in the section above, you also need to get the app properly reading data from" }, - "id": "5f28bd6828ccbca2072376f4" - } - ], - "/build-apps/howto-use-nrone-table-components": [ + "id": "5efa98d4e7b9d26d6b7bab74" + }, { - "body": "TableHeaderCell Usage Copy Props There are no props for this component.", + "body": "Query and store data 10 min To help you build a New Relic One application, we provide you with the New Relic One SDK. Here you can learn how to use the SDK query components, which allow you to make queries and mutations via NerdGraph, our GraphQL endpoint. Query-related React components can be identified by the Query suffix. Mutation-related components can be identified by the Mutation prefix. Components overview Our data components are based on React Apollo. The most basic component is NerdGraphQuery, which accepts any GraphQL (or GraphQL AST generated by the graphql-tag library as the query parameter, and a set of query variables passed as variables. Over this query, we have created an additional set of queries, which can be divided into four groups: User queries: These allow you to query the current user and its associated accounts. Components in this category: UserStorageQuery and AccountsQuery. Entities queries: Because New Relic One is entity-centric, we use queries to make access to your entities easier. You can count, search, list, query, and favorite them. Components in this category: EntityCountQuery, EntitySearchQuery, EntitiesByDomainTypeQuery, EntitiesByGuidsQuery, EntityByGuidQuery, EntityByNameQuery. Storage queries: New Relic One provides a simple storage mechanism that we call NerdStorage. This can be used by Nerdpack creators to store application configuration setting data, user-specific data, and other small pieces of data. Components in this category: UserStorageQuery, AccountStorageQuery, EntityStorageQuery, UserStorageMutation, AccountStorageMutation, and EntityStorageMutation. For details, see NerdStorage. NRQL queries: To be able to query your New Relic data via NRQL (New Relic Query Language), we provide a NrqlQuery component. This component can return data in different formats, so that you can use it for charting and not only for querying. Query components All query components accept a function as a children prop where the different statuses can be passed. This callback receives an object with the following properties: loading: Boolean that is set to true when data fetching is happening. Our components use the cache-and-network strategy, meaning that after the data has loaded, subsequent data reloads might be triggered first with stale data, then refreshed when the most recent data has arrived. data: Root property where the data requested is retrieved. The structure matches a root structure based on the NerdGraph schema. This is true even for highly nested data structures, which means you’ll have to traverse down to find the desired data. error: Contains an Error instance when the query fails. Set to undefined when data is loading or the fetch was successful. fetchMore: Callback function that can be called when the query is being loaded in chunks. The function will only be present when it’s feasible to do so, more data is available, and no fetchMore has already been triggered. Data is loaded in batches of 200 by default. Other components provided by the platform (like the Dropdown or the List) are capable of accepting fetchMore, meaning you can combine them easily. Mutation components Mutation components also accept a children as a function, like the query ones. The mutation can be preconfigured at the component level, and a function is passed back that you can use in your component. This is the standard React Apollo approach for performing mutations, but you might find it easier to use our static mutation method added to the component. More on this topic below. Static methods All of the described components also expose a static method so that they can be used imperatively rather than declaratively. All Query components have a static Query method, and all Mutation components have a mutation method. These static methods accept the same props as their query component, but passed as an object. For example: // Declarative way (using components). function renderAccountList() { return (
    ({data, error}) => { if (error) { return
  • Failed to retrieve list: {error.message}
  • ; } return data.map((account) => {
  • {account.name}
  • }); }}
); } // Imperative way (using promises). async function getAccountList() { let data = {}; try { data = await AccountsQuery.query(); } catch (error) { console.log('Failed to retrieve list: ' + error.message); return; } return data.actor.accounts.map((account) => { return account.name; }); } Copy Similarly, a mutation can happen either way; either declaratively or imperatively. NrqlQuery NrqlQuery deserves additional explanation, because there are multiple formats in which you can return data from it. To provide maximum functionality, all three are exposed through a formatType property. You can find its different values under NrqlQuery.formatType: NERD_GRAPH: Returns the format in which it arrives from NerdGraph. RAW: The format exposed by default in Insights and dashboards when being plotted as JSON. This format is useful if you have a pre-existing script in this format that you're willing to migrate to or incorporate with. CHART: The format used by the charting engine that we also expose. You can find a more detailed explanation of how to manipulate this format in the guide to chart components, and some examples. If you are willing to push data, we currently do not expose NrqlMutation. To do that, see the Event API for how to add custom events.", "type": "developer", "document_type": "page", - "info": "A TableHeaderCell component!", + "info": "Reference guide for SDK query components using NerdGraph", "sections": [ - "TableHeaderCell", - "Usage", - "Props" + "Query and store data", + "Components overview", + "Query components", + "Mutation components", + "Static methods", + "NrqlQuery" ], - "title": "TableHeaderCell", + "title": "Query and store data", "popularity": 1, - "external_id": "2a4be1419d1a6e501a8eed915b8acf7c9798259d", + "tags": [ + "nerdgraph query components", + "mutation components", + "static methods" + ], + "external_id": "cbbf363393edeefbc4c08f9754b43d38fd911026", "image": "", - "url": "https://developer.newrelic.com/components/table-header-cell/", - "published_at": "2020-08-18T02:07:10Z", - "updated_at": "2020-08-03T04:46:36Z", + "url": "https://developer.newrelic.com/explore-docs/query-and-store-data/", + "published_at": "2020-08-19T01:51:37Z", + "updated_at": "2020-08-01T01:42:02Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 3.722324, + "_score": 2.7747617, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "TableHeaderCell", - "sections": "TableHeaderCell", - "info": "A TableHeaderCell component!", - "body": "TableHeaderCell Usage Copy Props There are no props for this component." + "title": "Query and store data", + "sections": "Components overview", + "info": "Reference guide for SDK query components using NerdGraph", + "tags": "nerdgraph query components", + "body": " be identified by the Query suffix. Mutation-related components can be identified by the Mutation prefix. Components overview Our data components are based on React Apollo. The most basic component is NerdGraphQuery, which accepts any GraphQL (or GraphQL AST generated by the graphql-tag library as the query" }, - "id": "5efa9906196a67523e76646e" + "id": "5efa989e28ccbc2f15307deb" }, { - "body": "TableRow Usage Copy Props There are no props for this component.", + "body": "Intro to NerdStorage 30 min To help you build a New Relic One application, we provide you with the New Relic One SDK. On this page, you’ll learn how to use NerdStorage SDK components. Use NerdStorage in your apps NerdStorage is used to store and retrieve simple sets of data, including users's configuration settings and preferences (like favorites), or any other small data sets. This storage is unique per Nerdpack, and can't be shared with any other Nerdpack. NerdStorage can be classified into three categories: User storage: Data that is attached to a particular user. If you’re authenticated as the user the data is attached to, you can read it and write it. Account storage: Data that is attached to a particular account. If you’re authenticated and can access the account, you can read and write to account scoped NerdStorage. Visibility of account data is also determined by master/subaccount rules: If a user has access to the master account, then they also have access to data in all subaccounts. Entity storage: Data that is attached to a particular entity. If you can see the corresponding entity, you can read and write data on that entity. Data model You can imagine NerdStorage as a nested key-value map. Data is inside documents, which are nested inside collections: { 'YourNerdpackUuid': { 'collection-1': { 'document-1-of-collection-1': '{\"lastNumber\": 42, \"another\": [1]}', 'document-2-of-collection-1': '\"userToken\"', // ... }, 'another-collection': { 'fruits': '[\"pear\", \"apple\"]', // ... }, // ... }, } Copy Each NerdStorage level has different properties and purpose: Collections: From a Nerdpack, you can create multiple collections by naming each of them. Inside a collection you can put one or more documents. Think of a collection as key-value storage, where each document is a key-value pair. Documents: A document is formed by an identifier (documentId) and a set of data associated with it. Data associated with a document: NerdStorage accepts any sort of data associated to a documentId. Query and mutation components that are provided work by serializing and deserializing JSON. Limits A Nerdpack can hold up to 1,000 collections and 10,000 documents, plus storage type. A collection can hold up to 1,000 documents, plus storage type. Each document can have a maximum length of 64 KiB when serialized. Data access To access NerdStorage, you can run NerdGraph queries, or use the provided storage queries. Depending on which storage you want to access, you can use a different set of SDK components: User access: UserStorageQuery and UserStorageMutation Account access: AccountStorageQuery and AccountStorageMutation Entity access: EntityStorageQuery and EntityStorageMutation Each of these components can operate declaratively (for example, as part of your React rendering methods) or imperatively (by using the static methods for query and mutation). For more information on this, see Data querying and mutations. Permissions for working with NerdStorage In order to persist changes on NerdStorage, such as creating, updating, and deleting account and entity storage, you must have a user role with permission to persist changes.", "type": "developer", "document_type": "page", - "info": "A TableRow component!", + "info": "Intro to NerdStorage on New Relic One", "sections": [ - "TableRow", - "Usage", - "Props" + "Intro to NerdStorage", + "Use NerdStorage in your apps", + "Data model", + "Limits", + "Data access", + "Permissions for working with NerdStorage" ], - "title": "TableRow", + "title": "Intro to NerdStorage", "popularity": 1, - "external_id": "b9ca0d4e07a506dd961eb2194c5344bfa9ab770d", + "tags": [ + "nerdstorage", + "nerdstorage components", + "new relic one apps", + "data access" + ], + "external_id": "709e06c25376d98b2191ca369b4d139e5084bd62", "image": "", - "url": "https://developer.newrelic.com/components/table-row/", - "published_at": "2020-08-18T02:07:10Z", - "updated_at": "2020-08-03T04:45:42Z", + "url": "https://developer.newrelic.com/explore-docs/nerdstorage/", + "published_at": "2020-08-19T01:49:36Z", + "updated_at": "2020-08-14T01:50:34Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 3.6806536, + "_score": 2.7617235, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "TableRow", - "sections": "TableRow", - "info": "A TableRow component!", - "body": "TableRow Usage Copy Props There are no props for this component." + "title": "Intro to NerdStorage", + "sections": "Use NerdStorage in your apps", + "info": "Intro to NerdStorage on New Relic One", + "tags": "nerdstorage components", + "body": " as the user the data is attached to, you can read it and write it. Account storage: Data that is attached to a particular account. If you’re authenticated and can access the account, you can read and write to account scoped NerdStorage. Visibility of account data is also determined by master" }, - "id": "5efa98d564441f93435f7e24" + "id": "5efa989ee7b9d2048e7bab92" + }, + { + "body": "Add tables to your New Relic One application 30 min Tables are a popular way of displaying data in New Relic applications. For example, with the query builder you can create tables from NRQL queries. Whether you need to have more control over tables or you're importing third-party data, you can build your own tables into your New Relic One application. In this guide, you are going to build a sample table using various New Relic One components. Before you begin If you haven't already installed the New Relic One CLI, step through the quick start in New Relic One. This process also gets you an API key. In addition, to complete the steps in this guide, you need a GitHub account, and to have Node.js installed on your machine. See [Setting up your development environment](/build-apps/set-up-dev-env) for more info. Clone and set up the example application Step 1 of 4 Clone the nr1-how-to example application from GitHub to your local machine. Then, navigate to the app directory. The example app lets you experiment with tables. git clone https://github.com/newrelic/nr1-how-to.git` cd nr1-how-to/create-a-table/nerdlets/create-a-table-nerdlet` Copy Step 2 of 4 Edit the index.json file and set this.accountId to your Account ID as shown in the example. export default class Nr1HowtoAddTimePicker extends React.Component { constructor(props){ super(props) this.accountId = YOUR_ACCOUNT_ID; } ... } Copy Step 3 of 4 Run the demo application Change the directory back to nr1-how-to/create-a-table. Before you can load the demo application, you need to update its unique id by invoking the New Relic One CLI. Once you've assigned a new UUID to the app, install the dependencies and serve the demo app locally, so that you can test any change live in your browser. nr1 nerdpack:uuid -gf # Update the app unique ID npm install # Install dependencies nr1 nerdpack:serve # Serve the demo app locally Copy Step 4 of 4 Open one.newrelic.com/?nerdpacks=local in your browser. Click Apps*, and then in the Other apps section, you should see a Create a table** launcher. That's the demo application you're going to work on. Go ahead and select it. Have a good look at the demo app. There's a TableChart on the left side named Transaction Overview, with an AreaChart next to it. You'll use Table components to add a new table in the second row. Work with table components Step 1 of 10 Navigate to the `nerdlets/create-a-table-nerdlet` subdirectory and open the `index.js` file. Add the following components to the import statement at the top of the file so that it looks like the example: Table TableHeader TableHeaderCell TableRow TableRowCell import { Table, TableHeader, TableHeaderCell, TableRow, TableRowCell, PlatformStateContext, Grid, GridItem, HeadingText, AreaChart, TableChart, } from 'nr1'; Copy Step 2 of 10 Add a basic Table component Locate the empty GridItem in index.js: This is where you start building the table. Add the initial component. The items property collects the data by calling _getItems(), which contains sample values.
; Copy Step 3 of 10 Add the header and rows As the Table component renders a fixed number of header cells and rows, your next step is adding header components, as well as a function that returns the required table rows. Inside of the Table component, add the TableHeader and then a TableHeaderCell child for each heading. Since you don't know how many rows you'll need, your best bet is to call a function to build as many TableRows as items returned by _getItems(). Application Size Company Team Commit ; { ({ item }) => ( {item.name} {item.value} {item.company} {item.team} {item.commit} ); } Copy Step 4 of 10 Take a look at the application running in New Relic One: you should see something similar to the screenshot below. Step 5 of 10 Replace standard table cells with smart cells The New Relic One library includes cell components that can automatically format certain data types, like users, metrics, and entity names. The table you've just created contains columns that can benefit from those components: Application (an entity name) and Size (a metric). Before you can use EntityTitleTableRowCell and MetricTableRowCell, you have to add them to the import statement first. import { EntityTitleTableRowCell, MetricTableRowCell, ... /* All previous components */ } from 'nr1'; Copy Step 6 of 10 Update your table rows by replacing the first and second TableRowCells with entity and metric cells. Notice that EntityTitleTableRowCell and MetricTableRowCell are self-closing tags. { ({ item }) => ( {item.company} {item.team} {item.commit} ); } Copy Step 7 of 10 Time to give your table a second look: The cell components you've added take care of properly formatting the data. Step 8 of 10 Add some action to your table! Tables are great, but interactive tables can be better: As a last update, you are going to allow users to act on each data row. Add the _getActions() method to your index.js file, right before _getItems(). As you may have guessed from the code, _getActions() spawns an alert box when you click Team or Commit cells. _getActions() { return [ { label: 'Alert Team', iconType: TableRow.ACTIONS_ICON_TYPE.INTERFACE__OPERATIONS__ALERT, onClick: (evt, { item, index }) => { alert(`Alert Team: ${item.team}`); }, }, { label: 'Rollback Version', iconType: TableRow.ACTIONS_ICON_TYPE.INTERFACE__OPERATIONS__UNDO, onClick: (evt, { item, index }) => { alert(`Rollback from: ${item.commit}`); }, }, ]; } Copy Step 9 of 10 Find the TableRow component in your return statement and point the actions property to _getActions(). The TableRow actions property defines a set of actions that appear when the user hovers over a table row. Actions have a mandatory text and an onClick callback, but can also display an icon or be disabled if needed. Copy Step 10 of 10 Go back to your application and try hovering over any of the rows: Notice how the two available actions appear. When you click them, a function triggers with the selected row data as an argument, and an alert displays in your browser. Next steps You've built a table into a New Relic One application, using components to format data automatically and provide contextual actions. Well done! Keep exploring the Table components, their properties, and how to use them, in our SDK documentation.", + "type": "developer", + "document_type": "page", + "info": "Add a table to your New Relic One app.", + "sections": [ + "Add tables to your New Relic One application", + "Before you begin", + "Clone and set up the example application", + "Work with table components", + "Next steps" + ], + "title": "Add tables to your New Relic One application", + "popularity": 1, + "tags": [ + "table in app", + "Table component", + "TableHeaderc omponent", + "TableHeaderCell component", + "TableRow component", + "TableRowCell component" + ], + "external_id": "7ff7a8426eb1758a08ec360835d9085fae829936", + "image": "https://developer.newrelic.com/static/e637c7eb75a9dc01740db8fecc4d85bf/1d6ec/table-new-cells.png", + "url": "https://developer.newrelic.com/build-apps/howto-use-nrone-table-components/", + "published_at": "2020-08-19T01:48:30Z", + "updated_at": "2020-08-14T01:46:10Z", + "_index": "520d1d5d14cc8a32e600034b", + "_type": "520d1d5d14cc8a32e600034c", + "_score": 2.7332463, + "_version": null, + "_explanation": null, + "sort": null, + "highlight": { + "title": "Add tables to your New Relic One application", + "sections": "Work with table components", + "info": "Add a table to your New Relic One app.", + "tags": "Table component", + "body": " going to work on. Go ahead and select it. Have a good look at the demo app. There's a TableChart on the left side named Transaction Overview, with an AreaChart next to it. You'll use Table components to add a new table in the second row. Work with table components Step 1 of 10 Navigate" + }, + "id": "5efa989ee7b9d2ad567bab51" + } + ], + "/explore-docs/newrelic-cli": [ + { + "body": "Quickly tag a set of resources 5 min Tags help you group, search, filter, and focus the data about your entities, which can be anything from applications to hosts to services. Tagging entities using the New Relic CLI is a good candidate for automation. In this 5-minute guide, you use the New Relic CLI to add multiple tags to one of your entities. Before you begin For this guide you need your New Relic personal API Key: Create it at the Account settings screen for your account. Step 1 of 6 Install the New Relic CLI You can download the New Relic CLI via Homebrew (macOS), Scoop (Windows), and Snapcraft (Linux). You can also download pre-built binaries for all platforms, including .deb and .rpm packages, and our Windows x64 .msi installer. Linux With Snapcraft installed, run: sudo snap install newrelic-cli macOS With Homebrew installed, run: brew install newrelic-cli Windows With Scoop installed, run: scoop bucket add newrelic-cli https://github.com/newrelic/newrelic-cli.git scoop install newrelic-cli Step 2 of 6 Create your New Relic CLI profile New Relic CLI profiles contain credentials and settings that you can apply to any CLI command. To create your first CLI profile, run the profiles add command. Don't forget to set the region of your New Relic account: use -r to set either us or eu (this is required). # Create the tutorial account for the US region newrelic profiles add -n tutorial --apiKey API_KEY -r us # Set the profile as default newrelic profiles default -n tutorial Copy Step 3 of 6 Search for an entity Your New Relic account might have hundreds of entities: Have a quick look by opening the Entity explorer. In the terminal, run entity search to retrieve a list of entities from your account as JSON. In the example, you're searching for all entities with \"test\" in their name. # Change the `name` to match any of your existing entities newrelic entity search --name \"test\" Copy Step 4 of 6 If there are matching entities in your account, the query yields data in JSON format, similar to this workload example. Select an entity from the results and look for its guid value; the guid is the unique identifier of the entity. Write it down. { \"accountId\": 123456789, \"domain\": \"NR1\", \"entityType\": \"WORKLOAD_ENTITY\", \"guid\": \"F7B7AE59FDED4204B846FB08423DB18E\", \"name\": \"Test workload\", \"reporting\": true, \"type\": \"WORKLOAD\" }, Copy Step 5 of 6 Add tags and tag lists to your entity With your entity guid, you can add tags right away. You can do so by invoking the entities tags create command. What if you want to add multiple tags? You can use tag sets for that: While tags are key-value pairs separated by colons, tag sets are comma-separated lists of tags. For example: tag1:value1,tag2:value2 Note Adding tags is an asynchronous operation: it could take a little while for the tags to get created. # Adding a single tag newrelic entity tags create --guid GUID --tag key:value # Adding multiple tags newrelic entity tags create --guid GUID --tag tag1:test,tag2:test Copy Step 6 of 6 Check that the tags are there To make sure that the tags have been added to your entities, retrieve them using the entity tags get command. All tags associated with your entity are retrieved as a JSON array. newrelic entity tags get --guid GUID Tip Tags can be deleted at any time by invoking the entity tags delete command followed by the same arguments you used to create them. [ { Key: 'tag1', Values: ['true'], }, { Key: 'tag2', Values: ['test'], }, { Key: 'tag3', Values: ['testing'], }, // ... ]; Copy Next steps Have a look at all the New Relic CLI commands. For example, you could create a New Relic workflow using workload create. If you'd like to engage with other community members, visit our New Relic Explorers Hub page. We welcome feature requests or bug reports on GitHub.", + "type": "developer", + "document_type": "page", + "info": "Add tags to applications you instrument for easier filtering and organization.", + "sections": [ + "Quickly tag a set of resources", + "Before you begin", + "Install the New Relic CLI", + "Linux", + "macOS", + "Windows", + "Create your New Relic CLI profile", + "Search for an entity", + "Add tags and tag lists to your entity", + "Note", + "Check that the tags are there", + "Tip", + "Next steps" + ], + "title": "Quickly tag a set of resources", + "popularity": 1, + "tags": [ + "tags", + "new relic CLI" + ], + "external_id": "c7c374812f8295e409a9b06d552de51ceefc666b", + "image": "", + "url": "https://developer.newrelic.com/automate-workflows/5-mins-tag-resources/", + "published_at": "2020-08-19T01:44:48Z", + "updated_at": "2020-08-14T01:45:08Z", + "_index": "520d1d5d14cc8a32e600034b", + "_type": "520d1d5d14cc8a32e600034c", + "_score": 23.328325, + "_version": null, + "_explanation": null, + "sort": null, + "highlight": { + "sections": "Install the New Relic CLI", + "tags": "new relic CLI", + "body": "Quickly tag a set of resources 5 min Tags help you group, search, filter, and focus the data about your entities, which can be anything from applications to hosts to services. Tagging entities using the New Relic CLI is a good candidate for automation. In this 5-minute guide, you use the New Relic" + }, + "id": "5efa999d64441fa74a5f7e2d" + }, + { + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app, you might have some additional setup and configuration. This guide covers: Downloading the New Relic One CLI to build or modify apps Contribute content to this website Before you begin You must have: A github account account - While not strictly necessary for building apps, a GitHub account enables you to download and customize our open source apps, and contribute an open source project. A New Relic developer account - if you don't already have one, you can get a free trial account for developing New Relic applications. npm - If you've installed Node.js, then you already have npm, which is used to share, reuse, and update JavaScript code, and is necessary for working with React components that are the framework for New Relic apps and this website. Tip Use the New Relic One VSCode extension to build your apps. Prepare to build or modify apps Step 1 of 2 Download the CLI and API key On the Build New Relic One applications page, complete the Quick start steps. These six Quick start steps get you an API key for use with developing apps, and the New Relic One CLI, for building and deploying apps. At the end of the Quick start, you have a project consisting of the following: A Nerdpack - The package containing all the files required by your application. It contains two types of files that you customize to build your app: Nerdlets, and the launcher. One or more Nerdlet files - A specific UI view or window. A Nerdlet is a React JavaScript package that includes an index.js file, a stylesheet, and a JSON-format config file. It can contain any JS functionality (charts, interactive fields, tooltips, etc.). A launcher file: This is the basis for the launcher, which is used to open your application from New Relic One after you publish your app. Step 2 of 2 Start building If you're ready to code, cd to your Nerdpack and get started. If you want to learn more about building applications, try these step-by-step guides: Build a \"Hello, World!\" application shows how to create a little application, publish it to New Relic One, and share it with others by subscribing accounts to it. Map pageviews by region takes you through the steps to create one of our popular open source apps. You learn to add a custom query to an app and view it in a table, then add that data to a map. Contributing to developer.newrelic.com This site is open source, and we want your input. Create a pull request if you see a mistake you know how to fix. Drop us a GitHub issue if you see some content gaps you want us to work on. Or write up a whole new guide if you have one you'd like to share. Read on to learn how. Step 1 of 3 Fork the developer-website GithHub repo Forking the repo enables you to work on your own copy of the developer.newrelic.com files, and build the site locally. It also enables us to more easily manage incomimg pull requests. On the developer-website page in GitHub, select the Fork button on the top right of the page, choose the account you want to fork to, and wait a few seconds while the fork is created. Sync regularly to keep your fork up to date with changes and additions to the main branch upstream. Step 2 of 3 Make a feature or documentation request On any page, select the GitHub button at the top of the page, and then select the kind of change you want, and fill out the GitHub form. Step 3 of 3 Contribute a new guide Check out our contributors guidelines, which will walk you through the process.", + "type": "developer", + "document_type": "page", + "info": "Prepare to build apps and contribute to this site", + "sections": [ + "Set up your development environment", + "Before you begin", + "Tip", + "Prepare to build or modify apps", + "Start building" + ], + "title": "Set up your development environment", + "popularity": 1, + "tags": [ + "developer account", + "API key", + "New Relic One CLI" + ], + "external_id": "c45638a9cd548d1ffffc9f1c7708f115a92ae04a", + "image": "", + "url": "https://developer.newrelic.com/build-apps/set-up-dev-env/", + "published_at": "2020-08-19T01:44:48Z", + "updated_at": "2020-08-19T01:44:47Z", + "_index": "520d1d5d14cc8a32e600034b", + "_type": "520d1d5d14cc8a32e600034c", + "_score": 13.746651, + "_version": null, + "_explanation": null, + "sort": null, + "highlight": { + "tags": "New Relic One CLI", + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app" + }, + "id": "5efa9973e7b9d242237bab39" + }, + { + "body": "Nerdpack file structure A New Relic One application is represented by a Nerdpack folder, which can include one or more Nerdlet files, and (optionally) one or more launcher files. Here we explain: The file structure for a Nerdpack, a Nerdlet, and a launcher How to link a launcher file to a Nerdlet How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create a Nerdpack template that includes a Nerdlet and a launcher. Generate Nerdlet or launcher individually: Use the New Relic One CLI command nr1 create and choose either Nerdlet or launcher. This can be useful when adding Nerdlets to an existing Nerdpack. For documentation on generating and connecting Nerdpack components, see our app building guides and the New Relic One CLI command reference. Nerdpack file structure When you generate a Nerdpack template using the nr1 create command, it has the following file structure: my-nerdlet ├── README.md ├── launchers │   └── my-nerdlet-launcher │   ├── icon.png │   └── nr1.json ├── nerdlets │   └── my-nerdlet-nerdlet │   ├── index.js │   ├── nr1.json │   └── styles.scss ├── node_modules │   ├── js-tokens │   ├── loose-envify │   ├── object-assign │   ├── prop-types │   ├── react │   ├── react-dom │   ├── react-is │   └── scheduler ├── nr1.json ├── package-lock.json └── package.json Copy Nerdlet file structure A Nerdpack can contain one or more Nerdlets. A Nerdlet folder starts out with three default files, index.js, nr1.json, and styles.scss. Here is what the default files look like after being generated using the nr1 create command: index.js The JavaScript code of the Nerdlet. import React from 'react'; export default class MyAwesomeNerdpack extends React.Component { render() { return

Hello, my-awesome-nerdpack Nerdlet!

; } } Copy nr1.json The Nerdlet configuration file. { \"schemaType\": \"NERDLET\", \"id\": \"my-awesome-nerdpack-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\" } Copy Besides using the launcher as the access point for your application, you can also associate the application with a monitored entity to get it to appear in the entity explorer. To do this, add two additional fields to the config file of the first-launched Nerdlet: entities and actionCategory. In the following example, the Nerdlet has been associated with all Browser-monitored applications and will appear under the Monitor UI category : { \"schemaType\": \"NERDLET\", \"id\": \"my-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"Custom Data\", \"entities\": [{ \"domain\": \"BROWSER\", \"type\": \"APPLICATION\" }], \"actionCategory\": \"monitor\" } Copy To see this application in the UI, you would go to the entity explorer, select Browser applications, and select a monitored application. styles.scss An empty SCSS file for styling your application. icon.png The launcher icon that appears on the Apps page in New Relic One when an application is deployed. Launcher file structure Launchers have their own file structure. Note that: A launcher is not required; as an alternative to using a launcher, you can associate your application with a monitored entity. An application can have more than one launcher, which might be desired for an application with multiple Nerdlets. After generating a launcher using the nr1 create command, its folder contains two files: nr1.json The configuration file. { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy To connect a launcher to a Nerdlet, the rootNerdletId must match the id in the launched Nerdlet's nr1.json config file. For Nerdpacks with multiple Nerdlets, this needs to be done only for the first-launched Nerdlet. icon.png The icon displayed on the launcher for the app on the Apps page.", + "type": "developer", + "document_type": "page", + "info": "An overview of the Nerdpack File Structure", + "sections": [ + "Nerdpack file structure", + "Generate Nerdpack components", + "Nerdlet file structure", + "index.js", + "nr1.json", + "styles.scss", + "icon.png", + "Launcher file structure" + ], + "title": "Nerdpack file structure", + "popularity": 1, + "tags": [ + "New Relic One CLI", + "nerdpack", + "file structure", + "nerdlets", + "launchers" + ], + "external_id": "c97bcbb0a2b3d32ac93b5b379a1933e7b4e00161", + "image": "", + "url": "https://developer.newrelic.com/explore-docs/nerdpack-file-structure/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:49:25Z", + "_index": "520d1d5d14cc8a32e600034b", + "_type": "520d1d5d14cc8a32e600034c", + "_score": 10.313954, + "_version": null, + "_explanation": null, + "sort": null, + "highlight": { + "tags": "New Relic One CLI", + "body": " How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create" + }, + "id": "5efa989e196a671300766404" }, { "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build your own application launcher and follow the quick start instructions. The quick start automatically generates an API key for the account you select, and gives you the pre-populated commands to create a profile, generate your first \"Hello World\" app, and serve it locally. Tip Use the NR1 VS Code extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions. For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). Configure your CLI preferences nr1 config:set Sets a specific configuration value. nr1 config:get Shows a specific configuration. nr1 config:list Lists your configuration choices. nr1 config:delete Removes the value of a specific configuration. Set up your Nerdpacks nr1 nerdpack:clone Clones an open source Nerdpack from our GitHub repository. nr1 nerdpack:serve Serves your Nerdpack for testing and development purposes. nr1 nerdpack:uuid Shows or regenerates the UUID of a Nerdpack. nr1 nerdpack:publish Publishes your Nerdpack to New Relic. nr1 nerdpack:deploy Deploys a Nerdpack version to a specific channel. nr1 nerdpack:undeploy Undeploys a Nerdpack version from a specific channel. Manage your Nerdpack subscriptions nr1 subscription:set Subscribes your account to a Nerdpack and channel. nr1 subscription:list Lists all the Nerdpacks your account is subscribed to. nr1 subscription:unset Unsubscribes your account from a Nerdpack. Install and manage plugins nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin into the CLI for development. nr1 plugins:update Updates your installed plugins. nr1 plugins:uninstall Removes a plugin from the CLI. Manage catalog information nr1 catalog:info Shows the Nerdpack info stored in the catalog. nr1 catalog:submit Gathers and submits the catalog info on the current folder.", @@ -1369,322 +1627,198 @@ "external_id": "858339a44ead21c83257778ce60b4c352cd30d3b", "image": "https://developer.newrelic.com/static/2c6d337608b38a3312b4fc740afe6167/7272b/developercenter.png", "url": "https://developer.newrelic.com/explore-docs/nr1-cli/", - "published_at": "2020-08-18T02:07:10Z", + "published_at": "2020-08-19T01:50:40Z", "updated_at": "2020-08-18T01:50:36Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 3.2519772, + "_score": 0.60832024, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic One CLI reference", - "sections": "Installing the New Relic One CLI", - "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", - "tags": "New Relic One app", - "body": ". For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet" + "title": "New Relic One CLI reference", + "sections": "New Relic One CLI reference", + "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", + "tags": "New Relic One app", + "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use" }, "id": "5efa989e28ccbc535a307dd0" }, { - "body": "Table Usage Copy Props There are no props for this component.", + "body": "New Relic One CLI common commands Here's a list of common commands to get you started with the New Relic One CLI. You can click any command to see its usage options and additional details about the command. Command Description nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). See our other New Relic One CLI docs for commands specific to Nerdpack set-up, Nerdpack subscriptions, CLI configuration, plugins, or catalogs. Command details nr1 help See commands and get details Shows all nr1 commands by default. To get details about a specific command, run nr1 help COMMAND_NAME. Usage $ nr1 help Arguments COMMAND_NAME The name of a particular command. Examples $ nr1 help $ nr1 help nerdpack $ nr1 help nerdpack:deploy nr1 update Update your CLI Updates to latest version of the CLI. You can specify which channel to update if you'd like. Usage $ nr1 update Arguments CHANNEL The name of a particular channel. Examples $ nr1 update $ nr1 update somechannel nr1 create Create a new component Creates a new component from our template (either a Nerdpack, Nerdlet, launcher, or catalog). The CLI will walk you through this process. To learn more about Nerdpacks and their file structure, see Nerdpack file structure. For more on how to set up your Nerdpacks, see our Nerdpack CLI commands. Usage $ nr1 create Options -f, --force If present, overrides existing files without asking. -n, --name=NAME Names the component. -t, --type=TYPE Specifies the component type. --path=PATH The route to the component. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output. nr1 profiles Manage your profiles keychain Displays a list of commands you can use to manage your profiles. Run nr1 help profiles:COMMAND for more on their specific usages. You can have more than one profile, which is helpful for executing commands on multiple New Relic accounts. To learn more about setting up profiles, see our Github workshop. Usage $ nr1 profiles:COMMAND Commands profiles:add Adds a new profile to your profiles keychain. profiles:default Chooses which profile should be default. profiles:list Lists the profiles on your keychain. profiles:remove Removes a profile from your keychain. nr1 autocomplete See autocomplete installation instructions Displays the autocomplete installation instructions. By default, the command displays the autocomplete instructions for zsh. If you want instructions for bash, run nr1 autocomplete bash. Usage $ nr1 autocomplete Arguments SHELL The shell type you want instructions for. Options -r, --refresh-cache Refreshes cache (ignores displaying instructions). Examples $ nr1 autocomplete $ nr1 autocomplete zsh $ nr1 autocomplete bash $ nr1 autocomplete --refresh-cache nr1 nrql Query using NRQL Fetches data from databases using a NRQL query. To learn more about NRQL and how to use it, see our NRQL docs. Usage $ nr1 nrql OPTION ... Options -a, --account=ACCOUNT The user account ID. required -q, --query=QUERY The NRQL query to run. required -u, --ugly Displays the content without tabs or spaces. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output.", "type": "developer", "document_type": "page", - "info": "A Table component!", + "info": "An overview of common commands you can use with the New Relic One CLI.", "sections": [ - "Table", + "New Relic One CLI common commands", + "Command details", + "nr1 help", + "See commands and get details", "Usage", - "Props" + "Arguments", + "Examples", + "nr1 update", + "Update your CLI", + "nr1 create", + "Create a new component", + "Options", + "nr1 profiles", + "Manage your profiles keychain", + "Commands", + "nr1 autocomplete", + "See autocomplete installation instructions", + "nr1 nrql", + "Query using NRQL" ], - "title": "Table", + "title": "New Relic One CLI common commands", "popularity": 1, - "external_id": "878b3ab08dbd0a7df42558a970648013adde957f", + "external_id": "503e515e1095418f8d19329517344ab209d143a4", "image": "", - "url": "https://developer.newrelic.com/components/table/", - "published_at": "2020-08-18T02:07:10Z", - "updated_at": "2020-08-03T04:46:36Z", + "url": "https://developer.newrelic.com/explore-docs/nr1-common/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:48:10Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 1.4275227, + "_score": 0.37769696, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Table", - "sections": "Table", - "info": "A Table component!", - "body": "Table Usage Copy Props There are no props for this component." + "title": "New Relic One CLI common commands", + "sections": "New Relic One CLI common commands", + "info": "An overview of common commands you can use with the New Relic One CLI.", + "body": "New Relic One CLI common commands Here's a list of common commands to get you started with the New Relic One CLI. You can click any command to see its usage options and additional details about the command. Command Description nr1 help Shows all nr1 commands or details about each command. nr1" }, - "id": "5efa98d428ccbcebbd307dfb" - }, + "id": "5f28bd6ae7b9d267996ade94" + } + ], + "/build-apps/add-time-picker-guide": [ { - "body": "UserTableRowCell Usage Copy Props There are no props for this component.", + "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations, and fetch New Relic or third-party data. Components of the SDK SDK components are located in the Node module package named nr1, which you get when you install the NR1 CLI. The nr1 components can be divided into several categories: UI components Chart components Query and storage components Platform APIs UI components The UI components category of the SDK contains React UI components, including: Text components: These components provide basic font and heading elements. These include HeadingText and BlockText. Layout components: These components give you control over the layout, and help you build complex layout designs without having to deal with the CSS. Layout components include: Grid and GridItem: for organizing more complex, larger scale page content in rows and columns Stack and StackItem: for organizing simpler, smaller scale page content (in column or row) Tabs and TabsItem: group various related pieces of content into separate hideable sections List and ListItem: for providing a basic skeleton of virtualized lists Card, CardHeader and CardBody : used to group similar concepts and tasks together Form components: These components provide the basic building blocks to interact with the UI. These include Button, TextField, Dropdown and DropdownItem, Checkbox, RadioGroup, Radio, and Checkbox. Feedback components: These components are used to provide feedback to users about actions they have taken. These include: Spinnerand Toast. Overlaid components: These components are used to display contextual information and options in the form of an additional child view that appears above other content on screen when an action or event is triggered. They can either require user interaction (like modals), or be augmenting (like a tooltip). These include: Modal and Tooltip. Components suffixed with Item can only operate as direct children of that name without the suffix. For example: GridItem should only be found as a child of Grid. Chart components The Charts category of the SDK contains components representing different types of charts. The ChartGroup component helps a group of related charts share data and be aligned. Some chart components can perform NRQL queries on their own; some accept a customized set of data. Query and storage components The Query components category contains components for fetching and storing New Relic data. The main way to fetch data is with NerdGraph, our GraphQL endpoint. This can be queried using NerdGraphQuery. To simplify use of NerdGraph queries, we provide some components with pre-defined queries. For more on using NerdGraph, see Queries and mutations. We also provide storage for storing small data sets, such as configuration settings data, or user-specific data. For more on this, see NerdStorage. Platform APIs The Platform API components of the SDK enable your application to interact with different parts of the New Relic One platform, by reading and writing state from and to the URL, setting the configuration, etc. They can be divided into these categories: PlatformStateContext: provides read access to the platform URL state variables. Example: timeRange in the time picker. navigation: an object that allows programmatic manipulation of the navigation in New Relic One. Example: opening a new Nerdlet. NerdletStateContext: provides read access to the Nerdlet URL state variables. Example: an entityGuid in the entity explorer. nerdlet: an object that provides write access to the Nerdlet URL state.", "type": "developer", "document_type": "page", - "info": "A UserTableRowCell component!", + "info": "Intro to New Relic One API components", "sections": [ - "UserTableRowCell", - "Usage", - "Props" + "Intro to New Relic One API components", + "Components of the SDK", + "UI components", + "Chart components", + "Query and storage components", + "Platform APIs" ], - "title": "UserTableRowCell", + "title": "Intro to New Relic One API components", "popularity": 1, - "external_id": "765e8c8ba01ca8ae96c8e45e2223941812e17294", + "tags": [ + "SDK components", + "New Relic One apps", + "UI components", + "chart components", + "query and storage components", + "Platform APIs" + ], + "external_id": "3620920c26bcd66c59c810dccb1200931b23b8c2", "image": "", - "url": "https://developer.newrelic.com/components/user-table-row-cell/", - "published_at": "2020-08-18T02:07:10Z", - "updated_at": "2020-08-03T04:46:36Z", + "url": "https://developer.newrelic.com/explore-docs/intro-to-sdk/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:47:12Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 1.3801258, + "_score": 1.3013654, "_version": null, "_explanation": null, "sort": null, "highlight": { - "info": "A UserTableRowCell component!", - "body": "UserTableRowCell Usage Copy Props There are no props for this component." + "tags": "New Relic One apps", + "body": ". They can be divided into these categories: PlatformStateContext: provides read access to the platform URL state variables. Example: timeRange in the time picker. navigation: an object that allows programmatic manipulation of the navigation in New Relic One. Example: opening a new Nerdlet" }, - "id": "5efa98d464441f3b815f7e72" - } - ], - "/collect-data/get-started-nerdgraph-api-explorer": [ - { - "body": "You can manage your policies, conditions, and muting rules programmatically using our GraphQL NerdGraph API. This is a powerful alternative to managing them in New Relic One or through the REST API. Alerts features you can manage with NerdGraph Here's what you can do in NerdGraph: Manage policies Use NRQL conditions Muting rules: suppress notifications The easiest way to discover alerts queries and mutations is through the NerdGraph API explorer. NerdGraph API explorer Our NerdGraph API explorer is a GraphiQL editor where you can prototype queries and mutations. Here are some examples showing how to find fields for queries and mutations. For general information about NerdGraph, see Introduction to NerdGraph. Queries To explore the various queries, look for the available queries under the actor.account.alerts namespace in NerdGraph API explorer: Mutations To explore various mutations, look in the alerts dropdown in the NerdGraph API explorer: For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", - "type": "docs", - "document_type": "page", - "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / Alerts and Nerdgraph", - "info": "Read about how you can manage alerts conditions, policies, and muting rules using NerdGraph.", - "nodeid": 37751, - "sections": [ - "New Relic Alerts", - "Get started", - "Alert policies", - "Alert conditions", - "Alert violations", - "Alert Incidents", - "Alert notifications", - "Troubleshooting", - "Rules, limits, and glossary", - "Alerts and Nerdgraph", - "REST API alerts", - "NerdGraph API: Examples", - "Alerts features you can manage with NerdGraph", - "NerdGraph API explorer", - "Queries", - "Mutations", - "For more help" - ], - "title": "NerdGraph API: Examples ", - "popularity": 1, - "external_id": "017d6c34d340b9bc035e91483d675915fa5252eb", - "category_1": "New Relic Alerts", - "image": "https://docs.newrelic.com/sites/default/files/thumbnails/image/alerts_query_0.png", - "url": "https://docs.newrelic.com/docs/alerts-applied-intelligence/new-relic-alerts/alerts-nerdgraph/nerdgraph-api-examples", - "published_at": "2020-08-18T18:16:49Z", - "updated_at": "2020-08-11T04:59:00Z", - "category_0": "Alerts and Applied intelligence", - "_index": "520d1d5d14cc8a32e600034b", - "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.5397293, - "_version": null, - "_explanation": null, - "sort": null, - "highlight": { - "title": "NerdGraph API: Examples ", - "sections": "Mutations", - "info": "Read about how you can manage alerts conditions, policies, and muting rules using NerdGraph.", - "body": " Use NRQL conditions Muting rules: suppress notifications The easiest way to discover alerts queries and mutations is through the NerdGraph API explorer. NerdGraph API explorer Our NerdGraph API explorer is a GraphiQL editor where you can prototype queries and mutations. Here are some examples showing", - "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / Alerts and Nerdgraph" - }, - "id": "5f2dbad864441fd15456a9eb" - }, - { - "body": "You can manage alerts conditions using our GraphQL NerdGraph API. Here are some conditions queries and mutations you can develop in our NerdGraph API explorer. See the NerdGraph introduction for help getting started with NerdGraph API explorer. This document covers the following: Steps to create a NRQL condition NRQL static condition NRQL baseline condition NRQL outlier condition Update a condition Update mutations List and filter NRQL conditions Singular NRQL condition queries Create a description Delete conditions Steps to create a NRQL condition Follow these steps: Decide which condition type you want to create (see NRQL Condition threshold types). Find your relevant policyID by doing one of the following: Use the NerdGraph policies API. Go to one.newrelic.com, in the top nav click Alerts & AI, then click Policies. Choose a policy. Find the ID under the policy name. Provide the appropriate mutation for your NRQL condition type and the relevant values. The NerdGraph GraphiQL explorer is the best place to find up-to-date documentation about the per-field specifics of the NerdGraph NRQL Conditions API. For example, questions like \"What does the valueFunction field accept?\" are best answered with the inline NerdGraph documentation. NRQL static condition Here's an example of creating a static condition: mutation { alertsNrqlConditionStaticCreate(accountId: YOUR_ACCOUNT_ID, policyId: YOUR_POLICY_ID, condition: { name: \"Low Host Count - Catastrophic\" enabled: true nrql: { query: \"SELECT uniqueCount(host) from Transaction where appName='my-app-name'\" evaluationOffset: 3 } terms: { threshold: 2 thresholdOccurrences: AT_LEAST_ONCE thresholdDuration: 600 operator: BELOW priority: CRITICAL } valueFunction: SINGLE_VALUE violationTimeLimit: TWENTY_FOUR_HOURS }) { id name } } NRQL baseline condition Here's an example of creating a baseline condition: mutation { alertsNrqlConditionBaselineCreate(accountId: YOUR_ACCOUNT_ID, policyId: YOUR_POLICY_ID, condition: { name: \"Baseline Condition\" enabled: true baselineDirection: UPPER_ONLY nrql: { query: \"SELECT average(duration) FROM Transaction\" evaluationOffset: 3 } terms: { threshold: 13 thresholdDuration: 180 thresholdOccurrences: ALL operator: ABOVE priority: CRITICAL } violationTimeLimit: TWENTY_FOUR_HOURS }) { id name baselineDirection } } NRQL outlier condition Here's an example of creating an outlier condition: mutation { alertsNrqlConditionOutlierCreate(accountId: YOUR_ACCOUNT_ID, policyId: YOUR_POLICY_ID, condition: { name: \"Outlier Condition\" enabled: true expectedGroups: 4 openViolationOnGroupOverlap: false nrql: { query: \"SELECT average(duration) FROM Transaction FACET httpResponseCode\" evaluationOffset: 3 } terms: { threshold: 1 thresholdDuration: 300 thresholdOccurrences: ALL operator: ABOVE priority: CRITICAL } violationTimeLimit: TWENTY_FOUR_HOURS }) { id name expectedGroups openViolationOnGroupOverlap } } Update a condition Complete the following: Determine the type of your existing condition by requesting the type field in a nrqlConditionsSearch query like this: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditionsSearch { nrqlConditions { id type } } } } } } The type returned is what you use for your update mutation. For example, if the type returned is STATIC, use alertsNrqlConditionStaticUpdate. If the type returned is BASELINE, use alertsNrqlConditionBaselineUpdate. If the type returned is OUTLIER, use alertsNrqlConditionOutlierUpdate. Provide the id of your condition to your relevant condition type mutation. Note that you can only update conditions of the relevant type. Only provide update mutations for the fields you want to update. Fields you don't provide in the update are not touched. Update mutations Only fields that you provide in the update are changed. In the following example, baselineDirection returns unchanged, but name is updated. mutation { alertsNrqlConditionBaselineUpdate(id: YOUR_CONDITION_ID, accountId: YOUR_ACCOUNT_ID, condition: { name: \"Your updated name\" }) { id name baselineDirection } } List and filter NRQL conditions To list or filter your NRQL conditions, use the nrqlConditionsSearch query in NerdGraph. Use cursor pagination The basic of list functionality for NRQL conditions allows you to paginate through your NRQL conditions as well as request the total count of conditions per account. The nrqlConditionsSearch query utilizes cursor pagination to paginate through resources. The idea behind cursor pagination is that the client will request a cursor in a programmatic loop until the cursor comes back empty. An initial list response will look something like this: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditionsSearch { nextCursor nrqlConditions { id name type } totalCount } } } } } This example returns a JSON response like this: { \"data\": { \"actor\": { \"account\": { \"alerts\": { \"nrqlConditionsSearch\": { \"nextCursor\": \"WOwfJ4+TWm9QTFeKMGyg+w==:QqkI8S4+Wwnpno6z+uk8kQ==\", \"nrqlConditions\": [ { \"id\": \"4432\", \"name\": \"Baseline Condition\", \"type\": \"BASELINE\" }, { \"id\": \"443\", \"name\": \"A static condition\", \"type\": \"STATIC\" }, // more conditions here in reality ], \"totalCount\": 435 } } } } }, } In order to paginate through conditions in the response, have the client request the cursor to be returned until the nextCursor returns from the response as null: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditionsSearch(cursor: \"WOwfJ4+TWm9QTFeKMGyg+w==:QqkI8S4+Wwnpno6z+uk8kQ==\", ) { nextCursor nrqlConditions { id name type } totalCount } } } } } Request type-specific fields Certain fields are only available on specific NRQL condition types. The main reason that mutations are split between the different condition types is because they have minor differences between the fields they accept. For example, valueFunction is only relevant for static NRQL conditions and baselineDirection is only relevant on baseline NRQL conditions. But if these fields are only available on these certain condition types, how do we return them in a list of all of our condition types? The answer is a GraphQL convention known as inline fragments. Inline fragments allow you to access the data on a specific type of NRQL condition: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditionsSearch { nrqlConditions { id name type ...on AlertsNrqlStaticCondition { valueFunction } ...on AlertsNrqlBaselineCondition { baselineDirection } ...on AlertsNrqlOutlierCondition { expectedGroups } } } } } } } In the previous example query, we are asking GraphQL to do the hard work for us to determine which NRQL conditions are the correct type. So, when the returned type is a static condition, it will return the valueFunction in the object. When the returned type is a baseline condition, it will return baselineDirection instead, and when the type is an outlier condition, it will return expectedGroups. Here is an example response: { \"data\": { \"actor\": { \"account\": { \"alerts\": { \"nrqlConditionsSearch\": { \"nrqlConditions\": [ { \"baselineDirection\": \"UPPER_ONLY\", \"id\": \"342\", \"name\": \"My baseline condition\", \"type\": \"BASELINE\" }, { \"id\": \"553\", \"name\": \"My static condition\", \"type\": \"STATIC\", \"valueFunction\": \"SINGLE_VALUE\" }, { \"expectedGroups\": 4, \"id\": \"802\", \"name\": \"My outlier condition\", \"type\": \"OUTLIER\" } ] } } } } } } Filter NRQL conditions You can filter NRQL conditions with the searchCriteria argument of the nrqlConditionsSearch query: Here's an example of filtering NRQL conditions with matching by name. This query returns NRQL conditions that match the provided name. Note that this match is case insensitive. { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditionsSearch(searchCriteria: { name: \"Baseline Condition\" }) { nrqlConditions { id name type } } } } } } Singular NRQL condition queries You can use the NRQL condition API to query for a singular condition. Run the nrqlCondition query in the alerts namespace. Similar to type specific fields on the nrqlConditionSearch query, you can also use these inline fragmentsto request fields that are restricted to a NRQL condition type. { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlCondition(id: YOUR_CONDITION_ID) { id name ...on AlertsNrqlStaticCondition { valueFunction } } } } } } Update the description This will walk you through the procedure to create a description for a NRQL alert condition. 1. Get all the conditions for a policy: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditions(policyId: YOUR_POLICY_ID) { nextCursor results { id name description enabled nrql { query sinceValue } policyId runbookUrl terms { duration operator priority timeFunction threshold } type violationTimeLimit } } } } } } 2. Get the details for a single condition: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlCondition(id: \"YOUR_CONDITION_ID\") { description id enabled name nrql { query evaluationOffset } policyId runbookUrl terms { operator priority threshold thresholdDuration thresholdOccurrences } type violationTimeLimit } } } } } 3. Create a mutation with the description. Here's an empty mutation template: mutation { alertsNrqlConditionStaticUpdate(accountId: YOUR_ACCOUNT_ID, id: \"YOUR_CONDITION_ID\", condition: {description: \"\"}) { description } } Here'a an example mutation with an included example description: mutation { alertsNrqlConditionStaticUpdate(accountId: 123456, id: \"123456\", condition: {description: \"timestamp : {{timestamp}} \\n accountId : {{accountId}} \\n type : {{type}} \\n event : {{event}} \\n description : {{description}} \\n policyId : {{policyId}} \\n policyName: {{policyName}} \\n conditionName : {{conditionName}} \\n conditionId : {{conditionId}} \\n product : {{product}} \\n conditionType : {{conditionType}} \\n RunbookUrl : {{runbookUrl}} \\n nrqlQuery : {{nrqlQuery}} \\n nrqlEventType : {{nrqlEventType}} \\n targetID : {{targetId}} \\n targetName : {{targetName}} \\n commandLine : {{tag.commandLine}} \\n entityGuid : {{tag.entityGuid}} \\n entityName : {{tag.entityName}} \\n fullHostname : {{tag.fullHostname}} \\n instanceType : {{tag.instanceType}} \\n processDisplayName : {{tag.processDisplayName}}\"}) { description } } Delete conditions You can use the alertsConditionDelete mutation to delete any type of condition. You can only request the id field on a delete mutation; for example: mutation { alertsConditionDelete(accountId: YOUR_ACCOUNT_ID, id: YOUR_CONDITION_ID) { id } } For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", - "type": "docs", - "document_type": "page", - "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / Alerts and Nerdgraph", - "info": "Examples of how to use the NerdGraph API explorer to create alert conditions, queries, and mutations.", - "nodeid": 37711, - "sections": [ - "New Relic Alerts", - "Get started", - "Alert policies", - "Alert conditions", - "Alert violations", - "Alert Incidents", - "Alert notifications", - "Troubleshooting", - "Rules, limits, and glossary", - "Alerts and Nerdgraph", - "REST API alerts", - "NerdGraph API: NRQL condition alerts", - "Steps to create a NRQL condition", - "NRQL static condition", - "NRQL baseline condition", - "NRQL outlier condition", - "Update a condition", - "Update mutations", - "List and filter NRQL conditions", - "Singular NRQL condition queries", - "Update the description", - "Delete conditions", - "For more help" - ], - "title": "NerdGraph API: NRQL condition alerts ", - "popularity": 1, - "external_id": "86591bd20017930f1e4eef1b1a76e3806298dbb9", - "category_1": "New Relic Alerts", - "image": "", - "url": "https://docs.newrelic.com/docs/alerts-applied-intelligence/new-relic-alerts/alerts-nerdgraph/nerdgraph-api-nrql-condition-alerts", - "published_at": "2020-08-18T18:15:13Z", - "updated_at": "2020-08-11T04:56:49Z", - "category_0": "Alerts and Applied intelligence", - "_index": "520d1d5d14cc8a32e600034b", - "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.27475727, - "_version": null, - "_explanation": null, - "sort": null, - "highlight": { - "title": "NerdGraph API: NRQL condition alerts ", - "sections": "Update mutations", - "info": "Examples of how to use the NerdGraph API explorer to create alert conditions, queries, and mutations.", - "body": "You can manage alerts conditions using our GraphQL NerdGraph API. Here are some conditions queries and mutations you can develop in our NerdGraph API explorer. See the NerdGraph introduction for help getting started with NerdGraph API explorer. This document covers the following: Steps to create", - "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / Alerts and Nerdgraph" - }, - "id": "5f2dee1128ccbc562e88dfc1" + "id": "5efa989e28ccbc4071307de5" }, { - "body": "This document provides examples of how to use New Relic NerdGraph to query and modify your cloud integration configuration data, including Amazon AWS, Microsoft Azure, and Google Cloud Platform (GCP). Using the NerdGraph GraphiQL explorer, you can also query NRQL data. These examples for querying cloud integration configuration data use GraphQL queries and mutations: Queries: requests that are intended to only fetch data Mutations: requests that create or update data on the server Requirements Before querying cloud integration data with NerdGraph, ensure you have: Followed the instructions to connect cloud integrations with New Relic. Created an API key. Access the NerdGraph GraphiQL explorer To access the NerdGraph GraphiQL explorer: Go to https://api.newrelic.com/graphiql. Add any of the following examples. Query examples Queries are requests that are intended to only fetch data (no side effects). Queries in NerdGraph are not static, meaning that you can ask for more or less data depending on your needs. For each query, you can specify exactly what data you want to retrieve, as long as it is supported by the schema. Available provider accounts This query returns a list of all provider accounts available in your infrastructure data. Depending on the provider, additional properties can be requested. For example, for GCP, you can also ask for the serviceAccountId property, which is needed when linking a new GCP project to New Relic. Anonymous: { actor { account(id: ) { cloud { providers { id name slug ... on CloudGcpProvider { serviceAccountId } } } } } } Named: query cloudProviders { actor { account(id: ) { cloud { providers { id name slug } } } } } Specific provider account information This query returns information about a specific provider account for your Amazon AWS integration. The properties id, name, slug are requested, along with a list of integrations available to be monitored. { actor { account(id: ) { cloud { provider(slug: \"aws\") { id slug name services { id slug name } } } } } } Specific integration data from a specific cloud provider This query returns information about a specific cloud service integration of a provider. In this example, the integration is the Amazon AWS ALB monitoring integration and the provider is AWS. The properties id, name, slug, and isAllowed are requested with the available configuration parameters. { actor { account(id: ) { cloud { provider(slug: \"aws\") { service(slug: \"alb\") { id name slug isEnabled } } } } } } List of enabled cloud accounts This query returns the list of cloud accounts enabled with your New Relic account. (Your cloud account associates your New Relic account and a specific provider account with your integration.) You can enable multiple cloud provider accounts in the same New Relic account, even with the same cloud provider. { actor { account(id: ) { cloud { linkedAccounts { id name createdAt provider { id name } } } } } } Specific linked account data This query returns information about a linked account, including the properties name, providerId, and a list of the cloud integrations enabled for monitoring. { actor { account(id: ) { cloud { linkedAccount(id: ) { name provider { id name } integrations { id name createdAt updatedAt } } } } } } Enabled cloud integrations for all linked accounts This query returns all monitored integrations for all the provider cloud accounts. { actor { account(id: ) { cloud { linkedAccounts { name provider { id name } integrations { id name service { id name } createdAt updatedAt } } } } } } Specific cloud integration data for a specific linked account This query returns information about a specific integration from a specific linked account. { actor { account(id: ) { cloud { linkedAccount(id: ) { name provider { id name } integration(id: ) { id name service { id name } createdAt updatedAt } } } } } } Mutation examples Mutations are requests that are intended to have side effects, such as creating or updating data on the server. Mutations require the keyword mutation and the name of the mutation. NerdGraph mutations are restricted to a subset of all possible mutations. Link an account This mutation allows linking cloud provider accounts to a New Relic account, creating one or more linked accounts. It can link one specific cloud provider account (for example aws) to the New Relic account or multiple cloud provider accounts to one New Relic account. Required: The parameter is required and cannot be empty. It must be unique in your New Relic account. Other parameters are specific to the provider (AWS, GCP, and Azure) and are also required. In the following sections, you can see which parameters are required for each provider account. After linking an account the createdAt and updatedAt values are equal. mutation { cloudLinkAccount( accounts: { accountId: , aws: [{ name: , }] azure: [{ name: , }] gcp: [{ name: , }] } ) { linkedAccounts { id name authLabel createdAt updatedAt } } } } Link an Amazon AWS account This mutation links an Amazon AWS provider account to your New Relic account. mutation { cloudLinkAccount( accountId: , accounts: { aws: [{ name: , arn: }] } ) { linkedAccounts { id name authLabel createdAt updatedAt } } } } Link a Microsoft Azure account This mutation links a Microsoft Azure cloud subscription to the New Relic account. mutation { cloudLinkAccount( accountId: , accounts: { azure: [{ name: , applicationId: , clientSecret: , tenantId: , subscriptionId: }] } ) { linkedAccounts { id name authLabel createdAt updatedAt } } } Link a Google Cloud Platform (GCP) project This mutation links a GCP project to the New Relic account. mutation { cloudLinkAccount( accountId: , accounts: { gcp: [{ name: , projectId: }] } ) { linkedAccounts { id name authLabel createdAt updatedAt } } } Rename one or more cloud accounts This mutation allows you to rename one or more linked provider accounts. The name parameter is required, cannot be empty, and must be unique within your New Relic account. mutation { cloudRenameAccount( accountId: , accounts: [ { id: , name: }, { id: , name: } ] ) { linkedAccounts { id name } } } Enable an integration in a cloud account This mutation allows you to enable the monitoring of one or more specific cloud integrations in an existing cloud account. With this mutation, New Relic records data for the enabled integration from the provider account. For each provider account you have access to different input parameters, matching each available service. mutation { cloudConfigureIntegration ( accountId: , integrations: { : { : [{ linkedAccountId: , }] } } ) { integrations { id name integration { id slug } ... on SqsIntegration { awsRegions } } } } Enable an integration in multiple cloud accounts If you have many provider accounts linked, you can enable the same integration in the many cloud accounts at the same time. For the output of the operation, you can use GraphQL fragments for integration specific configuration parameters. mutation { cloudConfigureIntegration ( accountId: , integrations: { : { : [ { linkedAccountId: }, { linkedAccountId: } ] } } ) { integrations { id name integration { id name } ... on SqsIntegration { awsRegions } } } } Enable multiple integrations in multiple cloud accounts If you have multiple cloud accounts linked, you can also enable multiple integrations in multiple linked cloud accounts at the same time. For the output of the operation, you can use GraphQL fragments to ask for integration specific configuration parameters. mutation { cloudConfigureIntegration ( accountId: , integrations: { : { : [ { linkedAccountId: } ] : [ { linkedAccountId: } ] }, : { : [ { linkedAccountId: }, { linkedAccountId: } ] } } ) { integrations { id name service { id name } ... on SqsIntegration { awsRegions } } } } Modify an integration's configuration (regions, polling intervals, etc.) This mutation also allows you to modify one or more cloud integrations and change one or more configuration parameters. Each service will have specific parameters that you can modify. For parameters of a type list (for example, awsRegion) supply the full list. For the output of the operation, you can use GraphQL fragments to ask for integration specific configuration parameters. mutation { cloudConfigureIntegration ( accountId: , integrations: { : { : [{ linkedAccountId: , metricsPollingInterval: , : , : , }] } } ) { integrations { id name service { id slug } ... on SqsIntegration { metricsPollingInterval, , } } errors { type message } } } Disable (remove) an integration This mutation allows you to disable an integration and stop data collection for the specific cloud integration. mutation { cloudDisableIntegration ( accountId: , integrations: { : { : [ { linkedAccountId: } ] } } ) { disabledIntegrations { id name authLabel provider { id } } errors { type message } } } Unlink account This mutation allows you to unlink cloud provider accounts from New Relic account. This action can not be undone. However, you can link the account again, but account history will still be lost. mutation { cloudUnlinkAccount ( accountId: , accounts: { { linkedAccountId: } } ) { unlinkedAccounts { id name } errors { type message } } } Enable an Amazon AWS integration This example uses an Amazon AWS SQS integration and assumes you have connected an AWS account to New Relic. To enable an Amazon AWS integration: Send query to fetch account data Send a query to fetch data about the account, specifically available providers and already created provider accounts: { actor { account(id: ) { cloud { providers { id name slug } linkedAccounts { name integrations { id name } } } } } } Link AWS provider account Link an AWS provider account, if there is not one already linked or if you want to link another AWS account: Use your New Relic account identifier in the parameter. Provide a name for the provider account in the . Include the ARN of the AWS role used to fetch data from your AWS account. mutation { cloudLinkAccount( accountId: , accounts: { aws: [{ name: , arn: }] } ) { linkedAccounts { id name authLabel createdAt updatedAt } errors { type message } } } Enable Amazon AWS SQS integration Use your New Relic account ID in the parameter and the ID of the provider account in the parameter value. mutation { cloudConfigureIntegration ( accountId: , integrations: { aws: { sqs: [ { linkedAccountId: } ] } } ) { integrations { id name service { id name } } errors { type message } } } Enable integration in multiple provider accounts If you have multiple accounts with the same provider account, you can enable the same integration in multiple provider accounts at the same time. Use your New Relic account ID in the parameter and the ID of the provider accounts in the parameter value. mutation { cloudConfigureIntegration ( accountId: , integrations: { aws: { sqs: [ { linkedAccountId: }, { linkedAccountId: , configuration_param_1: value_1, configuration_param_2: value_2 } ] } } }) { integrations { id name service { id name } } errors { type message } } } Change polling interval for Amazon AWS integration This example uses an Amazon AWS SQS integration and assumes you have connected an AWS account to New Relic. To change the polling interval of an AWS integration: Update the polling interval To update the polling interval for an Amazon AWS SQS integration, use your New Relic account ID in the parameter and the id of the linked provider account in the parameter value: mutation { cloudConfigureIntegration( accountId: , integrations: { aws : { sqs: [ { linkedAccountId: , metricsPollingInterval: 300 } ] } } ) { integrations { id name service { id slug } ... on SqsIntegration { metricsPollingInterval } } errors { type message } } } Disable Amazon AWS integration This example uses an Amazon AWS SQS integration and assumes you have connected an AWS account to New Relic. To disable an AWS integration: Disable the SQS integration Use your New Relic account identifier in the parameter and the ID of the linked cloud account the parameter value. mutation { cloudDisableIntegration ( accountId: , integrations: { aws: { sqs : [ { linkedAccountId: } ] } } ) { disabledIntegrations { id accountId name } errors { type message } } } For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", - "type": "docs", + "body": "Add the NerdGraphQuery component to an application 20 minutes This guide steps you through the process of adding the `NerdGraphQuery` component to a sample transaction overview application. This allows you to query data from your New Relic account and add it to a dropdown menu. NerdGraph is our GraphQL implementation. GraphQL has some key differences when compared to REST: The client, not the server, determines what data is returned. You can easily collect data from multiple sources. For example, in a single query, you can get account information, infrastructure data, and issue a NRQL request. Note Before completing this exercise, you can experiment with GraphQL queries in our NerdGraph API explorer. We also have a 14-minute video that covers the steps below. Before you begin To develop projects, you need our New Relic One CLI (command line interface). If you haven't already installed it, do the following: Install Node.js. Complete steps 1–4 of our CLI quick start, and be sure to make a copy of your account ID from step 1 because you’ll need it later. Note If you've already installed the New Relic One CLI, but you can't remember your account ID, start the CLI quick start again, and then click the Get your API key down arrow. The account ID is the number preceding your account name. For additional details, see Set up your development environment. Prepare the sample code To get started, complete these steps to update the application UUID (unique ID) and run the sample application locally: Step 1 of 7 If you haven't already done so, clone the example applications from our how-to GitHub repo. Here's an example using HTTPS: git clone https://github.com/newrelic/nr1-how-to.git Copy Step 2 of 7 Change to the directory use-nerdgraph-nerdlet: cd nr1-how-to/use-nerdgraph/nerdlets/use-nerdgraph-nerdlet Copy Step 3 of 7 In your preferred text editor, open index.js. Step 4 of 7 Replace with your account id: Note Your account ID is available in the CLI quick start (see Before you begin). this.accountId = ; Copy Step 5 of 7 Change to the /nr1-howto/use-nerdgraph directory: cd ../.. Copy Step 6 of 7 Execute these commands to update the UUID and serve the sample application: nr1 nerdpack:uuid -gf nr1 nerdpack:serve Copy Step 7 of 7 Once the sample application is successfully served, go to the local New Relic One homepage (https://one.newrelic.com/?nerdpacks=local), click Apps, and then click Use NerdGraph. After launching the Use NerdGraph application, you see a dashboard that gives an overview of the transactions in your account: Add the NerdGraphQuery component Now you can create a dropdown menu for changing the account the application is viewing. The first step is to import the NerdGraphQuery component into the application's index.js file. Note If you need more details about our example below, see the APIs and components page on https://developer.newrelic.com Step 1 of 3 Add the NerdGraphQuery component into the first StackItem inside of the return in the index.js file: {({ loading, error, data }) => { console.log({ loading, error, data }); if (loading) { return ; } if (error) { return 'Error!'; } return null; }} ; Copy Step 2 of 3 The NerdGraphQuery component takes a query object that states the source you want to access and the data you want returned. Add the following code to your index.js file in the render method: Note In the browser console, you can see the data from your query returned in an object that follows the same structure of the object in the initial query. const query = ` query($id: Int!) { actor { account(id: $id) { name } } } `; Copy Step 3 of 3 To take the data returned by the NerdGraph query and display it in the application, replace the return null in the current NerdGraphQuery component with this return statement: return {data.actor.account.name} Apps:; Copy When you go back to the browser and view your application, you see a new headline showing the name of your account returned from NerdGraph: How to use NerdGraphQuery.query At this point, you have implemented the NerdGraphQuery component with the application's render method and displayed the return data within the transaction overview application. Here's what you need to do next: Query NerdGraph inside of the componentDidMount lifecycle method. Save the returned data for later use in the application. Step 1 of 2 This code takes the response from NerdGraph and makes sure the results are processed, stored into the application state, and logged to the browser console for viewing. Add this code into the index.js file just under the constructor: componentDidMount() { const accountId = this.state; const gql = `{ actor { accounts { id name } } }`; const accounts = NerdGraphQuery.query({query: gql}) //The NerdGraphQuery.query method called with the query object to get your account data is stored in the accounts variable. accounts.then(results => { console.log('Nerdgraph Response:', results); const accounts = results.data.actor.accounts.map(account => { return account; }); const account = accounts.length > 0 && accounts[0]; this.setState({ selectedAccount: account, accounts }); }).catch((error) => { console.log('Nerdgraph Error:', error); }) } Copy Step 2 of 2 After the data is stored into state, display a selection so users can change accounts and update the application. To do this, add this code to index.js for the second StackItem in the return statement: { accounts && ( ); } Copy Review the results of the NerdGraph query After you complete these steps, look at the application in your browser, and note the following: The dropdown menu now displays the data returned from the NerdGraphQuery.query and allows you to select an account. After you select a new account, the application shows data from the new selection. The final index.js file should have code similar to the code below. This completed sample is in your nerdlet final.js. import React from 'react'; import { PlatformStateContext, NerdGraphQuery, Spinner, HeadingText, Grid, GridItem, Stack, StackItem, Select, SelectItem, AreaChart, TableChart, PieChart } from 'nr1' import { timeRangeToNrql } from '@newrelic/nr1-community'; // https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction export default class UseNerdgraphNerdletNerdlet extends React.Component { constructor(props){ super(props) this.state = { accountId: , accounts: null, selectedAccount: null, } } componentDidMount() { const accountId = this.state; const gql = `{ actor { accounts { id name } } }`; const accounts = NerdGraphQuery.query({ query: gql }) accounts.then(results => { console.log('Nerdgraph Response:', results); const accounts = results.data.actor.accounts.map(account => { return account; }); const account = accounts.length > 0 && accounts[0]; this.setState({ selectedAccount: account, accounts }); }).catch((error) => { console.log('Nerdgraph Error:', error); }) } selectAccount(option) { this.setState({ accountId: option.id, selectedAccount: option }); } render() { const { accountId, accounts, selectedAccount } = this.state; console.log({ accountId, accounts, selectedAccount }); const query = ` query($id: Int!) { actor { account(id: $id) { name } } } `; const variables = { id: accountId, }; const avgResTime = `SELECT average(duration) FROM Transaction FACET appName TIMESERIES AUTO `; const trxOverview = `FROM Transaction SELECT count(*) as 'Transactions', apdex(duration) as 'apdex', percentile(duration, 99, 95) FACET appName `; const errCount = `FROM TransactionError SELECT count(*) as 'Transaction Errors' FACET error.message `; const responseCodes = `SELECT count(*) as 'Response Code' FROM Transaction FACET httpResponseCode `; return ( {({loading, error, data}) => { if (loading) { return ; } if (error) { return 'Error!'; } return {data.actor.account.name} Apps:; }} {accounts && }
{(PlatformState) => { /* Taking a peek at the PlatformState */ const since = timeRangeToNrql(PlatformState); return ( <>
Transaction Overview
Average Response Time
Response Code
Transaction Errors
); }}
) } } Copy Summary Now that you've completed all the steps in this example, you've successfully queried data from your account using the NerdGraphQuery component in two methods: Using the NerdGraphQuery component inside the application's render method and then passing the returned data into the children's components. Using the NerdGraphQuery.query method to query data before the application renders.", + "type": "developer", "document_type": "page", - "breadcrumb": "Contents / APIs / NerdGraph / Examples", - "info": "Use New Relic's NerdGraph (our GraphQL API) to query your New Relic Infrastructure cloud integration data. ", - "nodeid": 17141, + "info": "The NerdGraphQuery component allows you to query data from your account and add it to a dropdown menu in an application", "sections": [ - "NerdGraph", - "Get started", - "Examples", - "NerdGraph cloud integrations API tutorial", - "Requirements", - "Access the NerdGraph GraphiQL explorer", - "Query examples", - "Mutation examples", - "Enable an Amazon AWS integration", - "Change polling interval for Amazon AWS integration", - "Disable Amazon AWS integration", - "For more help" + "Add the NerdGraphQuery component to an application", + "Note", + "Before you begin", + "Prepare the sample code", + "Add the NerdGraphQuery component", + "How to use NerdGraphQuery.query", + "Review the results of the NerdGraph query", + "Summary" ], - "title": "NerdGraph cloud integrations API tutorial", + "title": "Add the NerdGraphQuery component to an application", "popularity": 1, - "external_id": "15caa0b35be84f2e6245826a5c9ac8e49cad6a89", - "category_1": "NerdGraph", - "category_2": "Examples", - "image": "", - "url": "https://docs.newrelic.com/docs/apis/nerdgraph/examples/nerdgraph-cloud-integrations-api-tutorial", - "published_at": "2020-08-18T03:42:15Z", - "updated_at": "2020-08-10T23:22:01Z", - "category_0": "APIs", - "_index": "520d1d5d14cc8a32e600034b", - "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.2695496, - "_version": null, - "_explanation": null, - "sort": null, - "highlight": { - "title": "NerdGraph cloud integrations API tutorial", - "sections": "NerdGraph", - "info": "Use New Relic's NerdGraph (our GraphQL API) to query your New Relic Infrastructure cloud integration data. ", - "category_1": "NerdGraph", - "body": "This document provides examples of how to use New Relic NerdGraph to query and modify your cloud integration configuration data, including Amazon AWS, Microsoft Azure, and Google Cloud Platform (GCP). Using the NerdGraph GraphiQL explorer, you can also query NRQL data. These examples for querying", - "breadcrumb": "Contents / APIs / NerdGraph / Examples" - }, - "id": "5d83537b28ccbc263a1b7bf7" - }, - { - "body": "You can manage your alerts policies using our GraphQL NerdGraph API. Here are some queries and mutations you can develop in our NerdGraph API explorer. See the NerdGraph introduction for help getting started with NerdGraph API explorer. List and filter policies The policiesSearch query allows you to paginate through all of your policies per account. It also allows some filtering functionality on the account policies. Listing all policies for an account Here's an example: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { policiesSearch { policies { id name incidentPreference } } } } } } Paginating through policies with cursor pagination In order to paginate through your policies, you must request the nextCursor field on your initial query. With cursor pagination, you continue to make a request through the result set until the nextCursor that is returned from the response comes back empty. This signifies that you reached the end of your results. Here's an example: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { policiesSearch { nextCursor policies { id name incidentPreference } totalCount } } } } } The code above returns a set of results like this: { \"data\": { \"actor\": { \"account\": { \"alerts\": { \"policiesSearch\": { \"nextCursor\": \"/8o0y2qiR54m6thkdgHgwg==:jZTXDFKbTkhKwvMx+CtsPVM=\", \"policies\": [ { \"id\": \"3455\", \"incidentPreference\": \"PER_POLICY\", \"name\": \"First Policy Name\" }, { \"id\": \"2123\", \"incidentPreference\": \"PER_POLICY\", \"name\": \"Another Policy\" }, // ... more policies here in reality ], \"totalCount\": 745 } } } } } } So, in your subsequent request, provide the cursor like so, until the cursor is empty: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { policiesSearch(cursor: \"/8o0y2qiR54m6thkdgHgwg==:jZTXDFKbTkhKwvMx+CtsPVM=\") { nextCursor policies { id name incidentPreference } totalCount } } } } } Find all policies by selected ids The API allows policy queries by a sub-select of ids. This will only return the information for these policies that you provide. { actor { account(id: YOUR_ACCOUNT_ID) { alerts { policiesSearch(searchCriteria: { ids: [A_POLICY_ID, ANOTHER_POLICY_ID] }) { policies { id name incidentPreference } } } } } } Find policy by id The API lets you query by policy id: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { policy(id: YOUR_POLICY_ID) { id name incidentPreference } } } } } Create a policy In order to create a policy, supply a name and an incidentPreference. The incident preference will configure how incidents get created for each condition created in the policy. For more information, refer to the documentation about choosing your incident preference. mutation { alertsPolicyCreate(accountId: YOUR_ACCOUNT_ID, policy: { name: \"Your Policy Name\" incidentPreference: PER_CONDITION }) { id name incidentPreference } } Update a policy When you update a policy, note that you don't need to supply all of the attributes on the policy. For example, you only need to supply the name if you only intend to update the name: mutation { alertsPolicyUpdate(accountId: YOUR_ACCOUNT_ID, id: YOUR_POLICY_ID, policy: { name: \"Updated Policy Name\" }) { id name incidentPreference } } Delete a policy You can delete policies via the NerdGraph API. Note that only the id may be requested back from a deleted resource: mutation { alertsPolicyDelete(accountId: YOUR_ACCOUNT_ID, id: YOUR_POLICY_ID) { id } } For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", - "type": "docs", - "document_type": "page", - "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / Alerts and Nerdgraph", - "info": "Read about how you can list, create, update, and delete policies using the NerdGraph API.", - "nodeid": 37716, - "sections": [ - "New Relic Alerts", - "Get started", - "Alert policies", - "Alert conditions", - "Alert violations", - "Alert Incidents", - "Alert notifications", - "Troubleshooting", - "Rules, limits, and glossary", - "Alerts and Nerdgraph", - "REST API alerts", - "NerdGraph API: Alerts policies", - "List and filter policies", - "Create a policy", - "Update a policy", - "Delete a policy", - "For more help" + "tags": [ + "nerdgraphquery component", + "transaction overview app", + "query account data", + "drop-down menu", + "NerdGraphQuery.query method" ], - "title": "NerdGraph API: Alerts policies ", - "popularity": 1, - "external_id": "cde6b52e96940389d03ae58acbfce482b5d455e6", - "category_1": "New Relic Alerts", - "image": "", - "url": "https://docs.newrelic.com/docs/alerts-applied-intelligence/new-relic-alerts/alerts-nerdgraph/nerdgraph-api-alerts-policies", - "published_at": "2020-08-18T18:15:13Z", - "updated_at": "2020-08-11T04:56:49Z", - "category_0": "Alerts and Applied intelligence", + "external_id": "6bd6c8a72eab352a3e8f4332570e286c7831ba84", + "image": "https://developer.newrelic.com/static/5dcf6e45874c1fa40bb6f21151af0c24/b01d9/no-name.png", + "url": "https://developer.newrelic.com/build-apps/add-nerdgraphquery-guide/", + "published_at": "2020-08-19T01:48:31Z", + "updated_at": "2020-08-19T01:48:30Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.2629376, + "_score": 1.2568725, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "NerdGraph API: Alerts policies ", - "sections": "Alerts and Nerdgraph", - "info": "Read about how you can list, create, update, and delete policies using the NerdGraph API.", - "body": "You can manage your alerts policies using our GraphQL NerdGraph API. Here are some queries and mutations you can develop in our NerdGraph API explorer. See the NerdGraph introduction for help getting started with NerdGraph API explorer. List and filter policies The policiesSearch query allows you", - "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / Alerts and Nerdgraph" + "title": "Add the NerdGraphQuery component to an application", + "sections": "Add the NerdGraphQuery component to an application", + "info": "The NerdGraphQuery component allows you to query data from your account and add it to a dropdown menu in an application", + "tags": "transaction overview app", + "body": " { PlatformStateContext, NerdGraphQuery, Spinner, HeadingText, Grid, GridItem, Stack, StackItem, Select, SelectItem, AreaChart, TableChart, PieChart } from 'nr1' import { timeRangeToNrql } from '@newrelic/nr1-community'; // https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction" }, - "id": "5f2dee1128ccbc65b688dfc1" + "id": "5efa993c64441ff4865f7e32" }, { - "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations, and fetch New Relic or third-party data. Components of the SDK SDK components are located in the Node module package named nr1, which you get when you install the NR1 CLI. The nr1 components can be divided into several categories: UI components Chart components Query and storage components Platform APIs UI components The UI components category of the SDK contains React UI components, including: Text components: These components provide basic font and heading elements. These include HeadingText and BlockText. Layout components: These components give you control over the layout, and help you build complex layout designs without having to deal with the CSS. Layout components include: Grid and GridItem: for organizing more complex, larger scale page content in rows and columns Stack and StackItem: for organizing simpler, smaller scale page content (in column or row) Tabs and TabsItem: group various related pieces of content into separate hideable sections List and ListItem: for providing a basic skeleton of virtualized lists Card, CardHeader and CardBody : used to group similar concepts and tasks together Form components: These components provide the basic building blocks to interact with the UI. These include Button, TextField, Dropdown and DropdownItem, Checkbox, RadioGroup, Radio, and Checkbox. Feedback components: These components are used to provide feedback to users about actions they have taken. These include: Spinnerand Toast. Overlaid components: These components are used to display contextual information and options in the form of an additional child view that appears above other content on screen when an action or event is triggered. They can either require user interaction (like modals), or be augmenting (like a tooltip). These include: Modal and Tooltip. Components suffixed with Item can only operate as direct children of that name without the suffix. For example: GridItem should only be found as a child of Grid. Chart components The Charts category of the SDK contains components representing different types of charts. The ChartGroup component helps a group of related charts share data and be aligned. Some chart components can perform NRQL queries on their own; some accept a customized set of data. Query and storage components The Query components category contains components for fetching and storing New Relic data. The main way to fetch data is with NerdGraph, our GraphQL endpoint. This can be queried using NerdGraphQuery. To simplify use of NerdGraph queries, we provide some components with pre-defined queries. For more on using NerdGraph, see Queries and mutations. We also provide storage for storing small data sets, such as configuration settings data, or user-specific data. For more on this, see NerdStorage. Platform APIs The Platform API components of the SDK enable your application to interact with different parts of the New Relic One platform, by reading and writing state from and to the URL, setting the configuration, etc. They can be divided into these categories: PlatformStateContext: provides read access to the platform URL state variables. Example: timeRange in the time picker. navigation: an object that allows programmatic manipulation of the navigation in New Relic One. Example: opening a new Nerdlet. NerdletStateContext: provides read access to the Nerdlet URL state variables. Example: an entityGuid in the entity explorer. nerdlet: an object that provides write access to the Nerdlet URL state.", + "body": "Add tables to your New Relic One application 30 min Tables are a popular way of displaying data in New Relic applications. For example, with the query builder you can create tables from NRQL queries. Whether you need to have more control over tables or you're importing third-party data, you can build your own tables into your New Relic One application. In this guide, you are going to build a sample table using various New Relic One components. Before you begin If you haven't already installed the New Relic One CLI, step through the quick start in New Relic One. This process also gets you an API key. In addition, to complete the steps in this guide, you need a GitHub account, and to have Node.js installed on your machine. See [Setting up your development environment](/build-apps/set-up-dev-env) for more info. Clone and set up the example application Step 1 of 4 Clone the nr1-how-to example application from GitHub to your local machine. Then, navigate to the app directory. The example app lets you experiment with tables. git clone https://github.com/newrelic/nr1-how-to.git` cd nr1-how-to/create-a-table/nerdlets/create-a-table-nerdlet` Copy Step 2 of 4 Edit the index.json file and set this.accountId to your Account ID as shown in the example. export default class Nr1HowtoAddTimePicker extends React.Component { constructor(props){ super(props) this.accountId = YOUR_ACCOUNT_ID; } ... } Copy Step 3 of 4 Run the demo application Change the directory back to nr1-how-to/create-a-table. Before you can load the demo application, you need to update its unique id by invoking the New Relic One CLI. Once you've assigned a new UUID to the app, install the dependencies and serve the demo app locally, so that you can test any change live in your browser. nr1 nerdpack:uuid -gf # Update the app unique ID npm install # Install dependencies nr1 nerdpack:serve # Serve the demo app locally Copy Step 4 of 4 Open one.newrelic.com/?nerdpacks=local in your browser. Click Apps*, and then in the Other apps section, you should see a Create a table** launcher. That's the demo application you're going to work on. Go ahead and select it. Have a good look at the demo app. There's a TableChart on the left side named Transaction Overview, with an AreaChart next to it. You'll use Table components to add a new table in the second row. Work with table components Step 1 of 10 Navigate to the `nerdlets/create-a-table-nerdlet` subdirectory and open the `index.js` file. Add the following components to the import statement at the top of the file so that it looks like the example: Table TableHeader TableHeaderCell TableRow TableRowCell import { Table, TableHeader, TableHeaderCell, TableRow, TableRowCell, PlatformStateContext, Grid, GridItem, HeadingText, AreaChart, TableChart, } from 'nr1'; Copy Step 2 of 10 Add a basic Table component Locate the empty GridItem in index.js: This is where you start building the table. Add the initial component. The items property collects the data by calling _getItems(), which contains sample values.
; Copy Step 3 of 10 Add the header and rows As the Table component renders a fixed number of header cells and rows, your next step is adding header components, as well as a function that returns the required table rows. Inside of the Table component, add the TableHeader and then a TableHeaderCell child for each heading. Since you don't know how many rows you'll need, your best bet is to call a function to build as many TableRows as items returned by _getItems(). Application Size Company Team Commit ; { ({ item }) => ( {item.name} {item.value} {item.company} {item.team} {item.commit} ); } Copy Step 4 of 10 Take a look at the application running in New Relic One: you should see something similar to the screenshot below. Step 5 of 10 Replace standard table cells with smart cells The New Relic One library includes cell components that can automatically format certain data types, like users, metrics, and entity names. The table you've just created contains columns that can benefit from those components: Application (an entity name) and Size (a metric). Before you can use EntityTitleTableRowCell and MetricTableRowCell, you have to add them to the import statement first. import { EntityTitleTableRowCell, MetricTableRowCell, ... /* All previous components */ } from 'nr1'; Copy Step 6 of 10 Update your table rows by replacing the first and second TableRowCells with entity and metric cells. Notice that EntityTitleTableRowCell and MetricTableRowCell are self-closing tags. { ({ item }) => ( {item.company} {item.team} {item.commit} ); } Copy Step 7 of 10 Time to give your table a second look: The cell components you've added take care of properly formatting the data. Step 8 of 10 Add some action to your table! Tables are great, but interactive tables can be better: As a last update, you are going to allow users to act on each data row. Add the _getActions() method to your index.js file, right before _getItems(). As you may have guessed from the code, _getActions() spawns an alert box when you click Team or Commit cells. _getActions() { return [ { label: 'Alert Team', iconType: TableRow.ACTIONS_ICON_TYPE.INTERFACE__OPERATIONS__ALERT, onClick: (evt, { item, index }) => { alert(`Alert Team: ${item.team}`); }, }, { label: 'Rollback Version', iconType: TableRow.ACTIONS_ICON_TYPE.INTERFACE__OPERATIONS__UNDO, onClick: (evt, { item, index }) => { alert(`Rollback from: ${item.commit}`); }, }, ]; } Copy Step 9 of 10 Find the TableRow component in your return statement and point the actions property to _getActions(). The TableRow actions property defines a set of actions that appear when the user hovers over a table row. Actions have a mandatory text and an onClick callback, but can also display an icon or be disabled if needed. Copy Step 10 of 10 Go back to your application and try hovering over any of the rows: Notice how the two available actions appear. When you click them, a function triggers with the selected row data as an argument, and an alert displays in your browser. Next steps You've built a table into a New Relic One application, using components to format data automatically and provide contextual actions. Well done! Keep exploring the Table components, their properties, and how to use them, in our SDK documentation.", "type": "developer", "document_type": "page", - "info": "Intro to New Relic One API components", + "info": "Add a table to your New Relic One app.", "sections": [ - "Intro to New Relic One API components", - "Components of the SDK", - "UI components", - "Chart components", - "Query and storage components", - "Platform APIs" + "Add tables to your New Relic One application", + "Before you begin", + "Clone and set up the example application", + "Work with table components", + "Next steps" ], - "title": "Intro to New Relic One API components", + "title": "Add tables to your New Relic One application", "popularity": 1, - "external_id": "3620920c26bcd66c59c810dccb1200931b23b8c2", - "image": "", - "url": "https://developer.newrelic.com/explore-docs/intro-to-sdk/", - "published_at": "2020-08-18T02:07:10Z", - "updated_at": "2020-08-14T01:47:12Z", + "tags": [ + "table in app", + "Table component", + "TableHeaderc omponent", + "TableHeaderCell component", + "TableRow component", + "TableRowCell component" + ], + "external_id": "7ff7a8426eb1758a08ec360835d9085fae829936", + "image": "https://developer.newrelic.com/static/e637c7eb75a9dc01740db8fecc4d85bf/1d6ec/table-new-cells.png", + "url": "https://developer.newrelic.com/build-apps/howto-use-nrone-table-components/", + "published_at": "2020-08-19T01:48:30Z", + "updated_at": "2020-08-14T01:46:10Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.22751394, + "_score": 1.2155066, "_version": null, "_explanation": null, "sort": null, "highlight": { - "sections": "Query and storage components", - "body": " is with NerdGraph, our GraphQL endpoint. This can be queried using NerdGraphQuery. To simplify use of NerdGraph queries, we provide some components with pre-defined queries. For more on using NerdGraph, see Queries and mutations. We also provide storage for storing small data sets, such as configuration" + "title": "Add tables to your New Relic One application", + "sections": "Add tables to your New Relic One application", + "info": "Add a table to your New Relic One app.", + "tags": "table in app", + "body": " and set this.accountId to your Account ID as shown in the example. export default class Nr1HowtoAddTimePicker extends React.Component { constructor(props){ super(props) this.accountId = YOUR_ACCOUNT_ID; } ... } Copy Step 3 of 4 Run the demo application Change the directory back to nr1-how-to/create" }, - "id": "5efa989e28ccbc4071307de5" - } - ], - "/build-apps/add-time-picker-guide": [ + "id": "5efa989ee7b9d2ad567bab51" + }, { "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build your own application launcher and follow the quick start instructions. The quick start automatically generates an API key for the account you select, and gives you the pre-populated commands to create a profile, generate your first \"Hello World\" app, and serve it locally. Tip Use the NR1 VS Code extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions. For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). Configure your CLI preferences nr1 config:set Sets a specific configuration value. nr1 config:get Shows a specific configuration. nr1 config:list Lists your configuration choices. nr1 config:delete Removes the value of a specific configuration. Set up your Nerdpacks nr1 nerdpack:clone Clones an open source Nerdpack from our GitHub repository. nr1 nerdpack:serve Serves your Nerdpack for testing and development purposes. nr1 nerdpack:uuid Shows or regenerates the UUID of a Nerdpack. nr1 nerdpack:publish Publishes your Nerdpack to New Relic. nr1 nerdpack:deploy Deploys a Nerdpack version to a specific channel. nr1 nerdpack:undeploy Undeploys a Nerdpack version from a specific channel. Manage your Nerdpack subscriptions nr1 subscription:set Subscribes your account to a Nerdpack and channel. nr1 subscription:list Lists all the Nerdpacks your account is subscribed to. nr1 subscription:unset Unsubscribes your account from a Nerdpack. Install and manage plugins nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin into the CLI for development. nr1 plugins:update Updates your installed plugins. nr1 plugins:uninstall Removes a plugin from the CLI. Manage catalog information nr1 catalog:info Shows the Nerdpack info stored in the catalog. nr1 catalog:submit Gathers and submits the catalog info on the current folder.", "type": "developer", @@ -1711,11 +1845,11 @@ "external_id": "858339a44ead21c83257778ce60b4c352cd30d3b", "image": "https://developer.newrelic.com/static/2c6d337608b38a3312b4fc740afe6167/7272b/developercenter.png", "url": "https://developer.newrelic.com/explore-docs/nr1-cli/", - "published_at": "2020-08-18T02:07:10Z", + "published_at": "2020-08-19T01:50:40Z", "updated_at": "2020-08-18T01:50:36Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.87591255, + "_score": 0.64661944, "_version": null, "_explanation": null, "sort": null, @@ -1727,892 +1861,826 @@ "id": "5efa989e28ccbc535a307dd0" }, { - "body": "PlatformStateContext Usage Copy Props There are no props for this component.", + "body": "Map page views by region in a custom app 30 min New Relic has powerful and flexible tools for building custom apps and populating them with data. This guide shows you how to build a custom app and populate it with page view data using New Relic's Query Language (NRQL - pronounced 'nurkle'). Then you make your data interactive. And last, if you have a little more time and want to install a third-party React library, you can display the page view data you collect on a map of the world. In this guide, you build an app to display page view data in two ways: In a table On a map Please review the Before you begin section to make sure you have everything you need and don't get stuck halfway through. Before you begin In order to get the most out of this guide, you must have: A New Relic developer account, API key, and the command-line tool. If you don't have these yet, see the steps in Setting up your development environment New Relic Browser page view data to populate the app. Without this data, you won't be able to complete this guide. To add your data to a world map in the second half of the guide: npm, which you'll use during this section of the guide to install Leaflet, a third-party JavaScript React library used to build interactive maps. If you're new to React and npm, you can go here to install Node.js and npm. New Relic terminology The following are some terms used in this guide: New Relic application: The finished product where data is rendered in New Relic One. This might look like a series of interactive charts or a map of the world. Nerdpack: New Relic's standard collection of JavaScript, JSON, CSS, and other files that control the functionality and look of your application. For more information, see Nerdpack file structure. Launcher: The button on New Relic One that launches your application. Nerdlets: New Relic React components used to build your application. The three default files are index.js, nr1.json, and styles.scss, but you can customize and add your own. Build a custom app with a table chart Step 1 of 8 Query your browser data Use Query builder to write a NRQL query to see your page view data, as follows. On New Relic One, select Query your data (in the top right corner). That puts you in NRQL mode. You'll use NRQL to test your query before dropping the data into your table. Copy and paste this query into a clear query field, and then select Run. FROM PageView SELECT count(*), average(duration) WHERE appName = 'WebPortal' FACET countryCode, regionCode SINCE 1 week ago LIMIT 1000 Copy If you have PageView data, this query shows a week of average page views broken down by country and limited to a thousand items. The table will be full width and use the \"chart\" class defined in the CSS. If you don't have any results at this point, ensure your query doesn't have any errors. If your query is correct, you might not have the Browser agent installed. Step 2 of 8 Create and serve a new Nerdpack To get started, create a new Nerdpack, and serve it up to New Relic from your local development environment: Create a new Nerdpack for this app: nr1 create --type nerdpack --name pageviews-app Copy Serve the project up to New Relic: cd pageviews-app && nr1 nerdpack:serve Copy Step 3 of 8 Review your app files and view your app locally Navigate to your pageviews-app to see how it's structured. It contains a launcher folder, where you can customize the description and icon that will be displayed on the app's launcher in New Relic One. It also contains nerdlets, which each contain three default files: index.js, nr1.json, and styles.scss. You'll edit some of these files as part of this guide. For more information, see Nerdpack file structure. Now in your browser, open https://one.newrelic.com/?nerdpacks=local, and then click Apps to see the pageview-apps Nerdpack that you served up. When you select the launcher, you see a Hello message. Step 4 of 8 Hard code your account ID For the purposes of this exercise and for your convenience, hard code your account ID. In the pageview-app-nerdlet directory, in the index.js file, add this code between the import and export lines. (Read about finding your account ID here). const accountId = [Replace with your account ID]; Copy Step 5 of 8 Import the TableChart component To show your data in a table chart, import the TableChart component from New Relic One. To do so, in index.js, add this code under import React. import { TableChart } from `nr1`; Copy Step 6 of 8 Add a table with a single row To add a table with a single row, in the index.js file, replace this line: return

Hello, pageview-app-nerdlet Nerdlet!

; Copy with this export code: export default class PageViewApp extends React.Component { render() { return (
); } } Copy Step 7 of 8 Customize the look of your table (optional) You can use standard CSS to customize the look of your components. In the styles.scss file, add this CSS. Feel free to customize this CSS to your taste. .container { width: 100%; height: 99vh; display: flex; flex-direction: column; .row { margin: 10px; display: flex; flex-direction: row; } .chart { height: 250px; } } Copy Step 8 of 8 Get your data into that table Now that you've got a table, you can drop a TableChart populated with data from the NRQL query you wrote at the very beginning of this guide. Put this code into the row div. ; Copy Go to New Relic One and click your app to see your data in the table. (You might need to serve your app to New Relic again.) Congratulations! You made your app! Continue on to make it interactive and show your data on a map. Make your app interactive with a text field Once you confirm that data is getting to New Relic from your app, you can start customizing it and making it interactive. To do this, you add a text field to filter your data. Later, you use a third-party library called Leaflet to show that data on a world map. Step 1 of 3 Import the TextField component Like you did with the TableChart component, you need to import a TextField component from New Relic One. import { TextField } from 'nr1'; Copy Step 2 of 3 Add a row for your text field To add a text field filter above the table, put this code above the TableChart div. The text field will have a default value of \"US\".
{ this.setState({ countryCode: event.target.value }); }} />
; Copy Step 3 of 3 Build the text field object Above the render() function, add a constructor to build the text field object. constructor(props) { super(props); this.state = { countryCode: null } } Copy Then, add a constructor to your render() function. Above return, add: const { countryCode } = this.state; Copy Now add countryCode to your table chart query. ; Copy Reload your app to try out the text field. Get your data on a map To create the map, you use npm to install Leaflet. Step 1 of 9 Install Leaflet In your terminal, type: npm install --save leaflet react-leaflet Copy In your nerdlets styles.scss file, import the Leaflet CSS: @import `~leaflet/dist/leaflet.css`; Copy While you're in styles.scss, fix the width and height of your map: .containerMap { width: 100%; z-index: 0; height: 70vh; } Copy Step 2 of 9 Add a webpack config file for Leaflet Add a webpack configuration file .extended-webpackrc.js to the top-level folder in your nerdpack. This supports your use of map tiling information data from Leaflet. module.exports = { module: { rules: [ { test: /\\.(png|jpe?g|gif)$/, use: [ { loader: 'file-loader', options: {}, }, { loader: 'url-loader', options: { limit: 25000 }, }, ], }, ], }, }; Copy Step 3 of 9 Import modules from Leaflet In index.js, import modules from Leaflet. import { Map, CircleMarker, TileLayer } from 'react-leaflet'; Copy Step 4 of 9 Import additional modules from New Relic One You need several more modules from New Relic One to make the Leaflet map work well. Import them with this code: import { NerdGraphQuery, Spinner, Button, BlockText } from 'nr1'; Copy NerdGraphQuery lets you make multiple NRQL queries at once and is what will populate the map with data. Spinner adds a loading spinner. Button gives you button components. BlockText give you block text components. Step 5 of 9 Get data for the map Using latitude and longitude with country codes, you can put New Relic data on a map. mapData() { const { countryCode } = this.state; const query = `{ actor { account(id: 1606862) { mapData: nrql(query: \"SELECT count(*) as x, average(duration) as y, sum(asnLatitude)/count(*) as lat, sum(asnLongitude)/count(*) as lng FROM PageView FACET regionCode, countryCode WHERE appName = 'WebPortal' ${countryCode ? ` WHERE countryCode like '%${countryCode}%' ` : ''} LIMIT 1000 \") { results nrql } } } }`; return query; }; Copy Step 6 of 9 Customize the map marker colors Above the mapData function, add this code to customize the map marker colors. getMarkerColor(measure, apdexTarget = 1.7) { if (measure <= apdexTarget) { return '#11A600'; } else if (measure >= apdexTarget && measure <= apdexTarget * 4) { return '#FFD966'; } else { return '#BF0016'; } }; Copy Feel free to change the HTML color code values to your taste. In this example, #11A600 is green, #FFD966 is sort of yellow, and #BF0016 is red. Step 7 of 9 Set your map's default center point Set a default center point for your map using latitude and longitude. const defaultMapCenter = [10.5731, -7.5898]; Copy Step 8 of 9 Add a row for your map Between the text field row and the table chart row, insert a new row for the map content using NerdGraphQuery.
{({ loading, error, data }) => { if (loading) { return ; } if (error) { return 'Error'; } const { results } = data.actor.account.mapData; console.debug(results); return 'Hello'; }}
; Copy Reload your application in New Relic One to test that it works. Step 9 of 9 Replace \"Hello\" with the Leaflet code Replace return \"Hello\"; with: return ( {results.map((pt, i) => { const center = [pt.lat, pt.lng]; return ( { alert(JSON.stringify(pt)); }} /> ); })} ); Copy This code creates a world map centered on the latitude and longitude you chose using OpenStreetMap data and your marker colors. Reload your app to see the pageview data on the map!", "type": "developer", "document_type": "page", - "info": "A PlatformStateContext component!", + "info": "Build a New Relic app showing page view data on a world map.", "sections": [ - "PlatformStateContext", - "Usage", - "Props" + "Map page views by region in a custom app", + "Before you begin", + "New Relic terminology", + "Build a custom app with a table chart", + "Query your browser data", + "Create and serve a new Nerdpack", + "Review your app files and view your app locally", + "Hard code your account ID", + "Import the TableChart component", + "Add a table with a single row", + "Customize the look of your table (optional)", + "Get your data into that table", + "Make your app interactive with a text field", + "Import the TextField component", + "Add a row for your text field", + "Build the text field object", + "Get your data on a map", + "Install Leaflet", + "Add a webpack config file for Leaflet", + "Import modules from Leaflet", + "Import additional modules from New Relic One", + "Get data for the map", + "Customize the map marker colors", + "Set your map's default center point", + "Add a row for your map", + "Replace \"Hello\" with the Leaflet code" ], - "title": "PlatformStateContext", + "title": "Map page views by region in a custom app", "popularity": 1, - "external_id": "aa6b86b3dc0dcd7cd758b20655318b108875cce7", - "image": "", - "url": "https://developer.newrelic.com/components/platform-state-context/", - "published_at": "2020-08-18T02:04:52Z", - "updated_at": "2020-08-01T01:47:08Z", - "_index": "520d1d5d14cc8a32e600034b", - "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.3045187, - "_version": null, - "_explanation": null, - "sort": null, - "highlight": { - "title": "PlatformStateContext", - "sections": "PlatformStateContext", - "info": "A PlatformStateContext component!", - "body": "PlatformStateContext Usage Copy Props There are no props for this component." - }, - "id": "5efa997128ccbccc6f307dc0" - }, - { - "body": "Build apps You know better than anyone what information is crucial to your business, and how best to visualize it. Sometimes, this means going beyond dashboards to creating your own app. With React and GraphQL, you can create custom views tailored to your business. These guides are designed to help you start building apps, and dive into our library of components. We also have a growing number of open source apps that you can use to get started. The rest is up to you. Guides to build apps 15 min Create a \"Hello, World!\" application Build a \"Hello, World!\" app and publish it to New Relic One 20 min Publish and deploy apps Start sharing the apps you build 20 min Set up your development environment Prepare to build apps and contribute to this site 20 minutes Add the NerdGraphQuery component to an application The NerdGraphQuery component allows you to query data from your account and add it to a dropdown menu in an application 20 min Add a time picker to your app Add a time picker to a sample application 45 min Add, query, and mutate data using NerdStorage NerdStorage is a document database accessible within New Relic One. It allows you to modify, save, and retrieve documents from one session to the next. 30 min Add a table to your app Add a table to your New Relic One app 30 min Create a custom map view Build an app to show page view data on a map", - "type": "developer", - "document_type": "page", - "info": "", - "sections": [ - "Build apps", - "Guides to build apps", - "Create a \"Hello, World!\" application", - "Publish and deploy apps", - "Set up your development environment", - "Add the NerdGraphQuery component to an application", - "Add a time picker to your app", - "Add, query, and mutate data using NerdStorage", - "Add a table to your app", - "Create a custom map view" + "tags": [ + "custom app", + "map", + "page views", + "region", + "nerdpack" ], - "title": "Build apps", - "popularity": 1, - "external_id": "abafbb8457d02084a1ca06f3bc68f7ca823edf1d", - "image": "", - "url": "https://developer.newrelic.com/build-apps/", - "published_at": "2020-08-18T02:08:12Z", - "updated_at": "2020-08-18T01:45:02Z", + "external_id": "6ff5d696556512bb8d8b33fb31732f22bab455cb", + "image": "https://developer.newrelic.com/static/d87a72e8ee14c52fdfcb91895567d268/0086b/pageview.png", + "url": "https://developer.newrelic.com/build-apps/map-pageviews-by-region/", + "published_at": "2020-08-19T01:48:30Z", + "updated_at": "2020-08-14T01:45:09Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.23860641, + "_score": 0.52191806, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Build apps", - "sections": "Add a time picker to your app", - "body": " it to a dropdown menu in an application 20 min Add a time picker to your app Add a time picker to a sample application 45 min Add, query, and mutate data using NerdStorage NerdStorage is a document database accessible within New Relic One. It allows you to modify, save, and retrieve documents from one" + "title": "Map page views by region in a custom app", + "sections": "Map page views by region in a custom app", + "info": "Build a New Relic app showing page view data on a world map.", + "tags": "custom app", + "body": "'). Then you make your data interactive. And last, if you have a little more time and want to install a third-party React library, you can display the page view data you collect on a map of the world. In this guide, you build an app to display page view data in two ways: In a table On a map Please review" }, - "id": "5efa999d64441fc0f75f7e21" - }, + "id": "5efa993c196a67066b766469" + } + ], + "/collect-data/custom-events": [ { - "body": "Add tables to your New Relic One application 30 min Tables are a popular way of displaying data in New Relic applications. For example, with the query builder you can create tables from NRQL queries. Whether you need to have more control over tables or you're importing third-party data, you can build your own tables into your New Relic One application. In this guide, you are going to build a sample table using various New Relic One components. Before you begin If you haven't already installed the New Relic One CLI, step through the quick start in New Relic One. This process also gets you an API key. In addition, to complete the steps in this guide, you need a GitHub account, and to have Node.js installed on your machine. See [Setting up your development environment](/build-apps/set-up-dev-env) for more info. Clone and set up the example application Step 1 of 4 Clone the nr1-how-to example application from GitHub to your local machine. Then, navigate to the app directory. The example app lets you experiment with tables. git clone https://github.com/newrelic/nr1-how-to.git` cd nr1-how-to/create-a-table/nerdlets/create-a-table-nerdlet` Copy Step 2 of 4 Edit the index.json file and set this.accountId to your Account ID as shown in the example. export default class Nr1HowtoAddTimePicker extends React.Component { constructor(props){ super(props) this.accountId = YOUR_ACCOUNT_ID; } ... } Copy Step 3 of 4 Run the demo application Change the directory back to nr1-how-to/create-a-table. Before you can load the demo application, you need to update its unique id by invoking the New Relic One CLI. Once you've assigned a new UUID to the app, install the dependencies and serve the demo app locally, so that you can test any change live in your browser. nr1 nerdpack:uuid -gf # Update the app unique ID npm install # Install dependencies nr1 nerdpack:serve # Serve the demo app locally Copy Step 4 of 4 Open one.newrelic.com/?nerdpacks=local in your browser. Click Apps*, and then in the Other apps section, you should see a Create a table** launcher. That's the demo application you're going to work on. Go ahead and select it. Have a good look at the demo app. There's a TableChart on the left side named Transaction Overview, with an AreaChart next to it. You'll use Table components to add a new table in the second row. Work with table components Step 1 of 10 Navigate to the `nerdlets/create-a-table-nerdlet` subdirectory and open the `index.js` file. Add the following components to the import statement at the top of the file so that it looks like the example: Table TableHeader TableHeaderCell TableRow TableRowCell import { Table, TableHeader, TableHeaderCell, TableRow, TableRowCell, PlatformStateContext, Grid, GridItem, HeadingText, AreaChart, TableChart, } from 'nr1'; Copy Step 2 of 10 Add a basic Table component Locate the empty GridItem in index.js: This is where you start building the table. Add the initial component. The items property collects the data by calling _getItems(), which contains sample values.
; Copy Step 3 of 10 Add the header and rows As the Table component renders a fixed number of header cells and rows, your next step is adding header components, as well as a function that returns the required table rows. Inside of the Table component, add the TableHeader and then a TableHeaderCell child for each heading. Since you don't know how many rows you'll need, your best bet is to call a function to build as many TableRows as items returned by _getItems(). Application Size Company Team Commit ; { ({ item }) => ( {item.name} {item.value} {item.company} {item.team} {item.commit} ); } Copy Step 4 of 10 Take a look at the application running in New Relic One: you should see something similar to the screenshot below. Step 5 of 10 Replace standard table cells with smart cells The New Relic One library includes cell components that can automatically format certain data types, like users, metrics, and entity names. The table you've just created contains columns that can benefit from those components: Application (an entity name) and Size (a metric). Before you can use EntityTitleTableRowCell and MetricTableRowCell, you have to add them to the import statement first. import { EntityTitleTableRowCell, MetricTableRowCell, ... /* All previous components */ } from 'nr1'; Copy Step 6 of 10 Update your table rows by replacing the first and second TableRowCells with entity and metric cells. Notice that EntityTitleTableRowCell and MetricTableRowCell are self-closing tags. { ({ item }) => ( {item.company} {item.team} {item.commit} ); } Copy Step 7 of 10 Time to give your table a second look: The cell components you've added take care of properly formatting the data. Step 8 of 10 Add some action to your table! Tables are great, but interactive tables can be better: As a last update, you are going to allow users to act on each data row. Add the _getActions() method to your index.js file, right before _getItems(). As you may have guessed from the code, _getActions() spawns an alert box when you click Team or Commit cells. _getActions() { return [ { label: 'Alert Team', iconType: TableRow.ACTIONS_ICON_TYPE.INTERFACE__OPERATIONS__ALERT, onClick: (evt, { item, index }) => { alert(`Alert Team: ${item.team}`); }, }, { label: 'Rollback Version', iconType: TableRow.ACTIONS_ICON_TYPE.INTERFACE__OPERATIONS__UNDO, onClick: (evt, { item, index }) => { alert(`Rollback from: ${item.commit}`); }, }, ]; } Copy Step 9 of 10 Find the TableRow component in your return statement and point the actions property to _getActions(). The TableRow actions property defines a set of actions that appear when the user hovers over a table row. Actions have a mandatory text and an onClick callback, but can also display an icon or be disabled if needed. Copy Step 10 of 10 Go back to your application and try hovering over any of the rows: Notice how the two available actions appear. When you click them, a function triggers with the selected row data as an argument, and an alert displays in your browser. Next steps You've built a table into a New Relic One application, using components to format data automatically and provide contextual actions. Well done! Keep exploring the Table components, their properties, and how to use them, in our SDK documentation.", + "body": "Collect data from any source 15 min New Relic products report a lot of data “out of the box.” When you use products like APM, Browser, Mobile, Infrastructure monitoring, or an integration, by default you receive performance data. But you may want to bring data into New Relic that isn't collected by default. Maybe you want an API-based solution that doesn't require install of an agent. Maybe you want to bring telemetry data from another analysis service into New Relic. This page describes several ways to get data into New Relic. Step 1 of 6 Agent APIs If you use our APM, Browser, or Mobile agents to report data, you can use their associated APIs to report custom data. For example, if you monitor your application with the our APM Python agent, you can use the Python agent API to set up custom instrumentation. See the agent APIs. Step 2 of 6 Telemetry SDK Our Telemetry SDKs are language wrappers for our Trace API and Metric API (and eventually our Log API and Event API). These SDKs let you easily send metrics and trace data to New Relic without needing to install an agent. For customers, we offer open-source exporters and integrations that use the Telemetry SDKs to send metrics and trace data: Istio adaptor Prometheus OpenMetrics (for Docker | for Kubernetes) OpenCensus exporter (for Go | for Python) DropWizard exporter Micrometer exporter Want to build your own solution? See our Telemetry SDK docs. Step 3 of 6 Trace API Our Trace API lets you send distributed tracing data to New Relic and consolidate tracing data from multiple sources in one place. We accept trace data in two formats: Zipkin format New Relic format (if you don’t have Zipkin-format data, you’d use this) 1 curl -i -X POST https://trace-api.newrelic.com/trace/v1 \\ 2 -H \"Content-Type: application/json\" \\ 3 -H \"Api-Key: $INSIGHTS_INSERT_API_KEY\" \\ 4 -H 'Data-Format: newrelic' \\ 5 -H 'Data-Format-Version: 1' \\ 6 -d '[ 7 { 8 \"common\": { 9 \"attributes\": { 10 \"service.name\": \"Test Service A\", 11 \"host\": \"host123.test.com\" 12 } 13 }, 14 \"spans\": [ 15 { 16 \"trace.id\": \"123456\", 17 \"id\": \"ABC\", 18 \"attributes\": { 19 \"duration.ms\": 12.53, 20 \"name\": \"/home\" 21 } 22 }, 23 { 24 \"trace.id\": \"123456\", 25 \"id\": \"DEF\", 26 \"attributes\": { 27 \"service.name\": \"Test Service A\", 28 \"host\": \"host456.test.com\", 29 \"duration.ms\": 2.97, 30 \"name\": \"/auth\", 31 \"parent.id\": \"ABC\" 32 } 33 } 34 ] 35 } 36 ]' Copy Step 4 of 6 Metric API You can use our Metric API to send metric data to New Relic from any source. 1 curl -i -X POST https://metric-api.newrelic.com/metric/v1 \\ 2 -H \"Content-Type: application/json\" \\ 3 -H \"Api-Key: $INSIGHTS_INSERT_API_KEY\" \\ 4 -d '[ 5 { 6 \"metrics\": [ 7 { 8 \"name\": \"memory.heap\", 9 \"type\": \"gauge\", 10 \"value\": 2.3, 11 \"timestamp\": 1531414060739, 12 \"attributes\": { 13 \"host.name\": \"dev.server.com\" 14 } 15 } 16 ] 17 } 18 ]' Copy Step 5 of 6 Event API For sending arbitrary events to New Relic, you can use our Event API. We save these events as a new event type, which can then be queried via NRQL. (Eventually, the Telemetry SDKs will support the Event API.) 1 curl -i -X POST https://insights-collector.newrelic.com/v1/accounts/$ACCOUNT_ID/events \\ 2 -H \"Content-Type: application/json\" \\ 3 -H \"x-insert-key: $INSIGHTS_INSERT_API_KEY\" \\ 4 -d '[ 5 { 6 \"eventType\": \"LoginEvent\", 7 \"service\": \"login-service\", 8 \"customerId\": \"xyz\" 9 } 10 ]' Copy Step 6 of 6 Log API If our existing logging integrations don’t meet your needs, you can use our Log API to send any arbitrary log data to New Relic. (Eventually, the Telemetry SDKs will support the Log API.) 1 curl -i -X POST https://log-api.newrelic.com/log/v1 \\ 2 -H \"Content-Type: application/json\" \\ 3 -H \"Api-Key: $INSIGHTS_INSERT_API_KEY\" \\ 4 -d '[ 5 \"logs\": [ 6 { 7 \"timestamp\": 1593538496000, 8 \"message\": \"User xyz logged in\", 9 \"service\": \"login-service\", 10 \"hostname\": \"login.example.com\" 11 } 12 ] 13 ]' Copy", "type": "developer", "document_type": "page", - "info": "Add a table to your New Relic One app.", + "info": "Open source emitters. APIs. New Relic agents. Get data from anywhere. ", "sections": [ - "Add tables to your New Relic One application", - "Before you begin", - "Clone and set up the example application", - "Work with table components", - "Next steps" + "Collect data from any source", + "Agent APIs", + "Telemetry SDK", + "Trace API", + "Metric API", + "Event API", + "Log API" ], - "title": "Add tables to your New Relic One application", + "title": "Collect data from any source", "popularity": 1, - "external_id": "7ff7a8426eb1758a08ec360835d9085fae829936", - "image": "https://developer.newrelic.com/static/e637c7eb75a9dc01740db8fecc4d85bf/1d6ec/table-new-cells.png", - "url": "https://developer.newrelic.com/build-apps/howto-use-nrone-table-components/", - "published_at": "2020-08-18T02:07:10Z", - "updated_at": "2020-08-14T01:46:10Z", + "tags": [ + "Agent API", + "Telemetry SDK", + "Trace API", + "Metric API", + "Event API" + ], + "external_id": "5bfb043fffe42ea4a78d5a90bf8e92aa8b8f8c33", + "image": "", + "url": "https://developer.newrelic.com/collect-data/collect-data-from-any-source/", + "published_at": "2020-08-19T01:44:48Z", + "updated_at": "2020-08-14T01:45:09Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.20037782, + "_score": 7.9432926, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Add tables to your New Relic One application", - "sections": "Add tables to your New Relic One application", - "info": "Add a table to your New Relic One app.", - "body": " and set this.accountId to your Account ID as shown in the example. export default class Nr1HowtoAddTimePicker extends React.Component { constructor(props){ super(props) this.accountId = YOUR_ACCOUNT_ID; } ... } Copy Step 3 of 4 Run the demo application Change the directory back to nr1-how-to/create" + "sections": "Agent APIs", + "info": "Open source emitters. APIs. New Relic agents. Get data from anywhere. ", + "tags": "Agent API", + "body": " agents to report data, you can use their associated APIs to report custom data. For example, if you monitor your application with the our APM Python agent, you can use the Python agent API to set up custom instrumentation. See the agent APIs. Step 2 of 6 Telemetry SDK Our Telemetry SDKs are language" }, - "id": "5efa989ee7b9d2ad567bab51" + "id": "5efa997128ccbc3c9a307dfd" }, { - "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations, and fetch New Relic or third-party data. Components of the SDK SDK components are located in the Node module package named nr1, which you get when you install the NR1 CLI. The nr1 components can be divided into several categories: UI components Chart components Query and storage components Platform APIs UI components The UI components category of the SDK contains React UI components, including: Text components: These components provide basic font and heading elements. These include HeadingText and BlockText. Layout components: These components give you control over the layout, and help you build complex layout designs without having to deal with the CSS. Layout components include: Grid and GridItem: for organizing more complex, larger scale page content in rows and columns Stack and StackItem: for organizing simpler, smaller scale page content (in column or row) Tabs and TabsItem: group various related pieces of content into separate hideable sections List and ListItem: for providing a basic skeleton of virtualized lists Card, CardHeader and CardBody : used to group similar concepts and tasks together Form components: These components provide the basic building blocks to interact with the UI. These include Button, TextField, Dropdown and DropdownItem, Checkbox, RadioGroup, Radio, and Checkbox. Feedback components: These components are used to provide feedback to users about actions they have taken. These include: Spinnerand Toast. Overlaid components: These components are used to display contextual information and options in the form of an additional child view that appears above other content on screen when an action or event is triggered. They can either require user interaction (like modals), or be augmenting (like a tooltip). These include: Modal and Tooltip. Components suffixed with Item can only operate as direct children of that name without the suffix. For example: GridItem should only be found as a child of Grid. Chart components The Charts category of the SDK contains components representing different types of charts. The ChartGroup component helps a group of related charts share data and be aligned. Some chart components can perform NRQL queries on their own; some accept a customized set of data. Query and storage components The Query components category contains components for fetching and storing New Relic data. The main way to fetch data is with NerdGraph, our GraphQL endpoint. This can be queried using NerdGraphQuery. To simplify use of NerdGraph queries, we provide some components with pre-defined queries. For more on using NerdGraph, see Queries and mutations. We also provide storage for storing small data sets, such as configuration settings data, or user-specific data. For more on this, see NerdStorage. Platform APIs The Platform API components of the SDK enable your application to interact with different parts of the New Relic One platform, by reading and writing state from and to the URL, setting the configuration, etc. They can be divided into these categories: PlatformStateContext: provides read access to the platform URL state variables. Example: timeRange in the time picker. navigation: an object that allows programmatic manipulation of the navigation in New Relic One. Example: opening a new Nerdlet. NerdletStateContext: provides read access to the Nerdlet URL state variables. Example: an entityGuid in the entity explorer. nerdlet: an object that provides write access to the Nerdlet URL state.", - "type": "developer", + "body": "New Relic products report a variety of default event data to your account. This document will explain how to report your own custom events and attributes. Overview of reporting custom events and attributes Event data is one of the fundamental New Relic data types. Events are reported by most New Relic products, and we give you several options for reporting your own custom events. Reporting custom events allows you to create more useful and customized queries and charts of your data, and is a key part of optimizing how New Relic works for you. Before beginning, it's important to know that reporting a large number of custom events and/or attributes can cause degraded query performance, or cause you to approach or pass data collection rate limits. For optimal performance, first think about what data you want to analyze, and then create only the events and/or attributes necessary to meet these specific goals. Be aware of the following data and subscription requirements for inserting and accessing custom data: Ensure you follow limits and requirements around event/attribute data types, naming syntax, and size. The amount of data you have access to over time depends on your data retention policy. Send custom events and attributes Methods for sending custom events and attributes include: Source How to send custom data APM agent Use APM agent APIs to report custom events and custom attributes. Browser agent Add custom attributes to the PageView event via the Browser API call addCustomAttribute. Send PageAction event and attributes via Browser API. Forward APM agent custom attributes to PageView event. Event API To report custom events not associated with other New Relic products, use the Event API. Infrastructure Add custom attributes to default Infrastructure events. Use the Flex integration tool to report your own custom event data. Mobile agent Use the mobile agent API to send custom events and attributes. Synthetics Add custom attributes to the SyntheticCheck event via the $util.insights tools. For ways to report other types of custom data, see: Metric API Logs Trace API Extend data retention To learn about how to extend how long events are retained in your account, see Event data retention. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "type": "docs", "document_type": "page", - "info": "Intro to New Relic One API components", + "breadcrumb": "Contents / Insights / Event data sources / Custom events", + "info": "An overview of the options for sending custom event data to New Relic. ", + "nodeid": 13806, "sections": [ - "Intro to New Relic One API components", - "Components of the SDK", - "UI components", - "Chart components", - "Query and storage components", - "Platform APIs" + "Event data sources", + "Default events", + "Custom events", + "Report custom event data", + "Overview of reporting custom events and attributes", + "Send custom events and attributes", + "Extend data retention", + "For more help" ], - "title": "Intro to New Relic One API components", + "title": "Report custom event data", "popularity": 1, - "external_id": "3620920c26bcd66c59c810dccb1200931b23b8c2", + "external_id": "afb5f5a81ae06b22935d98c470ed9cabd7c9da6b", + "category_1": "Event data sources", + "category_2": "Custom events", "image": "", - "url": "https://developer.newrelic.com/explore-docs/intro-to-sdk/", - "published_at": "2020-08-18T02:07:10Z", - "updated_at": "2020-08-14T01:47:12Z", + "url": "https://docs.newrelic.com/docs/insights/insights-data-sources/custom-data/report-custom-event-data", + "published_at": "2020-08-18T07:15:53Z", + "updated_at": "2020-07-26T05:52:23Z", + "category_0": "Insights", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.19302298, + "_score": 0.5264102, "_version": null, "_explanation": null, "sort": null, "highlight": { - "body": ". They can be divided into these categories: PlatformStateContext: provides read access to the platform URL state variables. Example: timeRange in the time picker. navigation: an object that allows programmatic manipulation of the navigation in New Relic One. Example: opening a new Nerdlet" + "title": "Report custom event data", + "sections": "Custom events", + "info": "An overview of the options for sending custom event data to New Relic. ", + "category_1": "Event data sources", + "category_2": "Custom events", + "body": " retention policy. Send custom events and attributes Methods for sending custom events and attributes include: Source How to send custom data APM agent Use APM agent APIs to report custom events and custom attributes. Browser agent Add custom attributes to the PageView event via the Browser API call", + "breadcrumb": "Contents / Insights / Event data sources / Custom events" }, - "id": "5efa989e28ccbc4071307de5" - } - ], - "/terms": [ + "id": "5e8e7f9de7b9d2aa122cf0f6" + }, { - "body": "The REST API endpoints allow you to create conditions for your policies. This glossary contains the names and descriptions of each of the fields that you can use to define or update a condition. Required and optional fields The API includes four types of New Relic Alerts conditions: APM External services Synthetic monitoring Plugins All of the fields used with a specific condition type are required except for these optional fields: enabled (defaults to false) runbook_url user_defined Field definitions Not every field listed in this glossary is required for every condition type. The condition type for which a field must be used is listed in each description. condition_scope This field allows you to scope a condition to either a JVM instance or to a whole application. This may be one of the strings: instance application Used for: Conditions Entity conditions For instance-based and JVM health metrics, see also violation_close_timer. enabled This is the status of your alert condition and is optional. The default is false. This field may be used to enable or disable a condition for maintenance or testing periods. Used for: Conditions External service conditions Synthetic monitoring conditions Plugin conditions entities This is an array of entity IDs identifying the objects which will be monitored with your condition. These may be application IDs, browser IDs, plugin IDs, key transaction IDs, external service IDs, etc. These are entered as a series of comma separated integers if there is more than one. Used for: Conditions External service conditions Plugin conditions expected_groups This is the number of groups you expect to see at any given time. It is used in combination with the ignore_overlap option. Used for: NRQL outlier conditions external_service_url This is the URL of the external service to be monitored. This string must not include the protocol. For example, use example.com, not https://example.com. Used for: External service conditions ignore_overlap If disabled, this looks for a convergence (or overlapping) of groups. If the condition is looking for two or more groups, and the returned values can't be separated into that number of distinct groups, then that will also produce a violation. This type of overlap event is represented on a chart by group bands touching. Used for: NRQL outlier conditions metric The metric field is used for three alert categories. The exact parameters available for use depend on the setting in the type field. These are listed below according to their alert type field. Alerts plugin conditions For Plugin conditions this is the metric, which has been defined in a plugin, that will be used to trigger a notification. Alerts conditions The value specified in the type field controls which of the parameters may be specified. The type field and corresponding available parameter names are listed in the following table. Only one may be specified. type Parameter apm_app_metric apdex error_percentage response_time_web response_time_background throughput_web throughput_background user_defined apm_kt_metric apdex error_percentage error_count response_time throughput browser_metric end_user_apdex total_page_load page_rendering web_application network dom_processing request_queuing ajax_response_time page_views_with_js_errors page_view_throughput ajax_throughput user_defined browser_metric_baseline page_view_throughput average_response_time ajax_response_time ajax_application_time mobile_metric database images json, network view_loading network_error_percentage status_error_percentage user_defined Alerts external service conditions The value specified in the type field controls which of the parameters may be specified. The type field and corresponding available parameter names are listed in the following table. Only one may be specified. type Parameter apm_external_service apdex error_percentage response_time_web response_time_background throughput_web throughput_background user_defined apm_app_metric_baseline external_service_transaction_time error_count database_transaction_time throughput_web response_time_web non_web_transaction_time web_transaction_database_time non_web_transaction_database_time mobile_external_service response_time_average response_time_minimum response_time_maximum throughput network_failure_percentage http_status_error_percentage metric_description This is a title for the metric which is displayed in notifications. Make this descriptive and unique so the reader will understand the nature of plugin metric being used to trigger an alert. Used for: Plugin conditions monitor_id This is the GUID of the Synthetic monitoring to alert on. Used for: Synthetic monitoring conditions name This condition title will allow to you identify it in the UI. Follow the guidelines for making this descriptive but short. Used for: Conditions External service conditions Synthetic monitoring conditions Plugin conditions nrql[query] This is the NRQL query that alerts monitors as part of a NRQL condition. Used for: NRQL conditions nrql[since_value] This is the timeframe (in minutes) in which to evaluate the specified NRQL query. since_value must be between 1 and 20. Used for: NRQL conditions plugin[guid] This is the GUID of the plugin for which the trigger is being defined. Used for: Plugin conditions plugin[id] This is the ID of the plugin for which the trigger is being defined. Used for: Plugin conditions runbook_url The runbook URL to display in notifications. This field is optional. Used for: Conditions External service conditions Synthetic monitoring conditions Plugin conditions terms[duration] This is the time (in minutes) for the condition to persist before triggering an event. It corresponds to the duration set when adding a threshold in the UI. Used for: Conditions terms[operator] This determines what comparison will be used between the value_function and the terms[threshold] value to trigger an event. It corresponds to the operation selected when adding a threshold in the UI. It must be one of the following strings: above below equal Used for: Conditions External service conditions Plugin conditions terms[priority] This corresponds to the severity level selected when setting the threshold values for the condition in the UI. This must be one of the following strings: critical warning Used for: Conditions External service conditions Plugin conditions terms[threshold] This is the threshold that the value_function must be compared to using the terms[operator] for an event to be triggered. It corresponds to the numeric value specified in the UI when adding the threshold values. This is a numeric value and must be 0 (zero) or greater. Used for: Conditions External service conditions Plugin conditions terms[time_function] This corresponds to the settings made in the UI when adding the threshold values. The choices are: all (corresponding to for at least in the UI) any (corresponding to at least once in in the UI) Used for: Conditions External service conditions Plugin conditions type This defines the type of metric that will be used for the alert. Allowable content for the metric field depends on the type value chosen. There are two product categories : Alerts conditions For this category, type is set to one of the following strings indicating the type of alerts condition. type Use apm_app_metric APM application metric will trigger an alert. apm_app_metric_baseline APM application metric will trigger an alert (using a baseline threshold). apm_kt_metric APM key transaction metric will trigger an alert. browser_metric Browser metric will trigger an alert. browser_metric_baseline Browser metric will trigger an alert (using a baseline threshold). mobile_metric Mobile metric will trigger an alert. Used for: Conditions Alerts external service conditions For this category, type is set to one of the following strings indicating the type of external service condition. type Use apm_external_service APM external metric will trigger an alert. mobile_external_service Mobile external metric will trigger an alert. Used for: External service conditions user_defined[metric] (optional) This is the name of a user defined custom metric to be used to determine if an event should be triggered. The user_defined[value_function] associated with the metric is compared with the terms[threshold] value when evaluating if an incident should be triggered. The comparison is performed using the operator defined by terms[operator]. Used for: Conditions External service conditions Synthetic monitoring conditions Plugin conditions user_defined[value_function] (optional) This is the numeric value obtained from the custom metric specified by user_defined[metric]. It is compared with the terms[threshold] value when evaluating if an incident should be triggered. The comparison is performed using the operator defined by terms[operator]. One of these value functions must be specified: average min max total sample_size Used for: Conditions value_function This is the value function used from the plugin metric. This may be one of the strings: min max average sample_size total percent Used for: Plugin conditions When used for a NRQL condition, the options are: single_value (condition is evaluated based on each query's returned value) sum (condition is evaluated based on the sum of each query's returned values over the specified duration) violation_time_limit_seconds Use to automatically close instance-based violations after the number of seconds specified. Must be one of these values: 3600 7200 14400 28800 43200 86400 Used for: Location conditions NRQL conditions violation_close_timer Use to automatically close instance-based violations, including JVM health metric violations, after the number of hours specified. Must be one of these values: 1 2 4 8 12 24 Used for: apm_app_metric (with condition_scope set to instance) apm_jvm_metric For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "body": "Custom events are useful to explore data for a single event you are interested in, including data from external sources, at a particular moment in time. To track arbitrary event data for apps monitored by your New Relic Go agent, add RecordCustomEvent to the apps. You can then query and visualize the event data. RecordCustomEvent parameters To add RecordCustomEvent to your Go app, use this format: RecordCustomEvent(eventType string, params map[string]interface{}) Parameter Description eventType string Required. The name of the event type to record. Must consist of alphanumeric characters, underscores _, or colons :. Must contain no more than 255 bytes. Must follow New Relic Insights data requirements for names, limits, and restricted characters. params map number, string, or boolean Required. Specify key/value pairs of attributes to annotate the event. Each value in the params map must be a number, string, or boolean. Keys must be less than 255 bytes. The params map must not contain more than 64 attributes. Example Here is an example of a custom event for a Go app: func customEvent(w http.ResponseWriter, r *http.Request) { io.WriteString(w, \"recording a custom event\") app.RecordCustomEvent(\"my_event_type\", map[string]interface{}{ \"myString\": \"hello\", \"myFloat\": 0.603, \"myInt\": 123, \"myBool\": true, }) } For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", "type": "docs", "document_type": "page", - "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / REST API alerts", - "info": "This glossary defines the alerts API fields, and provides links to relevant content to help better understand each one.", - "nodeid": 9276, + "breadcrumb": "Contents / APM agents / Go agent / Features", + "info": "To track arbitrary event data in New Relic Insights for apps monitored by your New Relic Go agent, use RecordCustomEvent.", + "nodeid": 13766, "sections": [ - "New Relic Alerts", + "Go agent", "Get started", - "Alert policies", - "Alert conditions", - "Alert violations", - "Alert Incidents", - "Alert notifications", + "Installation", + "Configuration", + "Instrumentation", + "API guides", + "Features", "Troubleshooting", - "Rules, limits, and glossary", - "Alerts and Nerdgraph", - "REST API alerts", - "Alerts conditions API field names", - "Required and optional fields", - "Field definitions", + "Create custom events (Go)", + "RecordCustomEvent parameters", + "Example", "For more help" ], - "title": "Alerts conditions API field names", + "title": "Create custom events (Go)", "popularity": 1, - "external_id": "08f92bd7e576017eb032cdd843c616c7c04fba11", - "category_1": "New Relic Alerts", + "external_id": "b4d19e4ff9eee2b00a40c4add7119820a5f4d3dc", + "category_1": "Go agent", + "category_2": "Features", "image": "", - "url": "https://docs.newrelic.com/docs/alerts-applied-intelligence/new-relic-alerts/rest-api-alerts/alerts-conditions-api-field-names", - "published_at": "2020-08-18T04:25:33Z", - "updated_at": "2020-08-15T13:54:16Z", - "category_0": "Alerts and Applied intelligence", + "url": "https://docs.newrelic.com/docs/agents/go-agent/features/create-custom-events-go", + "published_at": "2020-08-18T03:19:16Z", + "updated_at": "2020-08-15T02:23:50Z", + "category_0": "APM agents", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.0668915, + "_score": 0.4751798, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Alerts conditions API field names", - "sections": "Alert conditions", - "info": "This glossary defines the alerts API fields, and provides links to relevant content to help better understand each one.", - "category_0": "Alerts and Applied intelligence", - "body": ". Used for: Plugin conditions runbook_url The runbook URL to display in notifications. This field is optional. Used for: Conditions External service conditions Synthetic monitoring conditions Plugin conditions terms[duration] This is the time (in minutes) for the condition to persist before triggering" + "title": "Create custom events (Go)", + "sections": "Create custom events (Go)", + "info": "To track arbitrary event data in New Relic Insights for apps monitored by your New Relic Go agent, use RecordCustomEvent.", + "category_0": "APM agents", + "category_1": "Go agent", + "body": "Custom events are useful to explore data for a single event you are interested in, including data from external sources, at a particular moment in time. To track arbitrary event data for apps monitored by your New Relic Go agent, add RecordCustomEvent to the apps. You can then query and visualize", + "breadcrumb": "Contents / APM agents / Go agent / Features" }, - "id": "5f2dee1128ccbc1e7588dff5" + "id": "5f374736e7b9d2653b909280" }, { - "body": "As a customer, you are eligible to participate in New Relic’s Developer Program. Additional information and resources are available at New Relic’s Developer Program site. By downloading, accessing, or using the developer resources (including the CLI), you agree that usage of the developer resources is pursuant to the New Relic Developers Terms and Conditions and that you have the authority to bind your organization. Such terms do not have to be signed in order to be binding. If you do not agree to these terms and conditions, your sole remedy is to not use these developer resources. If your use of the New Relic developer resources are covered under a separate agreement, the above does not apply to you. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "body": "NewRelic.Api.Agent.NewRelic.RecordCustomEvent(string eventType, IEnumerable attributeValues) Records a custom event with the given name and attributes. Requirements Agent version 4.6.29.0 or higher. Compatible with all app types. Description Records a custom event with the given name and attributes, which you can query in the query builder. To verify if an event is being recorded correctly, look for the data in dashboards. For related API calls, see the .NET agent API guide. Sending a lot of events can increase the memory overhead of the agent. Additionally, posts greater than 1MB in size will not be recorded regardless of the maximum number of events. Custom Events are limited to 64-attributes. For more information about how custom attribute values are processed, see the custom attributes guide. Parameters Parameter Description eventType string Required. The name of the event type to record. Strings over 255 characters will result in the API call not being sent to New Relic. The name can only contain alphanumeric characters, underscores _, and colons :. For additional restrictions on event type names, see Reserved words. attributeValues IEnumerable Required. Specify key/value pairs of attributes to annotate the event. Example(s) Record values var eventAttributes = new Dictionary() {   {\"foo\", \"bar\"},   {\"alice\", \"bob\"},   {\"age\", 32},   {\"height\",21.3f} }; NewRelic.Api.Agent.NewRelic.RecordCustomEvent(\"MyCustomEvent\", eventAttributes);", "type": "docs", - "document_type": "page", - "breadcrumb": "Contents / Licenses / Product or service licenses / Developer Edition", - "info": "New Relic Developer edition policy", - "nodeid": 39641, + "document_type": "api_doc", + "breadcrumb": "Contents » APM agents / .NET agent / .NET agent API", + "info": "New Relic .NET agent API call to report custom event data to New Relic.", + "nodeid": 11631, "sections": [ - "Product or service licenses", - "New Relic One", - "APM", - "Browser", - "Developer Edition", - "Infrastructure", - "Insights", - "Logs", - "Mobile", - "Synthetics", - "Mobile apps", - "Plugins", - "Miscellaneous", - "Developer Program Resources", + ".NET agent", + "Getting started", + "Install", + "Azure installation", + "Other installation", + "Configuration", + "Other features", + "Custom instrumentation", + "API guides", + ".NET agent API", + "Attributes", + "Troubleshooting", + "Azure troubleshooting", + "RecordCustomEvent", + "Requirements", + "Description", + "Parameters", + "Example(s)", + "Record values", "For more help" ], - "title": "Developer Program Resources", + "title": "RecordCustomEvent (.NET agent API)", "popularity": 1, - "external_id": "98308cfffa652e4c25967e1be5b848b9c28ca410", - "category_1": "Product or service licenses", - "category_2": "Developer Edition", + "external_id": "2a0a0d5ed597c962d9c7c2b02d2ae40380ec6d3d", + "category_1": ".NET agent", + "category_2": ".NET agent API", "image": "", - "url": "https://docs.newrelic.com/docs/licenses/product-or-service-licenses/new-relic-developer-edition/developer-program-resources", - "published_at": "2020-08-18T17:43:42Z", - "updated_at": "2020-08-08T19:17:02Z", - "category_0": "Licenses", + "url": "https://docs.newrelic.com/docs/agents/net-agent/net-agent-api/recordcustomevent-net-agent-api", + "published_at": "2020-08-18T16:02:14Z", + "updated_at": "2020-08-18T16:02:14Z", + "category_0": "APM agents", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.060060218, + "_score": 0.42307377, "_version": null, "_explanation": null, "sort": null, "highlight": { - "body": " is pursuant to the New Relic Developers Terms and Conditions and that you have the authority to bind your organization. Such terms do not have to be signed in order to be binding. If you do not agree to these terms and conditions, your sole remedy is to not use these developer resources. If your" + "title": "RecordCustomEvent (.NET agent API)", + "sections": ".NET agent API", + "info": "New Relic .NET agent API call to report custom event data to New Relic.", + "category_0": "APM agents", + "category_1": ".NET agent", + "category_2": ".NET agent API", + "body": "NewRelic.Api.Agent.NewRelic.RecordCustomEvent(string eventType, IEnumerable<string, object> attributeValues) Records a custom event with the given name and attributes. Requirements Agent version 4.6.29.0 or higher. Compatible with all app types. Description Records a custom event with the given", + "breadcrumb": "Contents » APM agents / .NET agent / .NET agent API" }, - "id": "5f338507e7b9d2f670c9de83" + "id": "5f3bfb86196a674f83618a39" }, { - "body": "logo-newrelic Search Products Pricing Solutions Help Center About New Relic for iOS or Android    New Relic Insights App for iOS Search icon Sign Up Log In Products New Relic One Platform Overview Telemetry Data Platform Full-Stack Observability Applied Intelligence Solutions By Topic DevOps Cloud Adoption Cloud Native Digital Customer Experience By Industry E-commerce and Retail Media Public Sector By Technology Amazon Web Services Pivotal Cloud Foundry Microsoft Azure Google Cloud Platform Kubernetes Help Center Learn Docs Build on New Relic Explore open source projects Training Get help Community forum Global technical support Expert services About Our Customers Over 17,000 customers love New Relic, from Fortune 500 enterprises to small businesses around the globe. Our Blog The latest news, tips, and insights from the world of New Relic and digital intelligence. Our Company About Us Leadership Meetups and Events Resources   Investor Relations Newsroom Partner Program Contact Us logo-newrelic Want to use our logo? There's a page for that, including instructions and different styles and formats. Sorry about grabbing your right-click. Just trying to be helpful. You can also go home. Back to top icon New Relic Inc. Terms of Service Paid Accounts Customers that access New Relic’s platform through a paid subscription are governed by the Terms of Service set forth immediately above. Unpaid Accounts Customers that access New Relic’s platform on an unpaid (e.g. trials, proof of concepts, New Relic Developer Edition or ‘lite’) basis are governed by the Terms of Service set forth immediately above. Community Forums Community Forum participants ask and answer questions about New Relic’s platform.  Use of the Community Form is governed by the terms and conditions set forth immediately above. New Relic Data Processing Addendum Customers who currently send, or intend to send, personal data to the New Relic Services for processing should download and complete the Data Processing Addendum set forth immediately above. Data Processing Addendum FAQ  This guide is designed to assist customers in their completion of the New Relic Data Processing Addendum. COMPANY Careers and Culture Partner Program Investor Relations NewRelic.org Suppliers Portal CONNECT Contact Us Request Demo Events international newrelic.co.jp (Japanese) newrelic.fr (French) newrelic.de (German) Terms of Service DMCA Policy Privacy Policy Cookie Policy UK Slavery Act of 2015 ©2008-20 New Relic, Inc. All rights reserved", - "type": "", - "info": "", + "body": "You can report custom events to New Relic in several ways, including the New Relic Event API, APM agent APIs, Browser agent APIs, and the Mobile SDK. This document contains general requirements and rules for inserting and using custom events and their associated attributes. Additional requirements may apply based on the method you use. General requirements How long custom data is retained depends on your Insights subscription and its associated data retention. When reporting custom events and attributes, follow these general requirements for supported data types, naming syntax, and size: Requirement Description Payload Total maximum size or length: 1 MB maximum per POST. We highly recommend using compression. The Event API has additional HTTP rate limits. Attribute data types Attribute values can be either a string or a numeric integer or float. If your attribute values contain date information, define it as an unformatted Unix timestamp (in seconds or milliseconds) by using the Insights data formatter. Attribute size Maximum name size: 255 bytes. Maximum attribute value size: Custom attributes sent by the agent: 255 bytes Attributes attached to custom events sent using the Event API: 4096 characters Charts may only display the first 255 characters of attribute values. For complete attribute values, use the JSON chart type or Query API. Maximum total attributes per event: 254. Exception: If you use an APM agent API, the max is 64. Maximum total attributes per event type: 48,000. Naming syntax Attribute names can be a combination of alphanumeric characters, colons (:), periods (.), and underscores (_). Event types (using the eventType attribute) can be a combination of alphanumeric characters, colons (:), and underscores (_). Do not use words reserved for use by NRQL. Null values The database does not store any data with a null value. Reserved words Avoid using the following reserved words as names for events and attributes. Otherwise, unexpected results may occur. This is not a complete list. In general, it's a good practice to avoid using MySQL-reserved words to avoid collision with future New Relic functionality. Keyword Description accountId This is a reserved attribute name. If it's included, it will be dropped during ingest. appId Value must be an integer. If it is not an integer, the attribute name and value will be dropped during ingest. eventType The event type as stored in New Relic. New Relic agents and scripts normally report this as eventType. Can be a combination of alphanumeric characters, colons (:), and underscores (_). Be sure to review the prohibited eventType values and eventType limits. Prohibited eventType values For your eventType value, avoid using: Metric, MetricRaw, and strings prefixed with Metric[0-9] (such as Metric2 or Metric1Minute). Public_ and strings prefixed with Public_. These event types are reserved for use by New Relic. Events passed in with these eventType values will be dropped. timestamp Must be a Unix epoch timestamp. You can define timestamps either in seconds or in milliseconds. It must be +/-1 day (24 hours) of the current time on the server. Log forwarding terms The following keys are reserved by the Infrastructure agent's log forwarding feature: entity.guid, hostname, plugin.type, fb.input. If used, they are dropped during ingest and a warning is added to the logs. NRQL syntax terms If you need to use NRQL syntax terms as attribute names, including dotted attributes, they must be enclosed in backticks; for example, `LIMIT` or `consumer.offset`. Otherwise, avoid using these reserved words: ago, and, as, auto, begin, begintime, compare, day, days, end, endtime, explain, facet, from, hour, hours, in, is, like, limit, minute, minutes, month, months, not, null, offset, or, raw, second, seconds, select, since, timeseries, until, week, weeks, where, with Additional Browser PageAction requirements For additional requirements for using New Relic Browser's custom PageAction event, see Insert custom data via New Relic Browser agent. Additional Event API requirements For more requirements and details for the Event API, see Event API. Event type limits The current limit for total number of eventType values is 250 per sub-account in a given 24-hour time period. If a user exceeds this limit, New Relic may filter or drop data. Event types include: Default events from New Relic agents Custom events from New Relic agents Custom events from Insights custom event inserter If you have a use case that requires to need to store more than 250 unique event types in a given 24-hour period, file a New Relic support ticket at support.newrelic.com. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "type": "docs", + "document_type": "page", + "breadcrumb": "Contents / Insights / Event data sources / Custom events", + "info": "For New Relic, general limits and requirements for reporting custom events and attributes. ", + "nodeid": 13661, "sections": [ - "Terms of Service", - "COMPANY", - "CONNECT", - "international" + "Event data sources", + "Default events", + "Custom events", + "Data requirements and limits for custom event data", + "General requirements", + "Reserved words", + "Additional Browser PageAction requirements", + "Additional Event API requirements", + "Event type limits", + "For more help" ], - "title": "Terms of Service Agreement | New Relic", + "title": "Data requirements and limits for custom event data", + "translation_ja_url": "https://docs.newrelic.co.jp/docs/insights/insights-data-sources/custom-data/insights-custom-data-requirements-limits", "popularity": 1, - "external_id": "f1539ad0dbd46a29c243907400c646ed11c33bd1", - "image": "https://newrelic.com/content/dam/new-relic/opengraph/NROG_Image.png", - "url": "https://newrelic.com/termsandconditions/terms", - "published_at": "2020-08-18T02:00:39Z", - "updated_at": "2020-07-30T07:25:28Z", + "external_id": "f5beef0d09bb5918be3f8a1a3ece98c09947cd1e", + "category_1": "Event data sources", + "category_2": "Custom events", + "image": "", + "url": "https://docs.newrelic.com/docs/insights/insights-data-sources/custom-data/insights-custom-data-requirements-limits", + "published_at": "2020-08-19T01:42:32Z", + "updated_at": "2020-07-24T21:11:48Z", + "category_0": "Insights", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.059077285, + "_score": 0.40216738, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Terms of Service Agreement | New Relic", - "sections": "Terms of Service", - "body": " of concepts, New Relic Developer Edition or ‘lite’) basis are governed by the Terms of Service set forth immediately above. Community Forums Community Forum participants ask and answer questions about New Relic’s platform.  Use of the Community Form is governed by the terms and conditions set forth" + "title": "Data requirements and limits for custom event data", + "sections": "Custom events", + "info": "For New Relic, general limits and requirements for reporting custom events and attributes. ", + "category_1": "Event data sources", + "category_2": "Custom events", + "translation_ja_url": "https://docs.newrelic.co.jp/docs/insights/insights-data-sources/custom-data/insights-custom-data-requirements-limits", + "body": "You can report custom events to New Relic in several ways, including the New Relic Event API, APM agent APIs, Browser agent APIs, and the Mobile SDK. This document contains general requirements and rules for inserting and using custom events and their associated attributes. Additional requirements", + "breadcrumb": "Contents / Insights / Event data sources / Custom events" }, - "id": "5ac68e78c75d077fcb6edc38" - }, + "id": "59f4354f4bb81c2ea8b80d0a" + } + ], + "/build-apps/map-pageviews-by-region": [ { - "body": "As a customer with a paid subscription to New Relic products, you are eligible to participate in preview access of the New Relic One platform (e.g. Telemetry Data Platform, Full Stack Observability, and Applied Intelligence products) for the period beginning July 31, 2020 and ending December 31, 2020 (“Preview Access”). BY DOWNLOADING, ACCESSING, INDICATING YOUR AGREEMENT TO, OR USING THE PREVIEW ACCESS PRODUCTS, YOU AGREE THAT YOUR PREVIEW ACCESS USAGE IS PURSUANT TO THESE SEPARATE TERMS AND CONDITIONS IN LIEU OF ANY OTHER TERMS. These terms do not have to be signed in order to be binding. If you do not agree to these terms and conditions, your sole remedy is to not participate in Preview Access. New Relic reserves the right to terminate or restrict Preview Access, in whole or in part, at any time. Notwithstanding the foregoing and any other materials provided by New Relic, select customers are ineligible for the Preview Access. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", - "type": "docs", + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app, you might have some additional setup and configuration. This guide covers: Downloading the New Relic One CLI to build or modify apps Contribute content to this website Before you begin You must have: A github account account - While not strictly necessary for building apps, a GitHub account enables you to download and customize our open source apps, and contribute an open source project. A New Relic developer account - if you don't already have one, you can get a free trial account for developing New Relic applications. npm - If you've installed Node.js, then you already have npm, which is used to share, reuse, and update JavaScript code, and is necessary for working with React components that are the framework for New Relic apps and this website. Tip Use the New Relic One VSCode extension to build your apps. Prepare to build or modify apps Step 1 of 2 Download the CLI and API key On the Build New Relic One applications page, complete the Quick start steps. These six Quick start steps get you an API key for use with developing apps, and the New Relic One CLI, for building and deploying apps. At the end of the Quick start, you have a project consisting of the following: A Nerdpack - The package containing all the files required by your application. It contains two types of files that you customize to build your app: Nerdlets, and the launcher. One or more Nerdlet files - A specific UI view or window. A Nerdlet is a React JavaScript package that includes an index.js file, a stylesheet, and a JSON-format config file. It can contain any JS functionality (charts, interactive fields, tooltips, etc.). A launcher file: This is the basis for the launcher, which is used to open your application from New Relic One after you publish your app. Step 2 of 2 Start building If you're ready to code, cd to your Nerdpack and get started. If you want to learn more about building applications, try these step-by-step guides: Build a \"Hello, World!\" application shows how to create a little application, publish it to New Relic One, and share it with others by subscribing accounts to it. Map pageviews by region takes you through the steps to create one of our popular open source apps. You learn to add a custom query to an app and view it in a table, then add that data to a map. Contributing to developer.newrelic.com This site is open source, and we want your input. Create a pull request if you see a mistake you know how to fix. Drop us a GitHub issue if you see some content gaps you want us to work on. Or write up a whole new guide if you have one you'd like to share. Read on to learn how. Step 1 of 3 Fork the developer-website GithHub repo Forking the repo enables you to work on your own copy of the developer.newrelic.com files, and build the site locally. It also enables us to more easily manage incomimg pull requests. On the developer-website page in GitHub, select the Fork button on the top right of the page, choose the account you want to fork to, and wait a few seconds while the fork is created. Sync regularly to keep your fork up to date with changes and additions to the main branch upstream. Step 2 of 3 Make a feature or documentation request On any page, select the GitHub button at the top of the page, and then select the kind of change you want, and fill out the GitHub form. Step 3 of 3 Contribute a new guide Check out our contributors guidelines, which will walk you through the process.", + "type": "developer", "document_type": "page", - "breadcrumb": "Contents / Licenses / Product or service licenses / New Relic One", - "info": "", - "nodeid": 39366, + "info": "Prepare to build apps and contribute to this site", "sections": [ - "Product or service licenses", - "New Relic One", - "APM", - "Browser", - "Developer Edition", - "Infrastructure", - "Insights", - "Logs", - "Mobile", - "Synthetics", - "Mobile apps", - "Plugins", - "Miscellaneous", - "Preview access for New Relic One", - "For more help" + "Set up your development environment", + "Before you begin", + "Tip", + "Prepare to build or modify apps", + "Start building" ], - "title": "Preview access for New Relic One", + "title": "Set up your development environment", "popularity": 1, - "external_id": "eae3865081d3bd8ad2dd8b6eaf0fe0147355360c", - "category_1": "Product or service licenses", - "category_2": "New Relic One", + "tags": [ + "developer account", + "API key", + "New Relic One CLI" + ], + "external_id": "c45638a9cd548d1ffffc9f1c7708f115a92ae04a", "image": "", - "url": "https://docs.newrelic.com/docs/licenses/product-or-service-licenses/new-relic-one/preview-access-new-relic-one", - "published_at": "2020-08-18T11:19:02Z", - "updated_at": "2020-07-31T04:41:27Z", - "category_0": "Licenses", + "url": "https://developer.newrelic.com/build-apps/set-up-dev-env/", + "published_at": "2020-08-19T01:44:48Z", + "updated_at": "2020-08-19T01:44:47Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.050509326, + "_score": 0.21198887, "_version": null, "_explanation": null, "sort": null, "highlight": { - "body": ", 2020 (“Preview Access”). BY DOWNLOADING, ACCESSING, INDICATING YOUR AGREEMENT TO, OR USING THE PREVIEW ACCESS PRODUCTS, YOU AGREE THAT YOUR PREVIEW ACCESS USAGE IS PURSUANT TO THESE SEPARATE TERMS AND CONDITIONS IN LIEU OF ANY OTHER TERMS. These terms do not have to be signed in order to be binding" + "sections": "Prepare to build or modify apps", + "info": "Prepare to build apps and contribute to this site", + "body": " to it. Map pageviews by region takes you through the steps to create one of our popular open source apps. You learn to add a custom query to an app and view it in a table, then add that data to a map. Contributing to developer.newrelic.com This site is open source, and we want your input. Create a pull" }, - "id": "5f23a0f7e7b9d29da9c82305" + "id": "5efa9973e7b9d242237bab39" }, { - "body": "New Relic Open Source External Projects Highlighted Projects New Relic Projects Menu External Projects Highlighted Projects New Relic Projects NEW RELIC, INC. INDIVIDUAL CONTRIBUTOR LICENSE AGREEMENT Thank you for your interest in contributing to the open source projects of New Relic, Inc. (“New Relic”). In order to clarify the intellectual property license granted with Contributions from any person or entity, New Relic must have a Contributor License Agreement (\"Agreement\") on file that has been signed by each Contributor, indicating agreement to the license terms below. This Agreement is for your protection as a Contributor as well as the protection of New Relic; it does not change your rights to use your own Contributions for any other purpose. You accept and agree to the following terms and conditions for Your present and future Contributions submitted to New Relic. Except for the licenses granted herein to New Relic and recipients of software distributed by New Relic, You reserve all right, title, and interest in and to Your Contributions. Definitions. \"You\" (or \"Your\") shall mean the copyright owner or legal entity authorized by the copyright owner that is entering into this Agreement with New Relic. For legal entities, the entity making a Contribution and all other entities that control, are controlled by, or are under common control with that entity are considered to be a single Contributor. For the purposes of this definition, \"control\" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. \"Contribution\" shall mean any original work of authorship, including any modifications or additions to an existing work, that is intentionally submitted by You to New Relic for inclusion in, or documentation of, any of the products managed or maintained by New Relic (the \"Work\"). For the purposes of this definition, \"submitted\" means any form of electronic, verbal, or written communication sent to New Relic or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, New Relic for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by You as \"Not a Contribution.\" Grant of Copyright License. Subject to the terms and conditions of this Agreement, You hereby grant to New Relic and to recipients of software distributed by New Relic a perpetual, worldwide, non-exclusive, no-charge, royalty-free, transferable, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Your Contributions and such derivative works. Grant of Patent License. Subject to the terms and conditions of this Agreement, You hereby grant to New Relic and to recipients of software distributed by New Relic a perpetual, worldwide, non-exclusive, no-charge, royalty-free, transferable, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by You that are necessarily infringed by Your Contributions alone or by combination of Your Contribution(s) with the Work to which such Contribution(s) was submitted. If any entity institutes patent litigation against You or any other entity (including a cross-claim or counterclaim in a lawsuit) alleging that Your Contribution, or the Work to which You have contributed, constitutes direct or contributory patent infringement, then any patent licenses granted to that entity under this Agreement for that Contribution or Work shall terminate as of the date such litigation is filed. You represent that You are legally entitled to grant the above licenses. If Your employer(s) has rights to intellectual property that You create that includes Your Contributions, You represent that You have received permission to make Contributions on behalf of that employer, that Your employer has waived such rights for Your Contributions to New Relic, or that Your employer has executed a separate Agreement with New Relic. You represent that each of Your Contributions is Your original creation (see section 7 for submissions on behalf of others). You represent that Your Contribution submissions include complete details of any third-party license or other restriction (including, but not limited to, related patents and trademarks) of which You are personally aware and which are associated with any part of Your Contributions. You are not expected to provide support for Your Contributions, except to the extent You desire to provide support. You may provide support for free, for a fee, or not at all. Unless required by applicable law or agreed to in writing, You provide Your Contributions on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON- INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. Should You wish to submit work that is not Your original creation, You may submit it to New Relic separately from any Contribution, identifying the complete details of its source and of any license or other restriction (including, but not limited to, related patents, trademarks, and license agreements) of which You are personally aware, and conspicuously marking the work as \"Submitted on behalf of a third-party: [named here] \". You agree to notify New Relic of any facts or circumstances of which You become aware that would make these representations inaccurate in any respect. New Relic Open Source Standards External Projects Highlighted Projects New Relic Projects Edit this page Create an issue Copyright © 2020 New Relic Inc.Version 1.8.4", - "type": "opensource", + "body": "New Relic APM's Summary page provides general information about the selected app, including web transactions and non-web transactions, Apdex score, CPU usage, throughput (requests per minute or rpm), transaction times, error rate, application activity, and hosts. To get a high-level overview of all your applications and services, use the entity explorer. View your app's summary page Here are two ways to reach the Summary page: Entity explorer: Go to one.newrelic.com > Entity explorer > (select an app). APM: Go to one.newrelic.com > APM > (select an app). For more information, see the documentation about navigating core UI components in New Relic One. View app performance Use the Summary page for a quick summary of your website's performance. Overview charts Some charts include links to APM pages where you can drill down into additional details. APM Summary chart Comments Transactions response time This stacked chart represents the response time of web transactions or non-web transactions in your app. Segments in the chart vary depending on which agent you are using. Some charts may have an independent line for response time that represents the relationship between response time and total time. Also, for your external or background services, you may see data labeled as Web external. For more information about these out-of-process services, use the Externals page. Apdex score This chart measures the performance of your app based on its Apdex T value during the selected time window. To view additional details, hover over the question question circle icon or the chart's End user and App server lines. The End user line charts the Apdex for your Browser apps, and the App server line charts the Apdex for your APM apps. Throughput This chart illustrates the requests per minute for either web transactions or non-web transactions. To change the type of transaction, select the Transaction response time chart's dropdown arrow, then select Web or Non-web. Error rate This chart shows the number of errors that have occurred in the current time window. The tooltip that appears when you hover over the Error rate chart shows the combined throughput for both web and non-web transactions. To understand how error rate is calculated, see Application error rate example. Event markers Markers on the main Summary chart indicate events and changes to the app: Black vertical bar: Apdex settings have changed. Blue vertical bar: A deployment marker has been created or another event has occurred, such as a settings change for the app. Yellow or red area: This indicates alert thresholds have been violated. To view additional information, mouse over the marker. Drill-down details Use any of New Relic's standard page functions to drill down into detailed information. Here is a summary of additional options with the APM Summary page. If you want to... Do this... Change how data appears on the main chart Select the chart title's drop-down arrow, and then select your choice of view options, including histograms or percentiles if available. View threshold levels for your app's Apdex score Mouse over the Apdex score ? icon. For non-web transactions, the Apdex chart is blank because Apdex is not applicable to this class of apps. View trends in transaction time, Apdex, and throughput Select the Compare with yesterday and last week checkbox. The checkbox is only available when viewing the Web transaction response time chart with the time picker window Ending now. The checkbox is unavailable if you are viewing histograms, percentiles, or custom dates. View app performance since the last deployment From the time picker, select Performance since the last deployment. For detailed information about all deployments, select the Deployments page. View the Transactions page Select the Transactions table's heading on the APM Summary page. Or, to view details about a specific transaction (including operations, transaction traces, and key transactions), select its name. View the Databases or External services pages Click on a related time band in the Web transactions response time chart. View the Errors page Select the Error rate chart's title on the APM Summary page. You can also view the Errors page from one.newrelic.com > (select an app) > Events > Errors. Browser details In order to view Browser details, you must enable this feature from Browser settings. However, if your app has never reported any browser monitoring data, you must first enable it from the application's settings: Go to one.newrelic.com > (select an app) > Settings > Application. From the New Relic Browser section, select the Enable browser monitoring? checkbox. Select Apdex values for browser monitoring and app server requests, or leave the defaults. Optional: Select up to five countries or regions for browser monitoring to highlight on the Geography page. Select Save application settings. To enable additional features, follow standard procedures from Browser > (selected app) > Settings. After New Relic Browser instrumentation is set up, the APM Summary page provides summary information and direct links to detailed information on the app's corresponding Browser Summary page. To view chart details with browser page load time, select the main chart's Browser link. To view the Apdex score for browsers, select the Apdex chart's Browser link. Link app performance to resources The APM Summary page shows a table with averages about your app's instances on their hosts, including: Apdex Response time Throughput Error rate CPU usage Memory CPU usage percentage is calculated as though the application is running on one CPU core. For more information about this calculation, see CPU usage is over 100%. Examine app performance within system context Use any of these options to examine your app's performance within the context of your system's architecture and resources, such as individual hosts: Select your choice from the table at the bottom of the APM Summary page for infrastructure. Toggle between a table view or breakout metric details. If applicable, select your choice from the drop-down at the top of the APM Summary page for servers or JVMs. Examine details within infrastructure To help you understand the full context of your app's performance within your environment, New Relic APM includes options to view performance from inside the application, as well as from outside the application with the infrastructure agent. To view detailed information from your resources' point of view, click any host link. The link takes you directly to the infrastructure Compute page. When you click, the Compute data may not immediately appear. If that happens, follow the prompt to validate your account and complete the conversion process for the infrastructure agent. If you need additional help, get support at support.newrelic.com. Troubleshoot host link To troubleshoot the host link from the APM Summary page, use these tips: Host link from APM Summary Troubleshooting tips Your infrastructure agent is not installed on the host. Follow standard procedures to install our infrastructure agent. The application is operating within a container, and your infrastructure agent is installed on the container’s host. Set the hostname for the container to be the hostname of the underlying server. Docker containers: Run your Docker container with the argument: --uts=\"host\" This will cause the container to share the UTS Linux Namespace with the underlying host. However, by using this set, a privileged container could change the host's hostname. The application is running on a Windows container, and your infrastructure agent is installed on the Windows host. To get a direct link to infrastructure metric data for your application, enable process metrics in the infrastructure agent's configuration. Your infrastructure agent is installed, but it only reports the short hostname, not the long hostname. Configure your server's hostname settings so that the infrastructure agent and the APM agent return the exact same name string. If possible, do so by editing your server's fully qualified domain name (FQDN) settings. The APM and infrastructure agents both read their hostname from the operating system's FQDN settings, so setting the hostname there ensures both agents share a single hostname. For more information, see the Java agent troubleshooting example. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "type": "docs", "document_type": "page", - "info": "", + "breadcrumb": "Contents / APM / APM UI pages / Monitoring", + "info": "New Relic APM's Summary page provides charts and tables that you can drill down into details about your selected app’s performance.", + "nodeid": 3106, "sections": [ - "NEW RELIC, INC.", - "INDIVIDUAL CONTRIBUTOR LICENSE AGREEMENT", - "Definitions." + "APM UI pages", + "Monitoring", + "Error analytics", + "Features", + "Events", + "APM Summary page: View transaction, Apdex, usage data", + "View your app's summary page", + "View app performance", + "Link app performance to resources", + "For more help" ], - "title": "New Relic Open Source Contributor License Agreement", + "title": "APM Summary page: View transaction, Apdex, usage data", + "translation_ja_url": "https://docs.newrelic.co.jp/docs/apm/apm-ui-pages/monitoring/apm-summary-page-view-transaction-apdex-usage-data", "popularity": 1, - "external_id": "478151b2a97835e82c3cd1eaa49610793dc56783", - "image": "", - "url": "https://opensource.newrelic.com/cla/", - "published_at": "2020-08-18T02:21:01Z", - "updated_at": "2020-08-13T01:57:04Z", + "external_id": "107da0571b646cfe203af6c1114369e164edb390", + "category_1": "APM UI pages", + "category_2": "Monitoring", + "image": "https://docs.newrelic.com/sites/default/files/thumbnails/image/crop-apm-overview-hosts112116.png", + "url": "https://docs.newrelic.com/docs/apm/apm-ui-pages/monitoring/apm-summary-page-view-transaction-apdex-usage-data", + "published_at": "2020-08-18T12:28:49Z", + "updated_at": "2020-08-15T05:47:46Z", + "category_0": "APM", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.04286772, + "_score": 0.13611689, "_version": null, "_explanation": null, "sort": null, "highlight": { - "body": " is for your protection as a Contributor as well as the protection of New Relic; it does not change your rights to use your own Contributions for any other purpose. You accept and agree to the following terms and conditions for Your present and future Contributions submitted to New Relic. Except" + "title": "APM Summary page: View transaction, Apdex, usage data", + "sections": "View your app's summary page", + "info": "New Relic APM's Summary page provides charts and tables that you can drill down into details about your selected app’s performance.", + "category_1": "APM UI pages", + "translation_ja_url": "https://docs.newrelic.co.jp/docs/apm/apm-ui-pages/monitoring/apm-summary-page-view-transaction-apdex-usage-data", + "body": " your applications and services, use the entity explorer. View your app's summary page Here are two ways to reach the Summary page: Entity explorer: Go to one.newrelic.com > Entity explorer > (select an app). APM: Go to one.newrelic.com > APM > (select an app). For more information, see" }, - "id": "5f31822264441fcbe056a984" - } - ], - "/collect-data/collect-data-from-any-source": [ + "id": "5f377702196a67008755e629" + }, { - "body": "Our Telemetry SDKs are an open source set of API client libraries that send metrics and trace data to the New Relic platform. We offer open-source integrations for telemetry tools like Prometheus, Istio, and OpenCensus that were created using our Telemetry SDKs. If those solutions (or our other integrations) don't meet your needs, you can use the Telemetry SDKs to create your own telemetry data solutions. Requirements and compatibility To build with the Telemetry SDKs, you will need an Event API insert key. New Relic has contributed the Telemetry SDK to the open source community under an Apache 2.0 license. Available libraries The Telemetry SDKs are open source software on GitHub. Use the language-specific GitHub links below to get library details, coding examples, and procedures for how to use the SDKs. We currently support the following libraries, with more to be created in the future: Language Library Supported data types Java Java library on GitHub New Relic Metrics New Relic Traces Node/TypeScript NodeJS library on GitHub New Relic Metrics New Relic Traces Python Python library on GitHub New Relic Metrics New Relic Events New Relic Traces Go Go library on Github New Relic Metrics New Relic Traces .NET .NET library on GitHub .NET package in NuGet New Relic Metrics New Relic Traces For more on the supported data types: Metrics: see the Metric API Traces: see the Trace API Write your own Telemetry SDK or contribute to an existing one If you need a Telemetry SDK in a language that does not currently exist or want to contribute to an existing library, please see the Telemetry SDK specifications. Integrations built with the Telemetry SDKs To see the integrations built using our Telemetry SDKs, see Open source telemetry integrations. For all monitoring solutions, see our integrations page. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "body": "Browser monitoring's Geography page provides a world view with color-coded Apdex scores and other performance information about your end users' experience. You can select specific geographic regions, such as countries or states, and then you can drill down to detailed information about page load performance and historical performance. Contents View performance data by region Firewalls may have an impact on the geographical data collected about your end users. To view or sort the performance information by location: one.newrelic.com > Browser > (select an app) > Geo: This page provides a world view and drill-down details of color-coded performance information for geographic locations. Go to one.newrelic.com > Browser > (select an app) > Geo > Global (for a world view). OR Go to one.newrelic.com > Browser > (select an app) > Geo > (select a location) (for a specific location you identified in the Browser application settings). To drill down to a specific area, select a location from the list, or select any area on the geographical map. To view additional details about the selected location, select the Page load performance or Historical performance links. To return to the main Geography page, select X (Close). one.newrelic.com > Browser > (select an app) > Geo > (select a location): If you selected specific locations from Settings > Application settings, the Geography page includes tabs to view their performance data directly. Use page functions Use any of our standard user interface functions and page functions to drill down into detailed information. Here is a summary of additional options with the Geography page: If you want to... Do this... Change how the performance data appears Select your choice from the Sort by menu. Adjust the amount of information that appears Select or clear the Hide <% throughput checkbox (<1% for global view, <2% for selected locations). View a map of a specific location Do any of these as applicable: Select the location's name from the Geo > Global list. Select its physical location on the map. If you have pre-selected the location from Application settings, select its tab. View summary performance information about a specific location Mouse over any colored area. View drill-down details After you select a specific location, the Page load performance page shows: Average page load time in seconds Number of page views and active sessions as pages per minute (ppm) Recent browser traces if applicable one.newrelic.com > Browser > (select an app) > Geo > (select a location): After you select a specific location, you can view specific details about Page load performance and Historical performance. In addition, the Historical performance page shows comparison data for the selected time period, yesterday, and last week for the selected location. This includes: Response time Apdex Throughput in pages per minute (ppm) For more help Additional documentation resources include the Page views page (details about end users' overall experience with your site). If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", "type": "docs", "document_type": "page", - "breadcrumb": "Contents / Telemetry Data Platform / Ingest and manage data / Ingest APIs", - "info": "Report custom telemetry data with New Relic's open-source Telemetry SDKs.", - "nodeid": 35471, + "breadcrumb": "Contents / Browser monitoring / Browser monitoring / Additional standard features", + "info": "Browser's Geography feature shows color-coded Apdex scores and page load performance for your end users' experience around the world.", + "nodeid": 1921, "sections": [ - "Ingest and manage data", - "Get started", - "Understand data", - "Manage data", - "Ingest APIs", - "Telemetry SDKs: Report custom telemetry data", - "Requirements and compatibility", - "Available libraries", - "Write your own Telemetry SDK or contribute to an existing one", - "Integrations built with the Telemetry SDKs", + "Browser monitoring", + "Getting started", + "Guides", + "Installation", + "Configuration", + "Browser agent and SPA API", + "Page load timing resources", + "Browser Pro features", + "Additional standard features", + "Performance quality", + "Troubleshooting", + "Browser Geography: Webpage performance by location", + "Contents", + "View performance data by region", + "Use page functions", + "View drill-down details", "For more help" ], - "title": "Telemetry SDKs: Report custom telemetry data", + "title": "Browser Geography: Webpage performance by location", "popularity": 1, - "external_id": "47a4c8f38c1b1674504ea302d865fd499e90ea39", - "category_1": "Ingest and manage data", - "category_2": "Ingest APIs", - "image": "", - "url": "https://docs.newrelic.com/docs/telemetry-data-platform/get-started/capabilities/telemetry-sdks-send-custom-telemetry-data-new-relic", - "published_at": "2020-08-18T15:15:03Z", - "updated_at": "2020-08-11T01:15:34Z", - "category_0": "Telemetry Data Platform", + "external_id": "ccbfe8376f2aee5d35b31dbcee84ff1cbff5b094", + "category_1": "Browser monitoring", + "category_2": "Additional standard features", + "image": "https://docs.newrelic.com/sites/default/files/thumbnails/image/geo_overview.png", + "url": "https://docs.newrelic.com/docs/browser/new-relic-browser/additional-standard-features/browser-geography-webpage-performance-location", + "published_at": "2020-08-18T11:30:40Z", + "updated_at": "2020-08-15T09:25:45Z", + "category_0": "Browser monitoring", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.16237712, + "_score": 0.119279444, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Telemetry SDKs: Report custom telemetry data", - "sections": "Telemetry SDKs: Report custom telemetry data", - "info": "Report custom telemetry data with New Relic's open-source Telemetry SDKs.", - "category_0": "Telemetry Data Platform", - "category_2": "Ingest APIs", - "body": " Metrics New Relic Traces .NET .NET library on GitHub .NET package in NuGet New Relic Metrics New Relic Traces For more on the supported data types: Metrics: see the Metric API Traces: see the Trace API Write your own Telemetry SDK or contribute to an existing one If you need a Telemetry SDK", - "breadcrumb": "Contents / Telemetry Data Platform / Ingest and manage data / Ingest APIs" + "sections": "View performance data by region", + "info": "Browser's Geography feature shows color-coded Apdex scores and page load performance for your end users' experience around the world.", + "body": " performance and historical performance. Contents View performance data by region Firewalls may have an impact on the geographical data collected about your end users. To view or sort the performance information by location: one.newrelic.com > Browser > (select an app) > Geo: This page provides a world" }, - "id": "5d89fefbe7b9d2537ed30dc1" + "id": "561c8bbc827a6617ad000172" }, { - "body": "There are many ways to get data into your New Relic account. Any New Relic user can use any of our data ingest methods to report data to our Telemetry Data Platform. New Relic-built agents and integrations When you enable New Relic solutions like APM, browser monitoring, mobile monitoring, infrastructure monitoring, or any of our wide array of integrations, by default you'll receive data from your monitored applications, hosts, services, or other entities. To browse all New Relic-built tools and solutions, see New Relic integrations. Agent APIs Some of our monitoring solutions come with APIs and/or SDKs that allow you to customize the data reported and how it reports. For more information, see the relevant product: APM agent APIs Browser API Mobile API Infrastructure monitoring: the Flex integration tool Telemetry SDKs If our more curated solutions don't work for you, our open source Telemetry SDKs let you build your own solution. These SDKs are language wrappers for our data-ingest APIs (below) that let you send telemetry data to New Relic without requiring install of an agent. APIs for sending metrics, traces, logs, and events If our more curated solutions don't work for you, we also have data-ingest APIs: Trace API Event API Metric API Log API To learn about the differences between these data types, see Data types. New Relic One applications You can build entirely custom applications that reside in New Relic One and make use of any data you want. You can use existing open source New Relic One apps, or share your own with the open source community. For details, see New Relic One applications. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "body": "Browser monitoring supports the uploading of source maps, which are used to un-minify error stack traces on the JS errors page. This document explains how to use the API to publish (upload) source maps to Browser. Prepare for using the source map API In order to upload source maps to Browser via the API, you'll need this information: An admin API key for the New Relic account The New Relic application ID for the deployed app The full JavaScript file URL Optionally, if the JavaScript URL doesn't automatically have release info appended to it, the release name and ID What is the JavaScript URL? Every time the agent captures an error in your code, it's associated with the URL of the JavaScript in which it occurred. This is the src attribute of the script tag in your HTML. This full JavaScript URL is required when sending source maps to Browser. You can find the URL for an error's JavaScript file in Browser, on the JS errors page. See Browser monitoring source maps for more on finding these errors in the UI. Is a release name and ID required? Many organizations include a version number or hash in the JavaScript URL. This is generally added to \"bust\" caches to ensure your users get the most recent version of your code. This type of URL might look something like: https://example.com/assets/application-59.min.js https://example.com/assets/bundle-d6d031.min.js https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js If your app's URLs automatically have the version info appended to it, the Browser agent has everything it needs in order to match errors with your code. You can move ahead to generating source maps. If this doesn't apply to you, and JS URLs do not have version info appended, you’ll have to assist the agent by specifying a release name and ID with the API. Are there limits to source map uploads? There is no limit to the overall number of source maps you can upload. However, the API is rate-limited: You can upload a maximum of 100 source maps per minute You can upload a maximum of 5,000 source maps per day Source map files can be a maximum of 50Mb in size. Push source maps to New Relic Now that you have one or more source maps, you are ready to publish it to Browser. You can use any of these methods to send source maps to Browser: Use the New Relic npm module with the API via the command line or via a client-side JavaScript build/deploy script like Gulp or Grunt. Use API curl commands. Use the Browser UI. Use npm module via command line or client-side script The easiest and recommended way to upload source maps to Browser is to use the our new @newrelic/publish-sourcemap npm module. It provides a command line tool and Javascript API to accomplish this task. More documentation is available in the npm repo. Here are some examples of using the npm module via the command line. The following examples are for US accounts. For EU accounts, the endpoint is https://sourcemaps.service.eu.newrelic.com. For more information, see Introduction to the EU region data center. npm command line: Publish Here's an example of uploading source maps using the npm module via the command line. Note that the source map can come from a local file or a remote URL. npm install -g @newrelic/publish-sourcemap publish-sourcemap PATH_TO_SOURCE_MAP_FILE (local or remote) PATH_TO_ORIGINAL_FILE --nrAdminKey=YOUR_NEW_RELIC_ADMIN_API_KEY --applicationId=YOUR_NEW_RELIC_APP_ID npm command line: List published maps Here's an example of listing published source maps: list-sourcemaps --applicationId=YOUR_APP_ID --nrAdminKey=YOUR_NEW_RELIC_ADMIN_KEY Options: --applicationId Browser application id --nrAdminKey New Relic admin API key npm command line: Delete Here's an example of deleting a source map: delete-sourcemap --applicationId=YOUR_APP_ID --nrAdminKey=YOUR_NEW_RELIC_ADMIN_API_KEY --sourcemapId=YOUR_SOURCE_MAP_ID Options: --applicationId Browser application id --nrAdminKey New Relic admin API key --sourcemapId Unique id generated for a source map Here are some examples of using the npm module to publish from client-side JavaScript: npm via Node.js script: Publish Here's an example of publishing a source map via a Node.js script: var publishSourcemap = require(‘@newrelic/publish-sourcemap’).publishSourcemap publishSourcemap({ sourcemapPath: 'SOURCE_MAP_FULL_PATH', javascriptUrl: 'JS_URL', applicationId: YOUR_NEW_RELIC_APP_ID, nrAdminKey: 'YOUR_NEW_RELIC_ADMIN_API_KEY' }, function (err) { console.log(err || 'Sourcemap upload done')}) npm via Node.js script: List published maps Here's an example of listing all published source maps: var listSourcemaps = require(‘@newrelic/publish-sourcemap’).listSourcemaps listSourcemaps({ sourcemapPath: 'SOURCE_MAP_FULL_PATH', javascriptUrl: 'JS_URL', applicationId: YOUR_NEW_RELIC_APP_ID, nrAdminKey: 'YOUR_NEW_RELIC_ADMIN_API_KEY', }, function (err, res) { console.log(err || res.body)}) npm via Node.js script: Delete Here's an example of deleting a source map file via a Node.js script: var deleteSourcemap = require(‘@newrelic/publish-sourcemap’).deleteSourcemap deleteSourcemap({ sourcemapId: 'SOURCE_MAP_ID', applicationId: YOUR_NEW_RELIC_APP_ID, nrAdminKey: 'YOUR_NEW_RELIC_ADMIN_API_KEY', }, function (err) { console.log(err || 'Deleted source map')}) When you're done, go to the JS errors page in Browser, select an error grouping, and see if your error stack traces have been un-minified. Use API via curl Below are some examples of using curl to publish, list, and delete source maps: curl: Upload maps An example of using API via curl to publish maps to Browser: curl -H \"Newrelic-Api-Key: YOUR_NEW_RELIC_ADMIN_API_KEY\" \\ -F \"sourcemap=@SOURCE_MAP_PATH\" \\ -F \"javascriptUrl=JS_URL\" \\ -F \"releaseId=YOUR_RELEASE_ID\" \\ -F \"releaseName=YOUR_UI_PAGE\" \\ https://sourcemaps.service.newrelic.com/v2/applications/YOUR_NEW_RELIC_APP_ID/sourcemaps curl: List existing maps Below is an example of how to get a list of source maps previously uploaded to New Relic via curl. New Relic returns the source map's unique SOURCEMAP_ID and its components: curl \\ -H \"Newrelic-Api-Key: YOUR_NEW_RELIC_ADMIN_API_KEY\" \\ https://sourcemaps.service.newrelic.com/v2/applications/YOUR_NEW_RELIC_APP_ID/sourcemaps curl: Delete map To delete a source map: Use the GET endpoint to list existing source maps and locate the SOURCEMAP_ID. Run the following command via curl: curl -X DELETE \\ -H \"Newrelic-Api-Key: YOUR_NEW_RELIC_ADMIN_API_KEY\" \\ https://sourcemaps.service.newrelic.com/v2/applications/YOUR_NEW_RELIC_APP_ID/sourcemaps/SOURCEMAP_ID When you're done, go to the JS errors page in Browser, select an error grouping, and see if your error stack traces have been un-minified. Troubleshoot source maps If you are having trouble generating source maps from your build system, or if your errors in Browser are remaining minified, see the source maps troubleshooting documentation. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", "type": "docs", "document_type": "page", - "breadcrumb": "Contents / Telemetry Data Platform / Ingest and manage data / Get started", - "info": "An introduction to how to get data into New Relic. ", - "nodeid": 36051, + "breadcrumb": "Contents / Browser monitoring / Browser monitoring / Browser Pro features", + "info": "For Browser, how to upload and use source maps with the Browser API.", + "nodeid": 11696, "sections": [ - "Ingest and manage data", - "Get started", - "Understand data", - "Manage data", - "Ingest APIs", - "Get data into New Relic", - "New Relic-built agents and integrations", - "Agent APIs", - "Telemetry SDKs", - "APIs for sending metrics, traces, logs, and events", - "New Relic One applications", + "Browser monitoring", + "Getting started", + "Guides", + "Installation", + "Configuration", + "Browser agent and SPA API", + "Page load timing resources", + "Browser Pro features", + "Additional standard features", + "Performance quality", + "Troubleshooting", + "Upload source maps via API", + "Prepare for using the source map API", + "Push source maps to New Relic", + "Use npm module via command line or client-side script", + "Use API via curl", + "Troubleshoot source maps", "For more help" ], - "title": "Get data into New Relic", + "title": "Upload source maps via API", "popularity": 1, - "external_id": "7a413b4d7e5bd81088a08507ae4bad64c7e24b2d", - "category_1": "Ingest and manage data", - "category_2": "Get started", + "external_id": "6bc1cf3a1c7f6a2b7bdf464b7a6578b093950182", + "category_1": "Browser monitoring", + "category_2": "Browser Pro features", "image": "", - "url": "https://docs.newrelic.com/docs/telemetry-data-platform/get-data-new-relic/getting-started/introduction-new-relic-data-ingest-apis-sdks", - "published_at": "2020-08-18T15:33:40Z", - "updated_at": "2020-08-10T23:16:39Z", - "category_0": "Telemetry Data Platform", + "url": "https://docs.newrelic.com/docs/browser/new-relic-browser/browser-pro-features/upload-source-maps-api", + "published_at": "2020-08-18T16:05:37Z", + "updated_at": "2020-08-15T08:45:07Z", + "category_0": "Browser monitoring", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.148056, + "_score": 0.093903065, "_version": null, "_explanation": null, "sort": null, "highlight": { - "sections": "APIs for sending metrics, traces, logs, and events", - "category_0": "Telemetry Data Platform", - "body": " also have data-ingest APIs: Trace API Event API Metric API Log API To learn about the differences between these data types, see Data types. New Relic One applications You can build entirely custom applications that reside in New Relic One and make use of any data you want. You can use existing open", - "breadcrumb": "Contents / Telemetry Data Platform / Ingest and manage data / Get started" + "title": "Upload source maps via API", + "sections": "Page load timing resources", + "info": "For Browser, how to upload and use source maps with the Browser API.", + "body": ": 'SOURCE_MAP_ID', applicationId: YOUR_NEW_RELIC_APP_ID, nrAdminKey: 'YOUR_NEW_RELIC_ADMIN_API_KEY', }, function (err) { console.log(err || 'Deleted source map')}) When you're done, go to the JS errors page in Browser, select an error grouping, and see if your error stack traces have been un-minified. Use API" }, - "id": "5f24aa60196a67ede394f5f3" + "id": "5c6905d607552356e245ca12" }, { - "body": "New Relic products report a variety of default event data to your account. This document will explain how to report your own custom events and attributes. Overview of reporting custom events and attributes Event data is one of the fundamental New Relic data types. Events are reported by most New Relic products, and we give you several options for reporting your own custom events. Reporting custom events allows you to create more useful and customized queries and charts of your data, and is a key part of optimizing how New Relic works for you. Before beginning, it's important to know that reporting a large number of custom events and/or attributes can cause degraded query performance, or cause you to approach or pass data collection rate limits. For optimal performance, first think about what data you want to analyze, and then create only the events and/or attributes necessary to meet these specific goals. Be aware of the following data and subscription requirements for inserting and accessing custom data: Ensure you follow limits and requirements around event/attribute data types, naming syntax, and size. The amount of data you have access to over time depends on your data retention policy. Send custom events and attributes Methods for sending custom events and attributes include: Source How to send custom data APM agent Use APM agent APIs to report custom events and custom attributes. Browser agent Add custom attributes to the PageView event via the Browser API call addCustomAttribute. Send PageAction event and attributes via Browser API. Forward APM agent custom attributes to PageView event. Event API To report custom events not associated with other New Relic products, use the Event API. Infrastructure Add custom attributes to default Infrastructure events. Use the Flex integration tool to report your own custom event data. Mobile agent Use the mobile agent API to send custom events and attributes. Synthetics Add custom attributes to the SyntheticCheck event via the $util.insights tools. For ways to report other types of custom data, see: Metric API Logs Trace API Extend data retention To learn about how to extend how long events are retained in your account, see Event data retention. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", - "type": "docs", + "body": "Intro to NerdStorage 30 min To help you build a New Relic One application, we provide you with the New Relic One SDK. On this page, you’ll learn how to use NerdStorage SDK components. Use NerdStorage in your apps NerdStorage is used to store and retrieve simple sets of data, including users's configuration settings and preferences (like favorites), or any other small data sets. This storage is unique per Nerdpack, and can't be shared with any other Nerdpack. NerdStorage can be classified into three categories: User storage: Data that is attached to a particular user. If you’re authenticated as the user the data is attached to, you can read it and write it. Account storage: Data that is attached to a particular account. If you’re authenticated and can access the account, you can read and write to account scoped NerdStorage. Visibility of account data is also determined by master/subaccount rules: If a user has access to the master account, then they also have access to data in all subaccounts. Entity storage: Data that is attached to a particular entity. If you can see the corresponding entity, you can read and write data on that entity. Data model You can imagine NerdStorage as a nested key-value map. Data is inside documents, which are nested inside collections: { 'YourNerdpackUuid': { 'collection-1': { 'document-1-of-collection-1': '{\"lastNumber\": 42, \"another\": [1]}', 'document-2-of-collection-1': '\"userToken\"', // ... }, 'another-collection': { 'fruits': '[\"pear\", \"apple\"]', // ... }, // ... }, } Copy Each NerdStorage level has different properties and purpose: Collections: From a Nerdpack, you can create multiple collections by naming each of them. Inside a collection you can put one or more documents. Think of a collection as key-value storage, where each document is a key-value pair. Documents: A document is formed by an identifier (documentId) and a set of data associated with it. Data associated with a document: NerdStorage accepts any sort of data associated to a documentId. Query and mutation components that are provided work by serializing and deserializing JSON. Limits A Nerdpack can hold up to 1,000 collections and 10,000 documents, plus storage type. A collection can hold up to 1,000 documents, plus storage type. Each document can have a maximum length of 64 KiB when serialized. Data access To access NerdStorage, you can run NerdGraph queries, or use the provided storage queries. Depending on which storage you want to access, you can use a different set of SDK components: User access: UserStorageQuery and UserStorageMutation Account access: AccountStorageQuery and AccountStorageMutation Entity access: EntityStorageQuery and EntityStorageMutation Each of these components can operate declaratively (for example, as part of your React rendering methods) or imperatively (by using the static methods for query and mutation). For more information on this, see Data querying and mutations. Permissions for working with NerdStorage In order to persist changes on NerdStorage, such as creating, updating, and deleting account and entity storage, you must have a user role with permission to persist changes.", + "type": "developer", "document_type": "page", - "breadcrumb": "Contents / Insights / Event data sources / Custom events", - "info": "An overview of the options for sending custom event data to New Relic. ", - "nodeid": 13806, + "info": "Intro to NerdStorage on New Relic One", "sections": [ - "Event data sources", - "Default events", - "Custom events", - "Report custom event data", - "Overview of reporting custom events and attributes", - "Send custom events and attributes", - "Extend data retention", - "For more help" + "Intro to NerdStorage", + "Use NerdStorage in your apps", + "Data model", + "Limits", + "Data access", + "Permissions for working with NerdStorage" ], - "title": "Report custom event data", + "title": "Intro to NerdStorage", "popularity": 1, - "external_id": "afb5f5a81ae06b22935d98c470ed9cabd7c9da6b", - "category_1": "Event data sources", - "category_2": "Custom events", + "tags": [ + "nerdstorage", + "nerdstorage components", + "new relic one apps", + "data access" + ], + "external_id": "709e06c25376d98b2191ca369b4d139e5084bd62", "image": "", - "url": "https://docs.newrelic.com/docs/insights/insights-data-sources/custom-data/report-custom-event-data", - "published_at": "2020-08-18T07:15:53Z", - "updated_at": "2020-07-26T05:52:23Z", - "category_0": "Insights", + "url": "https://developer.newrelic.com/explore-docs/nerdstorage/", + "published_at": "2020-08-19T01:49:36Z", + "updated_at": "2020-08-14T01:50:34Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.12379804, + "_score": 0.074268796, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Report custom event data", - "sections": "Event data sources", - "info": "An overview of the options for sending custom event data to New Relic. ", - "category_1": "Event data sources", - "category_2": "Custom events", - "body": " the Flex integration tool to report your own custom event data. Mobile agent Use the mobile agent API to send custom events and attributes. Synthetics Add custom attributes to the SyntheticCheck event via the $util.insights tools. For ways to report other types of custom data, see: Metric API Logs Trace", - "breadcrumb": "Contents / Insights / Event data sources / Custom events" + "sections": "Use NerdStorage in your apps", + "tags": "new relic one apps", + "body": " as a nested key-value map. Data is inside documents, which are nested inside collections: { 'YourNerdpackUuid': { 'collection-1': { 'document-1-of-collection-1': '{"lastNumber": 42, "another": [1]}', 'document-2-of-collection-1': '"userToken"', // ... }, 'another-collection': { 'fruits': '["pear", "apple" }, - "id": "5e8e7f9de7b9d2aa122cf0f6" - }, + "id": "5efa989ee7b9d2048e7bab92" + } + ], + "/build-apps/howto-use-nrone-table-components": [ { - "body": "New Relic offers a variety of APIs and SDKs you can use to: Retrieve data from New Relic. Send data to New Relic. Adjust settings. This section of the docs provides examples and reference documentation for our API endpoints. For developer-focused content on how to use and customize New Relic, see developer.newrelic.com. NerdGraph (GraphQL) NerdGraph is New Relic's GraphQL API, an efficient and flexible query language that lets you request exactly the data you need, without over-fetching or under-fetching. While typical REST APIs require loading from multiple URLs, NerdGraph calls get all the data you need in a single request. NerdGraph also makes it easier to evolve APIs over time and enables powerful developer tools. New Relic provides a powerful GraphQL tool to explore the API with embedded schema definitions. To get started, go to api.newrelic.com/graphiql. For sample queries and mutations, use our NerdGraph tutorials. REST APIs by capability New Relic capabilities, like APM, infrastructure monitoring, or alerts, are often used together, and sometimes they overlap in functionality. This is why multiple APIs may be relevant to each area. Some API functionality will depend on your access to features and data. To learn more about different API key types, see Understand New Relic API keys. Alerts Use the REST API for alerts and the API Explorer to: Create and manage policies, conditions, and notification channels. Create alert conditions based on NRQL queries. Create alert conditions based on data from other New Relic capabilities. APM API resources for application monitoring include: Resource Details REST API REST API features include: Retrieve APM data, including metrics, Apdex, error rates, and host data. Report deployments. Change the app name in the UI. Agent APIs Every APM language agent has an API that lets you customize the agent's default behavior, including reporting custom data. APM agent APIs include: C SDK API Go agent API Java agent API .NET agent API Node.js agent API PHP agent API Python agent API Ruby agent API Query API To query APM data, use the Query API. Account management APIs For APIs related to accounts and subscription usage, see the account-related APIs. Browser monitoring The Browser API resources include: Resource Details Browser agent API Use the Browser agent API for tasks such as: Report custom end user data to browser monitoring. Monitor asynchronous browser activity using SPA API calls. Insert custom data into New Relic dashboards . Manage source maps. REST API With the REST API you can: Retrieve page load timing data and throughput. Add or list apps monitored by browser monitoring. Manage alerts conditions for your browser data. Query API To retrieve browser monitoring data, use the Query API. Account management APIs For APIs related to accounts and subscription usage, see the account-related APIs. Infrastructure monitoring The Infrastructure API resources include: Resource Details Query API To retrieve infrastructure data, use the Query API. This API can also be used to retrieve subscription usage data. Infrastructure alert API To manage your infrastructure alerts, use the Infrastructure alert API. Integrations SDK To make your own custom integrations for reporting data to infrastructure monitoring, use the Integrations SDK. NerdGraph You can use NerdGraph (our GraphQL API) to query your cloud integration data and make changes to cloud integration settings. Mobile monitoring Mobile API resources include: Resource Details Mobile agent APIs Mobile APIs let you custom instrument your own code and send events to New Relic. See the platform-specific documentation: iOS Android Unity REST API Use the REST API for such tasks as: Retrieve a list of monitored apps. Get subscription usage data. Get metric names and data. Get crash count and crash rate data. Manage New Relic alerts conditions for your mobile apps. Query API To retrieve Mobile data from New Relic, use the Query API. Account management APIs For account-related APIs, see Account APIs. Synthetic monitoring Synthetics API resources include: Resource Details Synthetics REST API The Synthetics REST API functionality includes: Create and manage synthetics monitors. Manage synthetics alert notifications. Add labels to monitors, and retrieve monitors with specific labels. Query API To retrieve synthetics event data, use the Query API. Alerts API To create and manage alert conditions that target synthetics monitors, use the Alerts API. Telemetry APIs for core data types We offer several APIs that allow you to get our core data types (metrics, logs, traces, and events) into New Relic without the use of an installed agent. Data type Description Trace API Send distributed tracing data to New Relic. Event API Send event data to New Relic. Metric API Send metrics to New Relic from any source (including other telemetry monitoring services). Log API Send your log data to New Relic. Account management, admin, and usage APIs Like any other New Relic product or service, you want to be confident that your APIs protect you and your customers' data privacy. The following are API resources related to New Relic account administration and usage. For more information about API capabilities, see the specific New Relic API. For more information about New Relic's security measures, see our security and privacy documentation, or visit the New Relic security website. Resource Details REST API REST API features include: Find your API keys, account ID, and information needed to use the REST API. Return a list of account users. Get SLA report data for browser and application monitoring. Subscription usage You can use the Query API to retrieve subscription usage data. This can be helpful to see how usage compares to your current subscription level, or for doing departmental chargebacks. If you implemented the REST API for querying subscription usage data prior to July 10, 2018, those usage-related REST APIs are now deprecated. You should use the Query API, which requires creating an API key. For more on switching to the new API format, see the transition guide. Partner API To retrieve information about your New Relic partner account, sub-accounts, and users, use the Partner API. Other APIs Insights API resources for Insights include: Resource Details Insert events API To report custom data use the Event insertion API. Query API To query your Insights data using NRQL-formatted queries, use the Query API. This API can also be used to retrieve subscription usage data. Dashboard API To create, read, update, and delete dashboards, use the Dashboard API. Other New Relic product APIs You can also report custom data from other New Relic features. For more information, see the API sections for other products. NerdGraph You can use NerdGraph (our GraphQL API) to query data with NRQL. Plugins Use the REST API for New Relic plugins and the API Explorer to: Get a list of plugins, including their names, IDs, and GUIDs. List one or more plugin components, their output, and their metric timeslice data. Developers and New Relic partners can also use New Relic's Plugin API to write an agent in any language that can work directly with the API for plugins. This allows you to send your own metric data to our plugins and view data received from the API in New Relic. See APIs in action For more on how you as a developer can optimize your ability to solve problems using New Relic, go to developer.newrelic.com. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", - "type": "docs", + "body": "Add the NerdGraphQuery component to an application 20 minutes This guide steps you through the process of adding the `NerdGraphQuery` component to a sample transaction overview application. This allows you to query data from your New Relic account and add it to a dropdown menu. NerdGraph is our GraphQL implementation. GraphQL has some key differences when compared to REST: The client, not the server, determines what data is returned. You can easily collect data from multiple sources. For example, in a single query, you can get account information, infrastructure data, and issue a NRQL request. Note Before completing this exercise, you can experiment with GraphQL queries in our NerdGraph API explorer. We also have a 14-minute video that covers the steps below. Before you begin To develop projects, you need our New Relic One CLI (command line interface). If you haven't already installed it, do the following: Install Node.js. Complete steps 1–4 of our CLI quick start, and be sure to make a copy of your account ID from step 1 because you’ll need it later. Note If you've already installed the New Relic One CLI, but you can't remember your account ID, start the CLI quick start again, and then click the Get your API key down arrow. The account ID is the number preceding your account name. For additional details, see Set up your development environment. Prepare the sample code To get started, complete these steps to update the application UUID (unique ID) and run the sample application locally: Step 1 of 7 If you haven't already done so, clone the example applications from our how-to GitHub repo. Here's an example using HTTPS: git clone https://github.com/newrelic/nr1-how-to.git Copy Step 2 of 7 Change to the directory use-nerdgraph-nerdlet: cd nr1-how-to/use-nerdgraph/nerdlets/use-nerdgraph-nerdlet Copy Step 3 of 7 In your preferred text editor, open index.js. Step 4 of 7 Replace with your account id: Note Your account ID is available in the CLI quick start (see Before you begin). this.accountId = ; Copy Step 5 of 7 Change to the /nr1-howto/use-nerdgraph directory: cd ../.. Copy Step 6 of 7 Execute these commands to update the UUID and serve the sample application: nr1 nerdpack:uuid -gf nr1 nerdpack:serve Copy Step 7 of 7 Once the sample application is successfully served, go to the local New Relic One homepage (https://one.newrelic.com/?nerdpacks=local), click Apps, and then click Use NerdGraph. After launching the Use NerdGraph application, you see a dashboard that gives an overview of the transactions in your account: Add the NerdGraphQuery component Now you can create a dropdown menu for changing the account the application is viewing. The first step is to import the NerdGraphQuery component into the application's index.js file. Note If you need more details about our example below, see the APIs and components page on https://developer.newrelic.com Step 1 of 3 Add the NerdGraphQuery component into the first StackItem inside of the return in the index.js file: {({ loading, error, data }) => { console.log({ loading, error, data }); if (loading) { return ; } if (error) { return 'Error!'; } return null; }} ; Copy Step 2 of 3 The NerdGraphQuery component takes a query object that states the source you want to access and the data you want returned. Add the following code to your index.js file in the render method: Note In the browser console, you can see the data from your query returned in an object that follows the same structure of the object in the initial query. const query = ` query($id: Int!) { actor { account(id: $id) { name } } } `; Copy Step 3 of 3 To take the data returned by the NerdGraph query and display it in the application, replace the return null in the current NerdGraphQuery component with this return statement: return {data.actor.account.name} Apps:; Copy When you go back to the browser and view your application, you see a new headline showing the name of your account returned from NerdGraph: How to use NerdGraphQuery.query At this point, you have implemented the NerdGraphQuery component with the application's render method and displayed the return data within the transaction overview application. Here's what you need to do next: Query NerdGraph inside of the componentDidMount lifecycle method. Save the returned data for later use in the application. Step 1 of 2 This code takes the response from NerdGraph and makes sure the results are processed, stored into the application state, and logged to the browser console for viewing. Add this code into the index.js file just under the constructor: componentDidMount() { const accountId = this.state; const gql = `{ actor { accounts { id name } } }`; const accounts = NerdGraphQuery.query({query: gql}) //The NerdGraphQuery.query method called with the query object to get your account data is stored in the accounts variable. accounts.then(results => { console.log('Nerdgraph Response:', results); const accounts = results.data.actor.accounts.map(account => { return account; }); const account = accounts.length > 0 && accounts[0]; this.setState({ selectedAccount: account, accounts }); }).catch((error) => { console.log('Nerdgraph Error:', error); }) } Copy Step 2 of 2 After the data is stored into state, display a selection so users can change accounts and update the application. To do this, add this code to index.js for the second StackItem in the return statement: { accounts && ( ); } Copy Review the results of the NerdGraph query After you complete these steps, look at the application in your browser, and note the following: The dropdown menu now displays the data returned from the NerdGraphQuery.query and allows you to select an account. After you select a new account, the application shows data from the new selection. The final index.js file should have code similar to the code below. This completed sample is in your nerdlet final.js. import React from 'react'; import { PlatformStateContext, NerdGraphQuery, Spinner, HeadingText, Grid, GridItem, Stack, StackItem, Select, SelectItem, AreaChart, TableChart, PieChart } from 'nr1' import { timeRangeToNrql } from '@newrelic/nr1-community'; // https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction export default class UseNerdgraphNerdletNerdlet extends React.Component { constructor(props){ super(props) this.state = { accountId: , accounts: null, selectedAccount: null, } } componentDidMount() { const accountId = this.state; const gql = `{ actor { accounts { id name } } }`; const accounts = NerdGraphQuery.query({ query: gql }) accounts.then(results => { console.log('Nerdgraph Response:', results); const accounts = results.data.actor.accounts.map(account => { return account; }); const account = accounts.length > 0 && accounts[0]; this.setState({ selectedAccount: account, accounts }); }).catch((error) => { console.log('Nerdgraph Error:', error); }) } selectAccount(option) { this.setState({ accountId: option.id, selectedAccount: option }); } render() { const { accountId, accounts, selectedAccount } = this.state; console.log({ accountId, accounts, selectedAccount }); const query = ` query($id: Int!) { actor { account(id: $id) { name } } } `; const variables = { id: accountId, }; const avgResTime = `SELECT average(duration) FROM Transaction FACET appName TIMESERIES AUTO `; const trxOverview = `FROM Transaction SELECT count(*) as 'Transactions', apdex(duration) as 'apdex', percentile(duration, 99, 95) FACET appName `; const errCount = `FROM TransactionError SELECT count(*) as 'Transaction Errors' FACET error.message `; const responseCodes = `SELECT count(*) as 'Response Code' FROM Transaction FACET httpResponseCode `; return ( {({loading, error, data}) => { if (loading) { return ; } if (error) { return 'Error!'; } return {data.actor.account.name} Apps:; }} {accounts && }
{(PlatformState) => { /* Taking a peek at the PlatformState */ const since = timeRangeToNrql(PlatformState); return ( <>
Transaction Overview
Average Response Time
Response Code
Transaction Errors
); }}
) } } Copy Summary Now that you've completed all the steps in this example, you've successfully queried data from your account using the NerdGraphQuery component in two methods: Using the NerdGraphQuery component inside the application's render method and then passing the returned data into the children's components. Using the NerdGraphQuery.query method to query data before the application renders.", + "type": "developer", "document_type": "page", - "breadcrumb": "Contents / APIs / Get started / Intro to APIs", - "info": "An introduction to all of the available New Relic APIs. ", - "nodeid": 15691, + "info": "The NerdGraphQuery component allows you to query data from your account and add it to a dropdown menu in an application", "sections": [ - "Get started", - "Intro to APIs", - "Introduction to New Relic APIs", - "NerdGraph (GraphQL)", - "REST APIs by capability", - "Telemetry APIs for core data types", - "Account management, admin, and usage APIs", - "Other APIs", - "See APIs in action", - "For more help" + "Add the NerdGraphQuery component to an application", + "Note", + "Before you begin", + "Prepare the sample code", + "Add the NerdGraphQuery component", + "How to use NerdGraphQuery.query", + "Review the results of the NerdGraph query", + "Summary" ], - "title": "Introduction to New Relic APIs", - "translation_ja_url": "https://docs.newrelic.co.jp/docs/apis/get-started/intro-apis/introduction-new-relic-apis", + "title": "Add the NerdGraphQuery component to an application", "popularity": 1, - "external_id": "bb3a7314b2407cfa765425553484cb364e27e7e3", - "category_1": "Get started", - "category_2": "Intro to APIs", - "image": "", - "url": "https://docs.newrelic.com/docs/apis/get-started/intro-apis/introduction-new-relic-apis", - "published_at": "2020-08-18T02:45:47Z", - "updated_at": "2020-08-10T01:40:52Z", - "category_0": "APIs", + "tags": [ + "nerdgraphquery component", + "transaction overview app", + "query account data", + "drop-down menu", + "NerdGraphQuery.query method" + ], + "external_id": "6bd6c8a72eab352a3e8f4332570e286c7831ba84", + "image": "https://developer.newrelic.com/static/5dcf6e45874c1fa40bb6f21151af0c24/b01d9/no-name.png", + "url": "https://developer.newrelic.com/build-apps/add-nerdgraphquery-guide/", + "published_at": "2020-08-19T01:48:31Z", + "updated_at": "2020-08-19T01:48:30Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.10374672, + "_score": 7.8629537, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Introduction to New Relic APIs", - "sections": "Telemetry APIs for core data types", - "info": "An introduction to all of the available New Relic APIs. ", - "category_0": "APIs", - "category_2": "Intro to APIs", - "translation_ja_url": "https://docs.newrelic.co.jp/docs/apis/get-started/intro-apis/introduction-new-relic-apis", - "body": ". Telemetry APIs for core data types We offer several APIs that allow you to get our core data types (metrics, logs, traces, and events) into New Relic without the use of an installed agent. Data type Description Trace API Send distributed tracing data to New Relic. Event API Send event data to New" + "title": "Add the NerdGraphQuery component to an application", + "sections": "Add the NerdGraphQuery component to an application", + "info": "The NerdGraphQuery component allows you to query data from your account and add it to a dropdown menu in an application", + "tags": "nerdgraphquery component", + "body": "Add the NerdGraphQuery component to an application 20 minutes This guide steps you through the process of adding the `NerdGraphQuery` component to a sample transaction overview application. This allows you to query data from your New Relic account and add it to a dropdown menu. NerdGraph is our" }, - "id": "5d4ae71be7b9d211b4d535a4" + "id": "5efa993c64441ff4865f7e32" }, { - "body": "New Relic offers several tools to help obtain the information needed to provide useful metrics about your Node.js application. These include: Reading the route names (if used) from the Express and Restify routers Using the API to name the current request, either with simple names or groups of controllers with actions Support rules that are stored in your agent's configuration that can mark requests to be renamed or ignored based on regular expressions matched against the request's raw URLs (also available as API calls) The number of names that New Relic tracks needs to be small enough so that the user experience is robust. It also needs to be large enough to provide the right amount of information (without overwhelming you with data) so that you can identify problem spots in your applications more easily. For more information, see the Node.js agent configuration documentation and the Node.js agent API documentation on Github. Request names The Node.js agent captures the HTTP method along with a potentially parameterized path (such as /user/:id) or a regular expression (such as /^/user/([-0-9a-f]+)$/). These pieces of information become part of the request name. If you have support for slow transaction traces and have enabled capture_params in your config file, the transaction trace will also have the request's parameters and their values attached to it. If you are dissatisfied with the request names that the Node.js agent uses, you can use API calls to create more descriptive names. If grouping your requests under the generic name, then /* is sufficient, and you do not need to customize your configuration file or API calls. Requirements New Relic uses request names to group requests for many charts and tables. The value of these visualizations will drop as the number of different request names increases. For example, do not include potentially dynamic data like GUIDs, numerical IDs, or timestamps in the request names you create. If your request is slow enough to generate a transaction trace, that trace will contain the original URL. If you enable parameter capture, the parameters will also be attached to the trace. Avoid having more than 50 different transaction names. For example, if you have more than a couple hundred different request names, rethink your naming strategy. Avoid metric grouping issues The request naming API helps New Relic avoid problems with trying to handle too many metrics, which sometimes is referred to as \"metric explosion.\" New Relic has several strategies to deal with these issues; the most severe is simply to add offending applications to your deny list. The main reason for you to be careful in using these request-naming tools is to prevent that from happening to your applications. For more information, see Metric grouping issues. Guidelines Define your configuration rules from the most specific to the most general. The first rules listed in your config file or added with the Node.js transaction naming API will be applied first and should be narrowly targeted. More general \"fall-through\" rules should be added toward the end of the list, because they will be evaluated in the order they were configured or added using the Node.js transaction naming API. URL pattern matching An online retailer has a URL pattern like this: /user/customers/all/prospects /user/customers/all/current /user/customers/all/returning /user/customers/John /user/customers/Jane The retailer could create rules like this: // newrelic.js exports.config={ //other configuration rules:{ name:[ { pattern: \"/user/customers/all/prospects/\", name: \"/user/customers/all/prospects\" }, { pattern: \"/user/customers/all/.*\", name: \"/user/customers/all\" }, { pattern: \"/user/customers/.*\", name: \"/user/customers/:customer\" } ] } } With these rules, the retailer would create three transaction names: /user/customers/:customer /user/customers/all /user/customers/all/prospects If the retailer reversed the order, the rules would catch all transactions in :customer, which would not be as useful. Load the request naming API Make sure that loading the New Relic module is the first thing your application does, as it needs to bootstrap itself before the rest of your application loads: var newrelic = require('newrelic'); This returns the request naming API. You can safely require the module from multiple modules in your application, as it only initializes itself once. Request API calls Here is a summary of the Request API calls for New Relic's Node.js agent. newrelic.setTransactionName(name) Name the current request, following the request naming requirements. You can call this function anywhere within the context of an HTTP request handler, at any time after handling of the request has started, but before the request has finished. In general, if the request and response objects are in scope, you can set the name. Explicitly calling newrelic.setTransactionName() will override any names set by Express or Restify routes. Also, calls to newrelic.setTransactionName() and newrelic.setControllerName() will overwrite each other. The last one to run before the request ends wins. newrelic.setControllerName(name, [action]) Name the current request using a controller-style pattern, optionally including the current controller action. If the action is omitted, New Relic will include the HTTP method (GET, POST, etc.) as the action. The rules for when you can call newrelic.setControllerName() are the same as they are for newrelic.setTransactionName(), including the request naming requirements. Explicitly calling newrelic.setControllerName() will override any names set by Express or Restify routes. Also, calls to newrelic.setTransactionName() and newrelic.setControllerName() will overwrite each other. The last one to run before the request ends wins. Custom instrumentation API calls Use these API calls to expand your instrumentation with custom instrumentation. newrelic.instrument(moduleName, onRequire [, onError]) Sets an instrumentation callback for a specific module. The provided onRequire callback will be fired when the given module is loaded with require. The moduleName parameter should be the string that will be passed to require; for example, 'express' or 'amqplib/callback_api'. The optional onError callback is called if the onRequire parameters throws an error. This is useful for debugging your instrumentation. Use this method to: Add instrumentation for modules not currently instrumented by New Relic. Instrument your own code. Replace the Node.js agent's built-in instrumentation with your own. For more information, see New Relic's Node.js instrumentation tutorial on Github. newrelic.instrumentDatastore(moduleName, onRequire [, onError]) Sets an instrumentation callback for a datastore module. This method is just like newrelic.instrument(), except it provides a datastore-specialized shim. For more information, see New Relic's Node.js datastore instrumentation tutorial on Github. newrelic.instrumentLoadedModule(moduleName, moduleInstance) The instrumentLoadedModule method allows you to add stock instrumentation to specific modules in situations where it's impossible to have require('newrelic'); as the first line of your app's main module. // load the agent const newrelic = require('newrelic') // module loaded before newrelic const expressModule = require('express') // instrument express _after_ the agent has been loaded newrelic.instrumentLoadedModule( 'express', // the module's name, as a string expressModule // the module instance ); This method cannot instrument any arbitrary module. Its purpose is to add modules that were missed because the agent was not loaded as the first thing in your program. The instrumentLoadedModule method can only instrument modules the agent would normally instrument. You can see a list of these modules in the agent's lib/instrumentations module. newrelic.instrumentMessages(moduleName, onRequire [, onError]) Sets an instrumentation callback for a message service client module. This method is just like newrelic.instrument(), except it provides a message-service-specialized shim. For more information, see New Relic's Node.js message service instrumentation tutorial on Github. newrelic.instrumentWebframework(moduleName, onRequire [, onError]) Sets an instrumentation callback for a web framework module. This method is just like newrelic.instrument(), except it provides a web-framework-specialized shim. For more information, see New Relic's Node.js web framework instrumentation tutorial on Github. newrelic.startWebTransaction(url, handle) Instrument the specified web transaction. Using this API call, you can instrument transactions that New Relic does not automatically detect. The url defines the transaction name and needs to be static. Do not include variable data such as user ID. The handle defines the function you want to instrument. New Relic will capture any metrics that would be captured by auto-instrumentation, as well as manual instrumentation via startSegment(). You must handle custom transactions manually by calling newrelic.getTransaction() at the start of your transaction, and then call transaction.end() when you are finished. New Relic begins timing the transaction when newrelic.startWebTransaction() is called and ends the transaction when transaction.end() is called. You can also return a promise to indicate the end of the transaction. Please note that if this promise rejects, it does not automatically hook into New Relic’s error tracking. This needs to be done manually with noticeError(). newrelic.startBackgroundTransaction(name, [group], handle) Instrument the specified background transaction. Using this API call, you can expand New Relic's instrumentation to capture data from background transactions. The name defines the transaction name and needs to be static. Do not include variable data such as user ID. The group is optional, and it allows you to group similar jobs together via the transaction type in the user interface. Like name, the group needs to be static. The handle defines a function that includes the entire background job you want to instrument. New Relic will capture any metrics that would be captured by auto-instrumentation, as well as manual instrumentation via startSegment(). You must handle custom transactions manually by calling newrelic.getTransaction() at the start of your transaction, and then call transaction.end() when you are finished. New Relic begins timing the transaction when newrelic.startBackgroundTransaction() is called and ends the transaction when transaction.end() is called. You can also return a promise to indicate the end of the transaction. Please note that if this promise rejects, it does not automatically hook into New Relic’s error tracking. This needs to be done manually with noticeError(). newrelic.getTransaction() Returns a handle on the currently executing transaction. This handle can then be used to interact with a given transaction safely from any context. It is best used with newrelic.startWebTransaction() and newrelic.startBackgroundTransaction(). Please refer to the transaction handle section for more details. newrelic.endTransaction() End the current web or background custom transaction. This method requires being in the correct transaction context when called. This API call takes no arguments. newrelic.startSegment(name, record, handler, callback) Instrument a particular method to improve visibility into a transaction, or optionally turn it into a metric. The name defines a name for the segment. This name will be visible in transaction traces and as a new metric in the New Relic UI. The record flag defines whether the segment should be recorded as a metric. The handler is the function you want to track as a segment. The optional callback is a function passed to the handler to fire after its work is done. The agent begins timing the segment when startSegment is called. The segment is ended when either the handler finishes executing, or callback is fired, if it is provided. Custom metrics API calls Use these API calls to record additional arbitrary metrics: newrelic.recordMetric(name, value) Use recordMetric to record an event-based metric, usually associated with a particular duration. The name must be a string following standard metric naming rules. The value will usually be a number, but it can also be an object. When value is a numeric value, it should represent the magnitude of a measurement associated with an event; for example, the duration for a particular method call. When value is an object, it must contain count, total, min, max, and sumOfSquares keys, all with number values. This form is useful to aggregate metrics on your own and report them periodically; for example, from a setInterval. These values will be aggregated with any previously collected values for the same metric. The names of these keys match the names of the keys used by the platform API. newrelic.incrementMetric(name, [amount]) Use incrementMetric to update a metric that acts as a simple counter. The count of the selected metric will be incremented by the specified amount, defaulting to 1. Custom events API calls Use these API calls to record additional events: newrelic.recordCustomEvent(eventType, attributes) Use recordCustomEvent to record an event-based metric, usually associated with a particular duration. The eventType must be an alphanumeric string less than 255 characters. The attributes must be an object of key and value pairs. The keys must be shorter than 255 characters, and the values must be string, number, or boolean. Recording a custom event The following example demonstrates recording a custom event with multiple attributes. const attributes = { attribute1: 'value1', attribute2: 2 } newrelic.recordCustomEvent('MessagingEvent', attributes) Transaction handle methods This section details the methods provided by the TransactionHandle class instance that can be obtained through newrelic.getTransaction(). Use these methods to interact directly with the current transaction: transactionHandle.end([callback]) Use transactionHandle.end to end the transaction referenced by the handle instance. The callback is invoked when the transaction has fully ended. The finished transaction passed to the callback as the first argument. transactionHandle.ignore() Use transactionHandle.ignore to ignore the transaction referenced by the handle instance. transactionHandle.insertDistributedTraceHeaders(headers) This API requires distributed tracing to be enabled. For context on how to use this call and its partner call acceptDistributedTraceHeaders, first read Enable distributed tracing with agent APIs. transactionHandle.insertDistributedTraceHeaders is used to implement distributed tracing. It modifies the headers map that is passed in by adding W3C Trace Context headers and New Relic Distributed Trace headers. The New Relic headers can be disabled with distributed_tracing.exclude_newrelic_header: true in the config. This method replaces the deprecated createDistributedTracePayload method, which only creates New Relic Distributed Trace payloads. Generating distributed trace headers In the following example, by calling insertDistributedTraceHeaders with an empty object, the appropriate Distributed Trace headers and W3C Trace Context headers will be generated for the transaction. // Call newrelic.getTransaction to retrieve a handle on the current transaction. const transactionHandle = newrelic.getTransaction() // This could be a header object from an incoming request as well const headersObject = {} newrelic.startBackgroundTransaction('background task', function executeTransaction() { const transaction = newrelic.getTransaction() // generate the headers transaction.insertDistributedTraceHeaders(headersObject) }) transactionHandle.acceptDistributedTraceHeaders(transportType, headers) This API requires distributed tracing to be enabled. For context on how to use this call and its partner call insertDistributedTraceHeaders, first read Enable distributed tracing with agent APIs. transactionHandle.acceptDistributedTraceHeaders is used to instrument the called service for inclusion in a distributed trace. It links the spans in a trace by accepting a payload generated by insertDistributedTraceHeaders or generated by some other W3C Trace Context compliant tracer. This method accepts the headers of an incoming request, looks for W3C Trace Context headers, and if not found, falls back to New Relic distributed trace headers. This method replaces the deprecated acceptDistributedTracePayload method, which only handles New Relic distributed trace payloads. transportType should be one of the following strings: AMQP HTTP HTTPS IronMQ JMS Kafka Other Queue Unknown headers should be an object containing all the headers in the incoming request. The keys must be lowercase. Accept incoming distributed trace headers The following example demonstrates adding distributed trace headers retrieved from a Kafka message. In this example, we assume that the incoming Kafka message has Distributed Trace headers inserted. // incoming Kafka message headers const headersObject = message.headers // Call newrelic.getTransaction to retrieve a handle on the current transaction. const transactionHandle = newrelic.getTransaction() newrelic.startBackgroundTransaction('background task', function executeTransaction() { const transaction = newrelic.getTransaction() // accept the headers transaction.acceptDistributedTraceHeaders('Kafka', headersObject) }) transactionHandle.createDistributedTracePayload() This method is deprecated and will be fully removed in the next major release! Please use insertDistributedTraceHeaders This API requires distributed tracing to be enabled. For instructions on how to use this call, along with its partner call acceptDistributedTracePayload, see Enable distributed tracing with agent APIs. This call is used to implement distributed tracing. It generates a payload that is read by the receiving application with acceptDistributedTracePayload. Note: In order to maintain proper ordering of spans in a trace, you must generate the payload in the context of the span that sends it. The DistributedTracePayload object has two available methods used for generating the payload in different formats: DistributedTracePayload#text: returns a JSON representation of the payload. Link a nested background transaction // Call newrelic.getTransaction to retrieve a handle on the current transaction. var transactionHandle = newrelic.getTransaction() var payload = transactionHandle.createDistributedTracePayload() var jsonPayload = payload.text() newrelic.startBackgroundTransaction('background task', function executeTransaction() { var backgroundHandle = newrelic.getTransaction() // Link the nested transaction by accepting the payload with the background transaction's handle backgroundHandle.acceptDistributedTracePayload(jsonPayload) }) DistributedTracePayload#httpSafe: returns a base64 encoded JSON representation of the payload. Place payload on an outgoing request // Call newrelic.getTransaction to retrieve a handle on the current transaction. var transactionHandle = newrelic.getTransaction() var payload = transactionHandle.createDistributedTracePayload() // Place the base64 encoded value on an outbound request header. req.headers[myTracingHeader] = payload.httpSafe() transactionHandle.acceptDistributedTracePayload(payload) This method is deprecated and will be fully removed in the next major release! Please use acceptDistributedTraceHeaders This API requires distributed tracing to be enabled. For context on how to use this call and its partner call createDistributedTracePayload, first read Enable distributed tracing with agent APIs. transactionHandle.acceptDistributedTracePayload is used to instrument the called service for inclusion in a distributed trace. It links the spans in a trace by accepting the payload generated by createDistributedTracePayload. transactionHandle.isSampled() Returns whether this trace is being sampled. Other API calls New Relic's Node.js agent includes additional API calls. newrelic.addCustomAttribute(name, value) Set a custom attribute value to be displayed along with the transaction trace in the New Relic UI. This must be called within the context of a transaction so it has a place to set the custom attributes. Custom attributes will appear in New Relic APM's transaction trace detail view and in errors for the transaction. Add custom attribute newrelic.addCustomAttribute('attribute1', 'value1') If you want to use your custom attributes, avoid using any of the reserved terms used by NRQL when naming them. newrelic.addCustomAttributes(attributes) Set multiple custom attribute values to be displayed along with the transaction trace in the New Relic UI. The attributes should be passed as a single object. This must be called within the context of a transaction so it has a place to set the custom attributes. Custom attributes will appear in the transaction trace detail view and in errors for the transaction. Adding custom attributes const attributes = { attribute1: 'value1', attribute2: 2 } newrelic.addCustomAttributes(attributes) If you want to use your custom attributes, avoid using any of the reserved terms used by NRQL when naming them. newrelic.addCustomSpanAttribute(name, value) Set a custom span attribute value to be displayed along with a transaction trace span in the New Relic UI. This must be called within the context of an active segment/span so it has a place to set the custom span attributes. Custom span attributes will appear in the Attributes section of the span detail view. Add custom span attribute newrelic.addCustomSpanAttribute('attribute1', 'value') This API requires distributed tracing and span events to be enabled. If you want to use your custom span attributes, avoid using any of the reserved terms used by NRQL when naming them. newrelic.addCustomSpanAttributes(attributes) Set multiple custom span attribute values to be displayed along with the transaction trace spans in the New Relic UI. The attributes should be passed as a single object. This must be called within the context of an active segment/span so it has a place to set the custom span attributes. Custom span attributes will appear in the Attributes section of the span detail view. Add custom span attributes const attributes = { attribute1: 'value1', attribute2: 'value2' } newrelic.addCustomSpanAttributes(attributes) This API requires distributed tracing and span events to be enabled. If you want to use your custom span attributes, avoid using any of the reserved terms used by NRQL when naming them. newrelic.getBrowserTimingHeader() Returns the HTML snippet to be inserted into the header of HTML pages to enable New Relic Browser. The HTML will instruct the browser to fetch a small JavaScript file and start the page timer. newrelic.setIgnoreTransaction(ignored) Tell the module whether or not to ignore a given request. This allows you to explicitly filter long-polling, irrelevant routes or requests you know will be time-consuming. This also allows you to gather metrics for requests that otherwise would be ignored. To ignore the transaction, set the parameter to true will ignore the transaction. To prevent a transaction from being ignored with this function, pass the parameter false. Passing null or undefined will not change whether the transaction is ignored. newrelic.noticeError(error, [customParameters]) Use this call if your app is doing its own error handling with domains or try/catch clauses, but you want all of the information about how many errors are coming out of the app to be centrally managed. Unlike other Node.js calls, this can be used outside of route handlers, but it will have additional context if called from within transaction scope. Errors recorded using this method do not obey the ignore_status_codes configuration value. newrelic.shutdown([options], callback) Use this method to gracefully shut down the agent. options options.collectPendingData - type boolean - Tell the agent whether to send any pending data to the New Relic collector before shutting down. options.timeout - type number (ms) - The default time before forcing a shutdown. When collectPendingData is true, the agent will wait for a connection before shutting down. This timeout is useful for short lived processes, like AWS Lambda, in order to keep the process from staying open too long, while trying to connect. Example: newrelic.shutdown({collectPendingData: true, timeout: 3000}, (error) => { process.exit() }) newrelic.getLinkingMetadata() Returns key/value pairs which can be used to link traces or entities. It will only contain items with meaningful values. For instance, if distributed tracing is disabled, trace.id will not be included. newrelic.getTraceMetadata() Returns and object containing the current trace ID and span ID. This API requires distributed tracing to be enabled or an empty object will be returned. Rules for naming and ignoring requests If you do not want to put calls to the New Relic module directly into your application code, you can use pattern-based rules to name requests. There are two sets of rules: one for renaming requests, and one to mark requests to be ignored by New Relic's instrumentation. Here is the structure for rules in New Relic's Node.js agent. rules.name A list of rules of the format {pattern : \"pattern\", name : \"name\"} for matching incoming request URLs to pattern and naming the matching New Relic transaction's name. This acts as a regex replace, where you can set the pattern either as a string, or as a JavaScript regular expression literal, and both pattern and name are required. When passing a regex as a string, escape backslashes, as the agent does not keep them when given as a string in a pattern. Define your configuration rules from the most specific to the most general, as the patterns will be evaluated in order and are terminal in nature. For more information, see the naming guidelines. This can also be set with the environment variable NEW_RELIC_NAMING_RULES, with multiple rules passed in as a list of comma-delimited JSON object literals: NEW_RELIC_NAMING_RULES='{\"pattern\":\"^t\",\"name\":\"u\"},{\"pattern\":\"^u\",\"name\":\"t\"}' Optional rules attributes Additional optional attributes are available: Optional rules attributes Description terminate_chain Default: true When set to true (default), no further rules will be evaluated if this rule is a match. Setting this to false is useful when multiple rules should be used together. For example, one rule could be replacing a common pattern in many different URLs, while subsequent rule(s) would be more specific. replace_all Default: false When set to true, all matches of the pattern will be replaced. Otherwise, only the first match will be replaced. Using the g flag with regular expression literal will have the same effect. For example: pattern: '[0-9]+', replace_all: true This has the same effect as pattern: /[0-9]+/g. precedence By default the rules are evaluated in order, from first to last. If you prefer to have complete control over the order, you can give each rule a precedence attribute. The precedence is an integer number, and rules are evaluated in ascending order. If precedence is not explicitly defined, it will be set to 500 by default. Additional attributes are ignored. Testing your naming rules The Node.js agent comes with a command-line tool for testing naming rules. For more information, run the following command in terminal window in a directory where your app is installed: node node_modules/.bin/newrelic-naming-rules Naming rule examples Here are some examples of naming rules and the results. Match full URL pattern: \"^/items/[0-9]+$\", name: \"/items/:id\" will result in: /items/123 => /items/:id /orders/123 => /orders/123 (not replaced since the rule is a full match) Replace first match in URL pattern: \"[0-9]+\", name: \":id\" will result in: /orders/123 => /orders/:id /items/123 => /items/:id /orders/123/items/123 => /orders/:id/items/123 Replace all matches in any URL pattern: \"[0-9]+\", name: \":id\", replace_all: true will result in: /orders/123/items/123 => /orders/:id/items/:id Match group references Using regular expression match group references: pattern: '^/(items|orders)/[0-9]+$', name: '/\\\\1/:id' will result in: /orders/123 => /orders/:id /items/123 => /items/:id rules.ignore This can also be set via the environment variable NEW_RELIC_IGNORING_RULES, with multiple rules passed in as a list of comma-delimited patterns. Currently there is no way to escape commas in patterns. NEW_RELIC_IGNORING_RULES='^/socket\\.io/\\*/xhr-polling,ignore_me' Here are full examples of how rules are included in the configuration file: Naming rule example // newrelic.js exports.config = { // other configuration rules : { name : [ { pattern: \"/tables/name-here\", name: \"/name-hererule1\" } ] } Ignoring rule example If you are using socket.io, you will have a use case for ignoring rules right out of the box. To keep socket.io long-polling from dominating your response-time metrics and affecting the Apdex metrics for your application, add a rule such as: // newrelic.js exports.config = { // other configuration rules : { ignore : [ '^\\/socket\\.io\\/.*\\/xhr-polling' ] } }; API calls for rules Here are the API calls for naming and ignoring rules with New Relic's Node.js agent. newrelic.addNamingRule(pattern, name) Programmatic version of rules.name. Once naming rules are added, they cannot be removed until the Node process is restarted. They can also be added via the Node.js agent's configuration. Both parameters are required. newrelic.addIgnoringRule(pattern) Programmatic version of rules.ignore. Once ignoring rules are added, they cannot be removed until the Node process is restarted. They can also be added via the Node.js agent's configuration. This parameter is required. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", - "type": "docs", + "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations, and fetch New Relic or third-party data. Components of the SDK SDK components are located in the Node module package named nr1, which you get when you install the NR1 CLI. The nr1 components can be divided into several categories: UI components Chart components Query and storage components Platform APIs UI components The UI components category of the SDK contains React UI components, including: Text components: These components provide basic font and heading elements. These include HeadingText and BlockText. Layout components: These components give you control over the layout, and help you build complex layout designs without having to deal with the CSS. Layout components include: Grid and GridItem: for organizing more complex, larger scale page content in rows and columns Stack and StackItem: for organizing simpler, smaller scale page content (in column or row) Tabs and TabsItem: group various related pieces of content into separate hideable sections List and ListItem: for providing a basic skeleton of virtualized lists Card, CardHeader and CardBody : used to group similar concepts and tasks together Form components: These components provide the basic building blocks to interact with the UI. These include Button, TextField, Dropdown and DropdownItem, Checkbox, RadioGroup, Radio, and Checkbox. Feedback components: These components are used to provide feedback to users about actions they have taken. These include: Spinnerand Toast. Overlaid components: These components are used to display contextual information and options in the form of an additional child view that appears above other content on screen when an action or event is triggered. They can either require user interaction (like modals), or be augmenting (like a tooltip). These include: Modal and Tooltip. Components suffixed with Item can only operate as direct children of that name without the suffix. For example: GridItem should only be found as a child of Grid. Chart components The Charts category of the SDK contains components representing different types of charts. The ChartGroup component helps a group of related charts share data and be aligned. Some chart components can perform NRQL queries on their own; some accept a customized set of data. Query and storage components The Query components category contains components for fetching and storing New Relic data. The main way to fetch data is with NerdGraph, our GraphQL endpoint. This can be queried using NerdGraphQuery. To simplify use of NerdGraph queries, we provide some components with pre-defined queries. For more on using NerdGraph, see Queries and mutations. We also provide storage for storing small data sets, such as configuration settings data, or user-specific data. For more on this, see NerdStorage. Platform APIs The Platform API components of the SDK enable your application to interact with different parts of the New Relic One platform, by reading and writing state from and to the URL, setting the configuration, etc. They can be divided into these categories: PlatformStateContext: provides read access to the platform URL state variables. Example: timeRange in the time picker. navigation: an object that allows programmatic manipulation of the navigation in New Relic One. Example: opening a new Nerdlet. NerdletStateContext: provides read access to the Nerdlet URL state variables. Example: an entityGuid in the entity explorer. nerdlet: an object that provides write access to the Nerdlet URL state.", + "type": "developer", "document_type": "page", - "breadcrumb": "Contents / APM agents / Node.js agent / API guides", - "info": "How to use the Node.js API to name, rename, and ignore requests, and to read router names with New Relic's Node.js agent.", - "nodeid": 1596, + "info": "Intro to New Relic One API components", "sections": [ - "Node.js agent", - "Getting started", - "Installation and configuration", - "Supported features", - "Attributes", - "API guides", - "Hosting services", - "Troubleshooting", - "Node.js agent API", - "Request names", - "Requirements", - "Avoid metric grouping issues", - "Guidelines", - "Load the request naming API", - "Request API calls", - "Custom instrumentation API calls", - "Custom metrics API calls", - "Custom events API calls", - "Transaction handle methods", - "Other API calls", - "Rules for naming and ignoring requests", - "Optional rules attributes", - "Testing your naming rules", - "Naming rule examples", - "API calls for rules", - "For more help" + "Intro to New Relic One API components", + "Components of the SDK", + "UI components", + "Chart components", + "Query and storage components", + "Platform APIs" ], - "title": "Node.js agent API", + "title": "Intro to New Relic One API components", "popularity": 1, - "external_id": "fb49a4025c716c56046403d960b0802bc7485af2", - "category_1": "Node.js agent", - "category_2": "API guides", + "tags": [ + "SDK components", + "New Relic One apps", + "UI components", + "chart components", + "query and storage components", + "Platform APIs" + ], + "external_id": "3620920c26bcd66c59c810dccb1200931b23b8c2", "image": "", - "url": "https://docs.newrelic.com/docs/agents/nodejs-agent/api-guides/nodejs-agent-api", - "published_at": "2020-08-18T08:18:21Z", - "updated_at": "2020-08-18T08:18:21Z", - "category_0": "APM agents", + "url": "https://developer.newrelic.com/explore-docs/intro-to-sdk/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:47:12Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.10157165, + "_score": 5.8302183, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Node.js agent API", - "sections": "Node.js agent API", - "info": "How to use the Node.js API to name, rename, and ignore requests, and to read router names with New Relic's Node.js agent.", - "category_0": "APM agents", - "category_1": "Node.js agent", - "category_2": "API guides", - "body": " for slow transaction traces and have enabled capture_params in your config file, the transaction trace will also have the request's parameters and their values attached to it. If you are dissatisfied with the request names that the Node.js agent uses, you can use API calls to create more", - "breadcrumb": "Contents / APM agents / Node.js agent / API guides" + "title": "Intro to New Relic One API components", + "sections": "Intro to New Relic One API components", + "info": "Intro to New Relic One API components", + "tags": "SDK components", + "body": " complex layout designs without having to deal with the CSS. Layout components include: Grid and GridItem: for organizing more complex, larger scale page content in rows and columns Stack and StackItem: for organizing simpler, smaller scale page content (in column or row) Tabs and TabsItem: group" }, - "id": "540a92a2c75d073d3d0006f7" - } - ], - "/collect-data/custom-events": [ + "id": "5efa989e28ccbc4071307de5" + }, { - "body": "Collect data from any source 15 min New Relic products report a lot of data “out of the box.” When you use products like APM, Browser, Mobile, Infrastructure monitoring, or an integration, by default you receive performance data. But you may want to bring data into New Relic that isn't collected by default. Maybe you want an API-based solution that doesn't require install of an agent. Maybe you want to bring telemetry data from another analysis service into New Relic. This page describes several ways to get data into New Relic. Step 1 of 6 Agent APIs If you use our APM, Browser, or Mobile agents to report data, you can use their associated APIs to report custom data. For example, if you monitor your application with the our APM Python agent, you can use the Python agent API to set up custom instrumentation. See the agent APIs. Step 2 of 6 Telemetry SDK Our Telemetry SDKs are language wrappers for our Trace API and Metric API (and eventually our Log API and Event API). These SDKs let you easily send metrics and trace data to New Relic without needing to install an agent. For customers, we offer open-source exporters and integrations that use the Telemetry SDKs to send metrics and trace data: Istio adaptor Prometheus OpenMetrics (for Docker | for Kubernetes) OpenCensus exporter (for Go | for Python) DropWizard exporter Micrometer exporter Want to build your own solution? See our Telemetry SDK docs. Step 3 of 6 Trace API Our Trace API lets you send distributed tracing data to New Relic and consolidate tracing data from multiple sources in one place. We accept trace data in two formats: Zipkin format New Relic format (if you don’t have Zipkin-format data, you’d use this) 1 curl -i -X POST https://trace-api.newrelic.com/trace/v1 \\ 2 -H \"Content-Type: application/json\" \\ 3 -H \"Api-Key: $INSIGHTS_INSERT_API_KEY\" \\ 4 -H 'Data-Format: newrelic' \\ 5 -H 'Data-Format-Version: 1' \\ 6 -d '[ 7 { 8 \"common\": { 9 \"attributes\": { 10 \"service.name\": \"Test Service A\", 11 \"host\": \"host123.test.com\" 12 } 13 }, 14 \"spans\": [ 15 { 16 \"trace.id\": \"123456\", 17 \"id\": \"ABC\", 18 \"attributes\": { 19 \"duration.ms\": 12.53, 20 \"name\": \"/home\" 21 } 22 }, 23 { 24 \"trace.id\": \"123456\", 25 \"id\": \"DEF\", 26 \"attributes\": { 27 \"service.name\": \"Test Service A\", 28 \"host\": \"host456.test.com\", 29 \"duration.ms\": 2.97, 30 \"name\": \"/auth\", 31 \"parent.id\": \"ABC\" 32 } 33 } 34 ] 35 } 36 ]' Copy Step 4 of 6 Metric API You can use our Metric API to send metric data to New Relic from any source. 1 curl -i -X POST https://metric-api.newrelic.com/metric/v1 \\ 2 -H \"Content-Type: application/json\" \\ 3 -H \"Api-Key: $INSIGHTS_INSERT_API_KEY\" \\ 4 -d '[ 5 { 6 \"metrics\": [ 7 { 8 \"name\": \"memory.heap\", 9 \"type\": \"gauge\", 10 \"value\": 2.3, 11 \"timestamp\": 1531414060739, 12 \"attributes\": { 13 \"host.name\": \"dev.server.com\" 14 } 15 } 16 ] 17 } 18 ]' Copy Step 5 of 6 Event API For sending arbitrary events to New Relic, you can use our Event API. We save these events as a new event type, which can then be queried via NRQL. (Eventually, the Telemetry SDKs will support the Event API.) 1 curl -i -X POST https://insights-collector.newrelic.com/v1/accounts/$ACCOUNT_ID/events \\ 2 -H \"Content-Type: application/json\" \\ 3 -H \"x-insert-key: $INSIGHTS_INSERT_API_KEY\" \\ 4 -d '[ 5 { 6 \"eventType\": \"LoginEvent\", 7 \"service\": \"login-service\", 8 \"customerId\": \"xyz\" 9 } 10 ]' Copy Step 6 of 6 Log API If our existing logging integrations don’t meet your needs, you can use our Log API to send any arbitrary log data to New Relic. (Eventually, the Telemetry SDKs will support the Log API.) 1 curl -i -X POST https://log-api.newrelic.com/log/v1 \\ 2 -H \"Content-Type: application/json\" \\ 3 -H \"Api-Key: $INSIGHTS_INSERT_API_KEY\" \\ 4 -d '[ 5 \"logs\": [ 6 { 7 \"timestamp\": 1593538496000, 8 \"message\": \"User xyz logged in\", 9 \"service\": \"login-service\", 10 \"hostname\": \"login.example.com\" 11 } 12 ] 13 ]' Copy", + "body": "TableHeaderCell Usage Copy Props There are no props for this component.", "type": "developer", "document_type": "page", - "info": "Open source emitters. APIs. New Relic agents. Get data from anywhere. ", + "info": "A TableHeaderCell component!", "sections": [ - "Collect data from any source", - "Agent APIs", - "Telemetry SDK", - "Trace API", - "Metric API", - "Event API", - "Log API" + "TableHeaderCell", + "Usage", + "Props" ], - "title": "Collect data from any source", + "title": "TableHeaderCell", "popularity": 1, - "tags": [ - "Agent API", - "Telemetry SDK", - "Trace API", - "Metric API", - "Event API" - ], - "external_id": "5bfb043fffe42ea4a78d5a90bf8e92aa8b8f8c33", + "external_id": "2a4be1419d1a6e501a8eed915b8acf7c9798259d", "image": "", - "url": "https://developer.newrelic.com/collect-data/collect-data-from-any-source/", - "published_at": "2020-08-18T02:04:53Z", - "updated_at": "2020-08-14T01:45:09Z", + "url": "https://developer.newrelic.com/components/table-header-cell/", + "published_at": "2020-08-19T01:49:37Z", + "updated_at": "2020-08-03T04:46:36Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 8.521867, + "_score": 3.67105, "_version": null, "_explanation": null, "sort": null, "highlight": { - "sections": "Agent APIs", - "info": "Open source emitters. APIs. New Relic agents. Get data from anywhere. ", - "tags": "Agent API", - "body": " agents to report data, you can use their associated APIs to report custom data. For example, if you monitor your application with the our APM Python agent, you can use the Python agent API to set up custom instrumentation. See the agent APIs. Step 2 of 6 Telemetry SDK Our Telemetry SDKs are language" + "title": "TableHeaderCell", + "sections": "TableHeaderCell", + "info": "A TableHeaderCell component!", + "body": "TableHeaderCell Usage Copy Props There are no props for this component." }, - "id": "5efa997128ccbc3c9a307dfd" + "id": "5efa9906196a67523e76646e" }, { - "body": "New Relic products report a variety of default event data to your account. This document will explain how to report your own custom events and attributes. Overview of reporting custom events and attributes Event data is one of the fundamental New Relic data types. Events are reported by most New Relic products, and we give you several options for reporting your own custom events. Reporting custom events allows you to create more useful and customized queries and charts of your data, and is a key part of optimizing how New Relic works for you. Before beginning, it's important to know that reporting a large number of custom events and/or attributes can cause degraded query performance, or cause you to approach or pass data collection rate limits. For optimal performance, first think about what data you want to analyze, and then create only the events and/or attributes necessary to meet these specific goals. Be aware of the following data and subscription requirements for inserting and accessing custom data: Ensure you follow limits and requirements around event/attribute data types, naming syntax, and size. The amount of data you have access to over time depends on your data retention policy. Send custom events and attributes Methods for sending custom events and attributes include: Source How to send custom data APM agent Use APM agent APIs to report custom events and custom attributes. Browser agent Add custom attributes to the PageView event via the Browser API call addCustomAttribute. Send PageAction event and attributes via Browser API. Forward APM agent custom attributes to PageView event. Event API To report custom events not associated with other New Relic products, use the Event API. Infrastructure Add custom attributes to default Infrastructure events. Use the Flex integration tool to report your own custom event data. Mobile agent Use the mobile agent API to send custom events and attributes. Synthetics Add custom attributes to the SyntheticCheck event via the $util.insights tools. For ways to report other types of custom data, see: Metric API Logs Trace API Extend data retention To learn about how to extend how long events are retained in your account, see Event data retention. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", - "type": "docs", + "body": "TableRow Usage Copy Props There are no props for this component.", + "type": "developer", "document_type": "page", - "breadcrumb": "Contents / Insights / Event data sources / Custom events", - "info": "An overview of the options for sending custom event data to New Relic. ", - "nodeid": 13806, + "info": "A TableRow component!", "sections": [ - "Event data sources", - "Default events", - "Custom events", - "Report custom event data", - "Overview of reporting custom events and attributes", - "Send custom events and attributes", - "Extend data retention", - "For more help" + "TableRow", + "Usage", + "Props" ], - "title": "Report custom event data", + "title": "TableRow", "popularity": 1, - "external_id": "afb5f5a81ae06b22935d98c470ed9cabd7c9da6b", - "category_1": "Event data sources", - "category_2": "Custom events", + "external_id": "b9ca0d4e07a506dd961eb2194c5344bfa9ab770d", "image": "", - "url": "https://docs.newrelic.com/docs/insights/insights-data-sources/custom-data/report-custom-event-data", - "published_at": "2020-08-18T07:15:53Z", - "updated_at": "2020-07-26T05:52:23Z", - "category_0": "Insights", + "url": "https://developer.newrelic.com/components/table-row/", + "published_at": "2020-08-19T01:49:36Z", + "updated_at": "2020-08-03T04:45:42Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.5126784, + "_score": 3.650105, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Report custom event data", - "sections": "Custom events", - "info": "An overview of the options for sending custom event data to New Relic. ", - "category_1": "Event data sources", - "category_2": "Custom events", - "body": " retention policy. Send custom events and attributes Methods for sending custom events and attributes include: Source How to send custom data APM agent Use APM agent APIs to report custom events and custom attributes. Browser agent Add custom attributes to the PageView event via the Browser API call", - "breadcrumb": "Contents / Insights / Event data sources / Custom events" + "title": "TableRow", + "sections": "TableRow", + "info": "A TableRow component!", + "body": "TableRow Usage Copy Props There are no props for this component." }, - "id": "5e8e7f9de7b9d2aa122cf0f6" + "id": "5efa98d564441f93435f7e24" }, { - "body": "Custom events are useful to explore data for a single event you are interested in, including data from external sources, at a particular moment in time. To track arbitrary event data for apps monitored by your New Relic Go agent, add RecordCustomEvent to the apps. You can then query and visualize the event data. RecordCustomEvent parameters To add RecordCustomEvent to your Go app, use this format: RecordCustomEvent(eventType string, params map[string]interface{}) Parameter Description eventType string Required. The name of the event type to record. Must consist of alphanumeric characters, underscores _, or colons :. Must contain no more than 255 bytes. Must follow New Relic Insights data requirements for names, limits, and restricted characters. params map number, string, or boolean Required. Specify key/value pairs of attributes to annotate the event. Each value in the params map must be a number, string, or boolean. Keys must be less than 255 bytes. The params map must not contain more than 64 attributes. Example Here is an example of a custom event for a Go app: func customEvent(w http.ResponseWriter, r *http.Request) { io.WriteString(w, \"recording a custom event\") app.RecordCustomEvent(\"my_event_type\", map[string]interface{}{ \"myString\": \"hello\", \"myFloat\": 0.603, \"myInt\": 123, \"myBool\": true, }) } For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", - "type": "docs", + "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build your own application launcher and follow the quick start instructions. The quick start automatically generates an API key for the account you select, and gives you the pre-populated commands to create a profile, generate your first \"Hello World\" app, and serve it locally. Tip Use the NR1 VS Code extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions. For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). Configure your CLI preferences nr1 config:set Sets a specific configuration value. nr1 config:get Shows a specific configuration. nr1 config:list Lists your configuration choices. nr1 config:delete Removes the value of a specific configuration. Set up your Nerdpacks nr1 nerdpack:clone Clones an open source Nerdpack from our GitHub repository. nr1 nerdpack:serve Serves your Nerdpack for testing and development purposes. nr1 nerdpack:uuid Shows or regenerates the UUID of a Nerdpack. nr1 nerdpack:publish Publishes your Nerdpack to New Relic. nr1 nerdpack:deploy Deploys a Nerdpack version to a specific channel. nr1 nerdpack:undeploy Undeploys a Nerdpack version from a specific channel. Manage your Nerdpack subscriptions nr1 subscription:set Subscribes your account to a Nerdpack and channel. nr1 subscription:list Lists all the Nerdpacks your account is subscribed to. nr1 subscription:unset Unsubscribes your account from a Nerdpack. Install and manage plugins nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin into the CLI for development. nr1 plugins:update Updates your installed plugins. nr1 plugins:uninstall Removes a plugin from the CLI. Manage catalog information nr1 catalog:info Shows the Nerdpack info stored in the catalog. nr1 catalog:submit Gathers and submits the catalog info on the current folder.", + "type": "developer", "document_type": "page", - "breadcrumb": "Contents / APM agents / Go agent / Features", - "info": "To track arbitrary event data in New Relic Insights for apps monitored by your New Relic Go agent, use RecordCustomEvent.", - "nodeid": 13766, + "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", "sections": [ - "Go agent", + "New Relic One CLI reference", + "Installing the New Relic One CLI", + "Tip", + "New Relic One CLI Commands", "Get started", - "Installation", - "Configuration", - "Instrumentation", - "API guides", - "Features", - "Troubleshooting", - "Create custom events (Go)", - "RecordCustomEvent parameters", - "Example", - "For more help" + "Configure your CLI preferences", + "Set up your Nerdpacks", + "Manage your Nerdpack subscriptions", + "Install and manage plugins", + "Manage catalog information" ], - "title": "Create custom events (Go)", + "title": "New Relic One CLI reference", "popularity": 1, - "external_id": "b4d19e4ff9eee2b00a40c4add7119820a5f4d3dc", - "category_1": "Go agent", - "category_2": "Features", - "image": "", - "url": "https://docs.newrelic.com/docs/agents/go-agent/features/create-custom-events-go", - "published_at": "2020-08-18T03:19:16Z", - "updated_at": "2020-08-15T02:23:50Z", - "category_0": "APM agents", - "_index": "520d1d5d14cc8a32e600034b", - "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.47695023, - "_version": null, - "_explanation": null, - "sort": null, - "highlight": { - "title": "Create custom events (Go)", - "sections": "Create custom events (Go)", - "info": "To track arbitrary event data in New Relic Insights for apps monitored by your New Relic Go agent, use RecordCustomEvent.", - "category_0": "APM agents", - "category_1": "Go agent", - "body": "Custom events are useful to explore data for a single event you are interested in, including data from external sources, at a particular moment in time. To track arbitrary event data for apps monitored by your New Relic Go agent, add RecordCustomEvent to the apps. You can then query and visualize", - "breadcrumb": "Contents / APM agents / Go agent / Features" - }, - "id": "5f374736e7b9d2653b909280" - }, - { - "body": "NewRelic.Api.Agent.NewRelic.RecordCustomEvent(string eventType, IEnumerable attributeValues) Records a custom event with the given name and attributes. Requirements Agent version 4.6.29.0 or higher. Compatible with all app types. Description Records a custom event with the given name and attributes, which you can query in the query builder. To verify if an event is being recorded correctly, look for the data in dashboards. For related API calls, see the .NET agent API guide. Sending a lot of events can increase the memory overhead of the agent. Additionally, posts greater than 1MB in size will not be recorded regardless of the maximum number of events. Custom Events are limited to 64-attributes. For more information about how custom attribute values are processed, see the custom attributes guide. Parameters Parameter Description eventType string Required. The name of the event type to record. Strings over 255 characters will result in the API call not being sent to New Relic. The name can only contain alphanumeric characters, underscores _, and colons :. For additional restrictions on event type names, see Reserved words. attributeValues IEnumerable Required. Specify key/value pairs of attributes to annotate the event. Example(s) Record values var eventAttributes = new Dictionary() {   {\"foo\", \"bar\"},   {\"alice\", \"bob\"},   {\"age\", 32},   {\"height\",21.3f} }; NewRelic.Api.Agent.NewRelic.RecordCustomEvent(\"MyCustomEvent\", eventAttributes);", - "type": "docs", - "document_type": "api_doc", - "breadcrumb": "Contents » APM agents / .NET agent / .NET agent API", - "info": "New Relic .NET agent API call to report custom event data to New Relic.", - "nodeid": 11631, - "sections": [ - ".NET agent", - "Getting started", - "Install", - "Azure installation", - "Other installation", - "Configuration", - "Other features", - "Custom instrumentation", - "API guides", - ".NET agent API", - "Attributes", - "Troubleshooting", - "Azure troubleshooting", - "RecordCustomEvent", - "Requirements", - "Description", - "Parameters", - "Example(s)", - "Record values", - "For more help" + "tags": [ + "New Relic One app", + "nerdpack commands" ], - "title": "RecordCustomEvent (.NET agent API)", - "popularity": 1, - "external_id": "2a0a0d5ed597c962d9c7c2b02d2ae40380ec6d3d", - "category_1": ".NET agent", - "category_2": ".NET agent API", - "image": "", - "url": "https://docs.newrelic.com/docs/agents/net-agent/net-agent-api/recordcustomevent-net-agent-api", - "published_at": "2020-08-18T16:02:14Z", - "updated_at": "2020-08-18T16:02:14Z", - "category_0": "APM agents", + "external_id": "858339a44ead21c83257778ce60b4c352cd30d3b", + "image": "https://developer.newrelic.com/static/2c6d337608b38a3312b4fc740afe6167/7272b/developercenter.png", + "url": "https://developer.newrelic.com/explore-docs/nr1-cli/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-18T01:50:36Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.42349094, + "_score": 2.5931602, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "RecordCustomEvent (.NET agent API)", - "sections": ".NET agent API", - "info": "New Relic .NET agent API call to report custom event data to New Relic.", - "category_0": "APM agents", - "category_1": ".NET agent", - "category_2": ".NET agent API", - "body": "NewRelic.Api.Agent.NewRelic.RecordCustomEvent(string eventType, IEnumerable<string, object> attributeValues) Records a custom event with the given name and attributes. Requirements Agent version 4.6.29.0 or higher. Compatible with all app types. Description Records a custom event with the given", - "breadcrumb": "Contents » APM agents / .NET agent / .NET agent API" + "title": "New Relic One CLI reference", + "sections": "Installing the New Relic One CLI", + "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", + "tags": "New Relic One app", + "body": ". For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet" }, - "id": "5f3bfb86196a674f83618a39" - }, + "id": "5efa989e28ccbc535a307dd0" + } + ], + "/automate-workflows/get-started-kubernetes": [ { - "body": "The New Relic Event API is one way to report custom events to New Relic. The Event API lets you send custom event data to your New Relic account with a POST command. These events are then queryable and chartable using NRQL. If your account hosts data in the EU data center, ensure you are using the proper API endpoints for EU region accounts. Related content: Learn about all options for reporting custom events. For details about how event data is retained, see Event data retention. For how to add attributes to existing events, see Add custom attributes. Check out New Relic University’s tutorial Adding custom events with the Event API (aka the Insights API). Or, go directly to the full online course Custom data. Basic workflow The Event API is an asynchronous endpoint. This allows you to send a very large volume of POSTS, reliably, with very low response latency. To send a custom event to your New Relic account: Register an Insert API key. Before creating custom events or attributes, review New Relic's list of reserved terms used by NRQL. Generate JSON for the event by instrumenting your application, querying an API, or some other method. Submit a compressed JSON payload (for example, gzip or deflate) to the HTTPS endpoint using curl in a POST request. Recommendation: Set up NRQL alert conditions to notify you when parsing errors occur. This method will send the events directly into your account, where they will be accessible from any NRQL interface or with the Query API. The Event API limits the size, rate, and characters allowed in custom events. Also, like other events available in NRQL, custom events cannot be updated or deleted after they are created. If you have problems with your custom event, follow the troubleshooting procedures or create a new custom event. Register an Insert API key You must have the correct user permissions to register Insert API keys. Insert API keys are generated for an account. They aren't associated with a specific user. Anyone in the account with access to the Insert API key can use it. You submit multiple event types under a single Insert API key. However, to help ensure security, we recommend that you use different keys for different applications or data sources. To register an Insert API key: From one.newrelic.com, click the account dropdown and then click Account settings. Click API keys. On the next page, click Insights API keys. Next to the Insert keys heading, select the plus symbol and follow the instructions. The Insert key page lists the curl command necessary to add event data for the key. For security reasons, the Insert API key cannot be altered or read using the API. To change or read a key, use the New Relic UI. Format the JSON The Event API accepts specific formats for attributes included in the payload. Only float or string values are allowed. JSON format guidelines When defining attributes for your custom events, follow these JSON format guidelines. Attributes JSON format guidelines eventType Required: The event's name. Float and string values Float value format: \"label\":value String value format: \"label\":\"value\" Data types The API only accepts key-value pairs, not map/object or array values. Supported data types for this API are strings and numbers (integers or floats). For more information, see Data requirements. Digits in strings For performance-related reasons, we do not cast values submitted to the API. For example, we treat 123 as a number and \"123\" as a string. The database will only store up to 64 bit numbers. Any numbers larger than 64 bits will be truncated. Dates For attributes that contain date information, use an unformatted Unix timestamp in the Insights data formatter. You can define the date attribute either in seconds or in milliseconds, both relative to the Unix epoch. Time Unless otherwise specified, the timestamp for a submitted event is the time it was submitted to New Relic. To specify a different time for the event, use the timestamp attribute. The timestamp must be a 64-bit integer within 24 hours of the time the event is submitted to New Relic. JSON example Here is an example of a typical JSON data set for sending with the API. This call sends two Purchase type events as a JSON array. You can add multiple events in a single HTTP call using a JSON array. [ { \"eventType\":\"Purchase\", \"account\":3, \"amount\":259.54 }, { \"eventType\":\"Purchase\", \"account\":5, \"amount\":12309, \"product\":\"Item\" } ] When generating the JSON, make sure your attributes are properly formatted. Limits and restricted characters The following size and rate limits apply to events sent to the Event API: Payload total size: 1MB maximum per POST. We highly recommend using compression. Number of attributes per event: 255 maximum Length of attribute name: 255 characters Length of attribute value: 4096 maximum character length There are rate limits on the number of HTTP requests per minute sent to the Event API. Some specific attributes have additional restrictions: accountId: This is a reserved attribute name. If it is included, it will be dropped during ingest. appId: Value must be an integer. If it is not an integer, the attribute name and value will be dropped during ingest. eventType: Can be a combination of alphanumeric characters, _ underscores, and : colons. timestamp: Must be a Unix epoch timestamp. You can define timestamps either in seconds or in milliseconds. Submit the custom event Data submitted to the Event API uses a compressed JSON format in a simple HTTPS POST request. The Insert key page in the Insights UI automatically generates a sample curl query for you to use as a template. This example uses gzip, but you can also use deflate. Linux/bash example gzip -c example_events.json | curl -X POST -H \"Content-Type: application/json\" -H \"X-Insert-Key: YOUR_KEY_HERE\" -H \"Content-Encoding: gzip\" https://insights-collector.newrelic.com/v1/accounts/YOUR_ACCOUNT_ID/events --data-binary @- Windows/PowerShell example $accountId = \"YOUR_ACCOUNT_ID\" $insertkey = \"YOUR_KEY_HERE\" # Replace with your custom event for the body $body = '[{\"eventType\": \"powershell\", \"account\": 4, \"amount\": 123, \"fileLocation\": \"c:\\\\temp2\", \"zipped\": \"true\" }]' $headers = @{} $headers.Add(\"X-Insert-Key\", \"$insertkey\") $headers.Add(\"Content-Encoding\", \"gzip\") $encoding = [System.Text.Encoding]::UTF8 $enc_data = $encoding.GetBytes($body) $output = [System.IO.MemoryStream]::new() $gzipStream = New-Object System.IO.Compression.GzipStream $output, ([IO.Compression.CompressionMode]::Compress) $gzipStream.Write($enc_data, 0, $enc_data.Length) $gzipStream.Close() $gzipBody = $output.ToArray() Invoke-WebRequest -Headers $headers -Method Post -Body $gzipBody \"https://insights-collector.newrelic.com/v1/accounts/$accountId/events\" Always use compression with every payload. This allows you to send more data, and it saves resources during parsing. Before generating your HTTP request, make sure it is properly formatted, including: The X-Insert-Key contains the correct Insert API key. The Content-Type is application/json. The request uses POST only. The API does not accept PUT and GET requests. The API supports HTTP/1.1 persistent connections. This is helpful to manage client-side performance under heavy event loads. Verify or troubleshoot request response The Event API follows a two-step process to process requests: The Event API synchronously acknowledges or rejects the request based on validation of the headers and payload size. The Event API asynchronously parses the payload after a successful HTTP response is provided to the client. This may generate an error due to missing or malformed data. These are classified as submission errors or parsing errors. All successful submissions receive a 200 response, regardless of any data errors that may exist within the payload. The response includes a uuid, which is a unique ID created for each request. The uuid also appears in any error events created for the request. Other potential issues: 10-second timeout: API calls exceeding 10 seconds will time out. Large payloads: Payloads exceeding 100 KB may see increased response times. Recommendation: In addition to checking for a success message, use the Insights data explorer to ensure your events are reporting correctly and to generate queries. Success response code Success message Comments 200 {\"success\":true,\"uuid\":\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"} Submission errors Payloads with submission errors are handled and returned to the sender through an HTTP response code. To troubleshoot payload submission errors, refer to these HTTP response codes. Submission errors Troubleshooting 400 Missing or invalid content length: Unable to process empty request. 403 Missing or invalid API key: Invalid Insert key, or the account does not have access to Insights. Register a valid Insert key. 408 Request timed out: Request took too long to process. 413 Content too large: Request is too large to process. Refer to the limits and restricted characters to troubleshoot. 415 Invalid content type: Must be application/JSON. The Event API accepts any content type except multi-part/related and assumes it can be parsed to JSON. 429 Too many requests due to rate limiting. 503 Service temporarily unavailable: Retry request Parsing errors Parsing errors occur if: An event is sent within a payload, but it is either missing data or is exceeding maximum limits. New Relic will drop the individual event from the payload, generate an NrIntegrationError event, and process the rest. The JSON payload includes malformed JSON or missing required data. Payloads with parsing errors receive a 200 response to indicate a successful submission. To help resolve parsing errors, a new NrIntegrationError event type is created. All parsing errors are due to NRQL queries. For error messages related to dropped events, New Relic will include the number of events that were dropped as part of the message. To troubleshoot requests with parsing errors, refer to these error messages. Parsing errors Troubleshooting X event(s) rejected because attribute appId was not an integer An appId attribute has a non-integer value, such as a decimal value or string. X event(s) rejected because eventType cannot contain the following characters: [., \\] An eventType attributed included an invalid character, such as a period or backslash. X event(s) rejected because attribute is missing attribute name An attribute name was set to null or an empty string. X event(s) rejected because attribute name exceeded maximum length An attribute name has more than 255 characters. X event(s) rejected because attribute value exceeded maximum length An attribute value was longer than 4096 characters. X event(s) rejected because event exceeded maximum number of attributes An event has more than 255 attributes. X event(s) rejected because missing required attributes eventType The eventType attribute is required for the custom event. Error parsing JSON payload There was an error parsing the request JSON because of formatting problems or corrupted data. Query and alert with NrIntegrationError The NrIntegrationError event allows you to query and set alerts on custom data being sent to your New Relic account. Recommendation: To have New Relic Alerts notify you about parsing errors, create a NRQL condition for NrIntegrationError. Use this example NRQL query: SELECT message FROM NrIntegrationError WHERE newRelicFeature = 'Event API' AND category = 'EventApiException' NrIntegrationError attributes Troubleshooting timestamp The timestamp when the request was received. The timestamp attribute takes an unformatted Unix timestamp. You can define timestamps either in seconds or in milliseconds, both relative to the Unix epoch. Do not use a decimal for the timestamp. If a decimal is used, the attribute will default to the timestamp when the custom event was created. newRelicFeature The name of the feature experiencing errors. For all custom event parsing errors, this will be Event API. apiKeyPrefix The first six characters of the Insert API key used for the request that generated an error. requestId The uuid returned by the the API for the request that generated an error. Category The category of the error. For custom events, this is EventApiException. Message Contents of the error message. Name The error's name. For custom events, this is always EventValidationException. eventTypeSample One of the event types that generated the error, when available. Find your data To find data sent via the Event API (and from integrations that use this API), you can query it. For example, to query a custom event using NRQL, you would run: SELECT * FROM YOUR_CUSTOM_EVENT For more on how to query, see Query data. Limit on HTTP requests The Event API has a rate limit of 100,000 HTTP requests (POSTs) per minute, per account. (Note that this is not a limit on the number of events per minute; only on the number of POSTs per minute.) This limit helps ensure that large traffic spikes in accounts across our multi-tenant platform do not negatively affect how the service performs for you. If your API usage exceeds 100k POSTs in a 1-minute window, we will reject subsequent API requests with a 429 response code for the remainder of the 1-minute window. At the end of the 1-minute window, the counter will be reset and allow traffic to resume. This limit is intended to be an upper threshold that you shouldn't hit under normal scenarios. If you have a high number of 429 responses, consider using the API less. If you are expecting a higher-than-normal activity level in the near future and want to prepare for that, contact technical support. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "body": "You can create alert conditions using NRQL queries. Create NRQL alert condition To create a NRQL condition: When you start to create a condition, where it prompts you to Select a product, click NRQL. Tips on creating a NRQL condition: NRQL conditions Tips Condition types NRQL condition types include static, baseline, and outlier. Create a description For some condition types, you can create a Description. Query results Queries must return a number. The condition works by evaluating that returned number against the thresholds you set. Time period As with all alert conditions, NRQL conditions evaluate one single minute at a time. The implicit SINCE ... UNTIL clause specifying which minute to evaluate is controlled by your Evaluation offset setting. Since very recent data may be incomplete, you may want to query data from 3 minutes ago or longer, especially for: Applications that run on multiple hosts. SyntheticCheck data: Timeouts can take 3 minutes, so 5 minutes or more is recommended. Also, if a query will generate intermittent data, consider using the sum of query results option. Condition settings Use the Condition settings to: Configure whether and how open violations are force-closed. Adjust the evaluation offset. Create a concise and descriptive condition name. (NerdGraph API Only) Provide a text description for the condition that will be included in violations and notifications. Troubleshooting procedures Optional: To include your organization's procedures for handling the incident, add the runbook URL to the condition. Limits on conditions See the maximum values. Examples For more information, see: Expected NRQL syntax Examples of NRQL condition queries Alert threshold types When you create a NRQL alert, you can choose from different types of thresholds: NRQL alert threshold types Description Static This is the simplest type of NRQL threshold. It allows you to create a condition based on a NRQL query that returns a numeric value. Optional: Include a FACET clause. Baseline Uses a self-adjusting condition based on the past behavior of the monitored values. Uses the same NRQL query form as the static type, except you cannot use a FACET clause. Outlier Looks for group behavior and values that are outliers from those groups. Uses the same NRQL query form as the static type, but requires a FACET clause. NRQL alert syntax Here is the basic syntax for creating all NRQL alert conditions. Depending on the threshold type, also include a FACET clause as applicable. SELECT function(attribute) FROM Event WHERE attribute [comparison] [AND|OR ...] Clause Notes SELECT function(attribute) Required Supported functions that return numbers include: apdex average count latest max min percentage percentile sum uniqueCount If you use the percentile aggregator in a faceted alert condition with many facets, this may cause the following error to appear: An error occurred while fetching chart data. If you see this error, use average instead. FROM data type Required Only one data type can be targeted. Supported data types: Event Metric (RAW data points will be returned) WHERE attribute [comparison] [AND|OR ...] Optional Use the WHERE clause to specify a series of one or more conditions. All the operators are supported. FACET attribute Static: Optional Baseline: Not allowed Outlier: Required Including a FACET clause in your NRQL syntax depends on the threshold type: static, baseline, or outlier. Use the FACET clause to separate your results by attribute and alert on each attribute independently. Faceted queries can return a maximum of 5000 values for static conditions and a maximum of 500 values for outlier conditions. If the query returns more than this number of values, the alert condition cannot be created. If you create the condition and the query returns more than this number later, the alert will fail. Sum of query results (limited or intermittent data) Available only for static (basic) threshold types. If a query returns intermittent or limited data, it may be difficult to set a meaningful threshold. Missing or limited data will sometimes generate false positives or false negatives. To avoid this problem when using the static threshold type, you can set the selector to sum of query results. This lets you set the alert on an aggregated sum instead of a value from a single harvest cycle. Up to two hours of the one-minute data checks can be aggregated. The duration you select determines the width of the rolling sum, and the preview chart will update accordingly. Offset the query time window Every minute, we evaluate the NRQL query in one-minute time windows. The start time depends on the value you select in the NRQL condition's Advanced settings > Evaluation offset. Example: Using the default time window to evaluate violations With the Evaluation offset at the default setting of three minutes, the NRQL time window applied to your query will be: SINCE 3 minutes ago UNTIL 2 minutes ago If the event type is sourced from an APM language agent and aggregated from many app instances (for example, Transactions, TransactionErrors, etc.), we recommend evaluating data from three minutes ago or longer. An offset of less than 3 minutes will trigger violations sooner, but you might see more false positives and negatives due to data latency. For cloud data, such as AWS integrations, you may need an offset longer than 3 minutes. Check our AWS polling intervals documentation to determine your best setting. NRQL alert threshold examples Here are some common use cases for NRQL alert conditions. These queries will work for static and baseline threshold types. The outlier threshold type will require additional FACET clauses. Alert on specific segments of your data Create constrained alerts that target a specific segment of your data, such as a few key customers or a range of data. Use the WHERE clause to define those conditions. SELECT average(duration) FROM Transaction WHERE account_id in (91290, 102021, 20230) SELECT percentile(duration, 95) FROM Transaction WHERE name LIKE 'Controller/checkout/%' Alert on Nth percentile of your data Create alerts when an Nth percentile of your data hits a specified threshold; for example, maintaining SLA service levels. Since we evaluate the NRQL query in one-minute time windows, percentiles will be calculated for each minute separately. SELECT percentile(duration, 95) FROM Transaction SELECT percentile(databaseDuration, 75) FROM Transaction Alert on max, min, avg of your data Create alerts when your data hits a certain maximum, minimum, or average; for example, ensuring that a duration or response time does not pass a certain threshold. SELECT max(duration) FROM Transaction SELECT average(duration) FROM Transaction Alert on a percentage of your data Create alerts when a proportion of your data goes above or below a certain threshold. SELECT percentage(count(*), WHERE duration > 2) FROM Transaction SELECT percentage(count(*), WHERE httpResponseCode = '500') FROM Transaction Alert on Apdex with any T-value Create alerts on Apdex, applying your own T-value for certain transactions. For example, get an alert notification when your Apdex for a T-value of 500ms on transactions for production apps goes below 0.8. SELECT apdex(duration, t:0.5) FROM Transaction WHERE appName like '%prod%' Create a description You can define a description that passes useful information downstream for better violation responses or for use by downstream systems. For details, see Description. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", "type": "docs", "document_type": "page", - "breadcrumb": "Contents / Telemetry Data Platform / Ingest and manage data / Ingest APIs", - "info": "Intro to New Relic's Event API, which lets you send custom event data to your New Relic account. ", - "nodeid": 17376, + "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / Alert conditions", + "info": "How to define thresholds that trigger alert notifications based on your NRQL queries.", + "nodeid": 9231, "sections": [ - "Ingest and manage data", + "New Relic Alerts", "Get started", - "Understand data", - "Manage data", - "Ingest APIs", - "Use the Event API to report custom events", - "Basic workflow", - "Register an Insert API key", - "Format the JSON", - "Submit the custom event", - "Verify or troubleshoot request response", - "Query and alert with NrIntegrationError", - "Find your data", - "Limit on HTTP requests", + "Alert policies", + "Alert conditions", + "Alert violations", + "Alert Incidents", + "Alert notifications", + "Troubleshooting", + "Rules, limits, and glossary", + "Alerts and Nerdgraph", + "REST API alerts", + "Create NRQL alert conditions", + "Create NRQL alert condition", + "Alert threshold types", + "NRQL alert syntax", + "Sum of query results (limited or intermittent data)", + "Offset the query time window", + "NRQL alert threshold examples", + "Create a description", "For more help" ], - "title": "Use the Event API to report custom events", - "translation_ja_url": "https://docs.newrelic.co.jp/docs/telemetry-data-platform/ingest-manage-data/ingest-apis/use-event-api-report-custom-events", + "title": "Create NRQL alert conditions", + "translation_ja_url": "https://docs.newrelic.co.jp/docs/alerts-applied-intelligence/new-relic-alerts/alert-conditions/create-nrql-alert-conditions", "popularity": 1, - "external_id": "589a1cbf9b6b64be620689b3af3cbadff0c67da2", - "category_1": "Ingest and manage data", - "category_2": "Ingest APIs", + "external_id": "956a7a0b84d2afac5e6236df3143085ebc4f7459", + "category_1": "New Relic Alerts", + "category_2": "Alert conditions", "image": "", - "url": "https://docs.newrelic.com/docs/telemetry-data-platform/ingest-manage-data/ingest-apis/use-event-api-report-custom-events", - "published_at": "2020-08-18T14:06:57Z", - "updated_at": "2020-08-15T09:07:03Z", - "category_0": "Telemetry Data Platform", + "url": "https://docs.newrelic.com/docs/alerts-applied-intelligence/new-relic-alerts/alert-conditions/create-nrql-alert-conditions", + "published_at": "2020-08-18T21:58:59Z", + "updated_at": "2020-08-15T23:05:02Z", + "category_0": "Alerts and Applied intelligence", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.39592767, + "_score": 0.3638357, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Use the Event API to report custom events", - "sections": "Use the Event API to report custom events", - "info": "Intro to New Relic's Event API, which lets you send custom event data to your New Relic account. ", - "category_2": "Ingest APIs", - "translation_ja_url": "https://docs.newrelic.co.jp/docs/telemetry-data-platform/ingest-manage-data/ingest-apis/use-event-api-report-custom-events", - "body": "The New Relic Event API is one way to report custom events to New Relic. The Event API lets you send custom event data to your New Relic account with a POST command. These events are then queryable and chartable using NRQL. If your account hosts data in the EU data center, ensure you are using", - "breadcrumb": "Contents / Telemetry Data Platform / Ingest and manage data / Ingest APIs" + "title": "Create NRQL alert conditions", + "sections": "Create NRQL alert conditions", + "info": "How to define thresholds that trigger alert notifications based on your NRQL queries.", + "category_0": "Alerts and Applied intelligence", + "category_1": "New Relic Alerts", + "category_2": "Alert conditions", + "translation_ja_url": "https://docs.newrelic.co.jp/docs/alerts-applied-intelligence/new-relic-alerts/alert-conditions/create-nrql-alert-conditions", + "body": "You can create alert conditions using NRQL queries. Create NRQL alert condition To create a NRQL condition: When you start to create a condition, where it prompts you to Select a product, click NRQL. Tips on creating a NRQL condition: NRQL conditions Tips Condition types NRQL condition types", + "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / Alert conditions" }, - "id": "5f37a5b7196a6743a355e613" - } - ], - "/automate-workflows/get-started-terraform": [ + "id": "5f2d992528ccbc489d88dfc1" + }, { - "body": "In order to provide a unified experience, we're deprecating Synthetics monitor alert notifications and alert conditions violations, and replacing these pages with a new synthetic monitor overview experience in New Relic One. This new experience provides visibility into a monitor's open violations and alert conditions with the monitor results in a single view, removing the need to open multiple tabs to view violations or alert conditions. For more information, check the EoL Announcements page. If you want to receive alert notifications when a synthetic monitor fails, you can configure the alert notification either while creating a monitor or after you have created one. You can configure your monitor's alert policy directly from the Synthetics UI or via the Alerts UI for existing monitors. To identify which monitors do not have policies assigned to them, review their color-coded health status. Add a synthetic monitor to alert policies A monitor can be included in multiple alert policies. You can view the alert policies and conditions for the selected monitor from the Synthetics UI or from the Alerts UI. To add an existing monitor to an alert policy: Go to one.newrelic.com > Alerts & AI > Policies. From the list of existing alert policies, use the search box or scroll the list to locate one or more alert policies where the monitor has not already been added. Open the policy, then click Add a condition. Click Synthetics and then select the monitor. Fill out the remaining settings and click Create condition. Existing monitor: Remove from alert policy To remove an existing monitor from an existing alert policy: Go to one.newrelic.com > Alerts & AI > Policies. From the list of existing alert policies, use the search box or scroll the list to locate one or more alert policies where the monitor has not already been added. Select the trash can (delete) icon on the monitor's row. Receive alert notifications on a three-strike basis Synthetic alert notifications operate on a three-strike basis, sending an alert after three monitor attempts from a single location return an error. Your alert policy configuration and notification channel settings will determine when you receive alerts for specific monitors and locations. If you monitor a non-public app and add your selected public minion IPs to your allow list, you may very infrequently receive a false downtime alert. When a synthetic monitoring data center goes down, New Relic may decide to temporarily use an alternate host, which results in the temporary server's IP being blocked by your app. Mute (disable) monitor's alert notifications To temporarily disable alerting for a monitor, mute it: Go to one.newrelic.com > Synthetics > Monitors > (select a monitor). Click General under the Settings menu in the left menu sidebar. Click the Notifications button to Off. Muting a monitor's alert notifications will not mute multi-location alerts or NRQL alerts. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", - "type": "docs", + "body": "Automate workflows When building today's complex systems, you want an easy, predictable way to verify that your configuration is defined as expected. This concept, Observability as Code, is brought to life through a collection of New Relic-supported orchestration tools, including Terraform, AWS CloudFormation, and a command-line interface. These tools enable you to integrate New Relic into your existing workflows, easing adoption, accelerating deployment, and returning focus to your main job — getting stuff done. In addition to our Terraform and CLI guides below, find more automation solutions in our Developer Toolkit. Guides to automate workflows 5 min Quickly tag resources Add tags to apps for easy filtering 20 min Set up New Relic using the Kubernetes operator Learn how to provision New Relic resources using the Kubernetes operator 20 min Automate common tasks Use the New Relic CLI to tag apps and create deployment markers 20 min Set up New Relic using Terraform Learn how to provision New Relic resources using Terraform", + "type": "developer", "document_type": "page", - "breadcrumb": "Contents / Synthetic monitoring / Synthetic monitoring / Using monitors", - "info": "New Relic can use alerts to notify you about synthetic monitors's failures.", - "nodeid": 6371, + "info": "", "sections": [ - "Synthetic monitoring", - "Getting started", - "Guides", - "Using monitors", - "Monitor scripting", - "Administration", - "Private locations", - "UI pages", - "Synthetics API", - "Troubleshooting", - "Alerts for synthetic monitoring", - "Add a synthetic monitor to alert policies", - "Existing monitor: Remove from alert policy", - "Receive alert notifications on a three-strike basis", - "Mute (disable) monitor's alert notifications", - "For more help" + "Automate workflows", + "Guides to automate workflows", + "Quickly tag resources", + "Set up New Relic using the Kubernetes operator", + "Automate common tasks", + "Set up New Relic using Terraform" ], - "title": "Alerts for synthetic monitoring", - "translation_ja_url": "https://docs.newrelic.co.jp/docs/synthetics/synthetic-monitoring/using-monitors/alerts-synthetic-monitoring", + "title": "Automate workflows", "popularity": 1, - "external_id": "b69353439d3cc180ca46c64bef5e8470cdda1636", - "category_1": "Synthetic monitoring", - "category_2": "Using monitors", + "external_id": "d4f408f077ed950dc359ad44829e9cfbd2ca4871", "image": "", - "url": "https://docs.newrelic.com/docs/synthetics/synthetic-monitoring/using-monitors/alerts-synthetic-monitoring", - "published_at": "2020-08-18T11:09:08Z", - "updated_at": "2020-08-14T00:47:54Z", - "category_0": "Synthetic monitoring", + "url": "https://developer.newrelic.com/automate-workflows/", + "published_at": "2020-08-19T01:44:47Z", + "updated_at": "2020-08-19T01:44:47Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.5598317, + "_score": 0.22022635, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Alerts for synthetic monitoring", - "sections": "Mute (disable) monitor's alert notifications", - "info": "New Relic can use alerts to notify you about synthetic monitors's failures.", - "category_0": "Synthetic monitoring", - "category_1": "Synthetic monitoring", - "category_2": "Using monitors", - "translation_ja_url": "https://docs.newrelic.co.jp/docs/synthetics/synthetic-monitoring/using-monitors/alerts-synthetic-monitoring", - "body": " the alert notification either while creating a monitor or after you have created one. You can configure your monitor's alert policy directly from the Synthetics UI or via the Alerts UI for existing monitors. To identify which monitors do not have policies assigned to them, review their color-coded health", - "breadcrumb": "Contents / Synthetic monitoring / Synthetic monitoring / Using monitors" + "sections": "Set up New Relic using the Kubernetes operator", + "body": " solutions in our Developer Toolkit. Guides to automate workflows 5 min Quickly tag resources Add tags to apps for easy filtering 20 min Set up New Relic using the Kubernetes operator Learn how to provision New Relic resources using the Kubernetes operator 20 min Automate common tasks Use the New Relic CLI to tag apps and create deployment markers 20 min Set up New Relic using Terraform Learn how to provision New Relic resources using Terraform" }, - "id": "5f31b60e196a6742d2fbd6c8" + "id": "5efa999c196a67dfb4766445" }, { - "body": "If you delete a channel, you cannot restore it. If you want to keep the notification channel, you can remove it from any associated policy. Delete a channel To delete a channel permanently: Go to one.newrelic.com, in the top nav click Alerts & AI, then click Notification channels. Optional: To find the notification channel easily, search the Notification channels index. From the Notification channels index, select the channel's delete icon, and then select the confirmation prompt to cancel or continue. When you delete (or remove) a channel, any policies associated with it will still remain. You must delete policies separately. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "body": "You can manage alerts conditions using our GraphQL NerdGraph API. Here are some conditions queries and mutations you can develop in our NerdGraph API explorer. See the NerdGraph introduction for help getting started with NerdGraph API explorer. This document covers the following: Steps to create a NRQL condition NRQL static condition NRQL baseline condition NRQL outlier condition Update a condition Update mutations List and filter NRQL conditions Singular NRQL condition queries Create a description Delete conditions Steps to create a NRQL condition Follow these steps: Decide which condition type you want to create (see NRQL Condition threshold types). Find your relevant policyID by doing one of the following: Use the NerdGraph policies API. Go to one.newrelic.com, in the top nav click Alerts & AI, then click Policies. Choose a policy. Find the ID under the policy name. Provide the appropriate mutation for your NRQL condition type and the relevant values. The NerdGraph GraphiQL explorer is the best place to find up-to-date documentation about the per-field specifics of the NerdGraph NRQL Conditions API. For example, questions like \"What does the valueFunction field accept?\" are best answered with the inline NerdGraph documentation. NRQL static condition Here's an example of creating a static condition: mutation { alertsNrqlConditionStaticCreate(accountId: YOUR_ACCOUNT_ID, policyId: YOUR_POLICY_ID, condition: { name: \"Low Host Count - Catastrophic\" enabled: true nrql: { query: \"SELECT uniqueCount(host) from Transaction where appName='my-app-name'\" evaluationOffset: 3 } terms: { threshold: 2 thresholdOccurrences: AT_LEAST_ONCE thresholdDuration: 600 operator: BELOW priority: CRITICAL } valueFunction: SINGLE_VALUE violationTimeLimit: TWENTY_FOUR_HOURS }) { id name } } NRQL baseline condition Here's an example of creating a baseline condition: mutation { alertsNrqlConditionBaselineCreate(accountId: YOUR_ACCOUNT_ID, policyId: YOUR_POLICY_ID, condition: { name: \"Baseline Condition\" enabled: true baselineDirection: UPPER_ONLY nrql: { query: \"SELECT average(duration) FROM Transaction\" evaluationOffset: 3 } terms: { threshold: 13 thresholdDuration: 180 thresholdOccurrences: ALL operator: ABOVE priority: CRITICAL } violationTimeLimit: TWENTY_FOUR_HOURS }) { id name baselineDirection } } NRQL outlier condition Here's an example of creating an outlier condition: mutation { alertsNrqlConditionOutlierCreate(accountId: YOUR_ACCOUNT_ID, policyId: YOUR_POLICY_ID, condition: { name: \"Outlier Condition\" enabled: true expectedGroups: 4 openViolationOnGroupOverlap: false nrql: { query: \"SELECT average(duration) FROM Transaction FACET httpResponseCode\" evaluationOffset: 3 } terms: { threshold: 1 thresholdDuration: 300 thresholdOccurrences: ALL operator: ABOVE priority: CRITICAL } violationTimeLimit: TWENTY_FOUR_HOURS }) { id name expectedGroups openViolationOnGroupOverlap } } Update a condition Complete the following: Determine the type of your existing condition by requesting the type field in a nrqlConditionsSearch query like this: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditionsSearch { nrqlConditions { id type } } } } } } The type returned is what you use for your update mutation. For example, if the type returned is STATIC, use alertsNrqlConditionStaticUpdate. If the type returned is BASELINE, use alertsNrqlConditionBaselineUpdate. If the type returned is OUTLIER, use alertsNrqlConditionOutlierUpdate. Provide the id of your condition to your relevant condition type mutation. Note that you can only update conditions of the relevant type. Only provide update mutations for the fields you want to update. Fields you don't provide in the update are not touched. Update mutations Only fields that you provide in the update are changed. In the following example, baselineDirection returns unchanged, but name is updated. mutation { alertsNrqlConditionBaselineUpdate(id: YOUR_CONDITION_ID, accountId: YOUR_ACCOUNT_ID, condition: { name: \"Your updated name\" }) { id name baselineDirection } } List and filter NRQL conditions To list or filter your NRQL conditions, use the nrqlConditionsSearch query in NerdGraph. Use cursor pagination The basic of list functionality for NRQL conditions allows you to paginate through your NRQL conditions as well as request the total count of conditions per account. The nrqlConditionsSearch query utilizes cursor pagination to paginate through resources. The idea behind cursor pagination is that the client will request a cursor in a programmatic loop until the cursor comes back empty. An initial list response will look something like this: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditionsSearch { nextCursor nrqlConditions { id name type } totalCount } } } } } This example returns a JSON response like this: { \"data\": { \"actor\": { \"account\": { \"alerts\": { \"nrqlConditionsSearch\": { \"nextCursor\": \"WOwfJ4+TWm9QTFeKMGyg+w==:QqkI8S4+Wwnpno6z+uk8kQ==\", \"nrqlConditions\": [ { \"id\": \"4432\", \"name\": \"Baseline Condition\", \"type\": \"BASELINE\" }, { \"id\": \"443\", \"name\": \"A static condition\", \"type\": \"STATIC\" }, // more conditions here in reality ], \"totalCount\": 435 } } } } }, } In order to paginate through conditions in the response, have the client request the cursor to be returned until the nextCursor returns from the response as null: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditionsSearch(cursor: \"WOwfJ4+TWm9QTFeKMGyg+w==:QqkI8S4+Wwnpno6z+uk8kQ==\", ) { nextCursor nrqlConditions { id name type } totalCount } } } } } Request type-specific fields Certain fields are only available on specific NRQL condition types. The main reason that mutations are split between the different condition types is because they have minor differences between the fields they accept. For example, valueFunction is only relevant for static NRQL conditions and baselineDirection is only relevant on baseline NRQL conditions. But if these fields are only available on these certain condition types, how do we return them in a list of all of our condition types? The answer is a GraphQL convention known as inline fragments. Inline fragments allow you to access the data on a specific type of NRQL condition: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditionsSearch { nrqlConditions { id name type ...on AlertsNrqlStaticCondition { valueFunction } ...on AlertsNrqlBaselineCondition { baselineDirection } ...on AlertsNrqlOutlierCondition { expectedGroups } } } } } } } In the previous example query, we are asking GraphQL to do the hard work for us to determine which NRQL conditions are the correct type. So, when the returned type is a static condition, it will return the valueFunction in the object. When the returned type is a baseline condition, it will return baselineDirection instead, and when the type is an outlier condition, it will return expectedGroups. Here is an example response: { \"data\": { \"actor\": { \"account\": { \"alerts\": { \"nrqlConditionsSearch\": { \"nrqlConditions\": [ { \"baselineDirection\": \"UPPER_ONLY\", \"id\": \"342\", \"name\": \"My baseline condition\", \"type\": \"BASELINE\" }, { \"id\": \"553\", \"name\": \"My static condition\", \"type\": \"STATIC\", \"valueFunction\": \"SINGLE_VALUE\" }, { \"expectedGroups\": 4, \"id\": \"802\", \"name\": \"My outlier condition\", \"type\": \"OUTLIER\" } ] } } } } } } Filter NRQL conditions You can filter NRQL conditions with the searchCriteria argument of the nrqlConditionsSearch query: Here's an example of filtering NRQL conditions with matching by name. This query returns NRQL conditions that match the provided name. Note that this match is case insensitive. { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditionsSearch(searchCriteria: { name: \"Baseline Condition\" }) { nrqlConditions { id name type } } } } } } Singular NRQL condition queries You can use the NRQL condition API to query for a singular condition. Run the nrqlCondition query in the alerts namespace. Similar to type specific fields on the nrqlConditionSearch query, you can also use these inline fragmentsto request fields that are restricted to a NRQL condition type. { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlCondition(id: YOUR_CONDITION_ID) { id name ...on AlertsNrqlStaticCondition { valueFunction } } } } } } Update the description This will walk you through the procedure to create a description for a NRQL alert condition. 1. Get all the conditions for a policy: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditions(policyId: YOUR_POLICY_ID) { nextCursor results { id name description enabled nrql { query sinceValue } policyId runbookUrl terms { duration operator priority timeFunction threshold } type violationTimeLimit } } } } } } 2. Get the details for a single condition: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlCondition(id: \"YOUR_CONDITION_ID\") { description id enabled name nrql { query evaluationOffset } policyId runbookUrl terms { operator priority threshold thresholdDuration thresholdOccurrences } type violationTimeLimit } } } } } 3. Create a mutation with the description. Here's an empty mutation template: mutation { alertsNrqlConditionStaticUpdate(accountId: YOUR_ACCOUNT_ID, id: \"YOUR_CONDITION_ID\", condition: {description: \"\"}) { description } } Here'a an example mutation with an included example description: mutation { alertsNrqlConditionStaticUpdate(accountId: 123456, id: \"123456\", condition: {description: \"timestamp : {{timestamp}} \\n accountId : {{accountId}} \\n type : {{type}} \\n event : {{event}} \\n description : {{description}} \\n policyId : {{policyId}} \\n policyName: {{policyName}} \\n conditionName : {{conditionName}} \\n conditionId : {{conditionId}} \\n product : {{product}} \\n conditionType : {{conditionType}} \\n RunbookUrl : {{runbookUrl}} \\n nrqlQuery : {{nrqlQuery}} \\n nrqlEventType : {{nrqlEventType}} \\n targetID : {{targetId}} \\n targetName : {{targetName}} \\n commandLine : {{tag.commandLine}} \\n entityGuid : {{tag.entityGuid}} \\n entityName : {{tag.entityName}} \\n fullHostname : {{tag.fullHostname}} \\n instanceType : {{tag.instanceType}} \\n processDisplayName : {{tag.processDisplayName}}\"}) { description } } Delete conditions You can use the alertsConditionDelete mutation to delete any type of condition. You can only request the id field on a delete mutation; for example: mutation { alertsConditionDelete(accountId: YOUR_ACCOUNT_ID, id: YOUR_CONDITION_ID) { id } } For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", "type": "docs", "document_type": "page", - "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / Alert notifications", - "info": "You can delete alerts notification channels permanently or you can keep channels but remove them from associated policies.", - "nodeid": 6471, + "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / Alerts and Nerdgraph", + "info": "Examples of how to use the NerdGraph API explorer to create alert conditions, queries, and mutations.", + "nodeid": 37711, "sections": [ "New Relic Alerts", "Get started", @@ -2625,559 +2693,588 @@ "Rules, limits, and glossary", "Alerts and Nerdgraph", "REST API alerts", - "Delete alert notification channels", - "Delete a channel", + "NerdGraph API: NRQL condition alerts", + "Steps to create a NRQL condition", + "NRQL static condition", + "NRQL baseline condition", + "NRQL outlier condition", + "Update a condition", + "Update mutations", + "List and filter NRQL conditions", + "Singular NRQL condition queries", + "Update the description", + "Delete conditions", "For more help" ], - "title": "Delete alert notification channels", + "title": "NerdGraph API: NRQL condition alerts ", "popularity": 1, - "external_id": "dcea3b60f23ddeb74a7a0a0f44a5130cd9e2885d", + "external_id": "86591bd20017930f1e4eef1b1a76e3806298dbb9", "category_1": "New Relic Alerts", - "category_2": "Alert notifications", "image": "", - "url": "https://docs.newrelic.com/docs/alerts-applied-intelligence/new-relic-alerts/alert-notifications/delete-alert-notification-channels", - "published_at": "2020-08-18T18:07:05Z", - "updated_at": "2020-08-15T07:46:52Z", + "url": "https://docs.newrelic.com/docs/alerts-applied-intelligence/new-relic-alerts/alerts-nerdgraph/nerdgraph-api-nrql-condition-alerts", + "published_at": "2020-08-18T18:15:13Z", + "updated_at": "2020-08-11T04:56:49Z", "category_0": "Alerts and Applied intelligence", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.5424085, + "_score": 0.1518009, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Delete alert notification channels", - "sections": "Delete alert notification channels", - "info": "You can delete alerts notification channels permanently or you can keep channels but remove them from associated policies.", - "category_2": "Alert notifications", - "body": "If you delete a channel, you cannot restore it. If you want to keep the notification channel, you can remove it from any associated policy. Delete a channel To delete a channel permanently: Go to one.newrelic.com, in the top nav click Alerts & AI, then click Notification channels. Optional: To find" + "title": "NerdGraph API: NRQL condition alerts ", + "sections": "NerdGraph API: NRQL condition alerts", + "info": "Examples of how to use the NerdGraph API explorer to create alert conditions, queries, and mutations.", + "category_0": "Alerts and Applied intelligence", + "category_1": "New Relic Alerts", + "body": " the conditions for a policy: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditions(policyId: YOUR_POLICY_ID) { nextCursor results { id name description enabled nrql { query sinceValue } policyId runbookUrl terms { duration operator priority timeFunction threshold } type violationTimeLimit" }, - "id": "5f2dbb3628ccbc65c788dfcb" + "id": "5f2dee1128ccbc562e88dfc1" }, { - "body": "Depending on the selected channel type, different values appear. Reference for updating channels Here's a quick reference for updating channels which also includes links to more detailed information and procedures. Add or remove policies assigned to a channel To add or remove policies assigned to a notification channel: Go to one.newrelic.com, in the top nav click Alerts & AI, click Notification channels. Choose a channel, and then click Alert policies. From the selected policy, use the windows to select, remove, or clear all notification channels. Assign a channel to policies To add a notification channel to one or more policies: Go to one.newrelic.com, in the top nav click Alerts & AI, click Policies. Choose a policy, click Notification channels, and then click Add notification channels. Choose a channel, and then click Update policy. Change a channel's name To rename an existing notification channel: Go to one.newrelic.com, in the top nav click Alerts & AI, click Notification channels, then choose a channel. From the Channel details, change the name (maximum 64 characters) based on the channel type if applicable, and then save. Check for policies assigned to a user To check whether an account user has any policies assigned: Go to one.newrelic.com, in the top nav click Alerts & AI, click Notification channels. Optional: Search by \"user\" to browse users or a specific username or email. Choose the user, then click Alert policies. Check how many policies are assigned to a channel To check whether a notification channel has any policies assigned: Go to one.newrelic.com, in the top nav click Alerts & AI, click Notification channels. The Policy subscriptions column lists how many policies are assigned to the channel. Create more channels To create a new notification channel: Go to one.newrelic.com, in the top nav click Alerts & AI, click Notification channels. Click New notification channel. Delete a channel To delete a notification channel: Go to one.newrelic.com, in the top nav click Alerts & AI, click Notification channels. In the list, click the Delete icon. Test a saved channelView assigned alert policies To view the policies assigned to a notification channel: Go to one.newrelic.com, in the top nav click Alerts & AI, click Notification channels, choose a channel, and then click Alert policies. OR To view the notification channels assigned to a policy: Go to one.newrelic.com, in the top nav click Alerts & AI, click Policies, choose a policy, then click Notification channels. Basic process Go to one.newrelic.com, in the top nav click Alerts & AI, click Notification channels, then choose a channel. From the Channel details page, make any necessary changes, and then save. The user interface shows a Last modified time stamp for any changes to policies, including their conditions and notification channels. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "body": "Use the entity explorer to access the performance data from all your monitored applications, services, and hosts. For more about entities, see What is an entity? View entities To use the entity explorer: Go to one.newrelic.com and select Entity explorer. Your monitored entities are on the left. You may need to scroll your list of entities to see them all. one.newrelic.com > Entity explorer: Use the entity explorer to locate and examine the entities you monitor. The entity explorer brings together data reported from across all of New Relic. Entity categories include: Services: APM-monitored applications and services monitored. Hosts: your monitored infrastructure (your servers and hosts). Mobile applications: your mobile apps. Browser applications: your front-end browser apps. Integration-reported data: data from services monitored by our integrations, including our on-host integrations (like Kubernetes, StatsD, and NGINX), and cloud platform integrations, like Amazon, Microsoft Azure, and Google Cloud Platform (GCP). Health (alert) status The entity explorer shows a color-coded alert status for entities. For example, you may see a red alert status indicating a critical violation in progress. To see what an alert status means, mouse over it. To see details about an entity's alerting status, select the entity. NRQL alert conditions aren't used to determine alert status because they aren't associated with specific entities. Starting June 8, 2020, New Relic One will not continue to display any APM application that hasn't reported data for 93 days. To match our published APM data retention guidelines, applications that have not reported data will be available within the New Relic UI for 90 days. After 90 days, those applications will be removed from the UI; however, key metrics will continue to be available via the New Relic REST API based on subscription level. For more information, see New Relic's Explorers Hub post. Filter by tag or entity name There are a couple ways to filter down to specific types of entities: Filter entities by tags: Use Filter with tags at the top of the page. For example, you may want to filter down to only entities tagged with production, or only entities with a specific AWS region tag. For more about tags, see Tagging. Filter by entity name: Use Search services by name at the top of the page. Entity data retention Availability of data depends on these factors: Scope Data retention Entity explorer and search In the UI, data is available for eight days after an entity no longer exists, with one exception: data reported by integrations, such as Amazon AWS, is only available for one day after an entity ceases to exist. Our database (accessible via NRQL query) For querying our database (for example, via the query builder or data explorer), availability is dependent on the data retention for that data type. As a result of these factors, a short-lived entity (like a cloud host) may not be available in the entity explorer list or via search, but its data may still be available via NRQL query. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", "type": "docs", "document_type": "page", - "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / Alert notifications", - "info": "Read about how to update alerts notification channels. ", - "nodeid": 6481, + "breadcrumb": "Contents / New Relic One / Use New Relic One / UI and data", + "info": "Use New Relic's entity explorer to see all your monitored entities in one place and explore the reported data. ", + "nodeid": 34316, "sections": [ - "New Relic Alerts", + "Use New Relic One", "Get started", - "Alert policies", - "Alert conditions", - "Alert violations", - "Alert Incidents", - "Alert notifications", - "Troubleshooting", - "Rules, limits, and glossary", - "Alerts and Nerdgraph", - "REST API alerts", - "Update alert notification channels", - "Reference for updating channels", - "Basic process", - "For more help" - ], - "title": "Update alert notification channels", - "popularity": 1, - "external_id": "ee8bce401d0623e8b85d84a6a20bd8a72b9764ef", - "category_1": "New Relic Alerts", - "category_2": "Alert notifications", - "image": "", - "url": "https://docs.newrelic.com/docs/alerts-applied-intelligence/new-relic-alerts/alert-notifications/update-alert-notification-channels", - "published_at": "2020-08-18T18:07:05Z", - "updated_at": "2020-08-11T06:42:27Z", - "category_0": "Alerts and Applied intelligence", - "_index": "520d1d5d14cc8a32e600034b", - "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.45523524, - "_version": null, - "_explanation": null, - "sort": null, - "highlight": { - "title": "Update alert notification channels", - "sections": "Update alert notification channels", - "info": "Read about how to update alerts notification channels. ", - "category_2": "Alert notifications", - "body": " to a notification channel: Go to one.newrelic.com, in the top nav click Alerts & AI, click Notification channels. Choose a channel, and then click Alert policies. From the selected policy, use the windows to select, remove, or clear all notification channels. Assign a channel to policies To add" - }, - "id": "5f2dbad928ccbcb8ca88dfed" - }, - { - "body": "You must save a new notification channel or any changes to an existing notification channel before testing it. Alerts will then send a test message to your chosen destination. Request the test To test a notification channel: Go to one.newrelic.com, in the top nav click Alerts & AI, then click Notification channels. Follow standard procedures to add a new notification channel or to update an existing notification channel, and save it. Select a notification channel, and then click Envelope Message Icon Send a test notification. Review the test confirmation message, and then click Got it. Troubleshoot the test results A confirmation message will automatically show up in the user interface that indicates where the test was sent (for example, email) and whether it was successful. Also, the test notification message itself includes detailed information, including: The person who requested the test Links to policies for the channel Links to all notification channels and policies for the account When troubleshooting problems, review the test notification message, and verify the setup requirements for the type of notification channel you selected. If necessary, make additional changes to your notification channel, and test it again as needed. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", - "type": "docs", - "document_type": "page", - "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / Alert notifications", - "info": "Be sure to save your alerts notification channels before testing them to make sure they're working properly.", - "nodeid": 6491, - "sections": [ - "New Relic Alerts", - "Get started", - "Alert policies", - "Alert conditions", - "Alert violations", - "Alert Incidents", - "Alert notifications", - "Troubleshooting", - "Rules, limits, and glossary", - "Alerts and Nerdgraph", - "REST API alerts", - "Test alert notification channels", - "Request the test", - "Troubleshoot the test results", + "Core concepts", + "UI and data", + "Workloads", + "Build on New Relic One", + "Entity explorer: View performance across apps, services, hosts", + "View entities", + "Health (alert) status", + "Filter by tag or entity name", + "Entity data retention", "For more help" ], - "title": "Test alert notification channels", + "title": "Entity explorer: View performance across apps, services, hosts", + "translation_ja_url": "https://docs.newrelic.co.jp/docs/new-relic-one/use-new-relic-one/ui-data/new-relic-one-entity-explorer-view-performance-across-apps-services-hosts", "popularity": 1, - "external_id": "fcea4cf920f099fa1fcf7fab3760d57bdf2e02b7", - "category_1": "New Relic Alerts", - "category_2": "Alert notifications", - "image": "", - "url": "https://docs.newrelic.com/docs/alerts-applied-intelligence/new-relic-alerts/alert-notifications/test-alert-notification-channels", - "published_at": "2020-08-18T18:08:07Z", - "updated_at": "2020-08-11T04:16:54Z", - "category_0": "Alerts and Applied intelligence", + "external_id": "4a6bab9713737af90dbcc516f3c61501354f15d2", + "category_1": "Use New Relic One", + "category_2": "UI and data", + "image": "https://docs.newrelic.com/sites/default/files/thumbnails/image/new-relic-one-entity-explorer.png", + "url": "https://docs.newrelic.com/docs/new-relic-one/use-new-relic-one/ui-data/new-relic-one-entity-explorer-view-performance-across-apps-services-hosts", + "published_at": "2020-08-18T14:54:15Z", + "updated_at": "2020-08-10T23:54:20Z", + "category_0": "New Relic One", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.45365188, + "_score": 0.08398412, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Test alert notification channels", - "sections": "Test alert notification channels", - "info": "Be sure to save your alerts notification channels before testing them to make sure they're working properly.", - "category_2": "Alert notifications", - "body": "You must save a new notification channel or any changes to an existing notification channel before testing it. Alerts will then send a test message to your chosen destination. Request the test To test a notification channel: Go to one.newrelic.com, in the top nav click Alerts & AI, then click" + "sections": "Health (alert) status", + "body": " in progress. To see what an alert status means, mouse over it. To see details about an entity's alerting status, select the entity. NRQL alert conditions aren't used to determine alert status because they aren't associated with specific entities. Starting June 8, 2020, New Relic One will not continue" }, - "id": "5f2dbb3664441fd3a556a97c" + "id": "5d244a5864441fe577a72a1b" }, { - "body": "You can use alerts to set up notification channels, and attach those channels to policies. Your selected channels provide fast and consistent ways for the right personnel to be notified about incidents. For example, notifications allow you to include charts about the incident to provide context and share them with your team. Alerts offers several notification channels, including webhooks, Slack rooms, email, and more. You'll be notified by your notification channels when incidents are opened, acknowledged, or closed. This document explains the available notification channels and how to set them up. This document is about alerts notifications. For general information about unsubscribing from other New Relic emails, including marketing emails, weekly reports, and announcements, see Unsubscribe from New Relic emails. View notification channels To see all notification channels in your account: Go to one.newrelic.com, in the top nav click Alerts & AI, then click Notification channels. Add or remove notification channels To set up a new notification channel: On the Notification channels, click New notification channel. Select the type of channel and complete other required steps for it. To add or remove a notification policy or channel: Select a specific notification channel, select Alert policies, and add or remove a policy. OR Select a specific policy, select Notification channels, and add or remove a channel. Instructions for specific notification channels These are the available notification channel types. User For your convenience, we automatically load all users and their email addresses for the selected account. If your account has one or more sub-accounts, the notification channel includes only users for the currently selected master or sub-account. Use the User notification channel to select existing account team members and admins. To view the Users list or to add users to alert policies: Go to one.newrelic.com, in the top nav click Alerts & AI, then click Notification channels. A user channel also sends push notifications to any of the user's registered mobile devices. A device is registered if the user has logged into New Relic using the mobile app on the device. Email We automatically add every individual and their email address on the selected account to the User notification channel and you can select them there. You don't need to add existing New Relic accounts to the Email channel. To add an email channel for other users, follow these guidelines: Field Description Email (required) In general, use the Email notification channel to identify user emails or email aliases that are not already on the selected account. For example, if you have a dev-ops@company.com email alias for your DevOps team, add the email alias to the Email channel. Otherwise, use the User notification channel to select specific users on your DevOps team. For easier maintenance, add a single non-user email address or alias to a single alert notification channel. If you want to use the email channel for more than one email, create an email group or alias outside your account. These email addresses can be the same as or different from email addresses already on your account. Users can unsubscribe from general (non-alerts-related) emails, but they cannot unsubscribe from alerts email notifications. Instead, the account Owner, Admin, or add-on manager must remove users from the policy's email notification channel. Include JSON attachment (optional) To include a JSON attachment with the email notification, select this checkbox. OpsGenie You must have an existing OpsGenie account integrated with New Relic in order to provide the following information: Field Description Channel name (required) A meaningful name for the OpsGenie notification channel (maximum 64 characters). API key (required) The API key generated from your OpsGenie integration used to authenticate API requests. Teams (optional) List of team names that are responsible for the alert. OpsGenie runs team escalation policies to calculate which users will receive notifications. Tags (optional) A comma-separated list of labels attached to the alert. To overwrite the OpsGenie Quiet Hours setting for urgent alerts, add an OverwriteQuietHours tag. Recipients (optional) One or more names of users, groups, on-call schedules, escalation policies, etc., that OpsGenie uses to calculate where to send notifications. PagerDuty You must have an existing PagerDuty account in order to provide the following information: Field Description Service name (required) The name of your service integrating with PagerDuty for notifications. Integration key (required) The unique service identifier used by PagerDuty's Integration API to trigger, acknowledge, and resolve incidents for the service. Slack Before adding Slack notifications, you must create a unique webhook integration using Slack's New Relic integration. If you want web, transaction, server, and mobile alerts to be posted in separate channels, you must set up separate integrations for each one. Field Description Channel name (required) A meaningful name for the Slack notification channel (maximum 64 characters); for example, Network Ops Center. URL (required) Copy and paste the New Relic webhook integration URL that you've set up with Slack. For example: https://hooks.slack.com/services/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 Be sure to include https:// in the URL. Do not use http://. Team channel (optional) If used, include # before the name of the Slack channel where alert notifications are sent; for example, #NOC. VictorOps You must have an existing VictorOps account in order to provide the following required information: Field Description Channel name (required) A meaningful name for this notification channel (maximum 64 characters). For example, if the VictorOps Route key is for your Technical Support team, you could name this channel Tech Support - VictorOps. Key (required) VictorOps generates a unique key for each account. It maps the VictorOps account to its associated integrations. Route key (optional) This key maps the alert or incident to a specific team. Webhook Webhooks are HTTP POST messages containing JSON documents delivered to a destination URL. When an incident is opened, acknowledged, or closed, our webhook feature sends a message to your URL with any relevant information, such as a description of the event and a link back to New Relic. You also have the option to customize the payload in the POST message for further integration into your system. If your endpoint does not acknowledge the POST request within 10 seconds, the Alerts UI may indicate a failed notification event for the related incident. Before adding webhook notifications, you must have an endpoint set up to respond with a status code between 200 and 206 after receiving the following required information: Field Description Channel name (required) A meaningful name for the webhook (maximum 64 characters). Base url (required) The endpoint that will receive the POST message and trigger customized behaviors in your system. If you want to include a port number in the webhook URL, make sure the port is available for requests. Otherwise the webhook will not work. Basic auth (optional) To require basic authentication for the webhook, select Add basic auth, and provide the user name and password to authenticate the webhook. Custom headers (optional) To include headers with webhooks, select Add custom headers, and provide the name and value for each header. Use custom payload (optional) To use the default values, leave blank. To view and edit the default values, select Add custom payload. Payload (for custom payloads only) Your customized POST message code. This field includes: A list of variables you can use Syntax highlighting, based on payload type Payload type (for custom payloads only) Specify the message format: JSON (default) or Form. xMatters You must have an existing xMatters account in order to provide the following information: Field Description Channel name (required) Name your channel so you can identify it easily when associating it with a policy. Integration url (required) The unique integration url provided by xMatters pointing to your xMatters account. Receive mobile push notifications In order to receive mobile push notifications, your device must be registered and listed in (account) > User preferences. If the device is not listed in User preferences, log out of the app, log back in, and check again to see if it is listed. To receive mobile push notifications: Log in to your New Relic account via the mobile app at least once to ensure the device is registered. Add the user channel to the alert policy. Switch push notifications On for the device. Acknowledge alert notifications Anyone in your account can acknowledge notifications through the user interface or email notification. Acknowledging an incident in New Relic also acknowledges any associated incident in PagerDuty. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "body": "New Relic's Kubernetes integration can be installed directly on a server or VM, or through several cloud platforms, such as GKE, EKS, AKS, or OpenShift. Each has a different compatibility with our integration. Compatibility Our Kubernetes integration is compatible with the following versions, depending on the installation mode: Install mode or feature Kubernetes versions Kubernetes cluster Currently tested with versions 1.10 to 1.18 Kubernetes cluster GKE Currently tested with versions 1.10 and 1.17 Kubernetes cluster EKS Currently tested with version 1.11 Kubernetes cluster AKS Currently tested with version 1.11 Kubernetes cluster OpenShift Currently tested with versions 3.7, 3.9, 4.2, 4.3, 4.4 and 4.5 Control plane monitoring Compatible with version 1.11 or higher Service monitoring Compatible with version 1.13 or higher Requirements The New Relic Kubernetes integration has the following requirements: Linux distribution compatible with New Relic infrastructure agent. kube-state-metrics version 1.9.5 running on the cluster. Install using Helm For compatibility and requirements when installing the Kubernetes integration using Helm, see Alternative install using Helm. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", "type": "docs", "document_type": "page", - "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / Alert notifications", - "info": "Read about how to set up alerts notification channels so you can be notified when incidents are opened, acknowledged, or closed.", - "nodeid": 6281, + "breadcrumb": "Contents / Integrations / Kubernetes integration / Get started", + "info": "Compatibility and requirements of the New Relic Kubernetes integration.", + "nodeid": 38331, "sections": [ - "New Relic Alerts", + "Kubernetes integration", "Get started", - "Alert policies", - "Alert conditions", - "Alert violations", - "Alert Incidents", - "Alert notifications", + "Installation", + "Understand and use data", + "Link apps and services", + "Kubernetes events", + "Logs", "Troubleshooting", - "Rules, limits, and glossary", - "Alerts and Nerdgraph", - "REST API alerts", - "Notification channels: Control where to send alerts", - "View notification channels", - "Add or remove notification channels", - "Instructions for specific notification channels", - "Receive mobile push notifications", - "Acknowledge alert notifications", + "Kubernetes integration: compatibility and requirements", + "Compatibility", + "Requirements", + "Install using Helm", "For more help" ], - "title": "Notification channels: Control where to send alerts", - "translation_ja_url": "https://docs.newrelic.co.jp/docs/alerts-applied-intelligence/new-relic-alerts/alert-notifications/notification-channels-control-where-send-alerts", + "title": "Kubernetes integration: compatibility and requirements", "popularity": 1, - "external_id": "65878aca7993877ee748776c87e9225c90687e3f", - "category_1": "New Relic Alerts", - "category_2": "Alert notifications", + "external_id": "dd40c3bef40e68d873d909dbff75708e20a1141e", + "category_1": "Kubernetes integration", + "category_2": "Get started", "image": "", - "url": "https://docs.newrelic.com/docs/alerts-applied-intelligence/new-relic-alerts/alert-notifications/notification-channels-control-where-send-alerts", - "published_at": "2020-08-18T18:51:22Z", - "updated_at": "2020-08-15T11:49:29Z", - "category_0": "Alerts and Applied intelligence", + "url": "https://docs.newrelic.com/docs/integrations/kubernetes-integration/get-started/kubernetes-integration-compatibility-requirements", + "published_at": "2020-08-18T17:13:01Z", + "updated_at": "2020-08-18T17:13:00Z", + "category_0": "Integrations", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.41058606, + "_score": 0.078668535, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Notification channels: Control where to send alerts", - "sections": "Notification channels: Control where to send alerts", - "info": "Read about how to set up alerts notification channels so you can be notified when incidents are opened, acknowledged, or closed.", - "category_2": "Alert notifications", - "translation_ja_url": "https://docs.newrelic.co.jp/docs/alerts-applied-intelligence/new-relic-alerts/alert-notifications/notification-channels-control-where-send-alerts", - "body": " account: Go to one.newrelic.com, in the top nav click Alerts & AI, then click Notification channels. Add or remove notification channels To set up a new notification channel: On the Notification channels, click New notification channel. Select the type of channel and complete other required steps" + "title": "Kubernetes integration: compatibility and requirements", + "sections": "Kubernetes integration", + "info": "Compatibility and requirements of the New Relic Kubernetes integration.", + "category_1": "Kubernetes integration", + "body": "New Relic's Kubernetes integration can be installed directly on a server or VM, or through several cloud platforms, such as GKE, EKS, AKS, or OpenShift. Each has a different compatibility with our integration. Compatibility Our Kubernetes integration is compatible with the following versions", + "breadcrumb": "Contents / Integrations / Kubernetes integration / Get started" }, - "id": "5f2dbad864441fb7d256a9db" + "id": "5ea87c3be7b9d2c533748090" } ], - "/build-apps/add-query-mutate-data-nerdstorage": [ + "/build-apps/build-hello-world-app": [ { - "body": "Build apps You know better than anyone what information is crucial to your business, and how best to visualize it. Sometimes, this means going beyond dashboards to creating your own app. With React and GraphQL, you can create custom views tailored to your business. These guides are designed to help you start building apps, and dive into our library of components. We also have a growing number of open source apps that you can use to get started. The rest is up to you. Guides to build apps 15 min Create a \"Hello, World!\" application Build a \"Hello, World!\" app and publish it to New Relic One 20 min Publish and deploy apps Start sharing the apps you build 20 min Set up your development environment Prepare to build apps and contribute to this site 20 minutes Add the NerdGraphQuery component to an application The NerdGraphQuery component allows you to query data from your account and add it to a dropdown menu in an application 20 min Add a time picker to your app Add a time picker to a sample application 45 min Add, query, and mutate data using NerdStorage NerdStorage is a document database accessible within New Relic One. It allows you to modify, save, and retrieve documents from one session to the next. 30 min Add a table to your app Add a table to your New Relic One app 30 min Create a custom map view Build an app to show page view data on a map", + "body": "Nerdpack file structure A New Relic One application is represented by a Nerdpack folder, which can include one or more Nerdlet files, and (optionally) one or more launcher files. Here we explain: The file structure for a Nerdpack, a Nerdlet, and a launcher How to link a launcher file to a Nerdlet How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create a Nerdpack template that includes a Nerdlet and a launcher. Generate Nerdlet or launcher individually: Use the New Relic One CLI command nr1 create and choose either Nerdlet or launcher. This can be useful when adding Nerdlets to an existing Nerdpack. For documentation on generating and connecting Nerdpack components, see our app building guides and the New Relic One CLI command reference. Nerdpack file structure When you generate a Nerdpack template using the nr1 create command, it has the following file structure: my-nerdlet ├── README.md ├── launchers │   └── my-nerdlet-launcher │   ├── icon.png │   └── nr1.json ├── nerdlets │   └── my-nerdlet-nerdlet │   ├── index.js │   ├── nr1.json │   └── styles.scss ├── node_modules │   ├── js-tokens │   ├── loose-envify │   ├── object-assign │   ├── prop-types │   ├── react │   ├── react-dom │   ├── react-is │   └── scheduler ├── nr1.json ├── package-lock.json └── package.json Copy Nerdlet file structure A Nerdpack can contain one or more Nerdlets. A Nerdlet folder starts out with three default files, index.js, nr1.json, and styles.scss. Here is what the default files look like after being generated using the nr1 create command: index.js The JavaScript code of the Nerdlet. import React from 'react'; export default class MyAwesomeNerdpack extends React.Component { render() { return

Hello, my-awesome-nerdpack Nerdlet!

; } } Copy nr1.json The Nerdlet configuration file. { \"schemaType\": \"NERDLET\", \"id\": \"my-awesome-nerdpack-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\" } Copy Besides using the launcher as the access point for your application, you can also associate the application with a monitored entity to get it to appear in the entity explorer. To do this, add two additional fields to the config file of the first-launched Nerdlet: entities and actionCategory. In the following example, the Nerdlet has been associated with all Browser-monitored applications and will appear under the Monitor UI category : { \"schemaType\": \"NERDLET\", \"id\": \"my-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"Custom Data\", \"entities\": [{ \"domain\": \"BROWSER\", \"type\": \"APPLICATION\" }], \"actionCategory\": \"monitor\" } Copy To see this application in the UI, you would go to the entity explorer, select Browser applications, and select a monitored application. styles.scss An empty SCSS file for styling your application. icon.png The launcher icon that appears on the Apps page in New Relic One when an application is deployed. Launcher file structure Launchers have their own file structure. Note that: A launcher is not required; as an alternative to using a launcher, you can associate your application with a monitored entity. An application can have more than one launcher, which might be desired for an application with multiple Nerdlets. After generating a launcher using the nr1 create command, its folder contains two files: nr1.json The configuration file. { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy To connect a launcher to a Nerdlet, the rootNerdletId must match the id in the launched Nerdlet's nr1.json config file. For Nerdpacks with multiple Nerdlets, this needs to be done only for the first-launched Nerdlet. icon.png The icon displayed on the launcher for the app on the Apps page.", "type": "developer", "document_type": "page", - "info": "", + "info": "An overview of the Nerdpack File Structure", "sections": [ - "Build apps", - "Guides to build apps", - "Create a \"Hello, World!\" application", - "Publish and deploy apps", - "Set up your development environment", - "Add the NerdGraphQuery component to an application", - "Add a time picker to your app", - "Add, query, and mutate data using NerdStorage", - "Add a table to your app", - "Create a custom map view" + "Nerdpack file structure", + "Generate Nerdpack components", + "Nerdlet file structure", + "index.js", + "nr1.json", + "styles.scss", + "icon.png", + "Launcher file structure" ], - "title": "Build apps", + "title": "Nerdpack file structure", "popularity": 1, - "external_id": "abafbb8457d02084a1ca06f3bc68f7ca823edf1d", + "tags": [ + "New Relic One CLI", + "nerdpack", + "file structure", + "nerdlets", + "launchers" + ], + "external_id": "c97bcbb0a2b3d32ac93b5b379a1933e7b4e00161", "image": "", - "url": "https://developer.newrelic.com/build-apps/", - "published_at": "2020-08-18T02:08:12Z", - "updated_at": "2020-08-18T01:45:02Z", + "url": "https://developer.newrelic.com/explore-docs/nerdpack-file-structure/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:49:25Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.6154529, + "_score": 7.03496, "_version": null, "_explanation": null, "sort": null, "highlight": { - "sections": "Add, query, and mutate data using NerdStorage", - "body": " it to a dropdown menu in an application 20 min Add a time picker to your app Add a time picker to a sample application 45 min Add, query, and mutate data using NerdStorage NerdStorage is a document database accessible within New Relic One. It allows you to modify, save, and retrieve documents from one" + "title": "Nerdpack file structure", + "sections": "Nerdpack file structure", + "info": "An overview of the Nerdpack File Structure", + "tags": "file structure", + "body": " components, see our app building guides and the New Relic One CLI command reference. Nerdpack file structure When you generate a Nerdpack template using the nr1 create command, it has the following file structure: my-nerdlet ├── README.md ├── launchers │   └── my-nerdlet-launcher │   ├── icon.png" }, - "id": "5efa999d64441fc0f75f7e21" + "id": "5efa989e196a671300766404" }, { - "body": "Intro to NerdStorage 30 min To help you build a New Relic One application, we provide you with the New Relic One SDK. On this page, you’ll learn how to use NerdStorage SDK components. Use NerdStorage in your apps NerdStorage is used to store and retrieve simple sets of data, including users's configuration settings and preferences (like favorites), or any other small data sets. This storage is unique per Nerdpack, and can't be shared with any other Nerdpack. NerdStorage can be classified into three categories: User storage: Data that is attached to a particular user. If you’re authenticated as the user the data is attached to, you can read it and write it. Account storage: Data that is attached to a particular account. If you’re authenticated and can access the account, you can read and write to account scoped NerdStorage. Visibility of account data is also determined by master/subaccount rules: If a user has access to the master account, then they also have access to data in all subaccounts. Entity storage: Data that is attached to a particular entity. If you can see the corresponding entity, you can read and write data on that entity. Data model You can imagine NerdStorage as a nested key-value map. Data is inside documents, which are nested inside collections: { 'YourNerdpackUuid': { 'collection-1': { 'document-1-of-collection-1': '{\"lastNumber\": 42, \"another\": [1]}', 'document-2-of-collection-1': '\"userToken\"', // ... }, 'another-collection': { 'fruits': '[\"pear\", \"apple\"]', // ... }, // ... }, } Copy Each NerdStorage level has different properties and purpose: Collections: From a Nerdpack, you can create multiple collections by naming each of them. Inside a collection you can put one or more documents. Think of a collection as key-value storage, where each document is a key-value pair. Documents: A document is formed by an identifier (documentId) and a set of data associated with it. Data associated with a document: NerdStorage accepts any sort of data associated to a documentId. Query and mutation components that are provided work by serializing and deserializing JSON. Limits A Nerdpack can hold up to 1,000 collections and 10,000 documents, plus storage type. A collection can hold up to 1,000 documents, plus storage type. Each document can have a maximum length of 64 KiB when serialized. Data access To access NerdStorage, you can run NerdGraph queries, or use the provided storage queries. Depending on which storage you want to access, you can use a different set of SDK components: User access: UserStorageQuery and UserStorageMutation Account access: AccountStorageQuery and AccountStorageMutation Entity access: EntityStorageQuery and EntityStorageMutation Each of these components can operate declaratively (for example, as part of your React rendering methods) or imperatively (by using the static methods for query and mutation). For more information on this, see Data querying and mutations. Permissions for working with NerdStorage In order to persist changes on NerdStorage, such as creating, updating, and deleting account and entity storage, you must have a user role with permission to persist changes.", + "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations, and fetch New Relic or third-party data. Components of the SDK SDK components are located in the Node module package named nr1, which you get when you install the NR1 CLI. The nr1 components can be divided into several categories: UI components Chart components Query and storage components Platform APIs UI components The UI components category of the SDK contains React UI components, including: Text components: These components provide basic font and heading elements. These include HeadingText and BlockText. Layout components: These components give you control over the layout, and help you build complex layout designs without having to deal with the CSS. Layout components include: Grid and GridItem: for organizing more complex, larger scale page content in rows and columns Stack and StackItem: for organizing simpler, smaller scale page content (in column or row) Tabs and TabsItem: group various related pieces of content into separate hideable sections List and ListItem: for providing a basic skeleton of virtualized lists Card, CardHeader and CardBody : used to group similar concepts and tasks together Form components: These components provide the basic building blocks to interact with the UI. These include Button, TextField, Dropdown and DropdownItem, Checkbox, RadioGroup, Radio, and Checkbox. Feedback components: These components are used to provide feedback to users about actions they have taken. These include: Spinnerand Toast. Overlaid components: These components are used to display contextual information and options in the form of an additional child view that appears above other content on screen when an action or event is triggered. They can either require user interaction (like modals), or be augmenting (like a tooltip). These include: Modal and Tooltip. Components suffixed with Item can only operate as direct children of that name without the suffix. For example: GridItem should only be found as a child of Grid. Chart components The Charts category of the SDK contains components representing different types of charts. The ChartGroup component helps a group of related charts share data and be aligned. Some chart components can perform NRQL queries on their own; some accept a customized set of data. Query and storage components The Query components category contains components for fetching and storing New Relic data. The main way to fetch data is with NerdGraph, our GraphQL endpoint. This can be queried using NerdGraphQuery. To simplify use of NerdGraph queries, we provide some components with pre-defined queries. For more on using NerdGraph, see Queries and mutations. We also provide storage for storing small data sets, such as configuration settings data, or user-specific data. For more on this, see NerdStorage. Platform APIs The Platform API components of the SDK enable your application to interact with different parts of the New Relic One platform, by reading and writing state from and to the URL, setting the configuration, etc. They can be divided into these categories: PlatformStateContext: provides read access to the platform URL state variables. Example: timeRange in the time picker. navigation: an object that allows programmatic manipulation of the navigation in New Relic One. Example: opening a new Nerdlet. NerdletStateContext: provides read access to the Nerdlet URL state variables. Example: an entityGuid in the entity explorer. nerdlet: an object that provides write access to the Nerdlet URL state.", "type": "developer", "document_type": "page", - "info": "Intro to NerdStorage on New Relic One", + "info": "Intro to New Relic One API components", "sections": [ - "Intro to NerdStorage", - "Use NerdStorage in your apps", - "Data model", - "Limits", - "Data access", - "Permissions for working with NerdStorage" + "Intro to New Relic One API components", + "Components of the SDK", + "UI components", + "Chart components", + "Query and storage components", + "Platform APIs" ], - "title": "Intro to NerdStorage", + "title": "Intro to New Relic One API components", "popularity": 1, - "external_id": "709e06c25376d98b2191ca369b4d139e5084bd62", + "tags": [ + "SDK components", + "New Relic One apps", + "UI components", + "chart components", + "query and storage components", + "Platform APIs" + ], + "external_id": "3620920c26bcd66c59c810dccb1200931b23b8c2", "image": "", - "url": "https://developer.newrelic.com/explore-docs/nerdstorage/", - "published_at": "2020-08-18T02:11:48Z", - "updated_at": "2020-08-14T01:50:34Z", + "url": "https://developer.newrelic.com/explore-docs/intro-to-sdk/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:47:12Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.15920696, + "_score": 1.1465895, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Intro to NerdStorage", - "sections": "Intro to NerdStorage", - "info": "Intro to NerdStorage on New Relic One", - "body": " document is a key-value pair. Documents: A document is formed by an identifier (documentId) and a set of data associated with it. Data associated with a document: NerdStorage accepts any sort of data associated to a documentId. Query and mutation components that are provided work by serializing" + "title": "Intro to New Relic One API components", + "sections": "Intro to New Relic One API components", + "info": "Intro to New Relic One API components", + "tags": "New Relic One apps", + "body": ", and fetch New Relic or third-party data. Components of the SDK SDK components are located in the Node module package named nr1, which you get when you install the NR1 CLI. The nr1 components can be divided into several categories: UI components Chart components Query and storage components Platform" }, - "id": "5efa989ee7b9d2048e7bab92" + "id": "5efa989e28ccbc4071307de5" }, { - "body": "Query and store data 10 min To help you build a New Relic One application, we provide you with the New Relic One SDK. Here you can learn how to use the SDK query components, which allow you to make queries and mutations via NerdGraph, our GraphQL endpoint. Query-related React components can be identified by the Query suffix. Mutation-related components can be identified by the Mutation prefix. Components overview Our data components are based on React Apollo. The most basic component is NerdGraphQuery, which accepts any GraphQL (or GraphQL AST generated by the graphql-tag library as the query parameter, and a set of query variables passed as variables. Over this query, we have created an additional set of queries, which can be divided into four groups: User queries: These allow you to query the current user and its associated accounts. Components in this category: UserStorageQuery and AccountsQuery. Entities queries: Because New Relic One is entity-centric, we use queries to make access to your entities easier. You can count, search, list, query, and favorite them. Components in this category: EntityCountQuery, EntitySearchQuery, EntitiesByDomainTypeQuery, EntitiesByGuidsQuery, EntityByGuidQuery, EntityByNameQuery. Storage queries: New Relic One provides a simple storage mechanism that we call NerdStorage. This can be used by Nerdpack creators to store application configuration setting data, user-specific data, and other small pieces of data. Components in this category: UserStorageQuery, AccountStorageQuery, EntityStorageQuery, UserStorageMutation, AccountStorageMutation, and EntityStorageMutation. For details, see NerdStorage. NRQL queries: To be able to query your New Relic data via NRQL (New Relic Query Language), we provide a NrqlQuery component. This component can return data in different formats, so that you can use it for charting and not only for querying. Query components All query components accept a function as a children prop where the different statuses can be passed. This callback receives an object with the following properties: loading: Boolean that is set to true when data fetching is happening. Our components use the cache-and-network strategy, meaning that after the data has loaded, subsequent data reloads might be triggered first with stale data, then refreshed when the most recent data has arrived. data: Root property where the data requested is retrieved. The structure matches a root structure based on the NerdGraph schema. This is true even for highly nested data structures, which means you’ll have to traverse down to find the desired data. error: Contains an Error instance when the query fails. Set to undefined when data is loading or the fetch was successful. fetchMore: Callback function that can be called when the query is being loaded in chunks. The function will only be present when it’s feasible to do so, more data is available, and no fetchMore has already been triggered. Data is loaded in batches of 200 by default. Other components provided by the platform (like the Dropdown or the List) are capable of accepting fetchMore, meaning you can combine them easily. Mutation components Mutation components also accept a children as a function, like the query ones. The mutation can be preconfigured at the component level, and a function is passed back that you can use in your component. This is the standard React Apollo approach for performing mutations, but you might find it easier to use our static mutation method added to the component. More on this topic below. Static methods All of the described components also expose a static method so that they can be used imperatively rather than declaratively. All Query components have a static Query method, and all Mutation components have a mutation method. These static methods accept the same props as their query component, but passed as an object. For example: // Declarative way (using components). function renderAccountList() { return (
    ({data, error}) => { if (error) { return
  • Failed to retrieve list: {error.message}
  • ; } return data.map((account) => {
  • {account.name}
  • }); }}
); } // Imperative way (using promises). async function getAccountList() { let data = {}; try { data = await AccountsQuery.query(); } catch (error) { console.log('Failed to retrieve list: ' + error.message); return; } return data.actor.accounts.map((account) => { return account.name; }); } Copy Similarly, a mutation can happen either way; either declaratively or imperatively. NrqlQuery NrqlQuery deserves additional explanation, because there are multiple formats in which you can return data from it. To provide maximum functionality, all three are exposed through a formatType property. You can find its different values under NrqlQuery.formatType: NERD_GRAPH: Returns the format in which it arrives from NerdGraph. RAW: The format exposed by default in Insights and dashboards when being plotted as JSON. This format is useful if you have a pre-existing script in this format that you're willing to migrate to or incorporate with. CHART: The format used by the charting engine that we also expose. You can find a more detailed explanation of how to manipulate this format in the guide to chart components, and some examples. If you are willing to push data, we currently do not expose NrqlMutation. To do that, see the Event API for how to add custom events.", + "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build your own application launcher and follow the quick start instructions. The quick start automatically generates an API key for the account you select, and gives you the pre-populated commands to create a profile, generate your first \"Hello World\" app, and serve it locally. Tip Use the NR1 VS Code extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions. For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). Configure your CLI preferences nr1 config:set Sets a specific configuration value. nr1 config:get Shows a specific configuration. nr1 config:list Lists your configuration choices. nr1 config:delete Removes the value of a specific configuration. Set up your Nerdpacks nr1 nerdpack:clone Clones an open source Nerdpack from our GitHub repository. nr1 nerdpack:serve Serves your Nerdpack for testing and development purposes. nr1 nerdpack:uuid Shows or regenerates the UUID of a Nerdpack. nr1 nerdpack:publish Publishes your Nerdpack to New Relic. nr1 nerdpack:deploy Deploys a Nerdpack version to a specific channel. nr1 nerdpack:undeploy Undeploys a Nerdpack version from a specific channel. Manage your Nerdpack subscriptions nr1 subscription:set Subscribes your account to a Nerdpack and channel. nr1 subscription:list Lists all the Nerdpacks your account is subscribed to. nr1 subscription:unset Unsubscribes your account from a Nerdpack. Install and manage plugins nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin into the CLI for development. nr1 plugins:update Updates your installed plugins. nr1 plugins:uninstall Removes a plugin from the CLI. Manage catalog information nr1 catalog:info Shows the Nerdpack info stored in the catalog. nr1 catalog:submit Gathers and submits the catalog info on the current folder.", "type": "developer", "document_type": "page", - "info": "Reference guide for SDK query components using NerdGraph", + "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", "sections": [ - "Query and store data", - "Components overview", - "Query components", - "Mutation components", - "Static methods", - "NrqlQuery" + "New Relic One CLI reference", + "Installing the New Relic One CLI", + "Tip", + "New Relic One CLI Commands", + "Get started", + "Configure your CLI preferences", + "Set up your Nerdpacks", + "Manage your Nerdpack subscriptions", + "Install and manage plugins", + "Manage catalog information" ], - "title": "Query and store data", + "title": "New Relic One CLI reference", "popularity": 1, - "external_id": "cbbf363393edeefbc4c08f9754b43d38fd911026", - "image": "", - "url": "https://developer.newrelic.com/explore-docs/query-and-store-data/", - "published_at": "2020-08-18T02:08:12Z", - "updated_at": "2020-08-01T01:42:02Z", + "tags": [ + "New Relic One app", + "nerdpack commands" + ], + "external_id": "858339a44ead21c83257778ce60b4c352cd30d3b", + "image": "https://developer.newrelic.com/static/2c6d337608b38a3312b4fc740afe6167/7272b/developercenter.png", + "url": "https://developer.newrelic.com/explore-docs/nr1-cli/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-18T01:50:36Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.13865894, + "_score": 0.8004142, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Query and store data", - "sections": "Query and store data", - "info": "Reference guide for SDK query components using NerdGraph", - "body": ", EntityByGuidQuery, EntityByNameQuery. Storage queries: New Relic One provides a simple storage mechanism that we call NerdStorage. This can be used by Nerdpack creators to store application configuration setting data, user-specific data, and other small pieces of data. Components in this category" + "title": "New Relic One CLI reference", + "sections": "New Relic One CLI reference", + "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", + "tags": "New Relic One app", + "body": ". For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet" }, - "id": "5efa989e28ccbc2f15307deb" + "id": "5efa989e28ccbc535a307dd0" }, { - "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs in GitHub. Options --format string output text format [YAML, JSON, Text] (default \"JSON\") -h, --help help for newrelic --plain output compact text Copy Commands newrelic apm - Interact with New Relic APM newrelic completion - Generates shell completion functions newrelic config - Manage the configuration of the New Relic CLI newrelic documentation - Generate CLI documentation newrelic entity - Interact with New Relic entities newrelic nerdgraph - Execute GraphQL requests to the NerdGraph API newrelic nerdstorage - Read, write, and delete NerdStorage documents and collections. newrelic nrql - Commands for interacting with the New Relic Database newrelic profile - Manage the authentication profiles for this tool newrelic version - Show the version of the New Relic CLI newrelic workload - Interact with New Relic One workloads", + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app, you might have some additional setup and configuration. This guide covers: Downloading the New Relic One CLI to build or modify apps Contribute content to this website Before you begin You must have: A github account account - While not strictly necessary for building apps, a GitHub account enables you to download and customize our open source apps, and contribute an open source project. A New Relic developer account - if you don't already have one, you can get a free trial account for developing New Relic applications. npm - If you've installed Node.js, then you already have npm, which is used to share, reuse, and update JavaScript code, and is necessary for working with React components that are the framework for New Relic apps and this website. Tip Use the New Relic One VSCode extension to build your apps. Prepare to build or modify apps Step 1 of 2 Download the CLI and API key On the Build New Relic One applications page, complete the Quick start steps. These six Quick start steps get you an API key for use with developing apps, and the New Relic One CLI, for building and deploying apps. At the end of the Quick start, you have a project consisting of the following: A Nerdpack - The package containing all the files required by your application. It contains two types of files that you customize to build your app: Nerdlets, and the launcher. One or more Nerdlet files - A specific UI view or window. A Nerdlet is a React JavaScript package that includes an index.js file, a stylesheet, and a JSON-format config file. It can contain any JS functionality (charts, interactive fields, tooltips, etc.). A launcher file: This is the basis for the launcher, which is used to open your application from New Relic One after you publish your app. Step 2 of 2 Start building If you're ready to code, cd to your Nerdpack and get started. If you want to learn more about building applications, try these step-by-step guides: Build a \"Hello, World!\" application shows how to create a little application, publish it to New Relic One, and share it with others by subscribing accounts to it. Map pageviews by region takes you through the steps to create one of our popular open source apps. You learn to add a custom query to an app and view it in a table, then add that data to a map. Contributing to developer.newrelic.com This site is open source, and we want your input. Create a pull request if you see a mistake you know how to fix. Drop us a GitHub issue if you see some content gaps you want us to work on. Or write up a whole new guide if you have one you'd like to share. Read on to learn how. Step 1 of 3 Fork the developer-website GithHub repo Forking the repo enables you to work on your own copy of the developer.newrelic.com files, and build the site locally. It also enables us to more easily manage incomimg pull requests. On the developer-website page in GitHub, select the Fork button on the top right of the page, choose the account you want to fork to, and wait a few seconds while the fork is created. Sync regularly to keep your fork up to date with changes and additions to the main branch upstream. Step 2 of 3 Make a feature or documentation request On any page, select the GitHub button at the top of the page, and then select the kind of change you want, and fill out the GitHub form. Step 3 of 3 Contribute a new guide Check out our contributors guidelines, which will walk you through the process.", "type": "developer", "document_type": "page", - "info": "The command line tools for performing tasks against New Relic APIs", + "info": "Prepare to build apps and contribute to this site", "sections": [ - "New Relic CLI Reference", - "New Relic CLI commands", - "Options", - "Commands" + "Set up your development environment", + "Before you begin", + "Tip", + "Prepare to build or modify apps", + "Start building" ], - "title": "New Relic CLI Reference", + "title": "Set up your development environment", "popularity": 1, - "tags": "new relic cli", - "external_id": "471ed214caaf80c70e14903ec71411e2a1c03888", + "tags": [ + "developer account", + "API key", + "New Relic One CLI" + ], + "external_id": "c45638a9cd548d1ffffc9f1c7708f115a92ae04a", "image": "", - "url": "https://developer.newrelic.com/explore-docs/newrelic-cli/", - "published_at": "2020-08-18T02:11:50Z", - "updated_at": "2020-08-14T01:47:12Z", + "url": "https://developer.newrelic.com/build-apps/set-up-dev-env/", + "published_at": "2020-08-19T01:44:48Z", + "updated_at": "2020-08-19T01:44:47Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.09380336, + "_score": 0.51757765, "_version": null, "_explanation": null, "sort": null, "highlight": { - "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs" + "tags": "New Relic One CLI", + "body": " On the Build New Relic One applications page, complete the Quick start steps. These six Quick start steps get you an API key for use with developing apps, and the New Relic One CLI, for building and deploying apps. At the end of the Quick start, you have a project consisting of the following: A Nerdpack" }, - "id": "5efa989ee7b9d2024b7bab97" + "id": "5efa9973e7b9d242237bab39" }, { - "body": "Query data with NRQL 10 min With NRQL, you can query any of the default event data being reported by New Relic, plus any custom events and attributes you’ve added. Step 1 of 4 NRQL syntax is comparable to ANSI SQL. Learn more about NRQL syntax SELECT function(attribute) [AS 'label'][, ...] FROM event [WHERE attribute [comparison] [AND|OR ...]][AS 'label'][, ...] [FACET attribute | function(attribute)] [LIMIT number] [SINCE time] [UNTIL time] [WITH TIMEZONE timezone] [COMPARE WITH time] [TIMESERIES time] Copy Step 2 of 4 NRQL queries can be as simple as fetching rows of data in a raw tabular form to inspect individual events. Learn what events open source agents provide out of the box -- Fetch a list of Browser PageView events SELECT * FROM PageView Copy Step 3 of 4 NRQL queries can also do extremely powerful calculations before the data is presented to you, such as crafting funnels based on the way people actually use your website. Learn more about NRQL funnels -- See how many users visit, signup, browse and purchase from your site as a funnel SELECT funnel(session, WHERE pageUrl='http://www.demotron.com/' AS 'Visited Homepage', WHERE pageUrl='http://www.demotron.com/signup' AS 'Signed Up', WHERE pageUrl='http://www.demotron.com/browse' AS 'Browsed Items', WHERE pageUrl='http://www.demotron.com/checkout' AS 'Made Purchase') FROM PageView SINCE 12 hours ago Copy Step 4 of 4 Using NRQL, you can customize your New Relic experience by crafting diverse dashboards that show your data from multiple angles. You can share these dashboards with technical and non-technical stakeholders alike. Learn more and start building Documentation For an overview of NRQL syntax, see Introduction to NRQL. For a detailed description of all available functions, see NRQL syntax, components, and functions. NRU Tutorials To learn how to query and narrow a large data store by a specific parameter, watch the tutorial on Filtering queries with NRQL. Community forum Connect with other developers in the our Explorers Hub. GitHub For examples of integrations and other technologies, check us out on GitHub.", - "type": "developer", + "body": "A New Relic One application is represented by a Nerdpack folder, which can include one or more Nerdlet files, and (optionally) one or more launcher files. This document explains: The file structure for a Nerdpack, a Nerdlet and a launcher How to link a launcher file to a Nerdlet How to link your application with a monitored entity For basic component definitions, see our developer site. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate Nerdpack. Use the CLI command nr1 create and select Nerdpack to create a Nerdpack template that includes a Nerdlet and a launcher. Generate Nerdlet or launcher individually. You can use the CLI command nr1 create and choose to select either a Nerdlet or launcher. This may be useful when adding Nerdlets to an existing Nerdpack. For a lesson on generating and connecting Nerdpack components, see the workshop. Nerdpack file structure When you generate a Nerdpack template using the CLI nr1 create command, it has this file structure: my-nerdlet ├── README.md ├── launchers │ └── my-nerdlet-launcher │ ├── icon.png │ └── nr1.json ├── nerdlets │ └── my-nerdlet-nerdlet │ ├── index.js │ ├── nr1.json │ └── styles.scss ├── node_modules │ ├── js-tokens │ ├── loose-envify │ ├── object-assign │ ├── prop-types │ ├── react │ ├── react-dom │ ├── react-is │ └── scheduler ├── nr1.json ├── package-lock.json └── package.json Nerdlet file structure A Nerdpack can contain one or more Nerdlets. A Nerdlet folder starts out with three default files: index.js The JavaScript code. Here's what the default file looks like when a Nerdlet is generated with the CLI nr1 create: import React from 'react'; export default class MyAwesomeNerdpack extends React.Component { render() { return

Hello, my-awesome-nerdpack Nerdlet!

} } nr1.json Configuration file. Here is the default file generated by the CLI nr1 create command: { \"schemaType\": \"NERDLET\", \"id\": \"my-awesome-nerdpack-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\" } Besides using the launcher as the access point for your application, you can also associate the application with a monitored entity to get it to appear in the New Relic One entity explorer. To do this, add two additional fields to the config file of the first-launched Nerdlet: entities and actionCategory. In the following example, the Nerdlet has been associated with all New Relic Browser-monitored applications and will appear under the Monitor UI category : { \"schemaType\": \"NERDLET\", \"id\": \"my-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"Custom Data\", \"entities\": [{\"domain\": \"BROWSER\", \"type\": \"APPLICATION\"}], \"actionCategory\": \"monitor\" } To see this application in the UI, you would go to the New Relic One entity explorer, select Browser applications, and select a monitored application. styles.scss The file for CSS styles (Sass SCSS syntax). Launcher file structure When an application with a launcher file has been deployed, its launcher is located on the New Relic One home page (one.newrelic.com). A launcher is not required; as an alternative to using a launcher, you can associate your application with a monitored entity. An application can have more than one launcher; this may be desired for an application with multiple Nerdlets. A launcher folder contains two files: nr1.json The configuration file. Here is the default file template created by the nr1 create command: { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } To connect a launcher to a Nerdlet, the rootNerdletId must match the id in the launched Nerdlet's nr1.json config file. For Nerdpacks with multiple Nerdlets, this needs to be done only for the first-launched Nerdlet. icon.png The launcher icon that appears on the one.newrelic.com home page when an application is deployed. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "type": "docs", "document_type": "page", - "info": "Query default event data as well as custom events and attributes with our powerful, SQL-like query language. Start querying now.", + "breadcrumb": "Contents / New Relic One / Use New Relic One / Build on New Relic One", + "info": "For building a New Relic One application: an explanation of the Nerdpack/Nerdlet file structure. ", + "nodeid": 36006, "sections": [ - "Query data with NRQL", - "Learn more and start building", - "Documentation", - "NRU Tutorials", - "Community forum", - "GitHub" + "Use New Relic One", + "Get started", + "Core concepts", + "UI and data", + "Workloads", + "Build on New Relic One", + "Nerdpack file structure", + "Generate Nerdpack components", + "Nerdlet file structure", + "Launcher file structure", + "For more help" ], - "title": "Query data with NRQL", + "title": "Nerdpack file structure", "popularity": 1, - "external_id": "7bb23b086badd7a572964357aad776116f5bfbbe", - "image": "https://developer.newrelic.com/static/eb2adf50e7680e8ba5b7daaf06c203d1/757a2/nr1-dashboard.png", - "url": "https://developer.newrelic.com/collect-data/query-data-nrql/", - "published_at": "2020-08-18T02:08:12Z", - "updated_at": "2020-08-14T01:46:10Z", + "external_id": "6e3788bee17cb65b6dc210862e2a10399f78ff67", + "category_1": "Use New Relic One", + "category_2": "Build on New Relic One", + "image": "", + "url": "https://docs.newrelic.com/docs/new-relic-one/use-new-relic-one/build-new-relic-one/new-relic-one-application-nerdpack-file-structure", + "published_at": "2020-08-18T15:32:31Z", + "updated_at": "2020-07-25T00:32:16Z", + "category_0": "New Relic One", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.08179283, + "_score": 0.43092638, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Query data with NRQL", - "sections": "Query data with NRQL", - "info": "Query default event data as well as custom events and attributes with our powerful, SQL-like query language. Start querying now.", - "body": "Query data with NRQL 10 min With NRQL, you can query any of the default event data being reported by New Relic, plus any custom events and attributes you’ve added. Step 1 of 4 NRQL syntax is comparable to ANSI SQL. Learn more about NRQL syntax SELECT function(attribute) [AS 'label'][, ...] FROM" + "title": "Nerdpack file structure", + "sections": "Nerdpack file structure", + "info": "For building a New Relic One application: an explanation of the Nerdpack/Nerdlet file structure. ", + "category_0": "New Relic One", + "category_1": "Use New Relic One", + "category_2": "Build on New Relic One", + "body": " file structure When you generate a Nerdpack template using the CLI nr1 create command, it has this file structure: my-nerdlet ├── README.md ├── launchers │ └── my-nerdlet-launcher │ ├── icon.png │ └── nr1.json ├── nerdlets │ └── my-nerdlet-nerdlet │ ├── index.js │ ├── nr1.json │ └── styles.scss", + "breadcrumb": "Contents / New Relic One / Use New Relic One / Build on New Relic One" }, - "id": "5efa999ce7b9d29f377bab69" + "id": "5da0e07a64441f1328edf241" } ], - "/build-apps/add-nerdgraphquery-guide": [ + "/collect-data/collect-data-from-any-source": [ { - "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build your own application launcher and follow the quick start instructions. The quick start automatically generates an API key for the account you select, and gives you the pre-populated commands to create a profile, generate your first \"Hello World\" app, and serve it locally. Tip Use the NR1 VS Code extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions. For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). Configure your CLI preferences nr1 config:set Sets a specific configuration value. nr1 config:get Shows a specific configuration. nr1 config:list Lists your configuration choices. nr1 config:delete Removes the value of a specific configuration. Set up your Nerdpacks nr1 nerdpack:clone Clones an open source Nerdpack from our GitHub repository. nr1 nerdpack:serve Serves your Nerdpack for testing and development purposes. nr1 nerdpack:uuid Shows or regenerates the UUID of a Nerdpack. nr1 nerdpack:publish Publishes your Nerdpack to New Relic. nr1 nerdpack:deploy Deploys a Nerdpack version to a specific channel. nr1 nerdpack:undeploy Undeploys a Nerdpack version from a specific channel. Manage your Nerdpack subscriptions nr1 subscription:set Subscribes your account to a Nerdpack and channel. nr1 subscription:list Lists all the Nerdpacks your account is subscribed to. nr1 subscription:unset Unsubscribes your account from a Nerdpack. Install and manage plugins nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin into the CLI for development. nr1 plugins:update Updates your installed plugins. nr1 plugins:uninstall Removes a plugin from the CLI. Manage catalog information nr1 catalog:info Shows the Nerdpack info stored in the catalog. nr1 catalog:submit Gathers and submits the catalog info on the current folder.", + "body": "Create custom New Relic events 5 min Measure what you need by creating your own event types. Whereas adding custom attributes adds metadata to an existing event, a custom event creates an entirely new event type. Create custom events to define, visualize, and get alerts on additional data, just as you would with any data we provide from our core agents. Custom events can be inserted through the Agent APIs or directly via the Insights Insert API. The following example shows how to send a custom event named CLIRun that tracks when a command line tool written in Ruby has its process exit due to an exception. # Hook into the runtime 'at_exit' event at_exit do # Name the custom event payload = { 'eventType' => 'CLIRun' } # Check to see if the process is exiting due to an error if $!.nil? || $!.is_a?(SystemExit) && $!.success? payload[:status] = 0 else # Gather any known errors errors = \"\" (Thread.current[:errors] ||= []).each do |err| errors += \"#{err}\\n\" end payload[:errors] = errors end # Send the errors to New Relic as a custom event insights_url = URI.parse(\"https://insights-collector.newrelic.com/v1/accounts/YOUR_ACCOUNT_ID/events\") headers = { \"x-insert-key\" => \"YOUR_API_KEY\", \"content-type\" => \"application/json\" } http = Net::HTTP.new(insights_url.host, insights_url.port) http.use_ssl = true request = Net::HTTP::Post.new(insights_url.request_uri, headers) request.body = payload.to_json puts \"Sending run summary to Insights: #{payload.to_json}\" begin response = http.request(request) puts \"Response from Insights: #{response.body}\" rescue Exception => e puts \"There was an error posting to Insights. Error: #{e.inspect}\" end end Copy Here, a NRQL query retrieves information about the custom event, and the result can be added to a dashboard. SELECT count(*) FROM CLIRun FACET errors SINCE 1 week ago Copy Learn more about custom events.", "type": "developer", "document_type": "page", - "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", + "info": "Create custom New Relic events", "sections": [ - "New Relic One CLI reference", - "Installing the New Relic One CLI", - "Tip", - "New Relic One CLI Commands", - "Get started", - "Configure your CLI preferences", - "Set up your Nerdpacks", - "Manage your Nerdpack subscriptions", - "Install and manage plugins", - "Manage catalog information" + "Create custom New Relic events", + "Measure what you need by creating your own event types." ], - "title": "New Relic One CLI reference", + "title": "Create custom New Relic events", "popularity": 1, "tags": [ - "New Relic One app", - "nerdpack commands" + "events", + "custom events", + "Agent APIs" ], - "external_id": "858339a44ead21c83257778ce60b4c352cd30d3b", - "image": "https://developer.newrelic.com/static/2c6d337608b38a3312b4fc740afe6167/7272b/developercenter.png", - "url": "https://developer.newrelic.com/explore-docs/nr1-cli/", - "published_at": "2020-08-18T02:07:10Z", - "updated_at": "2020-08-18T01:50:36Z", + "external_id": "92138b3846dabdae20d88c102dcac8e575502ad1", + "image": "https://developer.newrelic.com/static/65a2aca8a0e6d0d1b808c2cc98519def/0086b/UC2-sec2-query.png", + "url": "https://developer.newrelic.com/collect-data/custom-events/", + "published_at": "2020-08-19T01:46:02Z", + "updated_at": "2020-08-01T01:40:57Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 1.6000241, + "_score": 4.336734, "_version": null, "_explanation": null, "sort": null, "highlight": { - "sections": "Set up your Nerdpacks", - "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", - "tags": "New Relic One app", - "body": " your own application launcher and follow the quick start instructions. The quick start automatically generates an API key for the account you select, and gives you the pre-populated commands to create a profile, generate your first "Hello World" app, and serve it locally. Tip Use the NR1 VS Code" + "title": "Create custom New Relic events", + "sections": "Create custom New Relic events", + "info": "Create custom New Relic events", + "tags": "Agent APIs", + "body": " as you would with any data we provide from our core agents. Custom events can be inserted through the Agent APIs or directly via the Insights Insert API. The following example shows how to send a custom event named CLIRun that tracks when a command line tool written in Ruby has its process exit due" }, - "id": "5efa989e28ccbc535a307dd0" + "id": "5efa997364441f4a775f7e03" }, { - "body": "Build apps You know better than anyone what information is crucial to your business, and how best to visualize it. Sometimes, this means going beyond dashboards to creating your own app. With React and GraphQL, you can create custom views tailored to your business. These guides are designed to help you start building apps, and dive into our library of components. We also have a growing number of open source apps that you can use to get started. The rest is up to you. Guides to build apps 15 min Create a \"Hello, World!\" application Build a \"Hello, World!\" app and publish it to New Relic One 20 min Publish and deploy apps Start sharing the apps you build 20 min Set up your development environment Prepare to build apps and contribute to this site 20 minutes Add the NerdGraphQuery component to an application The NerdGraphQuery component allows you to query data from your account and add it to a dropdown menu in an application 20 min Add a time picker to your app Add a time picker to a sample application 45 min Add, query, and mutate data using NerdStorage NerdStorage is a document database accessible within New Relic One. It allows you to modify, save, and retrieve documents from one session to the next. 30 min Add a table to your app Add a table to your New Relic One app 30 min Create a custom map view Build an app to show page view data on a map", - "type": "developer", + "body": "Our Telemetry SDKs are an open source set of API client libraries that send metrics and trace data to the New Relic platform. We offer open-source integrations for telemetry tools like Prometheus, Istio, and OpenCensus that were created using our Telemetry SDKs. If those solutions (or our other integrations) don't meet your needs, you can use the Telemetry SDKs to create your own telemetry data solutions. Requirements and compatibility To build with the Telemetry SDKs, you will need an Event API insert key. New Relic has contributed the Telemetry SDK to the open source community under an Apache 2.0 license. Available libraries The Telemetry SDKs are open source software on GitHub. Use the language-specific GitHub links below to get library details, coding examples, and procedures for how to use the SDKs. We currently support the following libraries, with more to be created in the future: Language Library Supported data types Java Java library on GitHub New Relic Metrics New Relic Traces Node/TypeScript NodeJS library on GitHub New Relic Metrics New Relic Traces Python Python library on GitHub New Relic Metrics New Relic Events New Relic Traces Go Go library on Github New Relic Metrics New Relic Traces .NET .NET library on GitHub .NET package in NuGet New Relic Metrics New Relic Traces For more on the supported data types: Metrics: see the Metric API Traces: see the Trace API Write your own Telemetry SDK or contribute to an existing one If you need a Telemetry SDK in a language that does not currently exist or want to contribute to an existing library, please see the Telemetry SDK specifications. Integrations built with the Telemetry SDKs To see the integrations built using our Telemetry SDKs, see Open source telemetry integrations. For all monitoring solutions, see our integrations page. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "type": "docs", "document_type": "page", - "info": "", + "breadcrumb": "Contents / Telemetry Data Platform / Ingest and manage data / Ingest APIs", + "info": "Report custom telemetry data with New Relic's open-source Telemetry SDKs.", + "nodeid": 35471, "sections": [ - "Build apps", - "Guides to build apps", - "Create a \"Hello, World!\" application", - "Publish and deploy apps", - "Set up your development environment", - "Add the NerdGraphQuery component to an application", - "Add a time picker to your app", - "Add, query, and mutate data using NerdStorage", - "Add a table to your app", - "Create a custom map view" + "Ingest and manage data", + "Get started", + "Understand data", + "Manage data", + "Ingest APIs", + "Telemetry SDKs: Report custom telemetry data", + "Requirements and compatibility", + "Available libraries", + "Write your own Telemetry SDK or contribute to an existing one", + "Integrations built with the Telemetry SDKs", + "For more help" ], - "title": "Build apps", + "title": "Telemetry SDKs: Report custom telemetry data", "popularity": 1, - "external_id": "abafbb8457d02084a1ca06f3bc68f7ca823edf1d", + "external_id": "47a4c8f38c1b1674504ea302d865fd499e90ea39", + "category_1": "Ingest and manage data", + "category_2": "Ingest APIs", "image": "", - "url": "https://developer.newrelic.com/build-apps/", - "published_at": "2020-08-18T02:08:12Z", - "updated_at": "2020-08-18T01:45:02Z", + "url": "https://docs.newrelic.com/docs/telemetry-data-platform/get-started/capabilities/telemetry-sdks-send-custom-telemetry-data-new-relic", + "published_at": "2020-08-18T15:15:03Z", + "updated_at": "2020-08-11T01:15:34Z", + "category_0": "Telemetry Data Platform", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.79272, + "_score": 0.16157359, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Build apps", - "sections": "Add the NerdGraphQuery component to an application", - "body": " min Publish and deploy apps Start sharing the apps you build 20 min Set up your development environment Prepare to build apps and contribute to this site 20 minutes Add the NerdGraphQuery component to an application The NerdGraphQuery component allows you to query data from your account and add" + "title": "Telemetry SDKs: Report custom telemetry data", + "sections": "Telemetry SDKs: Report custom telemetry data", + "info": "Report custom telemetry data with New Relic's open-source Telemetry SDKs.", + "category_0": "Telemetry Data Platform", + "category_2": "Ingest APIs", + "body": " Metrics New Relic Traces .NET .NET library on GitHub .NET package in NuGet New Relic Metrics New Relic Traces For more on the supported data types: Metrics: see the Metric API Traces: see the Trace API Write your own Telemetry SDK or contribute to an existing one If you need a Telemetry SDK", + "breadcrumb": "Contents / Telemetry Data Platform / Ingest and manage data / Ingest APIs" }, - "id": "5efa999d64441fc0f75f7e21" + "id": "5d89fefbe7b9d2537ed30dc1" }, { - "body": "Map page views by region in a custom app 30 min New Relic has powerful and flexible tools for building custom apps and populating them with data. This guide shows you how to build a custom app and populate it with page view data using New Relic's Query Language (NRQL - pronounced 'nurkle'). Then you make your data interactive. And last, if you have a little more time and want to install a third-party React library, you can display the page view data you collect on a map of the world. In this guide, you build an app to display page view data in two ways: In a table On a map Please review the Before you begin section to make sure you have everything you need and don't get stuck halfway through. Before you begin In order to get the most out of this guide, you must have: A New Relic developer account, API key, and the command-line tool. If you don't have these yet, see the steps in Setting up your development environment New Relic Browser page view data to populate the app. Without this data, you won't be able to complete this guide. To add your data to a world map in the second half of the guide: npm, which you'll use during this section of the guide to install Leaflet, a third-party JavaScript React library used to build interactive maps. If you're new to React and npm, you can go here to install Node.js and npm. New Relic terminology The following are some terms used in this guide: New Relic application: The finished product where data is rendered in New Relic One. This might look like a series of interactive charts or a map of the world. Nerdpack: New Relic's standard collection of JavaScript, JSON, CSS, and other files that control the functionality and look of your application. For more information, see Nerdpack file structure. Launcher: The button on New Relic One that launches your application. Nerdlets: New Relic React components used to build your application. The three default files are index.js, nr1.json, and styles.scss, but you can customize and add your own. Build a custom app with a table chart Step 1 of 8 Query your browser data Use Query builder to write a NRQL query to see your page view data, as follows. On New Relic One, select Query your data (in the top right corner). That puts you in NRQL mode. You'll use NRQL to test your query before dropping the data into your table. Copy and paste this query into a clear query field, and then select Run. FROM PageView SELECT count(*), average(duration) WHERE appName = 'WebPortal' FACET countryCode, regionCode SINCE 1 week ago LIMIT 1000 Copy If you have PageView data, this query shows a week of average page views broken down by country and limited to a thousand items. The table will be full width and use the \"chart\" class defined in the CSS. If you don't have any results at this point, ensure your query doesn't have any errors. If your query is correct, you might not have the Browser agent installed. Step 2 of 8 Create and serve a new Nerdpack To get started, create a new Nerdpack, and serve it up to New Relic from your local development environment: Create a new Nerdpack for this app: nr1 create --type nerdpack --name pageviews-app Copy Serve the project up to New Relic: cd pageviews-app && nr1 nerdpack:serve Copy Step 3 of 8 Review your app files and view your app locally Navigate to your pageviews-app to see how it's structured. It contains a launcher folder, where you can customize the description and icon that will be displayed on the app's launcher in New Relic One. It also contains nerdlets, which each contain three default files: index.js, nr1.json, and styles.scss. You'll edit some of these files as part of this guide. For more information, see Nerdpack file structure. Now in your browser, open https://one.newrelic.com/?nerdpacks=local, and then click Apps to see the pageview-apps Nerdpack that you served up. When you select the launcher, you see a Hello message. Step 4 of 8 Hard code your account ID For the purposes of this exercise and for your convenience, hard code your account ID. In the pageview-app-nerdlet directory, in the index.js file, add this code between the import and export lines. (Read about finding your account ID here). const accountId = [Replace with your account ID]; Copy Step 5 of 8 Import the TableChart component To show your data in a table chart, import the TableChart component from New Relic One. To do so, in index.js, add this code under import React. import { TableChart } from `nr1`; Copy Step 6 of 8 Add a table with a single row To add a table with a single row, in the index.js file, replace this line: return

Hello, pageview-app-nerdlet Nerdlet!

; Copy with this export code: export default class PageViewApp extends React.Component { render() { return (
); } } Copy Step 7 of 8 Customize the look of your table (optional) You can use standard CSS to customize the look of your components. In the styles.scss file, add this CSS. Feel free to customize this CSS to your taste. .container { width: 100%; height: 99vh; display: flex; flex-direction: column; .row { margin: 10px; display: flex; flex-direction: row; } .chart { height: 250px; } } Copy Step 8 of 8 Get your data into that table Now that you've got a table, you can drop a TableChart populated with data from the NRQL query you wrote at the very beginning of this guide. Put this code into the row div. ; Copy Go to New Relic One and click your app to see your data in the table. (You might need to serve your app to New Relic again.) Congratulations! You made your app! Continue on to make it interactive and show your data on a map. Make your app interactive with a text field Once you confirm that data is getting to New Relic from your app, you can start customizing it and making it interactive. To do this, you add a text field to filter your data. Later, you use a third-party library called Leaflet to show that data on a world map. Step 1 of 3 Import the TextField component Like you did with the TableChart component, you need to import a TextField component from New Relic One. import { TextField } from 'nr1'; Copy Step 2 of 3 Add a row for your text field To add a text field filter above the table, put this code above the TableChart div. The text field will have a default value of \"US\".
{ this.setState({ countryCode: event.target.value }); }} />
; Copy Step 3 of 3 Build the text field object Above the render() function, add a constructor to build the text field object. constructor(props) { super(props); this.state = { countryCode: null } } Copy Then, add a constructor to your render() function. Above return, add: const { countryCode } = this.state; Copy Now add countryCode to your table chart query. ; Copy Reload your app to try out the text field. Get your data on a map To create the map, you use npm to install Leaflet. Step 1 of 9 Install Leaflet In your terminal, type: npm install --save leaflet react-leaflet Copy In your nerdlets styles.scss file, import the Leaflet CSS: @import `~leaflet/dist/leaflet.css`; Copy While you're in styles.scss, fix the width and height of your map: .containerMap { width: 100%; z-index: 0; height: 70vh; } Copy Step 2 of 9 Add a webpack config file for Leaflet Add a webpack configuration file .extended-webpackrc.js to the top-level folder in your nerdpack. This supports your use of map tiling information data from Leaflet. module.exports = { module: { rules: [ { test: /\\.(png|jpe?g|gif)$/, use: [ { loader: 'file-loader', options: {}, }, { loader: 'url-loader', options: { limit: 25000 }, }, ], }, ], }, }; Copy Step 3 of 9 Import modules from Leaflet In index.js, import modules from Leaflet. import { Map, CircleMarker, TileLayer } from 'react-leaflet'; Copy Step 4 of 9 Import additional modules from New Relic One You need several more modules from New Relic One to make the Leaflet map work well. Import them with this code: import { NerdGraphQuery, Spinner, Button, BlockText } from 'nr1'; Copy NerdGraphQuery lets you make multiple NRQL queries at once and is what will populate the map with data. Spinner adds a loading spinner. Button gives you button components. BlockText give you block text components. Step 5 of 9 Get data for the map Using latitude and longitude with country codes, you can put New Relic data on a map. mapData() { const { countryCode } = this.state; const query = `{ actor { account(id: 1606862) { mapData: nrql(query: \"SELECT count(*) as x, average(duration) as y, sum(asnLatitude)/count(*) as lat, sum(asnLongitude)/count(*) as lng FROM PageView FACET regionCode, countryCode WHERE appName = 'WebPortal' ${countryCode ? ` WHERE countryCode like '%${countryCode}%' ` : ''} LIMIT 1000 \") { results nrql } } } }`; return query; }; Copy Step 6 of 9 Customize the map marker colors Above the mapData function, add this code to customize the map marker colors. getMarkerColor(measure, apdexTarget = 1.7) { if (measure <= apdexTarget) { return '#11A600'; } else if (measure >= apdexTarget && measure <= apdexTarget * 4) { return '#FFD966'; } else { return '#BF0016'; } }; Copy Feel free to change the HTML color code values to your taste. In this example, #11A600 is green, #FFD966 is sort of yellow, and #BF0016 is red. Step 7 of 9 Set your map's default center point Set a default center point for your map using latitude and longitude. const defaultMapCenter = [10.5731, -7.5898]; Copy Step 8 of 9 Add a row for your map Between the text field row and the table chart row, insert a new row for the map content using NerdGraphQuery.
{({ loading, error, data }) => { if (loading) { return ; } if (error) { return 'Error'; } const { results } = data.actor.account.mapData; console.debug(results); return 'Hello'; }}
; Copy Reload your application in New Relic One to test that it works. Step 9 of 9 Replace \"Hello\" with the Leaflet code Replace return \"Hello\"; with: return ( {results.map((pt, i) => { const center = [pt.lat, pt.lng]; return ( { alert(JSON.stringify(pt)); }} /> ); })} ); Copy This code creates a world map centered on the latitude and longitude you chose using OpenStreetMap data and your marker colors. Reload your app to see the pageview data on the map!", - "type": "developer", + "body": "There are many ways to get data into your New Relic account. Any New Relic user can use any of our data ingest methods to report data to our Telemetry Data Platform. New Relic-built agents and integrations When you enable New Relic solutions like APM, browser monitoring, mobile monitoring, infrastructure monitoring, or any of our wide array of integrations, by default you'll receive data from your monitored applications, hosts, services, or other entities. To browse all New Relic-built tools and solutions, see New Relic integrations. Agent APIs Some of our monitoring solutions come with APIs and/or SDKs that allow you to customize the data reported and how it reports. For more information, see the relevant product: APM agent APIs Browser API Mobile API Infrastructure monitoring: the Flex integration tool Telemetry SDKs If our more curated solutions don't work for you, our open source Telemetry SDKs let you build your own solution. These SDKs are language wrappers for our data-ingest APIs (below) that let you send telemetry data to New Relic without requiring install of an agent. APIs for sending metrics, traces, logs, and events If our more curated solutions don't work for you, we also have data-ingest APIs: Trace API Event API Metric API Log API To learn about the differences between these data types, see Data types. New Relic One applications You can build entirely custom applications that reside in New Relic One and make use of any data you want. You can use existing open source New Relic One apps, or share your own with the open source community. For details, see New Relic One applications. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "type": "docs", "document_type": "page", - "info": "Build a New Relic app showing page view data on a world map.", + "breadcrumb": "Contents / Telemetry Data Platform / Ingest and manage data / Get started", + "info": "An introduction to how to get data into New Relic. ", + "nodeid": 36051, "sections": [ - "Map page views by region in a custom app", - "Before you begin", - "New Relic terminology", - "Build a custom app with a table chart", - "Query your browser data", - "Create and serve a new Nerdpack", - "Review your app files and view your app locally", - "Hard code your account ID", - "Import the TableChart component", - "Add a table with a single row", - "Customize the look of your table (optional)", - "Get your data into that table", - "Make your app interactive with a text field", - "Import the TextField component", - "Add a row for your text field", - "Build the text field object", - "Get your data on a map", - "Install Leaflet", - "Add a webpack config file for Leaflet", - "Import modules from Leaflet", - "Import additional modules from New Relic One", - "Get data for the map", - "Customize the map marker colors", - "Set your map's default center point", - "Add a row for your map", - "Replace \"Hello\" with the Leaflet code" + "Ingest and manage data", + "Get started", + "Understand data", + "Manage data", + "Ingest APIs", + "Get data into New Relic", + "New Relic-built agents and integrations", + "Agent APIs", + "Telemetry SDKs", + "APIs for sending metrics, traces, logs, and events", + "New Relic One applications", + "For more help" ], - "title": "Map page views by region in a custom app", + "title": "Get data into New Relic", "popularity": 1, - "external_id": "6ff5d696556512bb8d8b33fb31732f22bab455cb", - "image": "https://developer.newrelic.com/static/d87a72e8ee14c52fdfcb91895567d268/0086b/pageview.png", - "url": "https://developer.newrelic.com/build-apps/map-pageviews-by-region/", - "published_at": "2020-08-18T02:11:48Z", - "updated_at": "2020-08-14T01:45:09Z", + "external_id": "7a413b4d7e5bd81088a08507ae4bad64c7e24b2d", + "category_1": "Ingest and manage data", + "category_2": "Get started", + "image": "", + "url": "https://docs.newrelic.com/docs/telemetry-data-platform/get-data-new-relic/getting-started/introduction-new-relic-data-ingest-apis-sdks", + "published_at": "2020-08-18T15:33:40Z", + "updated_at": "2020-08-10T23:16:39Z", + "category_0": "Telemetry Data Platform", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.39790472, + "_score": 0.14225492, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Map page views by region in a custom app", - "sections": "Query your browser data", - "info": "Build a New Relic app showing page view data on a world map.", - "body": " <Spinner fillContainer />; } if (error) { return 'Error'; } const { results } = data.actor.account.mapData; console.debug(results); return 'Hello'; }} </NerdGraphQuery> </div>; Copy Reload your application in New Relic One to test that it works. Step 9 of 9 Replace "Hello" with the Leaflet code Replace" + "sections": "APIs for sending metrics, traces, logs, and events", + "category_0": "Telemetry Data Platform", + "body": " also have data-ingest APIs: Trace API Event API Metric API Log API To learn about the differences between these data types, see Data types. New Relic One applications You can build entirely custom applications that reside in New Relic One and make use of any data you want. You can use existing open", + "breadcrumb": "Contents / Telemetry Data Platform / Ingest and manage data / Get started" }, - "id": "5efa993c196a67066b766469" + "id": "5f24aa60196a67ede394f5f3" }, { - "body": "Query and store data 10 min To help you build a New Relic One application, we provide you with the New Relic One SDK. Here you can learn how to use the SDK query components, which allow you to make queries and mutations via NerdGraph, our GraphQL endpoint. Query-related React components can be identified by the Query suffix. Mutation-related components can be identified by the Mutation prefix. Components overview Our data components are based on React Apollo. The most basic component is NerdGraphQuery, which accepts any GraphQL (or GraphQL AST generated by the graphql-tag library as the query parameter, and a set of query variables passed as variables. Over this query, we have created an additional set of queries, which can be divided into four groups: User queries: These allow you to query the current user and its associated accounts. Components in this category: UserStorageQuery and AccountsQuery. Entities queries: Because New Relic One is entity-centric, we use queries to make access to your entities easier. You can count, search, list, query, and favorite them. Components in this category: EntityCountQuery, EntitySearchQuery, EntitiesByDomainTypeQuery, EntitiesByGuidsQuery, EntityByGuidQuery, EntityByNameQuery. Storage queries: New Relic One provides a simple storage mechanism that we call NerdStorage. This can be used by Nerdpack creators to store application configuration setting data, user-specific data, and other small pieces of data. Components in this category: UserStorageQuery, AccountStorageQuery, EntityStorageQuery, UserStorageMutation, AccountStorageMutation, and EntityStorageMutation. For details, see NerdStorage. NRQL queries: To be able to query your New Relic data via NRQL (New Relic Query Language), we provide a NrqlQuery component. This component can return data in different formats, so that you can use it for charting and not only for querying. Query components All query components accept a function as a children prop where the different statuses can be passed. This callback receives an object with the following properties: loading: Boolean that is set to true when data fetching is happening. Our components use the cache-and-network strategy, meaning that after the data has loaded, subsequent data reloads might be triggered first with stale data, then refreshed when the most recent data has arrived. data: Root property where the data requested is retrieved. The structure matches a root structure based on the NerdGraph schema. This is true even for highly nested data structures, which means you’ll have to traverse down to find the desired data. error: Contains an Error instance when the query fails. Set to undefined when data is loading or the fetch was successful. fetchMore: Callback function that can be called when the query is being loaded in chunks. The function will only be present when it’s feasible to do so, more data is available, and no fetchMore has already been triggered. Data is loaded in batches of 200 by default. Other components provided by the platform (like the Dropdown or the List) are capable of accepting fetchMore, meaning you can combine them easily. Mutation components Mutation components also accept a children as a function, like the query ones. The mutation can be preconfigured at the component level, and a function is passed back that you can use in your component. This is the standard React Apollo approach for performing mutations, but you might find it easier to use our static mutation method added to the component. More on this topic below. Static methods All of the described components also expose a static method so that they can be used imperatively rather than declaratively. All Query components have a static Query method, and all Mutation components have a mutation method. These static methods accept the same props as their query component, but passed as an object. For example: // Declarative way (using components). function renderAccountList() { return (
    ({data, error}) => { if (error) { return
  • Failed to retrieve list: {error.message}
  • ; } return data.map((account) => {
  • {account.name}
  • }); }}
); } // Imperative way (using promises). async function getAccountList() { let data = {}; try { data = await AccountsQuery.query(); } catch (error) { console.log('Failed to retrieve list: ' + error.message); return; } return data.actor.accounts.map((account) => { return account.name; }); } Copy Similarly, a mutation can happen either way; either declaratively or imperatively. NrqlQuery NrqlQuery deserves additional explanation, because there are multiple formats in which you can return data from it. To provide maximum functionality, all three are exposed through a formatType property. You can find its different values under NrqlQuery.formatType: NERD_GRAPH: Returns the format in which it arrives from NerdGraph. RAW: The format exposed by default in Insights and dashboards when being plotted as JSON. This format is useful if you have a pre-existing script in this format that you're willing to migrate to or incorporate with. CHART: The format used by the charting engine that we also expose. You can find a more detailed explanation of how to manipulate this format in the guide to chart components, and some examples. If you are willing to push data, we currently do not expose NrqlMutation. To do that, see the Event API for how to add custom events.", - "type": "developer", + "body": "New Relic products report a variety of default event data to your account. This document will explain how to report your own custom events and attributes. Overview of reporting custom events and attributes Event data is one of the fundamental New Relic data types. Events are reported by most New Relic products, and we give you several options for reporting your own custom events. Reporting custom events allows you to create more useful and customized queries and charts of your data, and is a key part of optimizing how New Relic works for you. Before beginning, it's important to know that reporting a large number of custom events and/or attributes can cause degraded query performance, or cause you to approach or pass data collection rate limits. For optimal performance, first think about what data you want to analyze, and then create only the events and/or attributes necessary to meet these specific goals. Be aware of the following data and subscription requirements for inserting and accessing custom data: Ensure you follow limits and requirements around event/attribute data types, naming syntax, and size. The amount of data you have access to over time depends on your data retention policy. Send custom events and attributes Methods for sending custom events and attributes include: Source How to send custom data APM agent Use APM agent APIs to report custom events and custom attributes. Browser agent Add custom attributes to the PageView event via the Browser API call addCustomAttribute. Send PageAction event and attributes via Browser API. Forward APM agent custom attributes to PageView event. Event API To report custom events not associated with other New Relic products, use the Event API. Infrastructure Add custom attributes to default Infrastructure events. Use the Flex integration tool to report your own custom event data. Mobile agent Use the mobile agent API to send custom events and attributes. Synthetics Add custom attributes to the SyntheticCheck event via the $util.insights tools. For ways to report other types of custom data, see: Metric API Logs Trace API Extend data retention To learn about how to extend how long events are retained in your account, see Event data retention. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "type": "docs", "document_type": "page", - "info": "Reference guide for SDK query components using NerdGraph", + "breadcrumb": "Contents / Insights / Event data sources / Custom events", + "info": "An overview of the options for sending custom event data to New Relic. ", + "nodeid": 13806, "sections": [ - "Query and store data", - "Components overview", - "Query components", - "Mutation components", - "Static methods", - "NrqlQuery" + "Event data sources", + "Default events", + "Custom events", + "Report custom event data", + "Overview of reporting custom events and attributes", + "Send custom events and attributes", + "Extend data retention", + "For more help" ], - "title": "Query and store data", + "title": "Report custom event data", "popularity": 1, - "external_id": "cbbf363393edeefbc4c08f9754b43d38fd911026", + "external_id": "afb5f5a81ae06b22935d98c470ed9cabd7c9da6b", + "category_1": "Event data sources", + "category_2": "Custom events", "image": "", - "url": "https://developer.newrelic.com/explore-docs/query-and-store-data/", - "published_at": "2020-08-18T02:08:12Z", - "updated_at": "2020-08-01T01:42:02Z", + "url": "https://docs.newrelic.com/docs/insights/insights-data-sources/custom-data/report-custom-event-data", + "published_at": "2020-08-18T07:15:53Z", + "updated_at": "2020-07-26T05:52:23Z", + "category_0": "Insights", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.29999372, + "_score": 0.11418797, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Query and store data", - "sections": "Components overview", - "info": "Reference guide for SDK query components using NerdGraph", - "body": " be identified by the Query suffix. Mutation-related components can be identified by the Mutation prefix. Components overview Our data components are based on React Apollo. The most basic component is NerdGraphQuery, which accepts any GraphQL (or GraphQL AST generated by the graphql-tag library as the query" + "title": "Report custom event data", + "sections": "Event data sources", + "info": "An overview of the options for sending custom event data to New Relic. ", + "category_1": "Event data sources", + "category_2": "Custom events", + "body": " the Flex integration tool to report your own custom event data. Mobile agent Use the mobile agent API to send custom events and attributes. Synthetics Add custom attributes to the SyntheticCheck event via the $util.insights tools. For ways to report other types of custom data, see: Metric API Logs Trace", + "breadcrumb": "Contents / Insights / Event data sources / Custom events" }, - "id": "5efa989e28ccbc2f15307deb" + "id": "5e8e7f9de7b9d2aa122cf0f6" }, { - "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations, and fetch New Relic or third-party data. Components of the SDK SDK components are located in the Node module package named nr1, which you get when you install the NR1 CLI. The nr1 components can be divided into several categories: UI components Chart components Query and storage components Platform APIs UI components The UI components category of the SDK contains React UI components, including: Text components: These components provide basic font and heading elements. These include HeadingText and BlockText. Layout components: These components give you control over the layout, and help you build complex layout designs without having to deal with the CSS. Layout components include: Grid and GridItem: for organizing more complex, larger scale page content in rows and columns Stack and StackItem: for organizing simpler, smaller scale page content (in column or row) Tabs and TabsItem: group various related pieces of content into separate hideable sections List and ListItem: for providing a basic skeleton of virtualized lists Card, CardHeader and CardBody : used to group similar concepts and tasks together Form components: These components provide the basic building blocks to interact with the UI. These include Button, TextField, Dropdown and DropdownItem, Checkbox, RadioGroup, Radio, and Checkbox. Feedback components: These components are used to provide feedback to users about actions they have taken. These include: Spinnerand Toast. Overlaid components: These components are used to display contextual information and options in the form of an additional child view that appears above other content on screen when an action or event is triggered. They can either require user interaction (like modals), or be augmenting (like a tooltip). These include: Modal and Tooltip. Components suffixed with Item can only operate as direct children of that name without the suffix. For example: GridItem should only be found as a child of Grid. Chart components The Charts category of the SDK contains components representing different types of charts. The ChartGroup component helps a group of related charts share data and be aligned. Some chart components can perform NRQL queries on their own; some accept a customized set of data. Query and storage components The Query components category contains components for fetching and storing New Relic data. The main way to fetch data is with NerdGraph, our GraphQL endpoint. This can be queried using NerdGraphQuery. To simplify use of NerdGraph queries, we provide some components with pre-defined queries. For more on using NerdGraph, see Queries and mutations. We also provide storage for storing small data sets, such as configuration settings data, or user-specific data. For more on this, see NerdStorage. Platform APIs The Platform API components of the SDK enable your application to interact with different parts of the New Relic One platform, by reading and writing state from and to the URL, setting the configuration, etc. They can be divided into these categories: PlatformStateContext: provides read access to the platform URL state variables. Example: timeRange in the time picker. navigation: an object that allows programmatic manipulation of the navigation in New Relic One. Example: opening a new Nerdlet. NerdletStateContext: provides read access to the Nerdlet URL state variables. Example: an entityGuid in the entity explorer. nerdlet: an object that provides write access to the Nerdlet URL state.", - "type": "developer", + "body": "New Relic offers several tools to help obtain the information needed to provide useful metrics about your Node.js application. These include: Reading the route names (if used) from the Express and Restify routers Using the API to name the current request, either with simple names or groups of controllers with actions Support rules that are stored in your agent's configuration that can mark requests to be renamed or ignored based on regular expressions matched against the request's raw URLs (also available as API calls) The number of names that New Relic tracks needs to be small enough so that the user experience is robust. It also needs to be large enough to provide the right amount of information (without overwhelming you with data) so that you can identify problem spots in your applications more easily. For more information, see the Node.js agent configuration documentation and the Node.js agent API documentation on Github. Request names The Node.js agent captures the HTTP method along with a potentially parameterized path (such as /user/:id) or a regular expression (such as /^/user/([-0-9a-f]+)$/). These pieces of information become part of the request name. If you have support for slow transaction traces and have enabled capture_params in your config file, the transaction trace will also have the request's parameters and their values attached to it. If you are dissatisfied with the request names that the Node.js agent uses, you can use API calls to create more descriptive names. If grouping your requests under the generic name, then /* is sufficient, and you do not need to customize your configuration file or API calls. Requirements New Relic uses request names to group requests for many charts and tables. The value of these visualizations will drop as the number of different request names increases. For example, do not include potentially dynamic data like GUIDs, numerical IDs, or timestamps in the request names you create. If your request is slow enough to generate a transaction trace, that trace will contain the original URL. If you enable parameter capture, the parameters will also be attached to the trace. Avoid having more than 50 different transaction names. For example, if you have more than a couple hundred different request names, rethink your naming strategy. Avoid metric grouping issues The request naming API helps New Relic avoid problems with trying to handle too many metrics, which sometimes is referred to as \"metric explosion.\" New Relic has several strategies to deal with these issues; the most severe is simply to add offending applications to your deny list. The main reason for you to be careful in using these request-naming tools is to prevent that from happening to your applications. For more information, see Metric grouping issues. Guidelines Define your configuration rules from the most specific to the most general. The first rules listed in your config file or added with the Node.js transaction naming API will be applied first and should be narrowly targeted. More general \"fall-through\" rules should be added toward the end of the list, because they will be evaluated in the order they were configured or added using the Node.js transaction naming API. URL pattern matching An online retailer has a URL pattern like this: /user/customers/all/prospects /user/customers/all/current /user/customers/all/returning /user/customers/John /user/customers/Jane The retailer could create rules like this: // newrelic.js exports.config={ //other configuration rules:{ name:[ { pattern: \"/user/customers/all/prospects/\", name: \"/user/customers/all/prospects\" }, { pattern: \"/user/customers/all/.*\", name: \"/user/customers/all\" }, { pattern: \"/user/customers/.*\", name: \"/user/customers/:customer\" } ] } } With these rules, the retailer would create three transaction names: /user/customers/:customer /user/customers/all /user/customers/all/prospects If the retailer reversed the order, the rules would catch all transactions in :customer, which would not be as useful. Load the request naming API Make sure that loading the New Relic module is the first thing your application does, as it needs to bootstrap itself before the rest of your application loads: var newrelic = require('newrelic'); This returns the request naming API. You can safely require the module from multiple modules in your application, as it only initializes itself once. Request API calls Here is a summary of the Request API calls for New Relic's Node.js agent. newrelic.setTransactionName(name) Name the current request, following the request naming requirements. You can call this function anywhere within the context of an HTTP request handler, at any time after handling of the request has started, but before the request has finished. In general, if the request and response objects are in scope, you can set the name. Explicitly calling newrelic.setTransactionName() will override any names set by Express or Restify routes. Also, calls to newrelic.setTransactionName() and newrelic.setControllerName() will overwrite each other. The last one to run before the request ends wins. newrelic.setControllerName(name, [action]) Name the current request using a controller-style pattern, optionally including the current controller action. If the action is omitted, New Relic will include the HTTP method (GET, POST, etc.) as the action. The rules for when you can call newrelic.setControllerName() are the same as they are for newrelic.setTransactionName(), including the request naming requirements. Explicitly calling newrelic.setControllerName() will override any names set by Express or Restify routes. Also, calls to newrelic.setTransactionName() and newrelic.setControllerName() will overwrite each other. The last one to run before the request ends wins. Custom instrumentation API calls Use these API calls to expand your instrumentation with custom instrumentation. newrelic.instrument(moduleName, onRequire [, onError]) Sets an instrumentation callback for a specific module. The provided onRequire callback will be fired when the given module is loaded with require. The moduleName parameter should be the string that will be passed to require; for example, 'express' or 'amqplib/callback_api'. The optional onError callback is called if the onRequire parameters throws an error. This is useful for debugging your instrumentation. Use this method to: Add instrumentation for modules not currently instrumented by New Relic. Instrument your own code. Replace the Node.js agent's built-in instrumentation with your own. For more information, see New Relic's Node.js instrumentation tutorial on Github. newrelic.instrumentDatastore(moduleName, onRequire [, onError]) Sets an instrumentation callback for a datastore module. This method is just like newrelic.instrument(), except it provides a datastore-specialized shim. For more information, see New Relic's Node.js datastore instrumentation tutorial on Github. newrelic.instrumentLoadedModule(moduleName, moduleInstance) The instrumentLoadedModule method allows you to add stock instrumentation to specific modules in situations where it's impossible to have require('newrelic'); as the first line of your app's main module. // load the agent const newrelic = require('newrelic') // module loaded before newrelic const expressModule = require('express') // instrument express _after_ the agent has been loaded newrelic.instrumentLoadedModule( 'express', // the module's name, as a string expressModule // the module instance ); This method cannot instrument any arbitrary module. Its purpose is to add modules that were missed because the agent was not loaded as the first thing in your program. The instrumentLoadedModule method can only instrument modules the agent would normally instrument. You can see a list of these modules in the agent's lib/instrumentations module. newrelic.instrumentMessages(moduleName, onRequire [, onError]) Sets an instrumentation callback for a message service client module. This method is just like newrelic.instrument(), except it provides a message-service-specialized shim. For more information, see New Relic's Node.js message service instrumentation tutorial on Github. newrelic.instrumentWebframework(moduleName, onRequire [, onError]) Sets an instrumentation callback for a web framework module. This method is just like newrelic.instrument(), except it provides a web-framework-specialized shim. For more information, see New Relic's Node.js web framework instrumentation tutorial on Github. newrelic.startWebTransaction(url, handle) Instrument the specified web transaction. Using this API call, you can instrument transactions that New Relic does not automatically detect. The url defines the transaction name and needs to be static. Do not include variable data such as user ID. The handle defines the function you want to instrument. New Relic will capture any metrics that would be captured by auto-instrumentation, as well as manual instrumentation via startSegment(). You must handle custom transactions manually by calling newrelic.getTransaction() at the start of your transaction, and then call transaction.end() when you are finished. New Relic begins timing the transaction when newrelic.startWebTransaction() is called and ends the transaction when transaction.end() is called. You can also return a promise to indicate the end of the transaction. Please note that if this promise rejects, it does not automatically hook into New Relic’s error tracking. This needs to be done manually with noticeError(). newrelic.startBackgroundTransaction(name, [group], handle) Instrument the specified background transaction. Using this API call, you can expand New Relic's instrumentation to capture data from background transactions. The name defines the transaction name and needs to be static. Do not include variable data such as user ID. The group is optional, and it allows you to group similar jobs together via the transaction type in the user interface. Like name, the group needs to be static. The handle defines a function that includes the entire background job you want to instrument. New Relic will capture any metrics that would be captured by auto-instrumentation, as well as manual instrumentation via startSegment(). You must handle custom transactions manually by calling newrelic.getTransaction() at the start of your transaction, and then call transaction.end() when you are finished. New Relic begins timing the transaction when newrelic.startBackgroundTransaction() is called and ends the transaction when transaction.end() is called. You can also return a promise to indicate the end of the transaction. Please note that if this promise rejects, it does not automatically hook into New Relic’s error tracking. This needs to be done manually with noticeError(). newrelic.getTransaction() Returns a handle on the currently executing transaction. This handle can then be used to interact with a given transaction safely from any context. It is best used with newrelic.startWebTransaction() and newrelic.startBackgroundTransaction(). Please refer to the transaction handle section for more details. newrelic.endTransaction() End the current web or background custom transaction. This method requires being in the correct transaction context when called. This API call takes no arguments. newrelic.startSegment(name, record, handler, callback) Instrument a particular method to improve visibility into a transaction, or optionally turn it into a metric. The name defines a name for the segment. This name will be visible in transaction traces and as a new metric in the New Relic UI. The record flag defines whether the segment should be recorded as a metric. The handler is the function you want to track as a segment. The optional callback is a function passed to the handler to fire after its work is done. The agent begins timing the segment when startSegment is called. The segment is ended when either the handler finishes executing, or callback is fired, if it is provided. Custom metrics API calls Use these API calls to record additional arbitrary metrics: newrelic.recordMetric(name, value) Use recordMetric to record an event-based metric, usually associated with a particular duration. The name must be a string following standard metric naming rules. The value will usually be a number, but it can also be an object. When value is a numeric value, it should represent the magnitude of a measurement associated with an event; for example, the duration for a particular method call. When value is an object, it must contain count, total, min, max, and sumOfSquares keys, all with number values. This form is useful to aggregate metrics on your own and report them periodically; for example, from a setInterval. These values will be aggregated with any previously collected values for the same metric. The names of these keys match the names of the keys used by the platform API. newrelic.incrementMetric(name, [amount]) Use incrementMetric to update a metric that acts as a simple counter. The count of the selected metric will be incremented by the specified amount, defaulting to 1. Custom events API calls Use these API calls to record additional events: newrelic.recordCustomEvent(eventType, attributes) Use recordCustomEvent to record an event-based metric, usually associated with a particular duration. The eventType must be an alphanumeric string less than 255 characters. The attributes must be an object of key and value pairs. The keys must be shorter than 255 characters, and the values must be string, number, or boolean. Recording a custom event The following example demonstrates recording a custom event with multiple attributes. const attributes = { attribute1: 'value1', attribute2: 2 } newrelic.recordCustomEvent('MessagingEvent', attributes) Transaction handle methods This section details the methods provided by the TransactionHandle class instance that can be obtained through newrelic.getTransaction(). Use these methods to interact directly with the current transaction: transactionHandle.end([callback]) Use transactionHandle.end to end the transaction referenced by the handle instance. The callback is invoked when the transaction has fully ended. The finished transaction passed to the callback as the first argument. transactionHandle.ignore() Use transactionHandle.ignore to ignore the transaction referenced by the handle instance. transactionHandle.insertDistributedTraceHeaders(headers) This API requires distributed tracing to be enabled. For context on how to use this call and its partner call acceptDistributedTraceHeaders, first read Enable distributed tracing with agent APIs. transactionHandle.insertDistributedTraceHeaders is used to implement distributed tracing. It modifies the headers map that is passed in by adding W3C Trace Context headers and New Relic Distributed Trace headers. The New Relic headers can be disabled with distributed_tracing.exclude_newrelic_header: true in the config. This method replaces the deprecated createDistributedTracePayload method, which only creates New Relic Distributed Trace payloads. Generating distributed trace headers In the following example, by calling insertDistributedTraceHeaders with an empty object, the appropriate Distributed Trace headers and W3C Trace Context headers will be generated for the transaction. // Call newrelic.getTransaction to retrieve a handle on the current transaction. const transactionHandle = newrelic.getTransaction() // This could be a header object from an incoming request as well const headersObject = {} newrelic.startBackgroundTransaction('background task', function executeTransaction() { const transaction = newrelic.getTransaction() // generate the headers transaction.insertDistributedTraceHeaders(headersObject) }) transactionHandle.acceptDistributedTraceHeaders(transportType, headers) This API requires distributed tracing to be enabled. For context on how to use this call and its partner call insertDistributedTraceHeaders, first read Enable distributed tracing with agent APIs. transactionHandle.acceptDistributedTraceHeaders is used to instrument the called service for inclusion in a distributed trace. It links the spans in a trace by accepting a payload generated by insertDistributedTraceHeaders or generated by some other W3C Trace Context compliant tracer. This method accepts the headers of an incoming request, looks for W3C Trace Context headers, and if not found, falls back to New Relic distributed trace headers. This method replaces the deprecated acceptDistributedTracePayload method, which only handles New Relic distributed trace payloads. transportType should be one of the following strings: AMQP HTTP HTTPS IronMQ JMS Kafka Other Queue Unknown headers should be an object containing all the headers in the incoming request. The keys must be lowercase. Accept incoming distributed trace headers The following example demonstrates adding distributed trace headers retrieved from a Kafka message. In this example, we assume that the incoming Kafka message has Distributed Trace headers inserted. // incoming Kafka message headers const headersObject = message.headers // Call newrelic.getTransaction to retrieve a handle on the current transaction. const transactionHandle = newrelic.getTransaction() newrelic.startBackgroundTransaction('background task', function executeTransaction() { const transaction = newrelic.getTransaction() // accept the headers transaction.acceptDistributedTraceHeaders('Kafka', headersObject) }) transactionHandle.createDistributedTracePayload() This method is deprecated and will be fully removed in the next major release! Please use insertDistributedTraceHeaders This API requires distributed tracing to be enabled. For instructions on how to use this call, along with its partner call acceptDistributedTracePayload, see Enable distributed tracing with agent APIs. This call is used to implement distributed tracing. It generates a payload that is read by the receiving application with acceptDistributedTracePayload. Note: In order to maintain proper ordering of spans in a trace, you must generate the payload in the context of the span that sends it. The DistributedTracePayload object has two available methods used for generating the payload in different formats: DistributedTracePayload#text: returns a JSON representation of the payload. Link a nested background transaction // Call newrelic.getTransaction to retrieve a handle on the current transaction. var transactionHandle = newrelic.getTransaction() var payload = transactionHandle.createDistributedTracePayload() var jsonPayload = payload.text() newrelic.startBackgroundTransaction('background task', function executeTransaction() { var backgroundHandle = newrelic.getTransaction() // Link the nested transaction by accepting the payload with the background transaction's handle backgroundHandle.acceptDistributedTracePayload(jsonPayload) }) DistributedTracePayload#httpSafe: returns a base64 encoded JSON representation of the payload. Place payload on an outgoing request // Call newrelic.getTransaction to retrieve a handle on the current transaction. var transactionHandle = newrelic.getTransaction() var payload = transactionHandle.createDistributedTracePayload() // Place the base64 encoded value on an outbound request header. req.headers[myTracingHeader] = payload.httpSafe() transactionHandle.acceptDistributedTracePayload(payload) This method is deprecated and will be fully removed in the next major release! Please use acceptDistributedTraceHeaders This API requires distributed tracing to be enabled. For context on how to use this call and its partner call createDistributedTracePayload, first read Enable distributed tracing with agent APIs. transactionHandle.acceptDistributedTracePayload is used to instrument the called service for inclusion in a distributed trace. It links the spans in a trace by accepting the payload generated by createDistributedTracePayload. transactionHandle.isSampled() Returns whether this trace is being sampled. Other API calls New Relic's Node.js agent includes additional API calls. newrelic.addCustomAttribute(name, value) Set a custom attribute value to be displayed along with the transaction trace in the New Relic UI. This must be called within the context of a transaction so it has a place to set the custom attributes. Custom attributes will appear in New Relic APM's transaction trace detail view and in errors for the transaction. Add custom attribute newrelic.addCustomAttribute('attribute1', 'value1') If you want to use your custom attributes, avoid using any of the reserved terms used by NRQL when naming them. newrelic.addCustomAttributes(attributes) Set multiple custom attribute values to be displayed along with the transaction trace in the New Relic UI. The attributes should be passed as a single object. This must be called within the context of a transaction so it has a place to set the custom attributes. Custom attributes will appear in the transaction trace detail view and in errors for the transaction. Adding custom attributes const attributes = { attribute1: 'value1', attribute2: 2 } newrelic.addCustomAttributes(attributes) If you want to use your custom attributes, avoid using any of the reserved terms used by NRQL when naming them. newrelic.addCustomSpanAttribute(name, value) Set a custom span attribute value to be displayed along with a transaction trace span in the New Relic UI. This must be called within the context of an active segment/span so it has a place to set the custom span attributes. Custom span attributes will appear in the Attributes section of the span detail view. Add custom span attribute newrelic.addCustomSpanAttribute('attribute1', 'value') This API requires distributed tracing and span events to be enabled. If you want to use your custom span attributes, avoid using any of the reserved terms used by NRQL when naming them. newrelic.addCustomSpanAttributes(attributes) Set multiple custom span attribute values to be displayed along with the transaction trace spans in the New Relic UI. The attributes should be passed as a single object. This must be called within the context of an active segment/span so it has a place to set the custom span attributes. Custom span attributes will appear in the Attributes section of the span detail view. Add custom span attributes const attributes = { attribute1: 'value1', attribute2: 'value2' } newrelic.addCustomSpanAttributes(attributes) This API requires distributed tracing and span events to be enabled. If you want to use your custom span attributes, avoid using any of the reserved terms used by NRQL when naming them. newrelic.getBrowserTimingHeader() Returns the HTML snippet to be inserted into the header of HTML pages to enable New Relic Browser. The HTML will instruct the browser to fetch a small JavaScript file and start the page timer. newrelic.setIgnoreTransaction(ignored) Tell the module whether or not to ignore a given request. This allows you to explicitly filter long-polling, irrelevant routes or requests you know will be time-consuming. This also allows you to gather metrics for requests that otherwise would be ignored. To ignore the transaction, set the parameter to true will ignore the transaction. To prevent a transaction from being ignored with this function, pass the parameter false. Passing null or undefined will not change whether the transaction is ignored. newrelic.noticeError(error, [customParameters]) Use this call if your app is doing its own error handling with domains or try/catch clauses, but you want all of the information about how many errors are coming out of the app to be centrally managed. Unlike other Node.js calls, this can be used outside of route handlers, but it will have additional context if called from within transaction scope. Errors recorded using this method do not obey the ignore_status_codes configuration value. newrelic.shutdown([options], callback) Use this method to gracefully shut down the agent. options options.collectPendingData - type boolean - Tell the agent whether to send any pending data to the New Relic collector before shutting down. options.timeout - type number (ms) - The default time before forcing a shutdown. When collectPendingData is true, the agent will wait for a connection before shutting down. This timeout is useful for short lived processes, like AWS Lambda, in order to keep the process from staying open too long, while trying to connect. Example: newrelic.shutdown({collectPendingData: true, timeout: 3000}, (error) => { process.exit() }) newrelic.getLinkingMetadata() Returns key/value pairs which can be used to link traces or entities. It will only contain items with meaningful values. For instance, if distributed tracing is disabled, trace.id will not be included. newrelic.getTraceMetadata() Returns and object containing the current trace ID and span ID. This API requires distributed tracing to be enabled or an empty object will be returned. Rules for naming and ignoring requests If you do not want to put calls to the New Relic module directly into your application code, you can use pattern-based rules to name requests. There are two sets of rules: one for renaming requests, and one to mark requests to be ignored by New Relic's instrumentation. Here is the structure for rules in New Relic's Node.js agent. rules.name A list of rules of the format {pattern : \"pattern\", name : \"name\"} for matching incoming request URLs to pattern and naming the matching New Relic transaction's name. This acts as a regex replace, where you can set the pattern either as a string, or as a JavaScript regular expression literal, and both pattern and name are required. When passing a regex as a string, escape backslashes, as the agent does not keep them when given as a string in a pattern. Define your configuration rules from the most specific to the most general, as the patterns will be evaluated in order and are terminal in nature. For more information, see the naming guidelines. This can also be set with the environment variable NEW_RELIC_NAMING_RULES, with multiple rules passed in as a list of comma-delimited JSON object literals: NEW_RELIC_NAMING_RULES='{\"pattern\":\"^t\",\"name\":\"u\"},{\"pattern\":\"^u\",\"name\":\"t\"}' Optional rules attributes Additional optional attributes are available: Optional rules attributes Description terminate_chain Default: true When set to true (default), no further rules will be evaluated if this rule is a match. Setting this to false is useful when multiple rules should be used together. For example, one rule could be replacing a common pattern in many different URLs, while subsequent rule(s) would be more specific. replace_all Default: false When set to true, all matches of the pattern will be replaced. Otherwise, only the first match will be replaced. Using the g flag with regular expression literal will have the same effect. For example: pattern: '[0-9]+', replace_all: true This has the same effect as pattern: /[0-9]+/g. precedence By default the rules are evaluated in order, from first to last. If you prefer to have complete control over the order, you can give each rule a precedence attribute. The precedence is an integer number, and rules are evaluated in ascending order. If precedence is not explicitly defined, it will be set to 500 by default. Additional attributes are ignored. Testing your naming rules The Node.js agent comes with a command-line tool for testing naming rules. For more information, run the following command in terminal window in a directory where your app is installed: node node_modules/.bin/newrelic-naming-rules Naming rule examples Here are some examples of naming rules and the results. Match full URL pattern: \"^/items/[0-9]+$\", name: \"/items/:id\" will result in: /items/123 => /items/:id /orders/123 => /orders/123 (not replaced since the rule is a full match) Replace first match in URL pattern: \"[0-9]+\", name: \":id\" will result in: /orders/123 => /orders/:id /items/123 => /items/:id /orders/123/items/123 => /orders/:id/items/123 Replace all matches in any URL pattern: \"[0-9]+\", name: \":id\", replace_all: true will result in: /orders/123/items/123 => /orders/:id/items/:id Match group references Using regular expression match group references: pattern: '^/(items|orders)/[0-9]+$', name: '/\\\\1/:id' will result in: /orders/123 => /orders/:id /items/123 => /items/:id rules.ignore This can also be set via the environment variable NEW_RELIC_IGNORING_RULES, with multiple rules passed in as a list of comma-delimited patterns. Currently there is no way to escape commas in patterns. NEW_RELIC_IGNORING_RULES='^/socket\\.io/\\*/xhr-polling,ignore_me' Here are full examples of how rules are included in the configuration file: Naming rule example // newrelic.js exports.config = { // other configuration rules : { name : [ { pattern: \"/tables/name-here\", name: \"/name-hererule1\" } ] } Ignoring rule example If you are using socket.io, you will have a use case for ignoring rules right out of the box. To keep socket.io long-polling from dominating your response-time metrics and affecting the Apdex metrics for your application, add a rule such as: // newrelic.js exports.config = { // other configuration rules : { ignore : [ '^\\/socket\\.io\\/.*\\/xhr-polling' ] } }; API calls for rules Here are the API calls for naming and ignoring rules with New Relic's Node.js agent. newrelic.addNamingRule(pattern, name) Programmatic version of rules.name. Once naming rules are added, they cannot be removed until the Node process is restarted. They can also be added via the Node.js agent's configuration. Both parameters are required. newrelic.addIgnoringRule(pattern) Programmatic version of rules.ignore. Once ignoring rules are added, they cannot be removed until the Node process is restarted. They can also be added via the Node.js agent's configuration. This parameter is required. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "type": "docs", "document_type": "page", - "info": "Intro to New Relic One API components", + "breadcrumb": "Contents / APM agents / Node.js agent / API guides", + "info": "How to use the Node.js API to name, rename, and ignore requests, and to read router names with New Relic's Node.js agent.", + "nodeid": 1596, "sections": [ - "Intro to New Relic One API components", - "Components of the SDK", - "UI components", - "Chart components", - "Query and storage components", - "Platform APIs" + "Node.js agent", + "Getting started", + "Installation and configuration", + "Supported features", + "Attributes", + "API guides", + "Hosting services", + "Troubleshooting", + "Node.js agent API", + "Request names", + "Requirements", + "Avoid metric grouping issues", + "Guidelines", + "Load the request naming API", + "Request API calls", + "Custom instrumentation API calls", + "Custom metrics API calls", + "Custom events API calls", + "Transaction handle methods", + "Other API calls", + "Rules for naming and ignoring requests", + "Optional rules attributes", + "Testing your naming rules", + "Naming rule examples", + "API calls for rules", + "For more help" ], - "title": "Intro to New Relic One API components", + "title": "Node.js agent API", "popularity": 1, - "external_id": "3620920c26bcd66c59c810dccb1200931b23b8c2", + "external_id": "fb49a4025c716c56046403d960b0802bc7485af2", + "category_1": "Node.js agent", + "category_2": "API guides", "image": "", - "url": "https://developer.newrelic.com/explore-docs/intro-to-sdk/", - "published_at": "2020-08-18T02:07:10Z", - "updated_at": "2020-08-14T01:47:12Z", + "url": "https://docs.newrelic.com/docs/agents/nodejs-agent/api-guides/nodejs-agent-api", + "published_at": "2020-08-18T08:18:21Z", + "updated_at": "2020-08-18T08:18:21Z", + "category_0": "APM agents", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.2660732, + "_score": 0.10052979, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Intro to New Relic One API components", - "sections": "Query and storage components", - "info": "Intro to New Relic One API components", - "body": " is with NerdGraph, our GraphQL endpoint. This can be queried using NerdGraphQuery. To simplify use of NerdGraph queries, we provide some components with pre-defined queries. For more on using NerdGraph, see Queries and mutations. We also provide storage for storing small data sets, such as configuration" + "title": "Node.js agent API", + "sections": "Node.js agent API", + "info": "How to use the Node.js API to name, rename, and ignore requests, and to read router names with New Relic's Node.js agent.", + "category_0": "APM agents", + "category_1": "Node.js agent", + "category_2": "API guides", + "body": " for slow transaction traces and have enabled capture_params in your config file, the transaction trace will also have the request's parameters and their values attached to it. If you are dissatisfied with the request names that the Node.js agent uses, you can use API calls to create more", + "breadcrumb": "Contents / APM agents / Node.js agent / API guides" }, - "id": "5efa989e28ccbc4071307de5" + "id": "540a92a2c75d073d3d0006f7" } ], "/explore-docs/query-and-store-data": [ @@ -3196,18 +3293,25 @@ ], "title": "Intro to NerdStorage", "popularity": 1, + "tags": [ + "nerdstorage", + "nerdstorage components", + "new relic one apps", + "data access" + ], "external_id": "709e06c25376d98b2191ca369b4d139e5084bd62", "image": "", "url": "https://developer.newrelic.com/explore-docs/nerdstorage/", - "published_at": "2020-08-18T02:11:48Z", + "published_at": "2020-08-19T01:49:36Z", "updated_at": "2020-08-14T01:50:34Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.25488237, + "_score": 0.24944517, "_version": null, "_explanation": null, "sort": null, "highlight": { + "tags": "nerdstorage components", "body": " and EntityStorageMutation Each of these components can operate declaratively (for example, as part of your React rendering methods) or imperatively (by using the static methods for query and mutation). For more information on this, see Data querying and mutations. Permissions for working with NerdStorage In order" }, "id": "5efa989ee7b9d2048e7bab92" @@ -3257,7 +3361,7 @@ "category_0": "APM agents", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.028378151, + "_score": 0.027693383, "_version": null, "_explanation": null, "sort": null, @@ -3299,7 +3403,7 @@ "category_0": "Release notes", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.026818182, + "_score": 0.027504738, "_version": null, "_explanation": null, "sort": null, @@ -3347,7 +3451,7 @@ "category_0": "APM agents", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.02058597, + "_score": 0.019499775, "_version": null, "_explanation": null, "sort": null, @@ -3398,7 +3502,7 @@ "category_0": "APM agents", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.01595171, + "_score": 0.016358085, "_version": null, "_explanation": null, "sort": null, @@ -3410,665 +3514,244 @@ "id": "58ca4191e621f45edd466e7a" } ], - "/build-apps/publish-deploy": [ - { - "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build your own application launcher and follow the quick start instructions. The quick start automatically generates an API key for the account you select, and gives you the pre-populated commands to create a profile, generate your first \"Hello World\" app, and serve it locally. Tip Use the NR1 VS Code extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions. For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). Configure your CLI preferences nr1 config:set Sets a specific configuration value. nr1 config:get Shows a specific configuration. nr1 config:list Lists your configuration choices. nr1 config:delete Removes the value of a specific configuration. Set up your Nerdpacks nr1 nerdpack:clone Clones an open source Nerdpack from our GitHub repository. nr1 nerdpack:serve Serves your Nerdpack for testing and development purposes. nr1 nerdpack:uuid Shows or regenerates the UUID of a Nerdpack. nr1 nerdpack:publish Publishes your Nerdpack to New Relic. nr1 nerdpack:deploy Deploys a Nerdpack version to a specific channel. nr1 nerdpack:undeploy Undeploys a Nerdpack version from a specific channel. Manage your Nerdpack subscriptions nr1 subscription:set Subscribes your account to a Nerdpack and channel. nr1 subscription:list Lists all the Nerdpacks your account is subscribed to. nr1 subscription:unset Unsubscribes your account from a Nerdpack. Install and manage plugins nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin into the CLI for development. nr1 plugins:update Updates your installed plugins. nr1 plugins:uninstall Removes a plugin from the CLI. Manage catalog information nr1 catalog:info Shows the Nerdpack info stored in the catalog. nr1 catalog:submit Gathers and submits the catalog info on the current folder.", - "type": "developer", - "document_type": "page", - "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", - "sections": [ - "New Relic One CLI reference", - "Installing the New Relic One CLI", - "Tip", - "New Relic One CLI Commands", - "Get started", - "Configure your CLI preferences", - "Set up your Nerdpacks", - "Manage your Nerdpack subscriptions", - "Install and manage plugins", - "Manage catalog information" - ], - "title": "New Relic One CLI reference", - "popularity": 1, - "tags": [ - "New Relic One app", - "nerdpack commands" - ], - "external_id": "858339a44ead21c83257778ce60b4c352cd30d3b", - "image": "https://developer.newrelic.com/static/2c6d337608b38a3312b4fc740afe6167/7272b/developercenter.png", - "url": "https://developer.newrelic.com/explore-docs/nr1-cli/", - "published_at": "2020-08-18T02:07:10Z", - "updated_at": "2020-08-18T01:50:36Z", - "_index": "520d1d5d14cc8a32e600034b", - "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.29266515, - "_version": null, - "_explanation": null, - "sort": null, - "highlight": { - "title": "New Relic One CLI reference", - "sections": "New Relic One CLI reference", - "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", - "tags": "New Relic One app", - "body": ". For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet" - }, - "id": "5efa989e28ccbc535a307dd0" - }, - { - "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs in GitHub. Options --format string output text format [YAML, JSON, Text] (default \"JSON\") -h, --help help for newrelic --plain output compact text Copy Commands newrelic apm - Interact with New Relic APM newrelic completion - Generates shell completion functions newrelic config - Manage the configuration of the New Relic CLI newrelic documentation - Generate CLI documentation newrelic entity - Interact with New Relic entities newrelic nerdgraph - Execute GraphQL requests to the NerdGraph API newrelic nerdstorage - Read, write, and delete NerdStorage documents and collections. newrelic nrql - Commands for interacting with the New Relic Database newrelic profile - Manage the authentication profiles for this tool newrelic version - Show the version of the New Relic CLI newrelic workload - Interact with New Relic One workloads", - "type": "developer", - "document_type": "page", - "info": "The command line tools for performing tasks against New Relic APIs", - "sections": [ - "New Relic CLI Reference", - "New Relic CLI commands", - "Options", - "Commands" - ], - "title": "New Relic CLI Reference", - "popularity": 1, - "tags": "new relic cli", - "external_id": "471ed214caaf80c70e14903ec71411e2a1c03888", - "image": "", - "url": "https://developer.newrelic.com/explore-docs/newrelic-cli/", - "published_at": "2020-08-18T02:11:50Z", - "updated_at": "2020-08-14T01:47:12Z", - "_index": "520d1d5d14cc8a32e600034b", - "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.047144882, - "_version": null, - "_explanation": null, - "sort": null, - "highlight": { - "title": "New Relic CLI Reference", - "sections": "New Relic CLI Reference", - "info": "The command line tools for performing tasks against New Relic APIs", - "tags": "new relic cli", - "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs" - }, - "id": "5efa989ee7b9d2024b7bab97" - }, - { - "body": "Get started with the New Relic CLI 20 min Access the New Relic platform from the comfort of your terminal: you can use the New Relic CLI to manage entity tags, define workloads, record deployment markers, and much more. Our CLI has been designed for automating common tasks in your DevOps workflow. This guide walks you through the essentials of New Relic CLI, from install and configuration to basic usage. Before you begin For this guide you just need: Your New Relic personal API Key, which you can create from the Account settings of your New Relic account An instrumented application in your New Relic account Step 1 of 10 Install the New Relic CLI The New Relic CLI can be downloaded via Homebrew (macOS), Scoop (Windows), and Snapcraft (Linux). You can also download pre-built binaries for all platforms, including .deb and .rpm packages, and our Windows x64 .msi installer. Linux With Snapcraft installed, run: sudo snap install newrelic-cli macOS With Homebrew installed, run: brew install newrelic-cli Windows With Scoop installed, run: scoop bucket add newrelic-cli https://github.com/newrelic/newrelic-cli.git scoop install newrelic-cli Step 2 of 10 Create your New Relic CLI profile Now that you've installed the New Relic CLI, it's time to create your first profile. Profiles contain credentials and settings that you can apply to any CLI command, which is useful when switching between accounts. To create your first CLI profile, run the profiles add command. Note that you need to set the region of your New Relic account: use -r to set either us or eu (this is required). # Create the tutorial account for the US region newrelic profiles add -n tutorial --apiKey YOUR_NEW_RELIC_API_KEY -r YOUR_REGION # Set the profile as defaults newrelic profiles default -n tutorial Copy Step 3 of 10 Get your application details In this example, you are going to add tags to the application you've instrumented with New Relic. Tags are key-value pairs that can help you organize and filter your entities. An entity (for example, an application) can have a maximum of 100 key-value pairs tied to it. Before searching for your application using the New Relic CLI, write down or copy your Account ID and the name of your application in New Relic - you need both to find applications in the New Relic platform. Step 4 of 10 The New Relic CLI can retrieve your application details as a JSON object. To search for your APM application use the apm application search command. If you get an error, check that the account ID and application name you provided are correct. newrelic apm application search --accountId YOUR_ACCOUNT_ID --name NAME_OF_YOUR_APP Copy Step 5 of 10 If the account ID is valid, and the application name exists in your account, apm application search yields data similar to this example. When you've successfully searched for your application, look for the guid value. It's a unique identifier for your application. You should copy it or write it down. [ { accountId: YOUR_ACCOUNT_ID, applicationId: YOUR_APP_ID, domain: 'APM', entityType: 'APM_APPLICATION_ENTITY', guid: 'A_LONG_GUID', name: 'NAME_OF_YOUR_APP', permalink: 'https://one.newrelic.com/redirect/entity/A_LONG_GUID', reporting: true, type: 'APPLICATION', }, ]; Copy Step 6 of 10 Add a simple tag to your application Now that you have the GUID, you can point the New Relic CLI directly at your application. Adding a tag is the simplest way to try out the CLI capabilities (don't worry, tags can be deleted by using entity tags delete). Let's suppose that you want to add an environment tag to your application. Go ahead and add the dev:testing tag⁠ (or any other key-value pair) to your application using the entities tags create command. newrelic entity tags create --guid YOUR_APP_GUID --tag devkit:testing Copy Step 7 of 10 What if you want to add multiple tags? Tag sets come to the rescue! While tags are key-value pairs separated by colons, tag sets are comma separated lists of tags. For example: tag1:value1,tag2:value2 To add multiple tags at once to your application, modify and run the following snippet. newrelic entity tags create --guid YOUR_APP_GUID --tag tag1:test,tag2:test Copy Adding tags is an asynchronous operation: this means it could take a while for the tags to get created. Step 8 of 10 You've created and added some tags to your application, but how do you know they're there? You need to retrieve your application's tags. To retrieve your application's tags, use the entity tags get command. newrelic entity tags get --guid YOUR_APP_GUID All tags associated with your application are retrieved as a JSON array. [ { Key: 'tag1', Values: ['true'], }, { Key: 'tag2', Values: ['test'], }, { Key: 'tag3', Values: ['testing'], }, // ... ]; Copy Step 9 of 10 Bonus step: Create a deployment marker Deployments of applications often go wrong. Deployment markers are labels that, when attached to your application data, help you track deployments and troubleshoot what happened. To create a deployment marker, run the apm deployment create command using the same Application ID from your earlier search. newrelic apm deployment create --applicationId YOUR_APP_ID --revision $(git describe --tags --always) Copy Step 10 of 10 Notice that the JSON response includes the revision and timestamp of the deployment. This workflow could be built into a continuous integration or continuous deployment (CI/CD) system to help indicate changes in your application's behavior after deployments. Here is an example. { \"id\": 37075986, \"links\": { \"application\": 204261368 }, \"revision\": \"v1.2.4\", \"timestamp\": \"2020-03-04T15:11:44-08:00\", \"user\": \"Developer Toolkit Test Account\" } Copy Next steps Have a look at all the available commands. For example, you could create a New Relic workflow using workload create If you'd like to engage with other community members, visit our New Relic Explorers Hub page. We welcome feature requests or bug reports on GitHub.", - "type": "developer", - "document_type": "page", - "info": "Learn the essentials of the New Relic CLI, from install and configuration to basic usage.", - "sections": [ - "Get started with the New Relic CLI", - "Before you begin", - "Install the New Relic CLI", - "Linux", - "macOS", - "Windows", - "Create your New Relic CLI profile", - "Get your application details", - "Add a simple tag to your application", - "Bonus step: Create a deployment marker", - "Next steps" - ], - "title": "Get started with the New Relic CLI", - "popularity": 1, - "tags": [ - "api key", - "New Relic CLI", - "Tags", - "Entity", - "Deployment markers" - ], - "external_id": "531f2f3985bf64bb0dc92a642445887095048882", - "image": "", - "url": "https://developer.newrelic.com/automate-workflows/get-started-new-relic-cli/", - "published_at": "2020-08-18T02:06:05Z", - "updated_at": "2020-08-08T01:41:47Z", - "_index": "520d1d5d14cc8a32e600034b", - "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.030464739, - "_version": null, - "_explanation": null, - "sort": null, - "highlight": { - "title": "Get started with the New Relic CLI", - "sections": "Create your New Relic CLI profile", - "info": "Learn the essentials of the New Relic CLI, from install and configuration to basic usage.", - "tags": "New Relic CLI", - "body": "Get started with the New Relic CLI 20 min Access the New Relic platform from the comfort of your terminal: you can use the New Relic CLI to manage entity tags, define workloads, record deployment markers, and much more. Our CLI has been designed for automating common tasks in your DevOps workflow" - }, - "id": "5efa999c196a67c4e1766461" - }, - { - "body": "Add tables to your New Relic One application 30 min Tables are a popular way of displaying data in New Relic applications. For example, with the query builder you can create tables from NRQL queries. Whether you need to have more control over tables or you're importing third-party data, you can build your own tables into your New Relic One application. In this guide, you are going to build a sample table using various New Relic One components. Before you begin If you haven't already installed the New Relic One CLI, step through the quick start in New Relic One. This process also gets you an API key. In addition, to complete the steps in this guide, you need a GitHub account, and to have Node.js installed on your machine. See [Setting up your development environment](/build-apps/set-up-dev-env) for more info. Clone and set up the example application Step 1 of 4 Clone the nr1-how-to example application from GitHub to your local machine. Then, navigate to the app directory. The example app lets you experiment with tables. git clone https://github.com/newrelic/nr1-how-to.git` cd nr1-how-to/create-a-table/nerdlets/create-a-table-nerdlet` Copy Step 2 of 4 Edit the index.json file and set this.accountId to your Account ID as shown in the example. export default class Nr1HowtoAddTimePicker extends React.Component { constructor(props){ super(props) this.accountId = YOUR_ACCOUNT_ID; } ... } Copy Step 3 of 4 Run the demo application Change the directory back to nr1-how-to/create-a-table. Before you can load the demo application, you need to update its unique id by invoking the New Relic One CLI. Once you've assigned a new UUID to the app, install the dependencies and serve the demo app locally, so that you can test any change live in your browser. nr1 nerdpack:uuid -gf # Update the app unique ID npm install # Install dependencies nr1 nerdpack:serve # Serve the demo app locally Copy Step 4 of 4 Open one.newrelic.com/?nerdpacks=local in your browser. Click Apps*, and then in the Other apps section, you should see a Create a table** launcher. That's the demo application you're going to work on. Go ahead and select it. Have a good look at the demo app. There's a TableChart on the left side named Transaction Overview, with an AreaChart next to it. You'll use Table components to add a new table in the second row. Work with table components Step 1 of 10 Navigate to the `nerdlets/create-a-table-nerdlet` subdirectory and open the `index.js` file. Add the following components to the import statement at the top of the file so that it looks like the example: Table TableHeader TableHeaderCell TableRow TableRowCell import { Table, TableHeader, TableHeaderCell, TableRow, TableRowCell, PlatformStateContext, Grid, GridItem, HeadingText, AreaChart, TableChart, } from 'nr1'; Copy Step 2 of 10 Add a basic Table component Locate the empty GridItem in index.js: This is where you start building the table. Add the initial component. The items property collects the data by calling _getItems(), which contains sample values.
; Copy Step 3 of 10 Add the header and rows As the Table component renders a fixed number of header cells and rows, your next step is adding header components, as well as a function that returns the required table rows. Inside of the Table component, add the TableHeader and then a TableHeaderCell child for each heading. Since you don't know how many rows you'll need, your best bet is to call a function to build as many TableRows as items returned by _getItems(). Application Size Company Team Commit ; { ({ item }) => ( {item.name} {item.value} {item.company} {item.team} {item.commit} ); } Copy Step 4 of 10 Take a look at the application running in New Relic One: you should see something similar to the screenshot below. Step 5 of 10 Replace standard table cells with smart cells The New Relic One library includes cell components that can automatically format certain data types, like users, metrics, and entity names. The table you've just created contains columns that can benefit from those components: Application (an entity name) and Size (a metric). Before you can use EntityTitleTableRowCell and MetricTableRowCell, you have to add them to the import statement first. import { EntityTitleTableRowCell, MetricTableRowCell, ... /* All previous components */ } from 'nr1'; Copy Step 6 of 10 Update your table rows by replacing the first and second TableRowCells with entity and metric cells. Notice that EntityTitleTableRowCell and MetricTableRowCell are self-closing tags. { ({ item }) => ( {item.company} {item.team} {item.commit} ); } Copy Step 7 of 10 Time to give your table a second look: The cell components you've added take care of properly formatting the data. Step 8 of 10 Add some action to your table! Tables are great, but interactive tables can be better: As a last update, you are going to allow users to act on each data row. Add the _getActions() method to your index.js file, right before _getItems(). As you may have guessed from the code, _getActions() spawns an alert box when you click Team or Commit cells. _getActions() { return [ { label: 'Alert Team', iconType: TableRow.ACTIONS_ICON_TYPE.INTERFACE__OPERATIONS__ALERT, onClick: (evt, { item, index }) => { alert(`Alert Team: ${item.team}`); }, }, { label: 'Rollback Version', iconType: TableRow.ACTIONS_ICON_TYPE.INTERFACE__OPERATIONS__UNDO, onClick: (evt, { item, index }) => { alert(`Rollback from: ${item.commit}`); }, }, ]; } Copy Step 9 of 10 Find the TableRow component in your return statement and point the actions property to _getActions(). The TableRow actions property defines a set of actions that appear when the user hovers over a table row. Actions have a mandatory text and an onClick callback, but can also display an icon or be disabled if needed. Copy Step 10 of 10 Go back to your application and try hovering over any of the rows: Notice how the two available actions appear. When you click them, a function triggers with the selected row data as an argument, and an alert displays in your browser. Next steps You've built a table into a New Relic One application, using components to format data automatically and provide contextual actions. Well done! Keep exploring the Table components, their properties, and how to use them, in our SDK documentation.", - "type": "developer", - "document_type": "page", - "info": "Add a table to your New Relic One app.", - "sections": [ - "Add tables to your New Relic One application", - "Before you begin", - "Clone and set up the example application", - "Work with table components", - "Next steps" - ], - "title": "Add tables to your New Relic One application", - "popularity": 1, - "external_id": "7ff7a8426eb1758a08ec360835d9085fae829936", - "image": "https://developer.newrelic.com/static/e637c7eb75a9dc01740db8fecc4d85bf/1d6ec/table-new-cells.png", - "url": "https://developer.newrelic.com/build-apps/howto-use-nrone-table-components/", - "published_at": "2020-08-18T02:07:10Z", - "updated_at": "2020-08-14T01:46:10Z", - "_index": "520d1d5d14cc8a32e600034b", - "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.0036841223, - "_version": null, - "_explanation": null, - "sort": null, - "highlight": { - "title": "Add tables to your New Relic One application", - "sections": "Add tables to your New Relic One application", - "info": "Add a table to your New Relic One app.", - "body": "-a-table. Before you can load the demo application, you need to update its unique id by invoking the New Relic One CLI. Once you've assigned a new UUID to the app, install the dependencies and serve the demo app locally, so that you can test any change live in your browser. nr1 nerdpack:uuid -gf # Update" - }, - "id": "5efa989ee7b9d2ad567bab51" - }, - { - "body": "For accounts on our New Relic One pricing plan, this document explains: How to add and manage users User types and user groups This doc is for accounts on our New Relic One pricing plan. If you're on our original product-based pricing plan, see Original user roles. Not sure which you're on? See Overview of pricing and account/user structure. Manage users Here are some important user management tips to remember and share with your team members: Basic users, who are free users, can self-serve to become billable full users. A New Relic user can have a maximum of either three concurrent active sessions, or three unique IP addresses in use at any given time. To manage users: from one.newrelic.com, select Apps from the top navigation, and then select User management. User type For accounts on the New Relic One pricing plan, the user type determines the monitoring and analysis features a user has access to. (Note that this does not control account admin-related permissions; that's determined by the user group.) User types include: Basic user: These users are free and have access to basic features like setting up reporting of data to New Relic, running queries of your data, making custom charts and dashboards, and setting up alert notifications. These users do not have access to Full-Stack Observability features. For details, see the capability table below. Full user: These users have access to Full-Stack Observability features, including our curated UI experiences for APM, infrastructure monitoring, browser monitoring, mobile monitoring, and synthetic monitors. The Standard pricing tier includes one full user. For details, see the capability table below. The number of full users is not the only pricing factor: Learn more about pricing. For details about full user and basic user capabilities, expand this collapser: Capabilities for full users vs. basic users Below are some important differences between basic user and full user capabilities. In short, basic users have access to our Telemetry Data Platform and Applied Intelligence (read-only) features, while full users have access to that plus Full-Stack Observability features. Features Full user Basic user Full-Stack Observability (New Relic-built UI experiences) Application performance monitoring (APM) UI fa-check Infrastructure monitoring UI fa-check Digital Experience Monitoring (Browser, Mobile, Synthetics) UI fa-check Serverless monitoring UI fa-check Logs in context with other UI experiences fa-check Synthetics checks fa-check New Relic Edge with Infinite Tracing (tail-based sampling) fa-check (Pro and Enterprise) Subscribe to New Relic One catalog apps fa-check Applied Intelligence (AI) Proactive Detection fa-check fa-check (read-only) Incident Intelligence fa-check fa-check (read-only) Telemetry Data Platform Data ingest from any source (Metrics, Events, Logs, Traces) fa-check fa-check Alerts and notifications fa-check fa-check Interactive query interface fa-check fa-check Custom charts and dashboards (not New Relic-built) fa-check fa-check Encryption at rest fa-check fa-check Standard data retention fa-check fa-check NerdGraph (GraphQL) API fa-check fa-check Security and compliance fa-check fa-check Integrations fa-check fa-check Data management fa-check fa-check Logs UI fa-check fa-check Build custom New Relic One apps fa-check fa-check User group When full users (not basic users) are added, there are additional choices related to account administration. For the Standard pricing tier, the two user groups available are: Admin: Adding someone to the Admin group gives them configuration and administrative abilities like adding/editing users, editing account and billing settings, and configuring some settings. User: Adding someone to the User group allows them to use and configure features but not manage users or billing. Coming soon: Pro and Enterprise tiers include additional admin functionalities and group-related features. Capability limitations There are some temporary limitations for users on the newer model, mainly around API access. For details, see Limitations. Query usage data See Query usage data. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", - "type": "docs", - "document_type": "page", - "breadcrumb": "Contents / New Relic accounts / Accounts and billing / New Relic One pricing and users", - "info": "For New Relic accounts on our New Relic One pricing plan, an explanation of user roles. ", - "nodeid": 39356, - "sections": [ - "Accounts and billing", - "Account setup", - "Account structure", - "New Relic One pricing and users", - "General account settings", - "Automated user management", - "SAML single sign on", - "Partner install", - "New Relic One users and roles", - "Manage users", - "User type", - "User group", - "Capability limitations", - "Query usage data", - "For more help" - ], - "title": "New Relic One users and roles ", - "popularity": 1, - "external_id": "6b424e8f440119aa9d9529ef1cf91fac524e2991", - "category_1": "Accounts and billing", - "category_2": "New Relic One pricing and users", - "image": "", - "url": "https://docs.newrelic.com/docs/accounts/accounts-billing/new-relic-one-pricing-users/users-roles", - "published_at": "2020-08-18T17:39:18Z", - "updated_at": "2020-08-15T05:13:24Z", - "category_0": "New Relic accounts", - "_index": "520d1d5d14cc8a32e600034b", - "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.0031960718, - "_version": null, - "_explanation": null, - "sort": null, - "highlight": { - "title": "New Relic One users and roles ", - "sections": "New Relic One pricing and users", - "info": "For New Relic accounts on our New Relic One pricing plan, an explanation of user roles. ", - "category_0": "New Relic accounts", - "category_1": "Accounts and billing", - "category_2": "New Relic One pricing and users", - "body": " Overview of pricing and account/user structure. Manage users Here are some important user management tips to remember and share with your team members: Basic users, who are free users, can self-serve to become billable full users. A New Relic user can have a maximum of either three concurrent active", - "breadcrumb": "Contents / New Relic accounts / Accounts and billing / New Relic One pricing and users" - }, - "id": "5f22d159196a67f322b53d0a" - } - ], - "/build-apps/build-hello-world-app": [ - { - "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build your own application launcher and follow the quick start instructions. The quick start automatically generates an API key for the account you select, and gives you the pre-populated commands to create a profile, generate your first \"Hello World\" app, and serve it locally. Tip Use the NR1 VS Code extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions. For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). Configure your CLI preferences nr1 config:set Sets a specific configuration value. nr1 config:get Shows a specific configuration. nr1 config:list Lists your configuration choices. nr1 config:delete Removes the value of a specific configuration. Set up your Nerdpacks nr1 nerdpack:clone Clones an open source Nerdpack from our GitHub repository. nr1 nerdpack:serve Serves your Nerdpack for testing and development purposes. nr1 nerdpack:uuid Shows or regenerates the UUID of a Nerdpack. nr1 nerdpack:publish Publishes your Nerdpack to New Relic. nr1 nerdpack:deploy Deploys a Nerdpack version to a specific channel. nr1 nerdpack:undeploy Undeploys a Nerdpack version from a specific channel. Manage your Nerdpack subscriptions nr1 subscription:set Subscribes your account to a Nerdpack and channel. nr1 subscription:list Lists all the Nerdpacks your account is subscribed to. nr1 subscription:unset Unsubscribes your account from a Nerdpack. Install and manage plugins nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin into the CLI for development. nr1 plugins:update Updates your installed plugins. nr1 plugins:uninstall Removes a plugin from the CLI. Manage catalog information nr1 catalog:info Shows the Nerdpack info stored in the catalog. nr1 catalog:submit Gathers and submits the catalog info on the current folder.", - "type": "developer", - "document_type": "page", - "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", - "sections": [ - "New Relic One CLI reference", - "Installing the New Relic One CLI", - "Tip", - "New Relic One CLI Commands", - "Get started", - "Configure your CLI preferences", - "Set up your Nerdpacks", - "Manage your Nerdpack subscriptions", - "Install and manage plugins", - "Manage catalog information" - ], - "title": "New Relic One CLI reference", - "popularity": 1, - "tags": [ - "New Relic One app", - "nerdpack commands" - ], - "external_id": "858339a44ead21c83257778ce60b4c352cd30d3b", - "image": "https://developer.newrelic.com/static/2c6d337608b38a3312b4fc740afe6167/7272b/developercenter.png", - "url": "https://developer.newrelic.com/explore-docs/nr1-cli/", - "published_at": "2020-08-18T02:07:10Z", - "updated_at": "2020-08-18T01:50:36Z", - "_index": "520d1d5d14cc8a32e600034b", - "_type": "520d1d5d14cc8a32e600034c", - "_score": 1.0103776, - "_version": null, - "_explanation": null, - "sort": null, - "highlight": { - "title": "New Relic One CLI reference", - "sections": "New Relic One CLI reference", - "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", - "tags": "New Relic One app", - "body": ". For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet" - }, - "id": "5efa989e28ccbc535a307dd0" - }, - { - "body": "Nerdpack file structure A New Relic One application is represented by a Nerdpack folder, which can include one or more Nerdlet files, and (optionally) one or more launcher files. Here we explain: The file structure for a Nerdpack, a Nerdlet, and a launcher How to link a launcher file to a Nerdlet How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create a Nerdpack template that includes a Nerdlet and a launcher. Generate Nerdlet or launcher individually: Use the New Relic One CLI command nr1 create and choose either Nerdlet or launcher. This can be useful when adding Nerdlets to an existing Nerdpack. For documentation on generating and connecting Nerdpack components, see our app building guides and the New Relic One CLI command reference. Nerdpack file structure When you generate a Nerdpack template using the nr1 create command, it has the following file structure: my-nerdlet ├── README.md ├── launchers │   └── my-nerdlet-launcher │   ├── icon.png │   └── nr1.json ├── nerdlets │   └── my-nerdlet-nerdlet │   ├── index.js │   ├── nr1.json │   └── styles.scss ├── node_modules │   ├── js-tokens │   ├── loose-envify │   ├── object-assign │   ├── prop-types │   ├── react │   ├── react-dom │   ├── react-is │   └── scheduler ├── nr1.json ├── package-lock.json └── package.json Copy Nerdlet file structure A Nerdpack can contain one or more Nerdlets. A Nerdlet folder starts out with three default files, index.js, nr1.json, and styles.scss. Here is what the default files look like after being generated using the nr1 create command: index.js The JavaScript code of the Nerdlet. import React from 'react'; export default class MyAwesomeNerdpack extends React.Component { render() { return

Hello, my-awesome-nerdpack Nerdlet!

; } } Copy nr1.json The Nerdlet configuration file. { \"schemaType\": \"NERDLET\", \"id\": \"my-awesome-nerdpack-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\" } Copy Besides using the launcher as the access point for your application, you can also associate the application with a monitored entity to get it to appear in the entity explorer. To do this, add two additional fields to the config file of the first-launched Nerdlet: entities and actionCategory. In the following example, the Nerdlet has been associated with all Browser-monitored applications and will appear under the Monitor UI category : { \"schemaType\": \"NERDLET\", \"id\": \"my-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"Custom Data\", \"entities\": [{ \"domain\": \"BROWSER\", \"type\": \"APPLICATION\" }], \"actionCategory\": \"monitor\" } Copy To see this application in the UI, you would go to the entity explorer, select Browser applications, and select a monitored application. styles.scss An empty SCSS file for styling your application. icon.png The launcher icon that appears on the Apps page in New Relic One when an application is deployed. Launcher file structure Launchers have their own file structure. Note that: A launcher is not required; as an alternative to using a launcher, you can associate your application with a monitored entity. An application can have more than one launcher, which might be desired for an application with multiple Nerdlets. After generating a launcher using the nr1 create command, its folder contains two files: nr1.json The configuration file. { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy To connect a launcher to a Nerdlet, the rootNerdletId must match the id in the launched Nerdlet's nr1.json config file. For Nerdpacks with multiple Nerdlets, this needs to be done only for the first-launched Nerdlet. icon.png The icon displayed on the launcher for the app on the Apps page.", - "type": "developer", - "document_type": "page", - "info": "An overview of the Nerdpack File Structure", - "sections": [ - "Nerdpack file structure", - "Generate Nerdpack components", - "Nerdlet file structure", - "index.js", - "nr1.json", - "styles.scss", - "icon.png", - "Launcher file structure" - ], - "title": "Nerdpack file structure", - "popularity": 1, - "external_id": "c97bcbb0a2b3d32ac93b5b379a1933e7b4e00161", - "image": "", - "url": "https://developer.newrelic.com/explore-docs/nerdpack-file-structure/", - "published_at": "2020-08-18T02:07:10Z", - "updated_at": "2020-08-14T01:49:25Z", - "_index": "520d1d5d14cc8a32e600034b", - "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.7917644, - "_version": null, - "_explanation": null, - "sort": null, - "highlight": { - "title": "Nerdpack file structure", - "sections": "Nerdpack file structure", - "info": "An overview of the Nerdpack File Structure", - "body": " components, see our app building guides and the New Relic One CLI command reference. Nerdpack file structure When you generate a Nerdpack template using the nr1 create command, it has the following file structure: my-nerdlet ├── README.md ├── launchers │   └── my-nerdlet-launcher │   ├── icon.png" - }, - "id": "5efa989e196a671300766404" - }, - { - "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs in GitHub. Options --format string output text format [YAML, JSON, Text] (default \"JSON\") -h, --help help for newrelic --plain output compact text Copy Commands newrelic apm - Interact with New Relic APM newrelic completion - Generates shell completion functions newrelic config - Manage the configuration of the New Relic CLI newrelic documentation - Generate CLI documentation newrelic entity - Interact with New Relic entities newrelic nerdgraph - Execute GraphQL requests to the NerdGraph API newrelic nerdstorage - Read, write, and delete NerdStorage documents and collections. newrelic nrql - Commands for interacting with the New Relic Database newrelic profile - Manage the authentication profiles for this tool newrelic version - Show the version of the New Relic CLI newrelic workload - Interact with New Relic One workloads", - "type": "developer", - "document_type": "page", - "info": "The command line tools for performing tasks against New Relic APIs", - "sections": [ - "New Relic CLI Reference", - "New Relic CLI commands", - "Options", - "Commands" - ], - "title": "New Relic CLI Reference", - "popularity": 1, - "tags": "new relic cli", - "external_id": "471ed214caaf80c70e14903ec71411e2a1c03888", - "image": "", - "url": "https://developer.newrelic.com/explore-docs/newrelic-cli/", - "published_at": "2020-08-18T02:11:50Z", - "updated_at": "2020-08-14T01:47:12Z", - "_index": "520d1d5d14cc8a32e600034b", - "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.510402, - "_version": null, - "_explanation": null, - "sort": null, - "highlight": { - "title": "New Relic CLI Reference", - "sections": "New Relic CLI Reference", - "tags": "new relic cli", - "body": " - Commands for interacting with the New Relic Database newrelic profile - Manage the authentication profiles for this tool newrelic version - Show the version of the New Relic CLI newrelic workload - Interact with New Relic One workloads" - }, - "id": "5efa989ee7b9d2024b7bab97" - }, - { - "body": "A New Relic One application is represented by a Nerdpack folder, which can include one or more Nerdlet files, and (optionally) one or more launcher files. This document explains: The file structure for a Nerdpack, a Nerdlet and a launcher How to link a launcher file to a Nerdlet How to link your application with a monitored entity For basic component definitions, see our developer site. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate Nerdpack. Use the CLI command nr1 create and select Nerdpack to create a Nerdpack template that includes a Nerdlet and a launcher. Generate Nerdlet or launcher individually. You can use the CLI command nr1 create and choose to select either a Nerdlet or launcher. This may be useful when adding Nerdlets to an existing Nerdpack. For a lesson on generating and connecting Nerdpack components, see the workshop. Nerdpack file structure When you generate a Nerdpack template using the CLI nr1 create command, it has this file structure: my-nerdlet ├── README.md ├── launchers │ └── my-nerdlet-launcher │ ├── icon.png │ └── nr1.json ├── nerdlets │ └── my-nerdlet-nerdlet │ ├── index.js │ ├── nr1.json │ └── styles.scss ├── node_modules │ ├── js-tokens │ ├── loose-envify │ ├── object-assign │ ├── prop-types │ ├── react │ ├── react-dom │ ├── react-is │ └── scheduler ├── nr1.json ├── package-lock.json └── package.json Nerdlet file structure A Nerdpack can contain one or more Nerdlets. A Nerdlet folder starts out with three default files: index.js The JavaScript code. Here's what the default file looks like when a Nerdlet is generated with the CLI nr1 create: import React from 'react'; export default class MyAwesomeNerdpack extends React.Component { render() { return

Hello, my-awesome-nerdpack Nerdlet!

} } nr1.json Configuration file. Here is the default file generated by the CLI nr1 create command: { \"schemaType\": \"NERDLET\", \"id\": \"my-awesome-nerdpack-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\" } Besides using the launcher as the access point for your application, you can also associate the application with a monitored entity to get it to appear in the New Relic One entity explorer. To do this, add two additional fields to the config file of the first-launched Nerdlet: entities and actionCategory. In the following example, the Nerdlet has been associated with all New Relic Browser-monitored applications and will appear under the Monitor UI category : { \"schemaType\": \"NERDLET\", \"id\": \"my-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"Custom Data\", \"entities\": [{\"domain\": \"BROWSER\", \"type\": \"APPLICATION\"}], \"actionCategory\": \"monitor\" } To see this application in the UI, you would go to the New Relic One entity explorer, select Browser applications, and select a monitored application. styles.scss The file for CSS styles (Sass SCSS syntax). Launcher file structure When an application with a launcher file has been deployed, its launcher is located on the New Relic One home page (one.newrelic.com). A launcher is not required; as an alternative to using a launcher, you can associate your application with a monitored entity. An application can have more than one launcher; this may be desired for an application with multiple Nerdlets. A launcher folder contains two files: nr1.json The configuration file. Here is the default file template created by the nr1 create command: { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } To connect a launcher to a Nerdlet, the rootNerdletId must match the id in the launched Nerdlet's nr1.json config file. For Nerdpacks with multiple Nerdlets, this needs to be done only for the first-launched Nerdlet. icon.png The launcher icon that appears on the one.newrelic.com home page when an application is deployed. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", - "type": "docs", - "document_type": "page", - "breadcrumb": "Contents / New Relic One / Use New Relic One / Build on New Relic One", - "info": "For building a New Relic One application: an explanation of the Nerdpack/Nerdlet file structure. ", - "nodeid": 36006, - "sections": [ - "Use New Relic One", - "Get started", - "Core concepts", - "UI and data", - "Workloads", - "Build on New Relic One", - "Nerdpack file structure", - "Generate Nerdpack components", - "Nerdlet file structure", - "Launcher file structure", - "For more help" - ], - "title": "Nerdpack file structure", - "popularity": 1, - "external_id": "6e3788bee17cb65b6dc210862e2a10399f78ff67", - "category_1": "Use New Relic One", - "category_2": "Build on New Relic One", - "image": "", - "url": "https://docs.newrelic.com/docs/new-relic-one/use-new-relic-one/build-new-relic-one/new-relic-one-application-nerdpack-file-structure", - "published_at": "2020-08-18T15:32:31Z", - "updated_at": "2020-07-25T00:32:16Z", - "category_0": "New Relic One", - "_index": "520d1d5d14cc8a32e600034b", - "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.44179532, - "_version": null, - "_explanation": null, - "sort": null, - "highlight": { - "title": "Nerdpack file structure", - "sections": "Nerdpack file structure", - "info": "For building a New Relic One application: an explanation of the Nerdpack/Nerdlet file structure. ", - "category_0": "New Relic One", - "category_1": "Use New Relic One", - "category_2": "Build on New Relic One", - "body": " file structure When you generate a Nerdpack template using the CLI nr1 create command, it has this file structure: my-nerdlet ├── README.md ├── launchers │ └── my-nerdlet-launcher │ ├── icon.png │ └── nr1.json ├── nerdlets │ └── my-nerdlet-nerdlet │ ├── index.js │ ├── nr1.json │ └── styles.scss", - "breadcrumb": "Contents / New Relic One / Use New Relic One / Build on New Relic One" - }, - "id": "5da0e07a64441f1328edf241" - }, - { - "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations, and fetch New Relic or third-party data. Components of the SDK SDK components are located in the Node module package named nr1, which you get when you install the NR1 CLI. The nr1 components can be divided into several categories: UI components Chart components Query and storage components Platform APIs UI components The UI components category of the SDK contains React UI components, including: Text components: These components provide basic font and heading elements. These include HeadingText and BlockText. Layout components: These components give you control over the layout, and help you build complex layout designs without having to deal with the CSS. Layout components include: Grid and GridItem: for organizing more complex, larger scale page content in rows and columns Stack and StackItem: for organizing simpler, smaller scale page content (in column or row) Tabs and TabsItem: group various related pieces of content into separate hideable sections List and ListItem: for providing a basic skeleton of virtualized lists Card, CardHeader and CardBody : used to group similar concepts and tasks together Form components: These components provide the basic building blocks to interact with the UI. These include Button, TextField, Dropdown and DropdownItem, Checkbox, RadioGroup, Radio, and Checkbox. Feedback components: These components are used to provide feedback to users about actions they have taken. These include: Spinnerand Toast. Overlaid components: These components are used to display contextual information and options in the form of an additional child view that appears above other content on screen when an action or event is triggered. They can either require user interaction (like modals), or be augmenting (like a tooltip). These include: Modal and Tooltip. Components suffixed with Item can only operate as direct children of that name without the suffix. For example: GridItem should only be found as a child of Grid. Chart components The Charts category of the SDK contains components representing different types of charts. The ChartGroup component helps a group of related charts share data and be aligned. Some chart components can perform NRQL queries on their own; some accept a customized set of data. Query and storage components The Query components category contains components for fetching and storing New Relic data. The main way to fetch data is with NerdGraph, our GraphQL endpoint. This can be queried using NerdGraphQuery. To simplify use of NerdGraph queries, we provide some components with pre-defined queries. For more on using NerdGraph, see Queries and mutations. We also provide storage for storing small data sets, such as configuration settings data, or user-specific data. For more on this, see NerdStorage. Platform APIs The Platform API components of the SDK enable your application to interact with different parts of the New Relic One platform, by reading and writing state from and to the URL, setting the configuration, etc. They can be divided into these categories: PlatformStateContext: provides read access to the platform URL state variables. Example: timeRange in the time picker. navigation: an object that allows programmatic manipulation of the navigation in New Relic One. Example: opening a new Nerdlet. NerdletStateContext: provides read access to the Nerdlet URL state variables. Example: an entityGuid in the entity explorer. nerdlet: an object that provides write access to the Nerdlet URL state.", - "type": "developer", - "document_type": "page", - "info": "Intro to New Relic One API components", - "sections": [ - "Intro to New Relic One API components", - "Components of the SDK", - "UI components", - "Chart components", - "Query and storage components", - "Platform APIs" - ], - "title": "Intro to New Relic One API components", - "popularity": 1, - "external_id": "3620920c26bcd66c59c810dccb1200931b23b8c2", - "image": "", - "url": "https://developer.newrelic.com/explore-docs/intro-to-sdk/", - "published_at": "2020-08-18T02:07:10Z", - "updated_at": "2020-08-14T01:47:12Z", - "_index": "520d1d5d14cc8a32e600034b", - "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.36209166, - "_version": null, - "_explanation": null, - "sort": null, - "highlight": { - "title": "Intro to New Relic One API components", - "sections": "Intro to New Relic One API components", - "info": "Intro to New Relic One API components", - "body": ", and fetch New Relic or third-party data. Components of the SDK SDK components are located in the Node module package named nr1, which you get when you install the NR1 CLI. The nr1 components can be divided into several categories: UI components Chart components Query and storage components Platform" - }, - "id": "5efa989e28ccbc4071307de5" - } - ], - "/build-apps/set-up-dev-env": [ - { - "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build your own application launcher and follow the quick start instructions. The quick start automatically generates an API key for the account you select, and gives you the pre-populated commands to create a profile, generate your first \"Hello World\" app, and serve it locally. Tip Use the NR1 VS Code extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions. For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). Configure your CLI preferences nr1 config:set Sets a specific configuration value. nr1 config:get Shows a specific configuration. nr1 config:list Lists your configuration choices. nr1 config:delete Removes the value of a specific configuration. Set up your Nerdpacks nr1 nerdpack:clone Clones an open source Nerdpack from our GitHub repository. nr1 nerdpack:serve Serves your Nerdpack for testing and development purposes. nr1 nerdpack:uuid Shows or regenerates the UUID of a Nerdpack. nr1 nerdpack:publish Publishes your Nerdpack to New Relic. nr1 nerdpack:deploy Deploys a Nerdpack version to a specific channel. nr1 nerdpack:undeploy Undeploys a Nerdpack version from a specific channel. Manage your Nerdpack subscriptions nr1 subscription:set Subscribes your account to a Nerdpack and channel. nr1 subscription:list Lists all the Nerdpacks your account is subscribed to. nr1 subscription:unset Unsubscribes your account from a Nerdpack. Install and manage plugins nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin into the CLI for development. nr1 plugins:update Updates your installed plugins. nr1 plugins:uninstall Removes a plugin from the CLI. Manage catalog information nr1 catalog:info Shows the Nerdpack info stored in the catalog. nr1 catalog:submit Gathers and submits the catalog info on the current folder.", - "type": "developer", - "document_type": "page", - "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", - "sections": [ - "New Relic One CLI reference", - "Installing the New Relic One CLI", - "Tip", - "New Relic One CLI Commands", - "Get started", - "Configure your CLI preferences", - "Set up your Nerdpacks", - "Manage your Nerdpack subscriptions", - "Install and manage plugins", - "Manage catalog information" - ], - "title": "New Relic One CLI reference", - "popularity": 1, - "tags": [ - "New Relic One app", - "nerdpack commands" - ], - "external_id": "858339a44ead21c83257778ce60b4c352cd30d3b", - "image": "https://developer.newrelic.com/static/2c6d337608b38a3312b4fc740afe6167/7272b/developercenter.png", - "url": "https://developer.newrelic.com/explore-docs/nr1-cli/", - "published_at": "2020-08-18T02:07:10Z", - "updated_at": "2020-08-18T01:50:36Z", - "_index": "520d1d5d14cc8a32e600034b", - "_type": "520d1d5d14cc8a32e600034c", - "_score": 14.765135, - "_version": null, - "_explanation": null, - "sort": null, - "highlight": { - "title": "New Relic One CLI reference", - "sections": "New Relic One CLI reference", - "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", - "tags": "New Relic One app", - "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use" - }, - "id": "5efa989e28ccbc535a307dd0" - }, + "/collect-data/get-started-nerdgraph-api-explorer": [ { - "body": "Get started with the New Relic CLI 20 min Access the New Relic platform from the comfort of your terminal: you can use the New Relic CLI to manage entity tags, define workloads, record deployment markers, and much more. Our CLI has been designed for automating common tasks in your DevOps workflow. This guide walks you through the essentials of New Relic CLI, from install and configuration to basic usage. Before you begin For this guide you just need: Your New Relic personal API Key, which you can create from the Account settings of your New Relic account An instrumented application in your New Relic account Step 1 of 10 Install the New Relic CLI The New Relic CLI can be downloaded via Homebrew (macOS), Scoop (Windows), and Snapcraft (Linux). You can also download pre-built binaries for all platforms, including .deb and .rpm packages, and our Windows x64 .msi installer. Linux With Snapcraft installed, run: sudo snap install newrelic-cli macOS With Homebrew installed, run: brew install newrelic-cli Windows With Scoop installed, run: scoop bucket add newrelic-cli https://github.com/newrelic/newrelic-cli.git scoop install newrelic-cli Step 2 of 10 Create your New Relic CLI profile Now that you've installed the New Relic CLI, it's time to create your first profile. Profiles contain credentials and settings that you can apply to any CLI command, which is useful when switching between accounts. To create your first CLI profile, run the profiles add command. Note that you need to set the region of your New Relic account: use -r to set either us or eu (this is required). # Create the tutorial account for the US region newrelic profiles add -n tutorial --apiKey YOUR_NEW_RELIC_API_KEY -r YOUR_REGION # Set the profile as defaults newrelic profiles default -n tutorial Copy Step 3 of 10 Get your application details In this example, you are going to add tags to the application you've instrumented with New Relic. Tags are key-value pairs that can help you organize and filter your entities. An entity (for example, an application) can have a maximum of 100 key-value pairs tied to it. Before searching for your application using the New Relic CLI, write down or copy your Account ID and the name of your application in New Relic - you need both to find applications in the New Relic platform. Step 4 of 10 The New Relic CLI can retrieve your application details as a JSON object. To search for your APM application use the apm application search command. If you get an error, check that the account ID and application name you provided are correct. newrelic apm application search --accountId YOUR_ACCOUNT_ID --name NAME_OF_YOUR_APP Copy Step 5 of 10 If the account ID is valid, and the application name exists in your account, apm application search yields data similar to this example. When you've successfully searched for your application, look for the guid value. It's a unique identifier for your application. You should copy it or write it down. [ { accountId: YOUR_ACCOUNT_ID, applicationId: YOUR_APP_ID, domain: 'APM', entityType: 'APM_APPLICATION_ENTITY', guid: 'A_LONG_GUID', name: 'NAME_OF_YOUR_APP', permalink: 'https://one.newrelic.com/redirect/entity/A_LONG_GUID', reporting: true, type: 'APPLICATION', }, ]; Copy Step 6 of 10 Add a simple tag to your application Now that you have the GUID, you can point the New Relic CLI directly at your application. Adding a tag is the simplest way to try out the CLI capabilities (don't worry, tags can be deleted by using entity tags delete). Let's suppose that you want to add an environment tag to your application. Go ahead and add the dev:testing tag⁠ (or any other key-value pair) to your application using the entities tags create command. newrelic entity tags create --guid YOUR_APP_GUID --tag devkit:testing Copy Step 7 of 10 What if you want to add multiple tags? Tag sets come to the rescue! While tags are key-value pairs separated by colons, tag sets are comma separated lists of tags. For example: tag1:value1,tag2:value2 To add multiple tags at once to your application, modify and run the following snippet. newrelic entity tags create --guid YOUR_APP_GUID --tag tag1:test,tag2:test Copy Adding tags is an asynchronous operation: this means it could take a while for the tags to get created. Step 8 of 10 You've created and added some tags to your application, but how do you know they're there? You need to retrieve your application's tags. To retrieve your application's tags, use the entity tags get command. newrelic entity tags get --guid YOUR_APP_GUID All tags associated with your application are retrieved as a JSON array. [ { Key: 'tag1', Values: ['true'], }, { Key: 'tag2', Values: ['test'], }, { Key: 'tag3', Values: ['testing'], }, // ... ]; Copy Step 9 of 10 Bonus step: Create a deployment marker Deployments of applications often go wrong. Deployment markers are labels that, when attached to your application data, help you track deployments and troubleshoot what happened. To create a deployment marker, run the apm deployment create command using the same Application ID from your earlier search. newrelic apm deployment create --applicationId YOUR_APP_ID --revision $(git describe --tags --always) Copy Step 10 of 10 Notice that the JSON response includes the revision and timestamp of the deployment. This workflow could be built into a continuous integration or continuous deployment (CI/CD) system to help indicate changes in your application's behavior after deployments. Here is an example. { \"id\": 37075986, \"links\": { \"application\": 204261368 }, \"revision\": \"v1.2.4\", \"timestamp\": \"2020-03-04T15:11:44-08:00\", \"user\": \"Developer Toolkit Test Account\" } Copy Next steps Have a look at all the available commands. For example, you could create a New Relic workflow using workload create If you'd like to engage with other community members, visit our New Relic Explorers Hub page. We welcome feature requests or bug reports on GitHub.", + "body": "Query and store data 10 min To help you build a New Relic One application, we provide you with the New Relic One SDK. Here you can learn how to use the SDK query components, which allow you to make queries and mutations via NerdGraph, our GraphQL endpoint. Query-related React components can be identified by the Query suffix. Mutation-related components can be identified by the Mutation prefix. Components overview Our data components are based on React Apollo. The most basic component is NerdGraphQuery, which accepts any GraphQL (or GraphQL AST generated by the graphql-tag library as the query parameter, and a set of query variables passed as variables. Over this query, we have created an additional set of queries, which can be divided into four groups: User queries: These allow you to query the current user and its associated accounts. Components in this category: UserStorageQuery and AccountsQuery. Entities queries: Because New Relic One is entity-centric, we use queries to make access to your entities easier. You can count, search, list, query, and favorite them. Components in this category: EntityCountQuery, EntitySearchQuery, EntitiesByDomainTypeQuery, EntitiesByGuidsQuery, EntityByGuidQuery, EntityByNameQuery. Storage queries: New Relic One provides a simple storage mechanism that we call NerdStorage. This can be used by Nerdpack creators to store application configuration setting data, user-specific data, and other small pieces of data. Components in this category: UserStorageQuery, AccountStorageQuery, EntityStorageQuery, UserStorageMutation, AccountStorageMutation, and EntityStorageMutation. For details, see NerdStorage. NRQL queries: To be able to query your New Relic data via NRQL (New Relic Query Language), we provide a NrqlQuery component. This component can return data in different formats, so that you can use it for charting and not only for querying. Query components All query components accept a function as a children prop where the different statuses can be passed. This callback receives an object with the following properties: loading: Boolean that is set to true when data fetching is happening. Our components use the cache-and-network strategy, meaning that after the data has loaded, subsequent data reloads might be triggered first with stale data, then refreshed when the most recent data has arrived. data: Root property where the data requested is retrieved. The structure matches a root structure based on the NerdGraph schema. This is true even for highly nested data structures, which means you’ll have to traverse down to find the desired data. error: Contains an Error instance when the query fails. Set to undefined when data is loading or the fetch was successful. fetchMore: Callback function that can be called when the query is being loaded in chunks. The function will only be present when it’s feasible to do so, more data is available, and no fetchMore has already been triggered. Data is loaded in batches of 200 by default. Other components provided by the platform (like the Dropdown or the List) are capable of accepting fetchMore, meaning you can combine them easily. Mutation components Mutation components also accept a children as a function, like the query ones. The mutation can be preconfigured at the component level, and a function is passed back that you can use in your component. This is the standard React Apollo approach for performing mutations, but you might find it easier to use our static mutation method added to the component. More on this topic below. Static methods All of the described components also expose a static method so that they can be used imperatively rather than declaratively. All Query components have a static Query method, and all Mutation components have a mutation method. These static methods accept the same props as their query component, but passed as an object. For example: // Declarative way (using components). function renderAccountList() { return (
    ({data, error}) => { if (error) { return
  • Failed to retrieve list: {error.message}
  • ; } return data.map((account) => {
  • {account.name}
  • }); }}
); } // Imperative way (using promises). async function getAccountList() { let data = {}; try { data = await AccountsQuery.query(); } catch (error) { console.log('Failed to retrieve list: ' + error.message); return; } return data.actor.accounts.map((account) => { return account.name; }); } Copy Similarly, a mutation can happen either way; either declaratively or imperatively. NrqlQuery NrqlQuery deserves additional explanation, because there are multiple formats in which you can return data from it. To provide maximum functionality, all three are exposed through a formatType property. You can find its different values under NrqlQuery.formatType: NERD_GRAPH: Returns the format in which it arrives from NerdGraph. RAW: The format exposed by default in Insights and dashboards when being plotted as JSON. This format is useful if you have a pre-existing script in this format that you're willing to migrate to or incorporate with. CHART: The format used by the charting engine that we also expose. You can find a more detailed explanation of how to manipulate this format in the guide to chart components, and some examples. If you are willing to push data, we currently do not expose NrqlMutation. To do that, see the Event API for how to add custom events.", "type": "developer", "document_type": "page", - "info": "Learn the essentials of the New Relic CLI, from install and configuration to basic usage.", + "info": "Reference guide for SDK query components using NerdGraph", "sections": [ - "Get started with the New Relic CLI", - "Before you begin", - "Install the New Relic CLI", - "Linux", - "macOS", - "Windows", - "Create your New Relic CLI profile", - "Get your application details", - "Add a simple tag to your application", - "Bonus step: Create a deployment marker", - "Next steps" - ], - "title": "Get started with the New Relic CLI", - "popularity": 1, - "tags": [ - "api key", - "New Relic CLI", - "Tags", - "Entity", - "Deployment markers" + "Query and store data", + "Components overview", + "Query components", + "Mutation components", + "Static methods", + "NrqlQuery" ], - "external_id": "531f2f3985bf64bb0dc92a642445887095048882", + "title": "Query and store data", + "popularity": 1, + "tags": [ + "nerdgraph query components", + "mutation components", + "static methods" + ], + "external_id": "cbbf363393edeefbc4c08f9754b43d38fd911026", "image": "", - "url": "https://developer.newrelic.com/automate-workflows/get-started-new-relic-cli/", - "published_at": "2020-08-18T02:06:05Z", - "updated_at": "2020-08-08T01:41:47Z", + "url": "https://developer.newrelic.com/explore-docs/query-and-store-data/", + "published_at": "2020-08-19T01:51:37Z", + "updated_at": "2020-08-01T01:42:02Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 6.516817, + "_score": 2.405505, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Get started with the New Relic CLI", - "sections": "Get started with the New Relic CLI", - "info": "Learn the essentials of the New Relic CLI, from install and configuration to basic usage.", - "tags": "New Relic CLI", - "body": ". This guide walks you through the essentials of New Relic CLI, from install and configuration to basic usage. Before you begin For this guide you just need: Your New Relic personal API Key, which you can create from the Account settings of your New Relic account An instrumented application in your" + "title": "Query and store data", + "sections": "Query and store data", + "info": "Reference guide for SDK query components using NerdGraph", + "tags": "nerdgraph query components", + "body": "Query and store data 10 min To help you build a New Relic One application, we provide you with the New Relic One SDK. Here you can learn how to use the SDK query components, which allow you to make queries and mutations via NerdGraph, our GraphQL endpoint. Query-related React components can" }, - "id": "5efa999c196a67c4e1766461" + "id": "5efa989e28ccbc2f15307deb" }, { - "body": "Create a \"Hello, World!\" application 15 min Here's how you can quickly build a \"Hello, World!\" application in New Relic One. In these steps, you create a local version of the New Relic One site where you can prototype your application. Then, when you're ready to share the application with others, you can publish it to New Relic One. See the video, which demonstrates the steps in this guide in five minutes. Before you begin To get started, make sure you have accounts in GitHub and New Relic. To develop projects, you need the New Relic One CLI (command line interface). If you haven't already installed it, do the following: Install Node.js. Complete all the steps in the CLI quick start. For additional details about setting up your environment, see Set up your development environment. Tip Use the NR1 VS Code extension to build your apps. Create a local version of the \"Hello, World!\" application The CLI allows you to run a local version of New Relic One. You can develop your application locally before you publish it in New Relic One. If you followed all the steps in the CLI quick start, you now have files under a new directory named after your nerdpack project. Here's how you edit those files to create a \"Hello, World!\" project: Step 1 of 9 Open a code editor and point it to the new directory named after your nerdpack project (for example, my-awesome-nerdpack). Your code editor displays two artifacts: launchers containing the homepage tile nerdlets containing your application code Step 2 of 9 Expand nerdlets in your code editor, and open index.js. Step 3 of 9 Change the default return message to \"Hello, World!\": import React from 'react'; // https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction export default class MyAwesomeNerdpackNerdletNerdlet extends React.Component { render() { return

\"Hello, World!\"

; } } Copy Step 4 of 9 As an optional step, you can add a custom launcher icon using any image file named icon.png. Replace the default icon.png file under launcher by dragging in your new image file: Step 5 of 9 To change the name of the launcher to something meaningful, in your code editor under launchers, open nr1.json. Step 6 of 9 Change the value for displayName to anything you want as the launcher label, and save the file: { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"INSERT_YOUR_TILE_LABEL_HERE\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy Step 7 of 9 To see your new changes locally, start the Node server with this command in your terminal: npm start Copy Step 8 of 9 Open a browser and go to https://one.newrelic.com/?nerdpacks=local (this url is also shown in the terminal). Step 9 of 9 When the browser opens, click Apps, and then in the Other apps section, click the new launcher for your application. Here's an example where we inserted a leaf icon: After you click the new launcher, your \"Hello, World!\" appears: Publish your application to New Relic Your colleagues can't see your local application, so when you are ready to share it, publish it to the New Relic One catalog. The catalog is where you can find any pre-existing custom applications, as well as any applications you create in your own organization. Step 1 of 4 Execute the following in your terminal: nr1 nerdpack:publish Copy Step 2 of 4 Close your local New Relic One development tab, and open New Relic One. Step 3 of 4 Click the Apps launcher. Step 4 of 4 Under New Relic One catalog, click the launcher for your new application. When your new application opens, notice that it doesn't display any helpful descriptive information. The next section shows you how to add descriptive metadata. Add details to describe your project Now that your new application is in the New Relic One catalog, you can add details that help users understand what your application does and how to use it. Step 1 of 5 Go to your project in the terminal and execute the following: nr1 create Copy Step 2 of 5 Select catalog, which creates a stub in your project under the catalog directory. Here's how the results might look in your code editor: Step 3 of 5 In the catalog directory of your project, add screenshots or various types of metadata to describe your project. For details about what you can add, see Add catalog metadata and screenshots. Step 4 of 5 After you add the screenshots and descriptions you want, execute the following to save your metadata to the catalog: nr1 catalog:submit Copy Step 5 of 5 Return to the catalog and refresh the page to see your new screenshots and metadata describing your project. Subscribe accounts to your application To make sure other users see your application in the catalog, you need to subscribe accounts to the application. Any user with the NerdPack Manager role can subscribe accounts to an application. Step 1 of 3 If you're not already displaying your application's description page in the browser, click the launcher for the application in the catalog under Your company applications. Step 2 of 3 On your application's description page, click Add this app. Step 3 of 3 Select the accounts you want to subscribe to the application, and then click Update accounts to save your selections. When you return to the Apps page, you'll see the launcher for your new application. Summary Now that you've completed the steps in this example, you learned the basic steps to: Create a local application. Publish the application to the New Relic One catalog so you can share it with your colleagues. Add details to the project in the catalog so users understand how to use it. Subscribe accounts to your application so other users can use it. Related information Create a local application. Publish the application to the New Relic One catalog so you can share it with your colleagues. Add details to the project in the catalog so users understand how to use it. Subscribe accounts to your application so other users can see it directly on their homepage.", + "body": "Add, query, and mutate data using NerdStorage 45 min NerdStorage is a document database accessible within New Relic One. It allows you to modify, save, and retrieve documents from one session to the next. Using NerdStorage, you can create individual documents of up to 64kb in size, create different collections of documents, and store data by entity, account, or user level. This guide explains how to add data and documents to NerdStorage. For an introduction to what NerdStorage is and how it works, see Intro to NerdStorage. Before you begin This guide requires that you have an API key and the New Relic One CLI as described in Set up your development environment. Get started First, get the NerdStorage app running successfully inside New Relic One. Step 1 of 3 Clone the example applications from the GitHub repo. Step 2 of 3 Use the New Relic One CLI to update the application UUID and run the application locally. In the terminal, switch to the /nr1-how-to/use-nerdstorage directory: cd / nr1 - how - to / use - nerdstorage; Copy Update the UUID and serve the application: nr1 nerdpack:uuid -gf nr1 nerdpack:serve Copy Step 3 of 3 Once the app is successfully served, your terminal will return the URL to view your running application on New Relic One. Load the URL. Click Apps and under Other apps you'll see the Use Nerdstorage app listed. Click to launch the app. Add data to NerdStorage Once the app is up and running on New Relic One, you can prepare the app and start adding data. On the How To Use NerdStorage app screen, there's a Saved to NerdStorage pane with a field for adding data. However, if you type something you'll get an error message. This is because you need to be set up to store data at the User level. You can do this with the help of the UserStorageMutation component. Step 1 of 3 Open the application’s ./nerdlets/use-nerdstorage-nerdlet/index.js file in the text editor of your choice and find the code for the TextField and Button used to enter data. The Button onClick prop makes a call to a helper method called _addToNerdStorage, and you need to update it to add UserStorageMutation The UserStorage NerdStorage components require a collection and documentId. In the constructor method in the application’s index.js file, you can see the variables being provided. In the .js file, it will look something like this: constructor(props) { super(props) this.collectionId = 'mycollection'; this.documentId = 'learning-nerdstorage'; this.state = { isOpen: true, storage: [], text: '', }; this._addToNerdStorage = this._addToNerdStorage.bind(this); this._removeFromNerdStorage = this._removeFromNerdStorage.bind(this); this._deleteDocument = this._deleteDocument.bind(this); } Copy Step 2 of 3 Import the UserStorageMutation by adding it to your import statement at the top of the index.js file: import { UserStorageMutation } from 'nr1'; Copy Then update the helper with this code beginning with _addToNerdStorage: _addToNerdStorage(){ const { text, storage } = this.state; storage.push(text); this.setState({storage}, () => { UserStorageMutation.mutate({ actionType: UserStorageMutation.ACTION_TYPE.WRITE_DOCUMENT, collection: this.collectionId, documentId: this.documentId, document: { storage }, }) .then((res) => { this.setState({text: ''}); Toast.showToast({ title: \"NerdStorage Update.\", type: Toast.TYPE.NORMAL }); }) .catch((err) => console.log(err)); }); } Copy Step 3 of 3 Return to your running How To Use NerdStorage app screen on New Relic One and reload the page. Add some text in the text entry field and click the check button. This will update NerdStorage and trigger a Toast notification inside the app. You should then see the text you typed displayed as a table row below the text entry field. Query data from NerdStorage Once you get data storage working as described in the section above, you also need to get the app properly reading data from NerdStorage, or the app will reload with an empty state every time you navigate away from the app page and back. To do this, add the UserStorageQuery component and update the componentDidMount method. Step 1 of 3 Import the UserStorageQuery by adding it to the import statement in the application’s ./nerdlets/use-nerdstorage-nerdlet/index.js file. import { UserStorageMutation, UserStorageQuery } from 'nr1'; Copy Step 2 of 3 Then, add the following componentDidMount method to your application: componentDidMount(){ UserStorageQuery.query({ collection: this.collectionId, documentId: this.documentId, }) .then(({ data }) => { if(data !== null) { this.setState({storage: data.storage}); } }) .catch(err => console.log(err)); } Copy Step 3 of 3 Back inside the NerdStorage app, test your changes by adding a few more rows using the text entry field. Then exit and relaunch the application. The application should load and show all the data you entered before you navigated away. Mutate data in NerdStorage Each NerdStorage entry displayed in the table inside the app has a trash button that can be used to update a specific entry. The trash button works by making a call to the _removeFromNerdStorage helper method. Step 1 of 1 To get this process working, update the code in _removeFromNerdStorage: _removeFromNerdStorage(index, data){ const { storage } = this.state; storage.pop(data); this.setState({storage}, () => { UserStorageMutation.mutate({ actionType: UserStorageMutation.ACTION_TYPE.WRITE_DOCUMENT, collection: this.collectionId, documentId: this.documentId, document: { storage }, }) .then((res) => { Toast.showToast({ title: \"NerdStorage Update.\", type: Toast.TYPE.NORMAL }); }) .catch((err) => console.log(err)); }); } Copy Once you do this, clicking the trash button removes the item it's associated with, and the app updates to show the change. Delete collection from NerdStorage While the trash button is a good method for removing specific entries one at a time, you may also want the ability to delete a whole NerdStorage document at once. You can do this by adding the Delete Document button to your app. Step 1 of 2 Add a new GridItem to the application immediately before the closing Grid tag. In the new GridItem add the following code to display your new button: ; Copy Step 2 of 2 Because the new Delete Document button will be calling the _deleteDocument helper method, you'll need to update that using this code: _deleteDocument(){ this.setState({storage: []}); UserStorageMutation.mutate({ actionType: UserStorageMutation.ACTION_TYPE.DELETE_DOCUMENT, collection: this.collectionId, documentId: this.documentId, }); Toast.showToast({ title: \"NerdStorage Update.\", type: Toast.TYPE.CRITICAL }); } Copy Back inside the application, you should now see both the individual trash buttons and the newly added Delete Document button. Next steps Now that you’ve successfully implemented NerdStorage into a New Relic One application, you can store and mutate data connected to your User. For more information on the various NerdStorage components, please visit the New Relic developer website API documentation.", "type": "developer", "document_type": "page", - "info": "Build a \"Hello, World!\" app and publish it to New Relic One", + "info": "NerdStorage is a document database accessible within New Relic One. It allows you to modify, save, and retrieve documents from one session to the next.", "sections": [ - "Create a \"Hello, World!\" application", + "Add, query, and mutate data using NerdStorage", "Before you begin", - "Tip", - "Create a local version of the \"Hello, World!\" application", - "Publish your application to New Relic", - "Add details to describe your project", - "Subscribe accounts to your application", - "Summary", - "Related information" + "Get started", + "Add data to NerdStorage", + "Query data from NerdStorage", + "Mutate data in NerdStorage", + "Delete collection from NerdStorage", + "Next steps" ], - "title": "Create a \"Hello, World!\" application", + "title": "Add, query, and mutate data using NerdStorage", "popularity": 1, "tags": [ - "nr1 cli", - "Nerdpack file structure", - "NR One Catalog", - "Subscribe applications" + "add data", + "query data", + "mutate data", + "nerdstorage" ], - "external_id": "aa427030169067481fb69a3560798265b6b52b7c", - "image": "https://developer.newrelic.com/static/cb65a35ad6fa52f5245359ecd24158ff/9466d/hello-world-output-local.png", - "url": "https://developer.newrelic.com/build-apps/build-hello-world-app/", - "published_at": "2020-08-18T02:09:27Z", - "updated_at": "2020-08-18T01:45:02Z", + "external_id": "97cc9637edea35ecd68683f1010f67a5f8c79038", + "image": "https://developer.newrelic.com/static/e03456a7ed8556f83bd3329ea38b261d/8f217/add-data-NerdStorage.png", + "url": "https://developer.newrelic.com/build-apps/add-query-mutate-data-nerdstorage/", + "published_at": "2020-08-19T01:48:30Z", + "updated_at": "2020-08-14T01:50:34Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 1.6688437, + "_score": 0.80428934, "_version": null, "_explanation": null, "sort": null, "highlight": { - "sections": "Publish your application to New Relic", - "info": "Build a "Hello, World!" app and publish it to New Relic One", - "tags": "nr1 cli", - "body": ", you can publish it to New Relic One. See the video, which demonstrates the steps in this guide in five minutes. Before you begin To get started, make sure you have accounts in GitHub and New Relic. To develop projects, you need the New Relic One CLI (command line interface). If you haven't already" + "title": "Add, query, and mutate data using NerdStorage", + "sections": "Add, query, and mutate data using NerdStorage", + "tags": "query data", + "body": "Add, query, and mutate data using NerdStorage 45 min NerdStorage is a document database accessible within New Relic One. It allows you to modify, save, and retrieve documents from one session to the next. Using NerdStorage, you can create individual documents of up to 64kb in size, create different" }, - "id": "5efa9973196a67d16d76645c" + "id": "5efa98d4e7b9d26d6b7bab74" }, { - "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs in GitHub. Options --format string output text format [YAML, JSON, Text] (default \"JSON\") -h, --help help for newrelic --plain output compact text Copy Commands newrelic apm - Interact with New Relic APM newrelic completion - Generates shell completion functions newrelic config - Manage the configuration of the New Relic CLI newrelic documentation - Generate CLI documentation newrelic entity - Interact with New Relic entities newrelic nerdgraph - Execute GraphQL requests to the NerdGraph API newrelic nerdstorage - Read, write, and delete NerdStorage documents and collections. newrelic nrql - Commands for interacting with the New Relic Database newrelic profile - Manage the authentication profiles for this tool newrelic version - Show the version of the New Relic CLI newrelic workload - Interact with New Relic One workloads", - "type": "developer", + "body": "You can manage your policies, conditions, and muting rules programmatically using our GraphQL NerdGraph API. This is a powerful alternative to managing them in New Relic One or through the REST API. Alerts features you can manage with NerdGraph Here's what you can do in NerdGraph: Manage policies Use NRQL conditions Muting rules: suppress notifications The easiest way to discover alerts queries and mutations is through the NerdGraph API explorer. NerdGraph API explorer Our NerdGraph API explorer is a GraphiQL editor where you can prototype queries and mutations. Here are some examples showing how to find fields for queries and mutations. For general information about NerdGraph, see Introduction to NerdGraph. Queries To explore the various queries, look for the available queries under the actor.account.alerts namespace in NerdGraph API explorer: Mutations To explore various mutations, look in the alerts dropdown in the NerdGraph API explorer: For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "type": "docs", "document_type": "page", - "info": "The command line tools for performing tasks against New Relic APIs", + "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / Alerts and Nerdgraph", + "info": "Read about how you can manage alerts conditions, policies, and muting rules using NerdGraph.", + "nodeid": 37751, "sections": [ - "New Relic CLI Reference", - "New Relic CLI commands", - "Options", - "Commands" + "New Relic Alerts", + "Get started", + "Alert policies", + "Alert conditions", + "Alert violations", + "Alert Incidents", + "Alert notifications", + "Troubleshooting", + "Rules, limits, and glossary", + "Alerts and Nerdgraph", + "REST API alerts", + "NerdGraph API: Examples", + "Alerts features you can manage with NerdGraph", + "NerdGraph API explorer", + "Queries", + "Mutations", + "For more help" ], - "title": "New Relic CLI Reference", + "title": "NerdGraph API: Examples ", "popularity": 1, - "tags": "new relic cli", - "external_id": "471ed214caaf80c70e14903ec71411e2a1c03888", - "image": "", - "url": "https://developer.newrelic.com/explore-docs/newrelic-cli/", - "published_at": "2020-08-18T02:11:50Z", - "updated_at": "2020-08-14T01:47:12Z", + "external_id": "017d6c34d340b9bc035e91483d675915fa5252eb", + "category_1": "New Relic Alerts", + "image": "https://docs.newrelic.com/sites/default/files/thumbnails/image/alerts_query_0.png", + "url": "https://docs.newrelic.com/docs/alerts-applied-intelligence/new-relic-alerts/alerts-nerdgraph/nerdgraph-api-examples", + "published_at": "2020-08-18T18:16:49Z", + "updated_at": "2020-08-11T04:59:00Z", + "category_0": "Alerts and Applied intelligence", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 1.5284107, + "_score": 0.5138427, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic CLI Reference", - "sections": "New Relic CLI Reference", - "info": "The command line tools for performing tasks against New Relic APIs", - "tags": "new relic cli", - "body": " the configuration of the New Relic CLI newrelic documentation - Generate CLI documentation newrelic entity - Interact with New Relic entities newrelic nerdgraph - Execute GraphQL requests to the NerdGraph API newrelic nerdstorage - Read, write, and delete NerdStorage documents and collections. newrelic nrql" + "title": "NerdGraph API: Examples ", + "sections": "Mutations", + "info": "Read about how you can manage alerts conditions, policies, and muting rules using NerdGraph.", + "body": " Use NRQL conditions Muting rules: suppress notifications The easiest way to discover alerts queries and mutations is through the NerdGraph API explorer. NerdGraph API explorer Our NerdGraph API explorer is a GraphiQL editor where you can prototype queries and mutations. Here are some examples showing", + "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / Alerts and Nerdgraph" }, - "id": "5efa989ee7b9d2024b7bab97" + "id": "5f2dbad864441fd15456a9eb" }, { - "body": "New Relic One CLI subscription commands To manage your Nerdpack subscriptions, use the commands below. You can click any command to see its usage options and additional details about the command. Command Description nr1 subscription:set Subscribes your account to a Nerdpack and channel. nr1 subscription:list Lists all the Nerdpacks your account is subscribed to. nr1 subscription:unset Unsubscribes your account from a Nerdpack. Command details nr1 subscription:set Subscribe to a Nerdpack Subscribes your account to a specific Nerdpack and channel. This command can be run with a Nerdpack UUID or within a specific Nerdpack folder. By default, the command uses the Nerdpack ID in package.json and subscribes to the STABLE channel. An account can only be subscribed to one Nerdpack and channel at a time. Usage $ nr1 subscription:set Options -i, --nerdpack-id=NERDPACK_ID Specifies the Nerdpack to subscribe to. By default, the command will use the one in package.json. -c, --channel=DEV/BETA/STABLE Specifies the channel to subscribe to. [default: STABLE] --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output. Aliases $ nr1 nerdpack:subscribe nr1 subscription:list See your subscription Lists all the Nerdpacks your account is subscribed to. Your account is linked to your API key. Usage $ nr1 subscription:list Options --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output. nr1 subscription:unset Unsubscribe from a Nerdpack Unsubscribes your account from a specific Nerdpack. When this command is executed within a Nerdpack folder, the Nerdpack ID from package.json is used by default. Usage $ nr1 subscription:unset Options -i, --nerdpack-id=NERDPACK_ID Specifies the Nerdpack to subscribe to. By default, the command will use the one in package.json. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output. Aliases $ nr1 nerdpack:unsubscribe $ nr1 subscription:delete $ nr1 subscription:remove $ nr1 subscription:rm", - "type": "developer", + "body": "You can manage alerts conditions using our GraphQL NerdGraph API. Here are some conditions queries and mutations you can develop in our NerdGraph API explorer. See the NerdGraph introduction for help getting started with NerdGraph API explorer. This document covers the following: Steps to create a NRQL condition NRQL static condition NRQL baseline condition NRQL outlier condition Update a condition Update mutations List and filter NRQL conditions Singular NRQL condition queries Create a description Delete conditions Steps to create a NRQL condition Follow these steps: Decide which condition type you want to create (see NRQL Condition threshold types). Find your relevant policyID by doing one of the following: Use the NerdGraph policies API. Go to one.newrelic.com, in the top nav click Alerts & AI, then click Policies. Choose a policy. Find the ID under the policy name. Provide the appropriate mutation for your NRQL condition type and the relevant values. The NerdGraph GraphiQL explorer is the best place to find up-to-date documentation about the per-field specifics of the NerdGraph NRQL Conditions API. For example, questions like \"What does the valueFunction field accept?\" are best answered with the inline NerdGraph documentation. NRQL static condition Here's an example of creating a static condition: mutation { alertsNrqlConditionStaticCreate(accountId: YOUR_ACCOUNT_ID, policyId: YOUR_POLICY_ID, condition: { name: \"Low Host Count - Catastrophic\" enabled: true nrql: { query: \"SELECT uniqueCount(host) from Transaction where appName='my-app-name'\" evaluationOffset: 3 } terms: { threshold: 2 thresholdOccurrences: AT_LEAST_ONCE thresholdDuration: 600 operator: BELOW priority: CRITICAL } valueFunction: SINGLE_VALUE violationTimeLimit: TWENTY_FOUR_HOURS }) { id name } } NRQL baseline condition Here's an example of creating a baseline condition: mutation { alertsNrqlConditionBaselineCreate(accountId: YOUR_ACCOUNT_ID, policyId: YOUR_POLICY_ID, condition: { name: \"Baseline Condition\" enabled: true baselineDirection: UPPER_ONLY nrql: { query: \"SELECT average(duration) FROM Transaction\" evaluationOffset: 3 } terms: { threshold: 13 thresholdDuration: 180 thresholdOccurrences: ALL operator: ABOVE priority: CRITICAL } violationTimeLimit: TWENTY_FOUR_HOURS }) { id name baselineDirection } } NRQL outlier condition Here's an example of creating an outlier condition: mutation { alertsNrqlConditionOutlierCreate(accountId: YOUR_ACCOUNT_ID, policyId: YOUR_POLICY_ID, condition: { name: \"Outlier Condition\" enabled: true expectedGroups: 4 openViolationOnGroupOverlap: false nrql: { query: \"SELECT average(duration) FROM Transaction FACET httpResponseCode\" evaluationOffset: 3 } terms: { threshold: 1 thresholdDuration: 300 thresholdOccurrences: ALL operator: ABOVE priority: CRITICAL } violationTimeLimit: TWENTY_FOUR_HOURS }) { id name expectedGroups openViolationOnGroupOverlap } } Update a condition Complete the following: Determine the type of your existing condition by requesting the type field in a nrqlConditionsSearch query like this: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditionsSearch { nrqlConditions { id type } } } } } } The type returned is what you use for your update mutation. For example, if the type returned is STATIC, use alertsNrqlConditionStaticUpdate. If the type returned is BASELINE, use alertsNrqlConditionBaselineUpdate. If the type returned is OUTLIER, use alertsNrqlConditionOutlierUpdate. Provide the id of your condition to your relevant condition type mutation. Note that you can only update conditions of the relevant type. Only provide update mutations for the fields you want to update. Fields you don't provide in the update are not touched. Update mutations Only fields that you provide in the update are changed. In the following example, baselineDirection returns unchanged, but name is updated. mutation { alertsNrqlConditionBaselineUpdate(id: YOUR_CONDITION_ID, accountId: YOUR_ACCOUNT_ID, condition: { name: \"Your updated name\" }) { id name baselineDirection } } List and filter NRQL conditions To list or filter your NRQL conditions, use the nrqlConditionsSearch query in NerdGraph. Use cursor pagination The basic of list functionality for NRQL conditions allows you to paginate through your NRQL conditions as well as request the total count of conditions per account. The nrqlConditionsSearch query utilizes cursor pagination to paginate through resources. The idea behind cursor pagination is that the client will request a cursor in a programmatic loop until the cursor comes back empty. An initial list response will look something like this: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditionsSearch { nextCursor nrqlConditions { id name type } totalCount } } } } } This example returns a JSON response like this: { \"data\": { \"actor\": { \"account\": { \"alerts\": { \"nrqlConditionsSearch\": { \"nextCursor\": \"WOwfJ4+TWm9QTFeKMGyg+w==:QqkI8S4+Wwnpno6z+uk8kQ==\", \"nrqlConditions\": [ { \"id\": \"4432\", \"name\": \"Baseline Condition\", \"type\": \"BASELINE\" }, { \"id\": \"443\", \"name\": \"A static condition\", \"type\": \"STATIC\" }, // more conditions here in reality ], \"totalCount\": 435 } } } } }, } In order to paginate through conditions in the response, have the client request the cursor to be returned until the nextCursor returns from the response as null: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditionsSearch(cursor: \"WOwfJ4+TWm9QTFeKMGyg+w==:QqkI8S4+Wwnpno6z+uk8kQ==\", ) { nextCursor nrqlConditions { id name type } totalCount } } } } } Request type-specific fields Certain fields are only available on specific NRQL condition types. The main reason that mutations are split between the different condition types is because they have minor differences between the fields they accept. For example, valueFunction is only relevant for static NRQL conditions and baselineDirection is only relevant on baseline NRQL conditions. But if these fields are only available on these certain condition types, how do we return them in a list of all of our condition types? The answer is a GraphQL convention known as inline fragments. Inline fragments allow you to access the data on a specific type of NRQL condition: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditionsSearch { nrqlConditions { id name type ...on AlertsNrqlStaticCondition { valueFunction } ...on AlertsNrqlBaselineCondition { baselineDirection } ...on AlertsNrqlOutlierCondition { expectedGroups } } } } } } } In the previous example query, we are asking GraphQL to do the hard work for us to determine which NRQL conditions are the correct type. So, when the returned type is a static condition, it will return the valueFunction in the object. When the returned type is a baseline condition, it will return baselineDirection instead, and when the type is an outlier condition, it will return expectedGroups. Here is an example response: { \"data\": { \"actor\": { \"account\": { \"alerts\": { \"nrqlConditionsSearch\": { \"nrqlConditions\": [ { \"baselineDirection\": \"UPPER_ONLY\", \"id\": \"342\", \"name\": \"My baseline condition\", \"type\": \"BASELINE\" }, { \"id\": \"553\", \"name\": \"My static condition\", \"type\": \"STATIC\", \"valueFunction\": \"SINGLE_VALUE\" }, { \"expectedGroups\": 4, \"id\": \"802\", \"name\": \"My outlier condition\", \"type\": \"OUTLIER\" } ] } } } } } } Filter NRQL conditions You can filter NRQL conditions with the searchCriteria argument of the nrqlConditionsSearch query: Here's an example of filtering NRQL conditions with matching by name. This query returns NRQL conditions that match the provided name. Note that this match is case insensitive. { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditionsSearch(searchCriteria: { name: \"Baseline Condition\" }) { nrqlConditions { id name type } } } } } } Singular NRQL condition queries You can use the NRQL condition API to query for a singular condition. Run the nrqlCondition query in the alerts namespace. Similar to type specific fields on the nrqlConditionSearch query, you can also use these inline fragmentsto request fields that are restricted to a NRQL condition type. { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlCondition(id: YOUR_CONDITION_ID) { id name ...on AlertsNrqlStaticCondition { valueFunction } } } } } } Update the description This will walk you through the procedure to create a description for a NRQL alert condition. 1. Get all the conditions for a policy: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlConditions(policyId: YOUR_POLICY_ID) { nextCursor results { id name description enabled nrql { query sinceValue } policyId runbookUrl terms { duration operator priority timeFunction threshold } type violationTimeLimit } } } } } } 2. Get the details for a single condition: { actor { account(id: YOUR_ACCOUNT_ID) { alerts { nrqlCondition(id: \"YOUR_CONDITION_ID\") { description id enabled name nrql { query evaluationOffset } policyId runbookUrl terms { operator priority threshold thresholdDuration thresholdOccurrences } type violationTimeLimit } } } } } 3. Create a mutation with the description. Here's an empty mutation template: mutation { alertsNrqlConditionStaticUpdate(accountId: YOUR_ACCOUNT_ID, id: \"YOUR_CONDITION_ID\", condition: {description: \"\"}) { description } } Here'a an example mutation with an included example description: mutation { alertsNrqlConditionStaticUpdate(accountId: 123456, id: \"123456\", condition: {description: \"timestamp : {{timestamp}} \\n accountId : {{accountId}} \\n type : {{type}} \\n event : {{event}} \\n description : {{description}} \\n policyId : {{policyId}} \\n policyName: {{policyName}} \\n conditionName : {{conditionName}} \\n conditionId : {{conditionId}} \\n product : {{product}} \\n conditionType : {{conditionType}} \\n RunbookUrl : {{runbookUrl}} \\n nrqlQuery : {{nrqlQuery}} \\n nrqlEventType : {{nrqlEventType}} \\n targetID : {{targetId}} \\n targetName : {{targetName}} \\n commandLine : {{tag.commandLine}} \\n entityGuid : {{tag.entityGuid}} \\n entityName : {{tag.entityName}} \\n fullHostname : {{tag.fullHostname}} \\n instanceType : {{tag.instanceType}} \\n processDisplayName : {{tag.processDisplayName}}\"}) { description } } Delete conditions You can use the alertsConditionDelete mutation to delete any type of condition. You can only request the id field on a delete mutation; for example: mutation { alertsConditionDelete(accountId: YOUR_ACCOUNT_ID, id: YOUR_CONDITION_ID) { id } } For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "type": "docs", "document_type": "page", - "info": "An overview of the CLI commands you can use to manage your Nerdpack subscriptions.", + "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / Alerts and Nerdgraph", + "info": "Examples of how to use the NerdGraph API explorer to create alert conditions, queries, and mutations.", + "nodeid": 37711, "sections": [ - "New Relic One CLI subscription commands", - "Command details", - "nr1 subscription:set", - "Subscribe to a Nerdpack", - "Usage", - "Options", - "Aliases", - "nr1 subscription:list", - "See your subscription", - "nr1 subscription:unset", - "Unsubscribe from a Nerdpack" + "New Relic Alerts", + "Get started", + "Alert policies", + "Alert conditions", + "Alert violations", + "Alert Incidents", + "Alert notifications", + "Troubleshooting", + "Rules, limits, and glossary", + "Alerts and Nerdgraph", + "REST API alerts", + "NerdGraph API: NRQL condition alerts", + "Steps to create a NRQL condition", + "NRQL static condition", + "NRQL baseline condition", + "NRQL outlier condition", + "Update a condition", + "Update mutations", + "List and filter NRQL conditions", + "Singular NRQL condition queries", + "Update the description", + "Delete conditions", + "For more help" ], - "title": "New Relic One CLI subscription commands", + "title": "NerdGraph API: NRQL condition alerts ", "popularity": 1, - "external_id": "12d2e1b06dede5b1272527f95a14518010aecc58", + "external_id": "86591bd20017930f1e4eef1b1a76e3806298dbb9", + "category_1": "New Relic Alerts", "image": "", - "url": "https://developer.newrelic.com/explore-docs/nr1-subscription/", - "published_at": "2020-08-18T02:11:48Z", - "updated_at": "2020-08-06T01:44:54Z", + "url": "https://docs.newrelic.com/docs/alerts-applied-intelligence/new-relic-alerts/alerts-nerdgraph/nerdgraph-api-nrql-condition-alerts", + "published_at": "2020-08-18T18:15:13Z", + "updated_at": "2020-08-11T04:56:49Z", + "category_0": "Alerts and Applied intelligence", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.4754124, + "_score": 0.31023735, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic One CLI subscription commands", - "sections": "New Relic One CLI subscription commands", - "info": "An overview of the CLI commands you can use to manage your Nerdpack subscriptions.", - "body": "New Relic One CLI subscription commands To manage your Nerdpack subscriptions, use the commands below. You can click any command to see its usage options and additional details about the command. Command Description nr1 subscription:set Subscribes your account to a Nerdpack and channel. nr1" + "title": "NerdGraph API: NRQL condition alerts ", + "sections": "Update mutations", + "info": "Examples of how to use the NerdGraph API explorer to create alert conditions, queries, and mutations.", + "body": "You can manage alerts conditions using our GraphQL NerdGraph API. Here are some conditions queries and mutations you can develop in our NerdGraph API explorer. See the NerdGraph introduction for help getting started with NerdGraph API explorer. This document covers the following: Steps to create", + "breadcrumb": "Contents / Alerts and Applied intelligence / New Relic Alerts / Alerts and Nerdgraph" }, - "id": "5f2b6096e7b9d225ebc9de6f" - } - ], - "/explore-docs/nerdpack-file-structure": [ + "id": "5f2dee1128ccbc562e88dfc1" + }, { - "body": "Create a \"Hello, World!\" application 15 min Here's how you can quickly build a \"Hello, World!\" application in New Relic One. In these steps, you create a local version of the New Relic One site where you can prototype your application. Then, when you're ready to share the application with others, you can publish it to New Relic One. See the video, which demonstrates the steps in this guide in five minutes. Before you begin To get started, make sure you have accounts in GitHub and New Relic. To develop projects, you need the New Relic One CLI (command line interface). If you haven't already installed it, do the following: Install Node.js. Complete all the steps in the CLI quick start. For additional details about setting up your environment, see Set up your development environment. Tip Use the NR1 VS Code extension to build your apps. Create a local version of the \"Hello, World!\" application The CLI allows you to run a local version of New Relic One. You can develop your application locally before you publish it in New Relic One. If you followed all the steps in the CLI quick start, you now have files under a new directory named after your nerdpack project. Here's how you edit those files to create a \"Hello, World!\" project: Step 1 of 9 Open a code editor and point it to the new directory named after your nerdpack project (for example, my-awesome-nerdpack). Your code editor displays two artifacts: launchers containing the homepage tile nerdlets containing your application code Step 2 of 9 Expand nerdlets in your code editor, and open index.js. Step 3 of 9 Change the default return message to \"Hello, World!\": import React from 'react'; // https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction export default class MyAwesomeNerdpackNerdletNerdlet extends React.Component { render() { return

\"Hello, World!\"

; } } Copy Step 4 of 9 As an optional step, you can add a custom launcher icon using any image file named icon.png. Replace the default icon.png file under launcher by dragging in your new image file: Step 5 of 9 To change the name of the launcher to something meaningful, in your code editor under launchers, open nr1.json. Step 6 of 9 Change the value for displayName to anything you want as the launcher label, and save the file: { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"INSERT_YOUR_TILE_LABEL_HERE\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy Step 7 of 9 To see your new changes locally, start the Node server with this command in your terminal: npm start Copy Step 8 of 9 Open a browser and go to https://one.newrelic.com/?nerdpacks=local (this url is also shown in the terminal). Step 9 of 9 When the browser opens, click Apps, and then in the Other apps section, click the new launcher for your application. Here's an example where we inserted a leaf icon: After you click the new launcher, your \"Hello, World!\" appears: Publish your application to New Relic Your colleagues can't see your local application, so when you are ready to share it, publish it to the New Relic One catalog. The catalog is where you can find any pre-existing custom applications, as well as any applications you create in your own organization. Step 1 of 4 Execute the following in your terminal: nr1 nerdpack:publish Copy Step 2 of 4 Close your local New Relic One development tab, and open New Relic One. Step 3 of 4 Click the Apps launcher. Step 4 of 4 Under New Relic One catalog, click the launcher for your new application. When your new application opens, notice that it doesn't display any helpful descriptive information. The next section shows you how to add descriptive metadata. Add details to describe your project Now that your new application is in the New Relic One catalog, you can add details that help users understand what your application does and how to use it. Step 1 of 5 Go to your project in the terminal and execute the following: nr1 create Copy Step 2 of 5 Select catalog, which creates a stub in your project under the catalog directory. Here's how the results might look in your code editor: Step 3 of 5 In the catalog directory of your project, add screenshots or various types of metadata to describe your project. For details about what you can add, see Add catalog metadata and screenshots. Step 4 of 5 After you add the screenshots and descriptions you want, execute the following to save your metadata to the catalog: nr1 catalog:submit Copy Step 5 of 5 Return to the catalog and refresh the page to see your new screenshots and metadata describing your project. Subscribe accounts to your application To make sure other users see your application in the catalog, you need to subscribe accounts to the application. Any user with the NerdPack Manager role can subscribe accounts to an application. Step 1 of 3 If you're not already displaying your application's description page in the browser, click the launcher for the application in the catalog under Your company applications. Step 2 of 3 On your application's description page, click Add this app. Step 3 of 3 Select the accounts you want to subscribe to the application, and then click Update accounts to save your selections. When you return to the Apps page, you'll see the launcher for your new application. Summary Now that you've completed the steps in this example, you learned the basic steps to: Create a local application. Publish the application to the New Relic One catalog so you can share it with your colleagues. Add details to the project in the catalog so users understand how to use it. Subscribe accounts to your application so other users can use it. Related information Create a local application. Publish the application to the New Relic One catalog so you can share it with your colleagues. Add details to the project in the catalog so users understand how to use it. Subscribe accounts to your application so other users can see it directly on their homepage.", - "type": "developer", + "body": "This document provides examples of how to use New Relic NerdGraph to query and modify your cloud integration configuration data, including Amazon AWS, Microsoft Azure, and Google Cloud Platform (GCP). Using the NerdGraph GraphiQL explorer, you can also query NRQL data. These examples for querying cloud integration configuration data use GraphQL queries and mutations: Queries: requests that are intended to only fetch data Mutations: requests that create or update data on the server Requirements Before querying cloud integration data with NerdGraph, ensure you have: Followed the instructions to connect cloud integrations with New Relic. Created an API key. Access the NerdGraph GraphiQL explorer To access the NerdGraph GraphiQL explorer: Go to https://api.newrelic.com/graphiql. Add any of the following examples. Query examples Queries are requests that are intended to only fetch data (no side effects). Queries in NerdGraph are not static, meaning that you can ask for more or less data depending on your needs. For each query, you can specify exactly what data you want to retrieve, as long as it is supported by the schema. Available provider accounts This query returns a list of all provider accounts available in your infrastructure data. Depending on the provider, additional properties can be requested. For example, for GCP, you can also ask for the serviceAccountId property, which is needed when linking a new GCP project to New Relic. Anonymous: { actor { account(id: ) { cloud { providers { id name slug ... on CloudGcpProvider { serviceAccountId } } } } } } Named: query cloudProviders { actor { account(id: ) { cloud { providers { id name slug } } } } } Specific provider account information This query returns information about a specific provider account for your Amazon AWS integration. The properties id, name, slug are requested, along with a list of integrations available to be monitored. { actor { account(id: ) { cloud { provider(slug: \"aws\") { id slug name services { id slug name } } } } } } Specific integration data from a specific cloud provider This query returns information about a specific cloud service integration of a provider. In this example, the integration is the Amazon AWS ALB monitoring integration and the provider is AWS. The properties id, name, slug, and isAllowed are requested with the available configuration parameters. { actor { account(id: ) { cloud { provider(slug: \"aws\") { service(slug: \"alb\") { id name slug isEnabled } } } } } } List of enabled cloud accounts This query returns the list of cloud accounts enabled with your New Relic account. (Your cloud account associates your New Relic account and a specific provider account with your integration.) You can enable multiple cloud provider accounts in the same New Relic account, even with the same cloud provider. { actor { account(id: ) { cloud { linkedAccounts { id name createdAt provider { id name } } } } } } Specific linked account data This query returns information about a linked account, including the properties name, providerId, and a list of the cloud integrations enabled for monitoring. { actor { account(id: ) { cloud { linkedAccount(id: ) { name provider { id name } integrations { id name createdAt updatedAt } } } } } } Enabled cloud integrations for all linked accounts This query returns all monitored integrations for all the provider cloud accounts. { actor { account(id: ) { cloud { linkedAccounts { name provider { id name } integrations { id name service { id name } createdAt updatedAt } } } } } } Specific cloud integration data for a specific linked account This query returns information about a specific integration from a specific linked account. { actor { account(id: ) { cloud { linkedAccount(id: ) { name provider { id name } integration(id: ) { id name service { id name } createdAt updatedAt } } } } } } Mutation examples Mutations are requests that are intended to have side effects, such as creating or updating data on the server. Mutations require the keyword mutation and the name of the mutation. NerdGraph mutations are restricted to a subset of all possible mutations. Link an account This mutation allows linking cloud provider accounts to a New Relic account, creating one or more linked accounts. It can link one specific cloud provider account (for example aws) to the New Relic account or multiple cloud provider accounts to one New Relic account. Required: The parameter is required and cannot be empty. It must be unique in your New Relic account. Other parameters are specific to the provider (AWS, GCP, and Azure) and are also required. In the following sections, you can see which parameters are required for each provider account. After linking an account the createdAt and updatedAt values are equal. mutation { cloudLinkAccount( accounts: { accountId: , aws: [{ name: , }] azure: [{ name: , }] gcp: [{ name: , }] } ) { linkedAccounts { id name authLabel createdAt updatedAt } } } } Link an Amazon AWS account This mutation links an Amazon AWS provider account to your New Relic account. mutation { cloudLinkAccount( accountId: , accounts: { aws: [{ name: , arn: }] } ) { linkedAccounts { id name authLabel createdAt updatedAt } } } } Link a Microsoft Azure account This mutation links a Microsoft Azure cloud subscription to the New Relic account. mutation { cloudLinkAccount( accountId: , accounts: { azure: [{ name: , applicationId: , clientSecret: , tenantId: , subscriptionId: }] } ) { linkedAccounts { id name authLabel createdAt updatedAt } } } Link a Google Cloud Platform (GCP) project This mutation links a GCP project to the New Relic account. mutation { cloudLinkAccount( accountId: , accounts: { gcp: [{ name: , projectId: }] } ) { linkedAccounts { id name authLabel createdAt updatedAt } } } Rename one or more cloud accounts This mutation allows you to rename one or more linked provider accounts. The name parameter is required, cannot be empty, and must be unique within your New Relic account. mutation { cloudRenameAccount( accountId: , accounts: [ { id: , name: }, { id: , name: } ] ) { linkedAccounts { id name } } } Enable an integration in a cloud account This mutation allows you to enable the monitoring of one or more specific cloud integrations in an existing cloud account. With this mutation, New Relic records data for the enabled integration from the provider account. For each provider account you have access to different input parameters, matching each available service. mutation { cloudConfigureIntegration ( accountId: , integrations: { : { : [{ linkedAccountId: , }] } } ) { integrations { id name integration { id slug } ... on SqsIntegration { awsRegions } } } } Enable an integration in multiple cloud accounts If you have many provider accounts linked, you can enable the same integration in the many cloud accounts at the same time. For the output of the operation, you can use GraphQL fragments for integration specific configuration parameters. mutation { cloudConfigureIntegration ( accountId: , integrations: { : { : [ { linkedAccountId: }, { linkedAccountId: } ] } } ) { integrations { id name integration { id name } ... on SqsIntegration { awsRegions } } } } Enable multiple integrations in multiple cloud accounts If you have multiple cloud accounts linked, you can also enable multiple integrations in multiple linked cloud accounts at the same time. For the output of the operation, you can use GraphQL fragments to ask for integration specific configuration parameters. mutation { cloudConfigureIntegration ( accountId: , integrations: { : { : [ { linkedAccountId: } ] : [ { linkedAccountId: } ] }, : { : [ { linkedAccountId: }, { linkedAccountId: } ] } } ) { integrations { id name service { id name } ... on SqsIntegration { awsRegions } } } } Modify an integration's configuration (regions, polling intervals, etc.) This mutation also allows you to modify one or more cloud integrations and change one or more configuration parameters. Each service will have specific parameters that you can modify. For parameters of a type list (for example, awsRegion) supply the full list. For the output of the operation, you can use GraphQL fragments to ask for integration specific configuration parameters. mutation { cloudConfigureIntegration ( accountId: , integrations: { : { : [{ linkedAccountId: , metricsPollingInterval: , : , : , }] } } ) { integrations { id name service { id slug } ... on SqsIntegration { metricsPollingInterval, , } } errors { type message } } } Disable (remove) an integration This mutation allows you to disable an integration and stop data collection for the specific cloud integration. mutation { cloudDisableIntegration ( accountId: , integrations: { : { : [ { linkedAccountId: } ] } } ) { disabledIntegrations { id name authLabel provider { id } } errors { type message } } } Unlink account This mutation allows you to unlink cloud provider accounts from New Relic account. This action can not be undone. However, you can link the account again, but account history will still be lost. mutation { cloudUnlinkAccount ( accountId: , accounts: { { linkedAccountId: } } ) { unlinkedAccounts { id name } errors { type message } } } Enable an Amazon AWS integration This example uses an Amazon AWS SQS integration and assumes you have connected an AWS account to New Relic. To enable an Amazon AWS integration: Send query to fetch account data Send a query to fetch data about the account, specifically available providers and already created provider accounts: { actor { account(id: ) { cloud { providers { id name slug } linkedAccounts { name integrations { id name } } } } } } Link AWS provider account Link an AWS provider account, if there is not one already linked or if you want to link another AWS account: Use your New Relic account identifier in the parameter. Provide a name for the provider account in the . Include the ARN of the AWS role used to fetch data from your AWS account. mutation { cloudLinkAccount( accountId: , accounts: { aws: [{ name: , arn: }] } ) { linkedAccounts { id name authLabel createdAt updatedAt } errors { type message } } } Enable Amazon AWS SQS integration Use your New Relic account ID in the parameter and the ID of the provider account in the parameter value. mutation { cloudConfigureIntegration ( accountId: , integrations: { aws: { sqs: [ { linkedAccountId: } ] } } ) { integrations { id name service { id name } } errors { type message } } } Enable integration in multiple provider accounts If you have multiple accounts with the same provider account, you can enable the same integration in multiple provider accounts at the same time. Use your New Relic account ID in the parameter and the ID of the provider accounts in the parameter value. mutation { cloudConfigureIntegration ( accountId: , integrations: { aws: { sqs: [ { linkedAccountId: }, { linkedAccountId: , configuration_param_1: value_1, configuration_param_2: value_2 } ] } } }) { integrations { id name service { id name } } errors { type message } } } Change polling interval for Amazon AWS integration This example uses an Amazon AWS SQS integration and assumes you have connected an AWS account to New Relic. To change the polling interval of an AWS integration: Update the polling interval To update the polling interval for an Amazon AWS SQS integration, use your New Relic account ID in the parameter and the id of the linked provider account in the parameter value: mutation { cloudConfigureIntegration( accountId: , integrations: { aws : { sqs: [ { linkedAccountId: , metricsPollingInterval: 300 } ] } } ) { integrations { id name service { id slug } ... on SqsIntegration { metricsPollingInterval } } errors { type message } } } Disable Amazon AWS integration This example uses an Amazon AWS SQS integration and assumes you have connected an AWS account to New Relic. To disable an AWS integration: Disable the SQS integration Use your New Relic account identifier in the parameter and the ID of the linked cloud account the parameter value. mutation { cloudDisableIntegration ( accountId: , integrations: { aws: { sqs : [ { linkedAccountId: } ] } } ) { disabledIntegrations { id accountId name } errors { type message } } } For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", + "type": "docs", "document_type": "page", - "info": "Build a \"Hello, World!\" app and publish it to New Relic One", + "breadcrumb": "Contents / APIs / NerdGraph / Examples", + "info": "Use New Relic's NerdGraph (our GraphQL API) to query your New Relic Infrastructure cloud integration data. ", + "nodeid": 17141, "sections": [ - "Create a \"Hello, World!\" application", - "Before you begin", - "Tip", - "Create a local version of the \"Hello, World!\" application", - "Publish your application to New Relic", - "Add details to describe your project", - "Subscribe accounts to your application", - "Summary", - "Related information" + "NerdGraph", + "Get started", + "Examples", + "NerdGraph cloud integrations API tutorial", + "Requirements", + "Access the NerdGraph GraphiQL explorer", + "Query examples", + "Mutation examples", + "Enable an Amazon AWS integration", + "Change polling interval for Amazon AWS integration", + "Disable Amazon AWS integration", + "For more help" ], - "title": "Create a \"Hello, World!\" application", + "title": "NerdGraph cloud integrations API tutorial", "popularity": 1, - "tags": [ - "nr1 cli", - "Nerdpack file structure", - "NR One Catalog", - "Subscribe applications" - ], - "external_id": "aa427030169067481fb69a3560798265b6b52b7c", - "image": "https://developer.newrelic.com/static/cb65a35ad6fa52f5245359ecd24158ff/9466d/hello-world-output-local.png", - "url": "https://developer.newrelic.com/build-apps/build-hello-world-app/", - "published_at": "2020-08-18T02:09:27Z", - "updated_at": "2020-08-18T01:45:02Z", + "external_id": "15caa0b35be84f2e6245826a5c9ac8e49cad6a89", + "category_1": "NerdGraph", + "category_2": "Examples", + "image": "", + "url": "https://docs.newrelic.com/docs/apis/nerdgraph/examples/nerdgraph-cloud-integrations-api-tutorial", + "published_at": "2020-08-18T03:42:15Z", + "updated_at": "2020-08-10T23:22:01Z", + "category_0": "APIs", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 17.529211, + "_score": 0.26618502, "_version": null, "_explanation": null, "sort": null, "highlight": { - "sections": "Publish your application to New Relic", - "info": "Build a "Hello, World!" app and publish it to New Relic One", - "tags": "Nerdpack file structure", - "body": "!" application The CLI allows you to run a local version of New Relic One. You can develop your application locally before you publish it in New Relic One. If you followed all the steps in the CLI quick start, you now have files under a new directory named after your nerdpack project. Here's how you edit" + "title": "NerdGraph cloud integrations API tutorial", + "sections": "NerdGraph", + "info": "Use New Relic's NerdGraph (our GraphQL API) to query your New Relic Infrastructure cloud integration data. ", + "category_1": "NerdGraph", + "body": "This document provides examples of how to use New Relic NerdGraph to query and modify your cloud integration configuration data, including Amazon AWS, Microsoft Azure, and Google Cloud Platform (GCP). Using the NerdGraph GraphiQL explorer, you can also query NRQL data. These examples for querying", + "breadcrumb": "Contents / APIs / NerdGraph / Examples" }, - "id": "5efa9973196a67d16d76645c" - }, + "id": "5d83537b28ccbc263a1b7bf7" + } + ], + "/explore-docs/nr1-subscription": [ { "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build your own application launcher and follow the quick start instructions. The quick start automatically generates an API key for the account you select, and gives you the pre-populated commands to create a profile, generate your first \"Hello World\" app, and serve it locally. Tip Use the NR1 VS Code extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions. For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). Configure your CLI preferences nr1 config:set Sets a specific configuration value. nr1 config:get Shows a specific configuration. nr1 config:list Lists your configuration choices. nr1 config:delete Removes the value of a specific configuration. Set up your Nerdpacks nr1 nerdpack:clone Clones an open source Nerdpack from our GitHub repository. nr1 nerdpack:serve Serves your Nerdpack for testing and development purposes. nr1 nerdpack:uuid Shows or regenerates the UUID of a Nerdpack. nr1 nerdpack:publish Publishes your Nerdpack to New Relic. nr1 nerdpack:deploy Deploys a Nerdpack version to a specific channel. nr1 nerdpack:undeploy Undeploys a Nerdpack version from a specific channel. Manage your Nerdpack subscriptions nr1 subscription:set Subscribes your account to a Nerdpack and channel. nr1 subscription:list Lists all the Nerdpacks your account is subscribed to. nr1 subscription:unset Unsubscribes your account from a Nerdpack. Install and manage plugins nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin into the CLI for development. nr1 plugins:update Updates your installed plugins. nr1 plugins:uninstall Removes a plugin from the CLI. Manage catalog information nr1 catalog:info Shows the Nerdpack info stored in the catalog. nr1 catalog:submit Gathers and submits the catalog info on the current folder.", "type": "developer", @@ -4086,31 +3769,67 @@ "Install and manage plugins", "Manage catalog information" ], - "title": "New Relic One CLI reference", + "title": "New Relic One CLI reference", + "popularity": 1, + "tags": [ + "New Relic One app", + "nerdpack commands" + ], + "external_id": "858339a44ead21c83257778ce60b4c352cd30d3b", + "image": "https://developer.newrelic.com/static/2c6d337608b38a3312b4fc740afe6167/7272b/developercenter.png", + "url": "https://developer.newrelic.com/explore-docs/nr1-cli/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-18T01:50:36Z", + "_index": "520d1d5d14cc8a32e600034b", + "_type": "520d1d5d14cc8a32e600034c", + "_score": 0.60857034, + "_version": null, + "_explanation": null, + "sort": null, + "highlight": { + "title": "New Relic One CLI reference", + "sections": "New Relic One CLI Commands", + "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", + "tags": "New Relic One app", + "body": " extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions" + }, + "id": "5efa989e28ccbc535a307dd0" + }, + { + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app, you might have some additional setup and configuration. This guide covers: Downloading the New Relic One CLI to build or modify apps Contribute content to this website Before you begin You must have: A github account account - While not strictly necessary for building apps, a GitHub account enables you to download and customize our open source apps, and contribute an open source project. A New Relic developer account - if you don't already have one, you can get a free trial account for developing New Relic applications. npm - If you've installed Node.js, then you already have npm, which is used to share, reuse, and update JavaScript code, and is necessary for working with React components that are the framework for New Relic apps and this website. Tip Use the New Relic One VSCode extension to build your apps. Prepare to build or modify apps Step 1 of 2 Download the CLI and API key On the Build New Relic One applications page, complete the Quick start steps. These six Quick start steps get you an API key for use with developing apps, and the New Relic One CLI, for building and deploying apps. At the end of the Quick start, you have a project consisting of the following: A Nerdpack - The package containing all the files required by your application. It contains two types of files that you customize to build your app: Nerdlets, and the launcher. One or more Nerdlet files - A specific UI view or window. A Nerdlet is a React JavaScript package that includes an index.js file, a stylesheet, and a JSON-format config file. It can contain any JS functionality (charts, interactive fields, tooltips, etc.). A launcher file: This is the basis for the launcher, which is used to open your application from New Relic One after you publish your app. Step 2 of 2 Start building If you're ready to code, cd to your Nerdpack and get started. If you want to learn more about building applications, try these step-by-step guides: Build a \"Hello, World!\" application shows how to create a little application, publish it to New Relic One, and share it with others by subscribing accounts to it. Map pageviews by region takes you through the steps to create one of our popular open source apps. You learn to add a custom query to an app and view it in a table, then add that data to a map. Contributing to developer.newrelic.com This site is open source, and we want your input. Create a pull request if you see a mistake you know how to fix. Drop us a GitHub issue if you see some content gaps you want us to work on. Or write up a whole new guide if you have one you'd like to share. Read on to learn how. Step 1 of 3 Fork the developer-website GithHub repo Forking the repo enables you to work on your own copy of the developer.newrelic.com files, and build the site locally. It also enables us to more easily manage incomimg pull requests. On the developer-website page in GitHub, select the Fork button on the top right of the page, choose the account you want to fork to, and wait a few seconds while the fork is created. Sync regularly to keep your fork up to date with changes and additions to the main branch upstream. Step 2 of 3 Make a feature or documentation request On any page, select the GitHub button at the top of the page, and then select the kind of change you want, and fill out the GitHub form. Step 3 of 3 Contribute a new guide Check out our contributors guidelines, which will walk you through the process.", + "type": "developer", + "document_type": "page", + "info": "Prepare to build apps and contribute to this site", + "sections": [ + "Set up your development environment", + "Before you begin", + "Tip", + "Prepare to build or modify apps", + "Start building" + ], + "title": "Set up your development environment", "popularity": 1, "tags": [ - "New Relic One app", - "nerdpack commands" + "developer account", + "API key", + "New Relic One CLI" ], - "external_id": "858339a44ead21c83257778ce60b4c352cd30d3b", - "image": "https://developer.newrelic.com/static/2c6d337608b38a3312b4fc740afe6167/7272b/developercenter.png", - "url": "https://developer.newrelic.com/explore-docs/nr1-cli/", - "published_at": "2020-08-18T02:07:10Z", - "updated_at": "2020-08-18T01:50:36Z", + "external_id": "c45638a9cd548d1ffffc9f1c7708f115a92ae04a", + "image": "", + "url": "https://developer.newrelic.com/build-apps/set-up-dev-env/", + "published_at": "2020-08-19T01:44:48Z", + "updated_at": "2020-08-19T01:44:47Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 13.546968, + "_score": 0.28809583, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic One CLI reference", - "sections": "New Relic One CLI reference", - "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", - "tags": "New Relic One app", - "body": " CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build" + "tags": "New Relic One CLI", + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app" }, - "id": "5efa989e28ccbc535a307dd0" + "id": "5efa9973e7b9d242237bab39" }, { "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs in GitHub. Options --format string output text format [YAML, JSON, Text] (default \"JSON\") -h, --help help for newrelic --plain output compact text Copy Commands newrelic apm - Interact with New Relic APM newrelic completion - Generates shell completion functions newrelic config - Manage the configuration of the New Relic CLI newrelic documentation - Generate CLI documentation newrelic entity - Interact with New Relic entities newrelic nerdgraph - Execute GraphQL requests to the NerdGraph API newrelic nerdstorage - Read, write, and delete NerdStorage documents and collections. newrelic nrql - Commands for interacting with the New Relic Database newrelic profile - Manage the authentication profiles for this tool newrelic version - Show the version of the New Relic CLI newrelic workload - Interact with New Relic One workloads", @@ -4129,120 +3848,150 @@ "external_id": "471ed214caaf80c70e14903ec71411e2a1c03888", "image": "", "url": "https://developer.newrelic.com/explore-docs/newrelic-cli/", - "published_at": "2020-08-18T02:11:50Z", + "published_at": "2020-08-19T01:49:36Z", "updated_at": "2020-08-14T01:47:12Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 1.2413275, + "_score": 0.25162297, "_version": null, "_explanation": null, "sort": null, "highlight": { "title": "New Relic CLI Reference", - "sections": "New Relic CLI Reference", - "info": "The command line tools for performing tasks against New Relic APIs", + "sections": "New Relic CLI commands", + "info": "The command line tools for performing tasks against New Relic APIs", "tags": "new relic cli", - "body": " - Commands for interacting with the New Relic Database newrelic profile - Manage the authentication profiles for this tool newrelic version - Show the version of the New Relic CLI newrelic workload - Interact with New Relic One workloads" + "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs" }, "id": "5efa989ee7b9d2024b7bab97" }, { - "body": "A New Relic One application is represented by a Nerdpack folder, which can include one or more Nerdlet files, and (optionally) one or more launcher files. This document explains: The file structure for a Nerdpack, a Nerdlet and a launcher How to link a launcher file to a Nerdlet How to link your application with a monitored entity For basic component definitions, see our developer site. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate Nerdpack. Use the CLI command nr1 create and select Nerdpack to create a Nerdpack template that includes a Nerdlet and a launcher. Generate Nerdlet or launcher individually. You can use the CLI command nr1 create and choose to select either a Nerdlet or launcher. This may be useful when adding Nerdlets to an existing Nerdpack. For a lesson on generating and connecting Nerdpack components, see the workshop. Nerdpack file structure When you generate a Nerdpack template using the CLI nr1 create command, it has this file structure: my-nerdlet ├── README.md ├── launchers │ └── my-nerdlet-launcher │ ├── icon.png │ └── nr1.json ├── nerdlets │ └── my-nerdlet-nerdlet │ ├── index.js │ ├── nr1.json │ └── styles.scss ├── node_modules │ ├── js-tokens │ ├── loose-envify │ ├── object-assign │ ├── prop-types │ ├── react │ ├── react-dom │ ├── react-is │ └── scheduler ├── nr1.json ├── package-lock.json └── package.json Nerdlet file structure A Nerdpack can contain one or more Nerdlets. A Nerdlet folder starts out with three default files: index.js The JavaScript code. Here's what the default file looks like when a Nerdlet is generated with the CLI nr1 create: import React from 'react'; export default class MyAwesomeNerdpack extends React.Component { render() { return

Hello, my-awesome-nerdpack Nerdlet!

} } nr1.json Configuration file. Here is the default file generated by the CLI nr1 create command: { \"schemaType\": \"NERDLET\", \"id\": \"my-awesome-nerdpack-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\" } Besides using the launcher as the access point for your application, you can also associate the application with a monitored entity to get it to appear in the New Relic One entity explorer. To do this, add two additional fields to the config file of the first-launched Nerdlet: entities and actionCategory. In the following example, the Nerdlet has been associated with all New Relic Browser-monitored applications and will appear under the Monitor UI category : { \"schemaType\": \"NERDLET\", \"id\": \"my-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"Custom Data\", \"entities\": [{\"domain\": \"BROWSER\", \"type\": \"APPLICATION\"}], \"actionCategory\": \"monitor\" } To see this application in the UI, you would go to the New Relic One entity explorer, select Browser applications, and select a monitored application. styles.scss The file for CSS styles (Sass SCSS syntax). Launcher file structure When an application with a launcher file has been deployed, its launcher is located on the New Relic One home page (one.newrelic.com). A launcher is not required; as an alternative to using a launcher, you can associate your application with a monitored entity. An application can have more than one launcher; this may be desired for an application with multiple Nerdlets. A launcher folder contains two files: nr1.json The configuration file. Here is the default file template created by the nr1 create command: { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } To connect a launcher to a Nerdlet, the rootNerdletId must match the id in the launched Nerdlet's nr1.json config file. For Nerdpacks with multiple Nerdlets, this needs to be done only for the first-launched Nerdlet. icon.png The launcher icon that appears on the one.newrelic.com home page when an application is deployed. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", - "type": "docs", + "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations, and fetch New Relic or third-party data. Components of the SDK SDK components are located in the Node module package named nr1, which you get when you install the NR1 CLI. The nr1 components can be divided into several categories: UI components Chart components Query and storage components Platform APIs UI components The UI components category of the SDK contains React UI components, including: Text components: These components provide basic font and heading elements. These include HeadingText and BlockText. Layout components: These components give you control over the layout, and help you build complex layout designs without having to deal with the CSS. Layout components include: Grid and GridItem: for organizing more complex, larger scale page content in rows and columns Stack and StackItem: for organizing simpler, smaller scale page content (in column or row) Tabs and TabsItem: group various related pieces of content into separate hideable sections List and ListItem: for providing a basic skeleton of virtualized lists Card, CardHeader and CardBody : used to group similar concepts and tasks together Form components: These components provide the basic building blocks to interact with the UI. These include Button, TextField, Dropdown and DropdownItem, Checkbox, RadioGroup, Radio, and Checkbox. Feedback components: These components are used to provide feedback to users about actions they have taken. These include: Spinnerand Toast. Overlaid components: These components are used to display contextual information and options in the form of an additional child view that appears above other content on screen when an action or event is triggered. They can either require user interaction (like modals), or be augmenting (like a tooltip). These include: Modal and Tooltip. Components suffixed with Item can only operate as direct children of that name without the suffix. For example: GridItem should only be found as a child of Grid. Chart components The Charts category of the SDK contains components representing different types of charts. The ChartGroup component helps a group of related charts share data and be aligned. Some chart components can perform NRQL queries on their own; some accept a customized set of data. Query and storage components The Query components category contains components for fetching and storing New Relic data. The main way to fetch data is with NerdGraph, our GraphQL endpoint. This can be queried using NerdGraphQuery. To simplify use of NerdGraph queries, we provide some components with pre-defined queries. For more on using NerdGraph, see Queries and mutations. We also provide storage for storing small data sets, such as configuration settings data, or user-specific data. For more on this, see NerdStorage. Platform APIs The Platform API components of the SDK enable your application to interact with different parts of the New Relic One platform, by reading and writing state from and to the URL, setting the configuration, etc. They can be divided into these categories: PlatformStateContext: provides read access to the platform URL state variables. Example: timeRange in the time picker. navigation: an object that allows programmatic manipulation of the navigation in New Relic One. Example: opening a new Nerdlet. NerdletStateContext: provides read access to the Nerdlet URL state variables. Example: an entityGuid in the entity explorer. nerdlet: an object that provides write access to the Nerdlet URL state.", + "type": "developer", "document_type": "page", - "breadcrumb": "Contents / New Relic One / Use New Relic One / Build on New Relic One", - "info": "For building a New Relic One application: an explanation of the Nerdpack/Nerdlet file structure. ", - "nodeid": 36006, + "info": "Intro to New Relic One API components", + "sections": [ + "Intro to New Relic One API components", + "Components of the SDK", + "UI components", + "Chart components", + "Query and storage components", + "Platform APIs" + ], + "title": "Intro to New Relic One API components", + "popularity": 1, + "tags": [ + "SDK components", + "New Relic One apps", + "UI components", + "chart components", + "query and storage components", + "Platform APIs" + ], + "external_id": "3620920c26bcd66c59c810dccb1200931b23b8c2", + "image": "", + "url": "https://developer.newrelic.com/explore-docs/intro-to-sdk/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:47:12Z", + "_index": "520d1d5d14cc8a32e600034b", + "_type": "520d1d5d14cc8a32e600034c", + "_score": 0.24868889, + "_version": null, + "_explanation": null, + "sort": null, + "highlight": { + "title": "Intro to New Relic One API components", + "sections": "Intro to New Relic One API components", + "info": "Intro to New Relic One API components", + "tags": "New Relic One apps", + "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations" + }, + "id": "5efa989e28ccbc4071307de5" + }, + { + "body": "Nerdpack file structure A New Relic One application is represented by a Nerdpack folder, which can include one or more Nerdlet files, and (optionally) one or more launcher files. Here we explain: The file structure for a Nerdpack, a Nerdlet, and a launcher How to link a launcher file to a Nerdlet How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create a Nerdpack template that includes a Nerdlet and a launcher. Generate Nerdlet or launcher individually: Use the New Relic One CLI command nr1 create and choose either Nerdlet or launcher. This can be useful when adding Nerdlets to an existing Nerdpack. For documentation on generating and connecting Nerdpack components, see our app building guides and the New Relic One CLI command reference. Nerdpack file structure When you generate a Nerdpack template using the nr1 create command, it has the following file structure: my-nerdlet ├── README.md ├── launchers │   └── my-nerdlet-launcher │   ├── icon.png │   └── nr1.json ├── nerdlets │   └── my-nerdlet-nerdlet │   ├── index.js │   ├── nr1.json │   └── styles.scss ├── node_modules │   ├── js-tokens │   ├── loose-envify │   ├── object-assign │   ├── prop-types │   ├── react │   ├── react-dom │   ├── react-is │   └── scheduler ├── nr1.json ├── package-lock.json └── package.json Copy Nerdlet file structure A Nerdpack can contain one or more Nerdlets. A Nerdlet folder starts out with three default files, index.js, nr1.json, and styles.scss. Here is what the default files look like after being generated using the nr1 create command: index.js The JavaScript code of the Nerdlet. import React from 'react'; export default class MyAwesomeNerdpack extends React.Component { render() { return

Hello, my-awesome-nerdpack Nerdlet!

; } } Copy nr1.json The Nerdlet configuration file. { \"schemaType\": \"NERDLET\", \"id\": \"my-awesome-nerdpack-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\" } Copy Besides using the launcher as the access point for your application, you can also associate the application with a monitored entity to get it to appear in the entity explorer. To do this, add two additional fields to the config file of the first-launched Nerdlet: entities and actionCategory. In the following example, the Nerdlet has been associated with all Browser-monitored applications and will appear under the Monitor UI category : { \"schemaType\": \"NERDLET\", \"id\": \"my-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"Custom Data\", \"entities\": [{ \"domain\": \"BROWSER\", \"type\": \"APPLICATION\" }], \"actionCategory\": \"monitor\" } Copy To see this application in the UI, you would go to the entity explorer, select Browser applications, and select a monitored application. styles.scss An empty SCSS file for styling your application. icon.png The launcher icon that appears on the Apps page in New Relic One when an application is deployed. Launcher file structure Launchers have their own file structure. Note that: A launcher is not required; as an alternative to using a launcher, you can associate your application with a monitored entity. An application can have more than one launcher, which might be desired for an application with multiple Nerdlets. After generating a launcher using the nr1 create command, its folder contains two files: nr1.json The configuration file. { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy To connect a launcher to a Nerdlet, the rootNerdletId must match the id in the launched Nerdlet's nr1.json config file. For Nerdpacks with multiple Nerdlets, this needs to be done only for the first-launched Nerdlet. icon.png The icon displayed on the launcher for the app on the Apps page.", + "type": "developer", + "document_type": "page", + "info": "An overview of the Nerdpack File Structure", "sections": [ - "Use New Relic One", - "Get started", - "Core concepts", - "UI and data", - "Workloads", - "Build on New Relic One", "Nerdpack file structure", "Generate Nerdpack components", "Nerdlet file structure", - "Launcher file structure", - "For more help" + "index.js", + "nr1.json", + "styles.scss", + "icon.png", + "Launcher file structure" ], "title": "Nerdpack file structure", "popularity": 1, - "external_id": "6e3788bee17cb65b6dc210862e2a10399f78ff67", - "category_1": "Use New Relic One", - "category_2": "Build on New Relic One", + "tags": [ + "New Relic One CLI", + "nerdpack", + "file structure", + "nerdlets", + "launchers" + ], + "external_id": "c97bcbb0a2b3d32ac93b5b379a1933e7b4e00161", "image": "", - "url": "https://docs.newrelic.com/docs/new-relic-one/use-new-relic-one/build-new-relic-one/new-relic-one-application-nerdpack-file-structure", - "published_at": "2020-08-18T15:32:31Z", - "updated_at": "2020-07-25T00:32:16Z", - "category_0": "New Relic One", + "url": "https://developer.newrelic.com/explore-docs/nerdpack-file-structure/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:49:25Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.94898546, + "_score": 0.21573672, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Nerdpack file structure", - "sections": "Nerdpack file structure", - "info": "For building a New Relic One application: an explanation of the Nerdpack/Nerdlet file structure. ", - "category_0": "New Relic One", - "category_1": "Use New Relic One", - "category_2": "Build on New Relic One", - "body": "A New Relic One application is represented by a Nerdpack folder, which can include one or more Nerdlet files, and (optionally) one or more launcher files. This document explains: The file structure for a Nerdpack, a Nerdlet and a launcher How to link a launcher file to a Nerdlet How to link your", - "breadcrumb": "Contents / New Relic One / Use New Relic One / Build on New Relic One" + "tags": "New Relic One CLI", + "body": " How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create" }, - "id": "5da0e07a64441f1328edf241" - }, + "id": "5efa989e196a671300766404" + } + ], + "/build-apps/set-up-dev-env": [ { - "body": "New Relic One CLI common commands Here's a list of common commands to get you started with the New Relic One CLI. You can click any command to see its usage options and additional details about the command. Command Description nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). See our other New Relic One CLI docs for commands specific to Nerdpack set-up, Nerdpack subscriptions, CLI configuration, plugins, or catalogs. Command details nr1 help See commands and get details Shows all nr1 commands by default. To get details about a specific command, run nr1 help COMMAND_NAME. Usage $ nr1 help Arguments COMMAND_NAME The name of a particular command. Examples $ nr1 help $ nr1 help nerdpack $ nr1 help nerdpack:deploy nr1 update Update your CLI Updates to latest version of the CLI. You can specify which channel to update if you'd like. Usage $ nr1 update Arguments CHANNEL The name of a particular channel. Examples $ nr1 update $ nr1 update somechannel nr1 create Create a new component Creates a new component from our template (either a Nerdpack, Nerdlet, launcher, or catalog). The CLI will walk you through this process. To learn more about Nerdpacks and their file structure, see Nerdpack file structure. For more on how to set up your Nerdpacks, see our Nerdpack CLI commands. Usage $ nr1 create Options -f, --force If present, overrides existing files without asking. -n, --name=NAME Names the component. -t, --type=TYPE Specifies the component type. --path=PATH The route to the component. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output. nr1 profiles Manage your profiles keychain Displays a list of commands you can use to manage your profiles. Run nr1 help profiles:COMMAND for more on their specific usages. You can have more than one profile, which is helpful for executing commands on multiple New Relic accounts. To learn more about setting up profiles, see our Github workshop. Usage $ nr1 profiles:COMMAND Commands profiles:add Adds a new profile to your profiles keychain. profiles:default Chooses which profile should be default. profiles:list Lists the profiles on your keychain. profiles:remove Removes a profile from your keychain. nr1 autocomplete See autocomplete installation instructions Displays the autocomplete installation instructions. By default, the command displays the autocomplete instructions for zsh. If you want instructions for bash, run nr1 autocomplete bash. Usage $ nr1 autocomplete Arguments SHELL The shell type you want instructions for. Options -r, --refresh-cache Refreshes cache (ignores displaying instructions). Examples $ nr1 autocomplete $ nr1 autocomplete zsh $ nr1 autocomplete bash $ nr1 autocomplete --refresh-cache nr1 nrql Query using NRQL Fetches data from databases using a NRQL query. To learn more about NRQL and how to use it, see our NRQL docs. Usage $ nr1 nrql OPTION ... Options -a, --account=ACCOUNT The user account ID. required -q, --query=QUERY The NRQL query to run. required -u, --ugly Displays the content without tabs or spaces. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output.", + "body": "Nerdpack file structure A New Relic One application is represented by a Nerdpack folder, which can include one or more Nerdlet files, and (optionally) one or more launcher files. Here we explain: The file structure for a Nerdpack, a Nerdlet, and a launcher How to link a launcher file to a Nerdlet How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create a Nerdpack template that includes a Nerdlet and a launcher. Generate Nerdlet or launcher individually: Use the New Relic One CLI command nr1 create and choose either Nerdlet or launcher. This can be useful when adding Nerdlets to an existing Nerdpack. For documentation on generating and connecting Nerdpack components, see our app building guides and the New Relic One CLI command reference. Nerdpack file structure When you generate a Nerdpack template using the nr1 create command, it has the following file structure: my-nerdlet ├── README.md ├── launchers │   └── my-nerdlet-launcher │   ├── icon.png │   └── nr1.json ├── nerdlets │   └── my-nerdlet-nerdlet │   ├── index.js │   ├── nr1.json │   └── styles.scss ├── node_modules │   ├── js-tokens │   ├── loose-envify │   ├── object-assign │   ├── prop-types │   ├── react │   ├── react-dom │   ├── react-is │   └── scheduler ├── nr1.json ├── package-lock.json └── package.json Copy Nerdlet file structure A Nerdpack can contain one or more Nerdlets. A Nerdlet folder starts out with three default files, index.js, nr1.json, and styles.scss. Here is what the default files look like after being generated using the nr1 create command: index.js The JavaScript code of the Nerdlet. import React from 'react'; export default class MyAwesomeNerdpack extends React.Component { render() { return

Hello, my-awesome-nerdpack Nerdlet!

; } } Copy nr1.json The Nerdlet configuration file. { \"schemaType\": \"NERDLET\", \"id\": \"my-awesome-nerdpack-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\" } Copy Besides using the launcher as the access point for your application, you can also associate the application with a monitored entity to get it to appear in the entity explorer. To do this, add two additional fields to the config file of the first-launched Nerdlet: entities and actionCategory. In the following example, the Nerdlet has been associated with all Browser-monitored applications and will appear under the Monitor UI category : { \"schemaType\": \"NERDLET\", \"id\": \"my-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"Custom Data\", \"entities\": [{ \"domain\": \"BROWSER\", \"type\": \"APPLICATION\" }], \"actionCategory\": \"monitor\" } Copy To see this application in the UI, you would go to the entity explorer, select Browser applications, and select a monitored application. styles.scss An empty SCSS file for styling your application. icon.png The launcher icon that appears on the Apps page in New Relic One when an application is deployed. Launcher file structure Launchers have their own file structure. Note that: A launcher is not required; as an alternative to using a launcher, you can associate your application with a monitored entity. An application can have more than one launcher, which might be desired for an application with multiple Nerdlets. After generating a launcher using the nr1 create command, its folder contains two files: nr1.json The configuration file. { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy To connect a launcher to a Nerdlet, the rootNerdletId must match the id in the launched Nerdlet's nr1.json config file. For Nerdpacks with multiple Nerdlets, this needs to be done only for the first-launched Nerdlet. icon.png The icon displayed on the launcher for the app on the Apps page.", "type": "developer", "document_type": "page", - "info": "An overview of common commands you can use with the New Relic One CLI.", + "info": "An overview of the Nerdpack File Structure", "sections": [ - "New Relic One CLI common commands", - "Command details", - "nr1 help", - "See commands and get details", - "Usage", - "Arguments", - "Examples", - "nr1 update", - "Update your CLI", - "nr1 create", - "Create a new component", - "Options", - "nr1 profiles", - "Manage your profiles keychain", - "Commands", - "nr1 autocomplete", - "See autocomplete installation instructions", - "nr1 nrql", - "Query using NRQL" + "Nerdpack file structure", + "Generate Nerdpack components", + "Nerdlet file structure", + "index.js", + "nr1.json", + "styles.scss", + "icon.png", + "Launcher file structure" ], - "title": "New Relic One CLI common commands", + "title": "Nerdpack file structure", "popularity": 1, - "external_id": "503e515e1095418f8d19329517344ab209d143a4", + "tags": [ + "New Relic One CLI", + "nerdpack", + "file structure", + "nerdlets", + "launchers" + ], + "external_id": "c97bcbb0a2b3d32ac93b5b379a1933e7b4e00161", "image": "", - "url": "https://developer.newrelic.com/explore-docs/nr1-common/", - "published_at": "2020-08-18T02:06:04Z", - "updated_at": "2020-08-14T01:48:10Z", + "url": "https://developer.newrelic.com/explore-docs/nerdpack-file-structure/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:49:25Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.80596286, + "_score": 12.332505, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic One CLI common commands", - "sections": "New Relic One CLI common commands", - "info": "An overview of common commands you can use with the New Relic One CLI.", - "body": " update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL" + "tags": "New Relic One CLI", + "body": " How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create" }, - "id": "5f28bd6ae7b9d267996ade94" - } - ], - "/explore-docs/nr1-catalog": [ + "id": "5efa989e196a671300766404" + }, { "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build your own application launcher and follow the quick start instructions. The quick start automatically generates an API key for the account you select, and gives you the pre-populated commands to create a profile, generate your first \"Hello World\" app, and serve it locally. Tip Use the NR1 VS Code extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions. For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). Configure your CLI preferences nr1 config:set Sets a specific configuration value. nr1 config:get Shows a specific configuration. nr1 config:list Lists your configuration choices. nr1 config:delete Removes the value of a specific configuration. Set up your Nerdpacks nr1 nerdpack:clone Clones an open source Nerdpack from our GitHub repository. nr1 nerdpack:serve Serves your Nerdpack for testing and development purposes. nr1 nerdpack:uuid Shows or regenerates the UUID of a Nerdpack. nr1 nerdpack:publish Publishes your Nerdpack to New Relic. nr1 nerdpack:deploy Deploys a Nerdpack version to a specific channel. nr1 nerdpack:undeploy Undeploys a Nerdpack version from a specific channel. Manage your Nerdpack subscriptions nr1 subscription:set Subscribes your account to a Nerdpack and channel. nr1 subscription:list Lists all the Nerdpacks your account is subscribed to. nr1 subscription:unset Unsubscribes your account from a Nerdpack. Install and manage plugins nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin into the CLI for development. nr1 plugins:update Updates your installed plugins. nr1 plugins:uninstall Removes a plugin from the CLI. Manage catalog information nr1 catalog:info Shows the Nerdpack info stored in the catalog. nr1 catalog:submit Gathers and submits the catalog info on the current folder.", "type": "developer", @@ -4269,57 +4018,23 @@ "external_id": "858339a44ead21c83257778ce60b4c352cd30d3b", "image": "https://developer.newrelic.com/static/2c6d337608b38a3312b4fc740afe6167/7272b/developercenter.png", "url": "https://developer.newrelic.com/explore-docs/nr1-cli/", - "published_at": "2020-08-18T02:07:10Z", + "published_at": "2020-08-19T01:50:40Z", "updated_at": "2020-08-18T01:50:36Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.746022, + "_score": 12.1957655, "_version": null, "_explanation": null, "sort": null, "highlight": { "title": "New Relic One CLI reference", - "sections": "New Relic One CLI Commands", + "sections": "New Relic One CLI reference", "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", "tags": "New Relic One app", - "body": " CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build" + "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use" }, "id": "5efa989e28ccbc535a307dd0" }, - { - "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs in GitHub. Options --format string output text format [YAML, JSON, Text] (default \"JSON\") -h, --help help for newrelic --plain output compact text Copy Commands newrelic apm - Interact with New Relic APM newrelic completion - Generates shell completion functions newrelic config - Manage the configuration of the New Relic CLI newrelic documentation - Generate CLI documentation newrelic entity - Interact with New Relic entities newrelic nerdgraph - Execute GraphQL requests to the NerdGraph API newrelic nerdstorage - Read, write, and delete NerdStorage documents and collections. newrelic nrql - Commands for interacting with the New Relic Database newrelic profile - Manage the authentication profiles for this tool newrelic version - Show the version of the New Relic CLI newrelic workload - Interact with New Relic One workloads", - "type": "developer", - "document_type": "page", - "info": "The command line tools for performing tasks against New Relic APIs", - "sections": [ - "New Relic CLI Reference", - "New Relic CLI commands", - "Options", - "Commands" - ], - "title": "New Relic CLI Reference", - "popularity": 1, - "tags": "new relic cli", - "external_id": "471ed214caaf80c70e14903ec71411e2a1c03888", - "image": "", - "url": "https://developer.newrelic.com/explore-docs/newrelic-cli/", - "published_at": "2020-08-18T02:11:50Z", - "updated_at": "2020-08-14T01:47:12Z", - "_index": "520d1d5d14cc8a32e600034b", - "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.30402333, - "_version": null, - "_explanation": null, - "sort": null, - "highlight": { - "title": "New Relic CLI Reference", - "sections": "New Relic CLI commands", - "info": "The command line tools for performing tasks against New Relic APIs", - "tags": "new relic cli", - "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs" - }, - "id": "5efa989ee7b9d2024b7bab97" - }, { "body": "Get started with the New Relic CLI 20 min Access the New Relic platform from the comfort of your terminal: you can use the New Relic CLI to manage entity tags, define workloads, record deployment markers, and much more. Our CLI has been designed for automating common tasks in your DevOps workflow. This guide walks you through the essentials of New Relic CLI, from install and configuration to basic usage. Before you begin For this guide you just need: Your New Relic personal API Key, which you can create from the Account settings of your New Relic account An instrumented application in your New Relic account Step 1 of 10 Install the New Relic CLI The New Relic CLI can be downloaded via Homebrew (macOS), Scoop (Windows), and Snapcraft (Linux). You can also download pre-built binaries for all platforms, including .deb and .rpm packages, and our Windows x64 .msi installer. Linux With Snapcraft installed, run: sudo snap install newrelic-cli macOS With Homebrew installed, run: brew install newrelic-cli Windows With Scoop installed, run: scoop bucket add newrelic-cli https://github.com/newrelic/newrelic-cli.git scoop install newrelic-cli Step 2 of 10 Create your New Relic CLI profile Now that you've installed the New Relic CLI, it's time to create your first profile. Profiles contain credentials and settings that you can apply to any CLI command, which is useful when switching between accounts. To create your first CLI profile, run the profiles add command. Note that you need to set the region of your New Relic account: use -r to set either us or eu (this is required). # Create the tutorial account for the US region newrelic profiles add -n tutorial --apiKey YOUR_NEW_RELIC_API_KEY -r YOUR_REGION # Set the profile as defaults newrelic profiles default -n tutorial Copy Step 3 of 10 Get your application details In this example, you are going to add tags to the application you've instrumented with New Relic. Tags are key-value pairs that can help you organize and filter your entities. An entity (for example, an application) can have a maximum of 100 key-value pairs tied to it. Before searching for your application using the New Relic CLI, write down or copy your Account ID and the name of your application in New Relic - you need both to find applications in the New Relic platform. Step 4 of 10 The New Relic CLI can retrieve your application details as a JSON object. To search for your APM application use the apm application search command. If you get an error, check that the account ID and application name you provided are correct. newrelic apm application search --accountId YOUR_ACCOUNT_ID --name NAME_OF_YOUR_APP Copy Step 5 of 10 If the account ID is valid, and the application name exists in your account, apm application search yields data similar to this example. When you've successfully searched for your application, look for the guid value. It's a unique identifier for your application. You should copy it or write it down. [ { accountId: YOUR_ACCOUNT_ID, applicationId: YOUR_APP_ID, domain: 'APM', entityType: 'APM_APPLICATION_ENTITY', guid: 'A_LONG_GUID', name: 'NAME_OF_YOUR_APP', permalink: 'https://one.newrelic.com/redirect/entity/A_LONG_GUID', reporting: true, type: 'APPLICATION', }, ]; Copy Step 6 of 10 Add a simple tag to your application Now that you have the GUID, you can point the New Relic CLI directly at your application. Adding a tag is the simplest way to try out the CLI capabilities (don't worry, tags can be deleted by using entity tags delete). Let's suppose that you want to add an environment tag to your application. Go ahead and add the dev:testing tag⁠ (or any other key-value pair) to your application using the entities tags create command. newrelic entity tags create --guid YOUR_APP_GUID --tag devkit:testing Copy Step 7 of 10 What if you want to add multiple tags? Tag sets come to the rescue! While tags are key-value pairs separated by colons, tag sets are comma separated lists of tags. For example: tag1:value1,tag2:value2 To add multiple tags at once to your application, modify and run the following snippet. newrelic entity tags create --guid YOUR_APP_GUID --tag tag1:test,tag2:test Copy Adding tags is an asynchronous operation: this means it could take a while for the tags to get created. Step 8 of 10 You've created and added some tags to your application, but how do you know they're there? You need to retrieve your application's tags. To retrieve your application's tags, use the entity tags get command. newrelic entity tags get --guid YOUR_APP_GUID All tags associated with your application are retrieved as a JSON array. [ { Key: 'tag1', Values: ['true'], }, { Key: 'tag2', Values: ['test'], }, { Key: 'tag3', Values: ['testing'], }, // ... ]; Copy Step 9 of 10 Bonus step: Create a deployment marker Deployments of applications often go wrong. Deployment markers are labels that, when attached to your application data, help you track deployments and troubleshoot what happened. To create a deployment marker, run the apm deployment create command using the same Application ID from your earlier search. newrelic apm deployment create --applicationId YOUR_APP_ID --revision $(git describe --tags --always) Copy Step 10 of 10 Notice that the JSON response includes the revision and timestamp of the deployment. This workflow could be built into a continuous integration or continuous deployment (CI/CD) system to help indicate changes in your application's behavior after deployments. Here is an example. { \"id\": 37075986, \"links\": { \"application\": 204261368 }, \"revision\": \"v1.2.4\", \"timestamp\": \"2020-03-04T15:11:44-08:00\", \"user\": \"Developer Toolkit Test Account\" } Copy Next steps Have a look at all the available commands. For example, you could create a New Relic workflow using workload create If you'd like to engage with other community members, visit our New Relic Explorers Hub page. We welcome feature requests or bug reports on GitHub.", "type": "developer", @@ -4350,11 +4065,11 @@ "external_id": "531f2f3985bf64bb0dc92a642445887095048882", "image": "", "url": "https://developer.newrelic.com/automate-workflows/get-started-new-relic-cli/", - "published_at": "2020-08-18T02:06:05Z", + "published_at": "2020-08-19T01:47:10Z", "updated_at": "2020-08-08T01:41:47Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.15999478, + "_score": 6.2245407, "_version": null, "_explanation": null, "sort": null, @@ -4363,102 +4078,99 @@ "sections": "Get started with the New Relic CLI", "info": "Learn the essentials of the New Relic CLI, from install and configuration to basic usage.", "tags": "New Relic CLI", - "body": " that you've installed the New Relic CLI, it's time to create your first profile. Profiles contain credentials and settings that you can apply to any CLI command, which is useful when switching between accounts. To create your first CLI profile, run the profiles add command. Note that you need" + "body": ". This guide walks you through the essentials of New Relic CLI, from install and configuration to basic usage. Before you begin For this guide you just need: Your New Relic personal API Key, which you can create from the Account settings of your New Relic account An instrumented application in your" }, "id": "5efa999c196a67c4e1766461" }, { - "body": "Create a \"Hello, World!\" application 15 min Here's how you can quickly build a \"Hello, World!\" application in New Relic One. In these steps, you create a local version of the New Relic One site where you can prototype your application. Then, when you're ready to share the application with others, you can publish it to New Relic One. See the video, which demonstrates the steps in this guide in five minutes. Before you begin To get started, make sure you have accounts in GitHub and New Relic. To develop projects, you need the New Relic One CLI (command line interface). If you haven't already installed it, do the following: Install Node.js. Complete all the steps in the CLI quick start. For additional details about setting up your environment, see Set up your development environment. Tip Use the NR1 VS Code extension to build your apps. Create a local version of the \"Hello, World!\" application The CLI allows you to run a local version of New Relic One. You can develop your application locally before you publish it in New Relic One. If you followed all the steps in the CLI quick start, you now have files under a new directory named after your nerdpack project. Here's how you edit those files to create a \"Hello, World!\" project: Step 1 of 9 Open a code editor and point it to the new directory named after your nerdpack project (for example, my-awesome-nerdpack). Your code editor displays two artifacts: launchers containing the homepage tile nerdlets containing your application code Step 2 of 9 Expand nerdlets in your code editor, and open index.js. Step 3 of 9 Change the default return message to \"Hello, World!\": import React from 'react'; // https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction export default class MyAwesomeNerdpackNerdletNerdlet extends React.Component { render() { return

\"Hello, World!\"

; } } Copy Step 4 of 9 As an optional step, you can add a custom launcher icon using any image file named icon.png. Replace the default icon.png file under launcher by dragging in your new image file: Step 5 of 9 To change the name of the launcher to something meaningful, in your code editor under launchers, open nr1.json. Step 6 of 9 Change the value for displayName to anything you want as the launcher label, and save the file: { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"INSERT_YOUR_TILE_LABEL_HERE\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy Step 7 of 9 To see your new changes locally, start the Node server with this command in your terminal: npm start Copy Step 8 of 9 Open a browser and go to https://one.newrelic.com/?nerdpacks=local (this url is also shown in the terminal). Step 9 of 9 When the browser opens, click Apps, and then in the Other apps section, click the new launcher for your application. Here's an example where we inserted a leaf icon: After you click the new launcher, your \"Hello, World!\" appears: Publish your application to New Relic Your colleagues can't see your local application, so when you are ready to share it, publish it to the New Relic One catalog. The catalog is where you can find any pre-existing custom applications, as well as any applications you create in your own organization. Step 1 of 4 Execute the following in your terminal: nr1 nerdpack:publish Copy Step 2 of 4 Close your local New Relic One development tab, and open New Relic One. Step 3 of 4 Click the Apps launcher. Step 4 of 4 Under New Relic One catalog, click the launcher for your new application. When your new application opens, notice that it doesn't display any helpful descriptive information. The next section shows you how to add descriptive metadata. Add details to describe your project Now that your new application is in the New Relic One catalog, you can add details that help users understand what your application does and how to use it. Step 1 of 5 Go to your project in the terminal and execute the following: nr1 create Copy Step 2 of 5 Select catalog, which creates a stub in your project under the catalog directory. Here's how the results might look in your code editor: Step 3 of 5 In the catalog directory of your project, add screenshots or various types of metadata to describe your project. For details about what you can add, see Add catalog metadata and screenshots. Step 4 of 5 After you add the screenshots and descriptions you want, execute the following to save your metadata to the catalog: nr1 catalog:submit Copy Step 5 of 5 Return to the catalog and refresh the page to see your new screenshots and metadata describing your project. Subscribe accounts to your application To make sure other users see your application in the catalog, you need to subscribe accounts to the application. Any user with the NerdPack Manager role can subscribe accounts to an application. Step 1 of 3 If you're not already displaying your application's description page in the browser, click the launcher for the application in the catalog under Your company applications. Step 2 of 3 On your application's description page, click Add this app. Step 3 of 3 Select the accounts you want to subscribe to the application, and then click Update accounts to save your selections. When you return to the Apps page, you'll see the launcher for your new application. Summary Now that you've completed the steps in this example, you learned the basic steps to: Create a local application. Publish the application to the New Relic One catalog so you can share it with your colleagues. Add details to the project in the catalog so users understand how to use it. Subscribe accounts to your application so other users can use it. Related information Create a local application. Publish the application to the New Relic One catalog so you can share it with your colleagues. Add details to the project in the catalog so users understand how to use it. Subscribe accounts to your application so other users can see it directly on their homepage.", + "body": "Quickly tag a set of resources 5 min Tags help you group, search, filter, and focus the data about your entities, which can be anything from applications to hosts to services. Tagging entities using the New Relic CLI is a good candidate for automation. In this 5-minute guide, you use the New Relic CLI to add multiple tags to one of your entities. Before you begin For this guide you need your New Relic personal API Key: Create it at the Account settings screen for your account. Step 1 of 6 Install the New Relic CLI You can download the New Relic CLI via Homebrew (macOS), Scoop (Windows), and Snapcraft (Linux). You can also download pre-built binaries for all platforms, including .deb and .rpm packages, and our Windows x64 .msi installer. Linux With Snapcraft installed, run: sudo snap install newrelic-cli macOS With Homebrew installed, run: brew install newrelic-cli Windows With Scoop installed, run: scoop bucket add newrelic-cli https://github.com/newrelic/newrelic-cli.git scoop install newrelic-cli Step 2 of 6 Create your New Relic CLI profile New Relic CLI profiles contain credentials and settings that you can apply to any CLI command. To create your first CLI profile, run the profiles add command. Don't forget to set the region of your New Relic account: use -r to set either us or eu (this is required). # Create the tutorial account for the US region newrelic profiles add -n tutorial --apiKey API_KEY -r us # Set the profile as default newrelic profiles default -n tutorial Copy Step 3 of 6 Search for an entity Your New Relic account might have hundreds of entities: Have a quick look by opening the Entity explorer. In the terminal, run entity search to retrieve a list of entities from your account as JSON. In the example, you're searching for all entities with \"test\" in their name. # Change the `name` to match any of your existing entities newrelic entity search --name \"test\" Copy Step 4 of 6 If there are matching entities in your account, the query yields data in JSON format, similar to this workload example. Select an entity from the results and look for its guid value; the guid is the unique identifier of the entity. Write it down. { \"accountId\": 123456789, \"domain\": \"NR1\", \"entityType\": \"WORKLOAD_ENTITY\", \"guid\": \"F7B7AE59FDED4204B846FB08423DB18E\", \"name\": \"Test workload\", \"reporting\": true, \"type\": \"WORKLOAD\" }, Copy Step 5 of 6 Add tags and tag lists to your entity With your entity guid, you can add tags right away. You can do so by invoking the entities tags create command. What if you want to add multiple tags? You can use tag sets for that: While tags are key-value pairs separated by colons, tag sets are comma-separated lists of tags. For example: tag1:value1,tag2:value2 Note Adding tags is an asynchronous operation: it could take a little while for the tags to get created. # Adding a single tag newrelic entity tags create --guid GUID --tag key:value # Adding multiple tags newrelic entity tags create --guid GUID --tag tag1:test,tag2:test Copy Step 6 of 6 Check that the tags are there To make sure that the tags have been added to your entities, retrieve them using the entity tags get command. All tags associated with your entity are retrieved as a JSON array. newrelic entity tags get --guid GUID Tip Tags can be deleted at any time by invoking the entity tags delete command followed by the same arguments you used to create them. [ { Key: 'tag1', Values: ['true'], }, { Key: 'tag2', Values: ['test'], }, { Key: 'tag3', Values: ['testing'], }, // ... ]; Copy Next steps Have a look at all the New Relic CLI commands. For example, you could create a New Relic workflow using workload create. If you'd like to engage with other community members, visit our New Relic Explorers Hub page. We welcome feature requests or bug reports on GitHub.", "type": "developer", "document_type": "page", - "info": "Build a \"Hello, World!\" app and publish it to New Relic One", + "info": "Add tags to applications you instrument for easier filtering and organization.", "sections": [ - "Create a \"Hello, World!\" application", + "Quickly tag a set of resources", "Before you begin", + "Install the New Relic CLI", + "Linux", + "macOS", + "Windows", + "Create your New Relic CLI profile", + "Search for an entity", + "Add tags and tag lists to your entity", + "Note", + "Check that the tags are there", "Tip", - "Create a local version of the \"Hello, World!\" application", - "Publish your application to New Relic", - "Add details to describe your project", - "Subscribe accounts to your application", - "Summary", - "Related information" + "Next steps" ], - "title": "Create a \"Hello, World!\" application", + "title": "Quickly tag a set of resources", "popularity": 1, "tags": [ - "nr1 cli", - "Nerdpack file structure", - "NR One Catalog", - "Subscribe applications" + "tags", + "new relic CLI" ], - "external_id": "aa427030169067481fb69a3560798265b6b52b7c", - "image": "https://developer.newrelic.com/static/cb65a35ad6fa52f5245359ecd24158ff/9466d/hello-world-output-local.png", - "url": "https://developer.newrelic.com/build-apps/build-hello-world-app/", - "published_at": "2020-08-18T02:09:27Z", - "updated_at": "2020-08-18T01:45:02Z", + "external_id": "c7c374812f8295e409a9b06d552de51ceefc666b", + "image": "", + "url": "https://developer.newrelic.com/automate-workflows/5-mins-tag-resources/", + "published_at": "2020-08-19T01:44:48Z", + "updated_at": "2020-08-14T01:45:08Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.12382183, + "_score": 2.6271067, "_version": null, "_explanation": null, "sort": null, "highlight": { - "sections": "Publish your application to New Relic", - "info": "Build a "Hello, World!" app and publish it to New Relic One", - "tags": "NR One Catalog", - "body": ", you can publish it to New Relic One. See the video, which demonstrates the steps in this guide in five minutes. Before you begin To get started, make sure you have accounts in GitHub and New Relic. To develop projects, you need the New Relic One CLI (command line interface). If you haven't already" + "sections": "Install the New Relic CLI", + "tags": "new relic CLI", + "body": " CLI to add multiple tags to one of your entities. Before you begin For this guide you need your New Relic personal API Key: Create it at the Account settings screen for your account. Step 1 of 6 Install the New Relic CLI You can download the New Relic CLI via Homebrew (macOS), Scoop (Windows" }, - "id": "5efa9973196a67d16d76645c" + "id": "5efa999d64441fa74a5f7e2d" }, { - "body": "New Relic One CLI common commands Here's a list of common commands to get you started with the New Relic One CLI. You can click any command to see its usage options and additional details about the command. Command Description nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). See our other New Relic One CLI docs for commands specific to Nerdpack set-up, Nerdpack subscriptions, CLI configuration, plugins, or catalogs. Command details nr1 help See commands and get details Shows all nr1 commands by default. To get details about a specific command, run nr1 help COMMAND_NAME. Usage $ nr1 help Arguments COMMAND_NAME The name of a particular command. Examples $ nr1 help $ nr1 help nerdpack $ nr1 help nerdpack:deploy nr1 update Update your CLI Updates to latest version of the CLI. You can specify which channel to update if you'd like. Usage $ nr1 update Arguments CHANNEL The name of a particular channel. Examples $ nr1 update $ nr1 update somechannel nr1 create Create a new component Creates a new component from our template (either a Nerdpack, Nerdlet, launcher, or catalog). The CLI will walk you through this process. To learn more about Nerdpacks and their file structure, see Nerdpack file structure. For more on how to set up your Nerdpacks, see our Nerdpack CLI commands. Usage $ nr1 create Options -f, --force If present, overrides existing files without asking. -n, --name=NAME Names the component. -t, --type=TYPE Specifies the component type. --path=PATH The route to the component. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output. nr1 profiles Manage your profiles keychain Displays a list of commands you can use to manage your profiles. Run nr1 help profiles:COMMAND for more on their specific usages. You can have more than one profile, which is helpful for executing commands on multiple New Relic accounts. To learn more about setting up profiles, see our Github workshop. Usage $ nr1 profiles:COMMAND Commands profiles:add Adds a new profile to your profiles keychain. profiles:default Chooses which profile should be default. profiles:list Lists the profiles on your keychain. profiles:remove Removes a profile from your keychain. nr1 autocomplete See autocomplete installation instructions Displays the autocomplete installation instructions. By default, the command displays the autocomplete instructions for zsh. If you want instructions for bash, run nr1 autocomplete bash. Usage $ nr1 autocomplete Arguments SHELL The shell type you want instructions for. Options -r, --refresh-cache Refreshes cache (ignores displaying instructions). Examples $ nr1 autocomplete $ nr1 autocomplete zsh $ nr1 autocomplete bash $ nr1 autocomplete --refresh-cache nr1 nrql Query using NRQL Fetches data from databases using a NRQL query. To learn more about NRQL and how to use it, see our NRQL docs. Usage $ nr1 nrql OPTION ... Options -a, --account=ACCOUNT The user account ID. required -q, --query=QUERY The NRQL query to run. required -u, --ugly Displays the content without tabs or spaces. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output.", + "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations, and fetch New Relic or third-party data. Components of the SDK SDK components are located in the Node module package named nr1, which you get when you install the NR1 CLI. The nr1 components can be divided into several categories: UI components Chart components Query and storage components Platform APIs UI components The UI components category of the SDK contains React UI components, including: Text components: These components provide basic font and heading elements. These include HeadingText and BlockText. Layout components: These components give you control over the layout, and help you build complex layout designs without having to deal with the CSS. Layout components include: Grid and GridItem: for organizing more complex, larger scale page content in rows and columns Stack and StackItem: for organizing simpler, smaller scale page content (in column or row) Tabs and TabsItem: group various related pieces of content into separate hideable sections List and ListItem: for providing a basic skeleton of virtualized lists Card, CardHeader and CardBody : used to group similar concepts and tasks together Form components: These components provide the basic building blocks to interact with the UI. These include Button, TextField, Dropdown and DropdownItem, Checkbox, RadioGroup, Radio, and Checkbox. Feedback components: These components are used to provide feedback to users about actions they have taken. These include: Spinnerand Toast. Overlaid components: These components are used to display contextual information and options in the form of an additional child view that appears above other content on screen when an action or event is triggered. They can either require user interaction (like modals), or be augmenting (like a tooltip). These include: Modal and Tooltip. Components suffixed with Item can only operate as direct children of that name without the suffix. For example: GridItem should only be found as a child of Grid. Chart components The Charts category of the SDK contains components representing different types of charts. The ChartGroup component helps a group of related charts share data and be aligned. Some chart components can perform NRQL queries on their own; some accept a customized set of data. Query and storage components The Query components category contains components for fetching and storing New Relic data. The main way to fetch data is with NerdGraph, our GraphQL endpoint. This can be queried using NerdGraphQuery. To simplify use of NerdGraph queries, we provide some components with pre-defined queries. For more on using NerdGraph, see Queries and mutations. We also provide storage for storing small data sets, such as configuration settings data, or user-specific data. For more on this, see NerdStorage. Platform APIs The Platform API components of the SDK enable your application to interact with different parts of the New Relic One platform, by reading and writing state from and to the URL, setting the configuration, etc. They can be divided into these categories: PlatformStateContext: provides read access to the platform URL state variables. Example: timeRange in the time picker. navigation: an object that allows programmatic manipulation of the navigation in New Relic One. Example: opening a new Nerdlet. NerdletStateContext: provides read access to the Nerdlet URL state variables. Example: an entityGuid in the entity explorer. nerdlet: an object that provides write access to the Nerdlet URL state.", "type": "developer", "document_type": "page", - "info": "An overview of common commands you can use with the New Relic One CLI.", + "info": "Intro to New Relic One API components", "sections": [ - "New Relic One CLI common commands", - "Command details", - "nr1 help", - "See commands and get details", - "Usage", - "Arguments", - "Examples", - "nr1 update", - "Update your CLI", - "nr1 create", - "Create a new component", - "Options", - "nr1 profiles", - "Manage your profiles keychain", - "Commands", - "nr1 autocomplete", - "See autocomplete installation instructions", - "nr1 nrql", - "Query using NRQL" + "Intro to New Relic One API components", + "Components of the SDK", + "UI components", + "Chart components", + "Query and storage components", + "Platform APIs" + ], + "title": "Intro to New Relic One API components", + "popularity": 1, + "tags": [ + "SDK components", + "New Relic One apps", + "UI components", + "chart components", + "query and storage components", + "Platform APIs" ], - "title": "New Relic One CLI common commands", - "popularity": 1, - "external_id": "503e515e1095418f8d19329517344ab209d143a4", + "external_id": "3620920c26bcd66c59c810dccb1200931b23b8c2", "image": "", - "url": "https://developer.newrelic.com/explore-docs/nr1-common/", - "published_at": "2020-08-18T02:06:04Z", - "updated_at": "2020-08-14T01:48:10Z", + "url": "https://developer.newrelic.com/explore-docs/intro-to-sdk/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:47:12Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.019941866, + "_score": 2.5712626, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic One CLI common commands", - "sections": "New Relic One CLI common commands", - "info": "An overview of common commands you can use with the New Relic One CLI.", - "body": "New Relic One CLI common commands Here's a list of common commands to get you started with the New Relic One CLI. You can click any command to see its usage options and additional details about the command. Command Description nr1 help Shows all nr1 commands or details about each command. nr1" + "title": "Intro to New Relic One API components", + "sections": "Intro to New Relic One API components", + "info": "Intro to New Relic One API components", + "tags": "New Relic One apps", + "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations" }, - "id": "5f28bd6ae7b9d267996ade94" + "id": "5efa989e28ccbc4071307de5" } ], - "/explore-docs/nr1-nerdpack": [ + "/build-apps/publish-deploy": [ { "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build your own application launcher and follow the quick start instructions. The quick start automatically generates an API key for the account you select, and gives you the pre-populated commands to create a profile, generate your first \"Hello World\" app, and serve it locally. Tip Use the NR1 VS Code extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions. For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). Configure your CLI preferences nr1 config:set Sets a specific configuration value. nr1 config:get Shows a specific configuration. nr1 config:list Lists your configuration choices. nr1 config:delete Removes the value of a specific configuration. Set up your Nerdpacks nr1 nerdpack:clone Clones an open source Nerdpack from our GitHub repository. nr1 nerdpack:serve Serves your Nerdpack for testing and development purposes. nr1 nerdpack:uuid Shows or regenerates the UUID of a Nerdpack. nr1 nerdpack:publish Publishes your Nerdpack to New Relic. nr1 nerdpack:deploy Deploys a Nerdpack version to a specific channel. nr1 nerdpack:undeploy Undeploys a Nerdpack version from a specific channel. Manage your Nerdpack subscriptions nr1 subscription:set Subscribes your account to a Nerdpack and channel. nr1 subscription:list Lists all the Nerdpacks your account is subscribed to. nr1 subscription:unset Unsubscribes your account from a Nerdpack. Install and manage plugins nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin into the CLI for development. nr1 plugins:update Updates your installed plugins. nr1 plugins:uninstall Removes a plugin from the CLI. Manage catalog information nr1 catalog:info Shows the Nerdpack info stored in the catalog. nr1 catalog:submit Gathers and submits the catalog info on the current folder.", "type": "developer", @@ -4485,196 +4197,188 @@ "external_id": "858339a44ead21c83257778ce60b4c352cd30d3b", "image": "https://developer.newrelic.com/static/2c6d337608b38a3312b4fc740afe6167/7272b/developercenter.png", "url": "https://developer.newrelic.com/explore-docs/nr1-cli/", - "published_at": "2020-08-18T02:07:10Z", + "published_at": "2020-08-19T01:50:40Z", "updated_at": "2020-08-18T01:50:36Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.9420942, + "_score": 0.23095155, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic One CLI reference", - "sections": "New Relic One CLI Commands", - "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", - "tags": "New Relic One app", - "body": ". For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet" + "title": "New Relic One CLI reference", + "sections": "New Relic One CLI reference", + "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", + "tags": "New Relic One app", + "body": ". For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet" }, "id": "5efa989e28ccbc535a307dd0" }, { - "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs in GitHub. Options --format string output text format [YAML, JSON, Text] (default \"JSON\") -h, --help help for newrelic --plain output compact text Copy Commands newrelic apm - Interact with New Relic APM newrelic completion - Generates shell completion functions newrelic config - Manage the configuration of the New Relic CLI newrelic documentation - Generate CLI documentation newrelic entity - Interact with New Relic entities newrelic nerdgraph - Execute GraphQL requests to the NerdGraph API newrelic nerdstorage - Read, write, and delete NerdStorage documents and collections. newrelic nrql - Commands for interacting with the New Relic Database newrelic profile - Manage the authentication profiles for this tool newrelic version - Show the version of the New Relic CLI newrelic workload - Interact with New Relic One workloads", + "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations, and fetch New Relic or third-party data. Components of the SDK SDK components are located in the Node module package named nr1, which you get when you install the NR1 CLI. The nr1 components can be divided into several categories: UI components Chart components Query and storage components Platform APIs UI components The UI components category of the SDK contains React UI components, including: Text components: These components provide basic font and heading elements. These include HeadingText and BlockText. Layout components: These components give you control over the layout, and help you build complex layout designs without having to deal with the CSS. Layout components include: Grid and GridItem: for organizing more complex, larger scale page content in rows and columns Stack and StackItem: for organizing simpler, smaller scale page content (in column or row) Tabs and TabsItem: group various related pieces of content into separate hideable sections List and ListItem: for providing a basic skeleton of virtualized lists Card, CardHeader and CardBody : used to group similar concepts and tasks together Form components: These components provide the basic building blocks to interact with the UI. These include Button, TextField, Dropdown and DropdownItem, Checkbox, RadioGroup, Radio, and Checkbox. Feedback components: These components are used to provide feedback to users about actions they have taken. These include: Spinnerand Toast. Overlaid components: These components are used to display contextual information and options in the form of an additional child view that appears above other content on screen when an action or event is triggered. They can either require user interaction (like modals), or be augmenting (like a tooltip). These include: Modal and Tooltip. Components suffixed with Item can only operate as direct children of that name without the suffix. For example: GridItem should only be found as a child of Grid. Chart components The Charts category of the SDK contains components representing different types of charts. The ChartGroup component helps a group of related charts share data and be aligned. Some chart components can perform NRQL queries on their own; some accept a customized set of data. Query and storage components The Query components category contains components for fetching and storing New Relic data. The main way to fetch data is with NerdGraph, our GraphQL endpoint. This can be queried using NerdGraphQuery. To simplify use of NerdGraph queries, we provide some components with pre-defined queries. For more on using NerdGraph, see Queries and mutations. We also provide storage for storing small data sets, such as configuration settings data, or user-specific data. For more on this, see NerdStorage. Platform APIs The Platform API components of the SDK enable your application to interact with different parts of the New Relic One platform, by reading and writing state from and to the URL, setting the configuration, etc. They can be divided into these categories: PlatformStateContext: provides read access to the platform URL state variables. Example: timeRange in the time picker. navigation: an object that allows programmatic manipulation of the navigation in New Relic One. Example: opening a new Nerdlet. NerdletStateContext: provides read access to the Nerdlet URL state variables. Example: an entityGuid in the entity explorer. nerdlet: an object that provides write access to the Nerdlet URL state.", "type": "developer", "document_type": "page", - "info": "The command line tools for performing tasks against New Relic APIs", + "info": "Intro to New Relic One API components", "sections": [ - "New Relic CLI Reference", - "New Relic CLI commands", - "Options", - "Commands" + "Intro to New Relic One API components", + "Components of the SDK", + "UI components", + "Chart components", + "Query and storage components", + "Platform APIs" ], - "title": "New Relic CLI Reference", + "title": "Intro to New Relic One API components", "popularity": 1, - "tags": "new relic cli", - "external_id": "471ed214caaf80c70e14903ec71411e2a1c03888", + "tags": [ + "SDK components", + "New Relic One apps", + "UI components", + "chart components", + "query and storage components", + "Platform APIs" + ], + "external_id": "3620920c26bcd66c59c810dccb1200931b23b8c2", "image": "", - "url": "https://developer.newrelic.com/explore-docs/newrelic-cli/", - "published_at": "2020-08-18T02:11:50Z", + "url": "https://developer.newrelic.com/explore-docs/intro-to-sdk/", + "published_at": "2020-08-19T01:50:40Z", "updated_at": "2020-08-14T01:47:12Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.30665752, + "_score": 0.114149675, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic CLI Reference", - "sections": "New Relic CLI commands", - "info": "The command line tools for performing tasks against New Relic APIs", - "tags": "new relic cli", - "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs" + "title": "Intro to New Relic One API components", + "sections": "Intro to New Relic One API components", + "info": "Intro to New Relic One API components", + "tags": "New Relic One apps", + "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations" }, - "id": "5efa989ee7b9d2024b7bab97" + "id": "5efa989e28ccbc4071307de5" }, { - "body": "Get started with the New Relic CLI 20 min Access the New Relic platform from the comfort of your terminal: you can use the New Relic CLI to manage entity tags, define workloads, record deployment markers, and much more. Our CLI has been designed for automating common tasks in your DevOps workflow. This guide walks you through the essentials of New Relic CLI, from install and configuration to basic usage. Before you begin For this guide you just need: Your New Relic personal API Key, which you can create from the Account settings of your New Relic account An instrumented application in your New Relic account Step 1 of 10 Install the New Relic CLI The New Relic CLI can be downloaded via Homebrew (macOS), Scoop (Windows), and Snapcraft (Linux). You can also download pre-built binaries for all platforms, including .deb and .rpm packages, and our Windows x64 .msi installer. Linux With Snapcraft installed, run: sudo snap install newrelic-cli macOS With Homebrew installed, run: brew install newrelic-cli Windows With Scoop installed, run: scoop bucket add newrelic-cli https://github.com/newrelic/newrelic-cli.git scoop install newrelic-cli Step 2 of 10 Create your New Relic CLI profile Now that you've installed the New Relic CLI, it's time to create your first profile. Profiles contain credentials and settings that you can apply to any CLI command, which is useful when switching between accounts. To create your first CLI profile, run the profiles add command. Note that you need to set the region of your New Relic account: use -r to set either us or eu (this is required). # Create the tutorial account for the US region newrelic profiles add -n tutorial --apiKey YOUR_NEW_RELIC_API_KEY -r YOUR_REGION # Set the profile as defaults newrelic profiles default -n tutorial Copy Step 3 of 10 Get your application details In this example, you are going to add tags to the application you've instrumented with New Relic. Tags are key-value pairs that can help you organize and filter your entities. An entity (for example, an application) can have a maximum of 100 key-value pairs tied to it. Before searching for your application using the New Relic CLI, write down or copy your Account ID and the name of your application in New Relic - you need both to find applications in the New Relic platform. Step 4 of 10 The New Relic CLI can retrieve your application details as a JSON object. To search for your APM application use the apm application search command. If you get an error, check that the account ID and application name you provided are correct. newrelic apm application search --accountId YOUR_ACCOUNT_ID --name NAME_OF_YOUR_APP Copy Step 5 of 10 If the account ID is valid, and the application name exists in your account, apm application search yields data similar to this example. When you've successfully searched for your application, look for the guid value. It's a unique identifier for your application. You should copy it or write it down. [ { accountId: YOUR_ACCOUNT_ID, applicationId: YOUR_APP_ID, domain: 'APM', entityType: 'APM_APPLICATION_ENTITY', guid: 'A_LONG_GUID', name: 'NAME_OF_YOUR_APP', permalink: 'https://one.newrelic.com/redirect/entity/A_LONG_GUID', reporting: true, type: 'APPLICATION', }, ]; Copy Step 6 of 10 Add a simple tag to your application Now that you have the GUID, you can point the New Relic CLI directly at your application. Adding a tag is the simplest way to try out the CLI capabilities (don't worry, tags can be deleted by using entity tags delete). Let's suppose that you want to add an environment tag to your application. Go ahead and add the dev:testing tag⁠ (or any other key-value pair) to your application using the entities tags create command. newrelic entity tags create --guid YOUR_APP_GUID --tag devkit:testing Copy Step 7 of 10 What if you want to add multiple tags? Tag sets come to the rescue! While tags are key-value pairs separated by colons, tag sets are comma separated lists of tags. For example: tag1:value1,tag2:value2 To add multiple tags at once to your application, modify and run the following snippet. newrelic entity tags create --guid YOUR_APP_GUID --tag tag1:test,tag2:test Copy Adding tags is an asynchronous operation: this means it could take a while for the tags to get created. Step 8 of 10 You've created and added some tags to your application, but how do you know they're there? You need to retrieve your application's tags. To retrieve your application's tags, use the entity tags get command. newrelic entity tags get --guid YOUR_APP_GUID All tags associated with your application are retrieved as a JSON array. [ { Key: 'tag1', Values: ['true'], }, { Key: 'tag2', Values: ['test'], }, { Key: 'tag3', Values: ['testing'], }, // ... ]; Copy Step 9 of 10 Bonus step: Create a deployment marker Deployments of applications often go wrong. Deployment markers are labels that, when attached to your application data, help you track deployments and troubleshoot what happened. To create a deployment marker, run the apm deployment create command using the same Application ID from your earlier search. newrelic apm deployment create --applicationId YOUR_APP_ID --revision $(git describe --tags --always) Copy Step 10 of 10 Notice that the JSON response includes the revision and timestamp of the deployment. This workflow could be built into a continuous integration or continuous deployment (CI/CD) system to help indicate changes in your application's behavior after deployments. Here is an example. { \"id\": 37075986, \"links\": { \"application\": 204261368 }, \"revision\": \"v1.2.4\", \"timestamp\": \"2020-03-04T15:11:44-08:00\", \"user\": \"Developer Toolkit Test Account\" } Copy Next steps Have a look at all the available commands. For example, you could create a New Relic workflow using workload create If you'd like to engage with other community members, visit our New Relic Explorers Hub page. We welcome feature requests or bug reports on GitHub.", + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app, you might have some additional setup and configuration. This guide covers: Downloading the New Relic One CLI to build or modify apps Contribute content to this website Before you begin You must have: A github account account - While not strictly necessary for building apps, a GitHub account enables you to download and customize our open source apps, and contribute an open source project. A New Relic developer account - if you don't already have one, you can get a free trial account for developing New Relic applications. npm - If you've installed Node.js, then you already have npm, which is used to share, reuse, and update JavaScript code, and is necessary for working with React components that are the framework for New Relic apps and this website. Tip Use the New Relic One VSCode extension to build your apps. Prepare to build or modify apps Step 1 of 2 Download the CLI and API key On the Build New Relic One applications page, complete the Quick start steps. These six Quick start steps get you an API key for use with developing apps, and the New Relic One CLI, for building and deploying apps. At the end of the Quick start, you have a project consisting of the following: A Nerdpack - The package containing all the files required by your application. It contains two types of files that you customize to build your app: Nerdlets, and the launcher. One or more Nerdlet files - A specific UI view or window. A Nerdlet is a React JavaScript package that includes an index.js file, a stylesheet, and a JSON-format config file. It can contain any JS functionality (charts, interactive fields, tooltips, etc.). A launcher file: This is the basis for the launcher, which is used to open your application from New Relic One after you publish your app. Step 2 of 2 Start building If you're ready to code, cd to your Nerdpack and get started. If you want to learn more about building applications, try these step-by-step guides: Build a \"Hello, World!\" application shows how to create a little application, publish it to New Relic One, and share it with others by subscribing accounts to it. Map pageviews by region takes you through the steps to create one of our popular open source apps. You learn to add a custom query to an app and view it in a table, then add that data to a map. Contributing to developer.newrelic.com This site is open source, and we want your input. Create a pull request if you see a mistake you know how to fix. Drop us a GitHub issue if you see some content gaps you want us to work on. Or write up a whole new guide if you have one you'd like to share. Read on to learn how. Step 1 of 3 Fork the developer-website GithHub repo Forking the repo enables you to work on your own copy of the developer.newrelic.com files, and build the site locally. It also enables us to more easily manage incomimg pull requests. On the developer-website page in GitHub, select the Fork button on the top right of the page, choose the account you want to fork to, and wait a few seconds while the fork is created. Sync regularly to keep your fork up to date with changes and additions to the main branch upstream. Step 2 of 3 Make a feature or documentation request On any page, select the GitHub button at the top of the page, and then select the kind of change you want, and fill out the GitHub form. Step 3 of 3 Contribute a new guide Check out our contributors guidelines, which will walk you through the process.", "type": "developer", "document_type": "page", - "info": "Learn the essentials of the New Relic CLI, from install and configuration to basic usage.", + "info": "Prepare to build apps and contribute to this site", "sections": [ - "Get started with the New Relic CLI", + "Set up your development environment", "Before you begin", - "Install the New Relic CLI", - "Linux", - "macOS", - "Windows", - "Create your New Relic CLI profile", - "Get your application details", - "Add a simple tag to your application", - "Bonus step: Create a deployment marker", - "Next steps" + "Tip", + "Prepare to build or modify apps", + "Start building" ], - "title": "Get started with the New Relic CLI", + "title": "Set up your development environment", "popularity": 1, "tags": [ - "api key", - "New Relic CLI", - "Tags", - "Entity", - "Deployment markers" + "developer account", + "API key", + "New Relic One CLI" ], - "external_id": "531f2f3985bf64bb0dc92a642445887095048882", + "external_id": "c45638a9cd548d1ffffc9f1c7708f115a92ae04a", "image": "", - "url": "https://developer.newrelic.com/automate-workflows/get-started-new-relic-cli/", - "published_at": "2020-08-18T02:06:05Z", - "updated_at": "2020-08-08T01:41:47Z", + "url": "https://developer.newrelic.com/build-apps/set-up-dev-env/", + "published_at": "2020-08-19T01:44:48Z", + "updated_at": "2020-08-19T01:44:47Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.16153151, + "_score": 0.09152748, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Get started with the New Relic CLI", - "sections": "Get started with the New Relic CLI", - "info": "Learn the essentials of the New Relic CLI, from install and configuration to basic usage.", - "tags": "New Relic CLI", - "body": " that you've installed the New Relic CLI, it's time to create your first profile. Profiles contain credentials and settings that you can apply to any CLI command, which is useful when switching between accounts. To create your first CLI profile, run the profiles add command. Note that you need" + "title": "Set up your development environment", + "sections": "Set up your development environment", + "info": "Prepare to build apps and contribute to this site", + "tags": "New Relic One CLI", + "body": ", a stylesheet, and a JSON-format config file. It can contain any JS functionality (charts, interactive fields, tooltips, etc.). A launcher file: This is the basis for the launcher, which is used to open your application from New Relic One after you publish your app. Step 2 of 2 Start building If you're" }, - "id": "5efa999c196a67c4e1766461" + "id": "5efa9973e7b9d242237bab39" }, { - "body": "Create a \"Hello, World!\" application 15 min Here's how you can quickly build a \"Hello, World!\" application in New Relic One. In these steps, you create a local version of the New Relic One site where you can prototype your application. Then, when you're ready to share the application with others, you can publish it to New Relic One. See the video, which demonstrates the steps in this guide in five minutes. Before you begin To get started, make sure you have accounts in GitHub and New Relic. To develop projects, you need the New Relic One CLI (command line interface). If you haven't already installed it, do the following: Install Node.js. Complete all the steps in the CLI quick start. For additional details about setting up your environment, see Set up your development environment. Tip Use the NR1 VS Code extension to build your apps. Create a local version of the \"Hello, World!\" application The CLI allows you to run a local version of New Relic One. You can develop your application locally before you publish it in New Relic One. If you followed all the steps in the CLI quick start, you now have files under a new directory named after your nerdpack project. Here's how you edit those files to create a \"Hello, World!\" project: Step 1 of 9 Open a code editor and point it to the new directory named after your nerdpack project (for example, my-awesome-nerdpack). Your code editor displays two artifacts: launchers containing the homepage tile nerdlets containing your application code Step 2 of 9 Expand nerdlets in your code editor, and open index.js. Step 3 of 9 Change the default return message to \"Hello, World!\": import React from 'react'; // https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction export default class MyAwesomeNerdpackNerdletNerdlet extends React.Component { render() { return

\"Hello, World!\"

; } } Copy Step 4 of 9 As an optional step, you can add a custom launcher icon using any image file named icon.png. Replace the default icon.png file under launcher by dragging in your new image file: Step 5 of 9 To change the name of the launcher to something meaningful, in your code editor under launchers, open nr1.json. Step 6 of 9 Change the value for displayName to anything you want as the launcher label, and save the file: { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"INSERT_YOUR_TILE_LABEL_HERE\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy Step 7 of 9 To see your new changes locally, start the Node server with this command in your terminal: npm start Copy Step 8 of 9 Open a browser and go to https://one.newrelic.com/?nerdpacks=local (this url is also shown in the terminal). Step 9 of 9 When the browser opens, click Apps, and then in the Other apps section, click the new launcher for your application. Here's an example where we inserted a leaf icon: After you click the new launcher, your \"Hello, World!\" appears: Publish your application to New Relic Your colleagues can't see your local application, so when you are ready to share it, publish it to the New Relic One catalog. The catalog is where you can find any pre-existing custom applications, as well as any applications you create in your own organization. Step 1 of 4 Execute the following in your terminal: nr1 nerdpack:publish Copy Step 2 of 4 Close your local New Relic One development tab, and open New Relic One. Step 3 of 4 Click the Apps launcher. Step 4 of 4 Under New Relic One catalog, click the launcher for your new application. When your new application opens, notice that it doesn't display any helpful descriptive information. The next section shows you how to add descriptive metadata. Add details to describe your project Now that your new application is in the New Relic One catalog, you can add details that help users understand what your application does and how to use it. Step 1 of 5 Go to your project in the terminal and execute the following: nr1 create Copy Step 2 of 5 Select catalog, which creates a stub in your project under the catalog directory. Here's how the results might look in your code editor: Step 3 of 5 In the catalog directory of your project, add screenshots or various types of metadata to describe your project. For details about what you can add, see Add catalog metadata and screenshots. Step 4 of 5 After you add the screenshots and descriptions you want, execute the following to save your metadata to the catalog: nr1 catalog:submit Copy Step 5 of 5 Return to the catalog and refresh the page to see your new screenshots and metadata describing your project. Subscribe accounts to your application To make sure other users see your application in the catalog, you need to subscribe accounts to the application. Any user with the NerdPack Manager role can subscribe accounts to an application. Step 1 of 3 If you're not already displaying your application's description page in the browser, click the launcher for the application in the catalog under Your company applications. Step 2 of 3 On your application's description page, click Add this app. Step 3 of 3 Select the accounts you want to subscribe to the application, and then click Update accounts to save your selections. When you return to the Apps page, you'll see the launcher for your new application. Summary Now that you've completed the steps in this example, you learned the basic steps to: Create a local application. Publish the application to the New Relic One catalog so you can share it with your colleagues. Add details to the project in the catalog so users understand how to use it. Subscribe accounts to your application so other users can use it. Related information Create a local application. Publish the application to the New Relic One catalog so you can share it with your colleagues. Add details to the project in the catalog so users understand how to use it. Subscribe accounts to your application so other users can see it directly on their homepage.", + "body": "Intro to NerdStorage 30 min To help you build a New Relic One application, we provide you with the New Relic One SDK. On this page, you’ll learn how to use NerdStorage SDK components. Use NerdStorage in your apps NerdStorage is used to store and retrieve simple sets of data, including users's configuration settings and preferences (like favorites), or any other small data sets. This storage is unique per Nerdpack, and can't be shared with any other Nerdpack. NerdStorage can be classified into three categories: User storage: Data that is attached to a particular user. If you’re authenticated as the user the data is attached to, you can read it and write it. Account storage: Data that is attached to a particular account. If you’re authenticated and can access the account, you can read and write to account scoped NerdStorage. Visibility of account data is also determined by master/subaccount rules: If a user has access to the master account, then they also have access to data in all subaccounts. Entity storage: Data that is attached to a particular entity. If you can see the corresponding entity, you can read and write data on that entity. Data model You can imagine NerdStorage as a nested key-value map. Data is inside documents, which are nested inside collections: { 'YourNerdpackUuid': { 'collection-1': { 'document-1-of-collection-1': '{\"lastNumber\": 42, \"another\": [1]}', 'document-2-of-collection-1': '\"userToken\"', // ... }, 'another-collection': { 'fruits': '[\"pear\", \"apple\"]', // ... }, // ... }, } Copy Each NerdStorage level has different properties and purpose: Collections: From a Nerdpack, you can create multiple collections by naming each of them. Inside a collection you can put one or more documents. Think of a collection as key-value storage, where each document is a key-value pair. Documents: A document is formed by an identifier (documentId) and a set of data associated with it. Data associated with a document: NerdStorage accepts any sort of data associated to a documentId. Query and mutation components that are provided work by serializing and deserializing JSON. Limits A Nerdpack can hold up to 1,000 collections and 10,000 documents, plus storage type. A collection can hold up to 1,000 documents, plus storage type. Each document can have a maximum length of 64 KiB when serialized. Data access To access NerdStorage, you can run NerdGraph queries, or use the provided storage queries. Depending on which storage you want to access, you can use a different set of SDK components: User access: UserStorageQuery and UserStorageMutation Account access: AccountStorageQuery and AccountStorageMutation Entity access: EntityStorageQuery and EntityStorageMutation Each of these components can operate declaratively (for example, as part of your React rendering methods) or imperatively (by using the static methods for query and mutation). For more information on this, see Data querying and mutations. Permissions for working with NerdStorage In order to persist changes on NerdStorage, such as creating, updating, and deleting account and entity storage, you must have a user role with permission to persist changes.", "type": "developer", "document_type": "page", - "info": "Build a \"Hello, World!\" app and publish it to New Relic One", + "info": "Intro to NerdStorage on New Relic One", "sections": [ - "Create a \"Hello, World!\" application", - "Before you begin", - "Tip", - "Create a local version of the \"Hello, World!\" application", - "Publish your application to New Relic", - "Add details to describe your project", - "Subscribe accounts to your application", - "Summary", - "Related information" + "Intro to NerdStorage", + "Use NerdStorage in your apps", + "Data model", + "Limits", + "Data access", + "Permissions for working with NerdStorage" ], - "title": "Create a \"Hello, World!\" application", + "title": "Intro to NerdStorage", "popularity": 1, "tags": [ - "nr1 cli", - "Nerdpack file structure", - "NR One Catalog", - "Subscribe applications" + "nerdstorage", + "nerdstorage components", + "new relic one apps", + "data access" ], - "external_id": "aa427030169067481fb69a3560798265b6b52b7c", - "image": "https://developer.newrelic.com/static/cb65a35ad6fa52f5245359ecd24158ff/9466d/hello-world-output-local.png", - "url": "https://developer.newrelic.com/build-apps/build-hello-world-app/", - "published_at": "2020-08-18T02:09:27Z", - "updated_at": "2020-08-18T01:45:02Z", + "external_id": "709e06c25376d98b2191ca369b4d139e5084bd62", + "image": "", + "url": "https://developer.newrelic.com/explore-docs/nerdstorage/", + "published_at": "2020-08-19T01:49:36Z", + "updated_at": "2020-08-14T01:50:34Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.121671684, + "_score": 0.08144541, "_version": null, "_explanation": null, "sort": null, "highlight": { - "sections": "Publish your application to New Relic", - "info": "Build a "Hello, World!" app and publish it to New Relic One", - "tags": "nr1 cli", - "body": ", you can publish it to New Relic One. See the video, which demonstrates the steps in this guide in five minutes. Before you begin To get started, make sure you have accounts in GitHub and New Relic. To develop projects, you need the New Relic One CLI (command line interface). If you haven't already" + "sections": "Use NerdStorage in your apps", + "info": "Intro to NerdStorage on New Relic One", + "tags": "new relic one apps", + "body": "Intro to NerdStorage 30 min To help you build a New Relic One application, we provide you with the New Relic One SDK. On this page, you’ll learn how to use NerdStorage SDK components. Use NerdStorage in your apps NerdStorage is used to store and retrieve simple sets of data, including users's" }, - "id": "5efa9973196a67d16d76645c" + "id": "5efa989ee7b9d2048e7bab92" }, { - "body": "New Relic One CLI common commands Here's a list of common commands to get you started with the New Relic One CLI. You can click any command to see its usage options and additional details about the command. Command Description nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). See our other New Relic One CLI docs for commands specific to Nerdpack set-up, Nerdpack subscriptions, CLI configuration, plugins, or catalogs. Command details nr1 help See commands and get details Shows all nr1 commands by default. To get details about a specific command, run nr1 help COMMAND_NAME. Usage $ nr1 help Arguments COMMAND_NAME The name of a particular command. Examples $ nr1 help $ nr1 help nerdpack $ nr1 help nerdpack:deploy nr1 update Update your CLI Updates to latest version of the CLI. You can specify which channel to update if you'd like. Usage $ nr1 update Arguments CHANNEL The name of a particular channel. Examples $ nr1 update $ nr1 update somechannel nr1 create Create a new component Creates a new component from our template (either a Nerdpack, Nerdlet, launcher, or catalog). The CLI will walk you through this process. To learn more about Nerdpacks and their file structure, see Nerdpack file structure. For more on how to set up your Nerdpacks, see our Nerdpack CLI commands. Usage $ nr1 create Options -f, --force If present, overrides existing files without asking. -n, --name=NAME Names the component. -t, --type=TYPE Specifies the component type. --path=PATH The route to the component. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output. nr1 profiles Manage your profiles keychain Displays a list of commands you can use to manage your profiles. Run nr1 help profiles:COMMAND for more on their specific usages. You can have more than one profile, which is helpful for executing commands on multiple New Relic accounts. To learn more about setting up profiles, see our Github workshop. Usage $ nr1 profiles:COMMAND Commands profiles:add Adds a new profile to your profiles keychain. profiles:default Chooses which profile should be default. profiles:list Lists the profiles on your keychain. profiles:remove Removes a profile from your keychain. nr1 autocomplete See autocomplete installation instructions Displays the autocomplete installation instructions. By default, the command displays the autocomplete instructions for zsh. If you want instructions for bash, run nr1 autocomplete bash. Usage $ nr1 autocomplete Arguments SHELL The shell type you want instructions for. Options -r, --refresh-cache Refreshes cache (ignores displaying instructions). Examples $ nr1 autocomplete $ nr1 autocomplete zsh $ nr1 autocomplete bash $ nr1 autocomplete --refresh-cache nr1 nrql Query using NRQL Fetches data from databases using a NRQL query. To learn more about NRQL and how to use it, see our NRQL docs. Usage $ nr1 nrql OPTION ... Options -a, --account=ACCOUNT The user account ID. required -q, --query=QUERY The NRQL query to run. required -u, --ugly Displays the content without tabs or spaces. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output.", + "body": "Nerdpack file structure A New Relic One application is represented by a Nerdpack folder, which can include one or more Nerdlet files, and (optionally) one or more launcher files. Here we explain: The file structure for a Nerdpack, a Nerdlet, and a launcher How to link a launcher file to a Nerdlet How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create a Nerdpack template that includes a Nerdlet and a launcher. Generate Nerdlet or launcher individually: Use the New Relic One CLI command nr1 create and choose either Nerdlet or launcher. This can be useful when adding Nerdlets to an existing Nerdpack. For documentation on generating and connecting Nerdpack components, see our app building guides and the New Relic One CLI command reference. Nerdpack file structure When you generate a Nerdpack template using the nr1 create command, it has the following file structure: my-nerdlet ├── README.md ├── launchers │   └── my-nerdlet-launcher │   ├── icon.png │   └── nr1.json ├── nerdlets │   └── my-nerdlet-nerdlet │   ├── index.js │   ├── nr1.json │   └── styles.scss ├── node_modules │   ├── js-tokens │   ├── loose-envify │   ├── object-assign │   ├── prop-types │   ├── react │   ├── react-dom │   ├── react-is │   └── scheduler ├── nr1.json ├── package-lock.json └── package.json Copy Nerdlet file structure A Nerdpack can contain one or more Nerdlets. A Nerdlet folder starts out with three default files, index.js, nr1.json, and styles.scss. Here is what the default files look like after being generated using the nr1 create command: index.js The JavaScript code of the Nerdlet. import React from 'react'; export default class MyAwesomeNerdpack extends React.Component { render() { return

Hello, my-awesome-nerdpack Nerdlet!

; } } Copy nr1.json The Nerdlet configuration file. { \"schemaType\": \"NERDLET\", \"id\": \"my-awesome-nerdpack-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\" } Copy Besides using the launcher as the access point for your application, you can also associate the application with a monitored entity to get it to appear in the entity explorer. To do this, add two additional fields to the config file of the first-launched Nerdlet: entities and actionCategory. In the following example, the Nerdlet has been associated with all Browser-monitored applications and will appear under the Monitor UI category : { \"schemaType\": \"NERDLET\", \"id\": \"my-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"Custom Data\", \"entities\": [{ \"domain\": \"BROWSER\", \"type\": \"APPLICATION\" }], \"actionCategory\": \"monitor\" } Copy To see this application in the UI, you would go to the entity explorer, select Browser applications, and select a monitored application. styles.scss An empty SCSS file for styling your application. icon.png The launcher icon that appears on the Apps page in New Relic One when an application is deployed. Launcher file structure Launchers have their own file structure. Note that: A launcher is not required; as an alternative to using a launcher, you can associate your application with a monitored entity. An application can have more than one launcher, which might be desired for an application with multiple Nerdlets. After generating a launcher using the nr1 create command, its folder contains two files: nr1.json The configuration file. { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy To connect a launcher to a Nerdlet, the rootNerdletId must match the id in the launched Nerdlet's nr1.json config file. For Nerdpacks with multiple Nerdlets, this needs to be done only for the first-launched Nerdlet. icon.png The icon displayed on the launcher for the app on the Apps page.", "type": "developer", "document_type": "page", - "info": "An overview of common commands you can use with the New Relic One CLI.", + "info": "An overview of the Nerdpack File Structure", "sections": [ - "New Relic One CLI common commands", - "Command details", - "nr1 help", - "See commands and get details", - "Usage", - "Arguments", - "Examples", - "nr1 update", - "Update your CLI", - "nr1 create", - "Create a new component", - "Options", - "nr1 profiles", - "Manage your profiles keychain", - "Commands", - "nr1 autocomplete", - "See autocomplete installation instructions", - "nr1 nrql", - "Query using NRQL" + "Nerdpack file structure", + "Generate Nerdpack components", + "Nerdlet file structure", + "index.js", + "nr1.json", + "styles.scss", + "icon.png", + "Launcher file structure" ], - "title": "New Relic One CLI common commands", + "title": "Nerdpack file structure", "popularity": 1, - "external_id": "503e515e1095418f8d19329517344ab209d143a4", + "tags": [ + "New Relic One CLI", + "nerdpack", + "file structure", + "nerdlets", + "launchers" + ], + "external_id": "c97bcbb0a2b3d32ac93b5b379a1933e7b4e00161", "image": "", - "url": "https://developer.newrelic.com/explore-docs/nr1-common/", - "published_at": "2020-08-18T02:06:04Z", - "updated_at": "2020-08-14T01:48:10Z", + "url": "https://developer.newrelic.com/explore-docs/nerdpack-file-structure/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:49:25Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.092428446, + "_score": 0.06836939, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic One CLI common commands", - "sections": "New Relic One CLI common commands", - "info": "An overview of common commands you can use with the New Relic One CLI.", - "body": " (New Relic query language). See our other New Relic One CLI docs for commands specific to Nerdpack set-up, Nerdpack subscriptions, CLI configuration, plugins, or catalogs. Command details nr1 help See commands and get details Shows all nr1 commands by default. To get details about a specific command" + "tags": "New Relic One CLI", + "body": " How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create" }, - "id": "5f28bd6ae7b9d267996ade94" + "id": "5efa989e196a671300766404" } ], - "/explore-docs/nr1-plugins": [ + "/explore-docs/nr1-common": [ { "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build your own application launcher and follow the quick start instructions. The quick start automatically generates an API key for the account you select, and gives you the pre-populated commands to create a profile, generate your first \"Hello World\" app, and serve it locally. Tip Use the NR1 VS Code extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions. For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). Configure your CLI preferences nr1 config:set Sets a specific configuration value. nr1 config:get Shows a specific configuration. nr1 config:list Lists your configuration choices. nr1 config:delete Removes the value of a specific configuration. Set up your Nerdpacks nr1 nerdpack:clone Clones an open source Nerdpack from our GitHub repository. nr1 nerdpack:serve Serves your Nerdpack for testing and development purposes. nr1 nerdpack:uuid Shows or regenerates the UUID of a Nerdpack. nr1 nerdpack:publish Publishes your Nerdpack to New Relic. nr1 nerdpack:deploy Deploys a Nerdpack version to a specific channel. nr1 nerdpack:undeploy Undeploys a Nerdpack version from a specific channel. Manage your Nerdpack subscriptions nr1 subscription:set Subscribes your account to a Nerdpack and channel. nr1 subscription:list Lists all the Nerdpacks your account is subscribed to. nr1 subscription:unset Unsubscribes your account from a Nerdpack. Install and manage plugins nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin into the CLI for development. nr1 plugins:update Updates your installed plugins. nr1 plugins:uninstall Removes a plugin from the CLI. Manage catalog information nr1 catalog:info Shows the Nerdpack info stored in the catalog. nr1 catalog:submit Gathers and submits the catalog info on the current folder.", "type": "developer", @@ -4701,11 +4405,11 @@ "external_id": "858339a44ead21c83257778ce60b4c352cd30d3b", "image": "https://developer.newrelic.com/static/2c6d337608b38a3312b4fc740afe6167/7272b/developercenter.png", "url": "https://developer.newrelic.com/explore-docs/nr1-cli/", - "published_at": "2020-08-18T02:07:10Z", + "published_at": "2020-08-19T01:50:40Z", "updated_at": "2020-08-18T01:50:36Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.7391757, + "_score": 0.60584474, "_version": null, "_explanation": null, "sort": null, @@ -4718,6 +4422,42 @@ }, "id": "5efa989e28ccbc535a307dd0" }, + { + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app, you might have some additional setup and configuration. This guide covers: Downloading the New Relic One CLI to build or modify apps Contribute content to this website Before you begin You must have: A github account account - While not strictly necessary for building apps, a GitHub account enables you to download and customize our open source apps, and contribute an open source project. A New Relic developer account - if you don't already have one, you can get a free trial account for developing New Relic applications. npm - If you've installed Node.js, then you already have npm, which is used to share, reuse, and update JavaScript code, and is necessary for working with React components that are the framework for New Relic apps and this website. Tip Use the New Relic One VSCode extension to build your apps. Prepare to build or modify apps Step 1 of 2 Download the CLI and API key On the Build New Relic One applications page, complete the Quick start steps. These six Quick start steps get you an API key for use with developing apps, and the New Relic One CLI, for building and deploying apps. At the end of the Quick start, you have a project consisting of the following: A Nerdpack - The package containing all the files required by your application. It contains two types of files that you customize to build your app: Nerdlets, and the launcher. One or more Nerdlet files - A specific UI view or window. A Nerdlet is a React JavaScript package that includes an index.js file, a stylesheet, and a JSON-format config file. It can contain any JS functionality (charts, interactive fields, tooltips, etc.). A launcher file: This is the basis for the launcher, which is used to open your application from New Relic One after you publish your app. Step 2 of 2 Start building If you're ready to code, cd to your Nerdpack and get started. If you want to learn more about building applications, try these step-by-step guides: Build a \"Hello, World!\" application shows how to create a little application, publish it to New Relic One, and share it with others by subscribing accounts to it. Map pageviews by region takes you through the steps to create one of our popular open source apps. You learn to add a custom query to an app and view it in a table, then add that data to a map. Contributing to developer.newrelic.com This site is open source, and we want your input. Create a pull request if you see a mistake you know how to fix. Drop us a GitHub issue if you see some content gaps you want us to work on. Or write up a whole new guide if you have one you'd like to share. Read on to learn how. Step 1 of 3 Fork the developer-website GithHub repo Forking the repo enables you to work on your own copy of the developer.newrelic.com files, and build the site locally. It also enables us to more easily manage incomimg pull requests. On the developer-website page in GitHub, select the Fork button on the top right of the page, choose the account you want to fork to, and wait a few seconds while the fork is created. Sync regularly to keep your fork up to date with changes and additions to the main branch upstream. Step 2 of 3 Make a feature or documentation request On any page, select the GitHub button at the top of the page, and then select the kind of change you want, and fill out the GitHub form. Step 3 of 3 Contribute a new guide Check out our contributors guidelines, which will walk you through the process.", + "type": "developer", + "document_type": "page", + "info": "Prepare to build apps and contribute to this site", + "sections": [ + "Set up your development environment", + "Before you begin", + "Tip", + "Prepare to build or modify apps", + "Start building" + ], + "title": "Set up your development environment", + "popularity": 1, + "tags": [ + "developer account", + "API key", + "New Relic One CLI" + ], + "external_id": "c45638a9cd548d1ffffc9f1c7708f115a92ae04a", + "image": "", + "url": "https://developer.newrelic.com/build-apps/set-up-dev-env/", + "published_at": "2020-08-19T01:44:48Z", + "updated_at": "2020-08-19T01:44:47Z", + "_index": "520d1d5d14cc8a32e600034b", + "_type": "520d1d5d14cc8a32e600034c", + "_score": 0.28801563, + "_version": null, + "_explanation": null, + "sort": null, + "highlight": { + "tags": "New Relic One CLI", + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app" + }, + "id": "5efa9973e7b9d242237bab39" + }, { "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs in GitHub. Options --format string output text format [YAML, JSON, Text] (default \"JSON\") -h, --help help for newrelic --plain output compact text Copy Commands newrelic apm - Interact with New Relic APM newrelic completion - Generates shell completion functions newrelic config - Manage the configuration of the New Relic CLI newrelic documentation - Generate CLI documentation newrelic entity - Interact with New Relic entities newrelic nerdgraph - Execute GraphQL requests to the NerdGraph API newrelic nerdstorage - Read, write, and delete NerdStorage documents and collections. newrelic nrql - Commands for interacting with the New Relic Database newrelic profile - Manage the authentication profiles for this tool newrelic version - Show the version of the New Relic CLI newrelic workload - Interact with New Relic One workloads", "type": "developer", @@ -4735,11 +4475,11 @@ "external_id": "471ed214caaf80c70e14903ec71411e2a1c03888", "image": "", "url": "https://developer.newrelic.com/explore-docs/newrelic-cli/", - "published_at": "2020-08-18T02:11:50Z", + "published_at": "2020-08-19T01:49:36Z", "updated_at": "2020-08-14T01:47:12Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.30295157, + "_score": 0.25155777, "_version": null, "_explanation": null, "sort": null, @@ -4752,145 +4492,92 @@ }, "id": "5efa989ee7b9d2024b7bab97" }, - { - "body": "Get started with the New Relic CLI 20 min Access the New Relic platform from the comfort of your terminal: you can use the New Relic CLI to manage entity tags, define workloads, record deployment markers, and much more. Our CLI has been designed for automating common tasks in your DevOps workflow. This guide walks you through the essentials of New Relic CLI, from install and configuration to basic usage. Before you begin For this guide you just need: Your New Relic personal API Key, which you can create from the Account settings of your New Relic account An instrumented application in your New Relic account Step 1 of 10 Install the New Relic CLI The New Relic CLI can be downloaded via Homebrew (macOS), Scoop (Windows), and Snapcraft (Linux). You can also download pre-built binaries for all platforms, including .deb and .rpm packages, and our Windows x64 .msi installer. Linux With Snapcraft installed, run: sudo snap install newrelic-cli macOS With Homebrew installed, run: brew install newrelic-cli Windows With Scoop installed, run: scoop bucket add newrelic-cli https://github.com/newrelic/newrelic-cli.git scoop install newrelic-cli Step 2 of 10 Create your New Relic CLI profile Now that you've installed the New Relic CLI, it's time to create your first profile. Profiles contain credentials and settings that you can apply to any CLI command, which is useful when switching between accounts. To create your first CLI profile, run the profiles add command. Note that you need to set the region of your New Relic account: use -r to set either us or eu (this is required). # Create the tutorial account for the US region newrelic profiles add -n tutorial --apiKey YOUR_NEW_RELIC_API_KEY -r YOUR_REGION # Set the profile as defaults newrelic profiles default -n tutorial Copy Step 3 of 10 Get your application details In this example, you are going to add tags to the application you've instrumented with New Relic. Tags are key-value pairs that can help you organize and filter your entities. An entity (for example, an application) can have a maximum of 100 key-value pairs tied to it. Before searching for your application using the New Relic CLI, write down or copy your Account ID and the name of your application in New Relic - you need both to find applications in the New Relic platform. Step 4 of 10 The New Relic CLI can retrieve your application details as a JSON object. To search for your APM application use the apm application search command. If you get an error, check that the account ID and application name you provided are correct. newrelic apm application search --accountId YOUR_ACCOUNT_ID --name NAME_OF_YOUR_APP Copy Step 5 of 10 If the account ID is valid, and the application name exists in your account, apm application search yields data similar to this example. When you've successfully searched for your application, look for the guid value. It's a unique identifier for your application. You should copy it or write it down. [ { accountId: YOUR_ACCOUNT_ID, applicationId: YOUR_APP_ID, domain: 'APM', entityType: 'APM_APPLICATION_ENTITY', guid: 'A_LONG_GUID', name: 'NAME_OF_YOUR_APP', permalink: 'https://one.newrelic.com/redirect/entity/A_LONG_GUID', reporting: true, type: 'APPLICATION', }, ]; Copy Step 6 of 10 Add a simple tag to your application Now that you have the GUID, you can point the New Relic CLI directly at your application. Adding a tag is the simplest way to try out the CLI capabilities (don't worry, tags can be deleted by using entity tags delete). Let's suppose that you want to add an environment tag to your application. Go ahead and add the dev:testing tag⁠ (or any other key-value pair) to your application using the entities tags create command. newrelic entity tags create --guid YOUR_APP_GUID --tag devkit:testing Copy Step 7 of 10 What if you want to add multiple tags? Tag sets come to the rescue! While tags are key-value pairs separated by colons, tag sets are comma separated lists of tags. For example: tag1:value1,tag2:value2 To add multiple tags at once to your application, modify and run the following snippet. newrelic entity tags create --guid YOUR_APP_GUID --tag tag1:test,tag2:test Copy Adding tags is an asynchronous operation: this means it could take a while for the tags to get created. Step 8 of 10 You've created and added some tags to your application, but how do you know they're there? You need to retrieve your application's tags. To retrieve your application's tags, use the entity tags get command. newrelic entity tags get --guid YOUR_APP_GUID All tags associated with your application are retrieved as a JSON array. [ { Key: 'tag1', Values: ['true'], }, { Key: 'tag2', Values: ['test'], }, { Key: 'tag3', Values: ['testing'], }, // ... ]; Copy Step 9 of 10 Bonus step: Create a deployment marker Deployments of applications often go wrong. Deployment markers are labels that, when attached to your application data, help you track deployments and troubleshoot what happened. To create a deployment marker, run the apm deployment create command using the same Application ID from your earlier search. newrelic apm deployment create --applicationId YOUR_APP_ID --revision $(git describe --tags --always) Copy Step 10 of 10 Notice that the JSON response includes the revision and timestamp of the deployment. This workflow could be built into a continuous integration or continuous deployment (CI/CD) system to help indicate changes in your application's behavior after deployments. Here is an example. { \"id\": 37075986, \"links\": { \"application\": 204261368 }, \"revision\": \"v1.2.4\", \"timestamp\": \"2020-03-04T15:11:44-08:00\", \"user\": \"Developer Toolkit Test Account\" } Copy Next steps Have a look at all the available commands. For example, you could create a New Relic workflow using workload create If you'd like to engage with other community members, visit our New Relic Explorers Hub page. We welcome feature requests or bug reports on GitHub.", - "type": "developer", - "document_type": "page", - "info": "Learn the essentials of the New Relic CLI, from install and configuration to basic usage.", - "sections": [ - "Get started with the New Relic CLI", - "Before you begin", - "Install the New Relic CLI", - "Linux", - "macOS", - "Windows", - "Create your New Relic CLI profile", - "Get your application details", - "Add a simple tag to your application", - "Bonus step: Create a deployment marker", - "Next steps" - ], - "title": "Get started with the New Relic CLI", - "popularity": 1, - "tags": [ - "api key", - "New Relic CLI", - "Tags", - "Entity", - "Deployment markers" - ], - "external_id": "531f2f3985bf64bb0dc92a642445887095048882", - "image": "", - "url": "https://developer.newrelic.com/automate-workflows/get-started-new-relic-cli/", - "published_at": "2020-08-18T02:06:05Z", - "updated_at": "2020-08-08T01:41:47Z", - "_index": "520d1d5d14cc8a32e600034b", - "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.16104315, - "_version": null, - "_explanation": null, - "sort": null, - "highlight": { - "title": "Get started with the New Relic CLI", - "sections": "Get started with the New Relic CLI", - "info": "Learn the essentials of the New Relic CLI, from install and configuration to basic usage.", - "tags": "New Relic CLI", - "body": " that you've installed the New Relic CLI, it's time to create your first profile. Profiles contain credentials and settings that you can apply to any CLI command, which is useful when switching between accounts. To create your first CLI profile, run the profiles add command. Note that you need" - }, - "id": "5efa999c196a67c4e1766461" - }, - { - "body": "Create a \"Hello, World!\" application 15 min Here's how you can quickly build a \"Hello, World!\" application in New Relic One. In these steps, you create a local version of the New Relic One site where you can prototype your application. Then, when you're ready to share the application with others, you can publish it to New Relic One. See the video, which demonstrates the steps in this guide in five minutes. Before you begin To get started, make sure you have accounts in GitHub and New Relic. To develop projects, you need the New Relic One CLI (command line interface). If you haven't already installed it, do the following: Install Node.js. Complete all the steps in the CLI quick start. For additional details about setting up your environment, see Set up your development environment. Tip Use the NR1 VS Code extension to build your apps. Create a local version of the \"Hello, World!\" application The CLI allows you to run a local version of New Relic One. You can develop your application locally before you publish it in New Relic One. If you followed all the steps in the CLI quick start, you now have files under a new directory named after your nerdpack project. Here's how you edit those files to create a \"Hello, World!\" project: Step 1 of 9 Open a code editor and point it to the new directory named after your nerdpack project (for example, my-awesome-nerdpack). Your code editor displays two artifacts: launchers containing the homepage tile nerdlets containing your application code Step 2 of 9 Expand nerdlets in your code editor, and open index.js. Step 3 of 9 Change the default return message to \"Hello, World!\": import React from 'react'; // https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction export default class MyAwesomeNerdpackNerdletNerdlet extends React.Component { render() { return

\"Hello, World!\"

; } } Copy Step 4 of 9 As an optional step, you can add a custom launcher icon using any image file named icon.png. Replace the default icon.png file under launcher by dragging in your new image file: Step 5 of 9 To change the name of the launcher to something meaningful, in your code editor under launchers, open nr1.json. Step 6 of 9 Change the value for displayName to anything you want as the launcher label, and save the file: { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"INSERT_YOUR_TILE_LABEL_HERE\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy Step 7 of 9 To see your new changes locally, start the Node server with this command in your terminal: npm start Copy Step 8 of 9 Open a browser and go to https://one.newrelic.com/?nerdpacks=local (this url is also shown in the terminal). Step 9 of 9 When the browser opens, click Apps, and then in the Other apps section, click the new launcher for your application. Here's an example where we inserted a leaf icon: After you click the new launcher, your \"Hello, World!\" appears: Publish your application to New Relic Your colleagues can't see your local application, so when you are ready to share it, publish it to the New Relic One catalog. The catalog is where you can find any pre-existing custom applications, as well as any applications you create in your own organization. Step 1 of 4 Execute the following in your terminal: nr1 nerdpack:publish Copy Step 2 of 4 Close your local New Relic One development tab, and open New Relic One. Step 3 of 4 Click the Apps launcher. Step 4 of 4 Under New Relic One catalog, click the launcher for your new application. When your new application opens, notice that it doesn't display any helpful descriptive information. The next section shows you how to add descriptive metadata. Add details to describe your project Now that your new application is in the New Relic One catalog, you can add details that help users understand what your application does and how to use it. Step 1 of 5 Go to your project in the terminal and execute the following: nr1 create Copy Step 2 of 5 Select catalog, which creates a stub in your project under the catalog directory. Here's how the results might look in your code editor: Step 3 of 5 In the catalog directory of your project, add screenshots or various types of metadata to describe your project. For details about what you can add, see Add catalog metadata and screenshots. Step 4 of 5 After you add the screenshots and descriptions you want, execute the following to save your metadata to the catalog: nr1 catalog:submit Copy Step 5 of 5 Return to the catalog and refresh the page to see your new screenshots and metadata describing your project. Subscribe accounts to your application To make sure other users see your application in the catalog, you need to subscribe accounts to the application. Any user with the NerdPack Manager role can subscribe accounts to an application. Step 1 of 3 If you're not already displaying your application's description page in the browser, click the launcher for the application in the catalog under Your company applications. Step 2 of 3 On your application's description page, click Add this app. Step 3 of 3 Select the accounts you want to subscribe to the application, and then click Update accounts to save your selections. When you return to the Apps page, you'll see the launcher for your new application. Summary Now that you've completed the steps in this example, you learned the basic steps to: Create a local application. Publish the application to the New Relic One catalog so you can share it with your colleagues. Add details to the project in the catalog so users understand how to use it. Subscribe accounts to your application so other users can use it. Related information Create a local application. Publish the application to the New Relic One catalog so you can share it with your colleagues. Add details to the project in the catalog so users understand how to use it. Subscribe accounts to your application so other users can see it directly on their homepage.", - "type": "developer", - "document_type": "page", - "info": "Build a \"Hello, World!\" app and publish it to New Relic One", - "sections": [ - "Create a \"Hello, World!\" application", - "Before you begin", - "Tip", - "Create a local version of the \"Hello, World!\" application", - "Publish your application to New Relic", - "Add details to describe your project", - "Subscribe accounts to your application", - "Summary", - "Related information" + { + "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations, and fetch New Relic or third-party data. Components of the SDK SDK components are located in the Node module package named nr1, which you get when you install the NR1 CLI. The nr1 components can be divided into several categories: UI components Chart components Query and storage components Platform APIs UI components The UI components category of the SDK contains React UI components, including: Text components: These components provide basic font and heading elements. These include HeadingText and BlockText. Layout components: These components give you control over the layout, and help you build complex layout designs without having to deal with the CSS. Layout components include: Grid and GridItem: for organizing more complex, larger scale page content in rows and columns Stack and StackItem: for organizing simpler, smaller scale page content (in column or row) Tabs and TabsItem: group various related pieces of content into separate hideable sections List and ListItem: for providing a basic skeleton of virtualized lists Card, CardHeader and CardBody : used to group similar concepts and tasks together Form components: These components provide the basic building blocks to interact with the UI. These include Button, TextField, Dropdown and DropdownItem, Checkbox, RadioGroup, Radio, and Checkbox. Feedback components: These components are used to provide feedback to users about actions they have taken. These include: Spinnerand Toast. Overlaid components: These components are used to display contextual information and options in the form of an additional child view that appears above other content on screen when an action or event is triggered. They can either require user interaction (like modals), or be augmenting (like a tooltip). These include: Modal and Tooltip. Components suffixed with Item can only operate as direct children of that name without the suffix. For example: GridItem should only be found as a child of Grid. Chart components The Charts category of the SDK contains components representing different types of charts. The ChartGroup component helps a group of related charts share data and be aligned. Some chart components can perform NRQL queries on their own; some accept a customized set of data. Query and storage components The Query components category contains components for fetching and storing New Relic data. The main way to fetch data is with NerdGraph, our GraphQL endpoint. This can be queried using NerdGraphQuery. To simplify use of NerdGraph queries, we provide some components with pre-defined queries. For more on using NerdGraph, see Queries and mutations. We also provide storage for storing small data sets, such as configuration settings data, or user-specific data. For more on this, see NerdStorage. Platform APIs The Platform API components of the SDK enable your application to interact with different parts of the New Relic One platform, by reading and writing state from and to the URL, setting the configuration, etc. They can be divided into these categories: PlatformStateContext: provides read access to the platform URL state variables. Example: timeRange in the time picker. navigation: an object that allows programmatic manipulation of the navigation in New Relic One. Example: opening a new Nerdlet. NerdletStateContext: provides read access to the Nerdlet URL state variables. Example: an entityGuid in the entity explorer. nerdlet: an object that provides write access to the Nerdlet URL state.", + "type": "developer", + "document_type": "page", + "info": "Intro to New Relic One API components", + "sections": [ + "Intro to New Relic One API components", + "Components of the SDK", + "UI components", + "Chart components", + "Query and storage components", + "Platform APIs" ], - "title": "Create a \"Hello, World!\" application", + "title": "Intro to New Relic One API components", "popularity": 1, "tags": [ - "nr1 cli", - "Nerdpack file structure", - "NR One Catalog", - "Subscribe applications" + "SDK components", + "New Relic One apps", + "UI components", + "chart components", + "query and storage components", + "Platform APIs" ], - "external_id": "aa427030169067481fb69a3560798265b6b52b7c", - "image": "https://developer.newrelic.com/static/cb65a35ad6fa52f5245359ecd24158ff/9466d/hello-world-output-local.png", - "url": "https://developer.newrelic.com/build-apps/build-hello-world-app/", - "published_at": "2020-08-18T02:09:27Z", - "updated_at": "2020-08-18T01:45:02Z", + "external_id": "3620920c26bcd66c59c810dccb1200931b23b8c2", + "image": "", + "url": "https://developer.newrelic.com/explore-docs/intro-to-sdk/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:47:12Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.075089455, + "_score": 0.24860461, "_version": null, "_explanation": null, "sort": null, "highlight": { - "sections": "Publish your application to New Relic", - "info": "Build a "Hello, World!" app and publish it to New Relic One", - "tags": "nr1 cli", - "body": ", you can publish it to New Relic One. See the video, which demonstrates the steps in this guide in five minutes. Before you begin To get started, make sure you have accounts in GitHub and New Relic. To develop projects, you need the New Relic One CLI (command line interface). If you haven't already" + "title": "Intro to New Relic One API components", + "sections": "Intro to New Relic One API components", + "info": "Intro to New Relic One API components", + "tags": "New Relic One apps", + "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations" }, - "id": "5efa9973196a67d16d76645c" + "id": "5efa989e28ccbc4071307de5" }, { - "body": "New Relic One CLI common commands Here's a list of common commands to get you started with the New Relic One CLI. You can click any command to see its usage options and additional details about the command. Command Description nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). See our other New Relic One CLI docs for commands specific to Nerdpack set-up, Nerdpack subscriptions, CLI configuration, plugins, or catalogs. Command details nr1 help See commands and get details Shows all nr1 commands by default. To get details about a specific command, run nr1 help COMMAND_NAME. Usage $ nr1 help Arguments COMMAND_NAME The name of a particular command. Examples $ nr1 help $ nr1 help nerdpack $ nr1 help nerdpack:deploy nr1 update Update your CLI Updates to latest version of the CLI. You can specify which channel to update if you'd like. Usage $ nr1 update Arguments CHANNEL The name of a particular channel. Examples $ nr1 update $ nr1 update somechannel nr1 create Create a new component Creates a new component from our template (either a Nerdpack, Nerdlet, launcher, or catalog). The CLI will walk you through this process. To learn more about Nerdpacks and their file structure, see Nerdpack file structure. For more on how to set up your Nerdpacks, see our Nerdpack CLI commands. Usage $ nr1 create Options -f, --force If present, overrides existing files without asking. -n, --name=NAME Names the component. -t, --type=TYPE Specifies the component type. --path=PATH The route to the component. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output. nr1 profiles Manage your profiles keychain Displays a list of commands you can use to manage your profiles. Run nr1 help profiles:COMMAND for more on their specific usages. You can have more than one profile, which is helpful for executing commands on multiple New Relic accounts. To learn more about setting up profiles, see our Github workshop. Usage $ nr1 profiles:COMMAND Commands profiles:add Adds a new profile to your profiles keychain. profiles:default Chooses which profile should be default. profiles:list Lists the profiles on your keychain. profiles:remove Removes a profile from your keychain. nr1 autocomplete See autocomplete installation instructions Displays the autocomplete installation instructions. By default, the command displays the autocomplete instructions for zsh. If you want instructions for bash, run nr1 autocomplete bash. Usage $ nr1 autocomplete Arguments SHELL The shell type you want instructions for. Options -r, --refresh-cache Refreshes cache (ignores displaying instructions). Examples $ nr1 autocomplete $ nr1 autocomplete zsh $ nr1 autocomplete bash $ nr1 autocomplete --refresh-cache nr1 nrql Query using NRQL Fetches data from databases using a NRQL query. To learn more about NRQL and how to use it, see our NRQL docs. Usage $ nr1 nrql OPTION ... Options -a, --account=ACCOUNT The user account ID. required -q, --query=QUERY The NRQL query to run. required -u, --ugly Displays the content without tabs or spaces. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output.", + "body": "Nerdpack file structure A New Relic One application is represented by a Nerdpack folder, which can include one or more Nerdlet files, and (optionally) one or more launcher files. Here we explain: The file structure for a Nerdpack, a Nerdlet, and a launcher How to link a launcher file to a Nerdlet How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create a Nerdpack template that includes a Nerdlet and a launcher. Generate Nerdlet or launcher individually: Use the New Relic One CLI command nr1 create and choose either Nerdlet or launcher. This can be useful when adding Nerdlets to an existing Nerdpack. For documentation on generating and connecting Nerdpack components, see our app building guides and the New Relic One CLI command reference. Nerdpack file structure When you generate a Nerdpack template using the nr1 create command, it has the following file structure: my-nerdlet ├── README.md ├── launchers │   └── my-nerdlet-launcher │   ├── icon.png │   └── nr1.json ├── nerdlets │   └── my-nerdlet-nerdlet │   ├── index.js │   ├── nr1.json │   └── styles.scss ├── node_modules │   ├── js-tokens │   ├── loose-envify │   ├── object-assign │   ├── prop-types │   ├── react │   ├── react-dom │   ├── react-is │   └── scheduler ├── nr1.json ├── package-lock.json └── package.json Copy Nerdlet file structure A Nerdpack can contain one or more Nerdlets. A Nerdlet folder starts out with three default files, index.js, nr1.json, and styles.scss. Here is what the default files look like after being generated using the nr1 create command: index.js The JavaScript code of the Nerdlet. import React from 'react'; export default class MyAwesomeNerdpack extends React.Component { render() { return

Hello, my-awesome-nerdpack Nerdlet!

; } } Copy nr1.json The Nerdlet configuration file. { \"schemaType\": \"NERDLET\", \"id\": \"my-awesome-nerdpack-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\" } Copy Besides using the launcher as the access point for your application, you can also associate the application with a monitored entity to get it to appear in the entity explorer. To do this, add two additional fields to the config file of the first-launched Nerdlet: entities and actionCategory. In the following example, the Nerdlet has been associated with all Browser-monitored applications and will appear under the Monitor UI category : { \"schemaType\": \"NERDLET\", \"id\": \"my-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"Custom Data\", \"entities\": [{ \"domain\": \"BROWSER\", \"type\": \"APPLICATION\" }], \"actionCategory\": \"monitor\" } Copy To see this application in the UI, you would go to the entity explorer, select Browser applications, and select a monitored application. styles.scss An empty SCSS file for styling your application. icon.png The launcher icon that appears on the Apps page in New Relic One when an application is deployed. Launcher file structure Launchers have their own file structure. Note that: A launcher is not required; as an alternative to using a launcher, you can associate your application with a monitored entity. An application can have more than one launcher, which might be desired for an application with multiple Nerdlets. After generating a launcher using the nr1 create command, its folder contains two files: nr1.json The configuration file. { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy To connect a launcher to a Nerdlet, the rootNerdletId must match the id in the launched Nerdlet's nr1.json config file. For Nerdpacks with multiple Nerdlets, this needs to be done only for the first-launched Nerdlet. icon.png The icon displayed on the launcher for the app on the Apps page.", "type": "developer", "document_type": "page", - "info": "An overview of common commands you can use with the New Relic One CLI.", + "info": "An overview of the Nerdpack File Structure", "sections": [ - "New Relic One CLI common commands", - "Command details", - "nr1 help", - "See commands and get details", - "Usage", - "Arguments", - "Examples", - "nr1 update", - "Update your CLI", - "nr1 create", - "Create a new component", - "Options", - "nr1 profiles", - "Manage your profiles keychain", - "Commands", - "nr1 autocomplete", - "See autocomplete installation instructions", - "nr1 nrql", - "Query using NRQL" + "Nerdpack file structure", + "Generate Nerdpack components", + "Nerdlet file structure", + "index.js", + "nr1.json", + "styles.scss", + "icon.png", + "Launcher file structure" ], - "title": "New Relic One CLI common commands", + "title": "Nerdpack file structure", "popularity": 1, - "external_id": "503e515e1095418f8d19329517344ab209d143a4", + "tags": [ + "New Relic One CLI", + "nerdpack", + "file structure", + "nerdlets", + "launchers" + ], + "external_id": "c97bcbb0a2b3d32ac93b5b379a1933e7b4e00161", "image": "", - "url": "https://developer.newrelic.com/explore-docs/nr1-common/", - "published_at": "2020-08-18T02:06:04Z", - "updated_at": "2020-08-14T01:48:10Z", + "url": "https://developer.newrelic.com/explore-docs/nerdpack-file-structure/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:49:25Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.018434381, + "_score": 0.21567628, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic One CLI common commands", - "sections": "New Relic One CLI common commands", - "info": "An overview of common commands you can use with the New Relic One CLI.", - "body": "New Relic One CLI common commands Here's a list of common commands to get you started with the New Relic One CLI. You can click any command to see its usage options and additional details about the command. Command Description nr1 help Shows all nr1 commands or details about each command. nr1" + "tags": "New Relic One CLI", + "body": " How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create" }, - "id": "5f28bd6ae7b9d267996ade94" + "id": "5efa989e196a671300766404" } ], - "/explore-docs/nr1-common": [ + "/explore-docs/nr1-catalog": [ { "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build your own application launcher and follow the quick start instructions. The quick start automatically generates an API key for the account you select, and gives you the pre-populated commands to create a profile, generate your first \"Hello World\" app, and serve it locally. Tip Use the NR1 VS Code extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions. For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). Configure your CLI preferences nr1 config:set Sets a specific configuration value. nr1 config:get Shows a specific configuration. nr1 config:list Lists your configuration choices. nr1 config:delete Removes the value of a specific configuration. Set up your Nerdpacks nr1 nerdpack:clone Clones an open source Nerdpack from our GitHub repository. nr1 nerdpack:serve Serves your Nerdpack for testing and development purposes. nr1 nerdpack:uuid Shows or regenerates the UUID of a Nerdpack. nr1 nerdpack:publish Publishes your Nerdpack to New Relic. nr1 nerdpack:deploy Deploys a Nerdpack version to a specific channel. nr1 nerdpack:undeploy Undeploys a Nerdpack version from a specific channel. Manage your Nerdpack subscriptions nr1 subscription:set Subscribes your account to a Nerdpack and channel. nr1 subscription:list Lists all the Nerdpacks your account is subscribed to. nr1 subscription:unset Unsubscribes your account from a Nerdpack. Install and manage plugins nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin into the CLI for development. nr1 plugins:update Updates your installed plugins. nr1 plugins:uninstall Removes a plugin from the CLI. Manage catalog information nr1 catalog:info Shows the Nerdpack info stored in the catalog. nr1 catalog:submit Gathers and submits the catalog info on the current folder.", "type": "developer", @@ -4917,11 +4604,11 @@ "external_id": "858339a44ead21c83257778ce60b4c352cd30d3b", "image": "https://developer.newrelic.com/static/2c6d337608b38a3312b4fc740afe6167/7272b/developercenter.png", "url": "https://developer.newrelic.com/explore-docs/nr1-cli/", - "published_at": "2020-08-18T02:07:10Z", + "published_at": "2020-08-19T01:50:40Z", "updated_at": "2020-08-18T01:50:36Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.73570365, + "_score": 0.6195422, "_version": null, "_explanation": null, "sort": null, @@ -4930,10 +4617,46 @@ "sections": "New Relic One CLI Commands", "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", "tags": "New Relic One app", - "body": " extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions" + "body": " CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build" }, "id": "5efa989e28ccbc535a307dd0" }, + { + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app, you might have some additional setup and configuration. This guide covers: Downloading the New Relic One CLI to build or modify apps Contribute content to this website Before you begin You must have: A github account account - While not strictly necessary for building apps, a GitHub account enables you to download and customize our open source apps, and contribute an open source project. A New Relic developer account - if you don't already have one, you can get a free trial account for developing New Relic applications. npm - If you've installed Node.js, then you already have npm, which is used to share, reuse, and update JavaScript code, and is necessary for working with React components that are the framework for New Relic apps and this website. Tip Use the New Relic One VSCode extension to build your apps. Prepare to build or modify apps Step 1 of 2 Download the CLI and API key On the Build New Relic One applications page, complete the Quick start steps. These six Quick start steps get you an API key for use with developing apps, and the New Relic One CLI, for building and deploying apps. At the end of the Quick start, you have a project consisting of the following: A Nerdpack - The package containing all the files required by your application. It contains two types of files that you customize to build your app: Nerdlets, and the launcher. One or more Nerdlet files - A specific UI view or window. A Nerdlet is a React JavaScript package that includes an index.js file, a stylesheet, and a JSON-format config file. It can contain any JS functionality (charts, interactive fields, tooltips, etc.). A launcher file: This is the basis for the launcher, which is used to open your application from New Relic One after you publish your app. Step 2 of 2 Start building If you're ready to code, cd to your Nerdpack and get started. If you want to learn more about building applications, try these step-by-step guides: Build a \"Hello, World!\" application shows how to create a little application, publish it to New Relic One, and share it with others by subscribing accounts to it. Map pageviews by region takes you through the steps to create one of our popular open source apps. You learn to add a custom query to an app and view it in a table, then add that data to a map. Contributing to developer.newrelic.com This site is open source, and we want your input. Create a pull request if you see a mistake you know how to fix. Drop us a GitHub issue if you see some content gaps you want us to work on. Or write up a whole new guide if you have one you'd like to share. Read on to learn how. Step 1 of 3 Fork the developer-website GithHub repo Forking the repo enables you to work on your own copy of the developer.newrelic.com files, and build the site locally. It also enables us to more easily manage incomimg pull requests. On the developer-website page in GitHub, select the Fork button on the top right of the page, choose the account you want to fork to, and wait a few seconds while the fork is created. Sync regularly to keep your fork up to date with changes and additions to the main branch upstream. Step 2 of 3 Make a feature or documentation request On any page, select the GitHub button at the top of the page, and then select the kind of change you want, and fill out the GitHub form. Step 3 of 3 Contribute a new guide Check out our contributors guidelines, which will walk you through the process.", + "type": "developer", + "document_type": "page", + "info": "Prepare to build apps and contribute to this site", + "sections": [ + "Set up your development environment", + "Before you begin", + "Tip", + "Prepare to build or modify apps", + "Start building" + ], + "title": "Set up your development environment", + "popularity": 1, + "tags": [ + "developer account", + "API key", + "New Relic One CLI" + ], + "external_id": "c45638a9cd548d1ffffc9f1c7708f115a92ae04a", + "image": "", + "url": "https://developer.newrelic.com/build-apps/set-up-dev-env/", + "published_at": "2020-08-19T01:44:48Z", + "updated_at": "2020-08-19T01:44:47Z", + "_index": "520d1d5d14cc8a32e600034b", + "_type": "520d1d5d14cc8a32e600034c", + "_score": 0.29160455, + "_version": null, + "_explanation": null, + "sort": null, + "highlight": { + "tags": "New Relic One CLI", + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app" + }, + "id": "5efa9973e7b9d242237bab39" + }, { "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs in GitHub. Options --format string output text format [YAML, JSON, Text] (default \"JSON\") -h, --help help for newrelic --plain output compact text Copy Commands newrelic apm - Interact with New Relic APM newrelic completion - Generates shell completion functions newrelic config - Manage the configuration of the New Relic CLI newrelic documentation - Generate CLI documentation newrelic entity - Interact with New Relic entities newrelic nerdgraph - Execute GraphQL requests to the NerdGraph API newrelic nerdstorage - Read, write, and delete NerdStorage documents and collections. newrelic nrql - Commands for interacting with the New Relic Database newrelic profile - Manage the authentication profiles for this tool newrelic version - Show the version of the New Relic CLI newrelic workload - Interact with New Relic One workloads", "type": "developer", @@ -4951,11 +4674,11 @@ "external_id": "471ed214caaf80c70e14903ec71411e2a1c03888", "image": "", "url": "https://developer.newrelic.com/explore-docs/newrelic-cli/", - "published_at": "2020-08-18T02:11:50Z", + "published_at": "2020-08-19T01:49:36Z", "updated_at": "2020-08-14T01:47:12Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.3024054, + "_score": 0.25469238, "_version": null, "_explanation": null, "sort": null, @@ -4969,356 +4692,292 @@ "id": "5efa989ee7b9d2024b7bab97" }, { - "body": "Get started with the New Relic CLI 20 min Access the New Relic platform from the comfort of your terminal: you can use the New Relic CLI to manage entity tags, define workloads, record deployment markers, and much more. Our CLI has been designed for automating common tasks in your DevOps workflow. This guide walks you through the essentials of New Relic CLI, from install and configuration to basic usage. Before you begin For this guide you just need: Your New Relic personal API Key, which you can create from the Account settings of your New Relic account An instrumented application in your New Relic account Step 1 of 10 Install the New Relic CLI The New Relic CLI can be downloaded via Homebrew (macOS), Scoop (Windows), and Snapcraft (Linux). You can also download pre-built binaries for all platforms, including .deb and .rpm packages, and our Windows x64 .msi installer. Linux With Snapcraft installed, run: sudo snap install newrelic-cli macOS With Homebrew installed, run: brew install newrelic-cli Windows With Scoop installed, run: scoop bucket add newrelic-cli https://github.com/newrelic/newrelic-cli.git scoop install newrelic-cli Step 2 of 10 Create your New Relic CLI profile Now that you've installed the New Relic CLI, it's time to create your first profile. Profiles contain credentials and settings that you can apply to any CLI command, which is useful when switching between accounts. To create your first CLI profile, run the profiles add command. Note that you need to set the region of your New Relic account: use -r to set either us or eu (this is required). # Create the tutorial account for the US region newrelic profiles add -n tutorial --apiKey YOUR_NEW_RELIC_API_KEY -r YOUR_REGION # Set the profile as defaults newrelic profiles default -n tutorial Copy Step 3 of 10 Get your application details In this example, you are going to add tags to the application you've instrumented with New Relic. Tags are key-value pairs that can help you organize and filter your entities. An entity (for example, an application) can have a maximum of 100 key-value pairs tied to it. Before searching for your application using the New Relic CLI, write down or copy your Account ID and the name of your application in New Relic - you need both to find applications in the New Relic platform. Step 4 of 10 The New Relic CLI can retrieve your application details as a JSON object. To search for your APM application use the apm application search command. If you get an error, check that the account ID and application name you provided are correct. newrelic apm application search --accountId YOUR_ACCOUNT_ID --name NAME_OF_YOUR_APP Copy Step 5 of 10 If the account ID is valid, and the application name exists in your account, apm application search yields data similar to this example. When you've successfully searched for your application, look for the guid value. It's a unique identifier for your application. You should copy it or write it down. [ { accountId: YOUR_ACCOUNT_ID, applicationId: YOUR_APP_ID, domain: 'APM', entityType: 'APM_APPLICATION_ENTITY', guid: 'A_LONG_GUID', name: 'NAME_OF_YOUR_APP', permalink: 'https://one.newrelic.com/redirect/entity/A_LONG_GUID', reporting: true, type: 'APPLICATION', }, ]; Copy Step 6 of 10 Add a simple tag to your application Now that you have the GUID, you can point the New Relic CLI directly at your application. Adding a tag is the simplest way to try out the CLI capabilities (don't worry, tags can be deleted by using entity tags delete). Let's suppose that you want to add an environment tag to your application. Go ahead and add the dev:testing tag⁠ (or any other key-value pair) to your application using the entities tags create command. newrelic entity tags create --guid YOUR_APP_GUID --tag devkit:testing Copy Step 7 of 10 What if you want to add multiple tags? Tag sets come to the rescue! While tags are key-value pairs separated by colons, tag sets are comma separated lists of tags. For example: tag1:value1,tag2:value2 To add multiple tags at once to your application, modify and run the following snippet. newrelic entity tags create --guid YOUR_APP_GUID --tag tag1:test,tag2:test Copy Adding tags is an asynchronous operation: this means it could take a while for the tags to get created. Step 8 of 10 You've created and added some tags to your application, but how do you know they're there? You need to retrieve your application's tags. To retrieve your application's tags, use the entity tags get command. newrelic entity tags get --guid YOUR_APP_GUID All tags associated with your application are retrieved as a JSON array. [ { Key: 'tag1', Values: ['true'], }, { Key: 'tag2', Values: ['test'], }, { Key: 'tag3', Values: ['testing'], }, // ... ]; Copy Step 9 of 10 Bonus step: Create a deployment marker Deployments of applications often go wrong. Deployment markers are labels that, when attached to your application data, help you track deployments and troubleshoot what happened. To create a deployment marker, run the apm deployment create command using the same Application ID from your earlier search. newrelic apm deployment create --applicationId YOUR_APP_ID --revision $(git describe --tags --always) Copy Step 10 of 10 Notice that the JSON response includes the revision and timestamp of the deployment. This workflow could be built into a continuous integration or continuous deployment (CI/CD) system to help indicate changes in your application's behavior after deployments. Here is an example. { \"id\": 37075986, \"links\": { \"application\": 204261368 }, \"revision\": \"v1.2.4\", \"timestamp\": \"2020-03-04T15:11:44-08:00\", \"user\": \"Developer Toolkit Test Account\" } Copy Next steps Have a look at all the available commands. For example, you could create a New Relic workflow using workload create If you'd like to engage with other community members, visit our New Relic Explorers Hub page. We welcome feature requests or bug reports on GitHub.", + "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations, and fetch New Relic or third-party data. Components of the SDK SDK components are located in the Node module package named nr1, which you get when you install the NR1 CLI. The nr1 components can be divided into several categories: UI components Chart components Query and storage components Platform APIs UI components The UI components category of the SDK contains React UI components, including: Text components: These components provide basic font and heading elements. These include HeadingText and BlockText. Layout components: These components give you control over the layout, and help you build complex layout designs without having to deal with the CSS. Layout components include: Grid and GridItem: for organizing more complex, larger scale page content in rows and columns Stack and StackItem: for organizing simpler, smaller scale page content (in column or row) Tabs and TabsItem: group various related pieces of content into separate hideable sections List and ListItem: for providing a basic skeleton of virtualized lists Card, CardHeader and CardBody : used to group similar concepts and tasks together Form components: These components provide the basic building blocks to interact with the UI. These include Button, TextField, Dropdown and DropdownItem, Checkbox, RadioGroup, Radio, and Checkbox. Feedback components: These components are used to provide feedback to users about actions they have taken. These include: Spinnerand Toast. Overlaid components: These components are used to display contextual information and options in the form of an additional child view that appears above other content on screen when an action or event is triggered. They can either require user interaction (like modals), or be augmenting (like a tooltip). These include: Modal and Tooltip. Components suffixed with Item can only operate as direct children of that name without the suffix. For example: GridItem should only be found as a child of Grid. Chart components The Charts category of the SDK contains components representing different types of charts. The ChartGroup component helps a group of related charts share data and be aligned. Some chart components can perform NRQL queries on their own; some accept a customized set of data. Query and storage components The Query components category contains components for fetching and storing New Relic data. The main way to fetch data is with NerdGraph, our GraphQL endpoint. This can be queried using NerdGraphQuery. To simplify use of NerdGraph queries, we provide some components with pre-defined queries. For more on using NerdGraph, see Queries and mutations. We also provide storage for storing small data sets, such as configuration settings data, or user-specific data. For more on this, see NerdStorage. Platform APIs The Platform API components of the SDK enable your application to interact with different parts of the New Relic One platform, by reading and writing state from and to the URL, setting the configuration, etc. They can be divided into these categories: PlatformStateContext: provides read access to the platform URL state variables. Example: timeRange in the time picker. navigation: an object that allows programmatic manipulation of the navigation in New Relic One. Example: opening a new Nerdlet. NerdletStateContext: provides read access to the Nerdlet URL state variables. Example: an entityGuid in the entity explorer. nerdlet: an object that provides write access to the Nerdlet URL state.", "type": "developer", "document_type": "page", - "info": "Learn the essentials of the New Relic CLI, from install and configuration to basic usage.", + "info": "Intro to New Relic One API components", "sections": [ - "Get started with the New Relic CLI", - "Before you begin", - "Install the New Relic CLI", - "Linux", - "macOS", - "Windows", - "Create your New Relic CLI profile", - "Get your application details", - "Add a simple tag to your application", - "Bonus step: Create a deployment marker", - "Next steps" + "Intro to New Relic One API components", + "Components of the SDK", + "UI components", + "Chart components", + "Query and storage components", + "Platform APIs" ], - "title": "Get started with the New Relic CLI", + "title": "Intro to New Relic One API components", "popularity": 1, "tags": [ - "api key", - "New Relic CLI", - "Tags", - "Entity", - "Deployment markers" + "SDK components", + "New Relic One apps", + "UI components", + "chart components", + "query and storage components", + "Platform APIs" ], - "external_id": "531f2f3985bf64bb0dc92a642445887095048882", + "external_id": "3620920c26bcd66c59c810dccb1200931b23b8c2", "image": "", - "url": "https://developer.newrelic.com/automate-workflows/get-started-new-relic-cli/", - "published_at": "2020-08-18T02:06:05Z", - "updated_at": "2020-08-08T01:41:47Z", + "url": "https://developer.newrelic.com/explore-docs/intro-to-sdk/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:47:12Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.16154054, + "_score": 0.25170243, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Get started with the New Relic CLI", - "sections": "Get started with the New Relic CLI", - "info": "Learn the essentials of the New Relic CLI, from install and configuration to basic usage.", - "tags": "New Relic CLI", - "body": "Get started with the New Relic CLI 20 min Access the New Relic platform from the comfort of your terminal: you can use the New Relic CLI to manage entity tags, define workloads, record deployment markers, and much more. Our CLI has been designed for automating common tasks in your DevOps workflow" + "title": "Intro to New Relic One API components", + "sections": "Intro to New Relic One API components", + "info": "Intro to New Relic One API components", + "tags": "New Relic One apps", + "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations" }, - "id": "5efa999c196a67c4e1766461" + "id": "5efa989e28ccbc4071307de5" }, { - "body": "Create a \"Hello, World!\" application 15 min Here's how you can quickly build a \"Hello, World!\" application in New Relic One. In these steps, you create a local version of the New Relic One site where you can prototype your application. Then, when you're ready to share the application with others, you can publish it to New Relic One. See the video, which demonstrates the steps in this guide in five minutes. Before you begin To get started, make sure you have accounts in GitHub and New Relic. To develop projects, you need the New Relic One CLI (command line interface). If you haven't already installed it, do the following: Install Node.js. Complete all the steps in the CLI quick start. For additional details about setting up your environment, see Set up your development environment. Tip Use the NR1 VS Code extension to build your apps. Create a local version of the \"Hello, World!\" application The CLI allows you to run a local version of New Relic One. You can develop your application locally before you publish it in New Relic One. If you followed all the steps in the CLI quick start, you now have files under a new directory named after your nerdpack project. Here's how you edit those files to create a \"Hello, World!\" project: Step 1 of 9 Open a code editor and point it to the new directory named after your nerdpack project (for example, my-awesome-nerdpack). Your code editor displays two artifacts: launchers containing the homepage tile nerdlets containing your application code Step 2 of 9 Expand nerdlets in your code editor, and open index.js. Step 3 of 9 Change the default return message to \"Hello, World!\": import React from 'react'; // https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction export default class MyAwesomeNerdpackNerdletNerdlet extends React.Component { render() { return

\"Hello, World!\"

; } } Copy Step 4 of 9 As an optional step, you can add a custom launcher icon using any image file named icon.png. Replace the default icon.png file under launcher by dragging in your new image file: Step 5 of 9 To change the name of the launcher to something meaningful, in your code editor under launchers, open nr1.json. Step 6 of 9 Change the value for displayName to anything you want as the launcher label, and save the file: { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"INSERT_YOUR_TILE_LABEL_HERE\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy Step 7 of 9 To see your new changes locally, start the Node server with this command in your terminal: npm start Copy Step 8 of 9 Open a browser and go to https://one.newrelic.com/?nerdpacks=local (this url is also shown in the terminal). Step 9 of 9 When the browser opens, click Apps, and then in the Other apps section, click the new launcher for your application. Here's an example where we inserted a leaf icon: After you click the new launcher, your \"Hello, World!\" appears: Publish your application to New Relic Your colleagues can't see your local application, so when you are ready to share it, publish it to the New Relic One catalog. The catalog is where you can find any pre-existing custom applications, as well as any applications you create in your own organization. Step 1 of 4 Execute the following in your terminal: nr1 nerdpack:publish Copy Step 2 of 4 Close your local New Relic One development tab, and open New Relic One. Step 3 of 4 Click the Apps launcher. Step 4 of 4 Under New Relic One catalog, click the launcher for your new application. When your new application opens, notice that it doesn't display any helpful descriptive information. The next section shows you how to add descriptive metadata. Add details to describe your project Now that your new application is in the New Relic One catalog, you can add details that help users understand what your application does and how to use it. Step 1 of 5 Go to your project in the terminal and execute the following: nr1 create Copy Step 2 of 5 Select catalog, which creates a stub in your project under the catalog directory. Here's how the results might look in your code editor: Step 3 of 5 In the catalog directory of your project, add screenshots or various types of metadata to describe your project. For details about what you can add, see Add catalog metadata and screenshots. Step 4 of 5 After you add the screenshots and descriptions you want, execute the following to save your metadata to the catalog: nr1 catalog:submit Copy Step 5 of 5 Return to the catalog and refresh the page to see your new screenshots and metadata describing your project. Subscribe accounts to your application To make sure other users see your application in the catalog, you need to subscribe accounts to the application. Any user with the NerdPack Manager role can subscribe accounts to an application. Step 1 of 3 If you're not already displaying your application's description page in the browser, click the launcher for the application in the catalog under Your company applications. Step 2 of 3 On your application's description page, click Add this app. Step 3 of 3 Select the accounts you want to subscribe to the application, and then click Update accounts to save your selections. When you return to the Apps page, you'll see the launcher for your new application. Summary Now that you've completed the steps in this example, you learned the basic steps to: Create a local application. Publish the application to the New Relic One catalog so you can share it with your colleagues. Add details to the project in the catalog so users understand how to use it. Subscribe accounts to your application so other users can use it. Related information Create a local application. Publish the application to the New Relic One catalog so you can share it with your colleagues. Add details to the project in the catalog so users understand how to use it. Subscribe accounts to your application so other users can see it directly on their homepage.", + "body": "Nerdpack file structure A New Relic One application is represented by a Nerdpack folder, which can include one or more Nerdlet files, and (optionally) one or more launcher files. Here we explain: The file structure for a Nerdpack, a Nerdlet, and a launcher How to link a launcher file to a Nerdlet How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create a Nerdpack template that includes a Nerdlet and a launcher. Generate Nerdlet or launcher individually: Use the New Relic One CLI command nr1 create and choose either Nerdlet or launcher. This can be useful when adding Nerdlets to an existing Nerdpack. For documentation on generating and connecting Nerdpack components, see our app building guides and the New Relic One CLI command reference. Nerdpack file structure When you generate a Nerdpack template using the nr1 create command, it has the following file structure: my-nerdlet ├── README.md ├── launchers │   └── my-nerdlet-launcher │   ├── icon.png │   └── nr1.json ├── nerdlets │   └── my-nerdlet-nerdlet │   ├── index.js │   ├── nr1.json │   └── styles.scss ├── node_modules │   ├── js-tokens │   ├── loose-envify │   ├── object-assign │   ├── prop-types │   ├── react │   ├── react-dom │   ├── react-is │   └── scheduler ├── nr1.json ├── package-lock.json └── package.json Copy Nerdlet file structure A Nerdpack can contain one or more Nerdlets. A Nerdlet folder starts out with three default files, index.js, nr1.json, and styles.scss. Here is what the default files look like after being generated using the nr1 create command: index.js The JavaScript code of the Nerdlet. import React from 'react'; export default class MyAwesomeNerdpack extends React.Component { render() { return

Hello, my-awesome-nerdpack Nerdlet!

; } } Copy nr1.json The Nerdlet configuration file. { \"schemaType\": \"NERDLET\", \"id\": \"my-awesome-nerdpack-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\" } Copy Besides using the launcher as the access point for your application, you can also associate the application with a monitored entity to get it to appear in the entity explorer. To do this, add two additional fields to the config file of the first-launched Nerdlet: entities and actionCategory. In the following example, the Nerdlet has been associated with all Browser-monitored applications and will appear under the Monitor UI category : { \"schemaType\": \"NERDLET\", \"id\": \"my-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"Custom Data\", \"entities\": [{ \"domain\": \"BROWSER\", \"type\": \"APPLICATION\" }], \"actionCategory\": \"monitor\" } Copy To see this application in the UI, you would go to the entity explorer, select Browser applications, and select a monitored application. styles.scss An empty SCSS file for styling your application. icon.png The launcher icon that appears on the Apps page in New Relic One when an application is deployed. Launcher file structure Launchers have their own file structure. Note that: A launcher is not required; as an alternative to using a launcher, you can associate your application with a monitored entity. An application can have more than one launcher, which might be desired for an application with multiple Nerdlets. After generating a launcher using the nr1 create command, its folder contains two files: nr1.json The configuration file. { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy To connect a launcher to a Nerdlet, the rootNerdletId must match the id in the launched Nerdlet's nr1.json config file. For Nerdpacks with multiple Nerdlets, this needs to be done only for the first-launched Nerdlet. icon.png The icon displayed on the launcher for the app on the Apps page.", "type": "developer", "document_type": "page", - "info": "Build a \"Hello, World!\" app and publish it to New Relic One", + "info": "An overview of the Nerdpack File Structure", "sections": [ - "Create a \"Hello, World!\" application", - "Before you begin", - "Tip", - "Create a local version of the \"Hello, World!\" application", - "Publish your application to New Relic", - "Add details to describe your project", - "Subscribe accounts to your application", - "Summary", - "Related information" + "Nerdpack file structure", + "Generate Nerdpack components", + "Nerdlet file structure", + "index.js", + "nr1.json", + "styles.scss", + "icon.png", + "Launcher file structure" ], - "title": "Create a \"Hello, World!\" application", + "title": "Nerdpack file structure", "popularity": 1, "tags": [ - "nr1 cli", - "Nerdpack file structure", - "NR One Catalog", - "Subscribe applications" - ], - "external_id": "aa427030169067481fb69a3560798265b6b52b7c", - "image": "https://developer.newrelic.com/static/cb65a35ad6fa52f5245359ecd24158ff/9466d/hello-world-output-local.png", - "url": "https://developer.newrelic.com/build-apps/build-hello-world-app/", - "published_at": "2020-08-18T02:09:27Z", - "updated_at": "2020-08-18T01:45:02Z", - "_index": "520d1d5d14cc8a32e600034b", - "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.074954085, - "_version": null, - "_explanation": null, - "sort": null, - "highlight": { - "sections": "Publish your application to New Relic", - "info": "Build a "Hello, World!" app and publish it to New Relic One", - "tags": "nr1 cli", - "body": ", you can publish it to New Relic One. See the video, which demonstrates the steps in this guide in five minutes. Before you begin To get started, make sure you have accounts in GitHub and New Relic. To develop projects, you need the New Relic One CLI (command line interface). If you haven't already" - }, - "id": "5efa9973196a67d16d76645c" - }, - { - "body": "New Relic One CLI plugin commands To install and manage your plugins, use the commands below. You can click any command to see its usage options and additional details about the command. Command Description nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin into the CLI for development. nr1 plugins:update Updates your installed plugins. nr1 plugins:uninstall Removes a plugin from the CLI. Command details nr1 plugins:install Install a plugin Installs a plugin into the CLI. You can install plugins from npm or a Git URL. Please note that installing a plugin will override the core plugin. For example, if you have a core plugin that has a 'hello' command, then installing a plugin with a 'hello' command will override the core plugin implementation. This is useful if you want to update the core plugin functionality without patching and updating the whole CLI. Usage $ nr1 plugins:install PLUGIN Arguments PLUGIN: the name, path, or URL of the plugin you want to install. required Options -f, --force Runs yarn install --force. This forces a re-download of all the plugin's packages. -h, --help Shows CLI help. --verbose Adds extra information to the output. Examples $ nr1 plugins:install myplugin $ nr1 plugins:install https://github.com/someuser/someplugin $ nr1 plugins:install someuser/someplugin Aliases $ nr1 plugins:add nr1 plugins:link Link your plugin Links a local plugin into the CLI for development. Please note that linking a plugin will override your user-installed plugin or core plugin. For example, if you have a user-installed or core plugin that has a 'hello' command, linking a plugin with a 'hello' command will override the user-installed or core plugin implementation. This is useful for development work. Usage $ nr1 plugins:link PLUGIN Arguments PLUGIN: the name, path, or URL of the plugin you want to link. required Options -h, --help Shows CLI help. --verbose Adds extra information to the output. Examples $ nr1 plugins:link myplugin $ nr1 plugins:link someuser/someplugin nr1 plugins:update Update your plugins Updates all of your installed plugins. Usage $ nr1 plugins:update Options -h, --help Shows CLI help. --verbose Adds extra information to the output. nr1 plugins:uninstall Uninstall your plugin Removes a plugin from the CLI. Usage $ nr1 plugins:uninstall PLUGIN Arguments PLUGIN: the name of the plugin you want to uninstall. required Options -h, --help Shows CLI help. --verbose Adds extra information to the output. Aliases $ nr1 plugins:unlink $ nr1 plugins:remove", - "type": "developer", - "document_type": "page", - "info": "An overview of the CLI commands you can use to install and manage your plugins.", - "sections": [ - "New Relic One CLI plugin commands", - "Command details", - "nr1 plugins:install", - "Install a plugin", - "Usage", - "Arguments", - "Options", - "Examples", - "Aliases", - "nr1 plugins:link", - "Link your plugin", - "nr1 plugins:update", - "Update your plugins", - "nr1 plugins:uninstall", - "Uninstall your plugin" + "New Relic One CLI", + "nerdpack", + "file structure", + "nerdlets", + "launchers" ], - "title": "New Relic One CLI plugin commands", - "popularity": 1, - "external_id": "6e94c2de165c2b01c2b15c9297a7314f1895112e", + "external_id": "c97bcbb0a2b3d32ac93b5b379a1933e7b4e00161", "image": "", - "url": "https://developer.newrelic.com/explore-docs/nr1-plugins/", - "published_at": "2020-08-18T02:07:10Z", - "updated_at": "2020-08-14T01:50:34Z", + "url": "https://developer.newrelic.com/explore-docs/nerdpack-file-structure/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:49:25Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.016611477, + "_score": 0.21836379, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic One CLI plugin commands", - "sections": "New Relic One CLI plugin commands", - "info": "An overview of the CLI commands you can use to install and manage your plugins.", - "body": "New Relic One CLI plugin commands To install and manage your plugins, use the commands below. You can click any command to see its usage options and additional details about the command. Command Description nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin" + "tags": "New Relic One CLI", + "body": " How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create" }, - "id": "5f28bd6a196a670ddd19d000" + "id": "5efa989e196a671300766404" } ], - "/explore-docs/nr1-config": [ + "/explore-docs/nr1-cli": [ { - "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build your own application launcher and follow the quick start instructions. The quick start automatically generates an API key for the account you select, and gives you the pre-populated commands to create a profile, generate your first \"Hello World\" app, and serve it locally. Tip Use the NR1 VS Code extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions. For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). Configure your CLI preferences nr1 config:set Sets a specific configuration value. nr1 config:get Shows a specific configuration. nr1 config:list Lists your configuration choices. nr1 config:delete Removes the value of a specific configuration. Set up your Nerdpacks nr1 nerdpack:clone Clones an open source Nerdpack from our GitHub repository. nr1 nerdpack:serve Serves your Nerdpack for testing and development purposes. nr1 nerdpack:uuid Shows or regenerates the UUID of a Nerdpack. nr1 nerdpack:publish Publishes your Nerdpack to New Relic. nr1 nerdpack:deploy Deploys a Nerdpack version to a specific channel. nr1 nerdpack:undeploy Undeploys a Nerdpack version from a specific channel. Manage your Nerdpack subscriptions nr1 subscription:set Subscribes your account to a Nerdpack and channel. nr1 subscription:list Lists all the Nerdpacks your account is subscribed to. nr1 subscription:unset Unsubscribes your account from a Nerdpack. Install and manage plugins nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin into the CLI for development. nr1 plugins:update Updates your installed plugins. nr1 plugins:uninstall Removes a plugin from the CLI. Manage catalog information nr1 catalog:info Shows the Nerdpack info stored in the catalog. nr1 catalog:submit Gathers and submits the catalog info on the current folder.", + "body": "Intro to NerdStorage 30 min To help you build a New Relic One application, we provide you with the New Relic One SDK. On this page, you’ll learn how to use NerdStorage SDK components. Use NerdStorage in your apps NerdStorage is used to store and retrieve simple sets of data, including users's configuration settings and preferences (like favorites), or any other small data sets. This storage is unique per Nerdpack, and can't be shared with any other Nerdpack. NerdStorage can be classified into three categories: User storage: Data that is attached to a particular user. If you’re authenticated as the user the data is attached to, you can read it and write it. Account storage: Data that is attached to a particular account. If you’re authenticated and can access the account, you can read and write to account scoped NerdStorage. Visibility of account data is also determined by master/subaccount rules: If a user has access to the master account, then they also have access to data in all subaccounts. Entity storage: Data that is attached to a particular entity. If you can see the corresponding entity, you can read and write data on that entity. Data model You can imagine NerdStorage as a nested key-value map. Data is inside documents, which are nested inside collections: { 'YourNerdpackUuid': { 'collection-1': { 'document-1-of-collection-1': '{\"lastNumber\": 42, \"another\": [1]}', 'document-2-of-collection-1': '\"userToken\"', // ... }, 'another-collection': { 'fruits': '[\"pear\", \"apple\"]', // ... }, // ... }, } Copy Each NerdStorage level has different properties and purpose: Collections: From a Nerdpack, you can create multiple collections by naming each of them. Inside a collection you can put one or more documents. Think of a collection as key-value storage, where each document is a key-value pair. Documents: A document is formed by an identifier (documentId) and a set of data associated with it. Data associated with a document: NerdStorage accepts any sort of data associated to a documentId. Query and mutation components that are provided work by serializing and deserializing JSON. Limits A Nerdpack can hold up to 1,000 collections and 10,000 documents, plus storage type. A collection can hold up to 1,000 documents, plus storage type. Each document can have a maximum length of 64 KiB when serialized. Data access To access NerdStorage, you can run NerdGraph queries, or use the provided storage queries. Depending on which storage you want to access, you can use a different set of SDK components: User access: UserStorageQuery and UserStorageMutation Account access: AccountStorageQuery and AccountStorageMutation Entity access: EntityStorageQuery and EntityStorageMutation Each of these components can operate declaratively (for example, as part of your React rendering methods) or imperatively (by using the static methods for query and mutation). For more information on this, see Data querying and mutations. Permissions for working with NerdStorage In order to persist changes on NerdStorage, such as creating, updating, and deleting account and entity storage, you must have a user role with permission to persist changes.", "type": "developer", "document_type": "page", - "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", + "info": "Intro to NerdStorage on New Relic One", "sections": [ - "New Relic One CLI reference", - "Installing the New Relic One CLI", - "Tip", - "New Relic One CLI Commands", - "Get started", - "Configure your CLI preferences", - "Set up your Nerdpacks", - "Manage your Nerdpack subscriptions", - "Install and manage plugins", - "Manage catalog information" + "Intro to NerdStorage", + "Use NerdStorage in your apps", + "Data model", + "Limits", + "Data access", + "Permissions for working with NerdStorage" ], - "title": "New Relic One CLI reference", + "title": "Intro to NerdStorage", "popularity": 1, "tags": [ - "New Relic One app", - "nerdpack commands" + "nerdstorage", + "nerdstorage components", + "new relic one apps", + "data access" ], - "external_id": "858339a44ead21c83257778ce60b4c352cd30d3b", - "image": "https://developer.newrelic.com/static/2c6d337608b38a3312b4fc740afe6167/7272b/developercenter.png", - "url": "https://developer.newrelic.com/explore-docs/nr1-cli/", - "published_at": "2020-08-18T02:07:10Z", - "updated_at": "2020-08-18T01:50:36Z", + "external_id": "709e06c25376d98b2191ca369b4d139e5084bd62", + "image": "", + "url": "https://developer.newrelic.com/explore-docs/nerdstorage/", + "published_at": "2020-08-19T01:49:36Z", + "updated_at": "2020-08-14T01:50:34Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.7390982, + "_score": 18.52139, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic One CLI reference", - "sections": "New Relic One CLI Commands", - "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", - "tags": "New Relic One app", - "body": " extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions" + "sections": "Use NerdStorage in your apps", + "info": "Intro to NerdStorage on New Relic One", + "tags": "new relic one apps", + "body": "Intro to NerdStorage 30 min To help you build a New Relic One application, we provide you with the New Relic One SDK. On this page, you’ll learn how to use NerdStorage SDK components. Use NerdStorage in your apps NerdStorage is used to store and retrieve simple sets of data, including users's" }, - "id": "5efa989e28ccbc535a307dd0" + "id": "5efa989ee7b9d2048e7bab92" }, { - "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs in GitHub. Options --format string output text format [YAML, JSON, Text] (default \"JSON\") -h, --help help for newrelic --plain output compact text Copy Commands newrelic apm - Interact with New Relic APM newrelic completion - Generates shell completion functions newrelic config - Manage the configuration of the New Relic CLI newrelic documentation - Generate CLI documentation newrelic entity - Interact with New Relic entities newrelic nerdgraph - Execute GraphQL requests to the NerdGraph API newrelic nerdstorage - Read, write, and delete NerdStorage documents and collections. newrelic nrql - Commands for interacting with the New Relic Database newrelic profile - Manage the authentication profiles for this tool newrelic version - Show the version of the New Relic CLI newrelic workload - Interact with New Relic One workloads", + "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations, and fetch New Relic or third-party data. Components of the SDK SDK components are located in the Node module package named nr1, which you get when you install the NR1 CLI. The nr1 components can be divided into several categories: UI components Chart components Query and storage components Platform APIs UI components The UI components category of the SDK contains React UI components, including: Text components: These components provide basic font and heading elements. These include HeadingText and BlockText. Layout components: These components give you control over the layout, and help you build complex layout designs without having to deal with the CSS. Layout components include: Grid and GridItem: for organizing more complex, larger scale page content in rows and columns Stack and StackItem: for organizing simpler, smaller scale page content (in column or row) Tabs and TabsItem: group various related pieces of content into separate hideable sections List and ListItem: for providing a basic skeleton of virtualized lists Card, CardHeader and CardBody : used to group similar concepts and tasks together Form components: These components provide the basic building blocks to interact with the UI. These include Button, TextField, Dropdown and DropdownItem, Checkbox, RadioGroup, Radio, and Checkbox. Feedback components: These components are used to provide feedback to users about actions they have taken. These include: Spinnerand Toast. Overlaid components: These components are used to display contextual information and options in the form of an additional child view that appears above other content on screen when an action or event is triggered. They can either require user interaction (like modals), or be augmenting (like a tooltip). These include: Modal and Tooltip. Components suffixed with Item can only operate as direct children of that name without the suffix. For example: GridItem should only be found as a child of Grid. Chart components The Charts category of the SDK contains components representing different types of charts. The ChartGroup component helps a group of related charts share data and be aligned. Some chart components can perform NRQL queries on their own; some accept a customized set of data. Query and storage components The Query components category contains components for fetching and storing New Relic data. The main way to fetch data is with NerdGraph, our GraphQL endpoint. This can be queried using NerdGraphQuery. To simplify use of NerdGraph queries, we provide some components with pre-defined queries. For more on using NerdGraph, see Queries and mutations. We also provide storage for storing small data sets, such as configuration settings data, or user-specific data. For more on this, see NerdStorage. Platform APIs The Platform API components of the SDK enable your application to interact with different parts of the New Relic One platform, by reading and writing state from and to the URL, setting the configuration, etc. They can be divided into these categories: PlatformStateContext: provides read access to the platform URL state variables. Example: timeRange in the time picker. navigation: an object that allows programmatic manipulation of the navigation in New Relic One. Example: opening a new Nerdlet. NerdletStateContext: provides read access to the Nerdlet URL state variables. Example: an entityGuid in the entity explorer. nerdlet: an object that provides write access to the Nerdlet URL state.", "type": "developer", "document_type": "page", - "info": "The command line tools for performing tasks against New Relic APIs", - "sections": [ - "New Relic CLI Reference", - "New Relic CLI commands", - "Options", - "Commands" + "info": "Intro to New Relic One API components", + "sections": [ + "Intro to New Relic One API components", + "Components of the SDK", + "UI components", + "Chart components", + "Query and storage components", + "Platform APIs" ], - "title": "New Relic CLI Reference", + "title": "Intro to New Relic One API components", "popularity": 1, - "tags": "new relic cli", - "external_id": "471ed214caaf80c70e14903ec71411e2a1c03888", + "tags": [ + "SDK components", + "New Relic One apps", + "UI components", + "chart components", + "query and storage components", + "Platform APIs" + ], + "external_id": "3620920c26bcd66c59c810dccb1200931b23b8c2", "image": "", - "url": "https://developer.newrelic.com/explore-docs/newrelic-cli/", - "published_at": "2020-08-18T02:11:50Z", + "url": "https://developer.newrelic.com/explore-docs/intro-to-sdk/", + "published_at": "2020-08-19T01:50:40Z", "updated_at": "2020-08-14T01:47:12Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.30471438, + "_score": 14.815668, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic CLI Reference", - "sections": "New Relic CLI commands", - "info": "The command line tools for performing tasks against New Relic APIs", - "tags": "new relic cli", - "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs" + "title": "Intro to New Relic One API components", + "sections": "Intro to New Relic One API components", + "info": "Intro to New Relic One API components", + "tags": "New Relic One apps", + "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations" }, - "id": "5efa989ee7b9d2024b7bab97" + "id": "5efa989e28ccbc4071307de5" }, { - "body": "Get started with the New Relic CLI 20 min Access the New Relic platform from the comfort of your terminal: you can use the New Relic CLI to manage entity tags, define workloads, record deployment markers, and much more. Our CLI has been designed for automating common tasks in your DevOps workflow. This guide walks you through the essentials of New Relic CLI, from install and configuration to basic usage. Before you begin For this guide you just need: Your New Relic personal API Key, which you can create from the Account settings of your New Relic account An instrumented application in your New Relic account Step 1 of 10 Install the New Relic CLI The New Relic CLI can be downloaded via Homebrew (macOS), Scoop (Windows), and Snapcraft (Linux). You can also download pre-built binaries for all platforms, including .deb and .rpm packages, and our Windows x64 .msi installer. Linux With Snapcraft installed, run: sudo snap install newrelic-cli macOS With Homebrew installed, run: brew install newrelic-cli Windows With Scoop installed, run: scoop bucket add newrelic-cli https://github.com/newrelic/newrelic-cli.git scoop install newrelic-cli Step 2 of 10 Create your New Relic CLI profile Now that you've installed the New Relic CLI, it's time to create your first profile. Profiles contain credentials and settings that you can apply to any CLI command, which is useful when switching between accounts. To create your first CLI profile, run the profiles add command. Note that you need to set the region of your New Relic account: use -r to set either us or eu (this is required). # Create the tutorial account for the US region newrelic profiles add -n tutorial --apiKey YOUR_NEW_RELIC_API_KEY -r YOUR_REGION # Set the profile as defaults newrelic profiles default -n tutorial Copy Step 3 of 10 Get your application details In this example, you are going to add tags to the application you've instrumented with New Relic. Tags are key-value pairs that can help you organize and filter your entities. An entity (for example, an application) can have a maximum of 100 key-value pairs tied to it. Before searching for your application using the New Relic CLI, write down or copy your Account ID and the name of your application in New Relic - you need both to find applications in the New Relic platform. Step 4 of 10 The New Relic CLI can retrieve your application details as a JSON object. To search for your APM application use the apm application search command. If you get an error, check that the account ID and application name you provided are correct. newrelic apm application search --accountId YOUR_ACCOUNT_ID --name NAME_OF_YOUR_APP Copy Step 5 of 10 If the account ID is valid, and the application name exists in your account, apm application search yields data similar to this example. When you've successfully searched for your application, look for the guid value. It's a unique identifier for your application. You should copy it or write it down. [ { accountId: YOUR_ACCOUNT_ID, applicationId: YOUR_APP_ID, domain: 'APM', entityType: 'APM_APPLICATION_ENTITY', guid: 'A_LONG_GUID', name: 'NAME_OF_YOUR_APP', permalink: 'https://one.newrelic.com/redirect/entity/A_LONG_GUID', reporting: true, type: 'APPLICATION', }, ]; Copy Step 6 of 10 Add a simple tag to your application Now that you have the GUID, you can point the New Relic CLI directly at your application. Adding a tag is the simplest way to try out the CLI capabilities (don't worry, tags can be deleted by using entity tags delete). Let's suppose that you want to add an environment tag to your application. Go ahead and add the dev:testing tag⁠ (or any other key-value pair) to your application using the entities tags create command. newrelic entity tags create --guid YOUR_APP_GUID --tag devkit:testing Copy Step 7 of 10 What if you want to add multiple tags? Tag sets come to the rescue! While tags are key-value pairs separated by colons, tag sets are comma separated lists of tags. For example: tag1:value1,tag2:value2 To add multiple tags at once to your application, modify and run the following snippet. newrelic entity tags create --guid YOUR_APP_GUID --tag tag1:test,tag2:test Copy Adding tags is an asynchronous operation: this means it could take a while for the tags to get created. Step 8 of 10 You've created and added some tags to your application, but how do you know they're there? You need to retrieve your application's tags. To retrieve your application's tags, use the entity tags get command. newrelic entity tags get --guid YOUR_APP_GUID All tags associated with your application are retrieved as a JSON array. [ { Key: 'tag1', Values: ['true'], }, { Key: 'tag2', Values: ['test'], }, { Key: 'tag3', Values: ['testing'], }, // ... ]; Copy Step 9 of 10 Bonus step: Create a deployment marker Deployments of applications often go wrong. Deployment markers are labels that, when attached to your application data, help you track deployments and troubleshoot what happened. To create a deployment marker, run the apm deployment create command using the same Application ID from your earlier search. newrelic apm deployment create --applicationId YOUR_APP_ID --revision $(git describe --tags --always) Copy Step 10 of 10 Notice that the JSON response includes the revision and timestamp of the deployment. This workflow could be built into a continuous integration or continuous deployment (CI/CD) system to help indicate changes in your application's behavior after deployments. Here is an example. { \"id\": 37075986, \"links\": { \"application\": 204261368 }, \"revision\": \"v1.2.4\", \"timestamp\": \"2020-03-04T15:11:44-08:00\", \"user\": \"Developer Toolkit Test Account\" } Copy Next steps Have a look at all the available commands. For example, you could create a New Relic workflow using workload create If you'd like to engage with other community members, visit our New Relic Explorers Hub page. We welcome feature requests or bug reports on GitHub.", + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app, you might have some additional setup and configuration. This guide covers: Downloading the New Relic One CLI to build or modify apps Contribute content to this website Before you begin You must have: A github account account - While not strictly necessary for building apps, a GitHub account enables you to download and customize our open source apps, and contribute an open source project. A New Relic developer account - if you don't already have one, you can get a free trial account for developing New Relic applications. npm - If you've installed Node.js, then you already have npm, which is used to share, reuse, and update JavaScript code, and is necessary for working with React components that are the framework for New Relic apps and this website. Tip Use the New Relic One VSCode extension to build your apps. Prepare to build or modify apps Step 1 of 2 Download the CLI and API key On the Build New Relic One applications page, complete the Quick start steps. These six Quick start steps get you an API key for use with developing apps, and the New Relic One CLI, for building and deploying apps. At the end of the Quick start, you have a project consisting of the following: A Nerdpack - The package containing all the files required by your application. It contains two types of files that you customize to build your app: Nerdlets, and the launcher. One or more Nerdlet files - A specific UI view or window. A Nerdlet is a React JavaScript package that includes an index.js file, a stylesheet, and a JSON-format config file. It can contain any JS functionality (charts, interactive fields, tooltips, etc.). A launcher file: This is the basis for the launcher, which is used to open your application from New Relic One after you publish your app. Step 2 of 2 Start building If you're ready to code, cd to your Nerdpack and get started. If you want to learn more about building applications, try these step-by-step guides: Build a \"Hello, World!\" application shows how to create a little application, publish it to New Relic One, and share it with others by subscribing accounts to it. Map pageviews by region takes you through the steps to create one of our popular open source apps. You learn to add a custom query to an app and view it in a table, then add that data to a map. Contributing to developer.newrelic.com This site is open source, and we want your input. Create a pull request if you see a mistake you know how to fix. Drop us a GitHub issue if you see some content gaps you want us to work on. Or write up a whole new guide if you have one you'd like to share. Read on to learn how. Step 1 of 3 Fork the developer-website GithHub repo Forking the repo enables you to work on your own copy of the developer.newrelic.com files, and build the site locally. It also enables us to more easily manage incomimg pull requests. On the developer-website page in GitHub, select the Fork button on the top right of the page, choose the account you want to fork to, and wait a few seconds while the fork is created. Sync regularly to keep your fork up to date with changes and additions to the main branch upstream. Step 2 of 3 Make a feature or documentation request On any page, select the GitHub button at the top of the page, and then select the kind of change you want, and fill out the GitHub form. Step 3 of 3 Contribute a new guide Check out our contributors guidelines, which will walk you through the process.", "type": "developer", "document_type": "page", - "info": "Learn the essentials of the New Relic CLI, from install and configuration to basic usage.", + "info": "Prepare to build apps and contribute to this site", "sections": [ - "Get started with the New Relic CLI", + "Set up your development environment", "Before you begin", - "Install the New Relic CLI", - "Linux", - "macOS", - "Windows", - "Create your New Relic CLI profile", - "Get your application details", - "Add a simple tag to your application", - "Bonus step: Create a deployment marker", - "Next steps" + "Tip", + "Prepare to build or modify apps", + "Start building" ], - "title": "Get started with the New Relic CLI", + "title": "Set up your development environment", "popularity": 1, "tags": [ - "api key", - "New Relic CLI", - "Tags", - "Entity", - "Deployment markers" + "developer account", + "API key", + "New Relic One CLI" ], - "external_id": "531f2f3985bf64bb0dc92a642445887095048882", + "external_id": "c45638a9cd548d1ffffc9f1c7708f115a92ae04a", "image": "", - "url": "https://developer.newrelic.com/automate-workflows/get-started-new-relic-cli/", - "published_at": "2020-08-18T02:06:05Z", - "updated_at": "2020-08-08T01:41:47Z", + "url": "https://developer.newrelic.com/build-apps/set-up-dev-env/", + "published_at": "2020-08-19T01:44:48Z", + "updated_at": "2020-08-19T01:44:47Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.16224013, + "_score": 5.682625, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Get started with the New Relic CLI", - "sections": "Get started with the New Relic CLI", - "info": "Learn the essentials of the New Relic CLI, from install and configuration to basic usage.", - "tags": "New Relic CLI", - "body": " that you've installed the New Relic CLI, it's time to create your first profile. Profiles contain credentials and settings that you can apply to any CLI command, which is useful when switching between accounts. To create your first CLI profile, run the profiles add command. Note that you need" + "sections": "Prepare to build or modify apps", + "info": "Prepare to build apps and contribute to this site", + "tags": "New Relic One CLI", + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app" }, - "id": "5efa999c196a67c4e1766461" + "id": "5efa9973e7b9d242237bab39" }, { - "body": "Create a \"Hello, World!\" application 15 min Here's how you can quickly build a \"Hello, World!\" application in New Relic One. In these steps, you create a local version of the New Relic One site where you can prototype your application. Then, when you're ready to share the application with others, you can publish it to New Relic One. See the video, which demonstrates the steps in this guide in five minutes. Before you begin To get started, make sure you have accounts in GitHub and New Relic. To develop projects, you need the New Relic One CLI (command line interface). If you haven't already installed it, do the following: Install Node.js. Complete all the steps in the CLI quick start. For additional details about setting up your environment, see Set up your development environment. Tip Use the NR1 VS Code extension to build your apps. Create a local version of the \"Hello, World!\" application The CLI allows you to run a local version of New Relic One. You can develop your application locally before you publish it in New Relic One. If you followed all the steps in the CLI quick start, you now have files under a new directory named after your nerdpack project. Here's how you edit those files to create a \"Hello, World!\" project: Step 1 of 9 Open a code editor and point it to the new directory named after your nerdpack project (for example, my-awesome-nerdpack). Your code editor displays two artifacts: launchers containing the homepage tile nerdlets containing your application code Step 2 of 9 Expand nerdlets in your code editor, and open index.js. Step 3 of 9 Change the default return message to \"Hello, World!\": import React from 'react'; // https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction export default class MyAwesomeNerdpackNerdletNerdlet extends React.Component { render() { return

\"Hello, World!\"

; } } Copy Step 4 of 9 As an optional step, you can add a custom launcher icon using any image file named icon.png. Replace the default icon.png file under launcher by dragging in your new image file: Step 5 of 9 To change the name of the launcher to something meaningful, in your code editor under launchers, open nr1.json. Step 6 of 9 Change the value for displayName to anything you want as the launcher label, and save the file: { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"INSERT_YOUR_TILE_LABEL_HERE\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy Step 7 of 9 To see your new changes locally, start the Node server with this command in your terminal: npm start Copy Step 8 of 9 Open a browser and go to https://one.newrelic.com/?nerdpacks=local (this url is also shown in the terminal). Step 9 of 9 When the browser opens, click Apps, and then in the Other apps section, click the new launcher for your application. Here's an example where we inserted a leaf icon: After you click the new launcher, your \"Hello, World!\" appears: Publish your application to New Relic Your colleagues can't see your local application, so when you are ready to share it, publish it to the New Relic One catalog. The catalog is where you can find any pre-existing custom applications, as well as any applications you create in your own organization. Step 1 of 4 Execute the following in your terminal: nr1 nerdpack:publish Copy Step 2 of 4 Close your local New Relic One development tab, and open New Relic One. Step 3 of 4 Click the Apps launcher. Step 4 of 4 Under New Relic One catalog, click the launcher for your new application. When your new application opens, notice that it doesn't display any helpful descriptive information. The next section shows you how to add descriptive metadata. Add details to describe your project Now that your new application is in the New Relic One catalog, you can add details that help users understand what your application does and how to use it. Step 1 of 5 Go to your project in the terminal and execute the following: nr1 create Copy Step 2 of 5 Select catalog, which creates a stub in your project under the catalog directory. Here's how the results might look in your code editor: Step 3 of 5 In the catalog directory of your project, add screenshots or various types of metadata to describe your project. For details about what you can add, see Add catalog metadata and screenshots. Step 4 of 5 After you add the screenshots and descriptions you want, execute the following to save your metadata to the catalog: nr1 catalog:submit Copy Step 5 of 5 Return to the catalog and refresh the page to see your new screenshots and metadata describing your project. Subscribe accounts to your application To make sure other users see your application in the catalog, you need to subscribe accounts to the application. Any user with the NerdPack Manager role can subscribe accounts to an application. Step 1 of 3 If you're not already displaying your application's description page in the browser, click the launcher for the application in the catalog under Your company applications. Step 2 of 3 On your application's description page, click Add this app. Step 3 of 3 Select the accounts you want to subscribe to the application, and then click Update accounts to save your selections. When you return to the Apps page, you'll see the launcher for your new application. Summary Now that you've completed the steps in this example, you learned the basic steps to: Create a local application. Publish the application to the New Relic One catalog so you can share it with your colleagues. Add details to the project in the catalog so users understand how to use it. Subscribe accounts to your application so other users can use it. Related information Create a local application. Publish the application to the New Relic One catalog so you can share it with your colleagues. Add details to the project in the catalog so users understand how to use it. Subscribe accounts to your application so other users can see it directly on their homepage.", + "body": "Nerdpack file structure A New Relic One application is represented by a Nerdpack folder, which can include one or more Nerdlet files, and (optionally) one or more launcher files. Here we explain: The file structure for a Nerdpack, a Nerdlet, and a launcher How to link a launcher file to a Nerdlet How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create a Nerdpack template that includes a Nerdlet and a launcher. Generate Nerdlet or launcher individually: Use the New Relic One CLI command nr1 create and choose either Nerdlet or launcher. This can be useful when adding Nerdlets to an existing Nerdpack. For documentation on generating and connecting Nerdpack components, see our app building guides and the New Relic One CLI command reference. Nerdpack file structure When you generate a Nerdpack template using the nr1 create command, it has the following file structure: my-nerdlet ├── README.md ├── launchers │   └── my-nerdlet-launcher │   ├── icon.png │   └── nr1.json ├── nerdlets │   └── my-nerdlet-nerdlet │   ├── index.js │   ├── nr1.json │   └── styles.scss ├── node_modules │   ├── js-tokens │   ├── loose-envify │   ├── object-assign │   ├── prop-types │   ├── react │   ├── react-dom │   ├── react-is │   └── scheduler ├── nr1.json ├── package-lock.json └── package.json Copy Nerdlet file structure A Nerdpack can contain one or more Nerdlets. A Nerdlet folder starts out with three default files, index.js, nr1.json, and styles.scss. Here is what the default files look like after being generated using the nr1 create command: index.js The JavaScript code of the Nerdlet. import React from 'react'; export default class MyAwesomeNerdpack extends React.Component { render() { return

Hello, my-awesome-nerdpack Nerdlet!

; } } Copy nr1.json The Nerdlet configuration file. { \"schemaType\": \"NERDLET\", \"id\": \"my-awesome-nerdpack-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\" } Copy Besides using the launcher as the access point for your application, you can also associate the application with a monitored entity to get it to appear in the entity explorer. To do this, add two additional fields to the config file of the first-launched Nerdlet: entities and actionCategory. In the following example, the Nerdlet has been associated with all Browser-monitored applications and will appear under the Monitor UI category : { \"schemaType\": \"NERDLET\", \"id\": \"my-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"Custom Data\", \"entities\": [{ \"domain\": \"BROWSER\", \"type\": \"APPLICATION\" }], \"actionCategory\": \"monitor\" } Copy To see this application in the UI, you would go to the entity explorer, select Browser applications, and select a monitored application. styles.scss An empty SCSS file for styling your application. icon.png The launcher icon that appears on the Apps page in New Relic One when an application is deployed. Launcher file structure Launchers have their own file structure. Note that: A launcher is not required; as an alternative to using a launcher, you can associate your application with a monitored entity. An application can have more than one launcher, which might be desired for an application with multiple Nerdlets. After generating a launcher using the nr1 create command, its folder contains two files: nr1.json The configuration file. { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy To connect a launcher to a Nerdlet, the rootNerdletId must match the id in the launched Nerdlet's nr1.json config file. For Nerdpacks with multiple Nerdlets, this needs to be done only for the first-launched Nerdlet. icon.png The icon displayed on the launcher for the app on the Apps page.", "type": "developer", "document_type": "page", - "info": "Build a \"Hello, World!\" app and publish it to New Relic One", + "info": "An overview of the Nerdpack File Structure", "sections": [ - "Create a \"Hello, World!\" application", - "Before you begin", - "Tip", - "Create a local version of the \"Hello, World!\" application", - "Publish your application to New Relic", - "Add details to describe your project", - "Subscribe accounts to your application", - "Summary", - "Related information" + "Nerdpack file structure", + "Generate Nerdpack components", + "Nerdlet file structure", + "index.js", + "nr1.json", + "styles.scss", + "icon.png", + "Launcher file structure" ], - "title": "Create a \"Hello, World!\" application", + "title": "Nerdpack file structure", "popularity": 1, "tags": [ - "nr1 cli", - "Nerdpack file structure", - "NR One Catalog", - "Subscribe applications" + "New Relic One CLI", + "nerdpack", + "file structure", + "nerdlets", + "launchers" ], - "external_id": "aa427030169067481fb69a3560798265b6b52b7c", - "image": "https://developer.newrelic.com/static/cb65a35ad6fa52f5245359ecd24158ff/9466d/hello-world-output-local.png", - "url": "https://developer.newrelic.com/build-apps/build-hello-world-app/", - "published_at": "2020-08-18T02:09:27Z", - "updated_at": "2020-08-18T01:45:02Z", + "external_id": "c97bcbb0a2b3d32ac93b5b379a1933e7b4e00161", + "image": "", + "url": "https://developer.newrelic.com/explore-docs/nerdpack-file-structure/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:49:25Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.07506929, + "_score": 4.2587876, "_version": null, "_explanation": null, "sort": null, "highlight": { - "sections": "Publish your application to New Relic", - "info": "Build a "Hello, World!" app and publish it to New Relic One", - "tags": "nr1 cli", - "body": ", you can publish it to New Relic One. See the video, which demonstrates the steps in this guide in five minutes. Before you begin To get started, make sure you have accounts in GitHub and New Relic. To develop projects, you need the New Relic One CLI (command line interface). If you haven't already" + "title": "Nerdpack file structure", + "sections": "Nerdpack file structure", + "info": "An overview of the Nerdpack File Structure", + "tags": "New Relic One CLI", + "body": " components, see our app building guides and the New Relic One CLI command reference. Nerdpack file structure When you generate a Nerdpack template using the nr1 create command, it has the following file structure: my-nerdlet ├── README.md ├── launchers │   └── my-nerdlet-launcher │   ├── icon.png" }, - "id": "5efa9973196a67d16d76645c" + "id": "5efa989e196a671300766404" }, { - "body": "New Relic One CLI common commands Here's a list of common commands to get you started with the New Relic One CLI. You can click any command to see its usage options and additional details about the command. Command Description nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). See our other New Relic One CLI docs for commands specific to Nerdpack set-up, Nerdpack subscriptions, CLI configuration, plugins, or catalogs. Command details nr1 help See commands and get details Shows all nr1 commands by default. To get details about a specific command, run nr1 help COMMAND_NAME. Usage $ nr1 help Arguments COMMAND_NAME The name of a particular command. Examples $ nr1 help $ nr1 help nerdpack $ nr1 help nerdpack:deploy nr1 update Update your CLI Updates to latest version of the CLI. You can specify which channel to update if you'd like. Usage $ nr1 update Arguments CHANNEL The name of a particular channel. Examples $ nr1 update $ nr1 update somechannel nr1 create Create a new component Creates a new component from our template (either a Nerdpack, Nerdlet, launcher, or catalog). The CLI will walk you through this process. To learn more about Nerdpacks and their file structure, see Nerdpack file structure. For more on how to set up your Nerdpacks, see our Nerdpack CLI commands. Usage $ nr1 create Options -f, --force If present, overrides existing files without asking. -n, --name=NAME Names the component. -t, --type=TYPE Specifies the component type. --path=PATH The route to the component. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output. nr1 profiles Manage your profiles keychain Displays a list of commands you can use to manage your profiles. Run nr1 help profiles:COMMAND for more on their specific usages. You can have more than one profile, which is helpful for executing commands on multiple New Relic accounts. To learn more about setting up profiles, see our Github workshop. Usage $ nr1 profiles:COMMAND Commands profiles:add Adds a new profile to your profiles keychain. profiles:default Chooses which profile should be default. profiles:list Lists the profiles on your keychain. profiles:remove Removes a profile from your keychain. nr1 autocomplete See autocomplete installation instructions Displays the autocomplete installation instructions. By default, the command displays the autocomplete instructions for zsh. If you want instructions for bash, run nr1 autocomplete bash. Usage $ nr1 autocomplete Arguments SHELL The shell type you want instructions for. Options -r, --refresh-cache Refreshes cache (ignores displaying instructions). Examples $ nr1 autocomplete $ nr1 autocomplete zsh $ nr1 autocomplete bash $ nr1 autocomplete --refresh-cache nr1 nrql Query using NRQL Fetches data from databases using a NRQL query. To learn more about NRQL and how to use it, see our NRQL docs. Usage $ nr1 nrql OPTION ... Options -a, --account=ACCOUNT The user account ID. required -q, --query=QUERY The NRQL query to run. required -u, --ugly Displays the content without tabs or spaces. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output.", + "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs in GitHub. Options --format string output text format [YAML, JSON, Text] (default \"JSON\") -h, --help help for newrelic --plain output compact text Copy Commands newrelic apm - Interact with New Relic APM newrelic completion - Generates shell completion functions newrelic config - Manage the configuration of the New Relic CLI newrelic documentation - Generate CLI documentation newrelic entity - Interact with New Relic entities newrelic nerdgraph - Execute GraphQL requests to the NerdGraph API newrelic nerdstorage - Read, write, and delete NerdStorage documents and collections. newrelic nrql - Commands for interacting with the New Relic Database newrelic profile - Manage the authentication profiles for this tool newrelic version - Show the version of the New Relic CLI newrelic workload - Interact with New Relic One workloads", "type": "developer", "document_type": "page", - "info": "An overview of common commands you can use with the New Relic One CLI.", + "info": "The command line tools for performing tasks against New Relic APIs", "sections": [ - "New Relic One CLI common commands", - "Command details", - "nr1 help", - "See commands and get details", - "Usage", - "Arguments", - "Examples", - "nr1 update", - "Update your CLI", - "nr1 create", - "Create a new component", + "New Relic CLI Reference", + "New Relic CLI commands", "Options", - "nr1 profiles", - "Manage your profiles keychain", - "Commands", - "nr1 autocomplete", - "See autocomplete installation instructions", - "nr1 nrql", - "Query using NRQL" + "Commands" ], - "title": "New Relic One CLI common commands", + "title": "New Relic CLI Reference", "popularity": 1, - "external_id": "503e515e1095418f8d19329517344ab209d143a4", + "tags": "new relic cli", + "external_id": "471ed214caaf80c70e14903ec71411e2a1c03888", "image": "", - "url": "https://developer.newrelic.com/explore-docs/nr1-common/", - "published_at": "2020-08-18T02:06:04Z", - "updated_at": "2020-08-14T01:48:10Z", + "url": "https://developer.newrelic.com/explore-docs/newrelic-cli/", + "published_at": "2020-08-19T01:49:36Z", + "updated_at": "2020-08-14T01:47:12Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.018429406, + "_score": 0.90775174, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic One CLI common commands", - "sections": "New Relic One CLI common commands", - "info": "An overview of common commands you can use with the New Relic One CLI.", - "body": "New Relic One CLI common commands Here's a list of common commands to get you started with the New Relic One CLI. You can click any command to see its usage options and additional details about the command. Command Description nr1 help Shows all nr1 commands or details about each command. nr1" + "title": "New Relic CLI Reference", + "sections": "New Relic CLI commands", + "info": "The command line tools for performing tasks against New Relic APIs", + "tags": "new relic cli", + "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs" }, - "id": "5f28bd6ae7b9d267996ade94" + "id": "5efa989ee7b9d2024b7bab97" } ], - "/explore-docs/nerdstorage": [ + "/explore-docs/nr1-config": [ { "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build your own application launcher and follow the quick start instructions. The quick start automatically generates an API key for the account you select, and gives you the pre-populated commands to create a profile, generate your first \"Hello World\" app, and serve it locally. Tip Use the NR1 VS Code extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions. For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). Configure your CLI preferences nr1 config:set Sets a specific configuration value. nr1 config:get Shows a specific configuration. nr1 config:list Lists your configuration choices. nr1 config:delete Removes the value of a specific configuration. Set up your Nerdpacks nr1 nerdpack:clone Clones an open source Nerdpack from our GitHub repository. nr1 nerdpack:serve Serves your Nerdpack for testing and development purposes. nr1 nerdpack:uuid Shows or regenerates the UUID of a Nerdpack. nr1 nerdpack:publish Publishes your Nerdpack to New Relic. nr1 nerdpack:deploy Deploys a Nerdpack version to a specific channel. nr1 nerdpack:undeploy Undeploys a Nerdpack version from a specific channel. Manage your Nerdpack subscriptions nr1 subscription:set Subscribes your account to a Nerdpack and channel. nr1 subscription:list Lists all the Nerdpacks your account is subscribed to. nr1 subscription:unset Unsubscribes your account from a Nerdpack. Install and manage plugins nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin into the CLI for development. nr1 plugins:update Updates your installed plugins. nr1 plugins:uninstall Removes a plugin from the CLI. Manage catalog information nr1 catalog:info Shows the Nerdpack info stored in the catalog. nr1 catalog:submit Gathers and submits the catalog info on the current folder.", "type": "developer", @@ -5345,176 +5004,179 @@ "external_id": "858339a44ead21c83257778ce60b4c352cd30d3b", "image": "https://developer.newrelic.com/static/2c6d337608b38a3312b4fc740afe6167/7272b/developercenter.png", "url": "https://developer.newrelic.com/explore-docs/nr1-cli/", - "published_at": "2020-08-18T02:07:10Z", + "published_at": "2020-08-19T01:50:40Z", "updated_at": "2020-08-18T01:50:36Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 18.007029, + "_score": 0.60941243, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic One CLI reference", - "sections": "New Relic One CLI reference", - "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", - "tags": "New Relic One app", - "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use" + "title": "New Relic One CLI reference", + "sections": "New Relic One CLI Commands", + "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", + "tags": "New Relic One app", + "body": " extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions" }, "id": "5efa989e28ccbc535a307dd0" }, { - "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs in GitHub. Options --format string output text format [YAML, JSON, Text] (default \"JSON\") -h, --help help for newrelic --plain output compact text Copy Commands newrelic apm - Interact with New Relic APM newrelic completion - Generates shell completion functions newrelic config - Manage the configuration of the New Relic CLI newrelic documentation - Generate CLI documentation newrelic entity - Interact with New Relic entities newrelic nerdgraph - Execute GraphQL requests to the NerdGraph API newrelic nerdstorage - Read, write, and delete NerdStorage documents and collections. newrelic nrql - Commands for interacting with the New Relic Database newrelic profile - Manage the authentication profiles for this tool newrelic version - Show the version of the New Relic CLI newrelic workload - Interact with New Relic One workloads", + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app, you might have some additional setup and configuration. This guide covers: Downloading the New Relic One CLI to build or modify apps Contribute content to this website Before you begin You must have: A github account account - While not strictly necessary for building apps, a GitHub account enables you to download and customize our open source apps, and contribute an open source project. A New Relic developer account - if you don't already have one, you can get a free trial account for developing New Relic applications. npm - If you've installed Node.js, then you already have npm, which is used to share, reuse, and update JavaScript code, and is necessary for working with React components that are the framework for New Relic apps and this website. Tip Use the New Relic One VSCode extension to build your apps. Prepare to build or modify apps Step 1 of 2 Download the CLI and API key On the Build New Relic One applications page, complete the Quick start steps. These six Quick start steps get you an API key for use with developing apps, and the New Relic One CLI, for building and deploying apps. At the end of the Quick start, you have a project consisting of the following: A Nerdpack - The package containing all the files required by your application. It contains two types of files that you customize to build your app: Nerdlets, and the launcher. One or more Nerdlet files - A specific UI view or window. A Nerdlet is a React JavaScript package that includes an index.js file, a stylesheet, and a JSON-format config file. It can contain any JS functionality (charts, interactive fields, tooltips, etc.). A launcher file: This is the basis for the launcher, which is used to open your application from New Relic One after you publish your app. Step 2 of 2 Start building If you're ready to code, cd to your Nerdpack and get started. If you want to learn more about building applications, try these step-by-step guides: Build a \"Hello, World!\" application shows how to create a little application, publish it to New Relic One, and share it with others by subscribing accounts to it. Map pageviews by region takes you through the steps to create one of our popular open source apps. You learn to add a custom query to an app and view it in a table, then add that data to a map. Contributing to developer.newrelic.com This site is open source, and we want your input. Create a pull request if you see a mistake you know how to fix. Drop us a GitHub issue if you see some content gaps you want us to work on. Or write up a whole new guide if you have one you'd like to share. Read on to learn how. Step 1 of 3 Fork the developer-website GithHub repo Forking the repo enables you to work on your own copy of the developer.newrelic.com files, and build the site locally. It also enables us to more easily manage incomimg pull requests. On the developer-website page in GitHub, select the Fork button on the top right of the page, choose the account you want to fork to, and wait a few seconds while the fork is created. Sync regularly to keep your fork up to date with changes and additions to the main branch upstream. Step 2 of 3 Make a feature or documentation request On any page, select the GitHub button at the top of the page, and then select the kind of change you want, and fill out the GitHub form. Step 3 of 3 Contribute a new guide Check out our contributors guidelines, which will walk you through the process.", "type": "developer", "document_type": "page", - "info": "The command line tools for performing tasks against New Relic APIs", + "info": "Prepare to build apps and contribute to this site", "sections": [ - "New Relic CLI Reference", - "New Relic CLI commands", - "Options", - "Commands" + "Set up your development environment", + "Before you begin", + "Tip", + "Prepare to build or modify apps", + "Start building" ], - "title": "New Relic CLI Reference", + "title": "Set up your development environment", "popularity": 1, - "tags": "new relic cli", - "external_id": "471ed214caaf80c70e14903ec71411e2a1c03888", + "tags": [ + "developer account", + "API key", + "New Relic One CLI" + ], + "external_id": "c45638a9cd548d1ffffc9f1c7708f115a92ae04a", "image": "", - "url": "https://developer.newrelic.com/explore-docs/newrelic-cli/", - "published_at": "2020-08-18T02:11:50Z", - "updated_at": "2020-08-14T01:47:12Z", + "url": "https://developer.newrelic.com/build-apps/set-up-dev-env/", + "published_at": "2020-08-19T01:44:48Z", + "updated_at": "2020-08-19T01:44:47Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 1.9044049, + "_score": 0.28913003, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic CLI Reference", - "sections": "New Relic CLI Reference", - "info": "The command line tools for performing tasks against New Relic APIs", - "tags": "new relic cli", - "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs" + "tags": "New Relic One CLI", + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app" }, - "id": "5efa989ee7b9d2024b7bab97" + "id": "5efa9973e7b9d242237bab39" }, { - "body": "Add, query, and mutate data using NerdStorage 45 min NerdStorage is a document database accessible within New Relic One. It allows you to modify, save, and retrieve documents from one session to the next. Using NerdStorage, you can create individual documents of up to 64kb in size, create different collections of documents, and store data by entity, account, or user level. This guide explains how to add data and documents to NerdStorage. For an introduction to what NerdStorage is and how it works, see Intro to NerdStorage. Before you begin This guide requires that you have an API key and the New Relic One CLI as described in Set up your development environment. Get started First, get the NerdStorage app running successfully inside New Relic One. Step 1 of 3 Clone the example applications from the GitHub repo. Step 2 of 3 Use the New Relic One CLI to update the application UUID and run the application locally. In the terminal, switch to the /nr1-how-to/use-nerdstorage directory: cd / nr1 - how - to / use - nerdstorage; Copy Update the UUID and serve the application: nr1 nerdpack:uuid -gf nr1 nerdpack:serve Copy Step 3 of 3 Once the app is successfully served, your terminal will return the URL to view your running application on New Relic One. Load the URL. Click Apps and under Other apps you'll see the Use Nerdstorage app listed. Click to launch the app. Add data to NerdStorage Once the app is up and running on New Relic One, you can prepare the app and start adding data. On the How To Use NerdStorage app screen, there's a Saved to NerdStorage pane with a field for adding data. However, if you type something you'll get an error message. This is because you need to be set up to store data at the User level. You can do this with the help of the UserStorageMutation component. Step 1 of 3 Open the application’s ./nerdlets/use-nerdstorage-nerdlet/index.js file in the text editor of your choice and find the code for the TextField and Button used to enter data. The Button onClick prop makes a call to a helper method called _addToNerdStorage, and you need to update it to add UserStorageMutation The UserStorage NerdStorage components require a collection and documentId. In the constructor method in the application’s index.js file, you can see the variables being provided. In the .js file, it will look something like this: constructor(props) { super(props) this.collectionId = 'mycollection'; this.documentId = 'learning-nerdstorage'; this.state = { isOpen: true, storage: [], text: '', }; this._addToNerdStorage = this._addToNerdStorage.bind(this); this._removeFromNerdStorage = this._removeFromNerdStorage.bind(this); this._deleteDocument = this._deleteDocument.bind(this); } Copy Step 2 of 3 Import the UserStorageMutation by adding it to your import statement at the top of the index.js file: import { UserStorageMutation } from 'nr1'; Copy Then update the helper with this code beginning with _addToNerdStorage: _addToNerdStorage(){ const { text, storage } = this.state; storage.push(text); this.setState({storage}, () => { UserStorageMutation.mutate({ actionType: UserStorageMutation.ACTION_TYPE.WRITE_DOCUMENT, collection: this.collectionId, documentId: this.documentId, document: { storage }, }) .then((res) => { this.setState({text: ''}); Toast.showToast({ title: \"NerdStorage Update.\", type: Toast.TYPE.NORMAL }); }) .catch((err) => console.log(err)); }); } Copy Step 3 of 3 Return to your running How To Use NerdStorage app screen on New Relic One and reload the page. Add some text in the text entry field and click the check button. This will update NerdStorage and trigger a Toast notification inside the app. You should then see the text you typed displayed as a table row below the text entry field. Query data from NerdStorage Once you get data storage working as described in the section above, you also need to get the app properly reading data from NerdStorage, or the app will reload with an empty state every time you navigate away from the app page and back. To do this, add the UserStorageQuery component and update the componentDidMount method. Step 1 of 3 Import the UserStorageQuery by adding it to the import statement in the application’s ./nerdlets/use-nerdstorage-nerdlet/index.js file. import { UserStorageMutation, UserStorageQuery } from 'nr1'; Copy Step 2 of 3 Then, add the following componentDidMount method to your application: componentDidMount(){ UserStorageQuery.query({ collection: this.collectionId, documentId: this.documentId, }) .then(({ data }) => { if(data !== null) { this.setState({storage: data.storage}); } }) .catch(err => console.log(err)); } Copy Step 3 of 3 Back inside the NerdStorage app, test your changes by adding a few more rows using the text entry field. Then exit and relaunch the application. The application should load and show all the data you entered before you navigated away. Mutate data in NerdStorage Each NerdStorage entry displayed in the table inside the app has a trash button that can be used to update a specific entry. The trash button works by making a call to the _removeFromNerdStorage helper method. Step 1 of 1 To get this process working, update the code in _removeFromNerdStorage: _removeFromNerdStorage(index, data){ const { storage } = this.state; storage.pop(data); this.setState({storage}, () => { UserStorageMutation.mutate({ actionType: UserStorageMutation.ACTION_TYPE.WRITE_DOCUMENT, collection: this.collectionId, documentId: this.documentId, document: { storage }, }) .then((res) => { Toast.showToast({ title: \"NerdStorage Update.\", type: Toast.TYPE.NORMAL }); }) .catch((err) => console.log(err)); }); } Copy Once you do this, clicking the trash button removes the item it's associated with, and the app updates to show the change. Delete collection from NerdStorage While the trash button is a good method for removing specific entries one at a time, you may also want the ability to delete a whole NerdStorage document at once. You can do this by adding the Delete Document button to your app. Step 1 of 2 Add a new GridItem to the application immediately before the closing Grid tag. In the new GridItem add the following code to display your new button: ; Copy Step 2 of 2 Because the new Delete Document button will be calling the _deleteDocument helper method, you'll need to update that using this code: _deleteDocument(){ this.setState({storage: []}); UserStorageMutation.mutate({ actionType: UserStorageMutation.ACTION_TYPE.DELETE_DOCUMENT, collection: this.collectionId, documentId: this.documentId, }); Toast.showToast({ title: \"NerdStorage Update.\", type: Toast.TYPE.CRITICAL }); } Copy Back inside the application, you should now see both the individual trash buttons and the newly added Delete Document button. Next steps Now that you’ve successfully implemented NerdStorage into a New Relic One application, you can store and mutate data connected to your User. For more information on the various NerdStorage components, please visit the New Relic developer website API documentation.", + "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs in GitHub. Options --format string output text format [YAML, JSON, Text] (default \"JSON\") -h, --help help for newrelic --plain output compact text Copy Commands newrelic apm - Interact with New Relic APM newrelic completion - Generates shell completion functions newrelic config - Manage the configuration of the New Relic CLI newrelic documentation - Generate CLI documentation newrelic entity - Interact with New Relic entities newrelic nerdgraph - Execute GraphQL requests to the NerdGraph API newrelic nerdstorage - Read, write, and delete NerdStorage documents and collections. newrelic nrql - Commands for interacting with the New Relic Database newrelic profile - Manage the authentication profiles for this tool newrelic version - Show the version of the New Relic CLI newrelic workload - Interact with New Relic One workloads", "type": "developer", "document_type": "page", - "info": "NerdStorage is a document database accessible within New Relic One. It allows you to modify, save, and retrieve documents from one session to the next.", + "info": "The command line tools for performing tasks against New Relic APIs", "sections": [ - "Add, query, and mutate data using NerdStorage", - "Before you begin", - "Get started", - "Add data to NerdStorage", - "Query data from NerdStorage", - "Mutate data in NerdStorage", - "Delete collection from NerdStorage", - "Next steps" + "New Relic CLI Reference", + "New Relic CLI commands", + "Options", + "Commands" ], - "title": "Add, query, and mutate data using NerdStorage", + "title": "New Relic CLI Reference", "popularity": 1, - "external_id": "97cc9637edea35ecd68683f1010f67a5f8c79038", - "image": "https://developer.newrelic.com/static/e03456a7ed8556f83bd3329ea38b261d/8f217/add-data-NerdStorage.png", - "url": "https://developer.newrelic.com/build-apps/add-query-mutate-data-nerdstorage/", - "published_at": "2020-08-18T02:11:50Z", - "updated_at": "2020-08-14T01:50:34Z", + "tags": "new relic cli", + "external_id": "471ed214caaf80c70e14903ec71411e2a1c03888", + "image": "", + "url": "https://developer.newrelic.com/explore-docs/newrelic-cli/", + "published_at": "2020-08-19T01:49:36Z", + "updated_at": "2020-08-14T01:47:12Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.78831506, + "_score": 0.25395334, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Add, query, and mutate data using NerdStorage", - "sections": "Add, query, and mutate data using NerdStorage", - "info": "NerdStorage is a document database accessible within New Relic One. It allows you to modify, save, and retrieve documents from one session to the next.", - "body": " will return the URL to view your running application on New Relic One. Load the URL. Click Apps and under Other apps you'll see the Use Nerdstorage app listed. Click to launch the app. Add data to NerdStorage Once the app is up and running on New Relic One, you can prepare the app and start adding data" + "title": "New Relic CLI Reference", + "sections": "New Relic CLI commands", + "info": "The command line tools for performing tasks against New Relic APIs", + "tags": "new relic cli", + "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs" }, - "id": "5efa98d4e7b9d26d6b7bab74" + "id": "5efa989ee7b9d2024b7bab97" }, { - "body": "Create a \"Hello, World!\" application 15 min Here's how you can quickly build a \"Hello, World!\" application in New Relic One. In these steps, you create a local version of the New Relic One site where you can prototype your application. Then, when you're ready to share the application with others, you can publish it to New Relic One. See the video, which demonstrates the steps in this guide in five minutes. Before you begin To get started, make sure you have accounts in GitHub and New Relic. To develop projects, you need the New Relic One CLI (command line interface). If you haven't already installed it, do the following: Install Node.js. Complete all the steps in the CLI quick start. For additional details about setting up your environment, see Set up your development environment. Tip Use the NR1 VS Code extension to build your apps. Create a local version of the \"Hello, World!\" application The CLI allows you to run a local version of New Relic One. You can develop your application locally before you publish it in New Relic One. If you followed all the steps in the CLI quick start, you now have files under a new directory named after your nerdpack project. Here's how you edit those files to create a \"Hello, World!\" project: Step 1 of 9 Open a code editor and point it to the new directory named after your nerdpack project (for example, my-awesome-nerdpack). Your code editor displays two artifacts: launchers containing the homepage tile nerdlets containing your application code Step 2 of 9 Expand nerdlets in your code editor, and open index.js. Step 3 of 9 Change the default return message to \"Hello, World!\": import React from 'react'; // https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction export default class MyAwesomeNerdpackNerdletNerdlet extends React.Component { render() { return

\"Hello, World!\"

; } } Copy Step 4 of 9 As an optional step, you can add a custom launcher icon using any image file named icon.png. Replace the default icon.png file under launcher by dragging in your new image file: Step 5 of 9 To change the name of the launcher to something meaningful, in your code editor under launchers, open nr1.json. Step 6 of 9 Change the value for displayName to anything you want as the launcher label, and save the file: { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"INSERT_YOUR_TILE_LABEL_HERE\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy Step 7 of 9 To see your new changes locally, start the Node server with this command in your terminal: npm start Copy Step 8 of 9 Open a browser and go to https://one.newrelic.com/?nerdpacks=local (this url is also shown in the terminal). Step 9 of 9 When the browser opens, click Apps, and then in the Other apps section, click the new launcher for your application. Here's an example where we inserted a leaf icon: After you click the new launcher, your \"Hello, World!\" appears: Publish your application to New Relic Your colleagues can't see your local application, so when you are ready to share it, publish it to the New Relic One catalog. The catalog is where you can find any pre-existing custom applications, as well as any applications you create in your own organization. Step 1 of 4 Execute the following in your terminal: nr1 nerdpack:publish Copy Step 2 of 4 Close your local New Relic One development tab, and open New Relic One. Step 3 of 4 Click the Apps launcher. Step 4 of 4 Under New Relic One catalog, click the launcher for your new application. When your new application opens, notice that it doesn't display any helpful descriptive information. The next section shows you how to add descriptive metadata. Add details to describe your project Now that your new application is in the New Relic One catalog, you can add details that help users understand what your application does and how to use it. Step 1 of 5 Go to your project in the terminal and execute the following: nr1 create Copy Step 2 of 5 Select catalog, which creates a stub in your project under the catalog directory. Here's how the results might look in your code editor: Step 3 of 5 In the catalog directory of your project, add screenshots or various types of metadata to describe your project. For details about what you can add, see Add catalog metadata and screenshots. Step 4 of 5 After you add the screenshots and descriptions you want, execute the following to save your metadata to the catalog: nr1 catalog:submit Copy Step 5 of 5 Return to the catalog and refresh the page to see your new screenshots and metadata describing your project. Subscribe accounts to your application To make sure other users see your application in the catalog, you need to subscribe accounts to the application. Any user with the NerdPack Manager role can subscribe accounts to an application. Step 1 of 3 If you're not already displaying your application's description page in the browser, click the launcher for the application in the catalog under Your company applications. Step 2 of 3 On your application's description page, click Add this app. Step 3 of 3 Select the accounts you want to subscribe to the application, and then click Update accounts to save your selections. When you return to the Apps page, you'll see the launcher for your new application. Summary Now that you've completed the steps in this example, you learned the basic steps to: Create a local application. Publish the application to the New Relic One catalog so you can share it with your colleagues. Add details to the project in the catalog so users understand how to use it. Subscribe accounts to your application so other users can use it. Related information Create a local application. Publish the application to the New Relic One catalog so you can share it with your colleagues. Add details to the project in the catalog so users understand how to use it. Subscribe accounts to your application so other users can see it directly on their homepage.", + "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations, and fetch New Relic or third-party data. Components of the SDK SDK components are located in the Node module package named nr1, which you get when you install the NR1 CLI. The nr1 components can be divided into several categories: UI components Chart components Query and storage components Platform APIs UI components The UI components category of the SDK contains React UI components, including: Text components: These components provide basic font and heading elements. These include HeadingText and BlockText. Layout components: These components give you control over the layout, and help you build complex layout designs without having to deal with the CSS. Layout components include: Grid and GridItem: for organizing more complex, larger scale page content in rows and columns Stack and StackItem: for organizing simpler, smaller scale page content (in column or row) Tabs and TabsItem: group various related pieces of content into separate hideable sections List and ListItem: for providing a basic skeleton of virtualized lists Card, CardHeader and CardBody : used to group similar concepts and tasks together Form components: These components provide the basic building blocks to interact with the UI. These include Button, TextField, Dropdown and DropdownItem, Checkbox, RadioGroup, Radio, and Checkbox. Feedback components: These components are used to provide feedback to users about actions they have taken. These include: Spinnerand Toast. Overlaid components: These components are used to display contextual information and options in the form of an additional child view that appears above other content on screen when an action or event is triggered. They can either require user interaction (like modals), or be augmenting (like a tooltip). These include: Modal and Tooltip. Components suffixed with Item can only operate as direct children of that name without the suffix. For example: GridItem should only be found as a child of Grid. Chart components The Charts category of the SDK contains components representing different types of charts. The ChartGroup component helps a group of related charts share data and be aligned. Some chart components can perform NRQL queries on their own; some accept a customized set of data. Query and storage components The Query components category contains components for fetching and storing New Relic data. The main way to fetch data is with NerdGraph, our GraphQL endpoint. This can be queried using NerdGraphQuery. To simplify use of NerdGraph queries, we provide some components with pre-defined queries. For more on using NerdGraph, see Queries and mutations. We also provide storage for storing small data sets, such as configuration settings data, or user-specific data. For more on this, see NerdStorage. Platform APIs The Platform API components of the SDK enable your application to interact with different parts of the New Relic One platform, by reading and writing state from and to the URL, setting the configuration, etc. They can be divided into these categories: PlatformStateContext: provides read access to the platform URL state variables. Example: timeRange in the time picker. navigation: an object that allows programmatic manipulation of the navigation in New Relic One. Example: opening a new Nerdlet. NerdletStateContext: provides read access to the Nerdlet URL state variables. Example: an entityGuid in the entity explorer. nerdlet: an object that provides write access to the Nerdlet URL state.", "type": "developer", "document_type": "page", - "info": "Build a \"Hello, World!\" app and publish it to New Relic One", + "info": "Intro to New Relic One API components", "sections": [ - "Create a \"Hello, World!\" application", - "Before you begin", - "Tip", - "Create a local version of the \"Hello, World!\" application", - "Publish your application to New Relic", - "Add details to describe your project", - "Subscribe accounts to your application", - "Summary", - "Related information" + "Intro to New Relic One API components", + "Components of the SDK", + "UI components", + "Chart components", + "Query and storage components", + "Platform APIs" ], - "title": "Create a \"Hello, World!\" application", + "title": "Intro to New Relic One API components", "popularity": 1, "tags": [ - "nr1 cli", - "Nerdpack file structure", - "NR One Catalog", - "Subscribe applications" + "SDK components", + "New Relic One apps", + "UI components", + "chart components", + "query and storage components", + "Platform APIs" ], - "external_id": "aa427030169067481fb69a3560798265b6b52b7c", - "image": "https://developer.newrelic.com/static/cb65a35ad6fa52f5245359ecd24158ff/9466d/hello-world-output-local.png", - "url": "https://developer.newrelic.com/build-apps/build-hello-world-app/", - "published_at": "2020-08-18T02:09:27Z", - "updated_at": "2020-08-18T01:45:02Z", + "external_id": "3620920c26bcd66c59c810dccb1200931b23b8c2", + "image": "", + "url": "https://developer.newrelic.com/explore-docs/intro-to-sdk/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:47:12Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.3596391, + "_score": 0.24918094, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Create a "Hello, World!" application", - "sections": "Publish your application to New Relic", - "info": "Build a "Hello, World!" app and publish it to New Relic One", - "tags": "NR One Catalog", - "body": " the following in your terminal: nr1 nerdpack:publish Copy Step 2 of 4 Close your local New Relic One development tab, and open New Relic One. Step 3 of 4 Click the Apps launcher. Step 4 of 4 Under New Relic One catalog, click the launcher for your new application. When your new application opens, notice" + "title": "Intro to New Relic One API components", + "sections": "Intro to New Relic One API components", + "info": "Intro to New Relic One API components", + "tags": "New Relic One apps", + "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations" }, - "id": "5efa9973196a67d16d76645c" + "id": "5efa989e28ccbc4071307de5" }, { - "body": "Build apps You know better than anyone what information is crucial to your business, and how best to visualize it. Sometimes, this means going beyond dashboards to creating your own app. With React and GraphQL, you can create custom views tailored to your business. These guides are designed to help you start building apps, and dive into our library of components. We also have a growing number of open source apps that you can use to get started. The rest is up to you. Guides to build apps 15 min Create a \"Hello, World!\" application Build a \"Hello, World!\" app and publish it to New Relic One 20 min Publish and deploy apps Start sharing the apps you build 20 min Set up your development environment Prepare to build apps and contribute to this site 20 minutes Add the NerdGraphQuery component to an application The NerdGraphQuery component allows you to query data from your account and add it to a dropdown menu in an application 20 min Add a time picker to your app Add a time picker to a sample application 45 min Add, query, and mutate data using NerdStorage NerdStorage is a document database accessible within New Relic One. It allows you to modify, save, and retrieve documents from one session to the next. 30 min Add a table to your app Add a table to your New Relic One app 30 min Create a custom map view Build an app to show page view data on a map", + "body": "Nerdpack file structure A New Relic One application is represented by a Nerdpack folder, which can include one or more Nerdlet files, and (optionally) one or more launcher files. Here we explain: The file structure for a Nerdpack, a Nerdlet, and a launcher How to link a launcher file to a Nerdlet How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create a Nerdpack template that includes a Nerdlet and a launcher. Generate Nerdlet or launcher individually: Use the New Relic One CLI command nr1 create and choose either Nerdlet or launcher. This can be useful when adding Nerdlets to an existing Nerdpack. For documentation on generating and connecting Nerdpack components, see our app building guides and the New Relic One CLI command reference. Nerdpack file structure When you generate a Nerdpack template using the nr1 create command, it has the following file structure: my-nerdlet ├── README.md ├── launchers │   └── my-nerdlet-launcher │   ├── icon.png │   └── nr1.json ├── nerdlets │   └── my-nerdlet-nerdlet │   ├── index.js │   ├── nr1.json │   └── styles.scss ├── node_modules │   ├── js-tokens │   ├── loose-envify │   ├── object-assign │   ├── prop-types │   ├── react │   ├── react-dom │   ├── react-is │   └── scheduler ├── nr1.json ├── package-lock.json └── package.json Copy Nerdlet file structure A Nerdpack can contain one or more Nerdlets. A Nerdlet folder starts out with three default files, index.js, nr1.json, and styles.scss. Here is what the default files look like after being generated using the nr1 create command: index.js The JavaScript code of the Nerdlet. import React from 'react'; export default class MyAwesomeNerdpack extends React.Component { render() { return

Hello, my-awesome-nerdpack Nerdlet!

; } } Copy nr1.json The Nerdlet configuration file. { \"schemaType\": \"NERDLET\", \"id\": \"my-awesome-nerdpack-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\" } Copy Besides using the launcher as the access point for your application, you can also associate the application with a monitored entity to get it to appear in the entity explorer. To do this, add two additional fields to the config file of the first-launched Nerdlet: entities and actionCategory. In the following example, the Nerdlet has been associated with all Browser-monitored applications and will appear under the Monitor UI category : { \"schemaType\": \"NERDLET\", \"id\": \"my-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"Custom Data\", \"entities\": [{ \"domain\": \"BROWSER\", \"type\": \"APPLICATION\" }], \"actionCategory\": \"monitor\" } Copy To see this application in the UI, you would go to the entity explorer, select Browser applications, and select a monitored application. styles.scss An empty SCSS file for styling your application. icon.png The launcher icon that appears on the Apps page in New Relic One when an application is deployed. Launcher file structure Launchers have their own file structure. Note that: A launcher is not required; as an alternative to using a launcher, you can associate your application with a monitored entity. An application can have more than one launcher, which might be desired for an application with multiple Nerdlets. After generating a launcher using the nr1 create command, its folder contains two files: nr1.json The configuration file. { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy To connect a launcher to a Nerdlet, the rootNerdletId must match the id in the launched Nerdlet's nr1.json config file. For Nerdpacks with multiple Nerdlets, this needs to be done only for the first-launched Nerdlet. icon.png The icon displayed on the launcher for the app on the Apps page.", "type": "developer", "document_type": "page", - "info": "", + "info": "An overview of the Nerdpack File Structure", "sections": [ - "Build apps", - "Guides to build apps", - "Create a \"Hello, World!\" application", - "Publish and deploy apps", - "Set up your development environment", - "Add the NerdGraphQuery component to an application", - "Add a time picker to your app", - "Add, query, and mutate data using NerdStorage", - "Add a table to your app", - "Create a custom map view" + "Nerdpack file structure", + "Generate Nerdpack components", + "Nerdlet file structure", + "index.js", + "nr1.json", + "styles.scss", + "icon.png", + "Launcher file structure" ], - "title": "Build apps", + "title": "Nerdpack file structure", "popularity": 1, - "external_id": "abafbb8457d02084a1ca06f3bc68f7ca823edf1d", + "tags": [ + "New Relic One CLI", + "nerdpack", + "file structure", + "nerdlets", + "launchers" + ], + "external_id": "c97bcbb0a2b3d32ac93b5b379a1933e7b4e00161", "image": "", - "url": "https://developer.newrelic.com/build-apps/", - "published_at": "2020-08-18T02:08:12Z", - "updated_at": "2020-08-18T01:45:02Z", + "url": "https://developer.newrelic.com/explore-docs/nerdpack-file-structure/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:49:25Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.30304605, + "_score": 0.2165331, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Build apps", - "sections": "Add, query, and mutate data using NerdStorage", - "body": " you start building apps, and dive into our library of components. We also have a growing number of open source apps that you can use to get started. The rest is up to you. Guides to build apps 15 min Create a "Hello, World!" application Build a "Hello, World!" app and publish it to New Relic One 20" + "tags": "New Relic One CLI", + "body": " How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create" }, - "id": "5efa999d64441fc0f75f7e21" + "id": "5efa989e196a671300766404" } ], - "/explore-docs/intro-to-sdk": [ + "/explore-docs/nerdstorage": [ { "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build your own application launcher and follow the quick start instructions. The quick start automatically generates an API key for the account you select, and gives you the pre-populated commands to create a profile, generate your first \"Hello World\" app, and serve it locally. Tip Use the NR1 VS Code extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions. For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). Configure your CLI preferences nr1 config:set Sets a specific configuration value. nr1 config:get Shows a specific configuration. nr1 config:list Lists your configuration choices. nr1 config:delete Removes the value of a specific configuration. Set up your Nerdpacks nr1 nerdpack:clone Clones an open source Nerdpack from our GitHub repository. nr1 nerdpack:serve Serves your Nerdpack for testing and development purposes. nr1 nerdpack:uuid Shows or regenerates the UUID of a Nerdpack. nr1 nerdpack:publish Publishes your Nerdpack to New Relic. nr1 nerdpack:deploy Deploys a Nerdpack version to a specific channel. nr1 nerdpack:undeploy Undeploys a Nerdpack version from a specific channel. Manage your Nerdpack subscriptions nr1 subscription:set Subscribes your account to a Nerdpack and channel. nr1 subscription:list Lists all the Nerdpacks your account is subscribed to. nr1 subscription:unset Unsubscribes your account from a Nerdpack. Install and manage plugins nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin into the CLI for development. nr1 plugins:update Updates your installed plugins. nr1 plugins:uninstall Removes a plugin from the CLI. Manage catalog information nr1 catalog:info Shows the Nerdpack info stored in the catalog. nr1 catalog:submit Gathers and submits the catalog info on the current folder.", "type": "developer", @@ -5541,169 +5203,191 @@ "external_id": "858339a44ead21c83257778ce60b4c352cd30d3b", "image": "https://developer.newrelic.com/static/2c6d337608b38a3312b4fc740afe6167/7272b/developercenter.png", "url": "https://developer.newrelic.com/explore-docs/nr1-cli/", - "published_at": "2020-08-18T02:07:10Z", + "published_at": "2020-08-19T01:50:40Z", "updated_at": "2020-08-18T01:50:36Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 3.5731812, + "_score": 14.690018, "_version": null, "_explanation": null, "sort": null, "highlight": { "title": "New Relic One CLI reference", "sections": "New Relic One CLI reference", - "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", + "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", "tags": "New Relic One app", "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use" }, "id": "5efa989e28ccbc535a307dd0" }, { - "body": "Add the NerdGraphQuery component to an application 20 minutes This guide steps you through the process of adding the NerdGraphQuery component to a sample transaction overview application. This allows you to query data from your New Relic account and add it to a dropdown menu. NerdGraph is our GraphQL implementation. GraphQL has some key differences when compared to REST: The client, not the server, determines what data is returned. You can easily collect data from multiple sources. For example, in a single query, you can get account information, infrastructure data, and issue a NRQL request. Note Before completing this exercise, you can experiment with GraphQL queries in our NerdGraph API explorer. We also have a 14-minute video that covers the steps below. Before you begin To develop projects, you need our New Relic One CLI (command line interface). If you haven't already installed it, do the following: Install Node.js. Complete steps 1–4 of our CLI quick start, and be sure to make a copy of your account ID from step 1 because you’ll need it later. Note If you've already installed the New Relic One CLI, but you can't remember your account ID, start the CLI quick start again, and then click the Get your API key down arrow. The account ID is the number preceding your account name. For additional details, see Set up your development environment. Prepare the sample code To get started, complete these steps to update the application UUID (unique ID) and run the sample application locally: Step 1 of 7 If you haven't already done so, clone the example applications from our how-to GitHub repo. Here's an example using HTTPS: git clone https://github.com/newrelic/nr1-how-to.git Copy Step 2 of 7 Change to the directory use-nerdgraph-nerdlet: cd nr1-how-to/use-nerdgraph/nerdlets/use-nerdgraph-nerdlet Copy Step 3 of 7 In your preferred text editor, open index.js. Step 4 of 7 Replace with your account id: Note Your account ID is available in the CLI quick start (see Before you begin). this.accountId = ; Copy Step 5 of 7 Change to the /nr1-howto/use-nerdgraph directory: cd ../.. Copy Step 6 of 7 Execute these commands to update the UUID and serve the sample application: nr1 nerdpack:uuid -gf nr1 nerdpack:serve Copy Step 7 of 7 Once the sample application is successfully served, go to the local New Relic One homepage (https://one.newrelic.com/?nerdpacks=local), click Apps, and then click Use NerdGraph. After launching the Use NerdGraph application, you see a dashboard that gives an overview of the transactions in your account: Add the NerdGraphQuery component Now you can create a dropdown menu for changing the account the application is viewing. The first step is to import the NerdGraphQuery component into the application's index.js file. Note If you need more details about our example below, see the APIs and components page on https://developer.newrelic.com Step 1 of 3 Add the NerdGraphQuery component into the first StackItem inside of the return in the index.js file: {({ loading, error, data }) => { console.log({ loading, error, data }); if (loading) { return ; } if (error) { return 'Error!'; } return null; }} ; Copy Step 2 of 3 The NerdGraphQuery component takes a query object that states the source you want to access and the data you want returned. Add the following code to your index.js file in the render method: Note In the browser console, you can see the data from your query returned in an object that follows the same structure of the object in the initial query. const query = ` query($id: Int!) { actor { account(id: $id) { name } } } `; Copy Step 3 of 3 To take the data returned by the NerdGraph query and display it in the application, replace the return null in the current NerdGraphQuery component with this return statement: return {data.actor.account.name} Apps:; Copy When you go back to the browser and view your application, you see a new headline showing the name of your account returned from NerdGraph: How to use NerdGraphQuery.query At this point, you have implemented the NerdGraphQuery component with the application's render method and displayed the return data within the transaction overview application. Here's what you need to do next: Query NerdGraph inside of the componentDidMount lifecycle method. Save the returned data for later use in the application. Step 1 of 2 This code takes the response from NerdGraph and makes sure the results are processed, stored into the application state, and logged to the browser console for viewing. Add this code into the index.js file just under the constructor: componentDidMount() { const accountId = this.state; const gql = `{ actor { accounts { id name } } }`; const accounts = NerdGraphQuery.query({query: gql}) //The NerdGraphQuery.query method called with the query object to get your account data is stored in the accounts variable. accounts.then(results => { console.log('Nerdgraph Response:', results); const accounts = results.data.actor.accounts.map(account => { return account; }); const account = accounts.length > 0 && accounts[0]; this.setState({ selectedAccount: account, accounts }); }).catch((error) => { console.log('Nerdgraph Error:', error); }) } Copy Step 2 of 2 After the data is stored into state, display a selection so users can change accounts and update the application. To do this, add this code to index.js for the second StackItem in the return statement: { accounts && ( ); } Copy Review the results of the NerdGraph query After you complete these steps, look at the application in your browser, and note the following: The dropdown menu now displays the data returned from the NerdGraphQuery.query and allows you to select an account. After you select a new account, the application shows data from the new selection. The final index.js file should have code similar to the code below. This completed sample is in your nerdlet final.js. import React from 'react'; import { PlatformStateContext, NerdGraphQuery, Spinner, HeadingText, Grid, GridItem, Stack, StackItem, Select, SelectItem, AreaChart, TableChart, PieChart } from 'nr1' import { timeRangeToNrql } from '@newrelic/nr1-community'; // https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction export default class UseNerdgraphNerdletNerdlet extends React.Component { constructor(props){ super(props) this.state = { accountId: , accounts: null, selectedAccount: null, } } componentDidMount() { const accountId = this.state; const gql = `{ actor { accounts { id name } } }`; const accounts = NerdGraphQuery.query({ query: gql }) accounts.then(results => { console.log('Nerdgraph Response:', results); const accounts = results.data.actor.accounts.map(account => { return account; }); const account = accounts.length > 0 && accounts[0]; this.setState({ selectedAccount: account, accounts }); }).catch((error) => { console.log('Nerdgraph Error:', error); }) } selectAccount(option) { this.setState({ accountId: option.id, selectedAccount: option }); } render() { const { accountId, accounts, selectedAccount } = this.state; console.log({ accountId, accounts, selectedAccount }); const query = ` query($id: Int!) { actor { account(id: $id) { name } } } `; const variables = { id: accountId, }; const avgResTime = `SELECT average(duration) FROM Transaction FACET appName TIMESERIES AUTO `; const trxOverview = `FROM Transaction SELECT count(*) as 'Transactions', apdex(duration) as 'apdex', percentile(duration, 99, 95) FACET appName `; const errCount = `FROM TransactionError SELECT count(*) as 'Transaction Errors' FACET error.message `; const responseCodes = `SELECT count(*) as 'Response Code' FROM Transaction FACET httpResponseCode `; return ( {({loading, error, data}) => { if (loading) { return ; } if (error) { return 'Error!'; } return {data.actor.account.name} Apps:; }} {accounts && }
{(PlatformState) => { /* Taking a peek at the PlatformState */ const since = timeRangeToNrql(PlatformState); return ( <>
Transaction Overview
Average Response Time
Response Code
Transaction Errors
); }}
) } } Copy Summary Now that you've completed all the steps in this example, you've successfully queried data from your account using the NerdGraphQuery component in two methods: Using the NerdGraphQuery component inside the application's render method and then passing the returned data into the children's components. Using the NerdGraphQuery.query method to query data before the application renders.", + "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations, and fetch New Relic or third-party data. Components of the SDK SDK components are located in the Node module package named nr1, which you get when you install the NR1 CLI. The nr1 components can be divided into several categories: UI components Chart components Query and storage components Platform APIs UI components The UI components category of the SDK contains React UI components, including: Text components: These components provide basic font and heading elements. These include HeadingText and BlockText. Layout components: These components give you control over the layout, and help you build complex layout designs without having to deal with the CSS. Layout components include: Grid and GridItem: for organizing more complex, larger scale page content in rows and columns Stack and StackItem: for organizing simpler, smaller scale page content (in column or row) Tabs and TabsItem: group various related pieces of content into separate hideable sections List and ListItem: for providing a basic skeleton of virtualized lists Card, CardHeader and CardBody : used to group similar concepts and tasks together Form components: These components provide the basic building blocks to interact with the UI. These include Button, TextField, Dropdown and DropdownItem, Checkbox, RadioGroup, Radio, and Checkbox. Feedback components: These components are used to provide feedback to users about actions they have taken. These include: Spinnerand Toast. Overlaid components: These components are used to display contextual information and options in the form of an additional child view that appears above other content on screen when an action or event is triggered. They can either require user interaction (like modals), or be augmenting (like a tooltip). These include: Modal and Tooltip. Components suffixed with Item can only operate as direct children of that name without the suffix. For example: GridItem should only be found as a child of Grid. Chart components The Charts category of the SDK contains components representing different types of charts. The ChartGroup component helps a group of related charts share data and be aligned. Some chart components can perform NRQL queries on their own; some accept a customized set of data. Query and storage components The Query components category contains components for fetching and storing New Relic data. The main way to fetch data is with NerdGraph, our GraphQL endpoint. This can be queried using NerdGraphQuery. To simplify use of NerdGraph queries, we provide some components with pre-defined queries. For more on using NerdGraph, see Queries and mutations. We also provide storage for storing small data sets, such as configuration settings data, or user-specific data. For more on this, see NerdStorage. Platform APIs The Platform API components of the SDK enable your application to interact with different parts of the New Relic One platform, by reading and writing state from and to the URL, setting the configuration, etc. They can be divided into these categories: PlatformStateContext: provides read access to the platform URL state variables. Example: timeRange in the time picker. navigation: an object that allows programmatic manipulation of the navigation in New Relic One. Example: opening a new Nerdlet. NerdletStateContext: provides read access to the Nerdlet URL state variables. Example: an entityGuid in the entity explorer. nerdlet: an object that provides write access to the Nerdlet URL state.", "type": "developer", "document_type": "page", - "info": "The NerdGraphQuery component allows you to query data from your account and add it to a dropdown menu in an application", + "info": "Intro to New Relic One API components", "sections": [ - "Add the NerdGraphQuery component to an application", - "Note", - "Before you begin", - "Prepare the sample code", - "Add the NerdGraphQuery component", - "How to use NerdGraphQuery.query", - "Review the results of the NerdGraph query", - "Summary" + "Intro to New Relic One API components", + "Components of the SDK", + "UI components", + "Chart components", + "Query and storage components", + "Platform APIs" ], - "title": "Add the NerdGraphQuery component to an application", + "title": "Intro to New Relic One API components", "popularity": 1, - "external_id": "6bd6c8a72eab352a3e8f4332570e286c7831ba84", - "image": "https://developer.newrelic.com/static/5dcf6e45874c1fa40bb6f21151af0c24/b01d9/no-name.png", - "url": "https://developer.newrelic.com/build-apps/add-nerdgraphquery-guide/", - "published_at": "2020-08-18T02:07:10Z", - "updated_at": "2020-08-14T01:49:25Z", + "tags": [ + "SDK components", + "New Relic One apps", + "UI components", + "chart components", + "query and storage components", + "Platform APIs" + ], + "external_id": "3620920c26bcd66c59c810dccb1200931b23b8c2", + "image": "", + "url": "https://developer.newrelic.com/explore-docs/intro-to-sdk/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:47:12Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 1.1957614, + "_score": 12.128444, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Add the NerdGraphQuery component to an application", - "sections": "Add the NerdGraphQuery component to an application", - "info": "The NerdGraphQuery component allows you to query data from your account and add it to a dropdown menu in an application", - "body": " { PlatformStateContext, NerdGraphQuery, Spinner, HeadingText, Grid, GridItem, Stack, StackItem, Select, SelectItem, AreaChart, TableChart, PieChart } from 'nr1' import { timeRangeToNrql } from '@newrelic/nr1-community'; // https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction" + "title": "Intro to New Relic One API components", + "sections": "Intro to New Relic One API components", + "info": "Intro to New Relic One API components", + "tags": "New Relic One apps", + "body": " settings data, or user-specific data. For more on this, see NerdStorage. Platform APIs The Platform API components of the SDK enable your application to interact with different parts of the New Relic One platform, by reading and writing state from and to the URL, setting the configuration, etc" }, - "id": "5efa993c64441ff4865f7e32" + "id": "5efa989e28ccbc4071307de5" }, { - "body": "Add tables to your New Relic One application 30 min Tables are a popular way of displaying data in New Relic applications. For example, with the query builder you can create tables from NRQL queries. Whether you need to have more control over tables or you're importing third-party data, you can build your own tables into your New Relic One application. In this guide, you are going to build a sample table using various New Relic One components. Before you begin If you haven't already installed the New Relic One CLI, step through the quick start in New Relic One. This process also gets you an API key. In addition, to complete the steps in this guide, you need a GitHub account, and to have Node.js installed on your machine. See [Setting up your development environment](/build-apps/set-up-dev-env) for more info. Clone and set up the example application Step 1 of 4 Clone the nr1-how-to example application from GitHub to your local machine. Then, navigate to the app directory. The example app lets you experiment with tables. git clone https://github.com/newrelic/nr1-how-to.git` cd nr1-how-to/create-a-table/nerdlets/create-a-table-nerdlet` Copy Step 2 of 4 Edit the index.json file and set this.accountId to your Account ID as shown in the example. export default class Nr1HowtoAddTimePicker extends React.Component { constructor(props){ super(props) this.accountId = YOUR_ACCOUNT_ID; } ... } Copy Step 3 of 4 Run the demo application Change the directory back to nr1-how-to/create-a-table. Before you can load the demo application, you need to update its unique id by invoking the New Relic One CLI. Once you've assigned a new UUID to the app, install the dependencies and serve the demo app locally, so that you can test any change live in your browser. nr1 nerdpack:uuid -gf # Update the app unique ID npm install # Install dependencies nr1 nerdpack:serve # Serve the demo app locally Copy Step 4 of 4 Open one.newrelic.com/?nerdpacks=local in your browser. Click Apps*, and then in the Other apps section, you should see a Create a table** launcher. That's the demo application you're going to work on. Go ahead and select it. Have a good look at the demo app. There's a TableChart on the left side named Transaction Overview, with an AreaChart next to it. You'll use Table components to add a new table in the second row. Work with table components Step 1 of 10 Navigate to the `nerdlets/create-a-table-nerdlet` subdirectory and open the `index.js` file. Add the following components to the import statement at the top of the file so that it looks like the example: Table TableHeader TableHeaderCell TableRow TableRowCell import { Table, TableHeader, TableHeaderCell, TableRow, TableRowCell, PlatformStateContext, Grid, GridItem, HeadingText, AreaChart, TableChart, } from 'nr1'; Copy Step 2 of 10 Add a basic Table component Locate the empty GridItem in index.js: This is where you start building the table. Add the initial component. The items property collects the data by calling _getItems(), which contains sample values.
; Copy Step 3 of 10 Add the header and rows As the Table component renders a fixed number of header cells and rows, your next step is adding header components, as well as a function that returns the required table rows. Inside of the Table component, add the TableHeader and then a TableHeaderCell child for each heading. Since you don't know how many rows you'll need, your best bet is to call a function to build as many TableRows as items returned by _getItems(). Application Size Company Team Commit ; { ({ item }) => ( {item.name} {item.value} {item.company} {item.team} {item.commit} ); } Copy Step 4 of 10 Take a look at the application running in New Relic One: you should see something similar to the screenshot below. Step 5 of 10 Replace standard table cells with smart cells The New Relic One library includes cell components that can automatically format certain data types, like users, metrics, and entity names. The table you've just created contains columns that can benefit from those components: Application (an entity name) and Size (a metric). Before you can use EntityTitleTableRowCell and MetricTableRowCell, you have to add them to the import statement first. import { EntityTitleTableRowCell, MetricTableRowCell, ... /* All previous components */ } from 'nr1'; Copy Step 6 of 10 Update your table rows by replacing the first and second TableRowCells with entity and metric cells. Notice that EntityTitleTableRowCell and MetricTableRowCell are self-closing tags. { ({ item }) => ( {item.company} {item.team} {item.commit} ); } Copy Step 7 of 10 Time to give your table a second look: The cell components you've added take care of properly formatting the data. Step 8 of 10 Add some action to your table! Tables are great, but interactive tables can be better: As a last update, you are going to allow users to act on each data row. Add the _getActions() method to your index.js file, right before _getItems(). As you may have guessed from the code, _getActions() spawns an alert box when you click Team or Commit cells. _getActions() { return [ { label: 'Alert Team', iconType: TableRow.ACTIONS_ICON_TYPE.INTERFACE__OPERATIONS__ALERT, onClick: (evt, { item, index }) => { alert(`Alert Team: ${item.team}`); }, }, { label: 'Rollback Version', iconType: TableRow.ACTIONS_ICON_TYPE.INTERFACE__OPERATIONS__UNDO, onClick: (evt, { item, index }) => { alert(`Rollback from: ${item.commit}`); }, }, ]; } Copy Step 9 of 10 Find the TableRow component in your return statement and point the actions property to _getActions(). The TableRow actions property defines a set of actions that appear when the user hovers over a table row. Actions have a mandatory text and an onClick callback, but can also display an icon or be disabled if needed. Copy Step 10 of 10 Go back to your application and try hovering over any of the rows: Notice how the two available actions appear. When you click them, a function triggers with the selected row data as an argument, and an alert displays in your browser. Next steps You've built a table into a New Relic One application, using components to format data automatically and provide contextual actions. Well done! Keep exploring the Table components, their properties, and how to use them, in our SDK documentation.", + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app, you might have some additional setup and configuration. This guide covers: Downloading the New Relic One CLI to build or modify apps Contribute content to this website Before you begin You must have: A github account account - While not strictly necessary for building apps, a GitHub account enables you to download and customize our open source apps, and contribute an open source project. A New Relic developer account - if you don't already have one, you can get a free trial account for developing New Relic applications. npm - If you've installed Node.js, then you already have npm, which is used to share, reuse, and update JavaScript code, and is necessary for working with React components that are the framework for New Relic apps and this website. Tip Use the New Relic One VSCode extension to build your apps. Prepare to build or modify apps Step 1 of 2 Download the CLI and API key On the Build New Relic One applications page, complete the Quick start steps. These six Quick start steps get you an API key for use with developing apps, and the New Relic One CLI, for building and deploying apps. At the end of the Quick start, you have a project consisting of the following: A Nerdpack - The package containing all the files required by your application. It contains two types of files that you customize to build your app: Nerdlets, and the launcher. One or more Nerdlet files - A specific UI view or window. A Nerdlet is a React JavaScript package that includes an index.js file, a stylesheet, and a JSON-format config file. It can contain any JS functionality (charts, interactive fields, tooltips, etc.). A launcher file: This is the basis for the launcher, which is used to open your application from New Relic One after you publish your app. Step 2 of 2 Start building If you're ready to code, cd to your Nerdpack and get started. If you want to learn more about building applications, try these step-by-step guides: Build a \"Hello, World!\" application shows how to create a little application, publish it to New Relic One, and share it with others by subscribing accounts to it. Map pageviews by region takes you through the steps to create one of our popular open source apps. You learn to add a custom query to an app and view it in a table, then add that data to a map. Contributing to developer.newrelic.com This site is open source, and we want your input. Create a pull request if you see a mistake you know how to fix. Drop us a GitHub issue if you see some content gaps you want us to work on. Or write up a whole new guide if you have one you'd like to share. Read on to learn how. Step 1 of 3 Fork the developer-website GithHub repo Forking the repo enables you to work on your own copy of the developer.newrelic.com files, and build the site locally. It also enables us to more easily manage incomimg pull requests. On the developer-website page in GitHub, select the Fork button on the top right of the page, choose the account you want to fork to, and wait a few seconds while the fork is created. Sync regularly to keep your fork up to date with changes and additions to the main branch upstream. Step 2 of 3 Make a feature or documentation request On any page, select the GitHub button at the top of the page, and then select the kind of change you want, and fill out the GitHub form. Step 3 of 3 Contribute a new guide Check out our contributors guidelines, which will walk you through the process.", "type": "developer", "document_type": "page", - "info": "Add a table to your New Relic One app.", + "info": "Prepare to build apps and contribute to this site", "sections": [ - "Add tables to your New Relic One application", + "Set up your development environment", "Before you begin", - "Clone and set up the example application", - "Work with table components", - "Next steps" + "Tip", + "Prepare to build or modify apps", + "Start building" ], - "title": "Add tables to your New Relic One application", + "title": "Set up your development environment", "popularity": 1, - "external_id": "7ff7a8426eb1758a08ec360835d9085fae829936", - "image": "https://developer.newrelic.com/static/e637c7eb75a9dc01740db8fecc4d85bf/1d6ec/table-new-cells.png", - "url": "https://developer.newrelic.com/build-apps/howto-use-nrone-table-components/", - "published_at": "2020-08-18T02:07:10Z", - "updated_at": "2020-08-14T01:46:10Z", + "tags": [ + "developer account", + "API key", + "New Relic One CLI" + ], + "external_id": "c45638a9cd548d1ffffc9f1c7708f115a92ae04a", + "image": "", + "url": "https://developer.newrelic.com/build-apps/set-up-dev-env/", + "published_at": "2020-08-19T01:44:48Z", + "updated_at": "2020-08-19T01:44:47Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.7044865, + "_score": 3.6445959, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Add tables to your New Relic One application", - "sections": "Add tables to your New Relic One application", - "info": "Add a table to your New Relic One app.", - "body": "Add tables to your New Relic One application 30 min Tables are a popular way of displaying data in New Relic applications. For example, with the query builder you can create tables from NRQL queries. Whether you need to have more control over tables or you're importing third-party data, you can" + "sections": "Prepare to build or modify apps", + "info": "Prepare to build apps and contribute to this site", + "tags": "New Relic One CLI", + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app" }, - "id": "5efa989ee7b9d2ad567bab51" + "id": "5efa9973e7b9d242237bab39" }, { - "body": "Intro to NerdStorage 30 min To help you build a New Relic One application, we provide you with the New Relic One SDK. On this page, you’ll learn how to use NerdStorage SDK components. Use NerdStorage in your apps NerdStorage is used to store and retrieve simple sets of data, including users's configuration settings and preferences (like favorites), or any other small data sets. This storage is unique per Nerdpack, and can't be shared with any other Nerdpack. NerdStorage can be classified into three categories: User storage: Data that is attached to a particular user. If you’re authenticated as the user the data is attached to, you can read it and write it. Account storage: Data that is attached to a particular account. If you’re authenticated and can access the account, you can read and write to account scoped NerdStorage. Visibility of account data is also determined by master/subaccount rules: If a user has access to the master account, then they also have access to data in all subaccounts. Entity storage: Data that is attached to a particular entity. If you can see the corresponding entity, you can read and write data on that entity. Data model You can imagine NerdStorage as a nested key-value map. Data is inside documents, which are nested inside collections: { 'YourNerdpackUuid': { 'collection-1': { 'document-1-of-collection-1': '{\"lastNumber\": 42, \"another\": [1]}', 'document-2-of-collection-1': '\"userToken\"', // ... }, 'another-collection': { 'fruits': '[\"pear\", \"apple\"]', // ... }, // ... }, } Copy Each NerdStorage level has different properties and purpose: Collections: From a Nerdpack, you can create multiple collections by naming each of them. Inside a collection you can put one or more documents. Think of a collection as key-value storage, where each document is a key-value pair. Documents: A document is formed by an identifier (documentId) and a set of data associated with it. Data associated with a document: NerdStorage accepts any sort of data associated to a documentId. Query and mutation components that are provided work by serializing and deserializing JSON. Limits A Nerdpack can hold up to 1,000 collections and 10,000 documents, plus storage type. A collection can hold up to 1,000 documents, plus storage type. Each document can have a maximum length of 64 KiB when serialized. Data access To access NerdStorage, you can run NerdGraph queries, or use the provided storage queries. Depending on which storage you want to access, you can use a different set of SDK components: User access: UserStorageQuery and UserStorageMutation Account access: AccountStorageQuery and AccountStorageMutation Entity access: EntityStorageQuery and EntityStorageMutation Each of these components can operate declaratively (for example, as part of your React rendering methods) or imperatively (by using the static methods for query and mutation). For more information on this, see Data querying and mutations. Permissions for working with NerdStorage In order to persist changes on NerdStorage, such as creating, updating, and deleting account and entity storage, you must have a user role with permission to persist changes.", + "body": "Nerdpack file structure A New Relic One application is represented by a Nerdpack folder, which can include one or more Nerdlet files, and (optionally) one or more launcher files. Here we explain: The file structure for a Nerdpack, a Nerdlet, and a launcher How to link a launcher file to a Nerdlet How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create a Nerdpack template that includes a Nerdlet and a launcher. Generate Nerdlet or launcher individually: Use the New Relic One CLI command nr1 create and choose either Nerdlet or launcher. This can be useful when adding Nerdlets to an existing Nerdpack. For documentation on generating and connecting Nerdpack components, see our app building guides and the New Relic One CLI command reference. Nerdpack file structure When you generate a Nerdpack template using the nr1 create command, it has the following file structure: my-nerdlet ├── README.md ├── launchers │   └── my-nerdlet-launcher │   ├── icon.png │   └── nr1.json ├── nerdlets │   └── my-nerdlet-nerdlet │   ├── index.js │   ├── nr1.json │   └── styles.scss ├── node_modules │   ├── js-tokens │   ├── loose-envify │   ├── object-assign │   ├── prop-types │   ├── react │   ├── react-dom │   ├── react-is │   └── scheduler ├── nr1.json ├── package-lock.json └── package.json Copy Nerdlet file structure A Nerdpack can contain one or more Nerdlets. A Nerdlet folder starts out with three default files, index.js, nr1.json, and styles.scss. Here is what the default files look like after being generated using the nr1 create command: index.js The JavaScript code of the Nerdlet. import React from 'react'; export default class MyAwesomeNerdpack extends React.Component { render() { return

Hello, my-awesome-nerdpack Nerdlet!

; } } Copy nr1.json The Nerdlet configuration file. { \"schemaType\": \"NERDLET\", \"id\": \"my-awesome-nerdpack-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\" } Copy Besides using the launcher as the access point for your application, you can also associate the application with a monitored entity to get it to appear in the entity explorer. To do this, add two additional fields to the config file of the first-launched Nerdlet: entities and actionCategory. In the following example, the Nerdlet has been associated with all Browser-monitored applications and will appear under the Monitor UI category : { \"schemaType\": \"NERDLET\", \"id\": \"my-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"Custom Data\", \"entities\": [{ \"domain\": \"BROWSER\", \"type\": \"APPLICATION\" }], \"actionCategory\": \"monitor\" } Copy To see this application in the UI, you would go to the entity explorer, select Browser applications, and select a monitored application. styles.scss An empty SCSS file for styling your application. icon.png The launcher icon that appears on the Apps page in New Relic One when an application is deployed. Launcher file structure Launchers have their own file structure. Note that: A launcher is not required; as an alternative to using a launcher, you can associate your application with a monitored entity. An application can have more than one launcher, which might be desired for an application with multiple Nerdlets. After generating a launcher using the nr1 create command, its folder contains two files: nr1.json The configuration file. { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy To connect a launcher to a Nerdlet, the rootNerdletId must match the id in the launched Nerdlet's nr1.json config file. For Nerdpacks with multiple Nerdlets, this needs to be done only for the first-launched Nerdlet. icon.png The icon displayed on the launcher for the app on the Apps page.", "type": "developer", "document_type": "page", - "info": "Intro to NerdStorage on New Relic One", + "info": "An overview of the Nerdpack File Structure", "sections": [ - "Intro to NerdStorage", - "Use NerdStorage in your apps", - "Data model", - "Limits", - "Data access", - "Permissions for working with NerdStorage" + "Nerdpack file structure", + "Generate Nerdpack components", + "Nerdlet file structure", + "index.js", + "nr1.json", + "styles.scss", + "icon.png", + "Launcher file structure" ], - "title": "Intro to NerdStorage", + "title": "Nerdpack file structure", "popularity": 1, - "external_id": "709e06c25376d98b2191ca369b4d139e5084bd62", + "tags": [ + "New Relic One CLI", + "nerdpack", + "file structure", + "nerdlets", + "launchers" + ], + "external_id": "c97bcbb0a2b3d32ac93b5b379a1933e7b4e00161", "image": "", - "url": "https://developer.newrelic.com/explore-docs/nerdstorage/", - "published_at": "2020-08-18T02:11:48Z", - "updated_at": "2020-08-14T01:50:34Z", + "url": "https://developer.newrelic.com/explore-docs/nerdpack-file-structure/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:49:25Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.6584254, + "_score": 2.7281008, "_version": null, "_explanation": null, "sort": null, "highlight": { - "sections": "Use NerdStorage in your apps", - "info": "Intro to NerdStorage on New Relic One", - "body": "Intro to NerdStorage 30 min To help you build a New Relic One application, we provide you with the New Relic One SDK. On this page, you’ll learn how to use NerdStorage SDK components. Use NerdStorage in your apps NerdStorage is used to store and retrieve simple sets of data, including users's" + "sections": "Generate Nerdpack components", + "tags": "New Relic One CLI", + "body": " components, see our app building guides and the New Relic One CLI command reference. Nerdpack file structure When you generate a Nerdpack template using the nr1 create command, it has the following file structure: my-nerdlet ├── README.md ├── launchers │   └── my-nerdlet-launcher │   ├── icon.png" }, - "id": "5efa989ee7b9d2048e7bab92" + "id": "5efa989e196a671300766404" }, { - "body": "For an even better experience than plugins, go to: newrelic.com/integrations: Integrate the on-host and cloud systems you already use with New Relic, so you can filter and analyze data, create dashboards, and set alerts within a single platform. developer.newrelic.com: Use developer tools to collect data from any source, automate workflows, build apps, and use our APIs. Each plugin in Plugin Central includes procedures for how to install, use, troubleshoot, and uninstall it. After you install a plugin, it starts to receive data, usually within five minutes. The plugin automatically appears with a short name and icon on your Plugins menu in New Relic One. You do not need to select it from Plugin Central. Plugins in Plugin Central are not supported with accounts that host data in the EU region data center. View plugin dashboard details The amount and types of information on the plugin's summary page and dashboards depend on the specific plugin. For example, a plugin may have one or more components (instances) and one or more dashboards. To view summary and dashboard details about the plugin: Go to one.newrelic.com > More > Plugins, and select your plugin. From the plugin's summary page, review the list of components or instances, summary metrics, and list of Recent Events. To view dashboard details about any component or instance, select its name. Plugin summary Depending on the plugin, the summary includes: One or more components or instances (what the plugin agent is monitoring, typically a host/port pair) Zero to five summary metrics for the past three minutes (values such as average, total, minimum, maximum, standard deviation, rate, or count) with optional alerts Recent events list, including deployments, notifications, and alerts Other information about alert violations, events, and activity If your plugin has 100 or more components or instances, you can search for a specific component instance. Here is a summary of additional standard features. If you want to... Do this... View version information for a component's or instance's agent Mouse over the component's name. Change the sort order On the title row of the plugin's summary page, select the up or down arrow for a component (instance) or a summary metric's label. Show or hide items on the events and activity list Select an event icon, or select All. View details about an event On the events and activity list, select the link. View page details for a component or instance Select the name or a summary metric for the component (instance). Plugin dashboards Depending on the plugin, it may have one or more dashboards, and each dashboard may present data as a chart or a table. You can use any of New Relic's standard dashboard features to drill down into detailed information. The customized dashboards that show plugin data are part of the plugin. Users cannot add or remove these dashboards. This must be done by the author or publisher as part of a plugin update. Plugin alerts If the plugin publisher set Critical (red) or Caution (yellow) alert conditions for your plugin's components or instances, you can view details direct in the user interface. For example, you can: Select and view alert details. Change the existing thresholds. Set your alert notification options; for example, to receive email notifications for Critical events. Delete a plugin Each plugin in Plugin Central includes procedures for how to uninstall it. When you select the plugin's Download or Continue button, the plugin should include a README file or refer to other documentation resources. Remove plugin components (instances) At a minimum, your plugin must stop reporting data before you start uninstalling it. Make sure the health status for your plugin's components (instances) are gray. Depending on the plugin, there may be other dependencies before disabling or uninstalling it. For example, plugins from SaaS providers may have different requirements. Be sure to review the instructions that the plugin's publisher provides. Then, to remove individual components from your plugin, click the settings settings icon for each component (instance). Delete the plugin After you remove each component (instance) for the plugin, the plugin icon will automatically disappear from your Plugins menu in the New Relic UI. You do not need to do anything else to delete the plugin. If you are the plugin's publisher and need to delete the plugin from Plugin Central, go to support.newrelic.com. For more help If you need more help, check out these support and learning resources: Review the documentation provided by the plugin publisher, or contact the publisher's support resources (identified in the plugin's Get support link). Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", - "type": "docs", + "body": "Add, query, and mutate data using NerdStorage 45 min NerdStorage is a document database accessible within New Relic One. It allows you to modify, save, and retrieve documents from one session to the next. Using NerdStorage, you can create individual documents of up to 64kb in size, create different collections of documents, and store data by entity, account, or user level. This guide explains how to add data and documents to NerdStorage. For an introduction to what NerdStorage is and how it works, see Intro to NerdStorage. Before you begin This guide requires that you have an API key and the New Relic One CLI as described in Set up your development environment. Get started First, get the NerdStorage app running successfully inside New Relic One. Step 1 of 3 Clone the example applications from the GitHub repo. Step 2 of 3 Use the New Relic One CLI to update the application UUID and run the application locally. In the terminal, switch to the /nr1-how-to/use-nerdstorage directory: cd / nr1 - how - to / use - nerdstorage; Copy Update the UUID and serve the application: nr1 nerdpack:uuid -gf nr1 nerdpack:serve Copy Step 3 of 3 Once the app is successfully served, your terminal will return the URL to view your running application on New Relic One. Load the URL. Click Apps and under Other apps you'll see the Use Nerdstorage app listed. Click to launch the app. Add data to NerdStorage Once the app is up and running on New Relic One, you can prepare the app and start adding data. On the How To Use NerdStorage app screen, there's a Saved to NerdStorage pane with a field for adding data. However, if you type something you'll get an error message. This is because you need to be set up to store data at the User level. You can do this with the help of the UserStorageMutation component. Step 1 of 3 Open the application’s ./nerdlets/use-nerdstorage-nerdlet/index.js file in the text editor of your choice and find the code for the TextField and Button used to enter data. The Button onClick prop makes a call to a helper method called _addToNerdStorage, and you need to update it to add UserStorageMutation The UserStorage NerdStorage components require a collection and documentId. In the constructor method in the application’s index.js file, you can see the variables being provided. In the .js file, it will look something like this: constructor(props) { super(props) this.collectionId = 'mycollection'; this.documentId = 'learning-nerdstorage'; this.state = { isOpen: true, storage: [], text: '', }; this._addToNerdStorage = this._addToNerdStorage.bind(this); this._removeFromNerdStorage = this._removeFromNerdStorage.bind(this); this._deleteDocument = this._deleteDocument.bind(this); } Copy Step 2 of 3 Import the UserStorageMutation by adding it to your import statement at the top of the index.js file: import { UserStorageMutation } from 'nr1'; Copy Then update the helper with this code beginning with _addToNerdStorage: _addToNerdStorage(){ const { text, storage } = this.state; storage.push(text); this.setState({storage}, () => { UserStorageMutation.mutate({ actionType: UserStorageMutation.ACTION_TYPE.WRITE_DOCUMENT, collection: this.collectionId, documentId: this.documentId, document: { storage }, }) .then((res) => { this.setState({text: ''}); Toast.showToast({ title: \"NerdStorage Update.\", type: Toast.TYPE.NORMAL }); }) .catch((err) => console.log(err)); }); } Copy Step 3 of 3 Return to your running How To Use NerdStorage app screen on New Relic One and reload the page. Add some text in the text entry field and click the check button. This will update NerdStorage and trigger a Toast notification inside the app. You should then see the text you typed displayed as a table row below the text entry field. Query data from NerdStorage Once you get data storage working as described in the section above, you also need to get the app properly reading data from NerdStorage, or the app will reload with an empty state every time you navigate away from the app page and back. To do this, add the UserStorageQuery component and update the componentDidMount method. Step 1 of 3 Import the UserStorageQuery by adding it to the import statement in the application’s ./nerdlets/use-nerdstorage-nerdlet/index.js file. import { UserStorageMutation, UserStorageQuery } from 'nr1'; Copy Step 2 of 3 Then, add the following componentDidMount method to your application: componentDidMount(){ UserStorageQuery.query({ collection: this.collectionId, documentId: this.documentId, }) .then(({ data }) => { if(data !== null) { this.setState({storage: data.storage}); } }) .catch(err => console.log(err)); } Copy Step 3 of 3 Back inside the NerdStorage app, test your changes by adding a few more rows using the text entry field. Then exit and relaunch the application. The application should load and show all the data you entered before you navigated away. Mutate data in NerdStorage Each NerdStorage entry displayed in the table inside the app has a trash button that can be used to update a specific entry. The trash button works by making a call to the _removeFromNerdStorage helper method. Step 1 of 1 To get this process working, update the code in _removeFromNerdStorage: _removeFromNerdStorage(index, data){ const { storage } = this.state; storage.pop(data); this.setState({storage}, () => { UserStorageMutation.mutate({ actionType: UserStorageMutation.ACTION_TYPE.WRITE_DOCUMENT, collection: this.collectionId, documentId: this.documentId, document: { storage }, }) .then((res) => { Toast.showToast({ title: \"NerdStorage Update.\", type: Toast.TYPE.NORMAL }); }) .catch((err) => console.log(err)); }); } Copy Once you do this, clicking the trash button removes the item it's associated with, and the app updates to show the change. Delete collection from NerdStorage While the trash button is a good method for removing specific entries one at a time, you may also want the ability to delete a whole NerdStorage document at once. You can do this by adding the Delete Document button to your app. Step 1 of 2 Add a new GridItem to the application immediately before the closing Grid tag. In the new GridItem add the following code to display your new button: ; Copy Step 2 of 2 Because the new Delete Document button will be calling the _deleteDocument helper method, you'll need to update that using this code: _deleteDocument(){ this.setState({storage: []}); UserStorageMutation.mutate({ actionType: UserStorageMutation.ACTION_TYPE.DELETE_DOCUMENT, collection: this.collectionId, documentId: this.documentId, }); Toast.showToast({ title: \"NerdStorage Update.\", type: Toast.TYPE.CRITICAL }); } Copy Back inside the application, you should now see both the individual trash buttons and the newly added Delete Document button. Next steps Now that you’ve successfully implemented NerdStorage into a New Relic One application, you can store and mutate data connected to your User. For more information on the various NerdStorage components, please visit the New Relic developer website API documentation.", + "type": "developer", "document_type": "page", - "breadcrumb": "Contents / Plugins / Plugins for New Relic / Install plugins", - "info": "How to navigate the user interface for plugins you install from Plugin Central in New Relic One.", - "nodeid": 3276, + "info": "NerdStorage is a document database accessible within New Relic One. It allows you to modify, save, and retrieve documents from one session to the next.", "sections": [ - "Plugins for New Relic", + "Add, query, and mutate data using NerdStorage", + "Before you begin", "Get started", - "Install plugins", - "Custom dashboards and custom views", - "Use a Plugin Central plugin", - "View plugin dashboard details", - "Delete a plugin", - "For more help" + "Add data to NerdStorage", + "Query data from NerdStorage", + "Mutate data in NerdStorage", + "Delete collection from NerdStorage", + "Next steps" ], - "title": "Use a Plugin Central plugin", + "title": "Add, query, and mutate data using NerdStorage", "popularity": 1, - "external_id": "2d4076c0d593e21391ca034868b87042328d8a61", - "category_1": "Plugins for New Relic", - "category_2": "Install plugins", - "image": "", - "url": "https://docs.newrelic.com/docs/plugins/plugins-new-relic/installing-plugins/use-plugin-central-plugin", - "published_at": "2020-08-18T14:35:58Z", - "updated_at": "2020-08-18T14:35:58Z", - "category_0": "Plugins", + "tags": [ + "add data", + "query data", + "mutate data", + "nerdstorage" + ], + "external_id": "97cc9637edea35ecd68683f1010f67a5f8c79038", + "image": "https://developer.newrelic.com/static/e03456a7ed8556f83bd3329ea38b261d/8f217/add-data-NerdStorage.png", + "url": "https://developer.newrelic.com/build-apps/add-query-mutate-data-nerdstorage/", + "published_at": "2020-08-19T01:48:30Z", + "updated_at": "2020-08-14T01:50:34Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.59509915, + "_score": 1.9600999, "_version": null, "_explanation": null, "sort": null, "highlight": { - "sections": "Plugins for New Relic", - "info": "How to navigate the user interface for plugins you install from Plugin Central in New Relic One.", - "category_1": "Plugins for New Relic", - "body": "For an even better experience than plugins, go to: newrelic.com/integrations: Integrate the on-host and cloud systems you already use with New Relic, so you can filter and analyze data, create dashboards, and set alerts within a single platform. developer.newrelic.com: Use developer tools", - "breadcrumb": "Contents / Plugins / Plugins for New Relic / Install plugins" + "title": "Add, query, and mutate data using NerdStorage", + "sections": "Add, query, and mutate data using NerdStorage", + "info": "NerdStorage is a document database accessible within New Relic One. It allows you to modify, save, and retrieve documents from one session to the next.", + "tags": "nerdstorage", + "body": " will return the URL to view your running application on New Relic One. Load the URL. Click Apps and under Other apps you'll see the Use Nerdstorage app listed. Click to launch the app. Add data to NerdStorage Once the app is up and running on New Relic One, you can prepare the app and start adding data" }, - "id": "5f2ef9b3196a67c2a0fbd721" + "id": "5efa98d4e7b9d26d6b7bab74" } ], - "/explore-docs/nr1-subscription": [ + "/explore-docs/nr1-plugins": [ { "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build your own application launcher and follow the quick start instructions. The quick start automatically generates an API key for the account you select, and gives you the pre-populated commands to create a profile, generate your first \"Hello World\" app, and serve it locally. Tip Use the NR1 VS Code extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions. For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). Configure your CLI preferences nr1 config:set Sets a specific configuration value. nr1 config:get Shows a specific configuration. nr1 config:list Lists your configuration choices. nr1 config:delete Removes the value of a specific configuration. Set up your Nerdpacks nr1 nerdpack:clone Clones an open source Nerdpack from our GitHub repository. nr1 nerdpack:serve Serves your Nerdpack for testing and development purposes. nr1 nerdpack:uuid Shows or regenerates the UUID of a Nerdpack. nr1 nerdpack:publish Publishes your Nerdpack to New Relic. nr1 nerdpack:deploy Deploys a Nerdpack version to a specific channel. nr1 nerdpack:undeploy Undeploys a Nerdpack version from a specific channel. Manage your Nerdpack subscriptions nr1 subscription:set Subscribes your account to a Nerdpack and channel. nr1 subscription:list Lists all the Nerdpacks your account is subscribed to. nr1 subscription:unset Unsubscribes your account from a Nerdpack. Install and manage plugins nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin into the CLI for development. nr1 plugins:update Updates your installed plugins. nr1 plugins:uninstall Removes a plugin from the CLI. Manage catalog information nr1 catalog:info Shows the Nerdpack info stored in the catalog. nr1 catalog:submit Gathers and submits the catalog info on the current folder.", "type": "developer", @@ -5730,11 +5414,11 @@ "external_id": "858339a44ead21c83257778ce60b4c352cd30d3b", "image": "https://developer.newrelic.com/static/2c6d337608b38a3312b4fc740afe6167/7272b/developercenter.png", "url": "https://developer.newrelic.com/explore-docs/nr1-cli/", - "published_at": "2020-08-18T02:07:10Z", + "published_at": "2020-08-19T01:50:40Z", "updated_at": "2020-08-18T01:50:36Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.7381426, + "_score": 0.60932755, "_version": null, "_explanation": null, "sort": null, @@ -5747,6 +5431,42 @@ }, "id": "5efa989e28ccbc535a307dd0" }, + { + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app, you might have some additional setup and configuration. This guide covers: Downloading the New Relic One CLI to build or modify apps Contribute content to this website Before you begin You must have: A github account account - While not strictly necessary for building apps, a GitHub account enables you to download and customize our open source apps, and contribute an open source project. A New Relic developer account - if you don't already have one, you can get a free trial account for developing New Relic applications. npm - If you've installed Node.js, then you already have npm, which is used to share, reuse, and update JavaScript code, and is necessary for working with React components that are the framework for New Relic apps and this website. Tip Use the New Relic One VSCode extension to build your apps. Prepare to build or modify apps Step 1 of 2 Download the CLI and API key On the Build New Relic One applications page, complete the Quick start steps. These six Quick start steps get you an API key for use with developing apps, and the New Relic One CLI, for building and deploying apps. At the end of the Quick start, you have a project consisting of the following: A Nerdpack - The package containing all the files required by your application. It contains two types of files that you customize to build your app: Nerdlets, and the launcher. One or more Nerdlet files - A specific UI view or window. A Nerdlet is a React JavaScript package that includes an index.js file, a stylesheet, and a JSON-format config file. It can contain any JS functionality (charts, interactive fields, tooltips, etc.). A launcher file: This is the basis for the launcher, which is used to open your application from New Relic One after you publish your app. Step 2 of 2 Start building If you're ready to code, cd to your Nerdpack and get started. If you want to learn more about building applications, try these step-by-step guides: Build a \"Hello, World!\" application shows how to create a little application, publish it to New Relic One, and share it with others by subscribing accounts to it. Map pageviews by region takes you through the steps to create one of our popular open source apps. You learn to add a custom query to an app and view it in a table, then add that data to a map. Contributing to developer.newrelic.com This site is open source, and we want your input. Create a pull request if you see a mistake you know how to fix. Drop us a GitHub issue if you see some content gaps you want us to work on. Or write up a whole new guide if you have one you'd like to share. Read on to learn how. Step 1 of 3 Fork the developer-website GithHub repo Forking the repo enables you to work on your own copy of the developer.newrelic.com files, and build the site locally. It also enables us to more easily manage incomimg pull requests. On the developer-website page in GitHub, select the Fork button on the top right of the page, choose the account you want to fork to, and wait a few seconds while the fork is created. Sync regularly to keep your fork up to date with changes and additions to the main branch upstream. Step 2 of 3 Make a feature or documentation request On any page, select the GitHub button at the top of the page, and then select the kind of change you want, and fill out the GitHub form. Step 3 of 3 Contribute a new guide Check out our contributors guidelines, which will walk you through the process.", + "type": "developer", + "document_type": "page", + "info": "Prepare to build apps and contribute to this site", + "sections": [ + "Set up your development environment", + "Before you begin", + "Tip", + "Prepare to build or modify apps", + "Start building" + ], + "title": "Set up your development environment", + "popularity": 1, + "tags": [ + "developer account", + "API key", + "New Relic One CLI" + ], + "external_id": "c45638a9cd548d1ffffc9f1c7708f115a92ae04a", + "image": "", + "url": "https://developer.newrelic.com/build-apps/set-up-dev-env/", + "published_at": "2020-08-19T01:44:48Z", + "updated_at": "2020-08-19T01:44:47Z", + "_index": "520d1d5d14cc8a32e600034b", + "_type": "520d1d5d14cc8a32e600034c", + "_score": 0.28871018, + "_version": null, + "_explanation": null, + "sort": null, + "highlight": { + "tags": "New Relic One CLI", + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app" + }, + "id": "5efa9973e7b9d242237bab39" + }, { "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs in GitHub. Options --format string output text format [YAML, JSON, Text] (default \"JSON\") -h, --help help for newrelic --plain output compact text Copy Commands newrelic apm - Interact with New Relic APM newrelic completion - Generates shell completion functions newrelic config - Manage the configuration of the New Relic CLI newrelic documentation - Generate CLI documentation newrelic entity - Interact with New Relic entities newrelic nerdgraph - Execute GraphQL requests to the NerdGraph API newrelic nerdstorage - Read, write, and delete NerdStorage documents and collections. newrelic nrql - Commands for interacting with the New Relic Database newrelic profile - Manage the authentication profiles for this tool newrelic version - Show the version of the New Relic CLI newrelic workload - Interact with New Relic One workloads", "type": "developer", @@ -5764,162 +5484,232 @@ "external_id": "471ed214caaf80c70e14903ec71411e2a1c03888", "image": "", "url": "https://developer.newrelic.com/explore-docs/newrelic-cli/", - "published_at": "2020-08-18T02:11:50Z", + "published_at": "2020-08-19T01:49:36Z", + "updated_at": "2020-08-14T01:47:12Z", + "_index": "520d1d5d14cc8a32e600034b", + "_type": "520d1d5d14cc8a32e600034c", + "_score": 0.25216433, + "_version": null, + "_explanation": null, + "sort": null, + "highlight": { + "title": "New Relic CLI Reference", + "sections": "New Relic CLI commands", + "info": "The command line tools for performing tasks against New Relic APIs", + "tags": "new relic cli", + "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs" + }, + "id": "5efa989ee7b9d2024b7bab97" + }, + { + "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations, and fetch New Relic or third-party data. Components of the SDK SDK components are located in the Node module package named nr1, which you get when you install the NR1 CLI. The nr1 components can be divided into several categories: UI components Chart components Query and storage components Platform APIs UI components The UI components category of the SDK contains React UI components, including: Text components: These components provide basic font and heading elements. These include HeadingText and BlockText. Layout components: These components give you control over the layout, and help you build complex layout designs without having to deal with the CSS. Layout components include: Grid and GridItem: for organizing more complex, larger scale page content in rows and columns Stack and StackItem: for organizing simpler, smaller scale page content (in column or row) Tabs and TabsItem: group various related pieces of content into separate hideable sections List and ListItem: for providing a basic skeleton of virtualized lists Card, CardHeader and CardBody : used to group similar concepts and tasks together Form components: These components provide the basic building blocks to interact with the UI. These include Button, TextField, Dropdown and DropdownItem, Checkbox, RadioGroup, Radio, and Checkbox. Feedback components: These components are used to provide feedback to users about actions they have taken. These include: Spinnerand Toast. Overlaid components: These components are used to display contextual information and options in the form of an additional child view that appears above other content on screen when an action or event is triggered. They can either require user interaction (like modals), or be augmenting (like a tooltip). These include: Modal and Tooltip. Components suffixed with Item can only operate as direct children of that name without the suffix. For example: GridItem should only be found as a child of Grid. Chart components The Charts category of the SDK contains components representing different types of charts. The ChartGroup component helps a group of related charts share data and be aligned. Some chart components can perform NRQL queries on their own; some accept a customized set of data. Query and storage components The Query components category contains components for fetching and storing New Relic data. The main way to fetch data is with NerdGraph, our GraphQL endpoint. This can be queried using NerdGraphQuery. To simplify use of NerdGraph queries, we provide some components with pre-defined queries. For more on using NerdGraph, see Queries and mutations. We also provide storage for storing small data sets, such as configuration settings data, or user-specific data. For more on this, see NerdStorage. Platform APIs The Platform API components of the SDK enable your application to interact with different parts of the New Relic One platform, by reading and writing state from and to the URL, setting the configuration, etc. They can be divided into these categories: PlatformStateContext: provides read access to the platform URL state variables. Example: timeRange in the time picker. navigation: an object that allows programmatic manipulation of the navigation in New Relic One. Example: opening a new Nerdlet. NerdletStateContext: provides read access to the Nerdlet URL state variables. Example: an entityGuid in the entity explorer. nerdlet: an object that provides write access to the Nerdlet URL state.", + "type": "developer", + "document_type": "page", + "info": "Intro to New Relic One API components", + "sections": [ + "Intro to New Relic One API components", + "Components of the SDK", + "UI components", + "Chart components", + "Query and storage components", + "Platform APIs" + ], + "title": "Intro to New Relic One API components", + "popularity": 1, + "tags": [ + "SDK components", + "New Relic One apps", + "UI components", + "chart components", + "query and storage components", + "Platform APIs" + ], + "external_id": "3620920c26bcd66c59c810dccb1200931b23b8c2", + "image": "", + "url": "https://developer.newrelic.com/explore-docs/intro-to-sdk/", + "published_at": "2020-08-19T01:50:40Z", "updated_at": "2020-08-14T01:47:12Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.30232108, + "_score": 0.24920408, + "_version": null, + "_explanation": null, + "sort": null, + "highlight": { + "title": "Intro to New Relic One API components", + "sections": "Intro to New Relic One API components", + "info": "Intro to New Relic One API components", + "tags": "New Relic One apps", + "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations" + }, + "id": "5efa989e28ccbc4071307de5" + }, + { + "body": "Nerdpack file structure A New Relic One application is represented by a Nerdpack folder, which can include one or more Nerdlet files, and (optionally) one or more launcher files. Here we explain: The file structure for a Nerdpack, a Nerdlet, and a launcher How to link a launcher file to a Nerdlet How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create a Nerdpack template that includes a Nerdlet and a launcher. Generate Nerdlet or launcher individually: Use the New Relic One CLI command nr1 create and choose either Nerdlet or launcher. This can be useful when adding Nerdlets to an existing Nerdpack. For documentation on generating and connecting Nerdpack components, see our app building guides and the New Relic One CLI command reference. Nerdpack file structure When you generate a Nerdpack template using the nr1 create command, it has the following file structure: my-nerdlet ├── README.md ├── launchers │   └── my-nerdlet-launcher │   ├── icon.png │   └── nr1.json ├── nerdlets │   └── my-nerdlet-nerdlet │   ├── index.js │   ├── nr1.json │   └── styles.scss ├── node_modules │   ├── js-tokens │   ├── loose-envify │   ├── object-assign │   ├── prop-types │   ├── react │   ├── react-dom │   ├── react-is │   └── scheduler ├── nr1.json ├── package-lock.json └── package.json Copy Nerdlet file structure A Nerdpack can contain one or more Nerdlets. A Nerdlet folder starts out with three default files, index.js, nr1.json, and styles.scss. Here is what the default files look like after being generated using the nr1 create command: index.js The JavaScript code of the Nerdlet. import React from 'react'; export default class MyAwesomeNerdpack extends React.Component { render() { return

Hello, my-awesome-nerdpack Nerdlet!

; } } Copy nr1.json The Nerdlet configuration file. { \"schemaType\": \"NERDLET\", \"id\": \"my-awesome-nerdpack-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\" } Copy Besides using the launcher as the access point for your application, you can also associate the application with a monitored entity to get it to appear in the entity explorer. To do this, add two additional fields to the config file of the first-launched Nerdlet: entities and actionCategory. In the following example, the Nerdlet has been associated with all Browser-monitored applications and will appear under the Monitor UI category : { \"schemaType\": \"NERDLET\", \"id\": \"my-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"Custom Data\", \"entities\": [{ \"domain\": \"BROWSER\", \"type\": \"APPLICATION\" }], \"actionCategory\": \"monitor\" } Copy To see this application in the UI, you would go to the entity explorer, select Browser applications, and select a monitored application. styles.scss An empty SCSS file for styling your application. icon.png The launcher icon that appears on the Apps page in New Relic One when an application is deployed. Launcher file structure Launchers have their own file structure. Note that: A launcher is not required; as an alternative to using a launcher, you can associate your application with a monitored entity. An application can have more than one launcher, which might be desired for an application with multiple Nerdlets. After generating a launcher using the nr1 create command, its folder contains two files: nr1.json The configuration file. { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy To connect a launcher to a Nerdlet, the rootNerdletId must match the id in the launched Nerdlet's nr1.json config file. For Nerdpacks with multiple Nerdlets, this needs to be done only for the first-launched Nerdlet. icon.png The icon displayed on the launcher for the app on the Apps page.", + "type": "developer", + "document_type": "page", + "info": "An overview of the Nerdpack File Structure", + "sections": [ + "Nerdpack file structure", + "Generate Nerdpack components", + "Nerdlet file structure", + "index.js", + "nr1.json", + "styles.scss", + "icon.png", + "Launcher file structure" + ], + "title": "Nerdpack file structure", + "popularity": 1, + "tags": [ + "New Relic One CLI", + "nerdpack", + "file structure", + "nerdlets", + "launchers" + ], + "external_id": "c97bcbb0a2b3d32ac93b5b379a1933e7b4e00161", + "image": "", + "url": "https://developer.newrelic.com/explore-docs/nerdpack-file-structure/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:49:25Z", + "_index": "520d1d5d14cc8a32e600034b", + "_type": "520d1d5d14cc8a32e600034c", + "_score": 0.21619636, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic CLI Reference", - "sections": "New Relic CLI commands", - "info": "The command line tools for performing tasks against New Relic APIs", - "tags": "new relic cli", - "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs" + "tags": "New Relic One CLI", + "body": " How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create" }, - "id": "5efa989ee7b9d2024b7bab97" - }, + "id": "5efa989e196a671300766404" + } + ], + "/explore-docs/nr1-nerdpack": [ { - "body": "Get started with the New Relic CLI 20 min Access the New Relic platform from the comfort of your terminal: you can use the New Relic CLI to manage entity tags, define workloads, record deployment markers, and much more. Our CLI has been designed for automating common tasks in your DevOps workflow. This guide walks you through the essentials of New Relic CLI, from install and configuration to basic usage. Before you begin For this guide you just need: Your New Relic personal API Key, which you can create from the Account settings of your New Relic account An instrumented application in your New Relic account Step 1 of 10 Install the New Relic CLI The New Relic CLI can be downloaded via Homebrew (macOS), Scoop (Windows), and Snapcraft (Linux). You can also download pre-built binaries for all platforms, including .deb and .rpm packages, and our Windows x64 .msi installer. Linux With Snapcraft installed, run: sudo snap install newrelic-cli macOS With Homebrew installed, run: brew install newrelic-cli Windows With Scoop installed, run: scoop bucket add newrelic-cli https://github.com/newrelic/newrelic-cli.git scoop install newrelic-cli Step 2 of 10 Create your New Relic CLI profile Now that you've installed the New Relic CLI, it's time to create your first profile. Profiles contain credentials and settings that you can apply to any CLI command, which is useful when switching between accounts. To create your first CLI profile, run the profiles add command. Note that you need to set the region of your New Relic account: use -r to set either us or eu (this is required). # Create the tutorial account for the US region newrelic profiles add -n tutorial --apiKey YOUR_NEW_RELIC_API_KEY -r YOUR_REGION # Set the profile as defaults newrelic profiles default -n tutorial Copy Step 3 of 10 Get your application details In this example, you are going to add tags to the application you've instrumented with New Relic. Tags are key-value pairs that can help you organize and filter your entities. An entity (for example, an application) can have a maximum of 100 key-value pairs tied to it. Before searching for your application using the New Relic CLI, write down or copy your Account ID and the name of your application in New Relic - you need both to find applications in the New Relic platform. Step 4 of 10 The New Relic CLI can retrieve your application details as a JSON object. To search for your APM application use the apm application search command. If you get an error, check that the account ID and application name you provided are correct. newrelic apm application search --accountId YOUR_ACCOUNT_ID --name NAME_OF_YOUR_APP Copy Step 5 of 10 If the account ID is valid, and the application name exists in your account, apm application search yields data similar to this example. When you've successfully searched for your application, look for the guid value. It's a unique identifier for your application. You should copy it or write it down. [ { accountId: YOUR_ACCOUNT_ID, applicationId: YOUR_APP_ID, domain: 'APM', entityType: 'APM_APPLICATION_ENTITY', guid: 'A_LONG_GUID', name: 'NAME_OF_YOUR_APP', permalink: 'https://one.newrelic.com/redirect/entity/A_LONG_GUID', reporting: true, type: 'APPLICATION', }, ]; Copy Step 6 of 10 Add a simple tag to your application Now that you have the GUID, you can point the New Relic CLI directly at your application. Adding a tag is the simplest way to try out the CLI capabilities (don't worry, tags can be deleted by using entity tags delete). Let's suppose that you want to add an environment tag to your application. Go ahead and add the dev:testing tag⁠ (or any other key-value pair) to your application using the entities tags create command. newrelic entity tags create --guid YOUR_APP_GUID --tag devkit:testing Copy Step 7 of 10 What if you want to add multiple tags? Tag sets come to the rescue! While tags are key-value pairs separated by colons, tag sets are comma separated lists of tags. For example: tag1:value1,tag2:value2 To add multiple tags at once to your application, modify and run the following snippet. newrelic entity tags create --guid YOUR_APP_GUID --tag tag1:test,tag2:test Copy Adding tags is an asynchronous operation: this means it could take a while for the tags to get created. Step 8 of 10 You've created and added some tags to your application, but how do you know they're there? You need to retrieve your application's tags. To retrieve your application's tags, use the entity tags get command. newrelic entity tags get --guid YOUR_APP_GUID All tags associated with your application are retrieved as a JSON array. [ { Key: 'tag1', Values: ['true'], }, { Key: 'tag2', Values: ['test'], }, { Key: 'tag3', Values: ['testing'], }, // ... ]; Copy Step 9 of 10 Bonus step: Create a deployment marker Deployments of applications often go wrong. Deployment markers are labels that, when attached to your application data, help you track deployments and troubleshoot what happened. To create a deployment marker, run the apm deployment create command using the same Application ID from your earlier search. newrelic apm deployment create --applicationId YOUR_APP_ID --revision $(git describe --tags --always) Copy Step 10 of 10 Notice that the JSON response includes the revision and timestamp of the deployment. This workflow could be built into a continuous integration or continuous deployment (CI/CD) system to help indicate changes in your application's behavior after deployments. Here is an example. { \"id\": 37075986, \"links\": { \"application\": 204261368 }, \"revision\": \"v1.2.4\", \"timestamp\": \"2020-03-04T15:11:44-08:00\", \"user\": \"Developer Toolkit Test Account\" } Copy Next steps Have a look at all the available commands. For example, you could create a New Relic workflow using workload create If you'd like to engage with other community members, visit our New Relic Explorers Hub page. We welcome feature requests or bug reports on GitHub.", + "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build your own application launcher and follow the quick start instructions. The quick start automatically generates an API key for the account you select, and gives you the pre-populated commands to create a profile, generate your first \"Hello World\" app, and serve it locally. Tip Use the NR1 VS Code extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions. For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). Configure your CLI preferences nr1 config:set Sets a specific configuration value. nr1 config:get Shows a specific configuration. nr1 config:list Lists your configuration choices. nr1 config:delete Removes the value of a specific configuration. Set up your Nerdpacks nr1 nerdpack:clone Clones an open source Nerdpack from our GitHub repository. nr1 nerdpack:serve Serves your Nerdpack for testing and development purposes. nr1 nerdpack:uuid Shows or regenerates the UUID of a Nerdpack. nr1 nerdpack:publish Publishes your Nerdpack to New Relic. nr1 nerdpack:deploy Deploys a Nerdpack version to a specific channel. nr1 nerdpack:undeploy Undeploys a Nerdpack version from a specific channel. Manage your Nerdpack subscriptions nr1 subscription:set Subscribes your account to a Nerdpack and channel. nr1 subscription:list Lists all the Nerdpacks your account is subscribed to. nr1 subscription:unset Unsubscribes your account from a Nerdpack. Install and manage plugins nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin into the CLI for development. nr1 plugins:update Updates your installed plugins. nr1 plugins:uninstall Removes a plugin from the CLI. Manage catalog information nr1 catalog:info Shows the Nerdpack info stored in the catalog. nr1 catalog:submit Gathers and submits the catalog info on the current folder.", "type": "developer", "document_type": "page", - "info": "Learn the essentials of the New Relic CLI, from install and configuration to basic usage.", + "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", "sections": [ - "Get started with the New Relic CLI", - "Before you begin", - "Install the New Relic CLI", - "Linux", - "macOS", - "Windows", - "Create your New Relic CLI profile", - "Get your application details", - "Add a simple tag to your application", - "Bonus step: Create a deployment marker", - "Next steps" + "New Relic One CLI reference", + "Installing the New Relic One CLI", + "Tip", + "New Relic One CLI Commands", + "Get started", + "Configure your CLI preferences", + "Set up your Nerdpacks", + "Manage your Nerdpack subscriptions", + "Install and manage plugins", + "Manage catalog information" ], - "title": "Get started with the New Relic CLI", + "title": "New Relic One CLI reference", "popularity": 1, "tags": [ - "api key", - "New Relic CLI", - "Tags", - "Entity", - "Deployment markers" + "New Relic One app", + "nerdpack commands" ], - "external_id": "531f2f3985bf64bb0dc92a642445887095048882", - "image": "", - "url": "https://developer.newrelic.com/automate-workflows/get-started-new-relic-cli/", - "published_at": "2020-08-18T02:06:05Z", - "updated_at": "2020-08-08T01:41:47Z", + "external_id": "858339a44ead21c83257778ce60b4c352cd30d3b", + "image": "https://developer.newrelic.com/static/2c6d337608b38a3312b4fc740afe6167/7272b/developercenter.png", + "url": "https://developer.newrelic.com/explore-docs/nr1-cli/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-18T01:50:36Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.16199563, + "_score": 0.79331076, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Get started with the New Relic CLI", - "sections": "Get started with the New Relic CLI", - "info": "Learn the essentials of the New Relic CLI, from install and configuration to basic usage.", - "tags": "New Relic CLI", - "body": " that you've installed the New Relic CLI, it's time to create your first profile. Profiles contain credentials and settings that you can apply to any CLI command, which is useful when switching between accounts. To create your first CLI profile, run the profiles add command. Note that you need" + "title": "New Relic One CLI reference", + "sections": "New Relic One CLI Commands", + "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", + "tags": "New Relic One app", + "body": ". For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet" }, - "id": "5efa999c196a67c4e1766461" + "id": "5efa989e28ccbc535a307dd0" }, { - "body": "Create a \"Hello, World!\" application 15 min Here's how you can quickly build a \"Hello, World!\" application in New Relic One. In these steps, you create a local version of the New Relic One site where you can prototype your application. Then, when you're ready to share the application with others, you can publish it to New Relic One. See the video, which demonstrates the steps in this guide in five minutes. Before you begin To get started, make sure you have accounts in GitHub and New Relic. To develop projects, you need the New Relic One CLI (command line interface). If you haven't already installed it, do the following: Install Node.js. Complete all the steps in the CLI quick start. For additional details about setting up your environment, see Set up your development environment. Tip Use the NR1 VS Code extension to build your apps. Create a local version of the \"Hello, World!\" application The CLI allows you to run a local version of New Relic One. You can develop your application locally before you publish it in New Relic One. If you followed all the steps in the CLI quick start, you now have files under a new directory named after your nerdpack project. Here's how you edit those files to create a \"Hello, World!\" project: Step 1 of 9 Open a code editor and point it to the new directory named after your nerdpack project (for example, my-awesome-nerdpack). Your code editor displays two artifacts: launchers containing the homepage tile nerdlets containing your application code Step 2 of 9 Expand nerdlets in your code editor, and open index.js. Step 3 of 9 Change the default return message to \"Hello, World!\": import React from 'react'; // https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction export default class MyAwesomeNerdpackNerdletNerdlet extends React.Component { render() { return

\"Hello, World!\"

; } } Copy Step 4 of 9 As an optional step, you can add a custom launcher icon using any image file named icon.png. Replace the default icon.png file under launcher by dragging in your new image file: Step 5 of 9 To change the name of the launcher to something meaningful, in your code editor under launchers, open nr1.json. Step 6 of 9 Change the value for displayName to anything you want as the launcher label, and save the file: { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"INSERT_YOUR_TILE_LABEL_HERE\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy Step 7 of 9 To see your new changes locally, start the Node server with this command in your terminal: npm start Copy Step 8 of 9 Open a browser and go to https://one.newrelic.com/?nerdpacks=local (this url is also shown in the terminal). Step 9 of 9 When the browser opens, click Apps, and then in the Other apps section, click the new launcher for your application. Here's an example where we inserted a leaf icon: After you click the new launcher, your \"Hello, World!\" appears: Publish your application to New Relic Your colleagues can't see your local application, so when you are ready to share it, publish it to the New Relic One catalog. The catalog is where you can find any pre-existing custom applications, as well as any applications you create in your own organization. Step 1 of 4 Execute the following in your terminal: nr1 nerdpack:publish Copy Step 2 of 4 Close your local New Relic One development tab, and open New Relic One. Step 3 of 4 Click the Apps launcher. Step 4 of 4 Under New Relic One catalog, click the launcher for your new application. When your new application opens, notice that it doesn't display any helpful descriptive information. The next section shows you how to add descriptive metadata. Add details to describe your project Now that your new application is in the New Relic One catalog, you can add details that help users understand what your application does and how to use it. Step 1 of 5 Go to your project in the terminal and execute the following: nr1 create Copy Step 2 of 5 Select catalog, which creates a stub in your project under the catalog directory. Here's how the results might look in your code editor: Step 3 of 5 In the catalog directory of your project, add screenshots or various types of metadata to describe your project. For details about what you can add, see Add catalog metadata and screenshots. Step 4 of 5 After you add the screenshots and descriptions you want, execute the following to save your metadata to the catalog: nr1 catalog:submit Copy Step 5 of 5 Return to the catalog and refresh the page to see your new screenshots and metadata describing your project. Subscribe accounts to your application To make sure other users see your application in the catalog, you need to subscribe accounts to the application. Any user with the NerdPack Manager role can subscribe accounts to an application. Step 1 of 3 If you're not already displaying your application's description page in the browser, click the launcher for the application in the catalog under Your company applications. Step 2 of 3 On your application's description page, click Add this app. Step 3 of 3 Select the accounts you want to subscribe to the application, and then click Update accounts to save your selections. When you return to the Apps page, you'll see the launcher for your new application. Summary Now that you've completed the steps in this example, you learned the basic steps to: Create a local application. Publish the application to the New Relic One catalog so you can share it with your colleagues. Add details to the project in the catalog so users understand how to use it. Subscribe accounts to your application so other users can use it. Related information Create a local application. Publish the application to the New Relic One catalog so you can share it with your colleagues. Add details to the project in the catalog so users understand how to use it. Subscribe accounts to your application so other users can see it directly on their homepage.", + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app, you might have some additional setup and configuration. This guide covers: Downloading the New Relic One CLI to build or modify apps Contribute content to this website Before you begin You must have: A github account account - While not strictly necessary for building apps, a GitHub account enables you to download and customize our open source apps, and contribute an open source project. A New Relic developer account - if you don't already have one, you can get a free trial account for developing New Relic applications. npm - If you've installed Node.js, then you already have npm, which is used to share, reuse, and update JavaScript code, and is necessary for working with React components that are the framework for New Relic apps and this website. Tip Use the New Relic One VSCode extension to build your apps. Prepare to build or modify apps Step 1 of 2 Download the CLI and API key On the Build New Relic One applications page, complete the Quick start steps. These six Quick start steps get you an API key for use with developing apps, and the New Relic One CLI, for building and deploying apps. At the end of the Quick start, you have a project consisting of the following: A Nerdpack - The package containing all the files required by your application. It contains two types of files that you customize to build your app: Nerdlets, and the launcher. One or more Nerdlet files - A specific UI view or window. A Nerdlet is a React JavaScript package that includes an index.js file, a stylesheet, and a JSON-format config file. It can contain any JS functionality (charts, interactive fields, tooltips, etc.). A launcher file: This is the basis for the launcher, which is used to open your application from New Relic One after you publish your app. Step 2 of 2 Start building If you're ready to code, cd to your Nerdpack and get started. If you want to learn more about building applications, try these step-by-step guides: Build a \"Hello, World!\" application shows how to create a little application, publish it to New Relic One, and share it with others by subscribing accounts to it. Map pageviews by region takes you through the steps to create one of our popular open source apps. You learn to add a custom query to an app and view it in a table, then add that data to a map. Contributing to developer.newrelic.com This site is open source, and we want your input. Create a pull request if you see a mistake you know how to fix. Drop us a GitHub issue if you see some content gaps you want us to work on. Or write up a whole new guide if you have one you'd like to share. Read on to learn how. Step 1 of 3 Fork the developer-website GithHub repo Forking the repo enables you to work on your own copy of the developer.newrelic.com files, and build the site locally. It also enables us to more easily manage incomimg pull requests. On the developer-website page in GitHub, select the Fork button on the top right of the page, choose the account you want to fork to, and wait a few seconds while the fork is created. Sync regularly to keep your fork up to date with changes and additions to the main branch upstream. Step 2 of 3 Make a feature or documentation request On any page, select the GitHub button at the top of the page, and then select the kind of change you want, and fill out the GitHub form. Step 3 of 3 Contribute a new guide Check out our contributors guidelines, which will walk you through the process.", "type": "developer", "document_type": "page", - "info": "Build a \"Hello, World!\" app and publish it to New Relic One", + "info": "Prepare to build apps and contribute to this site", "sections": [ - "Create a \"Hello, World!\" application", + "Set up your development environment", "Before you begin", "Tip", - "Create a local version of the \"Hello, World!\" application", - "Publish your application to New Relic", - "Add details to describe your project", - "Subscribe accounts to your application", - "Summary", - "Related information" + "Prepare to build or modify apps", + "Start building" ], - "title": "Create a \"Hello, World!\" application", + "title": "Set up your development environment", "popularity": 1, "tags": [ - "nr1 cli", - "Nerdpack file structure", - "NR One Catalog", - "Subscribe applications" + "developer account", + "API key", + "New Relic One CLI" ], - "external_id": "aa427030169067481fb69a3560798265b6b52b7c", - "image": "https://developer.newrelic.com/static/cb65a35ad6fa52f5245359ecd24158ff/9466d/hello-world-output-local.png", - "url": "https://developer.newrelic.com/build-apps/build-hello-world-app/", - "published_at": "2020-08-18T02:09:27Z", - "updated_at": "2020-08-18T01:45:02Z", + "external_id": "c45638a9cd548d1ffffc9f1c7708f115a92ae04a", + "image": "", + "url": "https://developer.newrelic.com/build-apps/set-up-dev-env/", + "published_at": "2020-08-19T01:44:48Z", + "updated_at": "2020-08-19T01:44:47Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.07493319, + "_score": 0.2978394, "_version": null, "_explanation": null, "sort": null, "highlight": { - "sections": "Publish your application to New Relic", - "info": "Build a "Hello, World!" app and publish it to New Relic One", - "tags": "nr1 cli", - "body": ", you can publish it to New Relic One. See the video, which demonstrates the steps in this guide in five minutes. Before you begin To get started, make sure you have accounts in GitHub and New Relic. To develop projects, you need the New Relic One CLI (command line interface). If you haven't already" + "tags": "New Relic One CLI", + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app" }, - "id": "5efa9973196a67d16d76645c" + "id": "5efa9973e7b9d242237bab39" }, { - "body": "New Relic One CLI common commands Here's a list of common commands to get you started with the New Relic One CLI. You can click any command to see its usage options and additional details about the command. Command Description nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). See our other New Relic One CLI docs for commands specific to Nerdpack set-up, Nerdpack subscriptions, CLI configuration, plugins, or catalogs. Command details nr1 help See commands and get details Shows all nr1 commands by default. To get details about a specific command, run nr1 help COMMAND_NAME. Usage $ nr1 help Arguments COMMAND_NAME The name of a particular command. Examples $ nr1 help $ nr1 help nerdpack $ nr1 help nerdpack:deploy nr1 update Update your CLI Updates to latest version of the CLI. You can specify which channel to update if you'd like. Usage $ nr1 update Arguments CHANNEL The name of a particular channel. Examples $ nr1 update $ nr1 update somechannel nr1 create Create a new component Creates a new component from our template (either a Nerdpack, Nerdlet, launcher, or catalog). The CLI will walk you through this process. To learn more about Nerdpacks and their file structure, see Nerdpack file structure. For more on how to set up your Nerdpacks, see our Nerdpack CLI commands. Usage $ nr1 create Options -f, --force If present, overrides existing files without asking. -n, --name=NAME Names the component. -t, --type=TYPE Specifies the component type. --path=PATH The route to the component. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output. nr1 profiles Manage your profiles keychain Displays a list of commands you can use to manage your profiles. Run nr1 help profiles:COMMAND for more on their specific usages. You can have more than one profile, which is helpful for executing commands on multiple New Relic accounts. To learn more about setting up profiles, see our Github workshop. Usage $ nr1 profiles:COMMAND Commands profiles:add Adds a new profile to your profiles keychain. profiles:default Chooses which profile should be default. profiles:list Lists the profiles on your keychain. profiles:remove Removes a profile from your keychain. nr1 autocomplete See autocomplete installation instructions Displays the autocomplete installation instructions. By default, the command displays the autocomplete instructions for zsh. If you want instructions for bash, run nr1 autocomplete bash. Usage $ nr1 autocomplete Arguments SHELL The shell type you want instructions for. Options -r, --refresh-cache Refreshes cache (ignores displaying instructions). Examples $ nr1 autocomplete $ nr1 autocomplete zsh $ nr1 autocomplete bash $ nr1 autocomplete --refresh-cache nr1 nrql Query using NRQL Fetches data from databases using a NRQL query. To learn more about NRQL and how to use it, see our NRQL docs. Usage $ nr1 nrql OPTION ... Options -a, --account=ACCOUNT The user account ID. required -q, --query=QUERY The NRQL query to run. required -u, --ugly Displays the content without tabs or spaces. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output.", + "body": "Nerdpack file structure A New Relic One application is represented by a Nerdpack folder, which can include one or more Nerdlet files, and (optionally) one or more launcher files. Here we explain: The file structure for a Nerdpack, a Nerdlet, and a launcher How to link a launcher file to a Nerdlet How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create a Nerdpack template that includes a Nerdlet and a launcher. Generate Nerdlet or launcher individually: Use the New Relic One CLI command nr1 create and choose either Nerdlet or launcher. This can be useful when adding Nerdlets to an existing Nerdpack. For documentation on generating and connecting Nerdpack components, see our app building guides and the New Relic One CLI command reference. Nerdpack file structure When you generate a Nerdpack template using the nr1 create command, it has the following file structure: my-nerdlet ├── README.md ├── launchers │   └── my-nerdlet-launcher │   ├── icon.png │   └── nr1.json ├── nerdlets │   └── my-nerdlet-nerdlet │   ├── index.js │   ├── nr1.json │   └── styles.scss ├── node_modules │   ├── js-tokens │   ├── loose-envify │   ├── object-assign │   ├── prop-types │   ├── react │   ├── react-dom │   ├── react-is │   └── scheduler ├── nr1.json ├── package-lock.json └── package.json Copy Nerdlet file structure A Nerdpack can contain one or more Nerdlets. A Nerdlet folder starts out with three default files, index.js, nr1.json, and styles.scss. Here is what the default files look like after being generated using the nr1 create command: index.js The JavaScript code of the Nerdlet. import React from 'react'; export default class MyAwesomeNerdpack extends React.Component { render() { return

Hello, my-awesome-nerdpack Nerdlet!

; } } Copy nr1.json The Nerdlet configuration file. { \"schemaType\": \"NERDLET\", \"id\": \"my-awesome-nerdpack-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\" } Copy Besides using the launcher as the access point for your application, you can also associate the application with a monitored entity to get it to appear in the entity explorer. To do this, add two additional fields to the config file of the first-launched Nerdlet: entities and actionCategory. In the following example, the Nerdlet has been associated with all Browser-monitored applications and will appear under the Monitor UI category : { \"schemaType\": \"NERDLET\", \"id\": \"my-nerdlet\", \"description\": \"Describe me\", \"displayName\": \"Custom Data\", \"entities\": [{ \"domain\": \"BROWSER\", \"type\": \"APPLICATION\" }], \"actionCategory\": \"monitor\" } Copy To see this application in the UI, you would go to the entity explorer, select Browser applications, and select a monitored application. styles.scss An empty SCSS file for styling your application. icon.png The launcher icon that appears on the Apps page in New Relic One when an application is deployed. Launcher file structure Launchers have their own file structure. Note that: A launcher is not required; as an alternative to using a launcher, you can associate your application with a monitored entity. An application can have more than one launcher, which might be desired for an application with multiple Nerdlets. After generating a launcher using the nr1 create command, its folder contains two files: nr1.json The configuration file. { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"MyAwesomeNerdpack\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy To connect a launcher to a Nerdlet, the rootNerdletId must match the id in the launched Nerdlet's nr1.json config file. For Nerdpacks with multiple Nerdlets, this needs to be done only for the first-launched Nerdlet. icon.png The icon displayed on the launcher for the app on the Apps page.", "type": "developer", "document_type": "page", - "info": "An overview of common commands you can use with the New Relic One CLI.", + "info": "An overview of the Nerdpack File Structure", "sections": [ - "New Relic One CLI common commands", - "Command details", - "nr1 help", - "See commands and get details", - "Usage", - "Arguments", - "Examples", - "nr1 update", - "Update your CLI", - "nr1 create", - "Create a new component", - "Options", - "nr1 profiles", - "Manage your profiles keychain", - "Commands", - "nr1 autocomplete", - "See autocomplete installation instructions", - "nr1 nrql", - "Query using NRQL" + "Nerdpack file structure", + "Generate Nerdpack components", + "Nerdlet file structure", + "index.js", + "nr1.json", + "styles.scss", + "icon.png", + "Launcher file structure" ], - "title": "New Relic One CLI common commands", + "title": "Nerdpack file structure", "popularity": 1, - "external_id": "503e515e1095418f8d19329517344ab209d143a4", + "tags": [ + "New Relic One CLI", + "nerdpack", + "file structure", + "nerdlets", + "launchers" + ], + "external_id": "c97bcbb0a2b3d32ac93b5b379a1933e7b4e00161", "image": "", - "url": "https://developer.newrelic.com/explore-docs/nr1-common/", - "published_at": "2020-08-18T02:06:04Z", - "updated_at": "2020-08-14T01:48:10Z", + "url": "https://developer.newrelic.com/explore-docs/nerdpack-file-structure/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:49:25Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.018395994, + "_score": 0.28511304, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic One CLI common commands", - "sections": "New Relic One CLI common commands", - "info": "An overview of common commands you can use with the New Relic One CLI.", - "body": "New Relic One CLI common commands Here's a list of common commands to get you started with the New Relic One CLI. You can click any command to see its usage options and additional details about the command. Command Description nr1 help Shows all nr1 commands or details about each command. nr1" + "title": "Nerdpack file structure", + "sections": "Nerdpack file structure", + "info": "An overview of the Nerdpack File Structure", + "tags": "New Relic One CLI", + "body": " How to link your application with a monitored entity For basic component definitions, see our component reference. Generate Nerdpack components There are two ways to generate a Nerdpack template: Generate a Nerdpack: Use the New Relic One CLI command nr1 create and select Nerdpack to create" }, - "id": "5f28bd6ae7b9d267996ade94" - } - ], - "/explore-docs/nr1-cli": [ + "id": "5efa989e196a671300766404" + }, { "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs in GitHub. Options --format string output text format [YAML, JSON, Text] (default \"JSON\") -h, --help help for newrelic --plain output compact text Copy Commands newrelic apm - Interact with New Relic APM newrelic completion - Generates shell completion functions newrelic config - Manage the configuration of the New Relic CLI newrelic documentation - Generate CLI documentation newrelic entity - Interact with New Relic entities newrelic nerdgraph - Execute GraphQL requests to the NerdGraph API newrelic nerdstorage - Read, write, and delete NerdStorage documents and collections. newrelic nrql - Commands for interacting with the New Relic Database newrelic profile - Manage the authentication profiles for this tool newrelic version - Show the version of the New Relic CLI newrelic workload - Interact with New Relic One workloads", "type": "developer", @@ -5937,69 +5727,103 @@ "external_id": "471ed214caaf80c70e14903ec71411e2a1c03888", "image": "", "url": "https://developer.newrelic.com/explore-docs/newrelic-cli/", - "published_at": "2020-08-18T02:11:50Z", + "published_at": "2020-08-19T01:49:36Z", "updated_at": "2020-08-14T01:47:12Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 1.0787585, + "_score": 0.25921336, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic CLI Reference", - "sections": "New Relic CLI commands", + "title": "New Relic CLI Reference", + "sections": "New Relic CLI commands", "info": "The command line tools for performing tasks against New Relic APIs", - "tags": "new relic cli", - "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs" + "tags": "new relic cli", + "body": "New Relic CLI Reference The New Relic CLI enables the integration of New Relic into your existing workflows. Be it fetching data from your laptop while troubleshooting an issue, or adding New Relic into your CI/CD pipeline. New Relic CLI commands Find details for the New Relic CLI command docs" }, "id": "5efa989ee7b9d2024b7bab97" }, { - "body": "Get started with the New Relic CLI 20 min Access the New Relic platform from the comfort of your terminal: you can use the New Relic CLI to manage entity tags, define workloads, record deployment markers, and much more. Our CLI has been designed for automating common tasks in your DevOps workflow. This guide walks you through the essentials of New Relic CLI, from install and configuration to basic usage. Before you begin For this guide you just need: Your New Relic personal API Key, which you can create from the Account settings of your New Relic account An instrumented application in your New Relic account Step 1 of 10 Install the New Relic CLI The New Relic CLI can be downloaded via Homebrew (macOS), Scoop (Windows), and Snapcraft (Linux). You can also download pre-built binaries for all platforms, including .deb and .rpm packages, and our Windows x64 .msi installer. Linux With Snapcraft installed, run: sudo snap install newrelic-cli macOS With Homebrew installed, run: brew install newrelic-cli Windows With Scoop installed, run: scoop bucket add newrelic-cli https://github.com/newrelic/newrelic-cli.git scoop install newrelic-cli Step 2 of 10 Create your New Relic CLI profile Now that you've installed the New Relic CLI, it's time to create your first profile. Profiles contain credentials and settings that you can apply to any CLI command, which is useful when switching between accounts. To create your first CLI profile, run the profiles add command. Note that you need to set the region of your New Relic account: use -r to set either us or eu (this is required). # Create the tutorial account for the US region newrelic profiles add -n tutorial --apiKey YOUR_NEW_RELIC_API_KEY -r YOUR_REGION # Set the profile as defaults newrelic profiles default -n tutorial Copy Step 3 of 10 Get your application details In this example, you are going to add tags to the application you've instrumented with New Relic. Tags are key-value pairs that can help you organize and filter your entities. An entity (for example, an application) can have a maximum of 100 key-value pairs tied to it. Before searching for your application using the New Relic CLI, write down or copy your Account ID and the name of your application in New Relic - you need both to find applications in the New Relic platform. Step 4 of 10 The New Relic CLI can retrieve your application details as a JSON object. To search for your APM application use the apm application search command. If you get an error, check that the account ID and application name you provided are correct. newrelic apm application search --accountId YOUR_ACCOUNT_ID --name NAME_OF_YOUR_APP Copy Step 5 of 10 If the account ID is valid, and the application name exists in your account, apm application search yields data similar to this example. When you've successfully searched for your application, look for the guid value. It's a unique identifier for your application. You should copy it or write it down. [ { accountId: YOUR_ACCOUNT_ID, applicationId: YOUR_APP_ID, domain: 'APM', entityType: 'APM_APPLICATION_ENTITY', guid: 'A_LONG_GUID', name: 'NAME_OF_YOUR_APP', permalink: 'https://one.newrelic.com/redirect/entity/A_LONG_GUID', reporting: true, type: 'APPLICATION', }, ]; Copy Step 6 of 10 Add a simple tag to your application Now that you have the GUID, you can point the New Relic CLI directly at your application. Adding a tag is the simplest way to try out the CLI capabilities (don't worry, tags can be deleted by using entity tags delete). Let's suppose that you want to add an environment tag to your application. Go ahead and add the dev:testing tag⁠ (or any other key-value pair) to your application using the entities tags create command. newrelic entity tags create --guid YOUR_APP_GUID --tag devkit:testing Copy Step 7 of 10 What if you want to add multiple tags? Tag sets come to the rescue! While tags are key-value pairs separated by colons, tag sets are comma separated lists of tags. For example: tag1:value1,tag2:value2 To add multiple tags at once to your application, modify and run the following snippet. newrelic entity tags create --guid YOUR_APP_GUID --tag tag1:test,tag2:test Copy Adding tags is an asynchronous operation: this means it could take a while for the tags to get created. Step 8 of 10 You've created and added some tags to your application, but how do you know they're there? You need to retrieve your application's tags. To retrieve your application's tags, use the entity tags get command. newrelic entity tags get --guid YOUR_APP_GUID All tags associated with your application are retrieved as a JSON array. [ { Key: 'tag1', Values: ['true'], }, { Key: 'tag2', Values: ['test'], }, { Key: 'tag3', Values: ['testing'], }, // ... ]; Copy Step 9 of 10 Bonus step: Create a deployment marker Deployments of applications often go wrong. Deployment markers are labels that, when attached to your application data, help you track deployments and troubleshoot what happened. To create a deployment marker, run the apm deployment create command using the same Application ID from your earlier search. newrelic apm deployment create --applicationId YOUR_APP_ID --revision $(git describe --tags --always) Copy Step 10 of 10 Notice that the JSON response includes the revision and timestamp of the deployment. This workflow could be built into a continuous integration or continuous deployment (CI/CD) system to help indicate changes in your application's behavior after deployments. Here is an example. { \"id\": 37075986, \"links\": { \"application\": 204261368 }, \"revision\": \"v1.2.4\", \"timestamp\": \"2020-03-04T15:11:44-08:00\", \"user\": \"Developer Toolkit Test Account\" } Copy Next steps Have a look at all the available commands. For example, you could create a New Relic workflow using workload create If you'd like to engage with other community members, visit our New Relic Explorers Hub page. We welcome feature requests or bug reports on GitHub.", + "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations, and fetch New Relic or third-party data. Components of the SDK SDK components are located in the Node module package named nr1, which you get when you install the NR1 CLI. The nr1 components can be divided into several categories: UI components Chart components Query and storage components Platform APIs UI components The UI components category of the SDK contains React UI components, including: Text components: These components provide basic font and heading elements. These include HeadingText and BlockText. Layout components: These components give you control over the layout, and help you build complex layout designs without having to deal with the CSS. Layout components include: Grid and GridItem: for organizing more complex, larger scale page content in rows and columns Stack and StackItem: for organizing simpler, smaller scale page content (in column or row) Tabs and TabsItem: group various related pieces of content into separate hideable sections List and ListItem: for providing a basic skeleton of virtualized lists Card, CardHeader and CardBody : used to group similar concepts and tasks together Form components: These components provide the basic building blocks to interact with the UI. These include Button, TextField, Dropdown and DropdownItem, Checkbox, RadioGroup, Radio, and Checkbox. Feedback components: These components are used to provide feedback to users about actions they have taken. These include: Spinnerand Toast. Overlaid components: These components are used to display contextual information and options in the form of an additional child view that appears above other content on screen when an action or event is triggered. They can either require user interaction (like modals), or be augmenting (like a tooltip). These include: Modal and Tooltip. Components suffixed with Item can only operate as direct children of that name without the suffix. For example: GridItem should only be found as a child of Grid. Chart components The Charts category of the SDK contains components representing different types of charts. The ChartGroup component helps a group of related charts share data and be aligned. Some chart components can perform NRQL queries on their own; some accept a customized set of data. Query and storage components The Query components category contains components for fetching and storing New Relic data. The main way to fetch data is with NerdGraph, our GraphQL endpoint. This can be queried using NerdGraphQuery. To simplify use of NerdGraph queries, we provide some components with pre-defined queries. For more on using NerdGraph, see Queries and mutations. We also provide storage for storing small data sets, such as configuration settings data, or user-specific data. For more on this, see NerdStorage. Platform APIs The Platform API components of the SDK enable your application to interact with different parts of the New Relic One platform, by reading and writing state from and to the URL, setting the configuration, etc. They can be divided into these categories: PlatformStateContext: provides read access to the platform URL state variables. Example: timeRange in the time picker. navigation: an object that allows programmatic manipulation of the navigation in New Relic One. Example: opening a new Nerdlet. NerdletStateContext: provides read access to the Nerdlet URL state variables. Example: an entityGuid in the entity explorer. nerdlet: an object that provides write access to the Nerdlet URL state.", "type": "developer", "document_type": "page", - "info": "Learn the essentials of the New Relic CLI, from install and configuration to basic usage.", + "info": "Intro to New Relic One API components", "sections": [ - "Get started with the New Relic CLI", + "Intro to New Relic One API components", + "Components of the SDK", + "UI components", + "Chart components", + "Query and storage components", + "Platform APIs" + ], + "title": "Intro to New Relic One API components", + "popularity": 1, + "tags": [ + "SDK components", + "New Relic One apps", + "UI components", + "chart components", + "query and storage components", + "Platform APIs" + ], + "external_id": "3620920c26bcd66c59c810dccb1200931b23b8c2", + "image": "", + "url": "https://developer.newrelic.com/explore-docs/intro-to-sdk/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-14T01:47:12Z", + "_index": "520d1d5d14cc8a32e600034b", + "_type": "520d1d5d14cc8a32e600034c", + "_score": 0.25619078, + "_version": null, + "_explanation": null, + "sort": null, + "highlight": { + "title": "Intro to New Relic One API components", + "sections": "Intro to New Relic One API components", + "info": "Intro to New Relic One API components", + "tags": "New Relic One apps", + "body": "Intro to New Relic One API components To help you build New Relic One applications, we provide you with the New Relic One SDK. Here we give you an introduction to the types of API calls and components in the SDK. The SDK provides everything you need to build your Nerdlets, create visualizations" + }, + "id": "5efa989e28ccbc4071307de5" + } + ], + "/explore-docs/nerdpack-file-structure": [ + { + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app, you might have some additional setup and configuration. This guide covers: Downloading the New Relic One CLI to build or modify apps Contribute content to this website Before you begin You must have: A github account account - While not strictly necessary for building apps, a GitHub account enables you to download and customize our open source apps, and contribute an open source project. A New Relic developer account - if you don't already have one, you can get a free trial account for developing New Relic applications. npm - If you've installed Node.js, then you already have npm, which is used to share, reuse, and update JavaScript code, and is necessary for working with React components that are the framework for New Relic apps and this website. Tip Use the New Relic One VSCode extension to build your apps. Prepare to build or modify apps Step 1 of 2 Download the CLI and API key On the Build New Relic One applications page, complete the Quick start steps. These six Quick start steps get you an API key for use with developing apps, and the New Relic One CLI, for building and deploying apps. At the end of the Quick start, you have a project consisting of the following: A Nerdpack - The package containing all the files required by your application. It contains two types of files that you customize to build your app: Nerdlets, and the launcher. One or more Nerdlet files - A specific UI view or window. A Nerdlet is a React JavaScript package that includes an index.js file, a stylesheet, and a JSON-format config file. It can contain any JS functionality (charts, interactive fields, tooltips, etc.). A launcher file: This is the basis for the launcher, which is used to open your application from New Relic One after you publish your app. Step 2 of 2 Start building If you're ready to code, cd to your Nerdpack and get started. If you want to learn more about building applications, try these step-by-step guides: Build a \"Hello, World!\" application shows how to create a little application, publish it to New Relic One, and share it with others by subscribing accounts to it. Map pageviews by region takes you through the steps to create one of our popular open source apps. You learn to add a custom query to an app and view it in a table, then add that data to a map. Contributing to developer.newrelic.com This site is open source, and we want your input. Create a pull request if you see a mistake you know how to fix. Drop us a GitHub issue if you see some content gaps you want us to work on. Or write up a whole new guide if you have one you'd like to share. Read on to learn how. Step 1 of 3 Fork the developer-website GithHub repo Forking the repo enables you to work on your own copy of the developer.newrelic.com files, and build the site locally. It also enables us to more easily manage incomimg pull requests. On the developer-website page in GitHub, select the Fork button on the top right of the page, choose the account you want to fork to, and wait a few seconds while the fork is created. Sync regularly to keep your fork up to date with changes and additions to the main branch upstream. Step 2 of 3 Make a feature or documentation request On any page, select the GitHub button at the top of the page, and then select the kind of change you want, and fill out the GitHub form. Step 3 of 3 Contribute a new guide Check out our contributors guidelines, which will walk you through the process.", + "type": "developer", + "document_type": "page", + "info": "Prepare to build apps and contribute to this site", + "sections": [ + "Set up your development environment", "Before you begin", - "Install the New Relic CLI", - "Linux", - "macOS", - "Windows", - "Create your New Relic CLI profile", - "Get your application details", - "Add a simple tag to your application", - "Bonus step: Create a deployment marker", - "Next steps" + "Tip", + "Prepare to build or modify apps", + "Start building" ], - "title": "Get started with the New Relic CLI", + "title": "Set up your development environment", "popularity": 1, "tags": [ - "api key", - "New Relic CLI", - "Tags", - "Entity", - "Deployment markers" + "developer account", + "API key", + "New Relic One CLI" ], - "external_id": "531f2f3985bf64bb0dc92a642445887095048882", + "external_id": "c45638a9cd548d1ffffc9f1c7708f115a92ae04a", "image": "", - "url": "https://developer.newrelic.com/automate-workflows/get-started-new-relic-cli/", - "published_at": "2020-08-18T02:06:05Z", - "updated_at": "2020-08-08T01:41:47Z", + "url": "https://developer.newrelic.com/build-apps/set-up-dev-env/", + "published_at": "2020-08-19T01:44:48Z", + "updated_at": "2020-08-19T01:44:47Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.5655756, + "_score": 24.128044, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Get started with the New Relic CLI", - "sections": "Get started with the New Relic CLI", - "info": "Learn the essentials of the New Relic CLI, from install and configuration to basic usage.", - "tags": "New Relic CLI", - "body": " that you've installed the New Relic CLI, it's time to create your first profile. Profiles contain credentials and settings that you can apply to any CLI command, which is useful when switching between accounts. To create your first CLI profile, run the profiles add command. Note that you need" + "tags": "New Relic One CLI", + "body": " On the Build New Relic One applications page, complete the Quick start steps. These six Quick start steps get you an API key for use with developing apps, and the New Relic One CLI, for building and deploying apps. At the end of the Quick start, you have a project consisting of the following: A Nerdpack" }, - "id": "5efa999c196a67c4e1766461" + "id": "5efa9973e7b9d242237bab39" }, { "body": "Create a \"Hello, World!\" application 15 min Here's how you can quickly build a \"Hello, World!\" application in New Relic One. In these steps, you create a local version of the New Relic One site where you can prototype your application. Then, when you're ready to share the application with others, you can publish it to New Relic One. See the video, which demonstrates the steps in this guide in five minutes. Before you begin To get started, make sure you have accounts in GitHub and New Relic. To develop projects, you need the New Relic One CLI (command line interface). If you haven't already installed it, do the following: Install Node.js. Complete all the steps in the CLI quick start. For additional details about setting up your environment, see Set up your development environment. Tip Use the NR1 VS Code extension to build your apps. Create a local version of the \"Hello, World!\" application The CLI allows you to run a local version of New Relic One. You can develop your application locally before you publish it in New Relic One. If you followed all the steps in the CLI quick start, you now have files under a new directory named after your nerdpack project. Here's how you edit those files to create a \"Hello, World!\" project: Step 1 of 9 Open a code editor and point it to the new directory named after your nerdpack project (for example, my-awesome-nerdpack). Your code editor displays two artifacts: launchers containing the homepage tile nerdlets containing your application code Step 2 of 9 Expand nerdlets in your code editor, and open index.js. Step 3 of 9 Change the default return message to \"Hello, World!\": import React from 'react'; // https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction export default class MyAwesomeNerdpackNerdletNerdlet extends React.Component { render() { return

\"Hello, World!\"

; } } Copy Step 4 of 9 As an optional step, you can add a custom launcher icon using any image file named icon.png. Replace the default icon.png file under launcher by dragging in your new image file: Step 5 of 9 To change the name of the launcher to something meaningful, in your code editor under launchers, open nr1.json. Step 6 of 9 Change the value for displayName to anything you want as the launcher label, and save the file: { \"schemaType\": \"LAUNCHER\", \"id\": \"my-awesome-nerdpack-launcher\", \"description\": \"Describe me\", \"displayName\": \"INSERT_YOUR_TILE_LABEL_HERE\", \"rootNerdletId\": \"my-awesome-nerdpack-nerdlet\" } Copy Step 7 of 9 To see your new changes locally, start the Node server with this command in your terminal: npm start Copy Step 8 of 9 Open a browser and go to https://one.newrelic.com/?nerdpacks=local (this url is also shown in the terminal). Step 9 of 9 When the browser opens, click Apps, and then in the Other apps section, click the new launcher for your application. Here's an example where we inserted a leaf icon: After you click the new launcher, your \"Hello, World!\" appears: Publish your application to New Relic Your colleagues can't see your local application, so when you are ready to share it, publish it to the New Relic One catalog. The catalog is where you can find any pre-existing custom applications, as well as any applications you create in your own organization. Step 1 of 4 Execute the following in your terminal: nr1 nerdpack:publish Copy Step 2 of 4 Close your local New Relic One development tab, and open New Relic One. Step 3 of 4 Click the Apps launcher. Step 4 of 4 Under New Relic One catalog, click the launcher for your new application. When your new application opens, notice that it doesn't display any helpful descriptive information. The next section shows you how to add descriptive metadata. Add details to describe your project Now that your new application is in the New Relic One catalog, you can add details that help users understand what your application does and how to use it. Step 1 of 5 Go to your project in the terminal and execute the following: nr1 create Copy Step 2 of 5 Select catalog, which creates a stub in your project under the catalog directory. Here's how the results might look in your code editor: Step 3 of 5 In the catalog directory of your project, add screenshots or various types of metadata to describe your project. For details about what you can add, see Add catalog metadata and screenshots. Step 4 of 5 After you add the screenshots and descriptions you want, execute the following to save your metadata to the catalog: nr1 catalog:submit Copy Step 5 of 5 Return to the catalog and refresh the page to see your new screenshots and metadata describing your project. Subscribe accounts to your application To make sure other users see your application in the catalog, you need to subscribe accounts to the application. Any user with the NerdPack Manager role can subscribe accounts to an application. Step 1 of 3 If you're not already displaying your application's description page in the browser, click the launcher for the application in the catalog under Your company applications. Step 2 of 3 On your application's description page, click Add this app. Step 3 of 3 Select the accounts you want to subscribe to the application, and then click Update accounts to save your selections. When you return to the Apps page, you'll see the launcher for your new application. Summary Now that you've completed the steps in this example, you learned the basic steps to: Create a local application. Publish the application to the New Relic One catalog so you can share it with your colleagues. Add details to the project in the catalog so users understand how to use it. Subscribe accounts to your application so other users can use it. Related information Create a local application. Publish the application to the New Relic One catalog so you can share it with your colleagues. Add details to the project in the catalog so users understand how to use it. Subscribe accounts to your application so other users can see it directly on their homepage.", @@ -6028,123 +5852,175 @@ "external_id": "aa427030169067481fb69a3560798265b6b52b7c", "image": "https://developer.newrelic.com/static/cb65a35ad6fa52f5245359ecd24158ff/9466d/hello-world-output-local.png", "url": "https://developer.newrelic.com/build-apps/build-hello-world-app/", - "published_at": "2020-08-18T02:09:27Z", + "published_at": "2020-08-19T01:44:48Z", "updated_at": "2020-08-18T01:45:02Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.55214196, + "_score": 15.668253, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Create a "Hello, World!" application", - "sections": "Publish your application to New Relic", - "info": "Build a "Hello, World!" app and publish it to New Relic One", - "tags": "Nerdpack file structure", - "body": ", you can publish it to New Relic One. See the video, which demonstrates the steps in this guide in five minutes. Before you begin To get started, make sure you have accounts in GitHub and New Relic. To develop projects, you need the New Relic One CLI (command line interface). If you haven't already" + "sections": "Publish your application to New Relic", + "info": "Build a "Hello, World!" app and publish it to New Relic One", + "tags": "Nerdpack file structure", + "body": "!" application The CLI allows you to run a local version of New Relic One. You can develop your application locally before you publish it in New Relic One. If you followed all the steps in the CLI quick start, you now have files under a new directory named after your nerdpack project. Here's how you edit" }, "id": "5efa9973196a67d16d76645c" }, { - "body": "New Relic One CLI Nerdpack commands To set up your Nerdpacks, use the commands below. You can click any command to see its usage options and additional details about the command. Command Description nr1 nerdpack:clone Clones a Nerdpack from a git repository. nr1 nerdpack:serve Serves your Nerdpack for testing and development purposes. nr1 nerdpack:uuid Shows or regenerates the UUID of a Nerdpack. nr1 nerdpack:publish Publishes your Nerdpack to New Relic. nr1 nerdpack:deploy Deploys a Nerdpack version to a specific channel. nr1 nerdpack:undeploy Undeploys a Nerdpack version from a specific channel. Command details nr1 nerdpack:clone Clone an existing Nerdpack Duplicates an existing Nerdpack onto your local computer. You can clone an open source Nerdpack from our Open Source GitHub repositories. After choosing a git repository, this command performs the following actions so that you can start using the Nerdpack: Clones the repository. Sets the repository as remote upstream. Installs all of its dependencies (using npm). Generates a new UUID using your profile, and commits it. Usage $ nr1 nerdpack:clone OPTION Options -r, --repo=REPO Repository location (either an HTTPS or SSH path). (Required) -p, --path=PATH Determines the directory to clone to (defaults to the repository name). -f, --force Replaces destination folder if it exists. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output. nr1 nerdpack:serve Serve your Nerdpack locally Launches a server with your Nerdpack locally on the New Relic One platform, where it can be tested live. To learn more about working with apps locally, see our guide on how to serve, publish, and deploy documentation. Usage $ nr1 nerdpack:serve Options --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output. nr1 nerdpack:uuid Get your Nerdpack's UUID Prints the UUID (Universal Unique ID) of your Nerdpack, by default. The UUID determines what data the Nerdpack can access and who can subscribe to the Nerdpack. To deploy a Nerdpack you didn't make, you'll have to assign it a new UUID by using the -g or --generate option. For more details, see our GitHub workshop on GitHub. Usage $ nr1 nerdpack:uuid Options --profile=PROFILE The authentication profile you want to use. -f, --force If present, it will override the existing UUID without asking. -g, --generate Generates a new UUID if not available. --verbose Adds extra information to the output. nr1 nerdpack:publish Publish your Nerdpack Publishes your Nerdpack to New Relic. Please note: If no additional parameters are passed in, this command will automatically deploy the Nerdpack onto the DEV channel. If you want to specify your own list of deploy channels, add the --channel option. For example, $ nr1 nerdpack:publish --channel BETA --channel STABLE. If you want to disable this behavior, add -D or --skip-deploy to the command. Then, you can use nr1 nerdpack:deploy to perform a deploy manually. For more on publishing and deploying, see Deploy to New Relic One. Usage $ nr1 nerdpack:publish Options -B, --skip-build Skips the previous build process. -D, --skip-deploy Skips the following deploy process. -c, --channel=DEV/BETA/STABLE Specifies the channel to deploys to. [default: STABLE] -f, --force Forces the publish, overriding any existing version in the registry. --dry-run Undergoes publishing process without actually publishing anything. --extra-metadata-path=extra-metadata-path Specifies a json file .path with extra metadata. [default: extra-metadata.json] --prerelease=STRING The value you enter will be appended to the current version of generated files. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output. nr1 nerdpack:deploy Deploy your Nerdpack to a channel Deploys a Nerdpack version to a specific channel (DEV, BETA, or STABLE). A channel can only have one Nerdpack version deployed to it at one time. If a channel has an existing Nerdpack associated with it, deploying a new Nerdpack version to that channel will undeploy the previous one. For more on publishing and deploying, see Deploy to New Relic One. Usage $ nr1 nerdpack:deploy OPTION Options -c, --channel=DEV/BETA/STABLE Specifies the channel to deploy to. (required) -i, --nerdpack-id=NERDPACK_ID Specifies the Nerdpack to deploy. By default, the command will use the one in package.json. --from-version=VERSION Specifies which version to deploy. By default, the command will use the one in package.json. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output. nr1 nerdpack:undeploy Undeploy your Nerdpack Undeploys a Nerdpack version from a specific channel (for example, DEV, BETA, or STABLE). Usage $ nr1 nerdpack:undeploy OPTION Options -c, --channel=DEV/BETA/STABLE Specifies the channel to undeploy from. (required) -i, --nerdpack-id=NERDPACK_ID Specifies the Nerdpack to deploy. By default, the command will use the one in package.json. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output.", + "body": "New Relic One CLI reference To build a New Relic One app, you must install the New Relic One CLI. The CLI helps you build, publish, and manage your New Relic app. We provide a variety of tools for building apps, including the New Relic One CLI (command line interface). This page explains how to use CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build your own application launcher and follow the quick start instructions. The quick start automatically generates an API key for the account you select, and gives you the pre-populated commands to create a profile, generate your first \"Hello World\" app, and serve it locally. Tip Use the NR1 VS Code extension to build your apps. New Relic One CLI Commands This table provides descriptions for the New Relic One commands. For more context, including usage and option details, click any individual command or the command category. For details on user permissions, see Authentication and permissions. For more on how to serve and publish your application, see our guide on Deploying your New Relic One app. Get started nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). Configure your CLI preferences nr1 config:set Sets a specific configuration value. nr1 config:get Shows a specific configuration. nr1 config:list Lists your configuration choices. nr1 config:delete Removes the value of a specific configuration. Set up your Nerdpacks nr1 nerdpack:clone Clones an open source Nerdpack from our GitHub repository. nr1 nerdpack:serve Serves your Nerdpack for testing and development purposes. nr1 nerdpack:uuid Shows or regenerates the UUID of a Nerdpack. nr1 nerdpack:publish Publishes your Nerdpack to New Relic. nr1 nerdpack:deploy Deploys a Nerdpack version to a specific channel. nr1 nerdpack:undeploy Undeploys a Nerdpack version from a specific channel. Manage your Nerdpack subscriptions nr1 subscription:set Subscribes your account to a Nerdpack and channel. nr1 subscription:list Lists all the Nerdpacks your account is subscribed to. nr1 subscription:unset Unsubscribes your account from a Nerdpack. Install and manage plugins nr1 plugins:install Installs a plugin into the CLI. nr1 plugins:link Links a plugin into the CLI for development. nr1 plugins:update Updates your installed plugins. nr1 plugins:uninstall Removes a plugin from the CLI. Manage catalog information nr1 catalog:info Shows the Nerdpack info stored in the catalog. nr1 catalog:submit Gathers and submits the catalog info on the current folder.", + "type": "developer", + "document_type": "page", + "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", + "sections": [ + "New Relic One CLI reference", + "Installing the New Relic One CLI", + "Tip", + "New Relic One CLI Commands", + "Get started", + "Configure your CLI preferences", + "Set up your Nerdpacks", + "Manage your Nerdpack subscriptions", + "Install and manage plugins", + "Manage catalog information" + ], + "title": "New Relic One CLI reference", + "popularity": 1, + "tags": [ + "New Relic One app", + "nerdpack commands" + ], + "external_id": "858339a44ead21c83257778ce60b4c352cd30d3b", + "image": "https://developer.newrelic.com/static/2c6d337608b38a3312b4fc740afe6167/7272b/developercenter.png", + "url": "https://developer.newrelic.com/explore-docs/nr1-cli/", + "published_at": "2020-08-19T01:50:40Z", + "updated_at": "2020-08-18T01:50:36Z", + "_index": "520d1d5d14cc8a32e600034b", + "_type": "520d1d5d14cc8a32e600034c", + "_score": 11.220428, + "_version": null, + "_explanation": null, + "sort": null, + "highlight": { + "title": "New Relic One CLI reference", + "sections": "New Relic One CLI reference", + "info": "An overview of the CLI to help you build, deploy, and manage New Relic apps.", + "tags": "New Relic One app", + "body": " CLI commands to: Generate Nerdpack/Nerdlet templates Locally serve Nerdpacks (when developing) Publish and deploy Subscribe to Nerdpacks Add screenshots and metadata to the catalog Installing the New Relic One CLI In New Relic, click Apps and then in the New Relic One catalog area, click the Build" + }, + "id": "5efa989e28ccbc535a307dd0" + }, + { + "body": "Intro to NerdStorage 30 min To help you build a New Relic One application, we provide you with the New Relic One SDK. On this page, you’ll learn how to use NerdStorage SDK components. Use NerdStorage in your apps NerdStorage is used to store and retrieve simple sets of data, including users's configuration settings and preferences (like favorites), or any other small data sets. This storage is unique per Nerdpack, and can't be shared with any other Nerdpack. NerdStorage can be classified into three categories: User storage: Data that is attached to a particular user. If you’re authenticated as the user the data is attached to, you can read it and write it. Account storage: Data that is attached to a particular account. If you’re authenticated and can access the account, you can read and write to account scoped NerdStorage. Visibility of account data is also determined by master/subaccount rules: If a user has access to the master account, then they also have access to data in all subaccounts. Entity storage: Data that is attached to a particular entity. If you can see the corresponding entity, you can read and write data on that entity. Data model You can imagine NerdStorage as a nested key-value map. Data is inside documents, which are nested inside collections: { 'YourNerdpackUuid': { 'collection-1': { 'document-1-of-collection-1': '{\"lastNumber\": 42, \"another\": [1]}', 'document-2-of-collection-1': '\"userToken\"', // ... }, 'another-collection': { 'fruits': '[\"pear\", \"apple\"]', // ... }, // ... }, } Copy Each NerdStorage level has different properties and purpose: Collections: From a Nerdpack, you can create multiple collections by naming each of them. Inside a collection you can put one or more documents. Think of a collection as key-value storage, where each document is a key-value pair. Documents: A document is formed by an identifier (documentId) and a set of data associated with it. Data associated with a document: NerdStorage accepts any sort of data associated to a documentId. Query and mutation components that are provided work by serializing and deserializing JSON. Limits A Nerdpack can hold up to 1,000 collections and 10,000 documents, plus storage type. A collection can hold up to 1,000 documents, plus storage type. Each document can have a maximum length of 64 KiB when serialized. Data access To access NerdStorage, you can run NerdGraph queries, or use the provided storage queries. Depending on which storage you want to access, you can use a different set of SDK components: User access: UserStorageQuery and UserStorageMutation Account access: AccountStorageQuery and AccountStorageMutation Entity access: EntityStorageQuery and EntityStorageMutation Each of these components can operate declaratively (for example, as part of your React rendering methods) or imperatively (by using the static methods for query and mutation). For more information on this, see Data querying and mutations. Permissions for working with NerdStorage In order to persist changes on NerdStorage, such as creating, updating, and deleting account and entity storage, you must have a user role with permission to persist changes.", "type": "developer", "document_type": "page", - "info": "An overview of the CLI commands you can use to set up your New Relic One Nerdpacks.", + "info": "Intro to NerdStorage on New Relic One", "sections": [ - "New Relic One CLI Nerdpack commands", - "Command details", - "nr1 nerdpack:clone", - "Clone an existing Nerdpack", - "Usage", - "Options", - "nr1 nerdpack:serve", - "Serve your Nerdpack locally", - "nr1 nerdpack:uuid", - "Get your Nerdpack's UUID", - "nr1 nerdpack:publish", - "Publish your Nerdpack", - "nr1 nerdpack:deploy", - "Deploy your Nerdpack to a channel", - "nr1 nerdpack:undeploy", - "Undeploy your Nerdpack" - ], - "title": "New Relic One CLI Nerdpack commands", - "popularity": 1, - "external_id": "7c1050a6a8624664b90c15111f7c72e96b2fbe17", + "Intro to NerdStorage", + "Use NerdStorage in your apps", + "Data model", + "Limits", + "Data access", + "Permissions for working with NerdStorage" + ], + "title": "Intro to NerdStorage", + "popularity": 1, + "tags": [ + "nerdstorage", + "nerdstorage components", + "new relic one apps", + "data access" + ], + "external_id": "709e06c25376d98b2191ca369b4d139e5084bd62", "image": "", - "url": "https://developer.newrelic.com/explore-docs/nr1-nerdpack/", - "published_at": "2020-08-18T02:11:48Z", - "updated_at": "2020-08-04T01:44:10Z", + "url": "https://developer.newrelic.com/explore-docs/nerdstorage/", + "published_at": "2020-08-19T01:49:36Z", + "updated_at": "2020-08-14T01:50:34Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.47135732, + "_score": 2.6134825, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic One CLI Nerdpack commands", - "sections": "New Relic One CLI Nerdpack commands", - "info": "An overview of the CLI commands you can use to set up your New Relic One Nerdpacks.", - "body": "New Relic One CLI Nerdpack commands To set up your Nerdpacks, use the commands below. You can click any command to see its usage options and additional details about the command. Command Description nr1 nerdpack:clone Clones a Nerdpack from a git repository. nr1 nerdpack:serve Serves your Nerdpack" + "info": "Intro to NerdStorage on New Relic One", + "tags": "new relic one apps", + "body": "Intro to NerdStorage 30 min To help you build a New Relic One application, we provide you with the New Relic One SDK. On this page, you’ll learn how to use NerdStorage SDK components. Use NerdStorage in your apps NerdStorage is used to store and retrieve simple sets of data, including users's" }, - "id": "5f28bd6a64441f9817b11a38" + "id": "5efa989ee7b9d2048e7bab92" }, { - "body": "New Relic One CLI common commands Here's a list of common commands to get you started with the New Relic One CLI. You can click any command to see its usage options and additional details about the command. Command Description nr1 help Shows all nr1 commands or details about each command. nr1 update Updates to the latest version of the CLI. nr1 create Creates a new component from a template (Nerdpack, Nerdlet, launcher, or catalog). nr1 profiles Manages the profiles you use to run CLI commands. nr1 autocomplete Displays autocomplete installation instructions. nr1 nrql Fetches data using NRQL (New Relic query language). See our other New Relic One CLI docs for commands specific to Nerdpack set-up, Nerdpack subscriptions, CLI configuration, plugins, or catalogs. Command details nr1 help See commands and get details Shows all nr1 commands by default. To get details about a specific command, run nr1 help COMMAND_NAME. Usage $ nr1 help Arguments COMMAND_NAME The name of a particular command. Examples $ nr1 help $ nr1 help nerdpack $ nr1 help nerdpack:deploy nr1 update Update your CLI Updates to latest version of the CLI. You can specify which channel to update if you'd like. Usage $ nr1 update Arguments CHANNEL The name of a particular channel. Examples $ nr1 update $ nr1 update somechannel nr1 create Create a new component Creates a new component from our template (either a Nerdpack, Nerdlet, launcher, or catalog). The CLI will walk you through this process. To learn more about Nerdpacks and their file structure, see Nerdpack file structure. For more on how to set up your Nerdpacks, see our Nerdpack CLI commands. Usage $ nr1 create Options -f, --force If present, overrides existing files without asking. -n, --name=NAME Names the component. -t, --type=TYPE Specifies the component type. --path=PATH The route to the component. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output. nr1 profiles Manage your profiles keychain Displays a list of commands you can use to manage your profiles. Run nr1 help profiles:COMMAND for more on their specific usages. You can have more than one profile, which is helpful for executing commands on multiple New Relic accounts. To learn more about setting up profiles, see our Github workshop. Usage $ nr1 profiles:COMMAND Commands profiles:add Adds a new profile to your profiles keychain. profiles:default Chooses which profile should be default. profiles:list Lists the profiles on your keychain. profiles:remove Removes a profile from your keychain. nr1 autocomplete See autocomplete installation instructions Displays the autocomplete installation instructions. By default, the command displays the autocomplete instructions for zsh. If you want instructions for bash, run nr1 autocomplete bash. Usage $ nr1 autocomplete Arguments SHELL The shell type you want instructions for. Options -r, --refresh-cache Refreshes cache (ignores displaying instructions). Examples $ nr1 autocomplete $ nr1 autocomplete zsh $ nr1 autocomplete bash $ nr1 autocomplete --refresh-cache nr1 nrql Query using NRQL Fetches data from databases using a NRQL query. To learn more about NRQL and how to use it, see our NRQL docs. Usage $ nr1 nrql OPTION ... Options -a, --account=ACCOUNT The user account ID. required -q, --query=QUERY The NRQL query to run. required -u, --ugly Displays the content without tabs or spaces. --profile=PROFILE The authentication profile you want to use. --verbose Adds extra information to the output.", + "body": "Map page views by region in a custom app 30 min New Relic has powerful and flexible tools for building custom apps and populating them with data. This guide shows you how to build a custom app and populate it with page view data using New Relic's Query Language (NRQL - pronounced 'nurkle'). Then you make your data interactive. And last, if you have a little more time and want to install a third-party React library, you can display the page view data you collect on a map of the world. In this guide, you build an app to display page view data in two ways: In a table On a map Please review the Before you begin section to make sure you have everything you need and don't get stuck halfway through. Before you begin In order to get the most out of this guide, you must have: A New Relic developer account, API key, and the command-line tool. If you don't have these yet, see the steps in Setting up your development environment New Relic Browser page view data to populate the app. Without this data, you won't be able to complete this guide. To add your data to a world map in the second half of the guide: npm, which you'll use during this section of the guide to install Leaflet, a third-party JavaScript React library used to build interactive maps. If you're new to React and npm, you can go here to install Node.js and npm. New Relic terminology The following are some terms used in this guide: New Relic application: The finished product where data is rendered in New Relic One. This might look like a series of interactive charts or a map of the world. Nerdpack: New Relic's standard collection of JavaScript, JSON, CSS, and other files that control the functionality and look of your application. For more information, see Nerdpack file structure. Launcher: The button on New Relic One that launches your application. Nerdlets: New Relic React components used to build your application. The three default files are index.js, nr1.json, and styles.scss, but you can customize and add your own. Build a custom app with a table chart Step 1 of 8 Query your browser data Use Query builder to write a NRQL query to see your page view data, as follows. On New Relic One, select Query your data (in the top right corner). That puts you in NRQL mode. You'll use NRQL to test your query before dropping the data into your table. Copy and paste this query into a clear query field, and then select Run. FROM PageView SELECT count(*), average(duration) WHERE appName = 'WebPortal' FACET countryCode, regionCode SINCE 1 week ago LIMIT 1000 Copy If you have PageView data, this query shows a week of average page views broken down by country and limited to a thousand items. The table will be full width and use the \"chart\" class defined in the CSS. If you don't have any results at this point, ensure your query doesn't have any errors. If your query is correct, you might not have the Browser agent installed. Step 2 of 8 Create and serve a new Nerdpack To get started, create a new Nerdpack, and serve it up to New Relic from your local development environment: Create a new Nerdpack for this app: nr1 create --type nerdpack --name pageviews-app Copy Serve the project up to New Relic: cd pageviews-app && nr1 nerdpack:serve Copy Step 3 of 8 Review your app files and view your app locally Navigate to your pageviews-app to see how it's structured. It contains a launcher folder, where you can customize the description and icon that will be displayed on the app's launcher in New Relic One. It also contains nerdlets, which each contain three default files: index.js, nr1.json, and styles.scss. You'll edit some of these files as part of this guide. For more information, see Nerdpack file structure. Now in your browser, open https://one.newrelic.com/?nerdpacks=local, and then click Apps to see the pageview-apps Nerdpack that you served up. When you select the launcher, you see a Hello message. Step 4 of 8 Hard code your account ID For the purposes of this exercise and for your convenience, hard code your account ID. In the pageview-app-nerdlet directory, in the index.js file, add this code between the import and export lines. (Read about finding your account ID here). const accountId = [Replace with your account ID]; Copy Step 5 of 8 Import the TableChart component To show your data in a table chart, import the TableChart component from New Relic One. To do so, in index.js, add this code under import React. import { TableChart } from `nr1`; Copy Step 6 of 8 Add a table with a single row To add a table with a single row, in the index.js file, replace this line: return

Hello, pageview-app-nerdlet Nerdlet!

; Copy with this export code: export default class PageViewApp extends React.Component { render() { return (
); } } Copy Step 7 of 8 Customize the look of your table (optional) You can use standard CSS to customize the look of your components. In the styles.scss file, add this CSS. Feel free to customize this CSS to your taste. .container { width: 100%; height: 99vh; display: flex; flex-direction: column; .row { margin: 10px; display: flex; flex-direction: row; } .chart { height: 250px; } } Copy Step 8 of 8 Get your data into that table Now that you've got a table, you can drop a TableChart populated with data from the NRQL query you wrote at the very beginning of this guide. Put this code into the row div. ; Copy Go to New Relic One and click your app to see your data in the table. (You might need to serve your app to New Relic again.) Congratulations! You made your app! Continue on to make it interactive and show your data on a map. Make your app interactive with a text field Once you confirm that data is getting to New Relic from your app, you can start customizing it and making it interactive. To do this, you add a text field to filter your data. Later, you use a third-party library called Leaflet to show that data on a world map. Step 1 of 3 Import the TextField component Like you did with the TableChart component, you need to import a TextField component from New Relic One. import { TextField } from 'nr1'; Copy Step 2 of 3 Add a row for your text field To add a text field filter above the table, put this code above the TableChart div. The text field will have a default value of \"US\".
{ this.setState({ countryCode: event.target.value }); }} />
; Copy Step 3 of 3 Build the text field object Above the render() function, add a constructor to build the text field object. constructor(props) { super(props); this.state = { countryCode: null } } Copy Then, add a constructor to your render() function. Above return, add: const { countryCode } = this.state; Copy Now add countryCode to your table chart query. ; Copy Reload your app to try out the text field. Get your data on a map To create the map, you use npm to install Leaflet. Step 1 of 9 Install Leaflet In your terminal, type: npm install --save leaflet react-leaflet Copy In your nerdlets styles.scss file, import the Leaflet CSS: @import `~leaflet/dist/leaflet.css`; Copy While you're in styles.scss, fix the width and height of your map: .containerMap { width: 100%; z-index: 0; height: 70vh; } Copy Step 2 of 9 Add a webpack config file for Leaflet Add a webpack configuration file .extended-webpackrc.js to the top-level folder in your nerdpack. This supports your use of map tiling information data from Leaflet. module.exports = { module: { rules: [ { test: /\\.(png|jpe?g|gif)$/, use: [ { loader: 'file-loader', options: {}, }, { loader: 'url-loader', options: { limit: 25000 }, }, ], }, ], }, }; Copy Step 3 of 9 Import modules from Leaflet In index.js, import modules from Leaflet. import { Map, CircleMarker, TileLayer } from 'react-leaflet'; Copy Step 4 of 9 Import additional modules from New Relic One You need several more modules from New Relic One to make the Leaflet map work well. Import them with this code: import { NerdGraphQuery, Spinner, Button, BlockText } from 'nr1'; Copy NerdGraphQuery lets you make multiple NRQL queries at once and is what will populate the map with data. Spinner adds a loading spinner. Button gives you button components. BlockText give you block text components. Step 5 of 9 Get data for the map Using latitude and longitude with country codes, you can put New Relic data on a map. mapData() { const { countryCode } = this.state; const query = `{ actor { account(id: 1606862) { mapData: nrql(query: \"SELECT count(*) as x, average(duration) as y, sum(asnLatitude)/count(*) as lat, sum(asnLongitude)/count(*) as lng FROM PageView FACET regionCode, countryCode WHERE appName = 'WebPortal' ${countryCode ? ` WHERE countryCode like '%${countryCode}%' ` : ''} LIMIT 1000 \") { results nrql } } } }`; return query; }; Copy Step 6 of 9 Customize the map marker colors Above the mapData function, add this code to customize the map marker colors. getMarkerColor(measure, apdexTarget = 1.7) { if (measure <= apdexTarget) { return '#11A600'; } else if (measure >= apdexTarget && measure <= apdexTarget * 4) { return '#FFD966'; } else { return '#BF0016'; } }; Copy Feel free to change the HTML color code values to your taste. In this example, #11A600 is green, #FFD966 is sort of yellow, and #BF0016 is red. Step 7 of 9 Set your map's default center point Set a default center point for your map using latitude and longitude. const defaultMapCenter = [10.5731, -7.5898]; Copy Step 8 of 9 Add a row for your map Between the text field row and the table chart row, insert a new row for the map content using NerdGraphQuery.
{({ loading, error, data }) => { if (loading) { return ; } if (error) { return 'Error'; } const { results } = data.actor.account.mapData; console.debug(results); return 'Hello'; }}
; Copy Reload your application in New Relic One to test that it works. Step 9 of 9 Replace \"Hello\" with the Leaflet code Replace return \"Hello\"; with: return ( {results.map((pt, i) => { const center = [pt.lat, pt.lng]; return ( { alert(JSON.stringify(pt)); }} /> ); })} ); Copy This code creates a world map centered on the latitude and longitude you chose using OpenStreetMap data and your marker colors. Reload your app to see the pageview data on the map!", "type": "developer", "document_type": "page", - "info": "An overview of common commands you can use with the New Relic One CLI.", + "info": "Build a New Relic app showing page view data on a world map.", "sections": [ - "New Relic One CLI common commands", - "Command details", - "nr1 help", - "See commands and get details", - "Usage", - "Arguments", - "Examples", - "nr1 update", - "Update your CLI", - "nr1 create", - "Create a new component", - "Options", - "nr1 profiles", - "Manage your profiles keychain", - "Commands", - "nr1 autocomplete", - "See autocomplete installation instructions", - "nr1 nrql", - "Query using NRQL" + "Map page views by region in a custom app", + "Before you begin", + "New Relic terminology", + "Build a custom app with a table chart", + "Query your browser data", + "Create and serve a new Nerdpack", + "Review your app files and view your app locally", + "Hard code your account ID", + "Import the TableChart component", + "Add a table with a single row", + "Customize the look of your table (optional)", + "Get your data into that table", + "Make your app interactive with a text field", + "Import the TextField component", + "Add a row for your text field", + "Build the text field object", + "Get your data on a map", + "Install Leaflet", + "Add a webpack config file for Leaflet", + "Import modules from Leaflet", + "Import additional modules from New Relic One", + "Get data for the map", + "Customize the map marker colors", + "Set your map's default center point", + "Add a row for your map", + "Replace \"Hello\" with the Leaflet code" ], - "title": "New Relic One CLI common commands", + "title": "Map page views by region in a custom app", "popularity": 1, - "external_id": "503e515e1095418f8d19329517344ab209d143a4", - "image": "", - "url": "https://developer.newrelic.com/explore-docs/nr1-common/", - "published_at": "2020-08-18T02:06:04Z", - "updated_at": "2020-08-14T01:48:10Z", + "tags": [ + "custom app", + "map", + "page views", + "region", + "nerdpack" + ], + "external_id": "6ff5d696556512bb8d8b33fb31732f22bab455cb", + "image": "https://developer.newrelic.com/static/d87a72e8ee14c52fdfcb91895567d268/0086b/pageview.png", + "url": "https://developer.newrelic.com/build-apps/map-pageviews-by-region/", + "published_at": "2020-08-19T01:48:30Z", + "updated_at": "2020-08-14T01:45:09Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.16341951, + "_score": 1.7384683, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "New Relic One CLI common commands", - "sections": "New Relic One CLI common commands", - "info": "An overview of common commands you can use with the New Relic One CLI.", - "body": " (New Relic query language). See our other New Relic One CLI docs for commands specific to Nerdpack set-up, Nerdpack subscriptions, CLI configuration, plugins, or catalogs. Command details nr1 help See commands and get details Shows all nr1 commands by default. To get details about a specific command" + "sections": "Import additional modules from New Relic One", + "info": "Build a New Relic app showing page view data on a world map.", + "tags": "nerdpack", + "body": " look like a series of interactive charts or a map of the world. Nerdpack: New Relic's standard collection of JavaScript, JSON, CSS, and other files that control the functionality and look of your application. For more information, see Nerdpack file structure. Launcher: The button on New Relic One" }, - "id": "5f28bd6ae7b9d267996ade94" + "id": "5efa993c196a67066b766469" } ], "/collect-data/query-data-nrql": [ { - "body": "Add custom attributes to your New Relic data There are countless filters and pivots you might want to apply to your data. By adding custom attributes to your data, you can see beyond your code and analyze your business in-depth. A common pattern when using custom attributes is to capture user information, e.g. name, id, email, etc. This allows you to 'link' your operational data with your business data. For example, if you have the user information, you tie together your service desk and CRM data with the operational data in New Relic. Step 1 of 2 You can add a userid custom attribute to your APM-reported data (Transaction and TransactionError events) with the opensource Java APM agent's API. NewRelic.addCustomParameter('userid', userId); Copy Step 2 of 2 Once added, you can run a NRQL query that uses the 'userid' custom attribute. Once you have added a custom attribute like 'userid', you can use it to filter and facet your NRQL queries. -- Get a count of errors experienced by a single filtered userid faceted by date and error message SELECT count(*) FROM TransactionError WHERE userid = '1401961100' FACET dateOf(timestamp), `error.message` SINCE 1 week ago Copy", + "body": "Add custom attributes to your New Relic data There are countless filters and pivots you might want to apply to your data. By adding custom attributes to your data, you can see beyond your code and analyze your business in-depth. A common pattern when using custom attributes is to capture user information, such as name, ID, email, and more. This allows you to 'link' your operational data with your business data. For example, if you have the user information, you tie together your service desk and CRM data with the operational data in New Relic. Create a custom attribute Step 1 of 2 Use the open source Java APM agent's API to add a userid custom attribute to your APM-reported data, Transaction and TransactionError events. NewRelic.addCustomParameter('userid', userId); Copy Step 2 of 2 After you add the userid custom attribute, run a NRQL query that uses it. As the query shows, the userid attribute enables you to filter and facet your NRQL queries. -- Get a count of errors experienced by a single filtered userid faceted by date and error message SELECT count(*) FROM TransactionError WHERE userid = '1401961100' FACET dateOf(timestamp), `error.message` SINCE 1 week ago Copy", "type": "developer", "document_type": "page", "info": "Add metadata for more detailed analysis", "sections": [ - "Add custom attributes to your New Relic data" + "Add custom attributes to your New Relic data", + "Create a custom attribute" ], "title": "Add custom attributes to your New Relic data", "popularity": 1, @@ -6155,11 +6031,11 @@ "external_id": "b7c3eb72c1c275d97df9c6232d50bd675ac2e39a", "image": "https://developer.newrelic.com/static/2dd8a32b57677b2e8d2497147d8ebc26/2663f/custom-attribute-query.png", "url": "https://developer.newrelic.com/collect-data/custom-attributes/", - "published_at": "2020-08-18T02:08:12Z", - "updated_at": "2020-08-04T01:39:41Z", + "published_at": "2020-08-19T01:44:48Z", + "updated_at": "2020-08-19T01:44:47Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.7941898, + "_score": 1.3052268, "_version": null, "_explanation": null, "sort": null, @@ -6167,10 +6043,50 @@ "title": "Add custom attributes to your New Relic data", "sections": "Add custom attributes to your New Relic data", "tags": "NRQL", - "body": " APM-reported data (Transaction and TransactionError events) with the opensource Java APM agent's API. NewRelic.addCustomParameter('userid', userId); Copy Step 2 of 2 Once added, you can run a NRQL query that uses the 'userid' custom attribute. Once you have added a custom attribute like 'userid" + "body": " the open source Java APM agent's API to add a userid custom attribute to your APM-reported data, Transaction and TransactionError events. NewRelic.addCustomParameter('userid', userId); Copy Step 2 of 2 After you add the userid custom attribute, run a NRQL query that uses it. As the query shows, the userid" }, "id": "5efa999de7b9d2985d7bab67" }, + { + "body": "Set up New Relic using the Kubernetes operator 20 min Kubernetes is an open-source system for automating deployment, scaling, and management of containerized applications. You can use it to provision all kinds of infrastructure and services, including New Relic entities. In this guide you'll learn how to set up New Relic for the first time with the official New Relic Kubernetes operator. More specifically, you'll provision an alert policy with NRQL conditions in your New Relic account using Kubernetes. Before you begin This walkthrough assumes you’ve already deployed a Kubernetes cluster. You could even create a local cluster on your machine with kind. To use this guide, you should have some basic knowledge of both New Relic and Kubernetes. To complete the full exercise, you’ll need to: Deploy a New Relic agent if you haven't done so yet. Install New Relic for your application. Install kubectl and point it at the correct cluster; this determines the cluster where you’ll install the New Relic operator. Install kustomize. Step 1 of 3 Installing the operator on your Kubernetes cluster First, install cert-manager, which automatically provisions and manages TLS certificates in Kubernetes. kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.15.0/cert-manager.yaml Copy Next, install the Kubernetes operator. kustomize build https://github.com/newrelic/newrelic-kubernetes-operator/config/default | kubectl apply -f - Copy To confirm the installation was successful, run a few kubectl commands to check the status of the Kubernetes operator. Ensure the Kubernetes operator's namespace, newrelic-kubernetes-operator-system, has been applied: kubectl get namespaces Copy The output should be similar to the following, which includes the Kubernetes operator's namespace, newrelic-kubernetes-operator-system: NAME STATUS AGE cert-manager Active 4m35s default Active 20m kube-node-lease Active 20m kube-public Active 20m kube-system Active 20m newrelic-kubernetes-operator-system Active 3m48s Copy Now, make sure the Kubernetes operator's controller manager is running: Note: Don't forget to include the --namespace (shorthand -n) option when running kubectl get pods to ensure you're inspecting resources within the correct namespace. kubectl get pods --namespace newrelic-kubernetes-operator-system Copy You should see output similar to the following: NAME READY STATUS RESTARTS AGE newrelic-kubernetes-operator-controller-manager-7b9c64f58crwg9j 2/2 Running 0 157m Copy If your output is similar to the example shown, you’re ready for the next step. If you don’t see a pod named newrelic-kubernetes-operator-controller-manager-, double check your Kubernetes configuration to ensure you’re within the correct context and pointing to the correct cluster. Step 2 of 3 Creating your first alert policy To kick things off, start small. First, create an alert policy with the minimum required configuration, then add a NRQL alert condition to the policy, which will add the condition to the policy in New Relic. A minimal alert policy configuration is represented in the code below. For the sake of this walkthrough, name this file new_relic_alert_policy.yaml. Note: For help locating your personal API key, check out New Relic's personal API key documentation. apiVersion: nr.k8s.newrelic.com/v1 kind: AlertsPolicy metadata: name: my-policy spec: account_id: api_key: name: 'Alert Policy Created With k8s' # Feel free to rename region: 'us' Copy Now run the kubectl apply command to create your alert policy. kubectl apply -f ./new_relic_alert_policy.yaml Copy You'll see output that reads similar to the following: alertspolicy.nr.k8s.newrelic.com/my-policy created Copy Confirm that your alert policy was created by viewing your policies at alerts.newrelic.com/accounts/{your account ID}/policies. You can search for your new policy by its name. In this case, search for \"Alert Policy Created With k8s.\" You should see your new alert policy. Next it’s time to add a NRQL alert condition to the policy using the same configuration file. Step 3 of 3 Add NRQL alert conditions to your alert policy In the previous section you created an alert policy; now, you’ll add some alert conditions to the policy so you can trigger alerts when certain metrics are out of line. In your new_relic_alert_policy.yaml file, add a NRQL alert condition to the policy that will alert you when an application's average overall response time is above five seconds for a three minute period. Note: To receive notifications when an alert is triggered, add notification channels to your alert policy, with this code. # The policy from the previous steps apiVersion: nr.k8s.newrelic.com/v1 kind: AlertsPolicy metadata: name: my-policy spec: account_id: api_key: name: 'Alert Policy Created With k8s' # Feel free to rename region: 'us' # Add a NRQL alert condition to the policy conditions: - spec: type: 'NRQL' name: 'NRQL Alert Condition Created With k8s' nrql: query: \"SELECT average(duration) FROM Transaction WHERE appName = 'YOUR APP NAME'\" evaluationOffset: 3 enabled: true terms: - threshold: '5' threshold_occurrences: 'ALL' threshold_duration: 180 priority: 'CRITICAL' operator: 'ABOVE' violationTimeLimit: 'ONE_HOUR' valueFunction: 'SINGLE_VALUE' Copy With the alert condition added to the configuration, you can apply the update, which will create a NRQL alert condition and add it to your policy. kubectl apply -f ./new_relic_alert_policy.yaml Copy To confirm that the NRQL alert condition was created successfully, refresh your alert policy. If you see a new alert condition added to the alert policy, it was a success. To finish things off, you'll create and add an alert channel to your alert policy. For example, maybe you want to send an email out to your team when your alert condition is triggered. Try it out now We have a Kubernetes test cluster ready for you in 2 minutes. By following this on-line tutorial, you will learn how to: Deploy the New Relic agent in a Kubernetes environment Use the New Relic Kubernetes operator Some tips to use the on-line tutorial window: Accept the cookies, so you can see the menu bar. Click anywhere in the tutorial window to start. It will take about 2 minutes for your environment to be ready. Press CTRL-l or type clear to clear the terminal window Click on the finish flag icon in the bottom menu to hide or show the instructions Good luck! Note Some browsers automatically disable the use of iframes. If the module isn't loading please check your browser settings. Your browser does not support iframes. What’s next? Nice work — now you can manage your New Relic alert policies and NRQL alert conditions with code that integrates seamlessly within your Kubernetes workflow. This provides the ability to configure and manage your alerts with a domain-specific pattern, providing consistency and maintainability. You also gain the benefits of code reviews for any potential changes moving forward. As you and your team move forward, you might need to adjust some of the configuration values to better fit your needs. The New Relic Kubernetes Operator is just one of several tools in the New Relic Developer Toolkit aimed at facilitating observability as code.", + "type": "developer", + "document_type": "page", + "info": "Learn how to provision New Relic resources using the [Kubernetes operator](https://github.com/newrelic/newrelic-kubernetes-operator).", + "sections": [ + "Set up New Relic using the Kubernetes operator", + "Before you begin", + "Installing the operator on your Kubernetes cluster", + "Creating your first alert policy", + "Add NRQL alert conditions to your alert policy", + "Try it out now", + "Note", + "What’s next?" + ], + "title": "Set up New Relic using the Kubernetes operator", + "popularity": 1, + "tags": [ + "kubernetes", + "kubernetes operator", + "nrql alert conditions" + ], + "external_id": "2f9f7c55115d09255ade8f1d3fbcce4bee50d4aa", + "image": "", + "url": "https://developer.newrelic.com/automate-workflows/get-started-kubernetes/", + "published_at": "2020-08-19T01:47:11Z", + "updated_at": "2020-08-19T01:47:11Z", + "_index": "520d1d5d14cc8a32e600034b", + "_type": "520d1d5d14cc8a32e600034c", + "_score": 1.033874, + "_version": null, + "_explanation": null, + "sort": null, + "highlight": { + "sections": "Add NRQL alert conditions to your alert policy", + "tags": "nrql alert conditions", + "body": " how to set up New Relic for the first time with the official New Relic Kubernetes operator. More specifically, you'll provision an alert policy with NRQL conditions in your New Relic account using Kubernetes. Before you begin This walkthrough assumes you’ve already deployed a Kubernetes cluster. You" + }, + "id": "5f0e5de464441f2734cd74b2" + }, { "body": "NRQL is a query language you can use to query the New Relic database. This document explains NRQL syntax, clauses, components, and functions. Syntax This document is a reference for the functions and clauses used in a NRQL query. Other resources for understanding NRQL: Intro to NRQL: explains what NRQL is used for, what data you can query with it, and basic NRQL syntax Examine NRQL queries used to build New Relic charts Simulate SQL JOIN functions Use funnels to evaluate a series of related data Format NRQL for querying with the Event API Query components Every NRQL query will begin with a SELECT statement or a FROM clause. All other clauses are optional. The clause definitions below also contain example NRQL queries. Required: SELECT statement SELECT attribute ... SELECT function(attribute) ... The SELECT specifies what portion of a data type you want to query by specifying an attribute or a function. It's followed by one or more arguments separated by commas. In each argument you can: Get the values of all available attributes by using * as a wildcard. For example: SELECT * from Transaction. Get values associated with a specified attribute or multiple attributes specified in a comma separated list. Get aggregated values from specified attributes by selecting an aggregator function. Label the results returned in each argument with the AS clause. You can also use SELECT with basic math functions. Avg response time since last week This query returns the average response time since last week. SELECT average(duration) FROM PageView SINCE 1 week ago Required: FROM clause SELECT ... FROM data type ... Use the FROM clause to specify the data type you wish to query. You can start your query with FROM or with SELECT. You can merge values for the same attributes across multiple data types in a comma separated list. Query one data type This query returns the count of all APM transactions over the last three days: SELECT count(*) FROM Transaction SINCE 3 days ago Query multiple data types This query returns the count of all APM transactions and Browser events over the last three days: SELECT count(*) FROM Transaction, PageView SINCE 3 days ago SHOW EVENT TYPES clause SHOW EVENT TYPES... SHOW EVENT TYPES will return a list of all the data types present in your account for a specific time range. It is used as the first clause in a query instead of SELECT. In this context, \"event types\" refers to the data types you can access with a NRQL query. Data types in the last day This query will return all the data types present over the past day: SHOW EVENT TYPES SINCE 1 day ago WHERE clause Use the WHERE clause to filter results. NRQL returns the results that fulfill the condition(s) you specify in the clause. SELECT function(attribute) ... WHERE attribute [operator 'value' | IN ('value' [, 'value]) | IS [NOT] NULL ] [AND|OR ...] ... If you specify more than one condition, separate the conditions by the operators AND or OR. If you want to simulate a SQL join, use custom attributes in a WHERE or FACET clause. Operators that the WHERE clause accepts Description =, !=, <, <=, >, >= NRQL accepts standard comparison operators. Example: state = 'WA' AND Used to define an intersection of two conditions. OR Used to define a union of two conditions. IS NULL Determines if an attribute has a null value. IS NOT NULL Determines if an attribute does not have a null value. IN Determines if the string value of an attribute is in a specified set. Using this method yields better performance than stringing together multiple WHERE clauses. Example: animalType IN ('cat', 'dog', 'fish') NOT IN Determines if the string value of an attribute is not in a specified set. Using this method yields better performance than stringing together multiple WHERE clauses. Values must be in parentheses, separated by commas. For example: SELECT * FROM PageView WHERE countryCode NOT IN ('CA', 'WA') LIKE Determines if an attribute contains a specified sub-string. The string argument for the LIKE operator accepts the percent sign (%) as a wildcard anywhere in the string. If the substring does not begin or end the string you are matching against, the wildcard must begin or end the string. Examples: userAgentName LIKE 'IE%' IE IE Mobile userAgentName LIKE 'o%a%' Opera Opera Mini userAgentName LIKE 'o%a' Opera userAgentName LIKE '%o%a%' Opera Opera Mini Mozilla Gecko NOT LIKE Determines if an attribute does not contain a specified sub-string. RLIKE Determines if an attribute contains a specified Regex sub-string. Uses RE2 syntax. Examples: appName RLIKE 'z.*|q.*'' z-app q-app hostname RLIKE 'ip-10-351-[0-2]?[0-9]-.*' ip-10-351-19-237 ip-10-351-2-41 ip-10-351-24-238 ip-10-351-14-15 Note: Slashes must be escaped in the Regex pattern. For example, \\d must be \\\\d. Regex defaults to full-string matching, therefore ^ and $ are implicit and you do not need to add them. If the Regex pattern contains a capture group, the group will be ignored. That is, the group will not be captured for use later in the query. NOT RLIKE Determines if an attribute does not contain a specified Regex sub-string. Uses RE2 syntax. Example query with three conditions This query returns the browser response time for pages with checkout in the URL for Safari users in the United States and Canada over the past 24 hours. SELECT histogram(duration, 50, 20) FROM PageView WHERE countryCode IN ('CA', 'US') AND userAgentName='Safari' AND pageUrl LIKE '%checkout%' SINCE 1 day ago AS clause SELECT ... AS 'label' ... Use the AS clause to label an attribute, aggregator, step in a funnel, or the result of a math function with a string delimited by single quotes. The label is used in the resulting chart. Query using math function and AS This query returns the number of page views per session: SELECT count(*)/uniqueCount(session) AS 'Pageviews per Session' FROM PageView Query using funnel and AS This query returns a count of people who have visited both the main page and the careers page of a site over the past week: SELECT funnel(SESSION, WHERE name='Controller/about/main' AS 'Step 1', WHERE name = 'Controller/about/careers' AS 'Step 2') FROM PageView SINCE 1 week ago FACET clause SELECT ... FACET attribute ... Use FACET to separate and group your results by attribute values. For example, you could FACET your PageView data by deviceType to figure out what percentage of your traffic comes from mobile, tablet, and desktop devices. Use the LIMIT clause to specify how many facets appear (default is 10). For more complex grouping, use FACET CASES. FACET clauses support up to five attributes, separated by commas. The facets are sorted in descending order by the first field you provide in the SELECT clause. If you are faceting on attributes with more than 1,000 unique values, a subset of facet values is selected and sorted according to the query type. When selecting min(), max(), or count(), FACET uses those functions to determine how facets are picked and sorted. When selecting any other function, FACET uses the frequency of the attribute you are faceting on to determine how facets are picked and sorted. For more on faceting on multiple attributes, with some real-world examples, see this New Relic blog post. Faceted query using count() This query shows cities with the highest pageview counts. This query uses the total number of pageviews per city to determine how facets are picked and ordered. SELECT count(*) FROM PageView FACET city Faceted query using uniqueCount() This query shows the cities that access the highest number of unique URLs. This query uses the total number of times a particular city appears in the results to determine how facets are picked and ordered. SELECT uniqueCount(pageUrl) FROM PageView FACET city Grouping results across time Advanced segmentation and cohort analysis allow you to facet on bucket functions to more effectively break out your data. Cohort analysis is a way to group results together based on timestamps. You can separate them into buckets that cover a specified range of dates and times. FACET CASES clause SELECT ... FACET CASES ( WHERE attribute operator value, WHERE attribute operator value, ... ) ... Use FACET CASES to break out your data by more complex conditions than possible with FACET. Separate multiple conditions with a comma ,. For example, you could query your PageView data and FACET CASES into categories like less than 1 second, from 1 to 10 seconds, and greater than 10 seconds. You can combine multiple attributes within your cases, and label the cases with the AS selector. Data points will be added to at most one facet case, the first facet case that they match. You may also use a time function with your attribute. Basic usage with WHERE SELECT count(*) FROM PageView FACET CASES (WHERE duration < 1, WHERE duration > 1 and duration < 10, WHERE duration > 10) Group based on multiple attributes This example groups results into one bucket where the transaction name contains login, and another where the URL contains login and a custom attribute indicates that the user was a paid user: SELECT count(*) FROM Transaction FACET CASES (WHERE name LIKE '%login%', WHERE name LIKE '%feature%' AND customer_type='Paid') Label groups with AS This example uses the AS selector to give your results a human-readable name: SELECT count(*) FROM Transaction FACET CASES (WHERE name LIKE '%login%' AS 'Total Logins', WHERE name LIKE '%feature%' AND customer_type='Paid' AS 'Feature Visits from Paid Users') LIMIT clause SELECT ... LIMIT count ... Use the LIMIT clause to control the maximum number of facet values returned by FACET queries or the maximum number of items returned by SELECT * queries. This clause takes a single integer value as an argument. If the LIMIT clause is not specified, or no value is provided, the limit defaults to 10 for FACET queries and 100 in the case of SELECT * queries. The maximum allowed value for the LIMIT clause is 2,000. Query using LIMIT This query shows the top 20 countries by session count and provides 95th percentile of response time for each country for Windows users only. SELECT uniqueCount(session), percentile(duration, 95) FROM PageView WHERE userAgentOS = 'Windows' FACET countryCode LIMIT 20 SINCE YESTERDAY OFFSET clause SELECT ... LIMIT count OFFSET count ... Use the OFFSET clause with LIMIT to control the portion of rows returned by SELECT * or SELECT column queries. Like the LIMIT clause, OFFSET takes a single integer value as an argument. OFFSET sets the number of rows to be skipped before the selected rows of your query are returned. This is constrained by LIMIT. OFFSET rows are skipped starting from the most recent record. For example, the query SELECT interestingValue FROM Minute_Report LIMIT 5 OFFSET 1 returns the last 5 values from Minute_Report except for the most recent one. SINCE clause SELECT ... SINCE [numerical units AGO | phrase] ... The default value is 1 hour ago. Use the SINCE clause to define the beginning of a time range for the returned data. When using NRQL, you can set a UTC timestamp or relative time range. You can specify a timezone for the query but not for the results. NRQL results are based on your system time. See Set time range on dashboards and charts for detailed information and examples. UNTIL clause SELECT ... UNTIL integer units AGO ... The default value is NOW. Only use UNTIL to specify an end point other than the default. Use the UNTIL clause to define the end of a time range across which to return data. Once a time range has been specified, the data will be preserved and can be reviewed after the time range has ended. You can specify a UTC timestamp or relative time range. You can specify a time zone for the query but not for the results. The returned results are based on your system time. See Set time range on dashboards and charts for detailed information and examples. WITH TIMEZONE clause SELECT ... WITH TIMEZONE (selected zone) ... By default, query results are displayed in the timezone of the browser you're using. Use the WITH TIMEZONE clause to select a time zone for a date or time in the query that hasn't already had a time zone specified for it. For example, the query clause SINCE Monday UNTIL Tuesday WITH TIMEZONE 'America/New_York' will return data recorded from Monday at midnight, Eastern Standard Time, until midnight Tuesday, Eastern Standard Time. Available Time Zone Selections Africa/Abidjan Africa/Addis_Ababa Africa/Algiers Africa/Blantyre Africa/Cairo Africa/Windhoek America/Adak America/Anchorage America/Araguaina America/Argentina/Buenos_Aires America/Belize America/Bogota America/Campo_Grande America/Cancun America/Caracas America/Chicago America/Chihuahua America/Dawson_Creek America/Denver America/Ensenada America/Glace_Bay America/Godthab America/Goose_Bay America/Havana America/La_Paz America/Los_Angeles America/Miquelon America/Montevideo America/New_York America/Noronha America/Santiago America/Sao_Paulo America/St_Johns Asia/Anadyr Asia/Bangkok Asia/Beirut Asia/Damascus Asia/Dhaka Asia/Dubai Asia/Gaza Asia/Hong_Kong Asia/Irkutsk Asia/Jerusalem Asia/Kabul Asia/Katmandu Asia/Kolkata Asia/Krasnoyarsk Asia/Magadan Asia/Novosibirsk Asia/Rangoon Asia/Seoul Asia/Tashkent Asia/Tehran Asia/Tokyo Asia/Vladivostok Asia/Yakutsk Asia/Yekaterinburg Asia/Yerevan Atlantic/Azores Atlantic/Cape_Verde Atlantic/Stanley Australia/Adelaide Australia/Brisbane Australia/Darwin Australia/Eucla Australia/Hobart Australia/Lord_Howe Australia/Perth Chile/EasterIsland Etc/GMT+10 Etc/GMT+8 Etc/GMT-11 Etc/GMT-12 Europe/Amsterdam Europe/Belfast Europe/Belgrade Europe/Brussels Europe/Dublin Europe/Lisbon Europe/London Europe/Minsk Europe/Moscow Pacific/Auckland Pacific/Chatham Pacific/Gambier Pacific/Kiritimati Pacific/Marquesas Pacific/Midway Pacific/Norfolk Pacific/Tongatapu UTC   See Set time range on dashboards and charts for detailed information and examples. WITH METRIC_FORMAT clause For information on querying metric data, see Query metrics. COMPARE WITH clause SELECT ... (SINCE or UNTIL) (integer units) AGO COMPARE WITH (integer units) AGO ... Use the COMPARE WITH clause to compare the values for two different time ranges. COMPARE WITH requires a SINCE or UNTIL statement. The time specified by COMPARE WITH is relative to the time specified by SINCE or UNTIL. For example, SINCE 1 day ago COMPARE WITH 1 day ago compares yesterday with the day before. The time range for theCOMPARE WITH value is always the same as that specified by SINCE or UNTIL. For example, SINCE 2 hours ago COMPARE WITH 4 hours ago might compare 3:00pm through 5:00pm against 1:00 through 3:00pm. COMPARE WITH can be formatted as either a line chart or a billboard: With TIMESERIES, COMPARE WITH creates a line chart with the comparison mapped over time. Without TIMESERIES, COMPARE WITH generates a billboard with the current value and the percent change from the COMPARE WITH value. Example: This query returns data as a line chart showing the 95th percentile for the past hour compared to the same range one week ago. First as a single value, then as a line chart. SELECT percentile(duration) FROM PageView SINCE 1 week ago COMPARE WITH 1 week AGO SELECT percentile(duration) FROM PageView SINCE 1 week ago COMPARE WITH 1 week AGO TIMESERIES AUTO TIMESERIES clause SELECT ... TIMESERIES integer units ... Use the TIMESERIES clause to return data as a time series broken out by a specified period of time. Since TIMESERIES is used to trigger certain charts, there is no default value. To indicate the time range, use integer units. For example: TIMESERIES 1 minute TIMESERIES 30 minutes TIMESERIES 1 hour TIMESERIES 30 seconds Use a set interval The value provided indicates the units used to break out the graph. For example, to present a one-day graph showing 30 minute increments: SELECT ... SINCE 1 day AGO TIMESERIES 30 minutes Use automatically set interval TIMESERIES can also be set to AUTO, which will divide your graph into a reasonable number of divisions. For example, a daily chart will be divided into 30 minute intervals and a weekly chart will be divided into 6 hour intervals. This query returns data as a line chart showing the 50th and 90th percentile of client-side transaction time for one week with a data point every 6 hours. SELECT average(duration), percentile(duration, 50, 90) FROM PageView SINCE 1 week AGO TIMESERIES AUTO Use max interval You can set TIMESERIES to MAX, which will automatically adjust your time window to the maximum number of intervals allowed for a given time period. This allows you to update your time windows without having to manually update your TIMESERIES buckets and ensures your time window is being split into the peak number of intervals allowed. The maximum number of TIMESERIES buckets that will be returned is 366. For example, the following query creates 4-minute intervals, which is the ceiling for a daily chart. SELECT average(duration) FROM Transaction since 1 day ago TIMESERIES MAX For functions such as average( ) or percentile( ), a large interval can have a significant smoothing effect on outliers. EXTRAPOLATE clause You can use this clause with these data types: Transaction TransactionError Custom events reported via APM agent APIs The purpose of EXTRAPOLATE is to mathematically compensate for the effects of APM agent sampling of event data so that query results more closely represent the total activity in your system. This clause will be useful when a New Relic APM agent reports so many events that it often passes its harvest cycle reporting limits. When that occurs, the agent begins to sample events. When EXTRAPOLATE is used in a NRQL query that supports its use, the ratio between the reported events and the total events is used to extrapolate a close approximation of the total unsampled data. When it is used in a NRQL query that doesn’t support its use or that hasn’t used sampled data, it has no effect. Note that EXTRAPOLATE is most useful for homogenous data (like throughput or error rate). It's not effective when attempting to extrapolate a count of distinct things (like uniqueCount() or uniques()). This clause works only with NRQL queries that use one of the following aggregator functions: apdex average count histogram sum percentage (if function it takes as an argument supports EXTRAPOLATE) rate (if function it takes as an argument supports EXTRAPOLATE) stddev Example of extrapolating throughput A query that will show the extrapolated throughput of a service named interestingApplication. SELECT count(*) FROM Transaction WHERE appName='interestingApplication' SINCE 60 minutes ago EXTRAPOLATE Example of extrapolating throughput as a time series A query that will show the extrapolated throughput of a service named interestingApplication by transaction name, displayed as a time series. SELECT count(*) FROM Transaction WHERE appName='interestingApplication' SINCE 60 minutes ago FACET name TIMESERIES 1 minute EXTRAPOLATE Query metric data There are several ways to query metric data using NRQL: Query metric timeslice data, which is reported by New Relic APM, Mobile, Browser Query the Metric data type, which is reported by some of our integrations and Telemetry SDKs For more on understanding metrics in New Relic, see Metric data types. Aggregator functions Use aggregator functions to filter and aggregate data in a NRQL query. Some helpful information about using aggregator functions: See the New Relic University tutorials for Filter queries, Apdex queries, and Percentile queries. Or, go to the full online course Writing NRQL queries. Data type \"coercion\" is not supported. Read about available type conversion functions. Cohort analysis functions appear on the New Relic Insights Cohort analysis page. The cohort functions aggregate transactions into time segments. Here are the available aggregator functions. The definitions below contain example NRQL queries. Examples: SELECT histogram(duration, 10, 20) FROM PageView SINCE 1 week ago apdex(attribute, t: ) Use the apdex function to return an Apdex score for a single transaction or for all your transactions. The attribute can be any attribute based on response time, such as duration or backendDuration. The t: argument defines an Apdex T threshold in seconds. The Apdex score returned by the apdex( ) function is based only on execution time. It does not account for APM errors. If a transaction includes an error but completes in Apdex T or less, that transaction will be rated satisfying by the apdex ( ) function. Get Apdex for specific customers If you have defined custom attributes, you can filter based on those attributes. For example, you could monitor the Apdex for a particularly important customer: SELECT apdex(duration, t: 0.4) FROM Transaction WHERE customerName='ReallyImportantCustomer' SINCE 1 day ago Get Apdex for specific transaction Use the name attribute to return a score for a specific transaction, or return an overall Apdex by omitting name. This query returns an Apdex score for the Controller/notes/index transaction over the last hour: SELECT apdex(duration, t: 0.5) from Transaction WHERE name='Controller/notes/index' SINCE 1 hour ago The apdex function returns an Apdex score that measures user satisfaction with your site. Arguments are a response time attribute and an Apdex T threshold in seconds. Get overall Apdex for your app This example query returns an overall Apdex for the application over the last three weeks: SELECT apdex(duration, t: 0.08) FROM Transaction SINCE 3 week ago average(attribute) Use the average( ) function to return the average value for an attribute. It takes a single attribute name as an argument. If a value of the attribute is not numeric, it will be ignored when aggregating. If data matching the query's conditions is not found, or there are no numeric values returned by the query, it will return a value of null. buckets(attribute, ceiling [,number of buckets]) Use the buckets() function to aggregate data split up by a FACET clause into buckets based on ranges. You can bucket by any attribute that is stored as a numerical value in the New Relic database. It takes three arguments: Attribute name Maximum value of the sample range. Any outliers will appear in the final bucket. Total number of buckets For more information and examples, see Split your data into buckets. bucketPercentile(attribute) The bucketPercentile( ) function is the NRQL equivalent of the histogram_quantile function in Prometheus. It is intended to be used with dimensional metric data. Instead of the quantile, New Relic returns the percentile, which is the quantile * 100. Use the bucketPercentile( ) function to calculate the quantile from the histogram data in a Prometheus format. It takes the bucket name as an argument and reports percentiles along the bucket's boundaries: SELECT bucketPercentile(duration_bucket) FROM Metric SINCE 1 day ago Optionally, you can add percentile specifications as an argument: SELECT bucketPercentile(duration_bucket, 50, 75, 90) FROM Metric SINCE 1 day ago Because multiple metrics are used to make up Prometheus histogram data, you must query for specific Prometheus metrics in terms of the associated . For example, to compute percentiles from a Prometheus histogram, with the prometheus_http_request_duration_seconds using NRQL, use bucketPercentile(prometheus_http_request_duration_seconds_bucket, 50). Note how _bucket is added to the end of the as a suffix. See the Prometheus.io documentation for more information. cardinality(attribute) Use the cardinality( ) function to obtain the number of combinations of all the dimensions (attributes) on a metric. It takes three arguments, all optional: Metric name: if present, cardinality( ) only computes the metric specified. Include: if present, the include list restricts the cardinality computation to those attributes. Exclude: if present, the exclude list causes those attributes to be ignored in the cardinality computation. SELECT cardinality(metric_name, include:{attribute_list}, exclude:{attribute_list}) count(*) Use the count( ) function to return a count of available records. It takes a single argument; either *, an attribute, or a constant value. Currently, it follows typical SQL behavior and counts all records that have values for its argument. Since count(*) does not name a specific attribute, the results will be formatted in the default \"humanize\" format. derivative(attribute [,time interval]) derivative() finds the rate of change for a given dataset. The rate of change is calculated using a least-squares regression to approximate the derivative. The time interval is the period for which the rate of change is calculated. For example, derivative(attributeName, 1 minute) will return the rate of change per minute. dimensions(include: {attributes}, exclude: {attributes}) Use the dimensions( ) function to return all the dimensional values on a data type. You can explicitly include or exclude specific attributes using the optional arguments: Include: if present, the include list limits dimensions( ) to those attributes. Exclude: if present, the dimensions( ) calculation ignores those attributes. FROM Metric SELECT count(node_filesystem_size) TIMESERIES FACET dimensions() When used with a FACET clause, dimensions( ) produces a unique timeseries for all facets available on the event type, similar to how Prometheus behaves with non-aggregated queries. earliest(attribute) Use the earliest( ) function to return the earliest value for an attribute over the specified time range. It takes a single argument. Arguments after the first will be ignored. If used in conjunction with a FACET it will return the most recent value for an attribute for each of the resulting facets. Get earliest country per user agent from PageView This query returns the earliest country code per each user agent from the PageView event. SELECT earliest(countryCode) FROM PageView FACET userAgentName eventType() ...WHERE eventType() = 'EventNameHere'... ...FACET eventType()... Use the eventType() function in a FACET clause to break out results by the selected data type or in a WHERE clause to filter results to a specific data type. This is particularly useful for targeting specific data types with the filter() and percentage() functions. In this context, \"event type\" refers to the types of data you can access with a NRQL query. Use eventType() in filter() function This query returns the percentage of total TransactionError results out of the total Transaction results. You can use the eventType() function to target specific types of data with the filter() function. SELECT 100 * filter(count(*), where eventType() = 'TransactionError') / filter(count(*), where eventType() = 'Transaction') FROM Transaction, TransactionError WHERE appName = 'App.Prod' TIMESERIES 2 Minutes SINCE 6 hours ago Use eventType() with FACET This query displays a count of how many records each data type (Transaction and TransactionError) returns. SELECT count(*) FROM Transaction, TransactionError FACET eventType() TIMESERIES filter(function(attribute), WHERE condition) Use the filter( ) function to limit the results for one of the aggregator functions in your SELECT statement. You can use filter() in conjunction with FACET or TIMESERIES. Analyze purchases that used offer codes You could use filter() to compare the items bought in a set of transactions for those using an offer code versus those who aren't: Use the filter( ) function to limit the results for one of the aggregator functions in your SELECT statement. funnel(attribute, steps) Use the funnel() function to generate a funnel chart. It takes an attribute as its first argument. You then specify steps as WHERE clauses (with optional AS clauses for labels) separated by commas. For details and examples, see the funnels documentation. getField(attribute, field) Use the getField() function to extract a field from complex metrics. It takes the following arguments: Metric type Supported fields summary count, total, max, min gauge count, total, max, min, latest distribution count, total, max, min counter count Examples: SELECT max(getField(mySummary, count)) from Metric SELECT sum(mySummary) from Metric where getField(mySummary, count) > 10 histogram(attribute, ceiling [,number of buckets]) Use the histogram( ) function to generate histograms. It takes three arguments: Attribute name Maximum value of the sample range Total number of buckets Histogram of response times from PageView events This query results in a histogram of response times ranging up to 10 seconds over 20 buckets. SELECT histogram(duration, 10, 20) FROM PageView SINCE 1 week ago Prometheus histogram buckets histogram( ) accepts Prometheus histogram buckets: SELECT histogram(duration_bucket, 10, 20) FROM Metric SINCE 1 week ago New Relic distribution metric histogram( ) accepts Distribution metric as an input: SELECT histogram(myDistributionMetric, 10, 20) FROM Metric SINCE 1 week ago keyset() Using keyset() will allow you to see all of the attributes for a given data type over a given time range. It takes no arguments. It returns a JSON structure containing groups of string-typed keys, numeric-typed keys, boolean-typed keys, and all keys. See all attributes for a data type This query returns the attributes found for PageView events from the last day: SELECT keyset() FROM PageView SINCE 1 day ago latest(attribute) Use the latest( ) function to return the most recent value for an attribute over a specified time range. It takes a single argument. Arguments after the first will be ignored. If used in conjunction with a FACET it will return the most recent value for an attribute for each of the resulting facets. Get most recent country per user agent from PageView This query returns the most recent country code per each user agent from the PageView event. SELECT latest(countryCode) FROM PageView FACET userAgentName max(attribute) Use the max( ) function to return the maximum recorded value of a numeric attribute over the time range specified. It takes a single attribute name as an argument. If a value of the attribute is not numeric, it will be ignored when aggregating. If data matching the query's conditions is not found, or there are no numeric values returned by the query, it will return a value of null. median(attribute) Use the median( ) function to return an attribute's median, or 50th percentile. For more information about percentile queries, see percentile(). The median( ) query is only available when using the query builder. Median query This query will generate a line chart for the median value. SELECT median(duration) FROM PageView TIMESERIES AUTO min(attribute) Use the min( ) function to return the minimum recorded value of a numeric attribute over the time range specified. It takes a single attribute name as an argument. If a value of the attribute is not numeric, it will be ignored when aggregating. If data matching the query's conditions is not found, or there are no numeric values returned by the query, it will return a value of null. percentage(function(attribute), WHERE condition) Use the percentage( ) function to return the percentage of a target data set that matches some condition. The first argument requires an aggregator function against the desired attribute. Use exactly two arguments (arguments after the first two will be ignored). If the attribute is not numeric, this function returns a value of 100%. percentile(attribute [, percentile [, ...]]) Use the percentile( ) function to return an attribute's approximate value at a given percentile. It requires an attribute and can take any number of arguments representing percentile points. The percentile() function enables percentiles to displays with up to three digits after the decimal point, providing greater precision. Percentile thresholds may be specified as decimal values, but be aware that for most data sets, percentiles closer than 0.1 from each other will not be resolved. Percentile display examples Use TIMESERIES to generate a line chart with percentiles mapped over time. Omit TIMESERIES to generate a billboard and attribute sheet showing aggregate values for the percentiles. If no percentiles are listed, the default is the 95th percentile. To return only the 50th percentile value, the median, you can also use median(). Basic percentile query This query will generate a line chart with lines for the 5th, 50th, and 95th percentile. SELECT percentile(duration, 5, 50, 95) FROM PageView TIMESERIES AUTO predictLinear(attribute, [,time interval]) predictLinear() is an extension of the derivative() function. It uses a similar method of least-squares linear regression to predict the future values for a dataset. The time interval is how far the query will look into the future. For example, predictLinear(attributeName, 1 hour) is a linear prediction 1 hour into the future of the query time window. Generally, predictLinear() is helpful for continuously growing values like disk space, or predictions on large trends. Since predictLinear() is a linear regression, familiarity with the dataset being queried helps to ensure accurate long-term predictions. Any dataset which grows exponentially, logarithmically, or by other nonlinear means will likely only be successful in very short-term predictions. New Relic recommends against using predictLinear in TIMESERIES queries. This is because each bucket will be making an individual prediction based on its relative timeframe within the query, meaning that such queries will not show predictions from the end of the timeseries forward. rate(function(attribute) [,time interval]) Use the rate( ) function to visualize the frequency or rate of a given query per time interval. For example, you might want to know the number of pageviews per minute over an hour-long period or the count of unique sessions on your site per hour over a day-long period. Use TIMESERIES to generate a line chart with rates mapped over time. Omit TIMESERIES to generate a billboard showing a single rate value averaged over time. Basic rate query This query will generate a line chart showing the rate of throughput for APM transactions per 10 minutes over the past 6 hours. SELECT rate(count(*), 10 minute) FROM Transaction SINCE 6 hours ago TIMESERIES round(attribute) Use the round( ) function to return the rounded value of an attribute. Optionally round( ) can take a second argument, to_nearest, to round the first argument to the closest multiple of the second one. to_nearest can be fractional. SELECT round(n [, to_nearest]) stddev(attribute) Use the stddev( ) function to return one standard deviation for a numeric attribute over the time range specified. It takes a single argument. If the attribute is not numeric, it will return a value of zero. stdvar(attribute) Use the stdvar( ) function to return the standard variance for a numeric attribute over the time range specified. It takes a single argument. If the attribute is not numeric, it will return a value of zero. sum(attribute) Use the sum( ) function to return the sum recorded values of a numeric attribute over the time range specified. It takes a single argument. Arguments after the first will be ignored. If the attribute is not numeric, it will return a value of zero. uniqueCount(attribute) Use the uniqueCount( ) function to return the number of unique values recorded for an attribute over the time range specified. To optimize query performance, this function returns approximate results for queries that inspect more than 256 unique values. uniques(attribute [,limit]​) Use the uniques( ) function to return a list of unique values recorded for an attribute over the time range specified. When used along with the facet clause, a list of unique attribute values will be returned per each facet value. The limit parameter is optional. When it is not provided, the default limit of 1,000 unique attribute values per facet is applied. You may specify a different limit value, up to a maximum of 10,000. The uniques( ) function will return the first set of unique attribute values discovered, until the limit is reached. Therefore, if you have 5,000 unique attribute values in your data set, and the limit is set to 1,000, the operator will return the first 1,000 unique values that it discovers, regardless of their frequency. The maximum number of values that can be returned in a query result is the product of the uniques( ) limit times the facet limit. In the following query, the theoretical maximum number of values that can be returned is 5 million (5,000 x 1,000). From Transaction SELECT uniques(host,5000) FACET appName LIMIT 1000 However, depending on the data set being queried, and the complexity of the query, memory protection limits may prevent a very large query from being executed. Type conversion NRQL does not support \"coercion.\" This means that a float stored as a string is treated as a string and cannot be operated on by functions expecting float values. You can convert a string with a numeric value or a boolean with a string value to their numeric and boolean types with these functions: Use the numeric() function to convert a number with a string format to a numeric function. The function can be built into a query that uses math functions on query results or NRQL aggregator functions, such as average(). Use the boolean() function to convert a string value of \"true\" or \"false\" to the corresponding boolean value. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", "type": "docs", @@ -6204,7 +6120,7 @@ "category_0": "Query your data", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.6758109, + "_score": 0.6727866, "_version": null, "_explanation": null, "sort": null, @@ -6262,7 +6178,7 @@ "category_0": "Alerts and Applied intelligence", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.170984, + "_score": 0.17380425, "_version": null, "_explanation": null, "sort": null, @@ -6312,7 +6228,7 @@ "category_0": "Query your data", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.10769665, + "_score": 0.110183515, "_version": null, "_explanation": null, "sort": null, @@ -6327,53 +6243,212 @@ "breadcrumb": "Contents / Query your data / NRQL: New Relic Query Language / NRQL query tutorials" }, "id": "5f2b1349196a67379343fbcf" + } + ], + "/explore-docs/intro-to-sdk": [ + { + "body": "Intro to NerdStorage 30 min To help you build a New Relic One application, we provide you with the New Relic One SDK. On this page, you’ll learn how to use NerdStorage SDK components. Use NerdStorage in your apps NerdStorage is used to store and retrieve simple sets of data, including users's configuration settings and preferences (like favorites), or any other small data sets. This storage is unique per Nerdpack, and can't be shared with any other Nerdpack. NerdStorage can be classified into three categories: User storage: Data that is attached to a particular user. If you’re authenticated as the user the data is attached to, you can read it and write it. Account storage: Data that is attached to a particular account. If you’re authenticated and can access the account, you can read and write to account scoped NerdStorage. Visibility of account data is also determined by master/subaccount rules: If a user has access to the master account, then they also have access to data in all subaccounts. Entity storage: Data that is attached to a particular entity. If you can see the corresponding entity, you can read and write data on that entity. Data model You can imagine NerdStorage as a nested key-value map. Data is inside documents, which are nested inside collections: { 'YourNerdpackUuid': { 'collection-1': { 'document-1-of-collection-1': '{\"lastNumber\": 42, \"another\": [1]}', 'document-2-of-collection-1': '\"userToken\"', // ... }, 'another-collection': { 'fruits': '[\"pear\", \"apple\"]', // ... }, // ... }, } Copy Each NerdStorage level has different properties and purpose: Collections: From a Nerdpack, you can create multiple collections by naming each of them. Inside a collection you can put one or more documents. Think of a collection as key-value storage, where each document is a key-value pair. Documents: A document is formed by an identifier (documentId) and a set of data associated with it. Data associated with a document: NerdStorage accepts any sort of data associated to a documentId. Query and mutation components that are provided work by serializing and deserializing JSON. Limits A Nerdpack can hold up to 1,000 collections and 10,000 documents, plus storage type. A collection can hold up to 1,000 documents, plus storage type. Each document can have a maximum length of 64 KiB when serialized. Data access To access NerdStorage, you can run NerdGraph queries, or use the provided storage queries. Depending on which storage you want to access, you can use a different set of SDK components: User access: UserStorageQuery and UserStorageMutation Account access: AccountStorageQuery and AccountStorageMutation Entity access: EntityStorageQuery and EntityStorageMutation Each of these components can operate declaratively (for example, as part of your React rendering methods) or imperatively (by using the static methods for query and mutation). For more information on this, see Data querying and mutations. Permissions for working with NerdStorage In order to persist changes on NerdStorage, such as creating, updating, and deleting account and entity storage, you must have a user role with permission to persist changes.", + "type": "developer", + "document_type": "page", + "info": "Intro to NerdStorage on New Relic One", + "sections": [ + "Intro to NerdStorage", + "Use NerdStorage in your apps", + "Data model", + "Limits", + "Data access", + "Permissions for working with NerdStorage" + ], + "title": "Intro to NerdStorage", + "popularity": 1, + "tags": [ + "nerdstorage", + "nerdstorage components", + "new relic one apps", + "data access" + ], + "external_id": "709e06c25376d98b2191ca369b4d139e5084bd62", + "image": "", + "url": "https://developer.newrelic.com/explore-docs/nerdstorage/", + "published_at": "2020-08-19T01:49:36Z", + "updated_at": "2020-08-14T01:50:34Z", + "_index": "520d1d5d14cc8a32e600034b", + "_type": "520d1d5d14cc8a32e600034c", + "_score": 19.896872, + "_version": null, + "_explanation": null, + "sort": null, + "highlight": { + "sections": "Use NerdStorage in your apps", + "info": "Intro to NerdStorage on New Relic One", + "tags": "new relic one apps", + "body": "Intro to NerdStorage 30 min To help you build a New Relic One application, we provide you with the New Relic One SDK. On this page, you’ll learn how to use NerdStorage SDK components. Use NerdStorage in your apps NerdStorage is used to store and retrieve simple sets of data, including users's" + }, + "id": "5efa989ee7b9d2048e7bab92" }, { - "body": "New Relic Insights' Query page is one place you can run NRQL queries of your data. To get started: Go to insights.newrelic.com > Query, then use any of the available NRQL syntax and functions. Use the Query page to: Create and run queries of your data. View your query history. View favorite queries. Use the NRQL query to create, view, organize, and share Insights dashboards. For a library of educational videos about how to use New Relic Insights, visit learn.newrelic.com. Use NRQL query history To view up to twenty of your most recent queries, select the History tab directly below the query command line interface. Use the query history to adjust and improve recent queries. If you want to... Do this... Run recent queries Select a recent query from the history list. The query will appear on the command line, where it can be edited. Delete queries Mouse over a query in the history list so the delete [trash] icon appears. The query history only retains the twenty most recent queries, so it can be useful to delete unwanted queries to make room for queries you like. Favorite queries Mouse over a query in the history list and the favorite star icon appears. Then, to view and use your favorite queries, select the Favorites tab. For more help If you need more help, check out these support and learning resources: Browse the Explorers Hub to get help from the community and join in discussions. Find answers on our sites and learn how to use our support portal. Run New Relic Diagnostics, our troubleshooting tool for Linux, Windows, and macOS. Review New Relic's data security and licenses documentation.", - "type": "docs", + "body": "Add tables to your New Relic One application 30 min Tables are a popular way of displaying data in New Relic applications. For example, with the query builder you can create tables from NRQL queries. Whether you need to have more control over tables or you're importing third-party data, you can build your own tables into your New Relic One application. In this guide, you are going to build a sample table using various New Relic One components. Before you begin If you haven't already installed the New Relic One CLI, step through the quick start in New Relic One. This process also gets you an API key. In addition, to complete the steps in this guide, you need a GitHub account, and to have Node.js installed on your machine. See [Setting up your development environment](/build-apps/set-up-dev-env) for more info. Clone and set up the example application Step 1 of 4 Clone the nr1-how-to example application from GitHub to your local machine. Then, navigate to the app directory. The example app lets you experiment with tables. git clone https://github.com/newrelic/nr1-how-to.git` cd nr1-how-to/create-a-table/nerdlets/create-a-table-nerdlet` Copy Step 2 of 4 Edit the index.json file and set this.accountId to your Account ID as shown in the example. export default class Nr1HowtoAddTimePicker extends React.Component { constructor(props){ super(props) this.accountId = YOUR_ACCOUNT_ID; } ... } Copy Step 3 of 4 Run the demo application Change the directory back to nr1-how-to/create-a-table. Before you can load the demo application, you need to update its unique id by invoking the New Relic One CLI. Once you've assigned a new UUID to the app, install the dependencies and serve the demo app locally, so that you can test any change live in your browser. nr1 nerdpack:uuid -gf # Update the app unique ID npm install # Install dependencies nr1 nerdpack:serve # Serve the demo app locally Copy Step 4 of 4 Open one.newrelic.com/?nerdpacks=local in your browser. Click Apps*, and then in the Other apps section, you should see a Create a table** launcher. That's the demo application you're going to work on. Go ahead and select it. Have a good look at the demo app. There's a TableChart on the left side named Transaction Overview, with an AreaChart next to it. You'll use Table components to add a new table in the second row. Work with table components Step 1 of 10 Navigate to the `nerdlets/create-a-table-nerdlet` subdirectory and open the `index.js` file. Add the following components to the import statement at the top of the file so that it looks like the example: Table TableHeader TableHeaderCell TableRow TableRowCell import { Table, TableHeader, TableHeaderCell, TableRow, TableRowCell, PlatformStateContext, Grid, GridItem, HeadingText, AreaChart, TableChart, } from 'nr1'; Copy Step 2 of 10 Add a basic Table component Locate the empty GridItem in index.js: This is where you start building the table. Add the initial component. The items property collects the data by calling _getItems(), which contains sample values.
; Copy Step 3 of 10 Add the header and rows As the Table component renders a fixed number of header cells and rows, your next step is adding header components, as well as a function that returns the required table rows. Inside of the Table component, add the TableHeader and then a TableHeaderCell child for each heading. Since you don't know how many rows you'll need, your best bet is to call a function to build as many TableRows as items returned by _getItems(). Application Size Company Team Commit ; { ({ item }) => ( {item.name} {item.value} {item.company} {item.team} {item.commit} ); } Copy Step 4 of 10 Take a look at the application running in New Relic One: you should see something similar to the screenshot below. Step 5 of 10 Replace standard table cells with smart cells The New Relic One library includes cell components that can automatically format certain data types, like users, metrics, and entity names. The table you've just created contains columns that can benefit from those components: Application (an entity name) and Size (a metric). Before you can use EntityTitleTableRowCell and MetricTableRowCell, you have to add them to the import statement first. import { EntityTitleTableRowCell, MetricTableRowCell, ... /* All previous components */ } from 'nr1'; Copy Step 6 of 10 Update your table rows by replacing the first and second TableRowCells with entity and metric cells. Notice that EntityTitleTableRowCell and MetricTableRowCell are self-closing tags. { ({ item }) => ( {item.company} {item.team} {item.commit} ); } Copy Step 7 of 10 Time to give your table a second look: The cell components you've added take care of properly formatting the data. Step 8 of 10 Add some action to your table! Tables are great, but interactive tables can be better: As a last update, you are going to allow users to act on each data row. Add the _getActions() method to your index.js file, right before _getItems(). As you may have guessed from the code, _getActions() spawns an alert box when you click Team or Commit cells. _getActions() { return [ { label: 'Alert Team', iconType: TableRow.ACTIONS_ICON_TYPE.INTERFACE__OPERATIONS__ALERT, onClick: (evt, { item, index }) => { alert(`Alert Team: ${item.team}`); }, }, { label: 'Rollback Version', iconType: TableRow.ACTIONS_ICON_TYPE.INTERFACE__OPERATIONS__UNDO, onClick: (evt, { item, index }) => { alert(`Rollback from: ${item.commit}`); }, }, ]; } Copy Step 9 of 10 Find the TableRow component in your return statement and point the actions property to _getActions(). The TableRow actions property defines a set of actions that appear when the user hovers over a table row. Actions have a mandatory text and an onClick callback, but can also display an icon or be disabled if needed. Copy Step 10 of 10 Go back to your application and try hovering over any of the rows: Notice how the two available actions appear. When you click them, a function triggers with the selected row data as an argument, and an alert displays in your browser. Next steps You've built a table into a New Relic One application, using components to format data automatically and provide contextual actions. Well done! Keep exploring the Table components, their properties, and how to use them, in our SDK documentation.", + "type": "developer", "document_type": "page", - "breadcrumb": "Contents / Insights / Use Insights UI / Explore data", - "info": "Use the New Relic Insights Query page to create and edit NRQL queries, favorite them for later use, and add query results to dashboards. ", - "nodeid": 1131, + "info": "Add a table to your New Relic One app.", "sections": [ - "Use Insights UI", - "Getting started", - "Explore data", - "Guides", - "Manage account data", - "Manage dashboards", - "Time settings", - "Export data", - "Troubleshooting", - "Query page: Create and edit NRQL queries", - "Use NRQL query history", - "For more help" + "Add tables to your New Relic One application", + "Before you begin", + "Clone and set up the example application", + "Work with table components", + "Next steps" + ], + "title": "Add tables to your New Relic One application", + "popularity": 1, + "tags": [ + "table in app", + "Table component", + "TableHeaderc omponent", + "TableHeaderCell component", + "TableRow component", + "TableRowCell component" + ], + "external_id": "7ff7a8426eb1758a08ec360835d9085fae829936", + "image": "https://developer.newrelic.com/static/e637c7eb75a9dc01740db8fecc4d85bf/1d6ec/table-new-cells.png", + "url": "https://developer.newrelic.com/build-apps/howto-use-nrone-table-components/", + "published_at": "2020-08-19T01:48:30Z", + "updated_at": "2020-08-14T01:46:10Z", + "_index": "520d1d5d14cc8a32e600034b", + "_type": "520d1d5d14cc8a32e600034c", + "_score": 14.661325, + "_version": null, + "_explanation": null, + "sort": null, + "highlight": { + "title": "Add tables to your New Relic One application", + "sections": "Add tables to your New Relic One application", + "info": "Add a table to your New Relic One app.", + "tags": "table in app", + "body": "Add tables to your New Relic One application 30 min Tables are a popular way of displaying data in New Relic applications. For example, with the query builder you can create tables from NRQL queries. Whether you need to have more control over tables or you're importing third-party data, you can" + }, + "id": "5efa989ee7b9d2ad567bab51" + }, + { + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app, you might have some additional setup and configuration. This guide covers: Downloading the New Relic One CLI to build or modify apps Contribute content to this website Before you begin You must have: A github account account - While not strictly necessary for building apps, a GitHub account enables you to download and customize our open source apps, and contribute an open source project. A New Relic developer account - if you don't already have one, you can get a free trial account for developing New Relic applications. npm - If you've installed Node.js, then you already have npm, which is used to share, reuse, and update JavaScript code, and is necessary for working with React components that are the framework for New Relic apps and this website. Tip Use the New Relic One VSCode extension to build your apps. Prepare to build or modify apps Step 1 of 2 Download the CLI and API key On the Build New Relic One applications page, complete the Quick start steps. These six Quick start steps get you an API key for use with developing apps, and the New Relic One CLI, for building and deploying apps. At the end of the Quick start, you have a project consisting of the following: A Nerdpack - The package containing all the files required by your application. It contains two types of files that you customize to build your app: Nerdlets, and the launcher. One or more Nerdlet files - A specific UI view or window. A Nerdlet is a React JavaScript package that includes an index.js file, a stylesheet, and a JSON-format config file. It can contain any JS functionality (charts, interactive fields, tooltips, etc.). A launcher file: This is the basis for the launcher, which is used to open your application from New Relic One after you publish your app. Step 2 of 2 Start building If you're ready to code, cd to your Nerdpack and get started. If you want to learn more about building applications, try these step-by-step guides: Build a \"Hello, World!\" application shows how to create a little application, publish it to New Relic One, and share it with others by subscribing accounts to it. Map pageviews by region takes you through the steps to create one of our popular open source apps. You learn to add a custom query to an app and view it in a table, then add that data to a map. Contributing to developer.newrelic.com This site is open source, and we want your input. Create a pull request if you see a mistake you know how to fix. Drop us a GitHub issue if you see some content gaps you want us to work on. Or write up a whole new guide if you have one you'd like to share. Read on to learn how. Step 1 of 3 Fork the developer-website GithHub repo Forking the repo enables you to work on your own copy of the developer.newrelic.com files, and build the site locally. It also enables us to more easily manage incomimg pull requests. On the developer-website page in GitHub, select the Fork button on the top right of the page, choose the account you want to fork to, and wait a few seconds while the fork is created. Sync regularly to keep your fork up to date with changes and additions to the main branch upstream. Step 2 of 3 Make a feature or documentation request On any page, select the GitHub button at the top of the page, and then select the kind of change you want, and fill out the GitHub form. Step 3 of 3 Contribute a new guide Check out our contributors guidelines, which will walk you through the process.", + "type": "developer", + "document_type": "page", + "info": "Prepare to build apps and contribute to this site", + "sections": [ + "Set up your development environment", + "Before you begin", + "Tip", + "Prepare to build or modify apps", + "Start building" ], - "title": "Query page: Create and edit NRQL queries", + "title": "Set up your development environment", "popularity": 1, - "external_id": "e00d2b865680d15c361b4058e22270fe5103aa8e", - "category_1": "Use Insights UI", - "category_2": "Explore data", + "tags": [ + "developer account", + "API key", + "New Relic One CLI" + ], + "external_id": "c45638a9cd548d1ffffc9f1c7708f115a92ae04a", "image": "", - "url": "https://docs.newrelic.com/docs/insights/use-insights-ui/manage-account-data/query-page-create-edit-nrql-queries", - "published_at": "2020-08-18T10:41:24Z", - "updated_at": "2020-07-26T08:08:39Z", - "category_0": "Insights", + "url": "https://developer.newrelic.com/build-apps/set-up-dev-env/", + "published_at": "2020-08-19T01:44:48Z", + "updated_at": "2020-08-19T01:44:47Z", + "_index": "520d1d5d14cc8a32e600034b", + "_type": "520d1d5d14cc8a32e600034c", + "_score": 13.0581255, + "_version": null, + "_explanation": null, + "sort": null, + "highlight": { + "sections": "Prepare to build or modify apps", + "info": "Prepare to build apps and contribute to this site", + "tags": "New Relic One CLI", + "body": "Set up your development environment 20 min If you've decided to build a custom app or modify one of our open source apps, you need a few essential tools: The New Relic One command line interface (CLI) An API key, which you get when you download the CLI Depending on what you want to do with your app" + }, + "id": "5efa9973e7b9d242237bab39" + }, + { + "body": "Add the NerdGraphQuery component to an application 20 minutes This guide steps you through the process of adding the `NerdGraphQuery` component to a sample transaction overview application. This allows you to query data from your New Relic account and add it to a dropdown menu. NerdGraph is our GraphQL implementation. GraphQL has some key differences when compared to REST: The client, not the server, determines what data is returned. You can easily collect data from multiple sources. For example, in a single query, you can get account information, infrastructure data, and issue a NRQL request. Note Before completing this exercise, you can experiment with GraphQL queries in our NerdGraph API explorer. We also have a 14-minute video that covers the steps below. Before you begin To develop projects, you need our New Relic One CLI (command line interface). If you haven't already installed it, do the following: Install Node.js. Complete steps 1–4 of our CLI quick start, and be sure to make a copy of your account ID from step 1 because you’ll need it later. Note If you've already installed the New Relic One CLI, but you can't remember your account ID, start the CLI quick start again, and then click the Get your API key down arrow. The account ID is the number preceding your account name. For additional details, see Set up your development environment. Prepare the sample code To get started, complete these steps to update the application UUID (unique ID) and run the sample application locally: Step 1 of 7 If you haven't already done so, clone the example applications from our how-to GitHub repo. Here's an example using HTTPS: git clone https://github.com/newrelic/nr1-how-to.git Copy Step 2 of 7 Change to the directory use-nerdgraph-nerdlet: cd nr1-how-to/use-nerdgraph/nerdlets/use-nerdgraph-nerdlet Copy Step 3 of 7 In your preferred text editor, open index.js. Step 4 of 7 Replace with your account id: Note Your account ID is available in the CLI quick start (see Before you begin). this.accountId = ; Copy Step 5 of 7 Change to the /nr1-howto/use-nerdgraph directory: cd ../.. Copy Step 6 of 7 Execute these commands to update the UUID and serve the sample application: nr1 nerdpack:uuid -gf nr1 nerdpack:serve Copy Step 7 of 7 Once the sample application is successfully served, go to the local New Relic One homepage (https://one.newrelic.com/?nerdpacks=local), click Apps, and then click Use NerdGraph. After launching the Use NerdGraph application, you see a dashboard that gives an overview of the transactions in your account: Add the NerdGraphQuery component Now you can create a dropdown menu for changing the account the application is viewing. The first step is to import the NerdGraphQuery component into the application's index.js file. Note If you need more details about our example below, see the APIs and components page on https://developer.newrelic.com Step 1 of 3 Add the NerdGraphQuery component into the first StackItem inside of the return in the index.js file: {({ loading, error, data }) => { console.log({ loading, error, data }); if (loading) { return ; } if (error) { return 'Error!'; } return null; }} ; Copy Step 2 of 3 The NerdGraphQuery component takes a query object that states the source you want to access and the data you want returned. Add the following code to your index.js file in the render method: Note In the browser console, you can see the data from your query returned in an object that follows the same structure of the object in the initial query. const query = ` query($id: Int!) { actor { account(id: $id) { name } } } `; Copy Step 3 of 3 To take the data returned by the NerdGraph query and display it in the application, replace the return null in the current NerdGraphQuery component with this return statement: return {data.actor.account.name} Apps:; Copy When you go back to the browser and view your application, you see a new headline showing the name of your account returned from NerdGraph: How to use NerdGraphQuery.query At this point, you have implemented the NerdGraphQuery component with the application's render method and displayed the return data within the transaction overview application. Here's what you need to do next: Query NerdGraph inside of the componentDidMount lifecycle method. Save the returned data for later use in the application. Step 1 of 2 This code takes the response from NerdGraph and makes sure the results are processed, stored into the application state, and logged to the browser console for viewing. Add this code into the index.js file just under the constructor: componentDidMount() { const accountId = this.state; const gql = `{ actor { accounts { id name } } }`; const accounts = NerdGraphQuery.query({query: gql}) //The NerdGraphQuery.query method called with the query object to get your account data is stored in the accounts variable. accounts.then(results => { console.log('Nerdgraph Response:', results); const accounts = results.data.actor.accounts.map(account => { return account; }); const account = accounts.length > 0 && accounts[0]; this.setState({ selectedAccount: account, accounts }); }).catch((error) => { console.log('Nerdgraph Error:', error); }) } Copy Step 2 of 2 After the data is stored into state, display a selection so users can change accounts and update the application. To do this, add this code to index.js for the second StackItem in the return statement: { accounts && ( ); } Copy Review the results of the NerdGraph query After you complete these steps, look at the application in your browser, and note the following: The dropdown menu now displays the data returned from the NerdGraphQuery.query and allows you to select an account. After you select a new account, the application shows data from the new selection. The final index.js file should have code similar to the code below. This completed sample is in your nerdlet final.js. import React from 'react'; import { PlatformStateContext, NerdGraphQuery, Spinner, HeadingText, Grid, GridItem, Stack, StackItem, Select, SelectItem, AreaChart, TableChart, PieChart } from 'nr1' import { timeRangeToNrql } from '@newrelic/nr1-community'; // https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction export default class UseNerdgraphNerdletNerdlet extends React.Component { constructor(props){ super(props) this.state = { accountId: , accounts: null, selectedAccount: null, } } componentDidMount() { const accountId = this.state; const gql = `{ actor { accounts { id name } } }`; const accounts = NerdGraphQuery.query({ query: gql }) accounts.then(results => { console.log('Nerdgraph Response:', results); const accounts = results.data.actor.accounts.map(account => { return account; }); const account = accounts.length > 0 && accounts[0]; this.setState({ selectedAccount: account, accounts }); }).catch((error) => { console.log('Nerdgraph Error:', error); }) } selectAccount(option) { this.setState({ accountId: option.id, selectedAccount: option }); } render() { const { accountId, accounts, selectedAccount } = this.state; console.log({ accountId, accounts, selectedAccount }); const query = ` query($id: Int!) { actor { account(id: $id) { name } } } `; const variables = { id: accountId, }; const avgResTime = `SELECT average(duration) FROM Transaction FACET appName TIMESERIES AUTO `; const trxOverview = `FROM Transaction SELECT count(*) as 'Transactions', apdex(duration) as 'apdex', percentile(duration, 99, 95) FACET appName `; const errCount = `FROM TransactionError SELECT count(*) as 'Transaction Errors' FACET error.message `; const responseCodes = `SELECT count(*) as 'Response Code' FROM Transaction FACET httpResponseCode `; return ( {({loading, error, data}) => { if (loading) { return ; } if (error) { return 'Error!'; } return {data.actor.account.name} Apps:; }} {accounts && }
{(PlatformState) => { /* Taking a peek at the PlatformState */ const since = timeRangeToNrql(PlatformState); return ( <>
Transaction Overview
Average Response Time
Response Code
Transaction Errors
); }}
) } } Copy Summary Now that you've completed all the steps in this example, you've successfully queried data from your account using the NerdGraphQuery component in two methods: Using the NerdGraphQuery component inside the application's render method and then passing the returned data into the children's components. Using the NerdGraphQuery.query method to query data before the application renders.", + "type": "developer", + "document_type": "page", + "info": "The NerdGraphQuery component allows you to query data from your account and add it to a dropdown menu in an application", + "sections": [ + "Add the NerdGraphQuery component to an application", + "Note", + "Before you begin", + "Prepare the sample code", + "Add the NerdGraphQuery component", + "How to use NerdGraphQuery.query", + "Review the results of the NerdGraph query", + "Summary" + ], + "title": "Add the NerdGraphQuery component to an application", + "popularity": 1, + "tags": [ + "nerdgraphquery component", + "transaction overview app", + "query account data", + "drop-down menu", + "NerdGraphQuery.query method" + ], + "external_id": "6bd6c8a72eab352a3e8f4332570e286c7831ba84", + "image": "https://developer.newrelic.com/static/5dcf6e45874c1fa40bb6f21151af0c24/b01d9/no-name.png", + "url": "https://developer.newrelic.com/build-apps/add-nerdgraphquery-guide/", + "published_at": "2020-08-19T01:48:31Z", + "updated_at": "2020-08-19T01:48:30Z", + "_index": "520d1d5d14cc8a32e600034b", + "_type": "520d1d5d14cc8a32e600034c", + "_score": 11.7240925, + "_version": null, + "_explanation": null, + "sort": null, + "highlight": { + "title": "Add the NerdGraphQuery component to an application", + "sections": "Add the NerdGraphQuery component to an application", + "info": "The NerdGraphQuery component allows you to query data from your account and add it to a dropdown menu in an application", + "tags": "nerdgraphquery component", + "body": " { PlatformStateContext, NerdGraphQuery, Spinner, HeadingText, Grid, GridItem, Stack, StackItem, Select, SelectItem, AreaChart, TableChart, PieChart } from 'nr1' import { timeRangeToNrql } from '@newrelic/nr1-community'; // https://docs.newrelic.com/docs/new-relic-programmable-platform-introduction" + }, + "id": "5efa993c64441ff4865f7e32" + }, + { + "body": "Query and store data 10 min To help you build a New Relic One application, we provide you with the New Relic One SDK. Here you can learn how to use the SDK query components, which allow you to make queries and mutations via NerdGraph, our GraphQL endpoint. Query-related React components can be identified by the Query suffix. Mutation-related components can be identified by the Mutation prefix. Components overview Our data components are based on React Apollo. The most basic component is NerdGraphQuery, which accepts any GraphQL (or GraphQL AST generated by the graphql-tag library as the query parameter, and a set of query variables passed as variables. Over this query, we have created an additional set of queries, which can be divided into four groups: User queries: These allow you to query the current user and its associated accounts. Components in this category: UserStorageQuery and AccountsQuery. Entities queries: Because New Relic One is entity-centric, we use queries to make access to your entities easier. You can count, search, list, query, and favorite them. Components in this category: EntityCountQuery, EntitySearchQuery, EntitiesByDomainTypeQuery, EntitiesByGuidsQuery, EntityByGuidQuery, EntityByNameQuery. Storage queries: New Relic One provides a simple storage mechanism that we call NerdStorage. This can be used by Nerdpack creators to store application configuration setting data, user-specific data, and other small pieces of data. Components in this category: UserStorageQuery, AccountStorageQuery, EntityStorageQuery, UserStorageMutation, AccountStorageMutation, and EntityStorageMutation. For details, see NerdStorage. NRQL queries: To be able to query your New Relic data via NRQL (New Relic Query Language), we provide a NrqlQuery component. This component can return data in different formats, so that you can use it for charting and not only for querying. Query components All query components accept a function as a children prop where the different statuses can be passed. This callback receives an object with the following properties: loading: Boolean that is set to true when data fetching is happening. Our components use the cache-and-network strategy, meaning that after the data has loaded, subsequent data reloads might be triggered first with stale data, then refreshed when the most recent data has arrived. data: Root property where the data requested is retrieved. The structure matches a root structure based on the NerdGraph schema. This is true even for highly nested data structures, which means you’ll have to traverse down to find the desired data. error: Contains an Error instance when the query fails. Set to undefined when data is loading or the fetch was successful. fetchMore: Callback function that can be called when the query is being loaded in chunks. The function will only be present when it’s feasible to do so, more data is available, and no fetchMore has already been triggered. Data is loaded in batches of 200 by default. Other components provided by the platform (like the Dropdown or the List) are capable of accepting fetchMore, meaning you can combine them easily. Mutation components Mutation components also accept a children as a function, like the query ones. The mutation can be preconfigured at the component level, and a function is passed back that you can use in your component. This is the standard React Apollo approach for performing mutations, but you might find it easier to use our static mutation method added to the component. More on this topic below. Static methods All of the described components also expose a static method so that they can be used imperatively rather than declaratively. All Query components have a static Query method, and all Mutation components have a mutation method. These static methods accept the same props as their query component, but passed as an object. For example: // Declarative way (using components). function renderAccountList() { return (
    ({data, error}) => { if (error) { return
  • Failed to retrieve list: {error.message}
  • ; } return data.map((account) => {
  • {account.name}
  • }); }}
); } // Imperative way (using promises). async function getAccountList() { let data = {}; try { data = await AccountsQuery.query(); } catch (error) { console.log('Failed to retrieve list: ' + error.message); return; } return data.actor.accounts.map((account) => { return account.name; }); } Copy Similarly, a mutation can happen either way; either declaratively or imperatively. NrqlQuery NrqlQuery deserves additional explanation, because there are multiple formats in which you can return data from it. To provide maximum functionality, all three are exposed through a formatType property. You can find its different values under NrqlQuery.formatType: NERD_GRAPH: Returns the format in which it arrives from NerdGraph. RAW: The format exposed by default in Insights and dashboards when being plotted as JSON. This format is useful if you have a pre-existing script in this format that you're willing to migrate to or incorporate with. CHART: The format used by the charting engine that we also expose. You can find a more detailed explanation of how to manipulate this format in the guide to chart components, and some examples. If you are willing to push data, we currently do not expose NrqlMutation. To do that, see the Event API for how to add custom events.", + "type": "developer", + "document_type": "page", + "info": "Reference guide for SDK query components using NerdGraph", + "sections": [ + "Query and store data", + "Components overview", + "Query components", + "Mutation components", + "Static methods", + "NrqlQuery" + ], + "title": "Query and store data", + "popularity": 1, + "tags": [ + "nerdgraph query components", + "mutation components", + "static methods" + ], + "external_id": "cbbf363393edeefbc4c08f9754b43d38fd911026", + "image": "", + "url": "https://developer.newrelic.com/explore-docs/query-and-store-data/", + "published_at": "2020-08-19T01:51:37Z", + "updated_at": "2020-08-01T01:42:02Z", "_index": "520d1d5d14cc8a32e600034b", "_type": "520d1d5d14cc8a32e600034c", - "_score": 0.09991312, + "_score": 11.651957, "_version": null, "_explanation": null, "sort": null, "highlight": { - "title": "Query page: Create and edit NRQL queries", - "sections": "Explore data", - "info": "Use the New Relic Insights Query page to create and edit NRQL queries, favorite them for later use, and add query results to dashboards. ", - "category_2": "Explore data", - "body": "New Relic Insights' Query page is one place you can run NRQL queries of your data. To get started: Go to insights.newrelic.com > Query, then use any of the available NRQL syntax and functions. Use the Query page to: Create and run queries of your data. View your query history. View favorite queries", - "breadcrumb": "Contents / Insights / Use Insights UI / Explore data" + "title": "Query and store data", + "sections": "Query components", + "info": "Reference guide for SDK query components using NerdGraph", + "tags": "nerdgraph query components", + "body": "Query and store data 10 min To help you build a New Relic One application, we provide you with the New Relic One SDK. Here you can learn how to use the SDK query components, which allow you to make queries and mutations via NerdGraph, our GraphQL endpoint. Query-related React components can" }, - "id": "59425a3c8e9c0f6937f1cda9" + "id": "5efa989e28ccbc2f15307deb" } ] } \ No newline at end of file From b3189f869613a66330193426b79b55e35400b9fe Mon Sep 17 00:00:00 2001 From: John P Vajda Date: Wed, 19 Aug 2020 19:27:12 -0600 Subject: [PATCH 15/25] review feedback --- .../collect-data/get-started-nerdgraph-api-explorer.mdx | 2 +- src/markdown-pages/collect-data/query-data-nrql.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/markdown-pages/collect-data/get-started-nerdgraph-api-explorer.mdx b/src/markdown-pages/collect-data/get-started-nerdgraph-api-explorer.mdx index d73ea5c8b..8a409b607 100644 --- a/src/markdown-pages/collect-data/get-started-nerdgraph-api-explorer.mdx +++ b/src/markdown-pages/collect-data/get-started-nerdgraph-api-explorer.mdx @@ -10,7 +10,7 @@ tileShorthand: redirects: - /technology/graphql resources: - - title: 'Introduction to New Relic NerdGraph' + - title: 'Introduction to NerdGraph' url: https://docs.newrelic.com/docs/apis/nerdgraph/get-started/introduction-new-relic-nerdgraph - title: 'NerdGraph tutorials' url: https://docs.newrelic.com/docs/apis/nerdgraph/tutorials diff --git a/src/markdown-pages/collect-data/query-data-nrql.mdx b/src/markdown-pages/collect-data/query-data-nrql.mdx index d6ff024cc..c1e349813 100644 --- a/src/markdown-pages/collect-data/query-data-nrql.mdx +++ b/src/markdown-pages/collect-data/query-data-nrql.mdx @@ -10,7 +10,7 @@ tileShorthand: redirects: - /technology/nrql resources: - - title: 'New Relic One NRQL Lessons' + - title: 'NRQL lessons' url: https://opensource.newrelic.com/projects/newrelic/nr1-learn-nrql tags: - NRQL From 900d8395857ce2e40e23542ffc9a6745151766ee Mon Sep 17 00:00:00 2001 From: John P Vajda Date: Wed, 19 Aug 2020 19:49:18 -0600 Subject: [PATCH 16/25] added screenshot and site yaml file --- sites.yml | 0 src/screenshots/developer-home.png | Bin 0 -> 268098 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 sites.yml create mode 100644 src/screenshots/developer-home.png diff --git a/sites.yml b/sites.yml new file mode 100644 index 000000000..e69de29bb diff --git a/src/screenshots/developer-home.png b/src/screenshots/developer-home.png new file mode 100644 index 0000000000000000000000000000000000000000..c76198ba83135d7680fe96c47e95b19cbf8a4165 GIT binary patch literal 268098 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

` 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 TAI(WS00000NkvXXu0mjfI9idG literal 0 HcmV?d00001 From 82d4ebca8bcc7398709b19b128b344d3e3b9d0fa Mon Sep 17 00:00:00 2001 From: John P Vajda Date: Wed, 19 Aug 2020 19:50:36 -0600 Subject: [PATCH 17/25] updated screenshot url --- sites.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/sites.yml b/sites.yml index e69de29bb..02ddb1adf 100644 --- a/sites.yml +++ b/sites.yml @@ -0,0 +1,31 @@ +- title: New Relic Developer Site + + # this is the URL that is linked from the showcase + main_url: https://developer.newrelic.com/ + + # this URL is used to generate a screenshot + url: https://github.com/newrelic/developer-website/screenshots + + # optional: for open-source sites, this URL points to the repo that powers the site + source_url: https://github.com/newrelic/developer-website + + # optional: short paragraph describing the content and/or purpose of the site that will appear in the modal detail view and permalink views for your site + description: The world’s best engineering teams rely on New Relic to visualize, + analyze and troubleshoot their software. New Relic One is the most powerful + cloud-based observability platform built to help companies create more perfect software. + + + # You can list as many categories as you want here. Check list of Categories below in this doc! + # If you'd like to create a new category, simply list it here. + categories: + - Data + - Programming + - Open Source + - Technology + + # Add the name (developer or company) and URL (e.g. Twitter, GitHub, portfolio) to be used for attribution + built_by: New Relic + built_by_url: https://www.newrelic.com + + # leave as false, the Gatsby site review board will choose featured sites quarterly + featured: false From 29c936eaa4e27243b4626769b02997158d68dcd0 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Thu, 20 Aug 2020 04:52:28 +0000 Subject: [PATCH 18/25] fix: upgrade @mdx-js/react from 1.6.14 to 1.6.16 Snyk has created this PR to upgrade @mdx-js/react from 1.6.14 to 1.6.16. See this package in npm: https://www.npmjs.com/package/@mdx-js/react See this project in Snyk: https://app.snyk.io/org/github-newrelic/project/868cac7a-942a-4cb5-a87b-05381c8ca7ec?utm_source=github&utm_medium=upgrade-pr --- package-lock.json | 16 +++++++++++++--- package.json | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3904e3921..eb3001216 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4072,9 +4072,9 @@ } }, "@mdx-js/react": { - "version": "1.6.14", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-1.6.14.tgz", - "integrity": "sha512-WN4OWXiSTN5x1Ee0ZeYQ9bjjSSgH3Mfx/ezcSV3T691C/PcHTNWwJa5qhcuq8V/NrVAeMc26aXuSdOAq6sRb1g==" + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-1.6.16.tgz", + "integrity": "sha512-+FhuSVOPo7+4fZaRwWuCSRUcZkJOkZu0rfAbBKvoCg1LWb1Td8Vzi0DTLORdSvgWNbU6+EL40HIgwTOs00x2Jw==" }, "@mdx-js/runtime": { "version": "1.6.6", @@ -4151,6 +4151,16 @@ "react-spring": "^8.0.27", "use-dark-mode": "^2.3.1", "use-media": "^1.4.0" + }, + "dependencies": { + "gatsby-plugin-newrelic": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/gatsby-plugin-newrelic/-/gatsby-plugin-newrelic-1.0.2.tgz", + "integrity": "sha512-TWVysdMSuSRbzAAdHK+aZYxmMPQJDygvT1sKApApJBhVQ79ElBRiBnqIE5vDU26WH6sjqaxf8RlZFzmNWZ6n+A==", + "requires": { + "@babel/runtime": "^7.0.0" + } + } } }, "@nodelib/fs.scandir": { diff --git a/package.json b/package.json index f4476b90c..425871fce 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "@emotion/core": "^10.0.28", "@emotion/styled": "^10.0.27", "@mdx-js/mdx": "^1.6.10", - "@mdx-js/react": "^1.6.14", + "@mdx-js/react": "^1.6.16", "@newrelic/gatsby-theme-newrelic": "^1.7.1", "classnames": "^2.2.6", "date-fns": "^2.15.0", From 4529dd3d7890ff1f0bef0adea2ecb80bd55b0fec Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Thu, 20 Aug 2020 04:52:37 +0000 Subject: [PATCH 19/25] fix: upgrade gatsby-image from 2.4.13 to 2.4.14 Snyk has created this PR to upgrade gatsby-image from 2.4.13 to 2.4.14. See this package in npm: https://www.npmjs.com/package/gatsby-image See this project in Snyk: https://app.snyk.io/org/github-newrelic/project/868cac7a-942a-4cb5-a87b-05381c8ca7ec?utm_source=github&utm_medium=upgrade-pr --- package-lock.json | 22 ++++++++++++++++------ package.json | 2 +- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3904e3921..fcae647b7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4151,6 +4151,16 @@ "react-spring": "^8.0.27", "use-dark-mode": "^2.3.1", "use-media": "^1.4.0" + }, + "dependencies": { + "gatsby-plugin-newrelic": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/gatsby-plugin-newrelic/-/gatsby-plugin-newrelic-1.0.2.tgz", + "integrity": "sha512-TWVysdMSuSRbzAAdHK+aZYxmMPQJDygvT1sKApApJBhVQ79ElBRiBnqIE5vDU26WH6sjqaxf8RlZFzmNWZ6n+A==", + "requires": { + "@babel/runtime": "^7.0.0" + } + } } }, "@nodelib/fs.scandir": { @@ -13266,9 +13276,9 @@ } }, "gatsby-image": { - "version": "2.4.13", - "resolved": "https://registry.npmjs.org/gatsby-image/-/gatsby-image-2.4.13.tgz", - "integrity": "sha512-j9FIH+EUY6oWQdcNr5Xb87VGsdT/dztqB0wKkMqboIIqPoK/Zdzvd2cUbLIYVOI9zOSsFNDoVsHqe/M0bfu4HA==", + "version": "2.4.14", + "resolved": "https://registry.npmjs.org/gatsby-image/-/gatsby-image-2.4.14.tgz", + "integrity": "sha512-JO4Ul+EMCCPS0FddFc8USCDl5roUZDOXg8x99DxE0UShuZTEAtkn+kb8KzpvtPlnwt/0YwBUpcvVrat3yAVz2w==", "requires": { "@babel/runtime": "^7.10.3", "object-fit-images": "^3.2.4", @@ -13276,9 +13286,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.0.tgz", - "integrity": "sha512-qArkXsjJq7H+T86WrIFV0Fnu/tNOkZ4cgXmjkzAu3b/58D5mFIO8JH/y77t7C9q0OdDRdh9s7Ue5GasYssxtXw==", + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.2.tgz", + "integrity": "sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==", "requires": { "regenerator-runtime": "^0.13.4" } diff --git a/package.json b/package.json index f4476b90c..173e6d2d6 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "date-fns": "^2.15.0", "eslint-plugin-react-hooks": "^4.0.8", "gatsby": "^2.24.2", - "gatsby-image": "^2.4.13", + "gatsby-image": "^2.4.14", "gatsby-plugin-clearbit": "^1.1.0", "gatsby-plugin-emotion": "^4.3.10", "gatsby-plugin-google-analytics": "^2.3.10", From 46f31d45e138d8a6fd16b46a14a753756258fb84 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Thu, 20 Aug 2020 10:11:45 -0700 Subject: [PATCH 20/25] chore: disable branch protections when pushing the changelog, then re-enable --- .github/workflows/release.yml | 41 +++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9b8535094..297ba4110 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -100,6 +100,25 @@ jobs: echo "No change in package.json, not regenerating third-party notices" fi + - name: Temporarily disable "required_pull_request_reviews" branch protection + id: disable-branch-protection + if: always() + uses: actions/github-script@v1 + with: + github-token: ${{ secrets.OPENSOURCE_BOT_TOKEN }} + previews: luke-cage-preview + script: | + const result = await github.repos.updateBranchProtection({ + owner: context.repo.owner, + repo: context.repo.repo, + branch: 'main', + required_status_checks: null, + restrictions: null, + enforce_admins: null, + required_pull_request_reviews: null + }) + console.log("Result:", result) + - name: Push Commit if: steps.generate-notices.outputs.commit == 'true' uses: ad-m/github-push-action@v0.6.0 @@ -107,6 +126,28 @@ jobs: github_token: ${{ secrets.OPENSOURCE_BOT_TOKEN }} branch: main + - name: Re-enable "required_pull_request_reviews" branch protection + id: enable-branch-protection + if: always() + uses: actions/github-script@v1 + with: + github-token: ${{ secrets.OPENSOURCE_BOT_TOKEN }} + previews: luke-cage-preview + script: | + const result = await github.repos.updateBranchProtection({ + owner: context.repo.owner, + repo: context.repo.repo, + branch: 'main', + required_status_checks: null, + restrictions: null, + enforce_admins: true, + required_pull_request_reviews: { + dismiss_stale_reviews: true, + required_approving_review_count: 1 + } + }) + console.log("Result:", result) + generate-changelog: runs-on: ubuntu-latest needs: [checkout-and-build, generate-third-party-notices] From f814fbf724b9979052413d7f0e79d8273e77c871 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Thu, 20 Aug 2020 10:34:25 -0700 Subject: [PATCH 21/25] chore: fix eslint errors preventing pushes --- src/pages/nerd-days.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/pages/nerd-days.js b/src/pages/nerd-days.js index b1364bfc5..0ec131a3e 100644 --- a/src/pages/nerd-days.js +++ b/src/pages/nerd-days.js @@ -9,8 +9,7 @@ import '../components/marketo.scss'; const NerdDaysPage = () => { useEffect(() => { - // eslint-disable-next-line no-undef - MktoForms2.loadForm('//app-abj.marketo.com', '412-MZS-894', 3525); + window.MktoForms2.loadForm('//app-abj.marketo.com', '412-MZS-894', 3525); const pollForDefinition = function (scope, varname, callback) { if (typeof scope[varname] !== 'undefined') { @@ -34,8 +33,7 @@ const NerdDaysPage = () => { // eslint-disable-next-line no-console console.log('Clearbit Form JS unable to load'); pollForDefinition(window, 'MktoForms2', function () { - // eslint-disable-next-line no-undef - MktoForms2.whenReady(function (form) { + window.MktoForms2.whenReady(function (form) { form.setValues({ clearbitFormStatus: 'Clearbit Form JS unable to load', }); @@ -79,8 +77,8 @@ const NerdDaysPage = () => { Submit your proposals {' '} - by September 1, 2020 at 11:59 PM PT. Accepted proposals will contacted by September 30, 2020 at - the latest. + by September 1, 2020 at 11:59 PM PT. Accepted proposals will + contacted by September 30, 2020 at the latest.

From cca5b4ad26b1a5a2793db437134d583edca28560 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Thu, 20 Aug 2020 10:54:14 -0700 Subject: [PATCH 22/25] chore: add missed branch protection changes for other jobs --- .github/workflows/fetch-related-content.yml | 41 +++++++++++++++++++++ .github/workflows/release.yml | 41 +++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/.github/workflows/fetch-related-content.yml b/.github/workflows/fetch-related-content.yml index f6a437aa8..5a949f58d 100644 --- a/.github/workflows/fetch-related-content.yml +++ b/.github/workflows/fetch-related-content.yml @@ -47,9 +47,50 @@ jobs: git commit -m 'chore(related-content): updated related content data' echo "::set-output name=commit::true" + - name: Temporarily disable "required_pull_request_reviews" branch protection + id: disable-branch-protection + if: always() + uses: actions/github-script@v1 + with: + github-token: ${{ secrets.OPENSOURCE_BOT_TOKEN }} + previews: luke-cage-preview + script: | + const result = await github.repos.updateBranchProtection({ + owner: context.repo.owner, + repo: context.repo.repo, + branch: 'main', + required_status_checks: null, + restrictions: null, + enforce_admins: null, + required_pull_request_reviews: null + }) + console.log("Result:", result) + - name: Push Commit if: steps.commit-changes.outputs.commit == 'true' uses: ad-m/github-push-action@v0.6.0 with: github_token: ${{ secrets.OPENSOURCE_BOT_TOKEN }} branch: main + + - name: Re-enable "required_pull_request_reviews" branch protection + id: enable-branch-protection + if: always() + uses: actions/github-script@v1 + with: + github-token: ${{ secrets.OPENSOURCE_BOT_TOKEN }} + previews: luke-cage-preview + script: | + const result = await github.repos.updateBranchProtection({ + owner: context.repo.owner, + repo: context.repo.repo, + branch: 'main', + required_status_checks: null, + restrictions: null, + enforce_admins: true, + required_pull_request_reviews: { + dismiss_stale_reviews: true, + required_approving_review_count: 1 + } + }) + console.log("Result:", result) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 297ba4110..e9201869b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -176,6 +176,25 @@ jobs: - name: Install Dependencies run: npm ci + - name: Temporarily disable "required_pull_request_reviews" branch protection + id: disable-branch-protection + if: always() + uses: actions/github-script@v1 + with: + github-token: ${{ secrets.OPENSOURCE_BOT_TOKEN }} + previews: luke-cage-preview + script: | + const result = await github.repos.updateBranchProtection({ + owner: context.repo.owner, + repo: context.repo.repo, + branch: 'main', + required_status_checks: null, + restrictions: null, + enforce_admins: null, + required_pull_request_reviews: null + }) + console.log("Result:", result) + - name: Semantic Release env: # Use nr-opensource-bot for authoring commits done by @@ -186,3 +205,25 @@ jobs: GIT_COMMITTER_EMAIL: ${{ env.BOT_EMAIL }} GITHUB_TOKEN: ${{ secrets.OPENSOURCE_BOT_TOKEN }} run: npx semantic-release + + - name: Re-enable "required_pull_request_reviews" branch protection + id: enable-branch-protection + if: always() + uses: actions/github-script@v1 + with: + github-token: ${{ secrets.OPENSOURCE_BOT_TOKEN }} + previews: luke-cage-preview + script: | + const result = await github.repos.updateBranchProtection({ + owner: context.repo.owner, + repo: context.repo.repo, + branch: 'main', + required_status_checks: null, + restrictions: null, + enforce_admins: true, + required_pull_request_reviews: { + dismiss_stale_reviews: true, + required_approving_review_count: 1 + } + }) + console.log("Result:", result) From 97c2dec84ea83fd25c901865359acdff8c6e0870 Mon Sep 17 00:00:00 2001 From: nr-opensource-bot Date: Thu, 20 Aug 2020 18:46:20 +0000 Subject: [PATCH 23/25] chore(release): 1.13.6 ## [1.13.6](https://github.com/newrelic/developer-website/compare/v1.13.5...v1.13.6) (2020-08-20) ### Bug Fixes * upgrade @mdx-js/react from 1.6.14 to 1.6.16 ([29c936e](https://github.com/newrelic/developer-website/commit/29c936eaa4e27243b4626769b02997158d68dcd0)) * upgrade gatsby-image from 2.4.13 to 2.4.14 ([4529dd3](https://github.com/newrelic/developer-website/commit/4529dd3d7890ff1f0bef0adea2ecb80bd55b0fec)) --- CHANGELOG.md | 8 ++++++++ package-lock.json | 2 +- package.json | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf06e45d1..93235d0c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## [1.13.6](https://github.com/newrelic/developer-website/compare/v1.13.5...v1.13.6) (2020-08-20) + + +### Bug Fixes + +* upgrade @mdx-js/react from 1.6.14 to 1.6.16 ([29c936e](https://github.com/newrelic/developer-website/commit/29c936eaa4e27243b4626769b02997158d68dcd0)) +* upgrade gatsby-image from 2.4.13 to 2.4.14 ([4529dd3](https://github.com/newrelic/developer-website/commit/4529dd3d7890ff1f0bef0adea2ecb80bd55b0fec)) + ## [1.13.5](https://github.com/newrelic/developer-website/compare/v1.13.4...v1.13.5) (2020-08-19) diff --git a/package-lock.json b/package-lock.json index 19f426059..7b26ce63d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "developer-website", - "version": "1.13.5", + "version": "1.13.6", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index c24ce492e..298eeca4e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "developer-website", "private": true, - "version": "1.13.5", + "version": "1.13.6", "dependencies": { "@emotion/core": "^10.0.28", "@emotion/styled": "^10.0.27", From ca696e49ef0f18a03b5fb3957853fdff6d8f9bee Mon Sep 17 00:00:00 2001 From: John P Vajda Date: Thu, 20 Aug 2020 14:54:48 -0600 Subject: [PATCH 24/25] cleaned up sites.yml file --- sites.yml | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/sites.yml b/sites.yml index 02ddb1adf..71ddf3d28 100644 --- a/sites.yml +++ b/sites.yml @@ -1,31 +1,15 @@ - title: New Relic Developer Site - - # this is the URL that is linked from the showcase main_url: https://developer.newrelic.com/ - - # this URL is used to generate a screenshot url: https://github.com/newrelic/developer-website/screenshots - - # optional: for open-source sites, this URL points to the repo that powers the site source_url: https://github.com/newrelic/developer-website - - # optional: short paragraph describing the content and/or purpose of the site that will appear in the modal detail view and permalink views for your site description: The world’s best engineering teams rely on New Relic to visualize, analyze and troubleshoot their software. New Relic One is the most powerful cloud-based observability platform built to help companies create more perfect software. - - - # You can list as many categories as you want here. Check list of Categories below in this doc! - # If you'd like to create a new category, simply list it here. categories: - Data - Programming - Open Source - Technology - - # Add the name (developer or company) and URL (e.g. Twitter, GitHub, portfolio) to be used for attribution built_by: New Relic built_by_url: https://www.newrelic.com - - # leave as false, the Gatsby site review board will choose featured sites quarterly - featured: false + featured: false \ No newline at end of file From 4b4209ac10a728d14c4a47f35b518ca0e6d1ad7e Mon Sep 17 00:00:00 2001 From: nr-opensource-bot Date: Thu, 20 Aug 2020 22:34:46 +0000 Subject: [PATCH 25/25] chore(release): 1.13.7 ## [1.13.7](https://github.com/newrelic/developer-website/compare/v1.13.6...v1.13.7) (2020-08-20) ### Bug Fixes * upgrade @mdx-js/mdx from 1.6.10 to 1.6.13 ([2ca8bd0](https://github.com/newrelic/developer-website/commit/2ca8bd0e82062c2b1b27116682018f1024cf95e7)) * upgrade multiple dependencies with Snyk ([d194e87](https://github.com/newrelic/developer-website/commit/d194e87ae94a69bef0e5adb885a65c5fb95a65ab)) --- CHANGELOG.md | 8 ++++++++ package-lock.json | 2 +- package.json | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93235d0c0..636e42343 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## [1.13.7](https://github.com/newrelic/developer-website/compare/v1.13.6...v1.13.7) (2020-08-20) + + +### Bug Fixes + +* upgrade @mdx-js/mdx from 1.6.10 to 1.6.13 ([2ca8bd0](https://github.com/newrelic/developer-website/commit/2ca8bd0e82062c2b1b27116682018f1024cf95e7)) +* upgrade multiple dependencies with Snyk ([d194e87](https://github.com/newrelic/developer-website/commit/d194e87ae94a69bef0e5adb885a65c5fb95a65ab)) + ## [1.13.6](https://github.com/newrelic/developer-website/compare/v1.13.5...v1.13.6) (2020-08-20) diff --git a/package-lock.json b/package-lock.json index ee9c83a90..3a8c8ebad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "developer-website", - "version": "1.13.6", + "version": "1.13.7", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index c52feffed..b333d466b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "developer-website", "private": true, - "version": "1.13.6", + "version": "1.13.7", "dependencies": { "@emotion/core": "^10.0.28", "@emotion/styled": "^10.0.27",