OpenTelemetry using Nuxt.js
This page explains how to configure OpenTelemetry in a Nuxt.js app to send telemetry data to Axiom.
OpenTelemetry provides a unified approach to collecting telemetry data from your Nuxt.js and TypeScript apps. This page demonstrates how to configure OpenTelemetry in a Nuxt.js app to send telemetry data to Axiom using OpenTelemetry SDK.
Prerequisites
- Create an Axiom account.
- Create a dataset in Axiom where you send your data.
- Create an API token in Axiom with permissions to ingest data to the dataset you have created.
- Install Node.js version 18 or newer.
- Use your own app written in Nuxt.js, or follow this guide to create a new one.
Create new Nuxt.js app
Run the following command to create a new Nuxt.js app. Accept the default options during the initialization.
Install dependencies
Install the required OpenTelemetry packages:
Configure environment variables
Create a .env file in the root of your project to store your Axiom credentials:
Configure Nuxt.js app
Configure your Nuxt app in nuxt.config.ts to expose the environment variables to the runtime:
Server setup
Create server directories
Create the necessary directories for your server-side code:
Instrumentation plugin
Create the OpenTelemetry instrumentation plugin in server/plugins/instrumentation.ts. This file sets up the OpenTelemetry SDK and configures it to send traces to Axiom.
Example API endpoint
Create an example API endpoint in server/api/hello.ts to test your OpenTelemetry setup.
The example endpoint below demonstrates manual span creation. Each request to /api/hello creates a trace span and sends it to Axiom.
Run instrumented app
In development mode
To run your Nuxt app with OpenTelemetry instrumentation in development mode:
You see the following output in the console:
Test setup
Test your API endpoint to generate traces:
You get the following response from the API endpoint:
After making 5-10 requests, you see the following output in the console:
In production mode
To build and run in production:
After generating some traces by visiting your API endpoints, go to the Stream tab in Axiom, and then click your dataset. You see the traces appearing in the stream.
Project directory structure
Your Nuxt.js project has the following structure:
Root-level files
.env: Stores environment variables (API token, dataset name)nuxt.config.ts: Nuxt configuration file that exposes environment variables to the runtimepackage.json: Lists dependencies and npm scriptstsconfig.json: TypeScript configuration (auto-generated by Nuxt)
Server directory
The server/ directory contains all server-side code that runs in Nitro, Nuxt's server engine.
-
server/api/directory contains API route handlers. Each file becomes an API endpoint:server/api/hello.ts→/api/helloserver/api/users.ts→/api/usersserver/api/posts/[id].ts→/api/posts/:id
-
server/plugins/directory contains Nitro plugins that run when the server starts:server/plugins/instrumentation.ts: Initializes OpenTelemetry SDK
Manual instrumentation
Manual instrumentation in Nuxt.js allows you to create custom spans for specific operations.
Initialize tracer
Import the OpenTelemetry API in any server file, such as server/api/hello.ts:
Create spans
Wrap operations you want to trace:
Annotate spans
Add metadata to your spans, such as order.id, user.id, and order.amount:
Create nested spans
Create parent-child relationships between spans:
Automatic instrumentation
Automatic instrumentation is already set up in the server/plugins/instrumentation.ts file:
This automatically traces:
- HTTP requests and responses
- Database queries (MySQL, PostgreSQL, MongoDB, etc.)
- Redis operations
- File system operations
- DNS lookups
- And many more Node.js operations
Reference
List of OpenTelemetry Trace Fields
| Field Category | Field Name | Description |
|---|---|---|
| Unique Identifiers | ||
| _rowid | Unique identifier for each row in the trace data. | |
| span_id | Unique identifier for the span within the trace. | |
| trace_id | Unique identifier for the entire trace. | |
| Timestamps | ||
| _systime | System timestamp when the trace data was recorded. | |
| _time | Timestamp when the actual event being traced occurred. | |
| HTTP Attributes | ||
| attributes.http.method | HTTP method used for the request. | |
| attributes.http.path | The API path accessed during the request. | |
| attributes.http.status_code | HTTP response status code. | |
| attributes.http.route | Route pattern (for example, /api/:id). | |
| attributes.http.scheme | Protocol scheme (HTTP/HTTPS). | |
| attributes.http.user_agent | User agent string of the client. | |
| Network Attributes | ||
| attributes.net.host.port | Port number on the host receiving the request. | |
| attributes.net.peer.ip | IP address of the peer in the network interaction. | |
| Operational Details | ||
| duration | Time taken for the operation in nanoseconds. | |
| kind | Type of span (server, client, internal, producer, consumer). | |
| name | Name of the span (for example, 'api.hello'). | |
| scope | Instrumentation scope. | |
| service.name | Name of the service generating the trace. | |
| Resource Attributes | ||
| resource.process.pid | Process ID of the Nitro server. | |
| resource.process.runtime.name | Runtime name (for example, 'nodejs'). | |
| resource.process.runtime.version | Node.js version. | |
| Telemetry SDK Attributes | ||
| telemetry.sdk.language | Language of the telemetry SDK (javascript). | |
| telemetry.sdk.name | Name of the telemetry SDK (opentelemetry). | |
| telemetry.sdk.version | Version of the telemetry SDK. |
List of Imported Libraries
@opentelemetry/sdk-node
The core SDK for OpenTelemetry in Node.js. Provides the primary interface for configuring and initializing OpenTelemetry in a Node.js/Nuxt app. It includes functionalities for managing traces, metrics, and context propagation.
@opentelemetry/auto-instrumentations-node
Offers automatic instrumentation for Node.js apps. Automatically collects telemetry data from common Node.js libraries and frameworks without manual instrumentation. Essential for Nuxt/Nitro server operations.
@opentelemetry/exporter-trace-otlp-proto
Provides an exporter that sends trace data using the OpenTelemetry Protocol (OTLP). Allows Nuxt apps to send collected traces to Axiom or any OTLP-compatible backend.
@opentelemetry/sdk-trace-base
Contains the BatchSpanProcessor and other foundational elements for tracing. The BatchSpanProcessor batches spans before sending them to the exporter, improving performance and reducing network overhead.
@opentelemetry/resources
Provides the resourceFromAttributes() function to create resource objects that identify your service in traces. Resources contain service metadata like service name, version, and environment.
@opentelemetry/semantic-conventions
Provides standard attribute names like ATTR_SERVICE_NAME for consistent telemetry data. Ensures your traces follow OpenTelemetry semantic conventions for better interoperability.
@opentelemetry/api
The OpenTelemetry API package that provides the trace and context APIs for manual instrumentation. This is a peer dependency that other OpenTelemetry packages rely on.
Advanced configurations
Custom span processor
For more control over span processing, use the SimpleSpanProcessor instead of the BatchSpanProcessor:
Sampling
To reduce the volume of traces, use the TraceIdRatioBasedSampler to sample a percentage of traces:
Custom resource attributes
Add custom attributes to all traces, such as service.version and deployment.environment: