# https://github.com/newrelic/node-newrelic Project Manual

Generated at: 2026-06-17 19:02:22 UTC

## Table of Contents

- [Overview and Core Architecture](#page-1)
- [Instrumentation Framework and Subscribers](#page-2)
- [OpenTelemetry, Hybrid Agent, and Modern Runtimes](#page-3)
- [AI/LLM Monitoring and Modern Integrations](#page-4)

<a id='page-1'></a>

## Overview and Core Architecture

### Related Pages

Related topics: [Instrumentation Framework and Subscribers](#page-2), [OpenTelemetry, Hybrid Agent, and Modern Runtimes](#page-3), [AI/LLM Monitoring and Modern Integrations](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [README.md](https://github.com/newrelic/node-newrelic/blob/main/README.md)
- [package.json](https://github.com/newrelic/node-newrelic/blob/main/package.json)
- [lib/metrics/recorders/middleware.js](https://github.com/newrelic/node-newrelic/blob/main/lib/metrics/recorders/middleware.js)
- [lib/instrumentation/core/timers.js](https://github.com/newrelic/node-newrelic/blob/main/lib/instrumentation/core/timers.js)
- [lib/otel/traces/constants.js](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/constants.js)
- [lib/otel/traces/segments/utils.js](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/segments/utils.js)
- [lib/otel/traces/transformation-rules/499-FallbackProducer.json](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/transformation-rules/499-FallbackProducer.json)
- [lib/otel/traces/transformation-rules/312-OtelHttpClient1_23.json](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/transformation-rules/312-OtelHttpClient1_23.json)
- [lib/subscribers/README.md](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/README.md)
- [lib/subscribers/aws-sdk/send.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/aws-sdk/send.js)
- [lib/subscribers/aws-sdk/utils/constants.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/aws-sdk/utils/constants.js)
- [lib/subscribers/aws-sdk/utils/attach-headers.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/aws-sdk/utils/attach-headers.js)
- [lib/subscribers/kafkajs/utils/record-linking-metrics.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/kafkajs/utils/record-linking-metrics.js)
- [cloud-tooling/azure-site-extension/Content/README.md](https://github.com/newrelic/node-newrelic/blob/main/cloud-tooling/azure-site-extension/Content/README.md)
</details>

# Overview and Core Architecture

The `newrelic` Node.js agent instruments application code to collect performance metrics, traces, and events for the New Relic observability platform. The repository bundles a runtime loader, a configuration system, a metric/transaction engine, and dozens of package-specific instrumentation modules (called "shims" and "subscribers") that activate when the host application `require`s or `import`s a supported dependency. Source: [README.md:1-12]().

The published `newrelic` npm package targets Node.js `>=22` and ships a focused set of entry points: `index.js`, `api.js`, `stub_api.js`, `newrelic.js`, `load-externals.js`, and `esm-loader.mjs`. Source: [package.json:50-60](). The package's optional dependencies include `@newrelic/native-metrics`, `@newrelic/fn-inspect`, `@datadog/pprof`, and `@prisma/prisma-fmt-wasm`, which are used for native profiling, function inspection, continuous profiling, and Prisma schema parsing respectively. Source: [package.json:80-86]().

## High-Level Architecture

The agent is structured around three cooperating layers:

1. **Bootstrap & Configuration Layer** — Loads `newrelic.js` (or an environment-supplied config), resolves environment variables, and instantiates the `Agent` object.
2. **Instrumentation Layer** — A pluggable registry of `shim` modules and `subscribers` that hook into Node.js core APIs and third-party packages. Each module declares a `functionQuery` (which symbol to wrap) and an instrumentation callback. Source: [lib/subscribers/README.md:5-30]().
3. **Telemetry Layer** — Collects metrics (per-recorder), segments, transactions, and spans, then normalizes them via OpenTelemetry semantic-convention constants and transformation rules before shipping to the collector.

```mermaid
flowchart TB
  App[Host Application] -->|require/import newrelic| Loader[index.js / newrelic.js]
  Loader --> Config[Configuration System]
  Loader --> Agent[Agent Instance]
  Agent --> Shims[Shim Registry]
  Agent --> Subs[Subscriber Registry]
  Shims --> Core[lib/instrumentation/core/*]
  Shims --> Pkg[Package-Specific Shims]
  Subs --> Otel[OpenTelemetry Bridge]
  Subs --> Aws[AWS SDK v3 Subscriber]
  Subs --> Kfk[KafkaJS Subscriber]
  Otel --> Rules[Transformation Rules JSON]
  Otel --> Collector[New Relic Collector]
  Shims --> Collector
  Subs --> Collector
```

Source: [lib/instrumentation/core/timers.js:7-15](), [lib/subscribers/aws-sdk/send.js:11-30](), [lib/otel/traces/segments/utils.js:1-20]().

## Instrumentation Patterns

The agent uses two complementary wrapping mechanisms. The legacy **shim** model wraps core modules (for example, `timers.js` patches `setTimeout`, `setInterval`, and `clearTimeout` on both the `timers` module and `global`, then attaches a `RecorderSpec` to each call). Source: [lib/instrumentation/core/timers.js:9-20](). The newer **subscriber** model is declarative: each subscriber exports a configuration object identifying the target module by `name`, `versionRange`, and `filePath`, plus a `functionQuery` (e.g., `className`/`methodName` or `moduleName`/`expressionName`) and a `kind` of `Sync` or `Async`. Source: [lib/subscribers/README.md:5-42]().

Metric recorders are tiny, single-purpose functions. The middleware recorder, for example, reads both inclusive and exclusive segment durations and records them under a scoped and unscoped metric name. Source: [lib/metrics/recorders/middleware.js:9-20](). A KafkaJS helper similarly records per-broker produce/consume counts under a stable `MessageBroker/Kafka/Nodes/<broker>/<Produce|Consume>/<topic>` namespace. Source: [lib/subscribers/kafkajs/utils/record-linking-metrics.js:1-22]().

## OpenTelemetry Integration

The agent can ingest OpenTelemetry spans and convert them into New Relic segments through a transformation-rules engine. Each rule (a JSON file under `lib/otel/traces/transformation-rules/`) declares a `matcher` (required span kinds and attribute keys) and a `segment` template. Rule `499-FallbackProducer.json` matches any span with `kind=producer` and emits a `MessageBroker/unknown/unknown/Produce` segment when no other rule applies. Source: [lib/otel/traces/transformation-rules/499-FallbackProducer.json:1-14](). Rule `312-OtelHttpClient1_23.json` demonstrates attribute remapping: it renames `server.address` to the segment host, `url.full` to the URL, and produces a segment name via the template `External/${host}${path}`. Source: [lib/otel/traces/transformation-rules/312-OtelHttpClient1_23.json:1-30]().

Trace context is propagated bidirectionally. The helper `propagateTraceContext` reads `spanContext()` and `parentSpanId` from the active OTel span, constructs a W3C `Traceparent` object, and calls `transaction.acceptTraceContextPayload` on the local transaction, preserving the upstream `traceState`. Source: [lib/otel/traces/segments/utils.js:11-25](). Attribute names follow OpenTelemetry semantic conventions maintained in `lib/otel/traces/constants.js`. Source: [lib/otel/traces/constants.js:1-25]().

## AWS SDK v3, Distributed Tracing, and Deployment Surfaces

The `SmithyClientSendSubscriber` is a single subscriber that hooks `@smithy/smithy-client`'s `Client.send()` and dispatches service-specific middleware for `BedrockRuntime`, `DynamoDB`, `Lambda`, `SNS`, and `SQS` clients. Source: [lib/subscribers/aws-sdk/send.js:1-30](). The W3C distributed-tracing headers used for AWS propagation are enumerated in a single constant: `['traceparent', 'tracestate', 'newrelic']`. Source: [lib/subscribers/aws-sdk/utils/constants.js:1-5](). SQS message attributes are bounded by AWS's 10-attribute limit, so `attachHeaders` reserves slots and inserts headers in priority order. Source: [lib/subscribers/aws-sdk/utils/attach-headers.js:1-30]().

For Azure App Service deployments, the repository ships a NuGet-distributed site extension that drops the agent into `C:\home\site\wwwroot\node_modules` and injects the `NODE_OPTIONS` preload variable via an `applicationHost.xdt` transform. Source: [cloud-tooling/azure-site-extension/Content/README.md:1-20]().

## Runtime Compatibility and Known Gaps

The `engines` field pins Node.js `>=22`, so older LTS lines are unsupported. Source: [package.json:25-30](). Community-reported gaps include Prisma (which uses its own query engine rather than `pg`/`mysql2`, so its queries are not auto-instrumented), ESM configuration discovery (the loader looks for `newrelic.js` and does not yet auto-pick `newrelic.cjs` for `"type": "module"` projects), Bun runtime compatibility, native Next.js support (addressed in v14.1.0 via the Hybrid Agent), and Deno support. These are tracked in issues #991, #553, #1959, #904, and #1727 respectively.

## See Also

- Configuration and Environment Variables
- Instrumentation Authoring Guide (Shims and Subscribers)
- OpenTelemetry Transformation Rules
- Distributed Tracing and W3C Trace Context
- AWS SDK v3 Instrumentation
- Azure Site Extension Deployment

---

<a id='page-2'></a>

## Instrumentation Framework and Subscribers

### Related Pages

Related topics: [Overview and Core Architecture](#page-1), [OpenTelemetry, Hybrid Agent, and Modern Runtimes](#page-3), [AI/LLM Monitoring and Modern Integrations](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [lib/subscribers/README.md](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/README.md)
- [lib/instrumentation/core/timers.js](https://github.com/newrelic/node-newrelic/blob/main/lib/instrumentation/core/timers.js)
- [lib/instrumentation/core/fs.js](https://github.com/newrelic/node-newrelic/blob/main/lib/instrumentation/core/fs.js)
- [lib/subscribers/aws-sdk/send.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/aws-sdk/send.js)
- [lib/subscribers/aws-sdk/utils/attach-headers.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/aws-sdk/utils/attach-headers.js)
- [lib/subscribers/aws-sdk/utils/constants.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/aws-sdk/utils/constants.js)
- [lib/subscribers/kafkajs/utils/record-linking-metrics.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/kafkajs/utils/record-linking-metrics.js)
- [lib/subscribers/kafkajs/utils/record-method-metric.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/kafkajs/utils/record-method-metric.js)
- [lib/metrics/recorders/middleware.js](https://github.com/newrelic/node-newrelic/blob/main/lib/metrics/recorders/middleware.js)
- [lib/metrics/recorders/apollo-resolver.js](https://github.com/newrelic/node-newrelic/blob/main/lib/metrics/recorders/apollo-resolver.js)
- [lib/otel/traces/segments/utils.js](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/segments/utils.js)
- [lib/otel/traces/transformation-rules/499-FallbackProducer.json](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/transformation-rules/499-FallbackProducer.json)
- [package.json](https://github.com/newrelic/node-newrelic/blob/main/package.json)
</details>

# Instrumentation Framework and Subscribers

## Overview

The New Relic Node.js agent instruments Node applications through a layered framework that combines **shims**, **subscribers**, **core instrumentations**, and **metric recorders**. The framework allows the agent to automatically measure the performance of third-party modules (databases, message brokers, AWS SDK, GraphQL servers) and built-in Node.js modules (timers, `fs`) without requiring manual instrumentation from the application developer.

The minimum supported runtime is declared in `package.json`: `node >= 22` and `npm >= 6.0.0`. This floor matters because subscribers rely on `node:diagnostics_channel` and `orchestrion` features that are only available in modern Node versions, and several community requests (such as #553 for ESM and #1959 for BunJS support) are directly constrained by this baseline. Source: [package.json:28-31](https://github.com/newrelic/node-newrelic/blob/main/package.json)

## Architecture

The framework is composed of cooperating layers that hook into a target module, extract timing and context information, and forward it to the agent's metrics engine.

```mermaid
graph LR
    A[Target Module<br/>e.g. kafkajs, fs, AWS SDK] --> B[Hook Layer<br/>require-in-the-middle /<br/>diagnostics_channel]
    B --> C[Subscriber or Core Init]
    C --> D[Segment / Transaction]
    C --> E[Metric Recorder]
    D --> F[Agent Metrics]
    E --> F
    F --> G[New Relic Backend]
    D --> H[OTEL Bridge]
    H --> G
```

Core instrumentations wrap built-in modules directly via the shim layer, while third-party instrumentations register subscribers that activate when the target module is `require()`d. The agent also runs an OpenTelemetry bridge that converts OTel spans into its own segment model, which is the mechanism behind the new native Next.js support shipped in v14.1.0.

## Subscriber System

Subscribers are the primary extension point for adding new instrumentation. The contributor documentation states that all subscribers inherit from the base `Subscriber` class defined in `lib/subscribers/base.js`, with the exception of subscribers that hook into `node:diagnostics_channel` channels directly — those inherit from `dc-base.js` instead. Source: [lib/subscribers/README.md:54-58](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/README.md)

The framework defines specialized base classes for the most common categories:

- `DbQuerySubscriber` — for database query-level tracing (e.g. SQL execution)
- `DbOperationSubscriber` — for connection pool, transaction, and lifecycle operations
- `MessageProducerSubscriber` — for outgoing message queue publishing
- `MessageConsumerSubscriber` — for incoming message queue consumption
- `PropagationSubscriber` — for context propagation across `AsyncLocalStorage` boundaries

Source: [lib/subscribers/README.md:62-70](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/README.md)

### Function Query Selectors

Each subscriber declares one or more function queries to identify the code being instrumented. Supported selectors include `expressionName`, `functionName`, `className + methodName`, and `moduleName + expressionName`. The `kind` property is set to `Sync` or `Async` to indicate whether the target function returns a promise. When code structure changes between versions, multiple query objects can be added to the same `instrumentations` array to cover both shapes. Source: [lib/subscribers/README.md:78-86](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/README.md)

### AWS SDK v3 Subscriber

The `SmithyClientSendSubscriber` in `lib/subscribers/aws-sdk/send.js` demonstrates the modern subscriber pattern. It hooks a single `Client.send` call on `@smithy/smithy-client` and dispatches service-specific middleware from a `middlewareByClient` map covering `BedrockRuntime`, `DynamoDB`, `DynamoDBDocument`, `Lambda`, `SNS`, and `SQS`. This consolidation means a single hook covers every AWS SDK v3 client because they all extend `@smithy/smithy-client.Client`. Source: [lib/subscribers/aws-sdk/send.js:10-32](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/aws-sdk/send.js)

For services that publish messages, the `attachHeaders` utility mutates the message's `MessageAttributes` to inject distributed-tracing headers. It enforces the AWS-imposed limit of 10 attributes per message and prioritizes header insertion in order so the most important headers survive when capacity is tight. Source: [lib/subscribers/aws-sdk/utils/attach-headers.js:18-44](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/aws-sdk/utils/attach-headers.js)

The set of propagated headers is centralized as a single constant: `traceparent`, `tracestate`, and `newrelic`. Source: [lib/subscribers/aws-sdk/utils/constants.js:5-7](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/aws-sdk/utils/constants.js)

### Kafka Subscriber Utilities

The Kafka instrumentation uses two helper recorders. `recordLinkingMetrics` increments a `MessageBroker/Kafka/Nodes/<broker>/<Produce|Consume>/<topic>` metric for every broker contacted during message production or consumption. Source: [lib/subscribers/kafkajs/utils/record-linking-metrics.js:16-30](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/kafkajs/utils/record-linking-metrics.js)

A separate `recordMethodMetric` utility records a generic call count using the `KAFKA.PREFIX` constant from the agent's metrics name registry. Source: [lib/subscribers/kafkajs/utils/record-method-metric.js:7-15](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/kafkajs/utils/record-method-metric.js)

## Core Instrumentation Modules

Built-in Node.js modules are instrumented through dedicated initializers that use the shim's `record` and `wrap` helpers.

The `timers` initializer instruments `setTimeout`, `setInterval`, and `clearTimeout` on both the `timers` module and the `global` object. The `wrappedClearTimeout` function marks the corresponding segment as `ignore = true` so cancelled timers do not contribute to transaction duration. Source: [lib/instrumentation/core/timers.js:20-47](https://github.com/newrelic/node-newrelic/blob/main/lib/instrumentation/core/timers.js)

The `fs` initializer records a large set of filesystem methods including `rename`, `readFile`, `writeFile`, and — on Node 22+ — `glob`. High-level and low-level variants are recorded separately to distinguish synchronous from asynchronous usage. Source: [lib/instrumentation/core/fs.js:10-50](https://github.com/newrelic/node-newrelic/blob/main/lib/instrumentation/core/fs.js)

## Metric Recorders

Metric recorders transform segment and transaction data into New Relic metric records. The framework ships several reusable recorders:

- `makeMiddlewareRecorder` produces a closure that records both scoped and unscoped versions of a middleware metric, using segment duration and exclusive time. Source: [lib/metrics/recorders/middleware.js:11-21](https://github.com/newrelic/node-newrelic/blob/main/lib/metrics/recorders/middleware.js)
- `recordResolveSegment` extracts `FIELD_NAME_ATTR` and `PARENT_TYPE_ATTR` from segment attributes to produce a `RESOLVE_PREFIX/<ParentType>.<fieldName>` metric for Apollo GraphQL resolvers, disambiguating duplicate field names across different types. Source: [lib/metrics/recorders/apollo-resolver.js:16-33](https://github.com/newrelic/node-newrelic/blob/main/lib/metrics/recorders/apollo-resolver.js)

## OpenTelemetry Bridge

The agent also bridges OpenTelemetry spans into its own transaction model. The `propagateTraceContext` helper reads the span context and constructs a W3C `Traceparent` object that the transaction accepts, forwarding the trace state to the New Relic backend under a `transport` tag (e.g. `http`, `kafkajs`, `rabbitmq`). Source: [lib/otel/traces/segments/utils.js:13-31](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/segments/utils.js)

Transformation rules describe how to map OTel spans onto agent segments. For example, the `FallbackProducer` rule converts any `producer` span into a `MessageBroker/unknown/unknown/Produce` segment when no more specific rule matches. Source: [lib/otel/traces/transformation-rules/499-FallbackProducer.json:1-13](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/transformation-rules/499-FallbackProducer.json)

The v14.1.0 release extended this OTEL bridge to support native Next.js instrumentation, demonstrating how the framework can absorb new runtimes and frameworks without changes to the subscriber contract.

## See Also

- Configuration and installation: [README.md](https://github.com/newrelic/node-newrelic/blob/main/README.md)
- Cloud deployment tooling: [cloud-tooling/README.md](https://github.com/newrelic/node-newrelic/blob/main/cloud-tooling/README.md)
- Azure site extension: [cloud-tooling/azure-site-extension/Content/README.md](https://github.com/newrelic/node-newrelic/blob/main/cloud-tooling/azure-site-extension/Content/README.md)
- Community issue [#991](https://github.com/newrelic/node-newrelic/issues/991) — Prisma instrumentation gap
- Community issue [#553](https://github.com/newrelic/node-newrelic/issues/553) — ESM support
- Community issue [#904](https://github.com/newrelic/node-newrelic/issues/904) — Next.js support
- Community issue [#1959](https://github.com/newrelic/node-newrelic/issues/1959) — BunJS compatibility
- Community issue [#1727](https://github.com/newrelic/node-newrelic/issues/1727) — Deno runtime support

---

<a id='page-3'></a>

## OpenTelemetry, Hybrid Agent, and Modern Runtimes

### Related Pages

Related topics: [Overview and Core Architecture](#page-1), [Instrumentation Framework and Subscribers](#page-2), [AI/LLM Monitoring and Modern Integrations](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [lib/otel/traces/index.js](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/index.js)
- [lib/otel/traces/sampler.js](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/sampler.js)
- [lib/otel/traces/span-processor.js](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/span-processor.js)
- [lib/otel/traces/rules.js](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/rules.js)
- [lib/otel/traces/segments/internal.js](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/segments/internal.js)
- [lib/otel/traces/segments/utils.js](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/segments/utils.js)
- [lib/otel/traces/constants.js](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/constants.js)
- [package.json](https://github.com/newrelic/node-newrelic/blob/main/package.json)
- [README.md](https://github.com/newrelic/node-newrelic/blob/main/README.md)
- [cloud-tooling/README.md](https://github.com/newrelic/node-newrelic/blob/main/cloud-tooling/README.md)
</details>

# OpenTelemetry, Hybrid Agent, and Modern Runtimes

## 1. Purpose and Scope

The `node-newrelic` agent ships an **OpenTelemetry (OTEL) bridge** that allows the agent to consume spans produced by upstream OTEL instrumentations and translate them into native New Relic APM segments. This is the foundation of the **Hybrid Agent** approach introduced in v14.1.0, which enables first-class support for runtimes and frameworks (such as Next.js) that already ship their own OTEL instrumentation rather than relying solely on the agent's shim-based hooks.

The OTEL bridge is registered through `SetupTraces`, which builds a `BasicTracerProvider` configured with a custom sampler and a New Relic span processor. Once installed globally, the bridge reuses the agent's existing tracer, segment tree, and metric pipeline, so OTEL spans appear in the same transaction trace as the agent's native segments.

```mermaid
flowchart LR
    A[OTEL Instrumentation<br/>e.g. Next.js] -->|spans| B[BasicTracerProvider]
    B --> C[NrSampler]
    C -->|sampled spans| D[NrSpanProcessor]
    D --> E[SegmentSynthesizer]
    E --> F[New Relic Segments / Metrics]
    D --> G[AttributeReconciler]
    G --> F
```

A supportability metric is emitted when the bridge is enabled, making it possible to confirm in the New Relic UI that the bridge is active in a given process — `Source: [lib/otel/traces/index.js:17-19]()`.

## 2. Sampling, Rules, and Span Processing

### Sampler

`NrSampler` decides whether an incoming OTEL span should be recorded. A span is sampled if any of the following is true:

- An active New Relic transaction is already in progress on the OTEL context.
- The parent span context is `isRemote` (i.e. propagated across a process boundary).
- The span is of kind `SERVER` or `CONSUMER`.

In all other cases the sampler returns `NOT_RECORD`, avoiding double-counting for internal spans that are already part of an instrumented transaction. `Source: [lib/otel/traces/sampler.js:9-21]()`.

### Rules Engine

OTEL spans do not carry the same semantic metadata as the agent's internal segments, so the bridge needs a rules engine to decide how each span should be mapped. `OtelRuleMatcher` in [lib/otel/traces/rules.js](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/rules.js) defines the matchable properties — required span kinds (`server`, `client`, `internal`), required attribute keys, attribute value conditions, and an `instrumentationScope.name` filter. This allows transformation rules (loaded from `transformation-rules/index.js`) to target only the spans produced by specific OTEL instrumentations.

### Span Processor

`NrSpanProcessor` runs on every emitted OTEL span. It:

- Pulls context from the agent tracer to find the active transaction and parent segment.
- Creates a new segment using the OTEL `spanId` to keep correlation stable.
- Reconciles attributes via `AttributeReconciler`.
- Synthesizes child segments through `SegmentSynthesizer` (see `lib/otel/traces/span-processor.js`).
- Forwards the final segments into the agent's existing transaction and metrics pipeline.

The processor reuses the agent's logger (`defaultLogger.child({ component: 'span-processor' })`) so OTEL-derived events appear in the same `newrelic_agent.log` file as native instrumentation logs. `Source: [lib/otel/traces/span-processor.js:13-44]()`.

## 3. Segment Synthesis and Distributed Trace Propagation

### Internal Segments

For spans that match an `internal` rule, the bridge creates a plain internal segment and attaches it to the active transaction's segment tree. The factory in [lib/otel/traces/segments/internal.js](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/segments/internal.js) reuses `agent.tracer.createSegment` with the OTEL span id and a `genericRecorder`, ensuring the segment inherits the same naming, timing, and exclusive-duration semantics as any other internal segment produced by the agent.

### Trace Context Propagation

Distributed trace headers are produced via `propagateTraceContext` in `lib/otel/traces/segments/utils.js`. When the OTEL span has a parent, the helper builds a W3C `traceparent` from the span context (prefixing `traceFlags` with `0` to match the parsed integer stored on `spanContext`) and calls `transaction.acceptTraceContextPayload`, ensuring that the OTEL span and any outbound HTTP/message-broker calls made by the same handler share a single distributed trace id. `Source: [lib/otel/traces/segments/utils.js:8-29]()`.

### Semantic Convention Constants

`lib/otel/traces/constants.js` provides a curated copy of OTEL semantic-convention attribute names (e.g. `aws.region`, `db.namespace`). The file's docblock notes that the upstream conventions are "still very much in flux" as of early 2025, so the agent maintains its own copy to insulate downstream code from breakage. `Source: [lib/otel/traces/constants.js:11-20]()`.

## 4. Modern Runtimes and Community Gaps

The Hybrid Agent strategy is particularly relevant for runtimes where the agent's traditional shim-based instrumentation either cannot run or is incomplete. The agent itself still targets Node.js 22+ as documented in [package.json](https://github.com/newrelic/node-newrelic/blob/main/package.json) (`"node": ">=22"`), and existing `core` instrumentations such as timers and DNS in [lib/instrumentation/core/timers.js](https://github.com/newrelic/node-newrelic/blob/main/lib/instrumentation/core/timers.js) and [lib/instrumentation/core/dns.js](https://github.com/newrelic/node-newrelic/blob/main/lib/instrumentation/core/dns.js) operate against Node's built-in modules.

Several long-running community requests illustrate the boundary of the current model:

- **Next.js (#904, addressed in v14.1.0):** the release notes for v14.1.0 explicitly call out "support for native Next.js OTEL instrumentation via the Hybrid Agent," which is the first framework to be brought on board through the OTEL bridge described above.
- **Bun (#1959) and Deno (#1727):** both runtimes execute npm packages but expose a different global surface than Node. Because the agent's bootstrap and `core/timers` instrumentation assumes Node's `setTimeout`/`setInterval` on `global`, these runtimes remain community feature requests rather than supported configurations.
- **ESM (#553):** the default config file lookup uses `newrelic.js`, which fails when a project sets `"type": "module"`. A `newrelic.cjs` workaround is mentioned in the issue, but the agent does not yet auto-detect the extension.
- **Prisma (#991):** because Prisma bypasses the standard `pg`/`mysql2` drivers, neither the agent's shim-based datastore instrumentation nor the OTEL bridge will see the queries, leaving a gap that requires either an upstream Prisma OTEL exporter or a dedicated instrumentation.

For deployments, the agent is also packaged for Azure App Services via the [Azure site extension](https://github.com/newrelic/node-newrelic/blob/main/cloud-tooling/azure-site-extension/Content/README.md), which installs the package and sets `NODE_OPTIONS` so the agent preloads automatically. The Hybrid Agent does not change that deployment model; the OTEL bridge is simply an additional signal source feeding the same agent core.

## See Also

- [Configuration and Instrumentation Overview](https://github.com/newrelic/node-newrelic)
- [OTEL Transformation Rules](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/transformation-rules/index.js)
- [AWS SDK Subscriber](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/aws-sdk/send.js)
- [Azure Site Extension](https://github.com/newrelic/node-newrelic/blob/main/cloud-tooling/azure-site-extension/Content/README.md)

---

<a id='page-4'></a>

## AI/LLM Monitoring and Modern Integrations

### Related Pages

Related topics: [Overview and Core Architecture](#page-1), [Instrumentation Framework and Subscribers](#page-2), [OpenTelemetry, Hybrid Agent, and Modern Runtimes](#page-3)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [lib/subscribers/aws-sdk/middleware/bedrock/utils.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/aws-sdk/middleware/bedrock/utils.js)
- [lib/subscribers/aws-sdk/send.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/aws-sdk/send.js)
- [lib/subscribers/aws-sdk/index.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/aws-sdk/index.js)
- [lib/subscribers/aws-sdk/utils/constants.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/aws-sdk/utils/constants.js)
- [lib/otel/traces/segment-synthesis.js](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/segment-synthesis.js)
- [lib/otel/traces/segments/utils.js](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/segments/utils.js)
- [lib/otel/traces/constants.js](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/constants.js)
- [lib/instrumentation/core/fs.js](https://github.com/newrelic/node-newrelic/blob/main/lib/instrumentation/core/fs.js)
- [lib/instrumentation/core/timers.js](https://github.com/newrelic/node-newrelic/blob/main/lib/instrumentation/core/timers.js)
- [lib/subscribers/kafkajs/utils/record-linking-metrics.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/kafkajs/utils/record-linking-metrics.js)
- [lib/subscribers/kafkajs/utils/record-method-metric.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/kafkajs/utils/record-method-metric.js)
- [lib/metrics/recorders/middleware.js](https://github.com/newrelic/node-newrelic/blob/main/lib/metrics/recorders/middleware.js)
- [package.json](https://github.com/newrelic/node-newrelic/blob/main/package.json)
- [cloud-tooling/azure-site-extension/Content/README.md](https://github.com/newrelic/node-newrelic/blob/main/cloud-tooling/azure-site-extension/Content/README.md)
- [README.md](https://github.com/newrelic/node-newrelic/blob/main/README.md)
</details>

# AI/LLM Monitoring and Modern Integrations

The New Relic Node.js agent has evolved from a classic APM package into a hybrid monitoring tool that supports modern, AI-driven workloads. This page documents the AI/LLM monitoring subsystem (centered on AWS Bedrock), the OpenTelemetry (OTEL) bridge that powers the agent's "Hybrid Agent" mode, and the related modern instrumentation hooks (AWS SDK v3, KafkaJS, core modules). It also calls out runtime and module-format limitations drawn from community discussion.

## AI/LLM Monitoring via AWS Bedrock

AI monitoring is gated by a single configuration switch and implemented as AWS SDK v3 middleware that records a set of LLM event types.

- Gate: `config.ai_monitoring.enabled` — `shouldSkipInstrumentation` returns `true` when the flag is `false`, so the middleware is short-circuited. Source: [lib/subscribers/aws-sdk/middleware/bedrock/utils.js:30-35]()
- Event vocabulary: `LlmChatCompletionMessage`, `LlmChatCompletionSummary`, `LlmEmbedding`, `LlmErrorMessage`, and `BedrockResponse` are imported from `#agentlib/llm-events/aws-bedrock/index.js`. Source: [lib/subscribers/aws-sdk/middleware/bedrock/utils.js:10-18]()
- Streaming: `isStreamingEnabled` checks both the `STREAMING_COMMANDS` set and `config.ai_monitoring?.streaming?.enabled`, delegating to a dedicated `StreamHandler` or `ConverseStreamHandler`. Source: [lib/subscribers/aws-sdk/middleware/bedrock/utils.js:46-53]()
- Attribute destinations: messages and tokens are routed through `DESTINATIONS` from `#agentlib/config/attribute-filter.js` to keep PII filtering consistent with the rest of the agent. Source: [lib/subscribers/aws-sdk/middleware/bedrock/utils.js:11]()

The Bedrock middleware is registered only for the `BedrockRuntime` client, alongside the other AWS v3 services (DynamoDB, Lambda, SNS, SQS). Source: [lib/subscribers/aws-sdk/send.js:12-19]()

## AWS SDK v3 Subscriber Architecture

Instead of registering a subscriber per AWS service package, the agent hooks `@smithy/smithy-client`'s `Client.send` once and dispatches middleware per client name. This is the central integration point for AI monitoring as well as standard AWS tracing.

- Subscriber design: `SmithyClientSendSubscriber` extends the base `Subscriber` and resolves a `middlewareByClient` map at load time. Source: [lib/subscribers/aws-sdk/send.js:12-19]()
- Common concerns: the `nrMiddleware` chain (DT header suppression, response attributes) is applied to every supported client, while service-specific middleware (Bedrock, DynamoDB, Lambda, SNS, SQS) is appended. Source: [lib/subscribers/aws-sdk/send.js:12-19]()
- Distributed-tracing header list: `traceparent`, `tracestate`, `newrelic`. These are the headers that the Bedrock and other AWS middleware suppress on outgoing requests to prevent leaks into non-NR systems. Source: [lib/subscribers/aws-sdk/utils/constants.js:7-9]()
- Middleware contract: each entry in `middlewareByClient` conforms to the `AwsSdkMiddleware` typedef (an `fn` plus optional `init` and `config`). Source: [lib/subscribers/aws-sdk/index.js:1-32]()

## OpenTelemetry Bridge and Hybrid Agent

The agent can synthesize New Relic segments from raw OTEL spans, enabling interoperability with OTEL-instrumented libraries and frameworks (e.g., the native Next.js OTEL path added in v14.1.0).

- Entry point: `SegmentSynthesizer#synthesize(otelSpan)` matches the span to a `RulesEngine` rule and dispatches to one of six segment factories. Source: [lib/otel/traces/segment-synthesis.js:30-71]()
- Supported span kinds: `consumer`, `db`, `external`, `internal`, `producer`, `server` — see `createConsumerSegment`, `createDbSegment`, etc. in the dispatch switch. Source: [lib/otel/traces/segment-synthesis.js:42-71]()
- Trace-context propagation: `propagateTraceContext` builds a W3C `Traceparent` from the OTEL span context, prepending `0` to `traceFlags` because OTEL stores the flags as a parsed integer. The transport tag (e.g., `kafkajs`, `rabbitmq`) is forwarded to `transaction.acceptTraceContextPayload`. Source: [lib/otel/traces/segments/utils.js:16-30]()
- Semantic constants: the agent keeps a curated copy of OTEL semantic-convention attribute names (e.g., `ATTR_AWS_REGION: 'aws.region'`) rather than depending on a moving upstream package. Source: [lib/otel/traces/constants.js:17-32]()

```mermaid
flowchart LR
    A[Instrumented Library] -->|OTEL span| B[SegmentSynthesizer]
    B --> C{RulesEngine match}
    C -->|consumer/db/external<br/>internal/producer/server| D[Segment Factory]
    D --> E[Transaction]
    A -->|direct hook| F[AWS SDK Subscriber]
    F --> G[Bedrock LLM Events]
    F --> H[DT header suppression]
```

## Modern Runtime and Integration Notes

A few adjacent "modern" features that AI/LLM and hybrid deployments typically depend on:

- Node version: the package requires `node >=22` and `npm >=6.0.0`, which is what enables newer features such as `fs.glob` instrumentation. Source: [package.json:31-34]()
- Core `fs`: `glob` is recorded only when it is present on the module (added in Node 22); `write` and `read` are excluded from the recorder list to avoid high-volume noise. Source: [lib/instrumentation/core/fs.js:51-58]()
- Core `timers`: `setTimeout`, `setInterval`, and `clearTimeout` are wrapped on both the `timers` module and `global`; wrapped timers are tagged with a symbol so `clearTimeout` can mark the corresponding segment as ignored. Source: [lib/instrumentation/core/timers.js:18-49]()
- Kafka: per-broker linking metrics (`MessageBroker/Kafka/Nodes/<broker>/<Produce|Consume>/<topic>`) and per-method counters are produced via `recordLinkingMetrics` and `recordMethodMetric`. Source: [lib/subscribers/kafkajs/utils/record-linking-metrics.js:18-24](), [lib/subscribers/kafkajs/utils/record-method-metric.js:12-16]()
- Middleware metrics: `makeMiddlewareRecorder` is the canonical helper for turning segment durations into scoped + unscoped measurements. Source: [lib/metrics/recorders/middleware.js:12-23]()

## Community-Relevant Limitations

Several frequently-requested integrations remain out of scope or partial as of v14.1.0:

- Next.js: native OTEL support landed in v14.1.0 via the Hybrid Agent path, but first-class framework support (custom server, app router specifics) is still requested (issue #904).
- Prisma: Prisma bypasses the standard `pg`/`mysql` drivers, so DB instrumentation does not cover Prisma's query engine (issue #991). Custom instrumentation is the current workaround.
- ESM: when `package.json` declares `"type": "module"`, the loader looks for the default config filename `newrelic.js` and does not auto-detect `newrelic.cjs` (issue #553). Users must pass the config path explicitly or rename the file.
- Bun and Deno: both are requested as target runtimes (issues #1959, #1727). The package currently targets Node ≥ 22 only.
- Cloud deployment: an Azure site extension exists that injects `NODE_OPTIONS` and installs the agent into `node_modules`; the install log lives under `C:\home\SiteExtensions\...`. Source: [cloud-tooling/azure-site-extension/Content/README.md:1-30]()

## See Also

- Configuration reference: `lib/config/default.js` (referenced from the stock `newrelic.js` template in the README).
- General agent installation and `-r newrelic` bootstrap: [README.md](https://github.com/newrelic/node-newrelic/blob/main/README.md).
- LLM event model: `#agentlib/llm-events/aws-bedrock/index.js`.

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Pitfall Log

Project: newrelic/node-newrelic

Summary: Found 14 structured pitfall item(s), including 4 high/blocking item(s). Top priority: Maintenance risk - Maintenance risk requires verification.

## 1. Maintenance risk - Maintenance risk requires verification

- Severity: high
- Evidence strength: source_linked
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/newrelic/node-newrelic/issues/4054

## 2. Maintenance risk - Maintenance risk requires verification

- Severity: high
- Evidence strength: source_linked
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/newrelic/node-newrelic/issues/4053

## 3. Maintenance risk - Maintenance risk requires verification

- Severity: high
- Evidence strength: source_linked
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/newrelic/node-newrelic/issues/4055

## 4. Security or permission risk - Security or permission risk requires verification

- Severity: high
- Evidence strength: source_linked
- Finding: Project evidence flags a security or permission risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/newrelic/node-newrelic/issues/4056

## 5. Identity risk - Identity risk requires verification

- Severity: medium
- Evidence strength: runtime_trace
- Finding: Project evidence flags a identity risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Repro command: `npm install newrelic`
- Evidence: identity.distribution | https://www.npmjs.com/package/newrelic

## 6. Configuration risk - Configuration risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a configuration risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/newrelic/node-newrelic/issues/3458

## 7. Capability evidence risk - Capability evidence risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: README/documentation is current enough for a first validation pass.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.assumptions | https://www.npmjs.com/package/newrelic

## 8. Runtime risk - Runtime risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a runtime risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/newrelic/node-newrelic/issues/4050

## 9. Maintenance risk - Maintenance risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/newrelic/node-newrelic/issues/4057

## 10. Maintenance risk - Maintenance risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://www.npmjs.com/package/newrelic

## 11. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: downstream_validation.risk_items | https://www.npmjs.com/package/newrelic

## 12. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: risks.scoring_risks | https://www.npmjs.com/package/newrelic

## 13. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: issue_or_pr_quality=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://www.npmjs.com/package/newrelic

## 14. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: release_recency=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://www.npmjs.com/package/newrelic

<!-- canonical_name: newrelic/node-newrelic; human_manual_source: deepwiki_human_wiki -->
