@elastic/mockotlpserver

中文文档
0.12.0发布于 2026/06/17Apache-2.0CommonJS构建来源已验证近 30 天下载 5186

模拟 OTLP 服务器, 可用于 dev 和测试

中文使用文档
文档目录4 节
  1. 不同的OTLP协议
  2. 不同的模拟服务器打印机
  3. json, json2 (英语)
  4. 微量摘要

@ 弹性/ mockotlpserver

用于开发和测试的模拟OTLP(开放遥测协议)服务器/接收器.

mockotlpserver 启动 HTTP 和 gRPC 服务器( 在默认的 OTLP 端口上) 收到OTLP请求。 请求中的数据将打印到 操纵台 支持各种输出格式.

它还支持从Node.js代码运行. 此用于 "./开远测量-节点"包件协助测试. 测试的形式是:

  1. 启动模拟服务器
  2. 运行有乐器的脚本
  3. 从模拟服务器获取收到的OTLP数据,并对这些数据作出断言.

CLI 使用量

首先要使用模拟服务器 启动服务器您可以通过 npx, (中文(简体) ), 如果你使用这个:

npx @elastic/mockotlpserver
npx @elastic/mockotlpserver --help

或通过出版物 ghcr.io/elastic/elastic-otel-node/mockotlpserver Docker 图像 :

docker run --rm -it -p 4317:4317 -p 4318:4318 --name mockotlpserver \
    ghcr.io/elastic/elastic-otel-node/mockotlpserver:latest

接下来, 向它发送OTLP数据。 。 。 .

默认情况下,smootlpserver将输出收到的OTLP数据,其形式有两种:

  1. inspect 格式: 使用节点.js util.inspect() (盖下用于: console.log) (中文(简体) ). 显示接收对象的完整结构 数据.
  2. summary 格式 : 这是一个自定义文本格式,试图显示 数据简要/相关摘要。 这一格式目前更为完善 页:1 跟踪 和一些为 日志/ 事件关于衡量尺度,摘要 产出不佳.

例如,这里是接收小型遥测数据时的输出 创建 HTTP 服务器并提出单一请求的脚本 . (此示例使用 OpenTeleometry 节点的弹性分布 页:1 仪器 上游 OpenTelemeting 节点 SDK 也可以使用。 )

