すべてのプロダクト
Search
ドキュメントセンター

Managed Service for OpenTelemetry:Managed Service for OpenTelemetry を使用して Node.js アプリケーションのトレースデータを送信する

最終更新日:Dec 30, 2024

OpenTelemetry を使用してアプリケーションをインストルメントし、トレースデータを Managed Service for OpenTelemetry に送信すると、Managed Service for OpenTelemetry はアプリケーションの監視を開始します。アプリケーショントポロジー、トレース、異常トランザクション、低速トランザクション、SQL分析データなど、アプリケーションの監視データを表示できます。このトピックでは、OpenTelemetry を使用して Express ベースの Node.js アプリケーションを自動または手動でインストルメントし、データを送信する方法について説明します。

前提条件

重要

Node.js のバージョンは 14 以降である必要があります。それ以外の場合は、Jaeger を使用して Node.js アプリケーションのトレースデータを送信することをお勧めします。詳細については、Node.js アプリケーションデータの送信 を参照してください。

Managed Service for OpenTelemetry のエンドポイントを取得するには、次の手順を実行します。

  1. Managed Service for OpenTelemetry コンソール にログインします。

  2. 左側のナビゲーションペインで、Cluster Configurations をクリックします。表示されるページで、Access point information タブをクリックします。

  3. 上部のナビゲーションバーで、リージョンを選択します。Cluster Information セクションで、Show Token をオンにします。

  4. Client パラメーターを OpenTelemetry に設定します。

    下部の表の Related Information 列に Managed Service for OpenTelemetry のエンドポイントが表示されます。OT接入点信息

    説明

    アプリケーションが Alibaba Cloud の本番環境にデプロイされている場合は、Virtual Private Cloud (VPC) エンドポイントを使用します。それ以外の場合は、パブリックエンドポイントを使用します。

背景情報

OpenTelemetry は、一般的なフレームワークのスパンを自動的に作成するために使用できる複数の自動インストルメンテーションプラグインを提供しています。次の表に、サポートされているフレームワークを示します。詳細については、OpenTelemetry のドキュメントを参照してください。

サポートされている Node.js フレームワークを表示する

フレームワーク

参照

amqplib

@opentelemetry/instrumentation-amqplib

aws-lambda

@opentelemetry/instrumentation-aws-lambda

aws-sdk

@opentelemetry/instrumentation-aws-sdk

bunyan

@opentelemetry/instrumentation-bunyan

cassandra-driver

@opentelemetry/instrumentation-cassandra-driver

connect

@opentelemetry/instrumentation-connect

cucumber

@opentelemetry/instrumentation-cucumber

dataloader

@opentelemetry/instrumentation-dataloader

dns

@opentelemetry/instrumentation-dns

express

@opentelemetry/instrumentation-express

fastify

@opentelemetry/instrumentation-fastify

generic-pool

@opentelemetry/instrumentation-generic-pool

graphql

@opentelemetry/instrumentation-graphql

grpc

@opentelemetry/instrumentation-grpc

hapi

@opentelemetry/instrumentation-hapi

http

@opentelemetry/instrumentation-http

ioredis

@opentelemetry/instrumentation-ioredis

knex

@opentelemetry/instrumentation-knex

koa

@opentelemetry/instrumentation-koa

lru-memoizer

@opentelemetry/instrumentation-lru-memoizer

memcached

@opentelemetry/instrumentation-memcached

mongodb

@opentelemetry/instrumentation-mongodb

mongoose

@opentelemetry/instrumentation-mongoose

mysql

@opentelemetry/instrumentation-mysql

mysql2

@opentelemetry/instrumentation-mysql2

nestjs-core

@opentelemetry/instrumentation-nestjs-core

net

@opentelemetry/instrumentation-net

pg

@opentelemetry/instrumentation-pg

pino

@opentelemetry/instrumentation-pino

redis

@opentelemetry/instrumentation-redis

restify

@opentelemetry/instrumentation-restify

socket.io

@opentelemetry/instrumentation-socket.io

winston

@opentelemetry/instrumentation-winston

サンプルコード

opentelemetry-nodejs-demo からサンプルコードをダウンロードできます。

方法 1: 自動インストルメンテーション (推奨)

  1. プロジェクトの実行に必要な依存関係をダウンロードします。

    cd auto-instrumentation
    
    npm init -y
    npm install express
    npm install axios
  2. OpenTelemetry 自動インストルメンテーションに必要な依存関係をダウンロードします。

    npm install --save @opentelemetry/api
    npm install --save @opentelemetry/auto-instrumentations-node
  3. アプリケーションコードを作成します。

    次のコードは、Express を使用して実装された簡単な例です。

    "use strict";
    
    const axios = require("axios").default;
    const express = require("express");
    const app = express();
    
    app.get("/", async (req, res) => {
      const result = await axios.get("http://localhost:7001/hello");
      return res.status(201).send(result.data);
    });
    
    app.get("/hello", async (req, res) => {
      console.log("hello world!")
      res.json({ code: 200, msg: "success" });
    });
    
    app.use(express.json());
    
    app.listen(7001, () => {
      console.log("Listening on http://localhost:7001");
    });
  4. 環境変数を使用して OpenTelemetry パラメーターを設定し、アプリケーションを実行します。

    ${httpEndpoint} を、前提条件 で取得した HTTP エンドポイントに置き換えます。${serviceName} をアプリケーション名に置き換えます。

    export OTEL_TRACES_EXPORTER="otlp"
    export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="${httpEndpoint}"
    export OTEL_NODE_RESOURCE_DETECTORS="env,host,os"
    export OTEL_SERVICE_NAME="${serviceName}"
    export NODE_OPTIONS="--require @opentelemetry/auto-instrumentations-node/register"
    node main.js
    説明

    OpenTelemetry 環境変数の詳細については、Automatic Instrumentation Configuration を参照してください。

  5. アプリケーションにアクセスします。

    次のコマンドを実行するか、ブラウザを使用してアプリケーションにアクセスします。その後、トレースを生成し、トレースデータを Managed Service for OpenTelemetry に送信できます。

    curl localhost:7001/hello

