OpenTelemetry Node.js
OTEL を使用して Trace / Metric を DataKit に送信する前に、収集器の設定が完了していることを確認してください。
OpenTelemetry Node.js は、Node.js アプリケーションの Trace と Metric データを収集し、OTLP プロトコルで DataKit に送信してから、Guance で統合表示できます。
標準の OpenTelemetry 機能に加えて、Guance は Node.js 向けに Profile 拡張機能 も提供します。この機能は、Guance が保守・公開している @cloudcare/profiler-nodejs と @datadog/pprof を基盤としており、wall / heap profile を収集して、DataKit の /profiling/v1/input インターフェース経由で Guance に送信できます。
バージョンサポート¶
- Node.js:
^18.19.0または>=20.6.0 - OpenTelemetry:現在の安定版の使用を推奨
- Profile 拡張パッケージ:
@cloudcare/profiler-nodejs - デフォルトの Profiling 送信先:
http://127.0.0.1:9529/profiling/v1/input
自動インストゥルメンテーション方式¶
Node.js では、もっとも一般的なのは自動インストゥルメンテーションで素早く導入する方法です。
1) 依存関係のインストール¶
npm install \
@opentelemetry/api \
@opentelemetry/sdk-node \
@opentelemetry/auto-instrumentations-node \
@opentelemetry/exporter-trace-otlp-proto \
@opentelemetry/exporter-metrics-otlp-proto
2) 環境変数で設定する方法¶
export OTEL_SERVICE_NAME="nodejs-demo"
export OTEL_TRACES_EXPORTER="otlp"
export OTEL_METRICS_EXPORTER="otlp"
export OTEL_LOGS_EXPORTER="none"
export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
export OTEL_EXPORTER_OTLP_ENDPOINT="http://127.0.0.1:9529/otel"
export NODE_OPTIONS="--require @opentelemetry/auto-instrumentations-node/register"
その後、アプリケーションをそのまま起動します。
デフォルトの HTTP パスを使う場合、Trace / Metric の実際の送信先はそれぞれ次のとおりです。
- Trace:
http://127.0.0.1:9529/otel/v1/traces - Metric:
http://127.0.0.1:9529/otel/v1/metrics
3) コマンドライン起動方式¶
環境変数の注入を使いたくない場合は、起動コマンド内で直接設定することもできます。
OTEL_SERVICE_NAME=nodejs-demo \
OTEL_TRACES_EXPORTER=otlp \
OTEL_METRICS_EXPORTER=otlp \
OTEL_LOGS_EXPORTER=none \
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf \
OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:9529/otel \
NODE_OPTIONS="--require @opentelemetry/auto-instrumentations-node/register" \
node app.js
4) PM2 / Systemd の場合¶
アプリケーションを PM2、Systemd、またはその他のプロセスマネージャーで起動している場合は、上記の OTEL_* 環境変数と NODE_OPTIONS を対応する起動設定に書き込むことを推奨します。
基本設定は通常 2 つだけです。
OTEL_SERVICE_NAMENODE_OPTIONS=--require @opentelemetry/auto-instrumentations-node/register
残りの OTLP パラメータは、実際の DataKit のアドレスに合わせて追加してください。
コードで導入する方法¶
自動インストゥルメンテーションが適さない場合は、コードで OpenTelemetry SDK を統合できます。
依存関係のインストール¶
npm install \
@opentelemetry/api \
@opentelemetry/sdk-node \
@opentelemetry/resources \
@opentelemetry/semantic-conventions \
@opentelemetry/exporter-trace-otlp-proto \
@opentelemetry/exporter-metrics-otlp-proto \
@opentelemetry/instrumentation-http
サンプルコード¶
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { resourceFromAttributes } = require('@opentelemetry/resources');
const {
ATTR_SERVICE_NAME,
ATTR_SERVICE_VERSION,
SEMRESATTRS_DEPLOYMENT_ENVIRONMENT,
} = require('@opentelemetry/semantic-conventions');
const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');
const {
OTLPTraceExporter,
} = require('@opentelemetry/exporter-trace-otlp-proto');
const resource = resourceFromAttributes({
[ATTR_SERVICE_NAME]: 'orders-api',
[ATTR_SERVICE_VERSION]: '1.0.0',
[SEMRESATTRS_DEPLOYMENT_ENVIRONMENT]: 'prod',
});
const sdk = new NodeSDK({
resource,
traceExporter: new OTLPTraceExporter({
url: 'http://127.0.0.1:9529/otel/v1/traces',
}),
instrumentations: [new HttpInstrumentation()],
});
async function main() {
await sdk.start();
console.log('OpenTelemetry Node.js started');
}
main().catch(err => {
console.error(err);
process.exit(1);
});
Node.js Profile 拡張¶
Node.js Profile は、Guance が現在 Node.js シナリオ向けに提供している拡張機能であり、標準の OTel Trace / Metric に加えて profile データの収集を補完します。
この機能は OpenTelemetry 公式の npm パッケージの一部ではなく、Guance が OpenTelemetry Node.js を基に拡張して公開しているものです。
現在サポートしている profile の種類は次のとおりです。
wallheap
実際に導入する際は、まず wall を有効にして接続が安定していることを確認し、その後必要に応じて heap を有効にすることを推奨します。
@cloudcare/profiler-nodejs の取得¶
現在の Node.js Profile 拡張パッケージ名は次のとおりです。
npm の公開リポジトリに直接アクセスできる場合は、次を実行できます。
依存関係のインストール¶
npm install \
@cloudcare/profiler-nodejs \
@datadog/pprof \
@opentelemetry/resources \
@opentelemetry/semantic-conventions
最小導入例¶
const { resourceFromAttributes } = require('@opentelemetry/resources');
const {
ATTR_SERVICE_NAME,
ATTR_SERVICE_VERSION,
SEMRESATTRS_DEPLOYMENT_ENVIRONMENT,
} = require('@opentelemetry/semantic-conventions');
const {
DatakitProfilingExporter,
NodeProfiling,
} = require('@cloudcare/profiler-nodejs');
const profiler = new NodeProfiling({
resource: resourceFromAttributes({
[ATTR_SERVICE_NAME]: 'orders-api',
[ATTR_SERVICE_VERSION]: '1.2.3',
[SEMRESATTRS_DEPLOYMENT_ENVIRONMENT]: 'prod',
}),
exporter: new DatakitProfilingExporter({
endpoint: 'http://127.0.0.1:9529/profiling/v1/input',
}),
profileTypes: ['wall'],
cpuProfilingEnabled: true,
});
async function main() {
await profiler.start();
}
main().catch(err => {
console.error(err);
process.exit(1);
});
OpenTelemetry SDK と一緒に使う¶
アプリケーションですでに OpenTelemetry SDK を導入している場合は、profiler を同時に初期化できます。
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { resourceFromAttributes } = require('@opentelemetry/resources');
const {
ATTR_SERVICE_NAME,
ATTR_SERVICE_VERSION,
SEMRESATTRS_DEPLOYMENT_ENVIRONMENT,
} = require('@opentelemetry/semantic-conventions');
const {
DatakitProfilingExporter,
NodeProfiling,
} = require('@cloudcare/profiler-nodejs');
const resource = resourceFromAttributes({
[ATTR_SERVICE_NAME]: 'orders-api',
[ATTR_SERVICE_VERSION]: '1.2.3',
[SEMRESATTRS_DEPLOYMENT_ENVIRONMENT]: 'prod',
});
const sdk = new NodeSDK({
resource,
});
const profiling = new NodeProfiling({
resource,
exporter: new DatakitProfilingExporter({
endpoint: 'http://127.0.0.1:9529/profiling/v1/input',
}),
});
async function main() {
await sdk.start();
await profiling.start();
}
process.on('SIGTERM', async () => {
await profiling.shutdown();
await sdk.shutdown();
process.exit(0);
});
main().catch(err => {
console.error(err);
process.exit(1);
});
手動で 1 回収集する¶
接続確認の際は、直接次を実行できます。
これは通常、次の用途に適しています。
- Profiling インターフェースに初回接続できるかの確認
- profile が正常に生成・送信されるかの確認
- 特定の負荷テスト時間帯に、1 回だけ profile を取得する
推奨 Profile 設定¶
多くのケースでは、次の主要パラメータだけを把握しておけば十分です。
| パラメータ | デフォルト値 | 説明 |
|---|---|---|
endpoint |
http://127.0.0.1:9529/profiling/v1/input |
Profile のアップロード先 |
profileTypes |
['wall', 'heap'] |
収集する profile の種類。まずは ['wall'] の使用を推奨 |
intervalMillis |
60000 |
周期収集の間隔 |
wallDurationMillis |
10000 |
1 回の wall profile の継続時間 |
特別な性能チューニングの必要がなければ、通常はデフォルト値のままで問題ありません。
デフォルト動作¶
デフォルトでは、Node.js Profile 拡張は次のように動作します。
60秒ごとに 1 回収集する- 各ラウンドで
wallとheapの 2 種類の profile を収集する wallprofile はデフォルトで10秒収集するcpuProfilingEnabledをデフォルトで有効にする- profile を
http://127.0.0.1:9529/profiling/v1/inputに送信する
現在の exporter は 2 つの pprof 添付ファイルを送信します。
wall.pprofspace.pprof
それぞれの内容は次のとおりです。
wall.pprof:sample/count、オプションのcpu/nanoseconds、wall/nanosecondsを含むspace.pprof:objects/count、space/bytesを含む
あわせて event.json も付与され、そこでは次の値が設定されます。
profilerは固定でddtracefamilyは固定でnodejsformatは固定でpprof
この構成は、Guance の現在の Node.js Profile 解析チェーンとの互換性のために使われます。
検証¶
Trace / Metric 送信の検証¶
アプリケーションが DataKit の OTLP HTTP エンドポイントにアクセスできることを確認します。
Profile 送信の検証¶
アプリケーションが Profiling インターフェースにアクセスできることを確認します。
ログの検証¶
profile の送信に成功した場合、デバッグログには通常次のような情報が表示されます。
Guance 側データの検証¶
導入後は、Guance で次を確認できます。
- Trace がサービスごとに正常送信されているか
- Metric が対応するメトリクスセットに入っているか
- Node.js Profile がサービス単位で表示されているか
注意事項¶
- Node.js Profile は Guance の拡張機能であり、OpenTelemetry の公式標準機能ではありません。
- 現在サポートしている profile は
wallとheapの 2 種類のみです。 - 実行環境に
globalThis.fetchがない場合は、fetch実装を明示的に渡してください。 - プロセス終了前に profile が失われるのを避けるため、終了時に
shutdown()を呼び出すことを推奨します。 - Trace / Metric のみが必要な場合は、
@cloudcare/profiler-nodejsをインストールする必要はありません。