Mastra
Mastra traces every agent run, model call and tool call in GenAI semantic conventions through its OpenTelemetry exporter.
Oodle is a managed observability platform for metrics, logs, traces and agent traces. It ingests OpenTelemetry natively, so the snippet on this page is the complete setup.
Each trace shows the full transcript, the token counts and cost of every call, the agent structure (runs, steps and tool calls) and Signals: labels for loops, rate limits, refusals and tool failures, detected as the trace arrives.
Sign up for free to get an instance ID and an API key, or see the Agent Observability overview first.
You will need:
OODLE_INSTANCE: your Oodle instance ID (ap1, us1)OODLE_API_KEY: an Oodle API key (ap1, us1)OTLP_ENDPOINT: your OTLP collector domain, shown on the tile
Open the Mastra tile on the ap1, us1 page to
get these filled in for you, or let an agent do the setup with
/oodle-onboarding set up the llm_observability_mastra integration.
Install
Install the Mastra OTel exporter alongside the OTLP transport:
npm install @mastra/core @mastra/observability @mastra/otel-exporter \
@opentelemetry/exporter-trace-otlp-proto @ai-sdk/openai zod
Instrument
Add the OTel exporter to the Mastra observability config. Mastra then traces every agent run, model call and tool call in GenAI semantic conventions:
// src/mastra/index.ts
import { Mastra } from '@mastra/core';
import { Agent } from '@mastra/core/agent';
import { createTool } from '@mastra/core/tools';
import { Observability } from '@mastra/observability';
import { OtelExporter } from '@mastra/otel-exporter';
import { openai } from '@ai-sdk/openai';
import { z } from 'zod';
const getWeather = createTool({
id: 'get_weather',
description: 'Return the weather for a city.',
inputSchema: z.object({ city: z.string() }),
execute: async ({ city }) => `Sunny in ${city}`,
});
const weatherAgent = new Agent({
id: 'weather-agent',
name: 'weather-agent',
instructions: 'Use tools when asked about the weather.',
model: openai('gpt-4o-mini'),
tools: { getWeather },
});
export const mastra = new Mastra({
agents: { weatherAgent },
observability: new Observability({
configs: {
default: {
serviceName: 'my-llm-app',
exporters: [
new OtelExporter({
provider: {
custom: {
endpoint: 'https://<OTLP_ENDPOINT>',
protocol: 'http/protobuf',
headers: {
'X-API-KEY': '<OODLE_API_KEY>',
'X-OODLE-INSTANCE': '<OODLE_INSTANCE>',
},
},
},
}),
],
},
},
}),
});
// Every agent.generate() / agent.stream() call is then traced:
// const result = await mastra.getAgent('weatherAgent').generate(
// 'What is the weather in Paris?',
// );
Environment
Point the application at Oodle:
# Compress the export: prompt payloads are large
export OTEL_EXPORTER_OTLP_COMPRESSION=gzip
Verify
Run your application, then open ap1, us1. Spans
carry gen_ai.* attributes: the model, token counts, and the prompt and
response content. Click a trace for the Transcript, the waterfall, and
the cost breakdown.
If nothing arrives, check that the exporter can reach
https://<OTLP_ENDPOINT> and that the instance and key are set: the
OTLP gateway answers 401 without them.
Support
If you need assistance or have any questions, please reach out to us through:
- Email at [email protected]