From d2877c17c7c2f4432b2ce4056c94200a2e7334b2 Mon Sep 17 00:00:00 2001 From: Bob Evans Date: Wed, 12 Jun 2024 12:12:38 -0400 Subject: [PATCH] chore: Added a script that generates Dashboard json for reporting on libraries by version (#2267) --- dashboards/constants.js | 71 ++ dashboards/generate-library-usage.js | 49 + dashboards/library-usage.json | 1666 ++++++++++++++++++++++++++ dashboards/utils.js | 116 ++ 4 files changed, 1902 insertions(+) create mode 100644 dashboards/constants.js create mode 100644 dashboards/generate-library-usage.js create mode 100644 dashboards/library-usage.json create mode 100644 dashboards/utils.js diff --git a/dashboards/constants.js b/dashboards/constants.js new file mode 100644 index 0000000000..358f536448 --- /dev/null +++ b/dashboards/constants.js @@ -0,0 +1,71 @@ +/* + * Copyright 2024 New Relic Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +'use strict' +const INSTRUMENTED_LIBRARIES = [ + '@apollo/gateway', + '@apollo/server', + '@aws-sdk/client-bedrock-runtime', + '@aws-sdk/client-dynamodb', + '@aws-sdk/client-sns', + '@aws-sdk/client-sqs', + '@aws-sdk/lib-dynamodb', + '@aws-sdk/smithy-client', + '@elastic/elasticsearch', + '@grpc/grpc-js', + '@hapi/hapi', + '@hapi/vision', + '@koa/router', + '@langchain/core', + '@nestjs/cli', + '@nestjs/core', + '@node-redis/client', + '@prisma/client', + '@redis/client', + '@smithy/smithy-client', + 'amqplib', + 'apollo-server', + 'apollo-server-express', + 'apollo-server-fastify', + 'apollo-server-hapi', + 'apollo-server-koa', + 'apollo-server-lambda', + 'aws-sdk', + 'bluebird', + 'bunyan', + 'cassandra-driver', + 'connect', + 'director', + 'express', + 'fastify', + 'generic-pool', + 'ioredis', + 'kafkajs', + 'koa', + 'koa-route', + 'koa-router', + 'memcached', + 'mongodb', + 'mysql', + 'mysql2', + 'next', + 'openai', + 'pg', + 'pg-native', + 'pino', + 'q', + 'redis', + 'restify', + 'superagent', + 'undici', + 'when', + 'winston' +] +const MIN_NODE_VERSION = 16 + +module.exports = { + INSTRUMENTED_LIBRARIES, + MIN_NODE_VERSION +} diff --git a/dashboards/generate-library-usage.js b/dashboards/generate-library-usage.js new file mode 100644 index 0000000000..5cbe8affe3 --- /dev/null +++ b/dashboards/generate-library-usage.js @@ -0,0 +1,49 @@ +/* + * Copyright 2024 New Relic Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +'use strict' +const fs = require('fs/promises') +const { INSTRUMENTED_LIBRARIES, MIN_NODE_VERSION } = require('./constants') +const { makeDashboard, makePage, makeWidget, libraryUsageQuery } = require('./utils') +const REPORT_NAME = process.env.REPORT_NAME || 'library-usage.json' + +function makeLibraryWidgets(libs) { + const width = 4 + const height = 3 + let row = 1 + let column = 1 + + return libs.map((lib, index) => { + const pos = index % height + + // on a new row, set column to 1 + if (pos === 0) { + column = 1 + // add width to column + } else { + column += width + } + + // start a new row + if (pos === 0 && index !== 0) { + row += height + } + const query = libraryUsageQuery({ lib, nodeVersion: MIN_NODE_VERSION }) + return makeWidget({ title: lib, column, row, width, height, query }) + }) +} + +async function main() { + const widgets = makeLibraryWidgets(INSTRUMENTED_LIBRARIES) + const page = makePage({ + name: 'Instrumented Libraries', + description: 'Reports usage by library, agent, and node.js versions', + widgets + }) + const dashboard = makeDashboard({ name: 'Node.js Library Usage', pages: [page] }) + await fs.writeFile(REPORT_NAME, JSON.stringify(dashboard)) +} + +main() diff --git a/dashboards/library-usage.json b/dashboards/library-usage.json new file mode 100644 index 0000000000..19ef113f3b --- /dev/null +++ b/dashboards/library-usage.json @@ -0,0 +1,1666 @@ +{ + "name": "Node.js Library Usage", + "description": null, + "permissions": "PUBLIC_READ_WRITE", + "pages": [ + { + "name": "Instrumented Libraries", + "description": "Reports usage by library, agent, and node.js versions", + "widgets": [ + { + "title": "@apollo/gateway", + "layout": { + "column": 1, + "row": 1, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `@apollo/gateway.version` IS NOT NULL and node.version.major >= '16' facet `@apollo/gateway.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "@apollo/server", + "layout": { + "column": 5, + "row": 1, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `@apollo/server.version` IS NOT NULL and node.version.major >= '16' facet `@apollo/server.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "@aws-sdk/client-bedrock-runtime", + "layout": { + "column": 9, + "row": 1, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `@aws-sdk/client-bedrock-runtime.version` IS NOT NULL and node.version.major >= '16' facet `@aws-sdk/client-bedrock-runtime.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "@aws-sdk/client-dynamodb", + "layout": { + "column": 1, + "row": 4, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `@aws-sdk/client-dynamodb.version` IS NOT NULL and node.version.major >= '16' facet `@aws-sdk/client-dynamodb.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "@aws-sdk/client-sns", + "layout": { + "column": 5, + "row": 4, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `@aws-sdk/client-sns.version` IS NOT NULL and node.version.major >= '16' facet `@aws-sdk/client-sns.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "@aws-sdk/client-sqs", + "layout": { + "column": 9, + "row": 4, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `@aws-sdk/client-sqs.version` IS NOT NULL and node.version.major >= '16' facet `@aws-sdk/client-sqs.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "@aws-sdk/lib-dynamodb", + "layout": { + "column": 1, + "row": 7, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `@aws-sdk/lib-dynamodb.version` IS NOT NULL and node.version.major >= '16' facet `@aws-sdk/lib-dynamodb.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "@aws-sdk/smithy-client", + "layout": { + "column": 5, + "row": 7, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `@aws-sdk/smithy-client.version` IS NOT NULL and node.version.major >= '16' facet `@aws-sdk/smithy-client.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "@elastic/elasticsearch", + "layout": { + "column": 9, + "row": 7, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `@elastic/elasticsearch.version` IS NOT NULL and node.version.major >= '16' facet `@elastic/elasticsearch.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "@grpc/grpc-js", + "layout": { + "column": 1, + "row": 10, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `@grpc/grpc-js.version` IS NOT NULL and node.version.major >= '16' facet `@grpc/grpc-js.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "@hapi/hapi", + "layout": { + "column": 5, + "row": 10, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `@hapi/hapi.version` IS NOT NULL and node.version.major >= '16' facet `@hapi/hapi.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "@hapi/vision", + "layout": { + "column": 9, + "row": 10, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `@hapi/vision.version` IS NOT NULL and node.version.major >= '16' facet `@hapi/vision.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "@koa/router", + "layout": { + "column": 1, + "row": 13, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `@koa/router.version` IS NOT NULL and node.version.major >= '16' facet `@koa/router.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "@langchain/core", + "layout": { + "column": 5, + "row": 13, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `@langchain/core.version` IS NOT NULL and node.version.major >= '16' facet `@langchain/core.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "@nestjs/cli", + "layout": { + "column": 9, + "row": 13, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `@nestjs/cli.version` IS NOT NULL and node.version.major >= '16' facet `@nestjs/cli.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "@nestjs/core", + "layout": { + "column": 1, + "row": 16, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `@nestjs/core.version` IS NOT NULL and node.version.major >= '16' facet `@nestjs/core.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "@node-redis/client", + "layout": { + "column": 5, + "row": 16, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `@node-redis/client.version` IS NOT NULL and node.version.major >= '16' facet `@node-redis/client.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "@prisma/client", + "layout": { + "column": 9, + "row": 16, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `@prisma/client.version` IS NOT NULL and node.version.major >= '16' facet `@prisma/client.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "@redis/client", + "layout": { + "column": 1, + "row": 19, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `@redis/client.version` IS NOT NULL and node.version.major >= '16' facet `@redis/client.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "@smithy/smithy-client", + "layout": { + "column": 5, + "row": 19, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `@smithy/smithy-client.version` IS NOT NULL and node.version.major >= '16' facet `@smithy/smithy-client.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "amqplib", + "layout": { + "column": 9, + "row": 19, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `amqplib.version` IS NOT NULL and node.version.major >= '16' facet `amqplib.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "apollo-server", + "layout": { + "column": 1, + "row": 22, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `apollo-server.version` IS NOT NULL and node.version.major >= '16' facet `apollo-server.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "apollo-server-express", + "layout": { + "column": 5, + "row": 22, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `apollo-server-express.version` IS NOT NULL and node.version.major >= '16' facet `apollo-server-express.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "apollo-server-fastify", + "layout": { + "column": 9, + "row": 22, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `apollo-server-fastify.version` IS NOT NULL and node.version.major >= '16' facet `apollo-server-fastify.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "apollo-server-hapi", + "layout": { + "column": 1, + "row": 25, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `apollo-server-hapi.version` IS NOT NULL and node.version.major >= '16' facet `apollo-server-hapi.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "apollo-server-koa", + "layout": { + "column": 5, + "row": 25, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `apollo-server-koa.version` IS NOT NULL and node.version.major >= '16' facet `apollo-server-koa.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "apollo-server-lambda", + "layout": { + "column": 9, + "row": 25, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `apollo-server-lambda.version` IS NOT NULL and node.version.major >= '16' facet `apollo-server-lambda.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "aws-sdk", + "layout": { + "column": 1, + "row": 28, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `aws-sdk.version` IS NOT NULL and node.version.major >= '16' facet `aws-sdk.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "bluebird", + "layout": { + "column": 5, + "row": 28, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `bluebird.version` IS NOT NULL and node.version.major >= '16' facet `bluebird.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "bunyan", + "layout": { + "column": 9, + "row": 28, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `bunyan.version` IS NOT NULL and node.version.major >= '16' facet `bunyan.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "cassandra-driver", + "layout": { + "column": 1, + "row": 31, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `cassandra-driver.version` IS NOT NULL and node.version.major >= '16' facet `cassandra-driver.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "connect", + "layout": { + "column": 5, + "row": 31, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `connect.version` IS NOT NULL and node.version.major >= '16' facet `connect.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "director", + "layout": { + "column": 9, + "row": 31, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `director.version` IS NOT NULL and node.version.major >= '16' facet `director.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "express", + "layout": { + "column": 1, + "row": 34, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `express.version` IS NOT NULL and node.version.major >= '16' facet `express.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "fastify", + "layout": { + "column": 5, + "row": 34, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `fastify.version` IS NOT NULL and node.version.major >= '16' facet `fastify.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "generic-pool", + "layout": { + "column": 9, + "row": 34, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `generic-pool.version` IS NOT NULL and node.version.major >= '16' facet `generic-pool.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "ioredis", + "layout": { + "column": 1, + "row": 37, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `ioredis.version` IS NOT NULL and node.version.major >= '16' facet `ioredis.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "kafkajs", + "layout": { + "column": 5, + "row": 37, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `kafkajs.version` IS NOT NULL and node.version.major >= '16' facet `kafkajs.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "koa", + "layout": { + "column": 9, + "row": 37, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `koa.version` IS NOT NULL and node.version.major >= '16' facet `koa.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "koa-route", + "layout": { + "column": 1, + "row": 40, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `koa-route.version` IS NOT NULL and node.version.major >= '16' facet `koa-route.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "koa-router", + "layout": { + "column": 5, + "row": 40, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `koa-router.version` IS NOT NULL and node.version.major >= '16' facet `koa-router.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "memcached", + "layout": { + "column": 9, + "row": 40, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `memcached.version` IS NOT NULL and node.version.major >= '16' facet `memcached.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "mongodb", + "layout": { + "column": 1, + "row": 43, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `mongodb.version` IS NOT NULL and node.version.major >= '16' facet `mongodb.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "mysql", + "layout": { + "column": 5, + "row": 43, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `mysql.version` IS NOT NULL and node.version.major >= '16' facet `mysql.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "mysql2", + "layout": { + "column": 9, + "row": 43, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `mysql2.version` IS NOT NULL and node.version.major >= '16' facet `mysql2.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "next", + "layout": { + "column": 1, + "row": 46, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `next.version` IS NOT NULL and node.version.major >= '16' facet `next.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "openai", + "layout": { + "column": 5, + "row": 46, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `openai.version` IS NOT NULL and node.version.major >= '16' facet `openai.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "pg", + "layout": { + "column": 9, + "row": 46, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `pg.version` IS NOT NULL and node.version.major >= '16' facet `pg.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "pg-native", + "layout": { + "column": 1, + "row": 49, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `pg-native.version` IS NOT NULL and node.version.major >= '16' facet `pg-native.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "pino", + "layout": { + "column": 5, + "row": 49, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `pino.version` IS NOT NULL and node.version.major >= '16' facet `pino.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "q", + "layout": { + "column": 9, + "row": 49, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `q.version` IS NOT NULL and node.version.major >= '16' facet `q.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "redis", + "layout": { + "column": 1, + "row": 52, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `redis.version` IS NOT NULL and node.version.major >= '16' facet `redis.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "restify", + "layout": { + "column": 5, + "row": 52, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `restify.version` IS NOT NULL and node.version.major >= '16' facet `restify.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "superagent", + "layout": { + "column": 9, + "row": 52, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `superagent.version` IS NOT NULL and node.version.major >= '16' facet `superagent.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "undici", + "layout": { + "column": 1, + "row": 55, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `undici.version` IS NOT NULL and node.version.major >= '16' facet `undici.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "when", + "layout": { + "column": 5, + "row": 55, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `when.version` IS NOT NULL and node.version.major >= '16' facet `when.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + }, + { + "title": "winston", + "layout": { + "column": 9, + "row": 55, + "width": 4, + "height": 3 + }, + "linkedEntityGuids": null, + "visualization": { + "id": "viz.bar" + }, + "rawConfiguration": { + "facet": { + "showOtherSeries": false + }, + "nrqlQueries": [ + { + "accountIds": [ + 1 + ], + "query": "FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where `winston.version` IS NOT NULL and node.version.major >= '16' facet `winston.version`, agentVersion, node.version.major limit max" + } + ], + "platformOptions": { + "ignoreTimeRange": false + } + } + } + ] + } + ] +} diff --git a/dashboards/utils.js b/dashboards/utils.js new file mode 100644 index 0000000000..3d53bc626c --- /dev/null +++ b/dashboards/utils.js @@ -0,0 +1,116 @@ +/* + * Copyright 2024 New Relic Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +'use strict' +const utils = module.exports + +/** + * @typedef {object} Page + * @property {string} name + * @property {description} description + * @property {Widget[]} widgets + */ + +/** + * @typedef {object} Dashboard + * @property {string} name + * @property {Page[]} pages + */ + +/** + * @typedef {object} Widget + * @property {string} title + * @property {number} column + * @property {number} row + * @property {number} width + * @property {number} height + * @property {string} query + */ + +/** + * Makes object structure of a New Relic dashboard + * + * @param {object} params to function + * @param {string} params.name name of dashboard + * @param {Page[]} params.pages page contents + * @returns {Dashboard} dashboard object + */ +utils.makeDashboard = function makeDashboard({ name, pages }) { + return { + name, + description: null, + permissions: 'PUBLIC_READ_WRITE', + pages + } +} + +/** + * Makes a page in a New Relic dashboard + * @param {object} params to function + * @param {string} params.name name of page + * @param {string} params.description description of page + * @param {Widget[]} params.widgets widgets in page + * @returns {Page} page object + */ +utils.makePage = function makePage({ name, description, widgets }) { + return { + name, + description, + widgets + } +} + +/** + * Makes a widget in a New Relic page + * @param {object} params to function + * @param {string} params.title of widget + * @param {number} params.column column number + * @param {number} params.row row number + * @param {number} [params.width] width of widget + * @param {number} [params.height] height of widget + * @param {string} params.query nrql query + * @returns {Widget} widget object + */ +utils.makeWidget = function makeWidget({ title, column, row, width = 4, height = 3, query }) { + return { + title, + layout: { + column, + row, + width, + height + }, + linkedEntityGuids: null, + visualization: { + id: 'viz.bar' + }, + rawConfiguration: { + facet: { + showOtherSeries: false + }, + nrqlQueries: [ + { + accountIds: [1], + query + } + ], + platformOptions: { + ignoreTimeRange: false + } + } + } +} + +/** + * Constructs NRQL for library usage + * + * @param {object} params to function + * @param {string} params.lib name of library + * @param {string} params.nodeVersion minimum node version + * @returns {string} NRQL query + */ +utils.libraryUsageQuery = function libraryUsageQuery({ lib, nodeVersion }) { + return `FROM NodeMetadataSummary SELECT uniqueCount(entity.guid) where \`${lib}.version\` IS NOT NULL and node.version.major >= '${nodeVersion}' facet \`${lib}.version\`, agentVersion, node.version.major limit max` +}