# OpenTelemetry Instrumentation

If your codebase is already instrumented with OpenTelemetry, you can start sending us your tracing data today.

Add the Baselime OTel endpoint to your exporter:

  • endpoint https://otel.baselime.io/v1/
  • header: x-api-key: <YOUR_BASELIME_API_KEY>

You can get your Baselime API key from the Baselime CLI with

baselime iam

If you have not instrumented your codebase with OTel yet, you can use the Baselime Node.js OTel tracer as outlined below. We're currently working on lightweight OTel tracers for other languages.

# 🎸 Lambda Opentelemetry for Node.JS

The @baselime/lambda-node-opentelemetry package instruments your lambda functions and automatically ships OTEL compatible trace data to Baselime. This is the most powerful and flexible way to instrument your node service.

The downside of this node tracer is it adds a small performance hit to each lambda invocation. We are working as hard as possible to minimise this but for now if this matters to you use our x-ray integration instead.

# Manual Installation

Install the @baselime/lambda-node-opentelemetry package

npm install @baselime/lambda-node-opentelemetry

Add the following environment variables to your service

Key Example Description
BASELIME_OTEL_KEY nora-is-the-cutest-baselime-dog Get this key from the cli running baselime iam
BASELIME_NAMESPACE prod-users The name of the service the traces belong to
NODE_OPTIONS --require @baselime/lambda-node-opentelemetry Preloads the tracing sdk at startup

Get the baselime key using our cli

baselime iam

You need to make sure the lambda-wrapper file is included in the .zip file that is used by aws-lambda. The exact steps depend on the packaging step of the framework you are using.

If you use export const export function or export default for your handler you need to rename it to a cjs export like module.exports = or exports.handler =. Even if you use esbuild. We are tracking issues in esbuild and open-telemetry and are looking to see how we can help out.

# Architect

Copy the lambda-wrapper.js file from our node modules to the shared folder of your architect project, this way it is automatically included in all of your lambdas bundles.

cp node_modules/@baselime/lambda-node-opentelemetry/lambda-wrapper.js src/shared/

Add the environment variables to your architect project

arc env -e production --add BASELIME_OTEL_KEY tux-is-the-smartest-baselime-dog
arc env -e production --add BASELIME_NAMESPACE project-1
arc env -e production --add -- NODE_OPTIONS '--require @architect/shared/lambda-wrapper'

Watch out for the '--' in the NODE_OPTIONS command. This is required to escape options parsing. This totally didn't frustrate me for a whole day! :D

# Serverless

By default the serverless framework includes your whole node_module directory in the .zip file. If you are using the serverless-esbuild plugin to avoid this then you need to add the following configuration to your project.


Add the following line to the package.patterns block of your serverless.yml

- 'node_modules/@baselime/lambda-node-opentelemetry/lambda-wrapper.js'


    - 'node_modules/@baselime/lambda-node-opentelemetry'

Add the following environment variables

    BASELIME_NAMESPACE: '${self:provider.stage}-${self:provider.service}'
    NODE_OPTIONS: '--require @baselime/lambda-node-opentelemetry'


Fun fact Baselime is built using SST :)

Copy the lambda-wrapper file to your srcPath directory

cp node_modules/@baselime/lambda-node-opentelemetry/lambda-wrapper.js services

Then add the default props to include the wrapper in your bundle and add your environment variables

  runtime: "nodejs16.x",
  srcPath: "services",
  environment: {
    NODE_OPTIONS: '--require lambda-wrapper.js',
    BASELIME_NAMESPACE: stack.stackName,
  bundle: {
    format: "esm",
    copyFiles: [{ from: "./lambda-wrapper.js", to: "./lambda-wrapper.js" }],

# Automatic Instrumentation [WIP]

Lambda Extension coming soon

# Send data to another OpenTelemetry Backend

Add the environment variable COLLECTOR_URL to send the spans somewhere else.