方法 2: 手動インストルメンテーション

  1. OpenTelemetry の次の依存関係を package.json ファイルに追加します。

     "dependencies": {
        "@opentelemetry/api": "^1.0.4",
        "@opentelemetry/exporter-trace-otlp-grpc": "^0.27.0",
        "@opentelemetry/instrumentation": "^0.27.0",
        "@opentelemetry/instrumentation-express": "^0.27.0",
        "@opentelemetry/instrumentation-http": "^0.27.0",
        "@opentelemetry/resources": "^1.0.1",
        "@opentelemetry/sdk-trace-base": "^1.0.1",
        "@opentelemetry/sdk-trace-node": "^1.0.1"
      }
  2. プロバイダーを作成します。

    const { Resource } = require("@opentelemetry/resources");
    const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node");
    const {
      SemanticResourceAttributes,
    } = require("@opentelemetry/semantic-conventions");
    
    const provider = new NodeTracerProvider({
      resource: new Resource({
        [SemanticResourceAttributes.HOST_NAME]: require("os").hostname(),
        [SemanticResourceAttributes.SERVICE_NAME]: "opentelemetry-express",    // opentelemetry-express を実際のサービス名に置き換えることができます。
      }),
    });
  3. プロバイダーを使用して HTTP および Express フレームワークを登録します。これらのフレームワークのアプリケーションは自動的に監視およびインターセプトされます。

    説明

    他のフレームワークの Node.js アプリケーションを監視する方法については、OpenTelemetry のドキュメントを参照してください。

    const { registerInstrumentations } = require("@opentelemetry/instrumentation");
    const { HttpInstrumentation } = require("@opentelemetry/instrumentation-http");
    const {
      ExpressInstrumentation,
    } = require("@opentelemetry/instrumentation-express");
    
    registerInstrumentations({
      tracerProvider: provider,
      instrumentations: [new HttpInstrumentation(), ExpressInstrumentation],
    });
  4. Managed Service for OpenTelemetry にデータをエクスポートするエクスポーターを構成します。

    次のコードの <ENDPOINT> および <AUTHENTICATION> を、前提条件で取得したエンドポイントとトークンに置き換えます。

    const metadata = new grpc.Metadata();
    metadata.set("Authentication", "<AUTHENTICATION>");
    
    const exporter = new OTLPTraceExporter({ url: "<ENDPOINT>", metadata });
    provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
    provider.register();
  5. オプション。 カスタムイベントと属性を追加します。

    説明

    OpenTelemetry API の使用方法については、OpenTelemetry のドキュメントを参照してください。

    const api = require("@opentelemetry/api");
    const currentSpan = api.trace.getSpan(api.context.active());
    currentSpan.addEvent("timestamp", { value: Date.now() });
    currentSpan.setAttribute("tagKey-01", "tagValue-01");

ARMS コンソールでトレースデータを表示する

Managed Service for OpenTelemetry コンソールApplications ページで、アプリケーションの名前をクリックします。表示されるページで、トレースデータを表示します。

Express ベースの Node.js アプリケーションの完全なサンプルコード

"use strict";

const { Resource } = require("@opentelemetry/resources");
const {
  OTLPTraceExporter,
} = require("@opentelemetry/exporter-trace-otlp-grpc");
const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node");
const { SimpleSpanProcessor } = require("@opentelemetry/sdk-trace-base");
const {
  ExpressInstrumentation,
} = require("@opentelemetry/instrumentation-express");
const { registerInstrumentations } = require("@opentelemetry/instrumentation");
const { HttpInstrumentation } = require("@opentelemetry/instrumentation-http");
const {
  SemanticResourceAttributes,
} = require("@opentelemetry/semantic-conventions");
const grpc = require("@grpc/grpc-js");

const provider = new NodeTracerProvider({
  resource: new Resource({
    [SemanticResourceAttributes.HOST_NAME]: require("os").hostname(),
    [SemanticResourceAttributes.SERVICE_NAME]: "opentelemetry-express",
  }),
});

registerInstrumentations({
  tracerProvider: provider,
  instrumentations: [new HttpInstrumentation(), ExpressInstrumentation],
});

const metadata = new grpc.Metadata();
metadata.set("Authentication", "<AUTHENTICATION>");

const exporter = new OTLPTraceExporter({ url: "<ENDPOINT>", metadata });
provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
provider.register();

// アプリケーションコード
const api = require("@opentelemetry/api");
const axios = require("axios").default;
const express = require("express");
const app = express();

app.get("/", async (req, res) => {
  const result = await axios.get("http://localhost:7001/api");
  return res.status(201).send(result.data);
});

app.get("/api", async (req, res) => {
  const currentSpan = api.trace.getSpan(api.context.active());
  currentSpan.addEvent("timestamp", { value: Date.now() });
  currentSpan.setAttribute("tagKey-01", "tagValue-01");
  res.json({ code: 200, msg: "success" });
});

app.use(express.json());

app.listen(7001, () => {
  console.log("Listening on http://localhost:7001");
});