Documentation
DocumentationDiscussions

Tracing from Node.js

To send traces from Node.js to Seq use the OpenTelemetry JavaScript SDK and its OTLP exporter.

This option has two important limitations:

  1. It does not yet support logs - it can only send spans. However, the spans can include logs.
  2. It only works with the CommonJS style of Node.js module definition.

Installing the OpenTelemetry JavaScript SDK

There are many ways to setup the OpenTelemetry JavaScript SDK. For the full details consult the documentation. The following is an example of one setup that works with Seq. It produces automatic spans for all instrumented libraries and supports the manual creation of spans.

Start by adding the necessary dependencies:

> npm install @opentelemetry/api @opentelemetry/auto-instrumentations-node 
@opentelemetry/exporter-trace-otlp-proto @opentelemetry/instrumentation-http 
@opentelemetry/resources @opentelemetry/sdk-trace-node

Next, define a module telemetry.js to configure OpenTelemetry:

const opentelemetry = require('@opentelemetry/api');
const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
const { ConsoleSpanExporter, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base');
const { registerInstrumentations } = require('@opentelemetry/instrumentation');
const { Resource } = require('@opentelemetry/resources');
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-proto');

module.exports = (serviceName) => {
  const provider = new NodeTracerProvider({
    resource: new Resource({
      [SemanticResourceAttributes.SERVICE_NAME]: serviceName,
    }),
  });

  const otlpExporter = new OTLPTraceExporter({
    url: 'http://localhost:5341/ingest/otlp/v1/traces',
    // headers: {
    //   "X-Seq-ApiKey": "abcde12345"
    // },
  });

  provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
  provider.addSpanProcessor(new SimpleSpanProcessor(otlpExporter));
  provider.register();

  registerInstrumentations({
    instrumentations: [
      new HttpInstrumentation(),
      getNodeAutoInstrumentations(),
    ],
  });

  return opentelemetry.trace.getTracer('example-tracer');
};

Using the OpenTelemetry JavaScript API

From the application code, require telemetry.js before requiring other modules, use it to acquire a tracer, and then write spans with the startActiveSpan method:

const tracer = require('./telemetry')('my-service'); // must be required first!

tracer.startActiveSpan('Request weather forecast for {postcode}', {
  attributes: {
    postcode
  }
}, (span) => {
  // add log event to the span
  span.addEvent("Received data");

  // set additional attributes to the span
  span.setAttribute("another-property", 1234);

  // send the span. Without this the span is not sent.
  span.end();
});

What’s Next