Usage
Tracing 是可观测性信号,用于记录请求如何流经 agents、workflows、tools 和模型调用。Mastra 将每个操作表示为一个 span,并将相关 spans 分组为一个 trace,以便你可以检查完整的执行路径。
本页重点介绍 trace 特定的概念:span 层级、采样、metadata、过滤、trace ID 和第三方 trace 上下文。
何时使用 tracing何时使用 tracing的直接链接
- 通过检查完整的执行路径来调试意外的 agent 或 workflow 行为。
- 跟踪单个请求内的模型调用、tool 调用和 workflow 步骤。
- 附加 trace 特定的 metadata 和 tags,用于过滤和调查。
- 将 Mastra traces 连接到第三方追踪系统。
开始使用开始使用的直接链接
要开始使用 tracing,请在 Mastra 实例中配置可观测性,然后运行 agent 或 workflow。你可以通过以下功能配置行为:
采样策略采样策略的直接链接
采样让你控制收集哪些 traces,帮助你在可观测性需求和资源成本之间取得平衡。
在高流量生产环境中,收集每个 trace 可能既昂贵又没有必要。
采样策略让你捕获具有代表性的 trace 子集,同时确保不会错过有关错误或重要操作的关键信息。
你可以在可观测性配置级别配置采样:
export const mastra = new Mastra({
observability: new Observability({
configs: {
'10_percent': {
serviceName: 'my-service',
// Sample 10% of traces
sampling: {
type: 'ratio',
probability: 0.1,
},
exporters: [new MastraStorageExporter()],
},
},
}),
})
sampling 选项让你控制收集哪些 traces,帮助在可观测性需求和资源成本之间取得平衡。Mastra 支持四种采样策略:
-
Always Sample:收集 100% 的 traces。最适合开发、调试或需要完整可见性的低流量场景。
sampling: {type: 'always'} -
Never Sample:完全禁用 tracing。适用于 tracing 没有价值的特定环境,或当你需要临时禁用 tracing 而不移除配置时。
sampling: {type: 'never'} -
Ratio-Based Sampling:随机采样一定百分比的 traces。非常适合希望获得统计洞察而不承担完整 tracing 成本的生产环境。概率值范围为 0(不采样)到 1(全部采样)。
sampling: {type: 'ratio',probability: 0.1 // Sample 10% of traces} -
Custom Sampling:根据请求上下文、metadata 或业务规则实现你自己的采样逻辑。非常适合基于用户层级、请求类型或错误条件进行采样等复杂场景。
sampling: {type: 'custom',sampler: (options) => {// Sample premium users at higher rateif (options?.metadata?.userTier === 'premium') {return Math.random() < 0.5; // 50% sampling}// Default 1% sampling for othersreturn Math.random() < 0.01;}}
添加自定义 metadata添加自定义 metadata的直接链接
添加自定义 metadata,以在 traces 中记录应用特定的上下文,用于调试生产问题。
Metadata 可以包括业务逻辑和性能指标。它还可以携带用户上下文或任何其他解释执行期间发生情况的信息。
你可以使用 tracing context 向任何 span 添加 metadata:
execute: async (inputData, context) => {
const startTime = Date.now()
const response = await fetch(inputData.endpoint)
// Add custom metadata to the current span
context?.tracingContext.currentSpan?.update({
metadata: {
apiStatusCode: response.status,
endpoint: inputData.endpoint,
responseTimeMs: Date.now() - startTime,
userTier: inputData.userTier,
region: process.env.AWS_REGION,
},
})
return await response.json()
}
在此设置的 metadata 会显示在所有已配置的导出器中。
使用部署环境标记 traces使用部署环境标记 traces的直接链接
在 Mastra 上设置顶层 environment 字段,即可自动将部署环境附加到所有可观测性信号,而无需在每次调用时传递 tracingOptions.metadata.environment。
export const mastra = new Mastra({
environment: 'production',
observability: new Observability({
configs: {
default: {
serviceName: 'my-service',
exporters: [new MastraStorageExporter()],
},
},
}),
})
如果未设置 environment,通过 mastra dev 启动的运行会解析为 development(即使 dev server 本身以 NODE_ENV=production 运行);否则 Mastra 会回退到 process.env.NODE_ENV。如果这些都未设置,该字段会保持 undefined,而不是进行猜测。
每次调用的 tracingOptions.metadata.environment 始终优先,因此单个调用可以在需要时覆盖该值。
从 RequestContext 自动提取 metadataautomatic-metadata-from-requestcontext的直接链接
无需手动向每个 span 添加 metadata,你可以配置 Mastra 自动从 RequestContext 提取值,并将其作为 metadata 附加到 trace 中的所有 spans。这对于在整个 trace 中一致地跟踪用户标识符和环境信息,以及功能开关或其他请求作用域数据非常有用。
配置级提取配置级提取的直接链接
在 tracing 配置中定义要提取的 RequestContext 键。这些键会自动作为 metadata 包含在使用此配置创建的所有 spans 中:
export const mastra = new Mastra({
observability: new Observability({
configs: {
default: {
serviceName: 'my-service',
requestContextKeys: ['userId', 'environment', 'tenantId'],
exporters: [new MastraStorageExporter()],
},
},
}),
})
现在,当你使用 RequestContext 执行 agents 或 workflows 时,这些值会被自动提取:
const requestContext = new RequestContext()
requestContext.set('userId', 'user-123')
requestContext.set('environment', 'production')
requestContext.set('tenantId', 'tenant-456')
// All spans in this trace automatically get userId, environment, and tenantId metadata
const result = await agent.generate('Hello', {
requestContext,
})
按请求添加按请求添加的直接链接
你可以使用 tracingOptions.requestContextKeys 添加 trace 特定的键。它们会与配置级键合并:
const requestContext = new RequestContext()
requestContext.set('userId', 'user-123')
requestContext.set('environment', 'production')
requestContext.set('experimentId', 'exp-789')
const result = await agent.generate('Hello', {
requestContext,
tracingOptions: {
requestContextKeys: ['experimentId'], // Adds to configured keys
},
})
// All spans now have: userId, environment, AND experimentId
嵌套值提取嵌套值提取的直接链接
使用点号表示法从 RequestContext 中提取嵌套值:
export const mastra = new Mastra({
observability: new Observability({
configs: {
default: {
requestContextKeys: ['user.id', 'session.data.experimentId'],
exporters: [new MastraStorageExporter()],
},
},
}),
})
const requestContext = new RequestContext()
requestContext.set('user', { id: 'user-456', name: 'John Doe' })
requestContext.set('session', { data: { experimentId: 'exp-999' } })
// Metadata will include: { user: { id: 'user-456' }, session: { data: { experimentId: 'exp-999' } } }
工作原理工作原理的直接链接
- TraceState 计算:在 trace 开始时(创建根 span),Mastra 通过合并配置级和按请求的键来计算要提取的键
- 自动提取:根 spans(agent 运行、workflow 执行)会自动从 RequestContext 提取 metadata
- 子 span 提取:如果你在创建子 spans 时传入
requestContext,它们也可以提取 metadata - Metadata 优先级:传递给 span 选项的显式 metadata 始终优先于提取的 metadata
向 traces 添加 tags向 traces 添加 tags的直接链接
Tags 是字符串标签,帮助你分类和过滤 traces。与 metadata(包含结构化键值数据)不同,tags 是用于快速过滤和组织的纯字符串。
在执行 agents 或 workflows 时,使用 tracingOptions.tags 添加 tags:
// With agents
const result = await agent.generate('Hello', {
tracingOptions: {
tags: ['production', 'experiment-v2', 'user-request'],
},
})
// With workflows
const run = await mastra.getWorkflow('myWorkflow').createRun()
const result = await run.start({
inputData: { data: 'process this' },
tracingOptions: {
tags: ['batch-processing', 'priority-high'],
},
})
Tags 的工作原理Tags 的工作原理的直接链接
- 仅根 span:Tags 仅应用于 trace 的根 span(agent 运行或 workflow 运行 span)
- 广泛支持:大多数导出器支持 tags,用于过滤和搜索 traces:
- Braintrust:原生
tags字段 - Langfuse:traces 上的原生
tags字段 - ArizeExporter:
tag.tagsOpenInference 属性 - OtelExporter:
mastra.tagsspan 属性 - OtelBridge:
mastra.tagsspan 属性
- Braintrust:原生
- 可与 metadata 组合:你可以在同一个
tracingOptions中同时使用tags和metadata
const result = await agent.generate([{ role: 'user', content: 'Analyze this' }], {
tracingOptions: {
tags: ['production', 'analytics'],
metadata: { userId: 'user-123', experimentId: 'exp-456' },
},
})
常见 tag 模式常见 tag 模式的直接链接
- 环境:
"production"、"staging"、"development" - 功能开关:
"feature-x-enabled"、"beta-user" - 请求类型:
"user-request"、"batch-job"、"scheduled-task" - 优先级:
"priority-high"、"priority-low" - 实验:
"experiment-v1"、"control-group"、"treatment-a"
命名 trace命名 trace的直接链接
默认情况下,同一 agent 或 workflow 的每次运行都会获得相同的根 span 名称,例如 workflow run: 'skill-analyze'。当一个 workflow 在多个对象上运行时,请在 tracingOptions 中设置 rootSpanName 来标记每次运行。该名称会替换 Studio trace 列表和显示 span 名称的导出器中的根 span 名称。
const run = await mastra.getWorkflow('skillAnalyze').createRun()
await run.start({
inputData: { skillId: 'typescript' },
tracingOptions: {
rootSpanName: 'skill-analyze: typescript',
},
})
该名称仅应用于根 span。子 spans 保留其默认名称。实体过滤器继续有效,因为 workflow 或 agent id 会单独存储为 entityId 和 entityName。
基于 OpenTelemetry 的导出器和 Langfuse 导出器会根据实体 id 构建其 span 和 trace 名称,因此不受影响。要命名 Langfuse trace,请按照 Langfuse 集成中的说明设置 metadata.traceName。
隐藏敏感的输入/输出隐藏敏感的输入/输出的直接链接
在处理敏感数据时,你可能希望防止输入和输出值被记录到可观测性平台。使用 tracingOptions 中的 hideInput 和 hideOutput 将这些数据从 trace 的所有 spans 中排除:
// Hide input data (e.g., user credentials, PII)
const result = await agent.generate([{ role: 'user', content: 'Process this sensitive data' }], {
tracingOptions: {
hideInput: true, // Input will be hidden from all spans
},
})
// Hide output data (e.g., generated secrets, confidential results)
const result = await agent.generate([{ role: 'user', content: 'Generate API keys' }], {
tracingOptions: {
hideOutput: true, // Output will be hidden from all spans
},
})
// Hide both input and output
const result = await agent.generate([{ role: 'user', content: 'Handle confidential request' }], {
tracingOptions: {
hideInput: true,
hideOutput: true,
},
})
工作原理工作原理的直接链接
- Trace 范围生效:当在根 span 上设置时,这些选项会应用于 trace 中的所有子 spans(tool 调用、模型生成等)
- 导出时过滤:数据在执行期间内部仍然可用,但在 spans 导出到可观测性平台时会被排除
- 可与其他选项组合:你可以将
hideInput/hideOutput与tags、metadata和其他tracingOptions一起使用
const result = await agent.generate([{ role: 'user', content: 'Sensitive operation' }], {
tracingOptions: {
hideInput: true,
hideOutput: true,
tags: ['sensitive-operation', 'pii-handling'],
metadata: { operationType: 'credential-processing' },
},
})
要对敏感数据进行更细粒度的控制,可以考虑使用 Sensitive Data Filter处理器,它可以对特定字段(如密码、token 和密钥)进行脱敏,同时保留输入/输出的其余部分。
子 spans 和 metadata 提取子 spans 和 metadata 提取的直接链接
在 tools 或 workflow 步骤中创建子 spans 时,你可以传入 requestContext 参数以启用 metadata 提取:
execute: async (inputData, context) => {
// Create child span WITH requestContext - gets metadata extraction
const dbSpan = context?.tracingContext.currentSpan?.createChildSpan({
type: 'generic',
name: 'database-query',
requestContext: context?.requestContext, // Pass to enable metadata extraction
})
const results = await db.query('SELECT * FROM users')
dbSpan?.end({ output: results })
// Or create child span WITHOUT requestContext - no metadata extraction
const cacheSpan = context?.tracingContext.currentSpan?.createChildSpan({
type: 'generic',
name: 'cache-check',
// No requestContext - won't extract metadata
})
return results
}
你可以精确控制哪些子 spans 包含 RequestContext metadata。根 spans(agent/workflow 执行)始终自动提取 metadata,而子 spans 仅在你显式传入 requestContext 时才提取。
创建子 spans创建子 spans的直接链接
子 spans 让你跟踪 workflow 步骤或 tools 中的细粒度操作。它们提供对子操作(如数据库查询和 API 调用)以及文件操作或复杂计算的可见性。这种层级结构帮助你识别性能瓶颈并理解操作的准确顺序。
在 tool 调用或 workflow 步骤中创建子 spans 以跟踪特定操作:
execute: async (inputData, context) => {
// Create another child span for the main database operation
const querySpan = context?.tracingContext.currentSpan?.createChildSpan({
type: 'generic',
name: 'database-query',
input: { query: inputData.query },
metadata: { database: 'production' },
})
try {
const results = await db.query(inputData.query)
querySpan?.end({
output: results.data,
metadata: {
rowsReturned: results.length,
queryTimeMs: results.executionTime,
cacheHit: results.fromCache,
},
})
return results
} catch (error) {
querySpan?.error({
error,
metadata: { retryable: isRetryableError(error) },
})
throw error
}
}
子 spans 会自动继承其父级的 trace 上下文,在可观测性平台中保持关系层级。
Span 格式化Span 格式化的直接链接
Mastra 提供两种在 span 数据到达可观测性平台之前对其进行转换的方式:span processors 和自定义 span formatters。两者都允许你修改、过滤或丰富 trace 数据,但它们在不同的层级上运行,服务于不同的目的。
| 功能 | Span Processors | 自定义 Span Formatters |
|---|---|---|
| 配置级别 | 可观测性配置 | 每个导出器 |
| 操作对象 | 内部 Span 对象 | 导出的 ExportedSpan 数据 |
| 应用于 | 所有导出器 | 单个导出器 |
| 异步支持 | 否 | 是 |
| 使用场景 | 安全、过滤、丰富 | 平台特定的格式化、异步丰富 |
使用 span processors 进行应应用于所有导出器的同步转换(例如对敏感数据进行脱敏)。当不同导出器需要同一数据的不同表示(例如一个平台使用纯文本,另一个使用结构化数据),或当你需要执行异步操作(如从外部 API 获取数据)时,使用自定义 span formatters。
Span processorsSpan processors的直接链接
Span processors 在 trace 数据导出之前对其进行转换、过滤或丰富。它们充当 span 创建和导出之间的管道,使你能够为安全、合规或调试目的修改 spans。Processors 运行一次并影响所有导出器。
内置 processors内置 processors的直接链接
- Sensitive Data Filter对敏感信息进行脱敏。它在默认可观测性配置中启用。
创建自定义 processors创建自定义 processors的直接链接
你可以通过实现 SpanOutputProcessor 接口创建自定义 span processors。以下是一个将 spans 中所有输入文本转换为小写的基本示例:
import type { SpanOutputProcessor, AnySpan } from '@mastra/core/observability'
export class LowercaseInputProcessor implements SpanOutputProcessor {
name = 'lowercase-processor'
process(span: AnySpan): AnySpan {
span.input = `${span.input}`.toLowerCase()
return span
}
async shutdown(): Promise<void> {
// Cleanup if needed
}
}
// Use the custom processor
export const mastra = new Mastra({
observability: new Observability({
configs: {
development: {
spanOutputProcessors: [new LowercaseInputProcessor(), new SensitiveDataFilter()],
exporters: [new MastraStorageExporter()],
},
},
}),
})
process() 必须修改它接收的 span 并返回同一个实例,或返回 undefined 以丢弃该 span。不要返回副本(例如 { ...span, input: '...' }):exportSpan() 和 isValid 是活动 span 的实例成员,因此副本无法导出。在这种情况下,Mastra 会记录 processor 错误并丢弃该 span。
Processors 按定义顺序执行,允许你链接多个转换。常见用例包括:
- 对敏感数据进行脱敏(密码、token、API keys)
- 添加环境特定的 metadata
- 根据条件过滤 spans
- 规范化数据格式
- 使用业务上下文丰富 spans
Span 过滤Span 过滤的直接链接
Span 过滤让你在数据到达可观测性平台之前减少噪声和每个 span 的成本。按可观测性实例配置它,因此不同的导出器或环境可以保留不同级别的细节。
- 使用
excludeSpanTypes以最少的配置丢弃整类 spans。 - 当你需要基于导出 span 数据的自定义逻辑时,使用
spanFilter。
以下示例演示如何在单个配置中组合这两个选项:
import { Mastra } from '@mastra/core'
import { SpanType } from '@mastra/core/observability'
import { Observability, MastraStorageExporter } from '@mastra/observability'
import { LangfuseExporter } from '@mastra/langfuse'
export const mastra = new Mastra({
observability: new Observability({
configs: {
default: {
serviceName: 'my-app',
exporters: [new MastraStorageExporter(), new LangfuseExporter()],
excludeSpanTypes: [SpanType.MODEL_CHUNK, SpanType.MODEL_STEP],
spanFilter: span => {
if (span.type === SpanType.TOOL_CALL && span.attributes?.success) {
return false
}
return true
},
},
},
}),
})
过滤在导出时按以下顺序发生:
- 除非
includeInternalSpans为true,否则内部 spans 会被丢弃。 excludeSpanTypes移除匹配的 span 类型。spanOutputProcessors转换剩余的 spans。spanFilter决定是否保留最终导出的 span。
如果 spanFilter 抛出异常,Mastra 会保留该 span 并记录错误,以避免静默丢失数据。完整 span 类型列表和更多示例参见 Span 过滤参考。
自定义 span formatters自定义 span formatters的直接链接
自定义 span formatters 转换 spans 在特定可观测性平台中的显示方式。与 span processors 不同,formatters 按导出器配置,允许为不同目的地使用不同格式。Formatters 支持同步和异步操作。
使用场景使用场景的直接链接
- 从 AI SDK 消息中提取纯文本:将结构化消息数组转换为可读文本
- 转换输入/输出格式:自定义数据在特定平台中的显示方式
- 平台特定的字段映射:根据平台要求添加或移除字段
- 异步数据丰富:从外部 API 或数据库获取额外上下文
配置配置的直接链接
向任何导出器配置添加 customSpanFormatter:
import { BraintrustExporter } from '@mastra/braintrust'
import { LangfuseExporter } from '@mastra/langfuse'
import { SpanType } from '@mastra/core/observability'
import type { CustomSpanFormatter } from '@mastra/core/observability'
// Formatter that extracts plain text from AI messages
const plainTextFormatter: CustomSpanFormatter = span => {
if (span.type === SpanType.AGENT_RUN && Array.isArray(span.input)) {
const userMessage = span.input.find(m => m.role === 'user')
return {
...span,
input: userMessage?.content ?? span.input,
}
}
return span
}
export const mastra = new Mastra({
observability: new Observability({
configs: {
default: {
serviceName: 'my-service',
exporters: [
// Braintrust gets plain text formatting
new BraintrustExporter({
customSpanFormatter: plainTextFormatter,
}),
// Langfuse keeps the original structured format
new LangfuseExporter(),
],
},
},
}),
})
链接多个 formatters链接多个 formatters的直接链接
使用 chainFormatters 组合多个 formatters。链支持同步和异步 formatters:
import { chainFormatters } from '@mastra/observability'
const inputFormatter: CustomSpanFormatter = span => ({
...span,
input: extractPlainText(span.input),
})
const outputFormatter: CustomSpanFormatter = span => ({
...span,
output: extractPlainText(span.output),
})
const exporter = new BraintrustExporter({
customSpanFormatter: chainFormatters([inputFormatter, outputFormatter]),
})
异步 formatters异步 formatters的直接链接
自定义 span formatters 支持异步操作,从而实现从外部 API 或数据库获取数据以丰富 spans 等用例:
import type { CustomSpanFormatter } from '@mastra/core/observability'
// Async formatter that enriches spans with user data
const userEnrichmentFormatter: CustomSpanFormatter = async span => {
const userId = span.metadata?.userId
if (!userId) return span
// Fetch user data from your API or database
const userData = await fetchUserData(userId)
return {
...span,
metadata: {
...span.metadata,
userName: userData.name,
userEmail: userData.email,
department: userData.department,
},
}
}
// Async formatter that looks up additional context
const contextEnrichmentFormatter: CustomSpanFormatter = async span => {
if (span.type !== SpanType.AGENT_RUN) return span
// Fetch experiment configuration
const experimentConfig = await getExperimentConfig(span.metadata?.experimentId)
return {
...span,
metadata: {
...span.metadata,
experimentVariant: experimentConfig?.variant,
experimentGroup: experimentConfig?.group,
},
}
}
// Use async formatters with an exporter
const exporter = new BraintrustExporter({
customSpanFormatter: userEnrichmentFormatter,
})
// Or chain sync and async formatters together
const exporter = new LangfuseExporter({
customSpanFormatter: chainFormatters([
plainTextFormatter, // sync
userEnrichmentFormatter, // async
contextEnrichmentFormatter, // async
]),
})
异步 formatters 会给 span 导出增加延迟。保持异步操作快速(低于 100ms),以避免拖慢应用。考虑对频繁访问的数据使用缓存。
序列化选项序列化选项的直接链接
序列化选项控制 span 数据(输入、输出和 attributes)在导出前如何被截断。这在处理大型载荷、深度嵌套对象,或需要优化 trace 存储时非常有用。
配置配置的直接链接
向可观测性配置添加 serializationOptions:
export const mastra = new Mastra({
observability: new Observability({
configs: {
default: {
serviceName: 'my-service',
serializationOptions: {
maxStringLength: 2048, // Maximum length for string values (default: 131072)
maxDepth: 10, // Maximum depth for nested objects (default: 8)
maxArrayLength: 100, // Maximum number of items in arrays (default: 50)
maxObjectKeys: 75, // Maximum number of keys in objects (default: 50)
},
exporters: [new MastraStorageExporter()],
},
},
}),
})
可用选项可用选项的直接链接
| 选项 | 默认值 | 描述 |
|---|---|---|
maxStringLength | 131072 (128 KB) | 字符串值的最大长度。更长的字符串会被截断。 |
maxDepth | 8 | 嵌套对象的最大深度。更深的层级会被省略。 |
maxArrayLength | 50 | 数组中的最大项数。额外的项会被省略。 |
maxObjectKeys | 50 | 对象中的最大键数。额外的键会被省略。 |
使用场景使用场景的直接链接
为调试增加限制:提高这些限制,以便为大型文档和 API 响应以及其他数据结构捕获更多上下文:
serializationOptions: {
maxStringLength: 262144, // Capture longer text content (256 KB)
maxDepth: 12, // Handle deeply nested JSON responses
maxArrayLength: 200, // Keep more items from large lists
}
为生产环境减小 trace 大小:当你不需要完整的载荷可见性时,降低这些值以减少存储成本并提高性能:
serializationOptions: {
maxStringLength: 256, // Truncate strings aggressively
maxDepth: 3, // Shallow object representation
maxArrayLength: 10, // Keep only first few items
maxObjectKeys: 20, // Limit object keys
}
所有选项都是可选的,如果未指定,则回退到上面显示的默认值。
获取 trace IDs获取 trace IDs的直接链接
当你执行启用了 tracing 的 agents 或 workflows 时,响应会包含一个 traceId,你可以用它来在可观测性平台中查找完整 trace。这对于调试或客户支持,或者将 traces 与系统中的其他事件关联非常有用。
Agent trace IDsAgent trace IDs的直接链接
generate 和 stream 方法都会在其响应中返回 trace ID:
// Using generate
const result = await agent.generate('Hello')
console.log('Trace ID:', result.traceId)
// Using stream
const streamResult = await agent.stream('Tell me a story')
console.log('Trace ID:', streamResult.traceId)
Workflow trace IDsWorkflow trace IDs的直接链接
Workflow 执行也会返回 trace IDs:
// Create a workflow run
const run = await mastra.getWorkflow('myWorkflow').createRun()
// Start the workflow
const result = await run.start({
inputData: { data: 'process this' },
})
console.log('Trace ID:', result.traceId)
// Or stream the workflow
const { stream, getWorkflowState } = run.stream({
inputData: { data: 'process this' },
})
// Get the final state which includes the trace ID
const finalState = await getWorkflowState()
console.log('Trace ID:', finalState.traceId)
使用 trace IDs使用 trace IDs的直接链接
获得 trace ID 后,你可以:
- 在 Studio 中查找 traces:导航到 traces 视图并按 ID 搜索
- 在外部平台中查询 traces:在 Langfuse、Braintrust、MLflow 或你的可观测性平台中使用该 ID
- 与日志关联:在应用日志中包含 trace ID 以便交叉引用
- 共享以进行调试:向支持团队或开发者提供 trace IDs 以供调查
Trace ID 仅在启用 tracing 时可用。如果 tracing 被禁用或采样排除了该请求,traceId 将为 undefined。
与外部追踪系统集成与外部追踪系统集成的直接链接
如果你的应用已经使用分布式追踪(例如 OpenTelemetry 或 Datadog),你可以将 Mastra traces 连接到父 trace 上下文。这样你可以跟踪请求在应用及其 Mastra agent 或 workflow 调用中的流转。
传递外部 trace IDs传递外部 trace IDs的直接链接
使用 tracingOptions 参数指定来自父系统的 trace 上下文:
// Get trace context from your existing tracing system
const parentTraceId = getCurrentTraceId() // Your tracing system
const parentSpanId = getCurrentSpanId() // Your tracing system
// Execute Mastra operations as part of the parent trace
const result = await agent.generate('Analyze this data', {
tracingOptions: {
traceId: parentTraceId,
parentSpanId: parentSpanId,
},
})
// The Mastra trace will now appear as a child in your distributed trace
OpenTelemetry 集成OpenTelemetry 集成的直接链接
与 OpenTelemetry 集成可以让 Mastra traces 直接显示在你现有的可观测性平台中:
import { trace } from '@opentelemetry/api'
// Get the current OpenTelemetry span
const currentSpan = trace.getActiveSpan()
const spanContext = currentSpan?.spanContext()
if (spanContext) {
const result = await agent.generate(userMessage, {
tracingOptions: {
traceId: spanContext.traceId,
parentSpanId: spanContext.spanId,
},
})
}
Workflow 集成Workflow 集成的直接链接
Workflows 支持相同的 trace 传播模式:
const workflow = mastra.getWorkflow('data-pipeline')
const run = await workflow.createRun()
const result = await run.start({
inputData: { data: '...' },
tracingOptions: {
traceId: externalTraceId,
parentSpanId: externalSpanId,
},
})
将运行嵌套在较早的 Mastra 运行下将运行嵌套在较早的 Mastra 运行下的直接链接
parentSpanId 可以指向两种 span。该 span 可以属于你自己的追踪系统,如上面的示例所示。此时 Mastra 会将运行视为其导出 trace 的顶部,并且该运行设置 trace 的名称、输入、输出和 tags。
该 span 也可以是同一 trace 中较早的 Mastra 运行,例如对已完成轮次评分的 LLM judge。对于这种情况,设置 nestUnderParent: true。新运行会成为该 span 的子级,trace 保留启动它的运行的名称、输入、输出、tags、user 和 session。
const turn = await assistant.generate('When does my order ship?')
await judge.generate(`Grade this answer: ${turn.text}`, {
tracingOptions: {
traceId: turn.traceId,
parentSpanId: turn.spanId,
nestUnderParent: true,
},
})
nestUnderRun() 辅助函数从较早运行的结果构建相同的选项:
import { nestUnderRun } from '@mastra/core/observability'
await judge.generate(`Grade this answer: ${turn.text}`, {
tracingOptions: nestUnderRun(turn),
})
两次运行可以位于不同的进程中。当 traceId 或 parentSpanId 缺失或无效时,Mastra 会忽略 nestUnderParent。当 tracing bridge 在另一个 trace 中启动该运行时,它也会忽略该选项。Langfuse和 Braintrust导出器使用此选项。在其他导出器中,仅 tags 规则适用。
ID 格式要求ID 格式要求的直接链接
Mastra 验证 trace 和 span ID 以确保兼容性:
- Trace IDs:1-32 个十六进制字符(OpenTelemetry 使用 32 个)
- Span IDs:1-16 个十六进制字符(OpenTelemetry 使用 16 个)
无效 ID 会被优雅处理,Mastra 会记录错误并继续:
- 无效 trace ID → 生成新的 trace ID
- 无效 parent span ID → 忽略父子关系
因此,即使输入格式错误,tracing 也绝不会导致应用崩溃。
示例:Express 中间件示例:Express 中间件的直接链接
以下是一个展示 Express 应用中 trace 传播的完整示例:
import { trace } from '@opentelemetry/api'
import express from 'express'
const app = express()
app.post('/api/analyze', async (req, res) => {
// Get current OpenTelemetry context
const currentSpan = trace.getActiveSpan()
const spanContext = currentSpan?.spanContext()
const result = await agent.generate(req.body.message, {
tracingOptions: spanContext
? {
traceId: spanContext.traceId,
parentSpanId: spanContext.spanId,
}
: undefined,
})
res.json(result)
})
这会创建一个单一的分布式 trace,包含 HTTP 请求处理和 Mastra agent 执行,可在你选择的可观测性平台中查看。
MCP 调用MCP 调用的直接链接
Model Context Protocol (MCP) 调用无需任何设置即可关联调用方的 trace 和服务器的 trace。当 agent 或 workflow 通过 MCPClient 调用 tool 时,处理它的 MCPServer 会保留自己的 trace 并记录指向 tool 调用 span 的链接,而 tool 调用 span 会链接回服务器的 span。每一侧都保留自己的 trace、根 span 和 trace 摘要。当服务器使用 tracing bridge 且其 HTTP instrumentation 延续调用方的 trace 时,请求会改为加入该 trace。Mastra 存储会保存与 spans 的链接,支持 span links 的导出器也会发送它们。
这也适用于任一侧的非 Mastra 软件。详情参见 MCPServer 参考,以及MCPClient 参考以发送你自己的 trace 上下文。
哪些内容会被追踪哪些内容会被追踪的直接链接
Mastra 会自动为以下内容创建 spans:
Agent 操作Agent 操作的直接链接
- Agent 运行:包含指令和 tools 的完整执行
- LLM 调用:带有 token 和参数的模型交互
- Tool 执行:带有输入和输出的函数调用
- Memory 操作:Thread 和语义召回
Workflow 操作Workflow 操作的直接链接
- Workflow 运行:从开始到结束的完整执行
- 单个步骤:带有输入/输出的步骤处理
- 控制流:条件、循环、并行执行
- 等待操作:延迟和事件等待