@swap-commerce/node-new-relic
v4.0.1
Published
A utility package for observability
Downloads
22,164
Maintainers
Keywords
Readme
Observability
This package exports an assortment of tools to handle server observability issues via new relic tooling, from logs, events and metrics.
Follow the guide to add telemetry to your project.
Package Installation
To install the package, run the following command in your repository:
npm install @swap-commerce/node-new-relicSetup Instrumentation
The first thing you'll have to do it to setup Instrumentation
In order to benefit from this package you need to start its instrumentation package BEFORE app code, fortunately that is easy to do in node.
On your package.json file create two entries, one to run in production named start and one that builds and runs the code start:build-run. (Names are just a suggestion here, could be named anything)
the start command should call for configure-observability-cjs or configure-observability-esm script, depending on your node project, followed by the script name to build and run your own server.
For example:
"scripts": {
"start": "configure-observability-cjs example:run",
"start:build-run": "build-package && node ./build/cjs/example/server.js"
}In your environment you should define the following env var NEW_RELIC_LICENSE_KEY, please follow the notion guide
The new-relic-configure-* command will be installed with this package and when called it will initialize newrelic, wrap your sever with instrumentation and run the provided script.
By default your service name and version is taken out of the package.json file, so keep this one updated.
NOTE:
- For performance reason, you shouldn't run the observability locally while debugging, it'll create too much noise.
- If you want to disable the
new relicwarning on dev or test, set the following ENV VARNEW_RELIC_ENABLEDtofalse.
Custom Instrumentation
Firestore Instrumentation
This package includes automatic instrumentation for Firebase Firestore operations. When you use the configure-observability-cjs or configure-observability-esm scripts, Firestore operations are automatically tracked in New Relic APM.
Tracked Operations:
Query.get()- Query operationsDocumentReference.get()- Document readsDocumentReference.set()- Document writesDocumentReference.update()- Document updatesDocumentReference.delete()- Document deletionsCollectionReference.add()- Adding documents to collections
Metrics Tracked:
- Operation duration
- Collection name
- Document path
- Operation type
Viewing in New Relic: Firestore operations appear in:
- Transaction traces as "Datastore/operation/Firestore/{operation}"
- Database tab alongside other datastore calls
- Service maps showing Firestore as a dependency
Example:
import { getFirestore } from 'firebase-admin/firestore'
const db = getFirestore()
// These operations are automatically instrumented:
const users = await db.collection('users').get() // Tracked
const user = await db.doc('users/123').get() // Tracked
await db.doc('users/123').set({ name: 'John' }) // TrackedAdding a Logger
This is your main way to create logs. By default logs are written to standard output. The logger functionality wraps pino.
On your project you can wrap it again by pino-http or pino-nest packages, to automatically provide logs on the HTTP/S requests.
To include default logs in your package:
- NestJS: https://github.com/iamolegga/nestjs-pino
- Express: https://github.com/pinojs/pino-http
- Hono: https://github.com/maou-shonen/hono-pino
Deep Dive into:
Basic Usage with NodeJS
// logger.ts
// Initialize your loggers and defaults
import { createLogger } from "@swap-commerce/node-new-relic";
// Create new loggers, you can use your `package.json` file to define the service name and version
export const { logger } = createLoggers({
serviceName: "my-test",
serviceVersion: "1.0.0",
});// someFile.ts
import { logger } from "./logger.ts";
// write logs by priority
logger.info("info message", { obj });
logger.warn("warn message", { obj });
logger.error("error message", { obj });Configure loggers
// logger.ts
const { logger, expressLogger } = createLoggers({
serviceName: "my-test",
serviceVersion: "1.0.0",
logger: {
// override with pino configuration
level: "error",
enabled: false,
},
});Adding a Metric
// Initialize your metrics
import { createMetrics } from "@swap-commerce/node-new-relic";
// Create new metrics object
const metrics = createMetrics();
// Record a new metric, use the dot notation to specify the metric. like - `my-server.3rd-party.calls`
// Pass a single metric
metrics.record("server/example", 3);
// Or pass a full metric
metrics.record("server/example", {
count: 3,
total: 5,
min: 1,
max: 5,
sumOfSquares: 25,
});
// You can also pass a incremental metric like a simple counter, if no value is passed it defaults to 1.
metrics.increment("server/example");
metrics.increment("server/example", 5);Adding a Custom Event
// Initialize your events
import { createEvents } from "@swap-commerce/node-new-relic";
// Create new events object
const events = createEvents();
// create a custom event with type, name, and additional properties.
// Type MUST BE alphanumeric and may include underscores (_)
events.custom("someExampleEvent", "server/example", {
user: "[email protected]",
});Environment
By default, this library relies on the SWAP_ENV variable to determine your app name and the env it's running on. SWAP_ENV should contain your actual environment, like uat or production.
However, if you don't have SWAP_ENV in your application yet, it'll fall back to using the NODE_ENV env var.
The environment is used to determine your application name on New Relic, as well as some event path names. For example, the Inventory application running on UAT will have the following name: inventory:UAT
Local development
When you need to make changes to this package and test the integration locally, you need to follow these steps:
In this directory
In this directory, run:
npm linkThen, run the compiler in the root directory of this project to run the package on watch mode. This will allow you to see all the changes in your package live, by running:
npm run watch buildThen, in the directory where this dependency is installed (for example, swap-global or swap-cloud-master), run:
npm link @swap-commerce/node-new-relicAnd then start the development server to see your changes live.
NOTE: If you're using any of the New Relic initialization scripts included in this project (new-relic-configure-cjs.sh or new-relic-configure-esm.sh) for testing purposes,
you'll need to comment the call to npm install newrelic and add the dependency directly in the host project.
Every time an npm install happens, the symlink created by npm link is overridden.
Build Issues
In some cases you might get an node-gyp error regarding native-metrics,like:
8.976 npm error gyp ERR! cwd /app/node_modules/@newrelic/native-metrics
8.976 npm error gyp ERR! node -v v18.20.5
8.976 npm error gyp ERR! node-gyp -v v10.1.0
8.976 npm error gyp ERR! not ok```In order to fix this you'll need to install the following in your dockerfile, before running the npm install command:
RUN apk add g++ make py3-pipThat means your docker will try to build the native-metrics before installing it, so it will need cpp, make and python installed.
