- Install and configure the agent
- Track authenticated users across traces
- Capture exceptions and custom messages
- Use tracing helpers and decorators
- Configure instrumentations (mail, cache, jobs, AI, MCP)
- Fan out telemetry to multiple destinations
Overview
The agent includes Adonis instrumentation and the Node auto-instrumentation bundle. Add Mastra, Vercel AI, BullMQ, Bentocache, and MCP support explicitly so your application only installs the integrations it uses.This guide uses
@monocle.sh/adonisjs-agent 2.x. Upgrading from 1.x? Follow the migration guide.mail, queue, and cli options. Optional mail and queue packages are resolved from your application; the agent does not install them.
Prerequisites
- AdonisJS 6.2.0+ or AdonisJS 7.0.0+
- A Monocle account with an API key
Installation
Install and configure the package using the Ace CLI.See what this command does
See what this command does
- Creates
config/monocle.tsconfiguration file - Creates
otel.tsinitialization file at project root - Adds the
otel.tsimport as the first import inbin/server.tsandbin/console.ts - Registers the Monocle provider in
adonisrc.ts - Registers the Monocle middleware as the first router middleware
- Adds required environment variables to
.envandstart/env.ts
.env:
.env
Environment Variables
The agent requires these environment variables:The
APP_ENV variable determines which environment your telemetry data is
associated with in Monocle. You can filter traces, logs, and metrics by
environment using the environment selector in the dashboard.Configuration
The configuration file is located atconfig/monocle.ts. Here is a minimal setup:
config/monocle.ts
Full configuration reference
All options are optional exceptapiKey, serviceName, serviceVersion, and environment.
config/monocle.ts
Customizing instrumentations
You can configure individual OpenTelemetry instrumentations by passing options keyed by their package name.config/monocle.ts
/health, /healthz, /ready, /readiness, /metrics, /favicon.ico and other common health check paths.
User Context
To associate telemetry data with authenticated users, callMonocle.setUser() in your authentication middleware. This lets you filter traces and exceptions by user in the dashboard.
app/middleware/silent_auth_middleware.ts
name field takes priority in the Monocle UI, falling back to email, then id.
Exception Tracking
Exceptions thrown during a request are automatically captured by the agent. It hooks into AdonisJS’sExceptionHandler.report() method and respects your ignore rules (ignoreExceptions, ignoreStatuses, ignoreCodes).
Manual exception capture
You can manually capture exceptions anywhere in your code.app/services/payment_service.ts
Capture messages
UseMonocle.captureMessage() to capture custom messages when you want to track something that is not an exception. Messages appear in the Exceptions dashboard alongside errors.
app/services/order_service.ts
debug, info, log, warning, error, fatal.
Tracing Helpers
Creating custom spans
Userecord() to wrap a section of code in a span. This is useful when you want to measure the duration of a specific operation that is not automatically instrumented.
app/services/report_service.ts
record() handles both sync and async callbacks, automatically records exceptions, and closes the span when done.
Decorators
The@span() decorator wraps a single method in a span. The @spanAll() decorator wraps every public method in a class.
app/services/order_service.ts
Other helpers
Instrumentations
HTTP
HTTP tracing is configured with the top-levelhttp option.
Alongside the standard HTTP instrumentation options, Monocle adds few specific features:
sanitizeUrlsto redact sensitive query parameters from URL span attributescaptureBodiesto record request and response payloads on spans
sanitizeUrls to enable URL sanitization. For body capture, set captureBodies.enabled: true, or opt in per side with incoming.request.enabled, incoming.response.enabled, and so on.
config/monocle.ts
URL sanitization
sanitizeUrls rewrites URL span attributes such as http.url, url.full, http.target, and url.query.
config/monocle.ts
sanitize function that takes the full URL object and returns a sanitized string.
config/monocle.ts
Body capture scope
incoming captures traffic handled by your Adonis app:
incoming.requestfor the HTTP request body sent to your serverincoming.responsefor the HTTP response body returned by your server
outgoing captures traffic created by Node HTTP clients inside your app:
outgoing.requestfor the request body your app sends to another serviceoutgoing.responsefor the response body returned by that service
captureBodies.outgoing only applies to traffic instrumented by
@opentelemetry/instrumentation-http, which means node:http and
node:https. It does not cover fetch or undici.Body capture defaults
captureBodies is opt-in because payload capture can expose sensitive data.
When enabled, Monocle:
- captures
application/jsonandapplication/x-www-form-urlencodedby default - stores at most
10_000bytes per request or response unless you increasemaxBodySize - shows captured payloads in the HTTP Body tab of the trace details view
Redaction order
captureBodies.redact applies declarative redaction rules first.
captureBodies.transform runs after that and lets you mutate or replace the captured payload programmatically.
The declarative redact rules extend Monocle’s built-in safe defaults. Common secrets such as password, token, code, access_token, refresh_token, authorization, and many others are redacted automatically even if you do not list them yourself.
Advanced overrides
If you need low-level OpenTelemetry overrides, you can still configureinstrumentations["@opentelemetry/instrumentation-http"].
When both are present, the low-level instrumentation config takes priority over the top-level http option.
@adonisjs/mail is installed, the agent automatically instruments all emails sent through the mail service. Every email appears as a span in your traces with subject, recipients, and transport info. You can monitor email activity in the dedicated Emails dashboard.
To disable:
config/monocle.ts
Cache
Install the Bentocache integration explicitly to trace cache operations, including when using@adonisjs/cache. Keep bentocache as a direct application dependency so the integration uses the same instance as your cache service.
Terminal
config/monocle.ts
cache configuration: keys are captured and sanitized, parent spans are not required, and internal Redis/L2 spans are suppressed. UUIDs, numeric IDs, and hex hashes in keys become *.
Pass your previous cache options to bentocache(). Omit the integration or use bentocache({ enabled: false }) to disable it. See the Bentocache guide for customization.
Background Jobs
@adonisjs/queue
If@adonisjs/queue (boringqueue) is installed, the agent instruments job dispatch and execution. Jobs appear in the Jobs dashboard with execution count, error rate, and latency metrics.
config/monocle.ts
BullMQ
Install@monocle.sh/instrumentation-bullmq in your BullMQ application, then register bullmq() to trace job dispatch and processing.
Terminal
config/monocle.ts
useProducerSpanAsConsumerParent: true to keep both in the same trace. See the BullMQ guide for all options.
Omit bullmq() to disable the Monocle BullMQ integration. Use queue: false to disable the separate Adonis queue integration. The Node auto-instrumentation bundle can still trace underlying Redis operations independently.
Sampling noisy jobs
Use thesampling(ctx) hook to reduce trace volume for high-throughput jobs while keeping failed executions.
config/monocle.ts
AI SDK
Install the Vercel AI integration and registervercelAi() to trace AI SDK calls, token usage, and costs.
Terminal
config/monocle.ts
vercelAi() to disable this integration. See the Vercel AI guide for supported operations and recording options.
Conversation tracking
ImportwithConversationId() directly from the integration package to group AI calls in the Conversations tab.
app/services/chat_service.ts
Mastra
Install the Mastra integration and registermastra() to normalize spans from your Mastra OpenTelemetry bridge. Configure the bridge using the Mastra guide.
Terminal
config/monocle.ts
vercelAi() options. Set them on both integrations if you use both. Omit mastra() to disable normalization.
CLI Commands
Ace CLI command execution is traced by default. Scaffolding commands (make:*, generate:*) and long-running queue workers are excluded automatically.
Command arguments and flags are captured as span attributes (cli.args.*, cli.flags.*).
config/monocle.ts
config/monocle.ts
MCP Server
Install the MCP integration explicitly, then attach it to your server instance. MCP does not need anintegrations entry.
Terminal
app/mcp/server.ts
Multi-Destination OTLP
You can send telemetry to additional OTLP backends alongside Monocle. The Monocle destination is always injected automatically.config/monocle.ts
Disabling Telemetry
If no API key is provided, telemetry is automatically disabled. This is useful for local development..env.development
Migrating from @adonisjs/otel
If you are already using@adonisjs/otel, switching to the Monocle agent is straightforward. The agent wraps @adonisjs/otel and provides the same API with additional capabilities.
1. Swap the package
2. Rename config file
Renameconfig/otel.ts to config/monocle.ts and replace defineConfig import:
config/monocle.ts
3. Update all imports
Replace all@adonisjs/otel imports with their Monocle equivalents:
Why use Monocle’s helpers
The Monocle agent re-exports most helpers from@adonisjs/otel unchanged (getCurrentSpan, setAttributes, recordEvent, etc.). However, record, handleError, @span, and @spanAll are enhanced versions that add source code context extraction.
When an exception is caught by these helpers, the agent reads the actual source files from disk and attaches the surrounding lines of code to the span. This is what powers the source code preview in the Monocle exception viewer. You get the exact line that errored with surrounding context, without needing source maps.
The agent also fully serializes the error cause chain (Error.cause), including AggregateError children, so nested errors are never lost.
These enhancements only work when importing from @monocle.sh/adonisjs-agent. If you keep using @adonisjs/otel imports directly, you will get standard OpenTelemetry error recording without the extra context.