通過OpenTelemetry為應用埋點並上報鏈路資料至Managed Service for OpenTelemetry後,Managed Service for OpenTelemetry即可開始監控應用,您可以查看應用拓撲、調用鏈路、異常事務、慢事務和SQL分析等一系列監控資料。本文介紹如何使用OpenTelemetry對Node.js Express應用進行自動或手動埋點並上報資料。
前提條件
支援的運行時環境:
OpenTelemetry 目前支援 Node.js v18 及以上版本。
需要注意的是,僅支援 Node.js 的 Active(活躍)或 Maintenance LTS(長期維護)版本。更早的 Node 版本未經過 OpenTelemetry 官方測試,因此不保證能夠正常運行。
更多版本相容性問題,請查看 Supported Runtimes。
支援的庫和架構:
許多流行的 Node.js 庫都支援自動埋點。有關完整列表,請參閱 Supported instrumentations。
方法一:自動埋點(推薦)
通過 OpenTelemetry 自動插樁技術,無需修改應用代碼即可實現 Node.js 應用的可觀測性資料擷取並接入CloudMonitor2.0。
運行以下命令來安裝 OpenTelemetry API、SDK 和插樁工具。
npm install --save @opentelemetry/api npm install --save @opentelemetry/auto-instrumentations-node配置 OpenTelemetry。
請將
${httpEndpoint}替換為HTTP存取點,將${serviceName}替換為您的應用程式名稱。export OTEL_SERVICE_NAME=${serviceName} export OTEL_TRACES_EXPORTER=otlp export OTEL_METRICS_EXPORTER=none export OTEL_LOGS_EXPORTER=none export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=${httpEndpoint} export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf export NODE_OPTIONS="--require @opentelemetry/auto-instrumentations-node/register" node app.js說明如要添加更多 OpenTelemetry 環境變數,請查看OpenTelemetry Node.js自動埋點配置。
方法二:手動埋點
以下內容使用 OpenTelemetry Node.js SDK 構造 Express 架構應用的 Trace 資料並上傳到阿里雲可觀測鏈路 OpenTelemetry 版。
步驟一:建立應用程式範例(可選)
這一步將示範如何構建一個簡單的 Web 應用程式。如果您已經有編寫好的 Node.js 應用程式,請跳過。
建立一個專案目錄,在目錄下執行
npm init -y命令,會建立一個空的 package.json 檔案。執行安裝依賴包命令:
npm install express。編寫應用代碼,建立一個名為 app.js 的檔案,添加如下內容,這段代碼類比扔骰子遊戲,返回1-6之間的一個隨機數。
/*app.js*/ const express = require('express'); const PORT = parseInt(process.env.PORT || '8080'); const app = express(); function getRandomNumber(min, max) { return Math.floor(Math.random() * (max - min + 1) + min); } app.get('/rolldice', (req, res) => { res.send(getRandomNumber(1, 6).toString()); }); app.listen(PORT, () => { console.log(`Listening for requests on http://localhost:${PORT}`); });此時應用已經編寫完成,執行
node app.js命令即可運行應用,訪問地址為http://localhost:8080/rolldice。
步驟二:匯入 OpenTelemetry 相關依賴
安裝 OpenTelemetry Node SDK 和自動插樁包。
auto-instrumentations-node會自動監控代碼中常用的第三方庫(如 Express),當這些庫被調用時自動產生追蹤資料。npm install @opentelemetry/sdk-node \ @opentelemetry/api \ @opentelemetry/auto-instrumentations-node \ @opentelemetry/sdk-trace-node \ @opentelemetry/exporter-trace-otlp-proto配置 OpenTelemetry:為了讓 OpenTelemetry 能夠自動收集應用程式的追蹤資料並上報到阿里雲可觀測鏈路 OpenTelemetry 版,需要建立一個插樁設定檔。該檔案負責初始化 SDK、配置資料匯出器和啟用自動插樁功能。 建立一個名為 instrumentation.js 的檔案。
請將
${httpEndpoint}替換為HTTP存取點,請將${serviceName}替換為您的應用程式名稱。/*instrumentation.js*/ const opentelemetry = require('@opentelemetry/sdk-node'); const { getNodeAutoInstrumentations, } = require('@opentelemetry/auto-instrumentations-node'); const { OTLPTraceExporter, } = require('@opentelemetry/exporter-trace-otlp-proto'); const sdk = new opentelemetry.NodeSDK({ resource: resourceFromAttributes({ [ATTR_SERVICE_NAME]: '${serviceName}' }), traceExporter: new OTLPTraceExporter({ url: "${httpEndpoint}" }), instrumentations: [getNodeAutoInstrumentations()], }); sdk.start();
步驟三:手動建立 Span(可選)
雖然 auto-instrumentations-node 已經能夠捕獲大部分常見架構和庫的調用,但在某些情境下您可能需要手動建立 Span 來獲得更細粒度的追蹤資訊。手動建立 Span 時,需要做以下幾件事情:
擷取 Tracer: 在應用程式中任何需要手動編寫代碼建立 Span 的地方,都應該調用 getTracer 來擷取一個 tracer。
建立和管理 Span: 在需要建立 Span 的代碼中,調用 startActiveSpan 方法來建立一個 span,並使用 end 方法來結束 span。
在原有的app.js上進行修改,支援輸出多次扔骰子的結果。以下代碼展示了如何為每次擲骰子操作建立獨立的 Span,以獲得更細粒度的追蹤資訊。
/*app.js*/
const { trace } = require('@opentelemetry/api');
const express = require('express');
const tracer = trace.getTracer('demo', '0.1.0');
const PORT = parseInt(process.env.PORT || '8080');
const app = express();
function rollOnce(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
function rollTheDice(rolls, min, max) {
// 建立一個 span
return tracer.startActiveSpan('rollTheDice', (span) => {
const result = [];
for (let i = 0; i < rolls; i++) {
result.push(rollOnce(min, max));
}
// 確保結束 span
span.end();
return result;
});
}
app.get('/rolldice', (req, res) => {
const rolls = req.query.rolls ? parseInt(req.query.rolls.toString()) : NaN;
if (isNaN(rolls)) {
res
.status(400)
.send("Request parameter 'rolls' is missing or not a number.");
return;
}
res.send(JSON.stringify(rollTheDice(rolls, 1, 6)));
});
app.listen(PORT, () => {
console.log(`Listening for requests on http://localhost:${PORT}`);
});步驟四:運行應用
執行命令運行應用:node --require ./instrumentation.js app.js。
在控制台查看Trace
在可觀測鏈路 OpenTelemetry 版控制台的應用列表頁面選擇目標應用,查看鏈路資料。