npm package: @loongsuite/cms_node_sdk
Description: @loongsuite/cms_node_sdk
Latest version: 1.0.0

@loongsuite/cms_node_sdk

简介

本页提供三个可直接运行的集成方式：
1. AMD（ESM Loader 自动注入）
2. CMD（CommonJS 预加载注入）
3. 手动埋点（完全手动创建与结束 Span）

安装

```bash
npm i @loongsuite/cms_node_sdk @loongsuite/cms_trace @loongsuite/cms_exporters @loongsuite/cms_core
```

说明

- SDK 默认启用 http 自动埋点；AMD/CMD 两种自动注入方式下无需额外配置。
- 下述示例仅使用 Console 导出，复制即可运行并在控制台看到导出日志。

一、AMD 集成（ESM Loader）

适用：ESM 项目。通过 Node.js Loader 在模块加载阶段完成自动注入。

1) 新建文件 server-auto.mjs

```javascript
import { NodeSDK } from '@loongsuite/cms_node_sdk';
import { BatchSpanProcessor } from '@loongsuite/cms_trace';
import { ConsoleSpanExporter } from '@loongsuite/cms_exporters';

const sdk = new NodeSDK({
  serviceName: 'amd-demo',
  spanProcessors: [
    new BatchSpanProcessor(new ConsoleSpanExporter(), {
      scheduledDelayMillis: 300,
      maxExportBatchSize: 1,
    }),
  ],
});
sdk.start();

const httpMod = await import('http');
const http = httpMod.default ?? httpMod;

const server = http.createServer((_req, res) => {
  res.statusCode = 200;
  res.setHeader('content-type', 'text/plain');
  res.end('ok');
});

server.listen(8888, () => {
  console.log('AMD/ESM loader demo: http://localhost:8888');
});
```

2) 启动命令

```bash
node --experimental-loader=@loongsuite/cms_node_sdk/import-hooks ./server-auto.mjs
```

二、CMD 集成（CommonJS 预加载）

适用：CommonJS 项目。通过 -r 预加载在用户代码前启用自动埋点。

1) 新建文件 app.js

```javascript
const http = require('http');

const server = http.createServer((_req, res) => {
  res.statusCode = 200;
  res.setHeader('content-type', 'text/plain');
  res.end('ok');
});

server.listen(8890, () => {
  console.log('CMD/preload demo: http://localhost:8890');
});
```

2) 启动命令

```bash
node -r @loongsuite/cms_node_sdk/register ./app.js
```

三、手动埋点

无需自动注入，完全由业务代码创建与关闭 Span。

1) 新建文件 server-manual.mjs

```javascript
import { NodeSDK } from '@loongsuite/cms_node_sdk';
import { BatchSpanProcessor } from '@loongsuite/cms_trace';
import { ConsoleSpanExporter } from '@loongsuite/cms_exporters';
import * as http from 'http';

const sdk = new NodeSDK({
  serviceName: 'manual-demo',
  spanProcessors: [
    new BatchSpanProcessor(new ConsoleSpanExporter(), {
      scheduledDelayMillis: 300,
      maxExportBatchSize: 1,
    }),
  ],
});
sdk.start();

const tracer = sdk.getTracerManager().getTracer('manual-demo');

const server = http.createServer((req, res) => {
  const span = tracer.startSpan(`${req.method} ${req.url}`, { kind: 1 /* SERVER */ });
  try {
    const tm = sdk.getTracerManager();
    const cm = sdk.getContextManager();
    cm.with(tm.setSpan(cm.active(), span), () => {
      const child = tracer.startSpan('work:handle_request');
      child.end();
      res.statusCode = 200;
      res.setHeader('content-type', 'text/plain');
      res.end('ok');
    });
  } finally {
    span.end();
  }
});

server.listen(8889, () => {
  console.log('Manual demo: http://localhost:8889');
});
```

2) 启动命令

```bash
node ./server-manual.mjs
```

四、可选：切换导出器到 OTLP/ARMS

如需接入 OTLP/ARMS，可将示例中的 ConsoleSpanExporter 替换或并列为其他导出器。

五、Node 18 以下版本注意事项

为保证在 Node < 18 环境下稳定运行，请注意：

1) ESM/Loader 标志

- 使用 AMD/ESM Loader 方式时，Node 14/12 需要实验标志：

```bash
# Node 14/12 示例
node --experimental-modules --experimental-loader=@loongsuite/cms_node_sdk/import-hooks ./server-auto.mjs
```

2) 顶层 await 的替代

- Node 12 对 ESM 支持较弱，若顶层 await 不可用，可改为 IIFE：

```javascript
// server-auto.mjs (替代写法)
import { NodeSDK } from '@loongsuite/cms_node_sdk';
import { BatchSpanProcessor } from '@loongsuite/cms_trace';
import { ConsoleSpanExporter } from '@loongsuite/cms_exporters';

const sdk = new NodeSDK({
  serviceName: 'amd-demo',
  spanProcessors: [new BatchSpanProcessor(new ConsoleSpanExporter(), { scheduledDelayMillis: 300, maxExportBatchSize: 1 })],
});
sdk.start();

(async () => {
  const httpMod = await import('http');
  const http = httpMod.default ?? httpMod;
  const server = http.createServer((_req, res) => {
    res.statusCode = 200;
    res.setHeader('content-type', 'text/plain');
    res.end('ok');
  });
  server.listen(8888, () => console.log('AMD/ESM loader demo: http://localhost:8888'));
})();
```

3) 上下文管理器选择

- Node 12 全版本可用：`AsyncHooksContextManager`（推荐）。
- Node ≥ 12.17 且环境允许：可使用 `AsyncLocalStorageContextManager`。

```javascript
// 手动埋点/CMD 场景可显式指定：
const { AsyncHooksContextManager, AsyncLocalStorageContextManager } = require('@loongsuite/cms_context');

const sdk = new NodeSDK({
  contextManager: new AsyncHooksContextManager(), // Node 12 稳妥选择
});
```

4) ESM 项目与 CommonJS 的选择

- Node 12/14 下，若非必须，优先使用 CommonJS 预加载（CMD）方式；更简单、更稳定。
- 仅在需要拦截 ESM 静态导入时，再考虑 AMD/ESM Loader 方式并开启实验标志。