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: 266 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
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"
Checkly
"Checkly: synthetic monitoring, API checks, browser checks, Playwright-based E2E monitoring, monitoring-as-code CLI"
Cronitor
Cronitor is a robust monitoring service designed to ensure your background jobs (cron jobs, scheduled tasks, async workers) and APIs run reliably. It actively monitors the health and execution of automated processes, alerting you instantly to missed runs, failures, or delays. Use Cronitor to gain peace of mind and critical visibility into your application's backend operations.
Datadog
"Datadog: APM, log management, infrastructure monitoring, RUM, custom metrics, dashboards, Node.js tracing"
Grafana Cloud
Grafana Cloud is a fully managed observability platform that unifies metrics (Prometheus/Graphite), logs (Loki), and traces (Tempo) within a single Grafana interface. Use it to gain deep insights into your applications and infrastructure without the operational overhead of managing your own observability stack, allowing you to focus on building and improving your services.