New Relic
New Relic: APM, distributed tracing, browser monitoring, custom events, NRQL queries, alert policies, Node.js and browser agents
You are an expert in integrating New Relic for application monitoring.
## Key Points
- **Use distributed tracing over cross-application tracing** — distributed tracing is the modern replacement and works across all language agents and third-party services.
- **Send custom events for business metrics** — NRQL can query custom events just like built-in data, giving you dashboards that track revenue, signups, or feature usage alongside technical metrics.
- **Exclude sensitive headers and attributes** — configure the `attributes.exclude` list to strip cookies, auth tokens, and PII from trace data before it leaves your infrastructure.
## Quick Example
```html
<!-- Paste the browser agent snippet from New Relic UI into <head>,
or use the npm package for SPA frameworks -->
```skilldb get monitoring-services-skills/new-relicFull skill: 265 linesNew Relic — Application Monitoring
You are an expert in integrating New Relic for application monitoring.
Core Philosophy
Overview
New Relic is a full-stack observability platform that provides APM, infrastructure monitoring, browser monitoring, log management, and custom dashboards. Its query language NRQL (New Relic Query Language) is central to building dashboards, alerts, and ad-hoc investigations. The Node.js agent auto-instruments popular frameworks and the browser agent captures real user performance data.
Setup & Configuration
Node.js APM Agent
// newrelic.ts — must be at the project root or specified via NEW_RELIC_HOME
// The agent is loaded via require('newrelic') as the FIRST import in your entry point.
// newrelic.js (CommonJS config file required by the agent)
"use strict";
exports.config = {
app_name: [process.env.NEW_RELIC_APP_NAME ?? "my-api-service"],
license_key: process.env.NEW_RELIC_LICENSE_KEY,
distributed_tracing: {
enabled: true,
},
logging: {
level: "info",
filepath: "stdout",
},
allow_all_headers: true,
application_logging: {
forwarding: {
enabled: true,
max_samples_stored: 10000,
},
},
attributes: {
exclude: [
"request.headers.cookie",
"request.headers.authorization",
"request.headers.proxyAuthorization",
"request.headers.setCookie*",
"request.headers.x*",
"response.headers.cookie",
"response.headers.authorization",
"response.headers.proxyAuthorization",
"response.headers.setCookie*",
],
},
};
// app.ts — entry point: require newrelic FIRST
import "newrelic";
import express from "express";
import { router } from "./routes";
const app = express();
app.use(router);
app.listen(3000);
Browser Monitoring (SPA Agent)
<!-- Paste the browser agent snippet from New Relic UI into <head>,
or use the npm package for SPA frameworks -->
// lib/newrelic-browser.ts — for React/Next.js apps
import { BrowserAgent } from "@newrelic/browser-agent/loaders/browser-agent";
const agent = new BrowserAgent({
init: {
distributed_tracing: { enabled: true },
privacy: { cookies_enabled: true },
ajax: { deny_list: ["bam.nr-data.net"] },
},
info: {
beacon: "bam.nr-data.net",
errorBeacon: "bam.nr-data.net",
licenseKey: process.env.NEXT_PUBLIC_NEW_RELIC_BROWSER_KEY!,
applicationID: process.env.NEXT_PUBLIC_NEW_RELIC_APP_ID!,
sa: 1,
},
loader_config: {
accountID: process.env.NEXT_PUBLIC_NEW_RELIC_ACCOUNT_ID!,
trustKey: process.env.NEXT_PUBLIC_NEW_RELIC_TRUST_KEY!,
agentID: process.env.NEXT_PUBLIC_NEW_RELIC_AGENT_ID!,
licenseKey: process.env.NEXT_PUBLIC_NEW_RELIC_BROWSER_KEY!,
applicationID: process.env.NEXT_PUBLIC_NEW_RELIC_APP_ID!,
},
});
export { agent };
Core Patterns
Custom Events and Attributes
// lib/nr-events.ts
import newrelic from "newrelic";
export function recordBusinessEvent(
eventType: string,
attributes: Record<string, string | number | boolean>
) {
newrelic.recordCustomEvent(eventType, {
...attributes,
environment: process.env.NODE_ENV,
service: process.env.NEW_RELIC_APP_NAME,
});
}
// Usage: track domain-specific events queryable with NRQL
recordBusinessEvent("OrderPlaced", {
orderId: "abc-123",
total: 59.99,
itemCount: 3,
paymentMethod: "stripe",
});
// Query in New Relic:
// SELECT count(*) FROM OrderPlaced FACET paymentMethod SINCE 1 hour ago
Custom Transaction Instrumentation
// lib/nr-tracing.ts
import newrelic from "newrelic";
export function instrumentBackground<T>(
name: string,
group: string,
fn: () => Promise<T>
): Promise<T> {
return new Promise((resolve, reject) => {
newrelic.startBackgroundTransaction(`${group}/${name}`, group, () => {
const transaction = newrelic.getTransaction();
fn()
.then((result) => {
transaction.end();
resolve(result);
})
.catch((error) => {
newrelic.noticeError(error as Error);
transaction.end();
reject(error);
});
});
});
}
// Usage: instrument a queue worker or cron job
await instrumentBackground("processEmailQueue", "Worker", async () => {
const messages = await queue.receive(10);
for (const msg of messages) {
await sendEmail(msg.body);
}
});
Error Tracking with Context
// middleware/nr-error-handler.ts
import newrelic from "newrelic";
import type { Request, Response, NextFunction } from "express";
export function nrErrorHandler(
err: Error,
req: Request,
res: Response,
next: NextFunction
) {
newrelic.noticeError(err, {
userId: (req as any).user?.id,
route: req.route?.path ?? req.path,
method: req.method,
statusCode: res.statusCode,
});
next(err);
}
// Add custom attributes to the current transaction
export function addTransactionContext(req: Request) {
if ((req as any).user) {
newrelic.addCustomAttributes({
"user.id": (req as any).user.id,
"user.plan": (req as any).user.plan,
});
}
}
NRQL Alert Conditions (as Code via Terraform)
resource "newrelic_nrql_alert_condition" "high_error_rate" {
account_id = var.new_relic_account_id
policy_id = newrelic_alert_policy.api_policy.id
type = "static"
name = "API Error Rate > 5%"
enabled = true
violation_time_limit_seconds = 3600
nrql {
query = <<-NRQL
SELECT percentage(count(*), WHERE error IS true)
FROM Transaction
WHERE appName = 'my-api-service'
NRQL
}
critical {
operator = "above"
threshold = 5
threshold_duration = 300
threshold_occurrences = "all"
}
warning {
operator = "above"
threshold = 2
threshold_duration = 300
threshold_occurrences = "all"
}
}
Best Practices
- Use distributed tracing over cross-application tracing — distributed tracing is the modern replacement and works across all language agents and third-party services.
- Send custom events for business metrics — NRQL can query custom events just like built-in data, giving you dashboards that track revenue, signups, or feature usage alongside technical metrics.
- Exclude sensitive headers and attributes — configure the
attributes.excludelist to strip cookies, auth tokens, and PII from trace data before it leaves your infrastructure.
Common Pitfalls
- Forgetting to require the agent first — the New Relic Node.js agent must be the very first
require/importin your entry point; otherwise auto-instrumentation of Express, pg, Redis, etc. silently fails. - High-cardinality custom attributes on transactions — adding unique IDs (like request IDs or session tokens) as transaction attributes inflates data volume and slows NRQL queries; use custom events for high-cardinality data instead.
Anti-Patterns
Using the service without understanding its pricing model. Cloud services bill differently — per request, per GB, per seat. Deploying without modeling expected costs leads to surprise invoices.
Hardcoding configuration instead of using environment variables. API keys, endpoints, and feature flags change between environments. Hardcoded values break deployments and leak secrets.
Ignoring the service's rate limits and quotas. Every external API has throughput limits. Failing to implement backoff, queuing, or caching results in dropped requests under load.
Treating the service as always available. External services go down. Without circuit breakers, fallbacks, or graceful degradation, a third-party outage becomes your outage.
Coupling your architecture to a single provider's API. Building directly against provider-specific interfaces makes migration painful. Wrap external services in thin adapter layers.
Install this skill directly: skilldb add monitoring-services-skills
Related Skills
Opentelemetry
OpenTelemetry provides a set of open-source APIs, SDKs, and tools to instrument, generate, collect, and export telemetry data (metrics, logs, traces) for observability. Use it to standardize your application's telemetry across various services and vendors without vendor lock-in.
Prometheus
Open-source monitoring and alerting toolkit for collecting metrics via pull-based scraping, building PromQL queries, setting up alerts, and instrumenting applications for cloud-native observability.
Sentry
Sentry: error tracking, performance monitoring, session replay, source maps, breadcrumbs, Next.js/React SDK, alerts
Uptime Robot
Uptime Robot: uptime monitoring API, HTTP/keyword/ping checks, status pages, alert contacts, maintenance windows
Baselime
Baselime is a serverless-native observability platform designed for AWS, unifying logs, traces, and metrics. It provides real-time insights and contextualized data to help you understand and troubleshoot your distributed serverless applications.
BetterStack
BetterStack (formerly Better Uptime + Logtail): uptime monitoring, log management, status pages, incident management, alerting