@ 弹性/ mockotlpserver
用于开发和测试的模拟OTLP(开放遥测协议)服务器/接收器.
mockotlpserver 启动 HTTP 和 gRPC 服务器( 在默认的 OTLP 端口上)
收到OTLP请求。 请求中的数据将打印到
操纵台 支持各种输出格式.
它还支持从Node.js代码运行. 此用于 "./开远测量-节点"包件协助测试. 测试的形式是:
- 启动模拟服务器
- 运行有乐器的脚本
- 从模拟服务器获取收到的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数据,其形式有两种:
inspect格式: 使用节点.jsutil.inspect()(盖下用于:console.log) (中文(简体) ). 显示接收对象的完整结构 数据.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”中表示
更完整的例子.