Quickstart
Create a service, install the SDK for your stack, set the DSN and see your first trace in Unhandled.
This page takes an app from no telemetry to its first trace. AdonisJS gets a first-party agent that instruments the whole framework, Node.js frameworks get an Unhandled SDK, and every other language uses its standard OpenTelemetry SDK. Pick your stack in the install step and the rest of the page follows it. The Node.js packages need Node.js 24 or later.
Install
Create a service and copy its DSN
Sign up at
/signup. Unhandled creates an organization with you as its admin, aDefaultproject, aGeneralteam that holds both, and a 14-day trial of the Starter plan.A service is one thing you deploy, such as an API, a worker or a web app. Each service has its own DSN.
- Open Settings at the bottom of the sidebar, then Services under Project.
- Click New service. Only organization admins see this button.
- Enter a Name, such as
Shop API, and a Telemetry name, such asshop-api. The telemetry name becomesservice.nameon everything the service sends and cannot change later. It starts with a letter or digit and may contain letters, digits,.,_and-, up to 120 characters. - Click Create service. The dialog shows the DSN and a stack picker. Pick your stack and copy each step; the snippets already contain the DSN.
A DSN looks like this. Core concepts breaks down each part.
https://[email protected]/0b4f6c2e-8a1d-4c3e-9f7a-1234567890abInstall and configure
The snippets use a sample DSN; paste your own. Install for your stack explains what each family of SDKs records and how the DSN maps to OpenTelemetry settings.
Unhandled SDKs
OpenTelemetry SDKs
Coding agents
Already on Sentry
The full agent: routes, Lucid queries, mail, queue jobs and Ace commands, configured by one installer. Guide
- 1
Install and configure the agent
bashnode ace add @unhandled/agent-adonisjsWrites config/unhandled.ts and otel.ts, and registers the provider and middleware.
- 2
Add the environment variables
.envUNHANDLED_DSN=https://[email protected]/0b6f3c1e-8d2a-4f7b-9c5e-2a1d4e6f8b3c APP_ENV=productionAPP_ENV decides which environment the data lands in: production, staging or development.
- 3
Start the app and send a request
bashnode ace build node build/bin/server.jsThe build does not copy .env, so set the variables where the server runs.
The Unhandled SDKs read the environment from
UNHANDLED_ENV, thenAPP_ENV, thenNODE_ENV. The value must beproduction,stagingordevelopment, and so mustx-unhandled-envon other SDKs. Set it per host, so production sendsproductionand staging sendsstaging.Each Node.js framework has its own page with the full setup: Node.js, Express, Fastify, Hono, NestJS and Next.js. Python, Go, Ruby, Java, .NET and other languages are on Any OpenTelemetry SDK.
The agent needs AdonisJS 6.2 or later, or AdonisJS 7, on Node.js 24 or later.
node ace addinstalls the package and runs its configure hook. AdonisJS 6.2 has noaddcommand (it arrived in 6.3), so run the two steps yourself there:pnpm add @unhandled/agent-adonisjs node ace configure @unhandled/agent-adonisjsThe configure hook changes these files:
- otel.tsstarts the agent before anything else loads
- bin/
- server.tsimport '../otel.js' added as the first import
- console.tssame
- config/
- unhandled.tsdefineConfig with dev, dsn and environment
- start/
- env.tsvalidation for APP_ENV and UNHANDLED_DSN
- kernel.tsUnhandled middleware registered first on the router
- adonisrc.tsUnhandled provider registered
- .envAPP_ENV=development and an empty UNHANDLED_DSN
Keep
import '../otel.js'as the first import ofbin/server.tsandbin/console.ts. Modules loaded before it are not instrumented and produce no spans. The generated config reads both variables:import env from '#start/env' import { defineConfig } from '@unhandled/agent-adonisjs' export default defineConfig({ dev: env.get('NODE_ENV') === 'development', dsn: env.get('UNHANDLED_DSN'), environment: env.get('APP_ENV'), })Every option is in configuration.
The Node.js packages send data as soon as the DSN is set, under the environment you chose. The AdonisJS agent is different. With
devtrue it ignores the DSN and exports nothing unlessendpointpoints at a local collector.node ace serveusually runs withNODE_ENV=development. To send local data from AdonisJS, start the built app withNODE_ENV=production, or setdev: falsewhile you test. Every Unhandled Node.js SDK stays off whenNODE_ENV=test, so your test suite never sends data.- 1
See your data
Send a few requests to the app, then open Unhandled.
- Pick the environment you set with the Env selector in the top bar. Pages open on Production, so data sent as
developmentshows only under DEV. - Open Traces. Each request appears as a trace. Exporters send in batches every few seconds, so allow a moment.
- Open Settings, then Services. Your service now shows events and a Last seen time.
To see an issue, make a route fail. With the AdonisJS agent, throw from a route and request it once:
import router from '@adonisjs/core/services/router' router.get('/orders/:id/refund', async () => { throw new Error('Refund provider is unavailable') })The exception handler reports it, and it appears under Exceptions with its stack trace and the source lines of your own files. Each SDK page has a Verify the setup section with the same check for its framework. With other SDKs, an exception shows up when an instrumentation or your code records it on a span, for example with
span.recordException(error).- Pick the environment you set with the Env selector in the top bar. Pages open on Production, so data sent as
Attach the signed-in user to requests and exceptions with setUser().
Mail, @adonisjs/queue jobs and Ace commands in AdonisJS.
Time your own code with record() or decorators.
Front-end errors, network calls and page views.
Check your URLs and get notified when they fail.
Roles, teams and who sees which project.
On AdonisJS, Users and exceptions and Custom tracing cover the same topics for the agent. BullMQ jobs need their instrumentation.