All Products
Search
Document Center

Simple Log Service:Import trace data from Node.js applications to Simple Log Service by using OpenTelemetry SDK for JavaScript

Last Updated:Sep 02, 2024

This topic describes how to import trace data from Node.js applications to Simple Log Service by using OpenTelemetry SDK for JavaScript.

Prerequisites

  • A trace instance is created. For more information, see Create a trace instance.

  • A Node.js development environment is set up. The Node.js version is 8.5.0 or later.

Method 1: (Recommended) Import data in semi-automatic mode

You can install Node.js dependencies in some frameworks to automatically upload trace data to Simple Log Service. The frameworks include HTTP, HTTPS, gRPC, Express, MySQL, MongoDB, and Redis. For more information about the frameworks, see opentelemetry-node-js-contrib. In this example, Express is used to describe how to import data in semi-automatic mode. For more information, see Examples.

  1. Install dependencies.

    npm install --save @opentelemetry/api
    npm install --save @opentelemetry/node
    npm install --save @opentelemetry/tracing
    npm install --save @opentelemetry/exporter-collector-grpc
    npm install --save @opentelemetry/instrumentation
    npm install --save @opentelemetry/instrumentation-express
    npm install --save @opentelemetry/instrumentation-http
    npm install --save @grpc/grpc-js
    npm install --save @opentelemetry/sdk-trace-node
  2. Initialize a tracer and start Express.

    Replace the variables in the following code with the actual values. For more information about the variables, see Variables.

    const opentelemetry = require("@opentelemetry/api");
    const { registerInstrumentations } = require("@opentelemetry/instrumentation");
    const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node");
    const { Resource } = require("@opentelemetry/resources");
    const {
      SemanticResourceAttributes,
    } = require("@opentelemetry/semantic-conventions");
    const {
      SimpleSpanProcessor,
      ConsoleSpanExporter,
    } = require("@opentelemetry/tracing");
    const grpc = require("@grpc/grpc-js");
    const {
      CollectorTraceExporter,
    } = require("@opentelemetry/exporter-collector-grpc");
    
    const {
      ExpressInstrumentation,
    } = require("@opentelemetry/instrumentation-express");
    const { HttpInstrumentation } = require("@opentelemetry/instrumentation-http");
    
    var os = require("os");
    var hostname = os.hostname();
    
    const provider = new NodeTracerProvider({
      resource: new Resource({
        [SemanticResourceAttributes.SERVICE_NAME]: "${service}",
          [SemanticResourceAttributes.DEPLOYMENT_ENVIRONMENT]: "${environment}",
        [SemanticResourceAttributes.SERVICE_VERSION]: "${version}",
        [SemanticResourceAttributes.SERVICE_NAMESPACE]: "${service.namespace}",
        [SemanticResourceAttributes.HOST_NAME]: hostname,
      }),
    });
    provider.register();
    
    registerInstrumentations({
      instrumentations: [
        new HttpInstrumentation(),
        new ExpressInstrumentation({
          ignoreLayersType: [new RegExp("middleware.*")],
        }),
      ],
      tracerProvider: provider,
    });
    
    var url = "${endpoint}";
    
    var logStdout = false;
    if (url == "stdout") {
      logStdout = true;
    }
    var meta = new grpc.Metadata();
    meta.add("x-sls-otel-project", "${project}");
    meta.add("x-sls-otel-instance-id", "${instance}");
    meta.add("x-sls-otel-ak-id", "${access-key-id}");
    meta.add("x-sls-otel-ak-secret", "${access-key-secret}");
    const collectorOptions = {
      url: url,
      credentials: grpc.credentials.createSsl(),
      metadata: meta,
    };
    const exporter = new CollectorTraceExporter(collectorOptions);
    
    if (!logStdout) {
      provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
    } else {
      var stdexporter = new ConsoleSpanExporter();
      provider.addSpanProcessor(new SimpleSpanProcessor(stdexporter));
    }
    provider.register();
    var tracer = opentelemetry.trace.getTracer("${service}");
    
    var express = require("express");
    var app = express();
    
    app.get("/hello", function (req, res, next) {
      res.send("success");
    });
    
    var server = app.listen(8079, function () {
      var port = server.address().port;
      console.log("App now running in %s mode on port %d", app.get("env"), port);
    });

    Table 1. Variables

    Variable

    Description

    Example

    ${endpoint}

    The endpoint of the Simple Log Service project. Format: ${project}.${region-endpoint}:Port.

    • ${project}: the name of the Simple Log Service project.

    • ${region-endpoint}: the Simple Log Service endpoint for the region where the project resides. You can access Simple Log Service by using an internal or public endpoint. An internal endpoint can be accessed over the classic network or a virtual private cloud (VPC). A public endpoint can be accessed over the Internet. For more information, see Endpoints.

    • Port: the port number. The value is fixed as 10010.

    test-project.cn-hangzhou.log.aliyuncs.com:10010

    ${project}

    The name of the Simple Log Service project.

    test-project

    ${instance}

    The ID of the trace instance. For more information, see Create a trace instance.

    test-traces

    ${access-key-id}

    The AccessKey ID of your Alibaba Cloud account.

    We recommend that you use the AccessKey pair of a RAM user that has only the write permissions on the Simple Log Service project. An AccessKey pair consists of an AccessKey ID and an AccessKey secret. For more information about how to grant the write permissions on a specified project to a RAM user, see Use custom policies to grant permissions to a RAM user. For more information about how to obtain an AccessKey pair, see AccessKey pair.

    None

    ${access-key-secret}

    The AccessKey secret of your Alibaba Cloud account.

    We recommend that you use the AccessKey pair of a RAM user that has only the write permissions on the Simple Log Service project.

    None

    ${service}

    The name of the service. Specify the value based on your business requirements.

    payment

    ${version}

    The version of the service. We recommend that you specify the version in the va.b.c format.

    v0.1.2

    ${service.namespace}

    The namespace to which the service belongs.

    order

    ${environment}

    The deployment environment of the service. Examples: test environment, staging environment, or production environment.

    pre

  3. Access the service to trigger trace data generation and send the trace data to Simple Log Service.

    127.0.0.1:8079/hello

Method 2: Manually generate and send trace data

If you use a self-managed framework or have special requirements, you can manually construct trace data and send the data to Simple Log Service. For more information, see opentelemetry-js.

  1. Install dependencies.

    npm install --save @opentelemetry/api
    npm install --save @opentelemetry/node
    npm install --save @opentelemetry/tracing
    npm install --save @opentelemetry/exporter-collector-grpc
  2. Initialize a tracer and start Express.

    Replace the variables in the following code with the actual values. For more information, see Variables.

    const opentelemetry = require("@opentelemetry/api");
    const { registerInstrumentations } = require("@opentelemetry/instrumentation");
    const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node");
    const { Resource } = require("@opentelemetry/resources");
    const {
      SemanticResourceAttributes,
    } = require("@opentelemetry/semantic-conventions");
    const {
      SimpleSpanProcessor,
      ConsoleSpanExporter,
    } = require("@opentelemetry/tracing");
    const grpc = require("@grpc/grpc-js");
    const {
      CollectorTraceExporter,
    } = require("@opentelemetry/exporter-collector-grpc");
    
    const {
      ExpressInstrumentation,
    } = require("@opentelemetry/instrumentation-express");
    const { HttpInstrumentation } = require("@opentelemetry/instrumentation-http");
    
    var os = require("os");
    var hostname = os.hostname();
    
    const provider = new NodeTracerProvider({
      resource: new Resource({
        [SemanticResourceAttributes.SERVICE_NAME]: "${service}",
          [SemanticResourceAttributes.DEPLOYMENT_ENVIRONMENT]: "${environment}",
        [SemanticResourceAttributes.SERVICE_VERSION]: "${version}",
        [SemanticResourceAttributes.SERVICE_NAMESPACE]: "${service.namespace}",
        [SemanticResourceAttributes.HOST_NAME]: hostname,
      }),
    });
    provider.register();
    
    registerInstrumentations({
      instrumentations: [
        new HttpInstrumentation(),
        new ExpressInstrumentation({
          ignoreLayersType: [new RegExp("middleware.*")],
        }),
      ],
      tracerProvider: provider,
    });
    
    var url = "${endpoint}";
    
    var logStdout = false;
    if (url == "stdout") {
      logStdout = true;
    }
    var meta = new grpc.Metadata();
    meta.add("x-sls-otel-project", "${project}");
    meta.add("x-sls-otel-instance-id", "${instance}");
    meta.add("x-sls-otel-ak-id", "${access-key-id}");
    meta.add("x-sls-otel-ak-secret", "${access-key-secret}");
    const collectorOptions = {
      url: url,
      credentials: grpc.credentials.createSsl(),
      metadata: meta,
    };
    const exporter = new CollectorTraceExporter(collectorOptions);
    
    if (!logStdout) {
      provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
    } else {
      var stdexporter = new ConsoleSpanExporter();
      provider.addSpanProcessor(new SimpleSpanProcessor(stdexporter));
    }
    provider.register();
    var tracer = opentelemetry.trace.getTracer("${service}");
    
    var express = require('express');
    
    var app = express()
    
    app.get('/hello', function (req, res, next) {
        const span = tracer.startSpan('hello');
        span.setAttribute('name', 'toma');
        span.setAttribute('age', '26');
        span.addEvent('invoking doWork');
    
        res.send("success");
    
        span.end();
    });
    
    var server = app.listen(8079, function () {
      var port = server.address().port;
      console.log("App now running in %s mode on port %d", app.get("env"), port);
    });
  3. Access the service to trigger trace data generation and send the trace data to Simple Log Service.

    127.0.0.1:8079/hello

What to do next