Sentry for Flue
Learn how to send Flue agent traces, model calls, tool executions, and errors to Sentry with the Sentry SDK.
Flue is an open TypeScript framework for building AI agents, made by the Astro team. This guide sets up the Sentry SDK in a Flue app so agent turns, model calls, tool executions, and errors flow into Sentry Agent Tracing.
This guide covers the Sentry SDK-based setup, which replaces the flue add tooling sentry blueprint. If you previously ran the blueprint, remove its createOpenTelemetryInstrumentation call — otherwise, you will get duplicate spans.
Deploying Flue agents to Cloudflare Workers? Follow the Cloudflare Quick Start instead.
Before you begin, you need:
- A Sentry account and project. The project's DSN tells the SDK where to send data.
- A Flue application using
@flue/runtimeversion2.0.0or later. Flue requires Node.js22.19or later. @sentry/nodeor@sentry/cloudflareversion11.0.0or later. Browser runtimes are not supported.
Choose the features you want to configure, and this guide will show you how:
Install the Sentry Node SDK:
npm install @sentry/node@^11.0.0
npm install @sentry/node@^11.0.0
yarn add @sentry/node@^11.0.0
pnpm add @sentry/node@^11.0.0
npm install @sentry/node@^11.0.0 @sentry/profiling-node@^11.0.0
npm install @sentry/node@^11.0.0 @sentry/profiling-node@^11.0.0
yarn add @sentry/node@^11.0.0 @sentry/profiling-node@^11.0.0
pnpm add @sentry/node@^11.0.0 @sentry/profiling-node@^11.0.0
Create a file that calls Sentry.init() and registers the Flue instrumentation. Flue is instrumented by registering with it rather than by patching, so this instrument() call is what connects the two:
src/instrument.tsimport { instrument } from "@flue/runtime";
import * as Sentry from "@sentry/node";
// ___PRODUCT_OPTION_START___ profiling
import { nodeProfilingIntegration } from "@sentry/profiling-node";
// ___PRODUCT_OPTION_END___ profiling
Sentry.init({
dsn: "___PUBLIC_DSN___",
// ___PRODUCT_OPTION_START___ profiling
// Add our Profiling integration
nodeProfilingIntegration(),
// ___PRODUCT_OPTION_END___ profiling
// ___PRODUCT_OPTION_START___ performance
// Set tracesSampleRate to 1.0 to capture 100%
// of spans for tracing.
// We recommend adjusting this value in production.
tracesSampleRate: 1.0,
// ___PRODUCT_OPTION_END___ performance
// ___PRODUCT_OPTION_START___ profiling
// Set profileSessionSampleRate to 1.0 to profile every session.
// Learn more at
// https://docs.sentry.io/platforms/javascript/configuration/options/#profileSessionSampleRate
profileSessionSampleRate: 1.0,
// ___PRODUCT_OPTION_END___ profiling
});
instrument(Sentry.createFlueInstrumentation());
import { instrument } from "@flue/runtime";
import * as Sentry from "@sentry/node";
// ___PRODUCT_OPTION_START___ profiling
import { nodeProfilingIntegration } from "@sentry/profiling-node";
// ___PRODUCT_OPTION_END___ profiling
Sentry.init({
dsn: "___PUBLIC_DSN___",
// ___PRODUCT_OPTION_START___ profiling
// Add our Profiling integration
nodeProfilingIntegration(),
// ___PRODUCT_OPTION_END___ profiling
// ___PRODUCT_OPTION_START___ performance
// Set tracesSampleRate to 1.0 to capture 100%
// of spans for tracing.
// We recommend adjusting this value in production.
tracesSampleRate: 1.0,
// ___PRODUCT_OPTION_END___ performance
// ___PRODUCT_OPTION_START___ profiling
// Set profileSessionSampleRate to 1.0 to profile every session.
// Learn more at
// https://docs.sentry.io/platforms/javascript/configuration/options/#profileSessionSampleRate
profileSessionSampleRate: 1.0,
// ___PRODUCT_OPTION_END___ profiling
});
instrument(Sentry.createFlueInstrumentation());
Import it at the top of your app entry, so it runs before your agents take a turn:
src/app.tsimport "./instrument.ts";
import "./instrument.ts";
Call instrument() once, at module scope. On Cloudflare the Vite plugin registers the instrumentation at build time instead; on Node there's no equivalent, so this call is what installs it.
Libraries like database drivers, caches, and dataloader are instrumented by a module transform that has to be installed before your app loads them. A Flue build imports your dependencies before src/instrument.ts runs, so start the server with the Sentry loader to catch them:
package.json{
"scripts": {
"dev": "NODE_OPTIONS='--import=@sentry/node/import' vite dev",
"start": "NODE_OPTIONS='--import=@sentry/node/import' node dist/server.mjs"
}
}
{
"scripts": {
"dev": "NODE_OPTIONS='--import=@sentry/node/import' vite dev",
"start": "NODE_OPTIONS='--import=@sentry/node/import' node dist/server.mjs"
}
}
Agent, model, and tool spans arrive without this, as do outgoing HTTP requests. Everything instrumented through the module transform needs it.
With this setup, Sentry captures errors thrown by your agents and tools, and AI spans for every run (agent turns, model calls, tool executions, token usage, and latency). Manual spans you start inside a tool nest under that tool's span.
To review what's captured and turn recording of prompts and responses off, see Privacy Controls below.
The SDK will record generative AI inputs and outputs (the prompts your agent sends and the model responses it receives) by default. To turn recording off, set genAI.inputs and genAI.outputs to false in dataCollection:
src/instrument.tsSentry.init({
dsn: "___PUBLIC_DSN___",
dataCollection: {
genAI: { inputs: false, outputs: false },
},
});
Sentry.init({
dsn: "___PUBLIC_DSN___",
dataCollection: {
genAI: { inputs: false, outputs: false },
},
});
See dataCollection documentation for details on privacy control options.
Sentry groups a multi-turn chat into a single Conversation automatically — there's no Sentry-specific setup. Flue already tracks a conversation id per conversation, and the SDK maps it to gen_ai.conversation.id on the agent, model, and tool spans of every turn.
The agent span also carries gen_ai.agent.name, so you can tell a lead agent's runs from its subagents'.
Send a message to one of your agents, then open Explore → Agents in Sentry. Select the conversation to open its detail. The timeline shows the agent turn, model calls, tool executions, token usage, latency, and any errors your tools threw.
If no data appears, confirm that:
- The
dsnbelongs to the Sentry project you're viewing. tracesSampleRateis greater than0.- Your agent completed at least one turn after you added the setup.
- Token and cost values are doubled. Remove the
createOpenTelemetryInstrumentationcall left over from theflue add tooling sentryblueprint. Flue emits its own model spans through it, so both it and the SDK count the same turn. - No AI spans at all. Confirm
instrument(Sentry.createFlueInstrumentation())actually runs. Importingsrc/instrument.tsat the top ofsrc/app.tsruns it during app startup, before any agent takes a turn.
- Name your agents so you can identify them in the Agents Dashboard.
- Track AI agent spend with dashboards and alerts: build a dashboard for cost, tokens, models, and conversations.
- Flue's observability guide: the event model behind the spans, from the Flue side.
- Use the appropriate JavaScript framework guide for application monitoring in a separate frontend or service.
@sentry/node:>=11.0.0@sentry/cloudflare:>=11.0.0@flue/runtime:>=2.0.0 <3.0.0
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").