git clone [email protected]:elastic/elastic-otel-node.git
cd elastic-otel-node
npm run ci-all
cd examples/
node -r @elastic/opentelemetry-node simple-http-request.js
模拟服务器控制台输出
% node lib/cli.js
{"name":"mockotlpserver","level":30,"msg":"OTLP/HTTP listening at http://[::1]:4318/","time":"2024-01-11T22:18:49.017Z"}
{"name":"mockotlpserver","level":30,"msg":"OTLP/HTTP listening at http://localhost:4317/","time":"2024-01-11T22:18:49.025Z"}
ExportTraceServiceRequest {
  resourceSpans: [
    ResourceSpans {
      scopeSpans: [
        ScopeSpans {
          spans: [
            Span {
              attributes: [
                KeyValue { key: 'http.url', value: AnyValue { stringValue: 'http://localhost:3000/' } },
                KeyValue { key: 'http.host', value: AnyValue { stringValue: 'localhost:3000' } },
                KeyValue { key: 'net.host.name', value: AnyValue { stringValue: 'localhost' } },
                KeyValue { key: 'http.method', value: AnyValue { stringValue: 'GET' } },
                KeyValue { key: 'http.scheme', value: AnyValue { stringValue: 'http' } },
                KeyValue { key: 'http.target', value: AnyValue { stringValue: '/' } },
                KeyValue { key: 'http.flavor', value: AnyValue { stringValue: '1.1' } },
                KeyValue { key: 'net.transport', value: AnyValue { stringValue: 'ip_tcp' } },
                KeyValue { key: 'net.host.ip', value: AnyValue { stringValue: '::1' } },
                KeyValue { key: 'net.host.port', value: AnyValue { intValue: Long { low: 3000, high: 0, unsigned: false } } },
                KeyValue { key: 'net.peer.ip', value: AnyValue { stringValue: '::1' } },
                KeyValue { key: 'net.peer.port', value: AnyValue { intValue: Long { low: 61855, high: 0, unsigned: false } } },
                KeyValue { key: 'http.status_code', value: AnyValue { intValue: Long { low: 200, high: 0, unsigned: false } } },
                KeyValue { key: 'http.status_text', value: AnyValue { stringValue: 'OK' } }
              ],
              events: [],
              links: [],
              traceId: Buffer(16) [Uint8Array] [
                128,  35,  86,  43, 203,
                245, 130,  92,  63, 188,
                 74, 232, 155, 123, 212,
                222
              ],
              spanId: Buffer(8) [Uint8Array] [
                 34, 107, 247,  13,
                140, 202, 136, 107
              ],
              parentSpanId: Buffer(8) [Uint8Array] [
                240, 107,  26, 226,
                101, 131, 149,  15
              ],
              name: 'GET',
              kind: 2,
              startTimeUnixNano: Long { low: 448057536, high: 396978934, unsigned: true },
              endTimeUnixNano: Long { low: 452218144, high: 396978934, unsigned: true },
              droppedAttributesCount: 0,
              droppedEventsCount: 0,
              droppedLinksCount: 0,
              status: Status { code: 0 }
            },
            Span {
              attributes: [
                KeyValue { key: 'http.url', value: AnyValue { stringValue: 'http://localhost:3000/' } },
                KeyValue { key: 'http.method', value: AnyValue { stringValue: 'GET' } },
                KeyValue { key: 'http.target', value: AnyValue { stringValue: '/' } },
                KeyValue { key: 'net.peer.name', value: AnyValue { stringValue: 'localhost' } },
                KeyValue { key: 'http.host', value: AnyValue { stringValue: 'localhost:3000' } },
                KeyValue { key: 'net.peer.ip', value: AnyValue { stringValue: '::1' } },
                KeyValue { key: 'net.peer.port', value: AnyValue { intValue: Long { low: 3000, high: 0, unsigned: false } } },
                KeyValue { key: 'http.response_content_length_uncompressed', value: AnyValue { intValue: Long { low: 4, high: 0, unsigned: false } } },
                KeyValue { key: 'http.status_code', value: AnyValue { intValue: Long { low: 200, high: 0, unsigned: false } } },
                KeyValue { key: 'http.status_text', value: AnyValue { stringValue: 'OK' } },
                KeyValue { key: 'http.flavor', value: AnyValue { stringValue: '1.1' } },
                KeyValue { key: 'net.transport', value: AnyValue { stringValue: 'ip_tcp' } }
              ],
              events: [],
              links: [],
              traceId: Buffer(16) [Uint8Array] [
                128,  35,  86,  43, 203,
                245, 130,  92,  63, 188,
                 74, 232, 155, 123, 212,
                222
              ],
              spanId: Buffer(8) [Uint8Array] [
                240, 107,  26, 226,
                101, 131, 149,  15
              ],
              name: 'GET',
              kind: 3,
              startTimeUnixNano: Long { low: 439057536, high: 396978934, unsigned: true },
              endTimeUnixNano: Long { low: 454517668, high: 396978934, unsigned: true },
              droppedAttributesCount: 0,
              droppedEventsCount: 0,
              droppedLinksCount: 0,
              status: Status { code: 0 }
            }
          ],
          scope: InstrumentationScope { attributes: [], name: '@opentelemetry/instrumentation-http', version: '0.45.1' }
        }
      ],
      resource: Resource {
        attributes: [
          KeyValue { key: 'service.name', value: AnyValue { stringValue: 'unknown-node-service' } },
          KeyValue { key: 'telemetry.sdk.language', value: AnyValue { stringValue: 'nodejs' } },
          KeyValue { key: 'telemetry.sdk.name', value: AnyValue { stringValue: 'opentelemetry' } },
          KeyValue { key: 'telemetry.sdk.version', value: AnyValue { stringValue: '1.18.1' } },
          KeyValue { key: 'process.pid', value: AnyValue { intValue: Long { low: 82408, high: 0, unsigned: false } } },
          KeyValue { key: 'process.executable.name', value: AnyValue { stringValue: 'node' } },
          KeyValue { key: 'process.executable.path', value: AnyValue { stringValue: '/Users/trentm/.nvm/versions/node/v18.18.2/bin/node' } },
          KeyValue {
            key: 'process.command_args',
            value: AnyValue {
              arrayValue: ArrayValue {
                values: [
                  AnyValue { stringValue: '/Users/trentm/.nvm/versions/node/v18.18.2/bin/node' },
                  AnyValue { stringValue: '-r' },
                  AnyValue { stringValue: '@elastic/opentelemetry-node' },
                  AnyValue { stringValue: '/Users/trentm/el/elastic-otel-node/examples/simple-http-request.js' }
                ]
              }
            }
          },
          KeyValue { key: 'process.runtime.version', value: AnyValue { stringValue: '18.18.2' } },
          KeyValue { key: 'process.runtime.name', value: AnyValue { stringValue: 'nodejs' } },
          KeyValue { key: 'process.runtime.description', value: AnyValue { stringValue: 'Node.js' } },
          KeyValue { key: 'process.command', value: AnyValue { stringValue: '/Users/trentm/el/elastic-otel-node/examples/simple-http-request.js' } },
          KeyValue { key: 'process.owner', value: AnyValue { stringValue: 'trentm' } },
          KeyValue { key: 'host.name', value: AnyValue { stringValue: 'pink.local' } },
          KeyValue { key: 'host.arch', value: AnyValue { stringValue: 'amd64' } },
          KeyValue { key: 'host.id', value: AnyValue { stringValue: 'DF529BD4-274A-53F1-A84E-7F85AFD59258' } }
        ],
        droppedAttributesCount: 0
      }
    }
  ]
}
------ trace 802356 (2 spans) ------
       span f06b1a "GET" (15.5ms, SPAN_KIND_CLIENT, GET http://localhost:3000/ -> 200)
  +9ms `- span 226bf7 "GET" (4.2ms, SPAN_KIND_SERVER, GET http://localhost:3000/ -> 200)

特别是注意“跟踪摘要”输出显示每个跨度的行,显示父母/子女的关系:

------ trace 802356 (2 spans) ------
       span f06b1a "GET" (15.5ms, SPAN_KIND_CLIENT, GET http://localhost:3000/ -> 200)
  +9ms `- span 226bf7 "GET" (4.2ms, SPAN_KIND_SERVER, GET http://localhost:3000/ -> 200)

不同的OTLP协议

默认情况下,OpenTeleometter JS NodeSDK使用 OTLP/proto 协议。 这个 oTLP的其他风味由以下元素支持: mockotlpserver 还有 使用 OTEL_EXPORTER_OTLP_PROTOCOL 告诉节点SDK使用不同的协议. 例如:

cd ../../examples
OTEL_EXPORTER_OTLP_PROTOCOL=http/json node -r @elastic/opentelemetry-node simple-http-request.js
OTEL_EXPORTER_OTLP_PROTOCOL=grpc      node -r @elastic/opentelemetry-node simple-http-request.js

如果你仔细看,你可以看到一些字段在代表上的有些差异 (起动TimeUnixNano,微分仪, salmId等).

警告: 在撰写时仅使用弹性OTel Node.js SDK Distro 支持 OTLP/proto 风味 计量 财务报告和审定财务报表 日志 导出 -- -- 该 OTEL_EXPORTER_OTLP_PROTOCOL 设置将被忽略。 这仅仅是 追踪 出口者,目前遵守这一设定.

不同的模拟服务器打印机

有几组"打印器",用于格式化和写入收到的OTLP数据 转到控制台 :

  • inspect - 使用节点Js的 util.inspect 丢弃完整和有色代表.
  • json, (中文(简体) ), json2 - 显示JSON代表(某种程度的正常化)。 这个 2 表示2个空间缩入.
  • summary - 对数据有意见的简明摘要.

每个打印机都可以通过前缀限定为特定信号 信号 举个例子. node lib/cli.js -o logs-inspect,summary 将显示完整 接收日志 OTLP 请求的“ 检查” 输出, 以及所有请求的汇总输出 信号.

下面是关于某些打印机的注释.

json, json2 (英语)

node lib/cli.js -o json   # 0-space indentation, i.e. compact
node lib/cli.js -o json2  # 2-space indentation

与JSON有关的打印机为了方便,对字段进行了一些正常化.

  • attributes 转换成简洁的映射
  • traceId, (中文(简体) ), spanId, (中文(简体) ), parentSpanId 转换为十六进制值
  • startTimeUnixNano, (中文(简体) ), endTimeUnixNano 转换为64位整数的字符串 (贾瓦斯克丽特的JSON. 字符串不能处理大64位整数, 因此使用 数字可以失去精度. )
  • 注:还有一些没有在这里提及。 详情请参见"lib/正统化.js".

你们可以跑 node lib/cli.js -o inspect,json 比较原始和已规范的 JSON表单.

微量摘要

此打印机将 OTLP 跟踪跨度转换为某种“ 瀑布” 代表 追踪。 显示父母/子女的关系以及一些跨度 时间和其他细节.

# server
node lib/cli.js -o inspect,trace-summary

# example client
(cd ../../examples; node -r @elastic/opentelemetry-node simple-http-request.js)

# waterfall rendering
------ trace 299229 (2 spans) ------
       span 090dfe "GET" (14.5ms, SPAN_KIND_CLIENT, GET http://localhost:3000/ -> 200)
  +9ms `- span 90acc7 "GET" (3.4ms, SPAN_KIND_SERVER, GET http://localhost:3000/ -> 200)
  • 领先的地沟显示起始时间被前一段所抵消.
  • `- 标记显示亲子关系.
  • 平面和痕量标识(例如:. 299229, (中文(简体) ), 090dfe)被修剪为简洁的前缀.

模块使用

模拟OTLP服务器也可以被用在Node.js代码中(如在测试套件中).

const {MockOtlpServer} = require('@elastic/mockotlpserver');
const otlpServer = new MockOtlpServer({
    onTrace: (trace) => { /* ... */ },
    // ... see code comment for other options.
});
otlpServer.start();

// Run code that sends telemetry via OTLP...

otlpServer.close();

见 runTestFixtures() 在“./开远测量-节点/测试/testutils.js”中表示 更完整的例子.

版本与发布记录

@elastic/mockotlpserver 共发布 10 个版本,首次发布于 2024/09/07;过去 12 个月发布了 2 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.12.0latest2026/06/174 个月前
0.11.02026/02/268 个月前
0.10.02025/09/031.2 年前
0.9.02025/08/191.2 年前
0.8.02025/04/011.6 年前
0.7.02025/03/051.7 年前

关于 @elastic/mockotlpserver 的常见问题

@elastic/mockotlpserver 是什么?

模拟 OTLP 服务器, 可用于 dev 和测试

如何安装 @elastic/mockotlpserver?

在项目目录运行 npm install @elastic/mockotlpserver,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 mockotlpserver,可以用 npx mockotlpserver 直接运行。

@elastic/mockotlpserver 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/elastic__mockotlpserver 是否存在。

@elastic/mockotlpserver 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@elastic/mockotlpserver 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js ^18.19.0 || >=20.6.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@elastic/mockotlpserver 可以商用吗?

@elastic/mockotlpserver 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@elastic/mockotlpserver 的下载量有多少?

根据 npm 官方下载统计,@elastic/mockotlpserver 在 2026/10/14 – 2026/11/12 这 30 天内被下载 5,186 次,日均约 173 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@elastic/mockotlpserver 还在维护吗?

最新版本 0.12.0 发布于 2026/06/17(4 个月前);至今共发布 10 个版本,其中过去 12 个月发布了 2 个;首次发布于 2024/09/07。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。