# https://github.com/newrelic/node-newrelic 项目说明书

生成时间：2026-06-17 18:51:55 UTC

## 目录

- [Agent 核心架构与数据流](#page-1)
- [插桩(Instrumentation)与订阅者(Subscribers)机制](#page-2)
- [配置系统、ESM 支持与自定义扩展](#page-3)
- [AI/LLM 监控、Next.js 混合 Agent 与 OpenTelemetry 集成](#page-4)

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

## Agent 核心架构与数据流

### 相关页面

相关主题：[插桩(Instrumentation)与订阅者(Subscribers)机制](#page-2), [配置系统、ESM 支持与自定义扩展](#page-3)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [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/subscribers/aws-sdk/send.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/aws-sdk/send.js)
- [lib/instrumentation/core/timers.js](https://github.com/newrelic/node-newrelic/blob/main/lib/instrumentation/core/timers.js)
- [lib/instrumentation/core/dns.js](https://github.com/newrelic/node-newrelic/blob/main/lib/instrumentation/core/dns.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/subscribers/amqplib/connect.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/amqplib/connect.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/aws-sdk/middleware/sqs/index.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/aws-sdk/middleware/sqs/index.js)
- [lib/subscribers/aws-sdk/middleware/sns/index.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/aws-sdk/middleware/sns/index.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/metrics/recorders/middleware.js](https://github.com/newrelic/node-newrelic/blob/main/lib/metrics/recorders/middleware.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)
</details>

# Agent 核心架构与数据流

New Relic Node.js 代理通过仪器化（instrumentation）机制采集运行时数据，转换为 Segment 与 Transaction，最终由 Harvester 周期上报至 New Relic Collector。本页基于源码梳理其核心组件、仪器化机制与数据流向。

## 1. 架构总览

代理通过 `require('newrelic')` 引导启动，要求 Node 版本 `>=22`（资料来源：[package.json:38-40]()）。源码内部采用子路径导入别名 `#agentlib/*.js` 指向 `lib/` 下的模块，便于测试与产物中解析相对路径（资料来源：[package.json:67-69]()）。

核心数据通路分为三层：

1. **引导层**：读取 `newrelic.js` 配置，构造 Agent 实例；
2. **仪器化层**：Subscribers 与 Shims 钩住 AWS SDK、amqplib、kafkajs 等第三方模块，在调用生命周期内创建 Segment；
3. **采集与传输层**：事务结束后由 Harvester 汇总，调用 Collector API 异步上报。

```mermaid
flowchart LR
    App[应用代码] -->|require| Agent[Agent 引导]
    Agent -->|装载| Cfg[配置]
    Agent -->|挂载| Sub[Subscribers]
    Sub -->|包装| Mod[目标模块]
    Mod -->|产出| Seg[Segments]
    Seg --> Tx[Transaction]
    Tx -->|聚合| Harv[Harvester]
    Harv -->|HTTPS| Col[New Relic Collector]
    Otel[OTEL Span] -->|SegmentSynthesizer| Seg
    Aws[AWS SDK v3] -->|Smithy Middleware| Seg
    Kfk[Kafka/Amqp] -->|Subscribers| Seg
```

## 2. 仪器化机制

代理采用 **Subscriber + Shim** 模式对 Node.js 核心模块与第三方库进行包装。`lib/instrumentation/core/timers.js` 通过 `shim.record` 注册 `setTimeout`、`setInterval`，并以 `shim.wrap` 重写 `clearTimeout`，在被取消时通过 Symbol 标记对应 segment 为 `ignore`，避免产生无效计时（资料来源：[lib/instrumentation/core/timers.js:30-58]()）。`lib/instrumentation/core/dns.js` 对 `dns.lookup`、`resolve4/6`、`reverse` 等共 12 个方法应用 `RecorderSpec`，生成 `dns.<method>` 段（资料来源：[lib/instrumentation/core/dns.js:9-32]()）。

针对特定库的订阅器位于 `lib/subscribers/`。`lib/subscribers/aws-sdk/send.js` 拦截 `@smithy/smithy-client` 的 `Client.send()`，依据 `middlewareByClient` 映射为 BedrockRuntime、DynamoDB、Lambda、SNS、SQS 等服务注入对应中间件（资料来源：[lib/subscribers/aws-sdk/send.js:14-20]()）。SQS 中间件覆盖 `ReceiveMessageCommand`、`SendMessageCommand`、`SendMessageBatchCommand` 三类命令，命中时将 `subscriber.opaque = true` 并返回异步包装函数（资料来源：[lib/subscribers/aws-sdk/middleware/sqs/index.js:15-44]()）。SNS 则专门处理 `PublishCommand`，优先从 `TopicArn` 或 `TargetArn` 解析目标名称（资料来源：[lib/subscribers/aws-sdk/middleware/sns/index.js:31-48]()）。

## 3. 数据流与转换

代理通过两条主要路径产生段：原生拦截与 OTEL 桥接。`lib/otel/traces/segment-synthesis.js` 中的 `SegmentSynthesizer` 在收到 OTEL Span 后交由 `RulesEngine` 匹配转换规则（资料来源：[lib/otel/traces/segment-synthesis.js:20-28]()）。若规则不匹配则回退到 `FallbackProducer`，输出模板 `MessageBroker/unknown/unknown/Produce`（资料来源：[lib/otel/traces/transformation-rules/499-FallbackProducer.json]()）。匹配成功则按 `rule.type` 分发至 `createConsumerSegment`、`createDbSegment`、`createHttpExternalSegment`、`createInternalSegment`、`createProducerSegment`、`createServerSegment` 之一（资料来源：[lib/otel/traces/segment-synthesis.js:31-54]()）。

跨进程追踪通过 W3C Traceparent 头传递。`propagateTraceContext` 从 OTEL SpanContext 提取 `traceId`、`parentSpanId`、`traceFlags`，构造 `Traceparent` 并调用 `transaction.acceptTraceContextPayload`（资料来源：[lib/otel/traces/segments/utils.js:20-35]()）。在 AWS 场景中，DT 头白名单定义于 `DT_HEADERS = ['traceparent', 'tracestate', 'newrelic']`（资料来源：[lib/subscribers/aws-sdk/utils/constants.js:9]()）。`attach-headers.js` 将这些头注入到 SQS `MessageAttributes` 中，最多 10 个槽位，按优先级回退（资料来源：[lib/subscribers/aws-sdk/utils/attach-headers.js:25-46]()）。

Kafka 路径在 `lib/subscribers/kafkajs/utils/record-linking-metrics.js` 中通过 `MessageBroker/Kafka/Nodes/<broker>/<Produce|Consume>/<topic>` 指标记录每个代理节点的活动（资料来源：[lib/subscribers/kafkajs/utils/record-linking-metrics.js:25-32]()）。amqplib 的 `ConnectSubscriber` 在 `nr_connect` 频道订阅 `asyncStart`、`asyncEnd`，将解析后的 `{ host, port }` 通过 Symbol `amqpConnection` 绑定到连接对象上（资料来源：[lib/subscribers/amqplib/connect.js:14-44]()）。

指标合并由 Recorder 完成。`makeMiddlewareRecorder` 同时记录有 scope（命名指标）与无 scope（聚合指标）两种形式，分别写入 `transaction.measure(metricName, scope, ...)` 和 `transaction.measure(metricName, null, ...)`（资料来源：[lib/metrics/recorders/middleware.js:12-21]()）。

## 4. 社区关注与运行时边界

代理的运行边界由 `engines.node` 明确限定为 `>=22`（资料来源：[package.json:38-40]()），这也解释了部分长期存在的社区诉求：ESM 支持（#553）受默认文件名 `newrelic.js` 限制，BunJS（#1959）与 Deno（#1727）需要兼容非 V8 运行时，Prisma（#991）则需要在其独立引擎上挂接仪器化点。最新 v14.1.0 通过 Hybrid Agent 增加了对原生 Next.js OTEL 仪器的支持（#904），借助上文所述 `SegmentSynthesizer` 桥接 OTEL Span 与本地段模型，从而在不侵入 Next.js 内部的前提下获得追踪数据（资料来源：[README.md]()）。

## See Also

- 配置加载与默认文件名：参见 `newrelic.js`
- Harvester 与采集周期：参见 `lib/harvester.js`
- Collector API 协议：参见 `lib/collector/api.js`

---

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

## 插桩(Instrumentation)与订阅者(Subscribers)机制

### 相关页面

相关主题：[Agent 核心架构与数据流](#page-1), [配置系统、ESM 支持与自定义扩展](#page-3), [AI/LLM 监控、Next.js 混合 Agent 与 OpenTelemetry 集成](#page-4)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [lib/instrumentations.js](https://github.com/newrelic/node-newrelic/blob/main/lib/instrumentations.js)
- [lib/shimmer.js](https://github.com/newrelic/node-newrelic/blob/main/lib/shimmer.js)
- [lib/shim/index.js](https://github.com/newrelic/node-newrelic/blob/main/lib/shim/index.js)
- [lib/shim/datastore-shim.js](https://github.com/newrelic/node-newrelic/blob/main/lib/shim/datastore-shim.js)
- [lib/shim/webframework-shim/index.js](https://github.com/newrelic/node-newrelic/blob/main/lib/shim/webframework-shim/index.js)
- [lib/shim/message-shim/index.js](https://github.com/newrelic/node-newrelic/blob/main/lib/shim/message-shim/index.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/middleware/sqs/index.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/aws-sdk/middleware/sqs/index.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/subscribers/amqplib/connect.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/amqplib/connect.js)
- [lib/subscribers/amqplib/send-message.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/amqplib/send-message.js)
- [lib/instrumentation/core/timers.js](https://github.com/newrelic/node-newrelic/blob/main/lib/instrumentation/core/timers.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/producer.js](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/segments/producer.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)
- [README.md](https://github.com/newrelic/node-newrelic/blob/main/README.md)

</details>

# 插桩(Instrumentation)与订阅者(Subscribers)机制

## 1. 概述

`node-newrelic` 是 New Relic 官方发布的 Node.js 性能监控代理，其核心使命在于对用户应用程序进行**透明插桩(transparent instrumentation)**,自动捕获 HTTP 请求、数据库调用、消息队列通信以及 AWS SDK 调用等运行时行为，并将数据上报至 New Relic 后端。代理通过 `newrelic` npm 包被加载到目标进程中，要求 Node.js 版本不低于 22（见 `package.json` 中的 `engines.node` 字段）。

插桩系统采用两层设计：

- **底层(Shimmer 层)**:通过 `lib/shimmer.js` 提供的 `wrap`/`record`/`wrapReturn` 等原语，在运行时替换 Node.js 模块的关键方法。
- **业务层(Subscriber 层)**:针对每一种被监控的库（kafkajs、amqplib、AWS SDK v3、Apollo Server 等）实现订阅者，将这些原语组合成具体的监控逻辑。

社区中关于 Prisma（issue #991）、ESM（#553）、BunJS（#1959）、Next.js（#904）与 Deno（#1727）的兼容性请求，本质上都集中在该插桩机制如何适配新型运行时与 ORM 引擎上。

## 2. 整体架构

插桩系统的核心数据流可概括为：**模块加载 → Shimmer 包裹 → 订阅者触发 → 记录器写入指标**。每个被监控的 npm 包都对应 `lib/instrumentations.js` 中的一条配置项。

```mermaid
flowchart LR
  A[Node.js require] --> B[instrumentations.js 匹配]
  B --> C[Shimmer.wrap/record]
  C --> D[Subscriber.handler]
  D --> E[Tracer 创建 Segment]
  E --> F[Metric Recorder]
  F --> G[MetricsAggregator]
  G --> H[New Relic Collector]
```

### 2.1 Shimmer 与 Shim

`lib/shimmer.js` 是最基础的包裹器，负责在函数执行前后注入回调；而 `lib/shim/index.js` 在 Shimmer 之上提供了领域语义，包括:

- `DatastoreShim`（`lib/shim/datastore-shim.js`）:用于数据库驱动，记录 SQL、集合名与主机。
- `WebFrameworkShim`（`lib/shim/webframework-shim/index.js`）:用于 Express、Koa 等 Web 框架。
- `MessageShim`（`lib/shim/message-shim/index.js`）:用于消息队列场景。

### 2.2 核心 API 插桩示例

以定时器为例，`lib/instrumentation/core/timers.js` 调用 `shim.record(nodule, asynchronizers, recordAsynchronizers)`，对 `setTimeout`、`setInterval` 进行计时，并将 `clearTimeout` 包裹为 `wrappedClearTimeout`，在清理时把对应 segment 标记为 `ignore = true`，避免上报无效的孤立片段。

## 3. 订阅者(Subscribers)子系统

订阅者是具体业务逻辑的载体。基类位于 `lib/subscribers/base.js`，每一种协议/库都派生出对应实现。

### 3.1 AWS SDK v3 订阅者

`lib/subscribers/aws-sdk/send.js` 定义了 `SmithyClientSendSubscriber`，通过单一 hook 覆盖所有 AWS SDK v3 服务。该文件中的 `middlewareByClient` 映射按服务名分派中间件（BedrockRuntime、DynamoDB、Lambda、SNS、SQS 等），其余服务回退到原有 shim 插桩。

`lib/subscribers/aws-sdk/middleware/sqs/index.js` 仅对 `ReceiveMessageCommand`、`SendMessageCommand`、`SendMessageBatchCommand` 三类命令启用中间件，定义 `priority: 'high'` 与 `override: true` 以保证链路稳定。

`lib/subscribers/aws-sdk/utils/attach-headers.js` 用于在 SQS 消息 `MessageAttributes` 中注入分布式追踪头。AWS 限制每条消息最多 10 个属性，因此该函数对头进行优先级排序并自动剔除超出部分。相关的头名称集中在 `lib/subscribers/aws-sdk/utils/constants.js` 的 `DT_HEADERS` 常量中（`traceparent`、`tracestate`、`newrelic`）。

### 3.2 消息队列订阅者

**Kafka**:`lib/subscribers/kafkajs/utils/record-linking-metrics.js` 按 broker 生成 `MessageBroker/Kafka/Nodes/{broker}/{Produce|Consume}/{topic}` 指标；`lib/subscribers/kafkajs/utils/record-method-metric.js` 则记录每一次方法调用。

**RabbitMQ**:`lib/subscribers/amqplib/connect.js` 在连接阶段创建 `amqplib.connect` 段；`lib/subscribers/amqplib/send-message.js` 继承 `MessageProducerSubscriber`，将消息路由识别为 `Default` 交换机或自定义 exchange，并提取发布参数。

### 3.3 指标记录器(Recorders)

记录器是订阅者与 `MetricsAggregator` 之间的桥梁。

| 记录器 | 文件 | 职责 |
|--------|------|------|
| `makeMiddlewareRecorder` | `lib/metrics/recorders/middleware.js` | 通用中间件耗时与独占时间 |
| `recordResolveSegment` | `lib/metrics/recorders/apollo-resolver.js` | Apollo Server 解析器字段耗时 |

`makeMiddlewareRecorder` 返回的工厂函数接收 `metricName` 后闭包生成记录器，分别按 `scope`（作用域）与全局两次调用 `transaction.measure`，从而保证既得到按路由分桶的指标，也得到聚合指标。

## 4. OpenTelemetry 桥接与转换规则

v14.x 起，代理引入了原生 OTEL 支持（最新发布说明见 v14.1.0）。`lib/otel/traces/segments/producer.js` 为 OTEL span 创建对应的 New Relic segment，`lib/otel/traces/segments/utils.js` 中的 `propagateTraceContext` 使用 `Traceparent` 将 OTEL trace context 透传到事务。当 OTEL span 不能匹配任何具体规则时，备用规则 `lib/otel/traces/transformation-rules/499-FallbackProducer.json` 将其命名为 `MessageBroker/unknown/unknown/Produce`，保证数据不丢失。

## 5. 常见失败模式

- **ESM 配置未生效**(issue #553):默认配置文件名为 `newrelic.js`，使用 `type: "module"` 时需显式指定 `newrelic.cjs`。
- **非标准 ORM**(issue #991):Prisma 等绕过 `pg`/`mysql` 驱动的 ORM 无法被现有 `DatastoreShim` 自动捕获，需要自定义插桩。
- **替代运行时**(issue #1727、#1959):BunJS 与 Deno 的模块解析机制与 Node.js 不同，shimmer 的 `require` 拦截会失效。
- **段孤儿化**:当 `setTimeout` 回调在事务结束后才触发，段将被忽略。`timers.js` 中的 `wrapClearTimeout` 会在清理时显式设置 `segment.ignore = true`，避免无效上报。

## See Also

- 配置文件与安装说明见 [README.md](https://github.com/newrelic/node-newrelic/blob/main/README.md)
- 引擎与依赖约束见 [package.json](https://github.com/newrelic/node-newrelic/blob/main/package.json)
- Azure 站点扩展部署见 [cloud-tooling/azure-site-extension/Content/README.md](https://github.com/newrelic/node-newrelic/blob/main/cloud-tooling/azure-site-extension/Content/README.md)

---

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

## 配置系统、ESM 支持与自定义扩展

### 相关页面

相关主题：[Agent 核心架构与数据流](#page-1), [插桩(Instrumentation)与订阅者(Subscribers)机制](#page-2)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/newrelic/node-newrelic/blob/main/README.md)
- [package.json](https://github.com/newrelic/node-newrelic/blob/main/package.json)
- [esm-loader.mjs](https://github.com/newrelic/node-newrelic/blob/main/esm-loader.mjs)
- [newrelic.js](https://github.com/newrelic/node-newrelic/blob/main/newrelic.js)
- [api.js](https://github.com/newrelic/node-newrelic/blob/main/api.js)
- [stub_api.js](https://github.com/newrelic/node-newrelic/blob/main/stub_api.js)
- [lib/config/default.js](https://github.com/newrelic/node-newrelic/blob/main/lib/config/default.js)
- [lib/config/index.js](https://github.com/newrelic/node-newrelic/blob/main/lib/config/index.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)
- [lib/otel/traces/segment-synthesis.js](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/segment-synthesis.js)
- [lib/subscribers/aws-sdk/send.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/aws-sdk/send.js)
</details>

# 配置系统、ESM 支持与自定义扩展

New Relic 的 Node.js 探针通过多层机制让用户在不同的运行时环境下完成加载、配置与扩展：核心配置文件、环境变量与命令行参数决定了探针行为；ESM 加载器让原生 ES Module 项目也能挂载探针；Hybrid Agent、Azure Site Extension 等扩展机制则将探针集成到云平台与第三方框架中。本页从源码角度梳理这套配置与扩展体系，帮助开发者理解探针在不同场景下的初始化路径。

## 1. 配置系统的三层结构

New Relic Node 探针的配置体系由三个层次组成：默认配置文件、用户级 `newrelic.js`、以及环境变量覆盖。

默认配置定义在 `lib/config/default.js` 中，作为所有用户配置的基线。`lib/config/index.js` 负责加载与合并流程：先读取默认配置，再读取用户配置文件，最后应用环境变量与命令行参数。顶层入口 `newrelic.js` 是用户最常编辑的配置文件，它会通过 `require()` 导出一个 JS 对象来覆盖默认值。`package.json` 中 `files` 字段明确将该文件与 `index.js`、`api.js`、`stub_api.js`、`load-externals.js` 一同打包发布 [资料来源：[package.json]()]。

运行时通过 `api.js` 暴露应用编程接口（API），让用户在应用代码内部也能查询或调整探针行为；`stub_api.js` 则在探针被禁用时提供一个空实现，确保即使未加载真实探针，应用调用 `require('newrelic')` 也不会崩溃。README.md 中建议的典型安装流程为：先 `npm install newrelic`，再在项目根目录创建配置文件，最后在应用入口通过 `require('newrelic')` 加载 [资料来源：[README.md]()]。

| 配置层 | 文件 / 来源 | 作用 | 可被覆盖 |
|---|---|---|---|
| 默认值 | `lib/config/default.js` | 提供全部可选项的初值 | 否 |
| 用户配置 | `newrelic.js` | 应用专属覆盖 | 是 |
| 环境变量 | `NEW_RELIC_*` 系列 | 部署时动态调整 | 是 |
| 运行时 API | `api.js` / `stub_api.js` | 应用内控制 | 是 |

## 2. ESM 支持与 Loader 机制

社区长期关注的 ES Module 支持由 `esm-loader.mjs` 实现。`package.json` 的 `engines` 字段要求 Node.js `>=22`，这是 ESM 加载器可靠运行的基础条件 [资料来源：[package.json]()]。当用户项目声明 `"type": "module"` 时，传统 `require('newrelic')` 方式在某些场景下无法找到默认的 `newrelic.js`（即社区问题 #553 中所描述的 `newrelic.cjs` 找不到的问题）。

为解决该问题，仓库同时发布 `esm-loader.mjs` 作为 Node.js 加载器钩子（loader hook）。开发者可通过 `NODE_OPTIONS='--loader=./node_modules/newrelic/esm-loader.mjs'` 启动应用，让 Node 在解析 ESM 时同步执行探针注入逻辑。`package.json` 的 `scripts` 中还提供了 `integration:esm` 任务，使用相同的 loader 跑集成测试，确保该机制在 CI 中被持续验证 [资料来源：[package.json]()]。

对于 Bun、Deno 等非官方 Node 兼容运行时（Bun #1959、Deno #1727），目前 Loader 仍依赖 Node 原生 `module.register` 钩子，官方未提供直接支持，需要通过 `--require` 或自定义胶水代码绕过。Next.js（#904）则通过最新 v14.1.0 中引入的 Hybrid Agent，由原生 OTEL 仪表化层完成接入，不再依赖传统 shim [资料来源：[README.md]()]。

```mermaid
flowchart LR
    A[应用入口] -->|require/import| B[newrelic]
    B --> C{是否为 ESM?}
    C -- 否 --> D[传统 shim 仪表化]
    C -- 是 --> E[esm-loader.mjs]
    E --> D
    D --> F[订阅器/Subscribers]
    F --> G[AWS SDK / OTEL / Next.js]
```

## 3. 自定义扩展：Hybrid Agent 与 Azure Site Extension

`lib/otel/traces/segment-synthesis.js` 中的 `SegmentSynthesizer` 类体现了 Hybrid Agent 的核心思路：它接收来自 OpenTelemetry 的 span，使用 `RulesEngine` 匹配规则（`lib/otel/traces/transformation-rules/*.json`）后调用相应的 `createXxxSegment` 工厂方法（HTTP、数据库、生产者、消费者等），最终生成 New Relic 内部的 segment 树 [资料来源：[lib/otel/traces/segment-synthesis.js]()]。

`lib/subscribers/aws-sdk/send.js` 展示了另一类扩展点：它通过 `middlewareByClient` 映射表将 `BedrockRuntime`、`DynamoDB`、`Lambda`、`SNS`、`SQS` 等 AWS SDK v3 服务与对应中间件链关联，单个 `@smithy/smithy-client` 的 `Client.send()` 钩子即可覆盖全部 AWS 服务 [资料来源：[lib/subscribers/aws-sdk/send.js]()]。

对云平台而言，`cloud-tooling/azure-site-extension/` 目录提供了 Azure 站点扩展，安装后会在 `NODE_OPTIONS` 中注入预加载项，并自动把探针及其依赖安装到 `C:\home\site\wwwroot\node_modules`；失败时会在 `install.log` 中记录原因 [资料来源：[cloud-tooling/azure-site-extension/Content/README.md]()]。

## 4. 常见失败模式与排查

1. **ESM 项目下找不到配置**：当 `package.json` 设置 `"type": "module"` 并把配置命名为 `newrelic.cjs` 时，需确认 Loader 已正确加载，或显式在 `newrelic.js` 中通过 `process.env.NEW_RELIC_CONFIG_FILE` 指向 `.cjs` 文件（参考 #553）。
2. **Prisma 数据存储未仪表化**：Prisma 使用自研引擎绕过 `pg`/`mysql`，因此 #991 描述的 SQL 仪表化不会自动生效；可通过自定义 Instrumentation 订阅器或记录外部 segment 的方式补偿。
3. **非 Node 运行时**：Bun、Deno 需要自行桥接 `require`/`module.register` 钩子；Next.js 14+ 建议改用 Hybrid Agent。

## See Also

- 安装与基础用法：见 [README.md](https://github.com/newrelic/node-newrelic/blob/main/README.md)
- AWS SDK v3 中间件：见 [lib/subscribers/aws-sdk/send.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/aws-sdk/send.js)
- OpenTelemetry Segment 合成：见 [lib/otel/traces/segment-synthesis.js](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/segment-synthesis.js)
- Azure 站点扩展：见 [cloud-tooling/azure-site-extension/Content/README.md](https://github.com/newrelic/node-newrelic/blob/main/cloud-tooling/azure-site-extension/Content/README.md)

---

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

## AI/LLM 监控、Next.js 混合 Agent 与 OpenTelemetry 集成

### 相关页面

相关主题：[Agent 核心架构与数据流](#page-1), [插桩(Instrumentation)与订阅者(Subscribers)机制](#page-2), [配置系统、ESM 支持与自定义扩展](#page-3)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [lib/subscribers/aws-sdk/send.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/aws-sdk/send.js)
- [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/middleware/nr-specific/index.js](https://github.com/newrelic/node-newrelic/blob/main/lib/subscribers/aws-sdk/middleware/nr-specific/index.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/otel/traces/segment-synthesis.js](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/segment-synthesis.js)
- [lib/otel/traces/rules.js](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/rules.js)
- [lib/otel/traces/exception-mapping.js](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/exception-mapping.js)
- [lib/otel/traces/segments/utils.js](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/segments/utils.js)
- [lib/otel/traces/utils.js](https://github.com/newrelic/node-newrelic/blob/main/lib/otel/traces/utils.js)
- [package.json](https://github.com/newrelic/node-newrelic/blob/main/package.json)
</details>

# AI/LLM 监控、Next.js 混合 Agent 与 OpenTelemetry 集成

## 1. 概览

New Relic Node Agent v14.1.0 引入了三项面向现代 LLM 应用与多运行时场景的观测能力。社区长期关注的 Next.js 支持请求 (issue #904) 在该版本中以"混合 Agent (Hybrid Agent)"形式落地，其核心是复用原生的 OpenTelemetry (OTEL) 插桩并将其合成为 New Relic 自身的事务 (Transaction) 与段 (Segment) 模型，相关依赖声明见 [package.json:6-12]()。

与此同时，Agent 通过统一订阅 AWS SDK v3 的 `@smithy/smithy-client` 的 `Client.send` 方法，将 Bedrock、DynamoDB、Lambda、SNS、SQS 等原本需要各自编写 subscriber 的服务合并到一条入口链上 资料来源：[lib/subscribers/aws-sdk/send.js:1-20]()。这种"一次 hook 覆盖所有 AWS 服务"的设计让 LLM 请求与分布式追踪传播可以在同一通道中完成。

## 2. LLM 监控 (AWS Bedrock)

Bedrock 子模块定义了一组完整的 LLM 事件类: `LlmChatCompletionMessage`、`LlmChatCompletionSummary`、`LlmEmbedding`、`LlmErrorMessage` 与 `BedrockResponse` 资料来源：[lib/subscribers/aws-sdk/middleware/bedrock/utils.js:1-15]()。这些类型最终被 New Relic AI Monitoring 用来输出 token、用时与提示词上下文等数据。

启用控制由两个判断函数承担:
- `shouldSkipInstrumentation(config)` 通过 `config.ai_monitoring.enabled === false` 决定是否整体跳过 资料来源：[lib/subscribers/aws-sdk/middleware/bedrock/utils.js:38-43]()。
- `isStreamingEnabled({ commandName, config })` 同时要求命令名命中 `STREAMING_COMMANDS` 集合，且 `config.ai_monitoring.streaming.enabled` 为真 资料来源：[lib/subscribers/aws-sdk/middleware/bedrock/utils.js:46-58]()。

所有支持的服务 (BedrockRuntime、DynamoDB、Lambda、SNS、SQS) 共用同一套通用 NR 中间件 (`headers.js` 与 `attributes.js`)，减少了每服务一份样板代码的需要 资料来源：[lib/subscribers/aws-sdk/middleware/nr-specific/index.js:1-10]()。分布式追踪头通过 `attachHeaders` 注入到消息的 `MessageAttributes`，并尊重 AWS 消息属性最多 10 个的上限，按优先级挑选最关键的头写入 资料来源：[lib/subscribers/aws-sdk/utils/attach-headers.js:14-32]()。

## 3. OpenTelemetry 集成与段合成

OTEL 段合成的核心入口是 `SegmentSynthesizer`。它在构造时持有一个 `RulesEngine` 实例，对每个 OTEL span 进行匹配 资料来源：[lib/otel/traces/segment-synthesis.js:1-25]()。当某条规则命中时，调度器按 `rule.type` 分派到对应的段工厂: consumer、db、external、internal、producer、server 资料来源：[lib/otel/traces/segment-synthesis.js:31-55]()。

规则由 `OtelRuleMatcher` 类型描述，包含 `required_span_kinds`、`required_attribute_keys`、`attribute_conditions` 与 `scope_name` 四个判定维度 资料来源：[lib/otel/traces/rules.js:1-25]()。规则集从 JSON 资源加载后，由 `buildRuleMappings` 编译为可执行函数 资料来源：[lib/otel/traces/utils.js:18-30]()。

异常属性的归一化通过一个小映射表完成: `msg` 对应 `EXCEPTION_MESSAGE`/`EXCEPTION_TYPE`，`stack` 对应 `EXCEPTION_STACKTRACE` 资料来源：[lib/otel/traces/exception-mapping.js:1-15]()。上下文传播方面，`propagateTraceContext` 在 span 拥有父级时构造 W3C `traceparent` 并调用 `transaction.acceptTraceContextPayload`，让 OTEL 的追踪上下文被 New Relic 事务继承 资料来源：[lib/otel/traces/segments/utils.js:14-30]()。

## 4. Next.js 混合 Agent

针对 issue #904 (Next.js)、#1959 (BunJS) 等多运行时诉求，v14.1.0 通过 PR #4040 引入了基于原生 OTEL 插桩的"混合 Agent"路径: Next.js 自身产出的 OTEL span 由 `SegmentSynthesizer` 自动合成为 New Relic 段，避免与进程内已有的 `Subscriber` 钩子产生重复或冲突 资料来源：[lib/otel/traces/segment-synthesis.js:18-30]()。这样既保留了统一抽象，又允许第三方插桩继续输出标准 OTEL 信号。

| 场景 | 启用方式 | 数据模型 |
| --- | --- | --- |
| Bedrock LLM | `ai_monitoring.enabled = true` | `LlmChatCompletionMessage` / `LlmChatCompletionSummary` / `LlmEmbedding` |
| OTEL span 合成 | 启动 OTEL SDK | New Relic `Transaction` / `Segment` |
| Next.js 混合 Agent | v14.1.0 默认开启 (PR #4040) | 双向: OTEL ↔ New Relic |

## 参见

- 社区 issue #904 — Support for Next.js
- 社区 issue #991 — Support for Prisma as a datastore
- 社区 issue #1959 — Add BunJS compatibility
- v14.1.0 发布说明 (PR #4040)
- 相关目录: `lib/subscribers/aws-sdk/`、`lib/otel/traces/`

---

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

---

## Doramagic 踩坑日志

项目：newrelic/node-newrelic

摘要：发现 14 个潜在踩坑项，其中 4 个为 high/blocking；最高优先级：维护坑 - 来源证据：Drop support for next < 16。

## 1. 维护坑 · 来源证据：Drop support for next < 16

- 严重度：high
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：Drop support for next < 16
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 证据：community_evidence:github | https://github.com/newrelic/node-newrelic/issues/4054 | 来源讨论提到 node 相关条件，需在安装/试用前复核。

## 2. 维护坑 · 来源证据：Drop support for prisma wasm client

- 严重度：high
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：Drop support for prisma wasm client
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 证据：community_evidence:github | https://github.com/newrelic/node-newrelic/issues/4053 | 来源类型 github_issue 暴露的待验证使用条件。

## 3. 维护坑 · 来源证据：Drop support for restify

- 严重度：high
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：Drop support for restify
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 证据：community_evidence:github | https://github.com/newrelic/node-newrelic/issues/4055 | 来源讨论提到 node 相关条件，需在安装/试用前复核。

## 4. 安全/权限坑 · 来源证据：[spike] Research migrating security agent to use tracing channel instrumentation

- 严重度：high
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：[spike] Research migrating security agent to use tracing channel instrumentation
- 对用户的影响：可能影响升级、迁移或版本选择。
- 证据：community_evidence:github | https://github.com/newrelic/node-newrelic/issues/4056 | 来源讨论提到 node 相关条件，需在安装/试用前复核。

## 5. 身份坑 · 仓库名和安装名不一致

- 严重度：medium
- 证据强度：runtime_trace
- 发现：仓库名 `node-newrelic` 与安装入口 `newrelic` 不完全一致。
- 对用户的影响：用户照着仓库名搜索包或照着包名找仓库时容易走错入口。
- 复现命令：`npm install newrelic`
- 证据：identity.distribution | https://www.npmjs.com/package/newrelic | repo=node-newrelic; install=newrelic

## 6. 配置坑 · 来源证据：Fix Next.js tests

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个配置相关的待验证问题：Fix Next.js tests
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 证据：community_evidence:github | https://github.com/newrelic/node-newrelic/issues/3458 | 来源类型 github_issue 暴露的待验证使用条件。

## 7. 能力坑 · 能力判断依赖假设

- 严重度：medium
- 证据强度：source_linked
- 发现：README/documentation is current enough for a first validation pass.
- 对用户的影响：假设不成立时，用户拿不到承诺的能力。
- 证据：capability.assumptions | https://www.npmjs.com/package/newrelic | README/documentation is current enough for a first validation pass.

## 8. 运行坑 · 来源证据：Add supportability metrics to OTEL metrics exporter

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个运行相关的待验证问题：Add supportability metrics to OTEL metrics exporter
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 证据：community_evidence:github | https://github.com/newrelic/node-newrelic/issues/4050 | 来源讨论提到 node 相关条件，需在安装/试用前复核。

## 9. 维护坑 · 来源证据：[spike] Research replacing instrument* api methods

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：[spike] Research replacing instrument* api methods
- 对用户的影响：可能影响升级、迁移或版本选择。
- 证据：community_evidence:github | https://github.com/newrelic/node-newrelic/issues/4057 | 来源讨论提到 node 相关条件，需在安装/试用前复核。

## 10. 维护坑 · 维护活跃度未知

- 严重度：medium
- 证据强度：source_linked
- 发现：未记录 last_activity_observed。
- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。
- 证据：evidence.maintainer_signals | https://www.npmjs.com/package/newrelic | last_activity_observed missing

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 证据：downstream_validation.risk_items | https://www.npmjs.com/package/newrelic | no_demo; severity=medium

## 12. 安全/权限坑 · 存在评分风险

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 对用户的影响：风险会影响是否适合普通用户安装。
- 证据：risks.scoring_risks | https://www.npmjs.com/package/newrelic | no_demo; severity=medium

## 13. 维护坑 · issue/PR 响应质量未知

- 严重度：low
- 证据强度：source_linked
- 发现：issue_or_pr_quality=unknown。
- 对用户的影响：用户无法判断遇到问题后是否有人维护。
- 证据：evidence.maintainer_signals | https://www.npmjs.com/package/newrelic | issue_or_pr_quality=unknown

## 14. 维护坑 · 发布节奏不明确

- 严重度：low
- 证据强度：source_linked
- 发现：release_recency=unknown。
- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。
- 证据：evidence.maintainer_signals | https://www.npmjs.com/package/newrelic | release_recency=unknown

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