This Quick Start guide shows you how to configure your Nodejs applications to send OpenTelemetry traces to Cloud Observability.
This guide does not provide documentation on application instrumentation. For Nodejs-specific information on instrumentation, please see the Nodejs OpenTelemetry getting started guide.
The sections below contain code snippets only. For full code listings, please see nodejs/otel-vanilla
and nodejs/launcher
in the Cloud Observability OpenTelemetry examples repository.
Sending OpenTelemetry data directly to Cloud Observability without a Collector for most developer setups will suffice. For non-development setups, however, it is highly recommended that you send OpenTelemetry data to Cloud Observability by way of the OpenTelemetry Collector. This can be done with or without a Launcher, as we’ll see below.
Before you get started with sending OpenTelemetry data to Cloud Observability, you will need the following:
In your application code, you will need to install dependencies and import OpenTelemetry packages before you can send data to Cloud Observability.
Start by installing the Node.JS OpenTelemetry packages. Do this by opening up a terminal window and pasting the following snippet in your project directory:
1
2
3
4
5
6
7
npm install --save \
@opentelemetry/api \
@opentelemetry/resources \
@opentelemetry/semantic-conventions \
@opentelemetry/sdk-node \
@opentelemetry/auto-instrumentations-node \
@opentelemetry/exporter-trace-otlp-proto
gRPC or Protobuf over HTTP export may also be used. Please refer to the appropriate README for more information.
The packages installed include the core OpenTelemetry components, as well as automatic instrumentation for popular Node.JS packages.
Although auto-instrumentation is a great way to get started quickly with instrumenting your Node application, it is often not sufficient. In order to gain greater insights into your application code, you should also add manual instrumentation to your business logic. More on auto-instrumentation vs manual instrumentation here.
In order to manually instrument your Node code, you need to acquire a Tracer. The Tracer is responsible for creating Spans and interacting with the Context.
Before you can acquire a Tracer, you must first import the appropriate package. Open up your application code, and add the following import to your .js
file:
In Node.JS, it is conventional to create a tracing.js
file that performs
bootstrapping and initialization of OpenTelemetry.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// tracing.js
'use strict'
const process = require('process');
const opentelemetry = require('@opentelemetry/sdk-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { Resource } = require('@opentelemetry/resources');
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-proto');
const traceExporter = new OTLPTraceExporter({
url: "https://ingest.lightstep.com/traces/otlp/v0.9",
headers: {
"lightstep-access-token": process.env.LIGHTSTEP_ACCESS_TOKEN,
}
});
const sdk = new opentelemetry.NodeSDK({
resource: new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: 'my-service',
}),
traceExporter,
instrumentations: [getNodeAutoInstrumentations()]
});
// initialize the SDK and register with the OpenTelemetry API
// this enables the API to record telemetry
sdk.start()
.then(() => console.log('Tracing initialized'))
.catch((error) => console.log('Error initializing tracing', error));
// gracefully shut down the SDK on process exit
process.on('SIGTERM', () => {
sdk.shutdown()
.then(() => console.log('Tracing terminated'))
.catch((error) => console.log('Error terminating tracing', error))
.finally(() => process.exit(0));
});
Save this file.
Once you have your tracing.js
file, you should run your application as
follows: node -r ./tracing.js app.js
. The -r
flag will require the tracing
module that was created and ensure it runs before your application code. You
will also need to configure environment variables as follows, depending on your
OpenTelemetry Collector configuration:
Start tabs
Direct (OTLP/HTTP)
1
export LIGHTSTEP_ACCESS_TOKEN=<your_access_token>
Collector (OTLP/HTTP)
1
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317" #or whatever your collector URL is
End tabs
To view traces in your Cloud Observability project, click explorer in the left navigation bar, and then click on any span in the Trace Analysis table.
By default, the OpenTelemetry exporters will not print errors. You can add the
following code to your tracing.js
file, before configuration, to enable
verbose logging.
1
2
const opentelemetryAPI = require("@opentelemetry/api");
opentelemetryAPI.diag.setLogger(new opentelemetryAPI.DiagConsoleLogger(), opentelemetryAPI.DiagLogLevel.WARN);
You can increase the verbosity of the logs with DiagLogLevel.DEBUG
.
http/json
instead of gRPC or Protobuf!As of this writing, Cloud Observability does not support http/json
for current versions
of the OpenTelemetry protocol via direct ingest. Please use gRPC or Protobuf
over HTTP.
We suggest using an OpenTelemetry collector to proxy your telemetry before sending it to Cloud Observability, which has no such limitation.
If multiple versions of OpenTelemetry are installed, traces are not created or propagated correctly. Check your dependencies to ensure that only a single version of OpenTelemetry is installed.
Cloud Observability’s public Microsatellites only accept spans via a secure endpoint. If you see security related errors (e.g., Netty TLS errors with Java), you may not have the necessary root certificate installed on the machine where the tracer is running. To add a root certificate, see the documentation about encrypted connections.
Not seeing metrics come through the OpenTelemetry Collector? Make sure that you have defined a Metrics pipeline in your Collector’s YAML config file.
Updated Sep 21, 2022