All Products
Search
Document Center

Application Real-Time Monitoring Service:Use Managed Service for OpenTelemetry to submit the trace data of a Node.js application

Last Updated:Sep 02, 2024

After you use OpenTelemetry to instrument an application and report the trace data to Managed Service for OpenTelemetry, Managed Service for OpenTelemetry starts to monitor the application. You can view the monitoring data of the application, such as application topologies, traces, abnormal transactions, slow transactions, and SQL analysis data. This topic describes how to use OpenTelemetry to automatically or manually instrument an Express-based Node.js application and report data.

Prerequisites

Important

The Node.js version must be 14 or later. Otherwise, we recommend that you use Jaeger to submit the trace data of a Node.js application. For more information, see Report Node.js application data.

To obtain the endpoint of Managed Service for OpenTelemetry, perform the following steps:

  1. Log on to the Managed Service for OpenTelemetry console.

  2. In the left-side navigation pane, click Cluster Configurations. On the page that appears, click the Access point information tab.

  3. In the top navigation bar, select a region. In the Cluster Information section, turn on Show Token.

  4. Set the Client parameter to OpenTelemetry.

    Obtain the endpoint of Managed Service for OpenTelemetry in the Related Information column of the table in the lower part.OT接入点信息

    Note

    If your application is deployed in an Alibaba Cloud production environment, use the Virtual Private Cloud (VPC) endpoint. Otherwise, use the public endpoint.

Background information

OpenTelemetry provides multiple automatic instrumentation plug-ins that can be used to automatically create spans for common frameworks. The following table describes the supported frameworks. For more information, see OpenTelemetry documentation.

View supported Node.js frameworks

Sample code

You can download the sample code from opentelemetry-nodejs-demo.

Method 1: Automatic instrumentation (recommended)

  1. Download the dependencies required to run the project.

    cd auto-instrumentation
    
    npm init -y
    npm install express
    npm install axios
  2. Download the dependencies required for OpenTelemetry automatic instrumentation.

    npm install --save @opentelemetry/api
    npm install --save @opentelemetry/auto-instrumentations-node
  3. Write the application code.

    The following code provides a simple example implemented by using 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. Use environment variables to set OpenTelemetry parameters and run the application.

    Replace ${httpEndpoint} with the HTTP endpoint obtained in Prerequisites. Replace ${serviceName} with the application name.

    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
    Note

    For information about OpenTelemetry environment variables, see Automatic Instrumentation Configuration.

  5. Access the application.

    Access the application by running the following command or using a browser. Then, you can generate traces and report the trace data to Managed Service for OpenTelemetry.

    curl localhost:7001/hello

Method 2: Manual instrumentation

  1. Add the following dependencies on OpenTelemetry to the package.json file.

     "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. Create a provider.

    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",    // You can replace opentelemetry-express with the actual service name. 
      }),
    });
  3. Register the HTTP and Express frameworks by using the provider. Applications in these frameworks are automatically monitored and intercepted.

    Note

    For information about how to monitor Node.js applications in other frameworks, see OpenTelemetry documentation.

    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. Configure an exporter to export data to Managed Service for OpenTelemetry.

    Replace <ENDPOINT> and <AUTHENTICATION> in the following code with the endpoint and token that are obtained in Prerequisites.

    const metadata = new grpc.Metadata();
    metadata.set("Authentication", "<AUTHENTICATION>");
    
    const exporter = new OTLPTraceExporter({ url: "<ENDPOINT>", metadata });
    provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
    provider.register();
  5. Optional. Add a custom event and attributes.

    Note

    For information about how to use the OpenTelemetry API, see OpenTelemetry documentation.

    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");

View trace data in the ARMS console

Log on to the ARMS console. In the left-side navigation pane, choose Application Monitoring > Applications. On the Applications page, click the name of the application. On the page that appears, view the trace data.

Note

If the image icon is displayed in the Language column, the application is connected to Application Monitoring. If a hyphen (-) is displayed, the application is connected to Managed Service for OpenTelemetry.

Complete sample code of an Express-based Node.js application

"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();

// Application code
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");
});