- 适用于 JDK 23 的 GraalVM(最新版)
- 适用于 JDK 24 的 GraalVM(早期访问版)
- 适用于 JDK 21 的 GraalVM
- 适用于 JDK 17 的 GraalVM
- 存档
- 开发版本
使用 Insight 进行追踪
可以使用 GraalVM Insight 通过标准的 OpenTracing API
实现流畅、声明式、临时的跟踪。可以将跟踪添加到正在运行的应用程序中,并根据需要进行自定义,以提取调查任何错误行为事件所需的信息。
以下示例将展示 GraalVM Insight 的跟踪功能。首先,安装 Jaeger 的 Node.js 客户端侧仪器库
./bin/npm install jaeger-client@3.17.1
现在可以使用 OpenTracing API(由 jaeger-client
模块提供)在你的仪器 agent.js
中通过 tracer
对象进行操作(在它可用后,将在本指南的后面部分讨论)
let initialize = function(tracer) {
var counter = 0;
insight.on('enter', function(ctx, frame) {
const args = frame.args;
if ('request' !== frame.type || args.length !== 2 || typeof args[0] !== 'object' || typeof args[1] !== 'object') {
return;
}
const req = args[0];
const res = args[1];
const span = tracer.startSpan("request");
span.setTag("span.kind", "server");
span.setTag("http.url", req.url);
span.setTag("http.method", req.method);
res.id = ++counter;
res.span = span;
console.log(`agent: handling #${res.id} request for ${req.url}`);
}, {
roots: true,
rootNameFilter: 'emit',
at: {
sourcePath: '.*events.js'
}
});
insight.on('return', function(ctx, frame) {
var res = frame['this'];
if (res.span) {
res.span.finish();
console.log(`agent: finished #${res.id} request`);
} else {
//Caused, for example, by Tracer itself connecting to the Jaeger server
}
}, {
roots: true,
rootNameFilter: 'end',
at: {
sourcePath: '.*_http_outgoing.js'
}
});
console.log('agent: ready');
};
系统挂钩到 emit('request', ...)
和 res.end()
函数,这些函数用于初始化对 HTTP 请求的响应并完成它。由于 res
对象是一个动态的 JavaScript 对象,因此可以在来自源 events.js
的 emit
函数的 enter
处理程序中向其添加 id
和 span
属性。然后可以在 end
函数的 return
处理程序中使用这些属性。
GraalVM Insight 提供对 frame
变量及其字段的访问。因此,仪器可以读取 req.url
或 req.method
的值,并将它们作为 span.setTag
值提供给 OpenTracing 服务器。
有了这个仪器,只需要能够在适当的时候启用它。查看 将 Insight 嵌入到 Node.js 应用程序 部分,了解如何创建管理员服务器并在需要时动态应用任何跟踪脚本(包括基于 OpenTracing 的脚本)。在本指南中,将使用更简单的方法。
在提供 jaeger
对象时启用该仪器
let initializeJaeger = function (ctx, frame) {
insight.off('enter', initializeJaeger);
let jaeger = frame.jaeger;
var initTracer = jaeger.initTracer;
console.log('agent: Jaeger tracer obtained');
// See schema https://github.com/jaegertracing/jaeger-client-node/blob/master/src/configuration.js#L37
var config = {
serviceName: 'insight-demo',
reporter: {
// Provide the traces endpoint. This forces the client to connect directly to the Collector and send
// spans over HTTP
collectorEndpoint: 'https://#:14268/api/traces',
// Provide username and password if authentication is enabled in the Collector
// username: '',
// password: '',
},
sampler: {
type : 'const',
param : 1
}
};
var options = {
tags: {
'insight-demo.version': '1.1.2',
},
// metrics: metrics,
logger: console,
sampler: {
type : 'const',
param : 1
}
};
var tracer = initTracer(config, options);
initialize(tracer);
};
insight.on('return', initializeJaeger, {
roots: true,
rootNameFilter: 'jaegerAvailable'
});
该仪器需要来自主服务器脚本的帮助。让 server.js
获取 jaeger-client
模块,并通过 jaegerAvailable
函数将其传递给代理。然后它创建一个典型的 HTTP 服务器。server.js
的内容是
function jaegerAvailable(jaeger) {
console.log("Providing Jaeger object to the agent");
}
jaegerAvailable(require("jaeger-client"));
const http = require("http");
const srv = http.createServer((req, res) => {
console.log(`server: obtained request ${res.id}`);
setTimeout(() => {
res.write(`OK# ${res.id}`);
console.log(`server: replied to request ${res.id}`);
res.end();
}, 5);
});
srv.listen(8080);
有了这两个文件,就可以启动 node 应用程序以及代理。但首先,启动 Jaeger 服务器
docker run -d --name jaeger \
-e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \
-p 5775:5775/udp -p 6831:6831/udp -p 6832:6832/udp \
-p 5778:5778 -p 16686:16686 -p 14268:14268 -p 9411:9411 \
jaegertracing/all-in-one:latest
./bin/node --insight=agent.js server.js
Providing Jaeger object to the agent
agent: Jaeger tracer obtained
Initializing Jaeger Tracer with RemoteReporter and ConstSampler(always)
agent: ready
现在可以连接到 Jaeger UI(可通过 https://#:16686/ 访问),并对服务器进行一些负载测试
ab -c 10 -n 10000 https://#:8080/
服务器在处理请求时会在控制台中打印详细信息,而 Jaeger UI 会显示跟踪信息
本指南介绍了如何使用跟踪来增强普通的 Node.js 应用程序。跟踪信息保存在自己的 agent.js
文件中,可以在启动时(此处演示)或在需要时 动态 应用。
下一步阅读内容 #
要了解有关 Insight 的更多信息,并找到一些有挑战性的任务,请访问 Insight 手册。