Aller au contenu principal

Traçage

Le traçage est le signal d’observabilité qui enregistre la façon dont une requête traverse les agents, workflows, outils et appels de modèles. Mastra représente chaque opération sous forme de span et regroupe les spans associés dans une trace afin que vous puissiez inspecter le chemin d’exécution complet.

Cette page se concentre sur les concepts propres aux traces : hiérarchie des spans, échantillonnage, métadonnées, filtrage, identifiants de trace et contexte de trace tiers.

Quand utiliser le traçage
Lien direct vers Quand utiliser le traçage

  • Déboguer un comportement inattendu d’un agent ou d’un workflow en inspectant le chemin d’exécution complet.
  • Suivre les appels de modèles, les appels d’outils et les étapes de workflow au sein d’une même requête.
  • Joindre des métadonnées et des tags propres aux traces afin de les filtrer et de les analyser.
  • Relier les traces Mastra à un système de traçage tiers.

Bien démarrer
Lien direct vers Bien démarrer

Pour commencer à utiliser le traçage, configurez l’observabilité dans votre instance Mastra et exécutez un agent ou un workflow. Vous pouvez configurer son comportement grâce aux fonctionnalités suivantes :

  • Configuration : configuration d’observabilité de base et configurations multiples, ainsi que vidage dans les environnements serverless
  • Stockage : routage du stockage pour les traces, journaux et métriques
  • Vue d’ensemble des intégrations : exportateurs, bridges et processeurs

Stratégies d’échantillonnage
Lien direct vers Stratégies d’échantillonnage

L’échantillonnage vous permet de contrôler les traces collectées et de trouver un équilibre entre vos besoins d’observabilité et le coût des ressources.

Dans les environnements de production à fort trafic, collecter chaque trace peut être coûteux et inutile.

Les stratégies d’échantillonnage vous permettent de capturer un sous-ensemble représentatif de traces tout en veillant à ne manquer aucune information critique sur les erreurs ou les opérations importantes.

Vous pouvez configurer l’échantillonnage au niveau de la configuration d’observabilité :

src/mastra/index.ts
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()],
},
},
}),
})

L’option sampling vous permet de contrôler les traces collectées et de trouver un équilibre entre vos besoins d’observabilité et le coût des ressources. Mastra prend en charge quatre stratégies d’échantillonnage :

  1. Toujours échantillonner : collecte 100 % des traces. Cette stratégie convient parfaitement au développement, au débogage ou aux scénarios à faible trafic qui nécessitent une visibilité complète.

    sampling: {
    type: 'always'
    }
  2. Ne jamais échantillonner : désactive entièrement le traçage. Cette stratégie est utile dans les environnements où le traçage n’apporte aucune valeur, ou lorsque vous devez le désactiver temporairement sans supprimer la configuration.

    sampling: {
    type: 'never'
    }
  3. Échantillonnage fondé sur un ratio : échantillonne aléatoirement un pourcentage des traces. Cette stratégie convient parfaitement aux environnements de production dans lesquels vous souhaitez obtenir des informations statistiques sans supporter le coût d’un traçage complet. La valeur de probabilité va de 0 (aucune trace) à 1 (toutes les traces).

    sampling: {
    type: 'ratio',
    probability: 0.1 // Sample 10% of traces
    }
  4. Échantillonnage personnalisé : met en œuvre votre propre logique d’échantillonnage en fonction du contexte de la requête, des métadonnées ou de règles métier. Cette stratégie convient aux scénarios complexes, comme un échantillonnage fondé sur le niveau de l’utilisateur, le type de requête ou les conditions d’erreur.

    sampling: {
    type: 'custom',
    sampler: (options) => {
    // Sample premium users at higher rate
    if (options?.metadata?.userTier === 'premium') {
    return Math.random() < 0.5; // 50% sampling
    }

    // Default 1% sampling for others
    return Math.random() < 0.01;
    }
    }

Ajouter des métadonnées personnalisées
Lien direct vers Ajouter des métadonnées personnalisées

Les métadonnées personnalisées vous permettent d’ajouter du contexte à vos traces, ce qui facilite le débogage des problèmes et la compréhension du comportement du système en production.

Les métadonnées peuvent inclure la logique métier et des métriques de performance. Elles peuvent également contenir le contexte utilisateur ou toute autre information expliquant ce qui s’est produit pendant l’exécution.

Vous pouvez ajouter des métadonnées à n’importe quel span à l’aide du contexte de traçage :

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()
}

Les métadonnées définies ici s’afficheront dans tous les exportateurs configurés.

Ajouter l’environnement de déploiement comme tag aux traces
Lien direct vers Ajouter l’environnement de déploiement comme tag aux traces

Définissez le champ environment de premier niveau dans Mastra pour joindre automatiquement l’environnement de déploiement à tous les signaux d’observabilité, sans transmettre tracingOptions.metadata.environment à chaque appel.

src/mastra/index.ts
export const mastra = new Mastra({
environment: 'production',
observability: new Observability({
configs: {
default: {
serviceName: 'my-service',
exporters: [new MastraStorageExporter()],
},
},
}),
})

Si environment n’est pas défini, Mastra se rabat sur process.env.NODE_ENV. Si aucun des deux n’est défini, le champ reste indéfini plutôt que d’être deviné.

La valeur tracingOptions.metadata.environment fournie lors de l’appel est toujours prioritaire ; chaque appel peut donc remplacer cette valeur si nécessaire.

Métadonnées automatiques issues de RequestContext
Lien direct vers automatic-metadata-from-requestcontext

Au lieu d’ajouter manuellement des métadonnées à chaque span, vous pouvez configurer Mastra pour qu’il extraie automatiquement des valeurs de RequestContext et les joigne comme métadonnées à tous les spans d’une trace. Cette fonctionnalité permet de suivre systématiquement les identifiants utilisateur, les informations d’environnement, les feature flags ou toute donnée propre à la requête dans l’ensemble de votre trace.

Extraction au niveau de la configuration
Lien direct vers Extraction au niveau de la configuration

Définissez les clés RequestContext à extraire dans votre configuration de traçage. Ces clés seront automatiquement incluses comme métadonnées dans tous les spans créés avec cette configuration :

src/mastra/index.ts
export const mastra = new Mastra({
observability: new Observability({
configs: {
default: {
serviceName: 'my-service',
requestContextKeys: ['userId', 'environment', 'tenantId'],
exporters: [new MastraStorageExporter()],
},
},
}),
})

Désormais, lorsque vous exécutez des agents ou des workflows avec un RequestContext, ces valeurs sont automatiquement extraites :

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,
})

Ajouts propres à une requête
Lien direct vers Ajouts propres à une requête

Vous pouvez ajouter des clés propres à une trace avec tracingOptions.requestContextKeys. Elles sont fusionnées avec les clés définies au niveau de la configuration :

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

Extraction de valeurs imbriquées
Lien direct vers Extraction de valeurs imbriquées

Utilisez la notation par points pour extraire des valeurs imbriquées de 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' } } }

Fonctionnement
Lien direct vers Fonctionnement

  1. Calcul de TraceState : au début d’une trace (lors de la création du span racine), Mastra détermine les clés à extraire en fusionnant celles définies au niveau de la configuration et celles propres à la requête
  2. Extraction automatique : les spans racines (exécutions d’agents et de workflows) extraient automatiquement les métadonnées de RequestContext
  3. Extraction dans les spans enfants : les spans enfants peuvent également extraire des métadonnées si vous transmettez requestContext lors de leur création
  4. Priorité des métadonnées : les métadonnées explicites transmises dans les options du span sont toujours prioritaires sur les métadonnées extraites

Ajouter des tags aux traces
Lien direct vers Ajouter des tags aux traces

Les tags sont des libellés textuels qui vous aident à catégoriser et filtrer les traces. Contrairement aux métadonnées, qui contiennent des données structurées sous forme de paires clé-valeur, les tags sont de simples chaînes conçues pour faciliter le filtrage et l’organisation.

Utilisez tracingOptions.tags pour ajouter des tags lors de l’exécution d’agents ou de workflows :

// 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'],
},
})

Fonctionnement des tags
Lien direct vers Fonctionnement des tags

  • Span racine uniquement : les tags s’appliquent uniquement au span racine d’une trace (le span d’exécution de l’agent ou du workflow)
  • Prise en charge étendue : la plupart des exportateurs prennent en charge les tags pour filtrer et rechercher des traces :
    • Braintrust : champ tags natif
    • Langfuse : champ tags natif sur les traces
    • ArizeExporter : attribut OpenInference tag.tags
    • OtelExporter : attribut de span mastra.tags
    • OtelBridge : attribut de span mastra.tags
  • Combinaison avec les métadonnées : vous pouvez utiliser à la fois tags et metadata dans le même objet tracingOptions
const result = await agent.generate([{ role: 'user', content: 'Analyze this' }], {
tracingOptions: {
tags: ['production', 'analytics'],
metadata: { userId: 'user-123', experimentId: 'exp-456' },
},
})

Schémas de tags courants
Lien direct vers Schémas de tags courants

  • Environnement : "production", "staging", "development"
  • Indicateurs de fonctionnalité : "feature-x-enabled", "beta-user"
  • Types de requêtes : "user-request", "batch-job", "scheduled-task"
  • Niveaux de priorité : "priority-high", "priority-low"
  • Expériences : "experiment-v1", "control-group", "treatment-a"

Masquer les entrées et sorties sensibles
Lien direct vers Masquer les entrées et sorties sensibles

Lorsque vous traitez des données sensibles, vous pouvez empêcher l’enregistrement des valeurs d’entrée et de sortie dans vos plateformes d’observabilité. Utilisez hideInput et hideOutput dans tracingOptions afin d’exclure ces données de tous les spans d’une trace :

// 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,
},
})

Fonctionnement
Lien direct vers Fonctionnement

  • Effet sur toute la trace : lorsque ces options sont définies sur le span racine, elles s’appliquent à tous les spans enfants de la trace (appels d’outils, générations de modèles, etc.)
  • Filtrage au moment de l’exportation : les données restent disponibles en interne pendant l’exécution, mais sont exclues lors de l’exportation des spans vers les plateformes d’observabilité
  • Combinaison avec d’autres options : vous pouvez utiliser hideInput/hideOutput avec tags, metadata et d’autres propriétés de 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' },
},
})

Pour contrôler plus finement les données sensibles, envisagez d’utiliser le processeur de filtrage des données sensibles, qui peut masquer des champs précis (comme les mots de passe, tokens et clés) tout en conservant le reste des entrées et sorties.

Spans enfants et extraction des métadonnées
Lien direct vers Spans enfants et extraction des métadonnées

Lorsque vous créez des spans enfants dans des outils ou des étapes de workflow, vous pouvez transmettre le paramètre requestContext pour activer l’extraction des métadonnées :

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
}

Vous contrôlez précisément les spans enfants qui incluent les métadonnées de RequestContext. Les spans racines (exécutions d’agents et de workflows) extraient toujours automatiquement les métadonnées, tandis que les spans enfants ne le font que si vous transmettez explicitement requestContext.

Créer des spans enfants
Lien direct vers Créer des spans enfants

Les spans enfants vous permettent de suivre des opérations détaillées au sein des étapes de votre workflow ou de vos outils. Ils rendent visibles les sous-opérations telles que les requêtes de base de données, les appels d’API, les opérations sur les fichiers ou les calculs complexes. Cette structure hiérarchique vous aide à repérer les goulots d’étranglement et à comprendre la séquence exacte des opérations.

Créez des spans enfants dans un appel d’outil ou une étape de workflow afin de suivre des opérations précises :

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
}
}

Les spans enfants héritent automatiquement du contexte de trace de leur parent, ce qui préserve la hiérarchie des relations dans votre plateforme d’observabilité.

Mise en forme des spans
Lien direct vers Mise en forme des spans

Mastra propose deux moyens de transformer les données de span avant qu’elles n’atteignent votre plateforme d’observabilité : les processeurs de spans et les formateurs de spans personnalisés. Tous deux permettent de modifier, filtrer ou enrichir les données de trace, mais ils interviennent à des niveaux différents et répondent à des besoins distincts.

FonctionnalitéProcesseurs de spansFormateurs de spans personnalisés
Niveau de configurationConfiguration d’observabilitéPar exportateur
Objet traitéObjet Span interneDonnées ExportedSpan exportées
S’applique àTous les exportateursUn seul exportateur
Prise en charge asynchroneNonOui
Cas d’utilisationSécurité, filtrage, enrichissementMise en forme propre à la plateforme, enrichissement asynchrone

Utilisez les processeurs de spans pour les transformations synchrones qui doivent s’appliquer à tous les exportateurs, comme le masquage des données sensibles. Utilisez les formateurs de spans personnalisés lorsque différents exportateurs nécessitent des représentations différentes des mêmes données, par exemple du texte brut pour une plateforme et des données structurées pour une autre, ou lorsque vous devez effectuer des opérations asynchrones telles que la récupération de données depuis des API externes.

Processeurs de spans
Lien direct vers Processeurs de spans

Les processeurs de spans transforment, filtrent ou enrichissent les données de trace avant leur exportation. Ils forment un pipeline entre la création des spans et leur exportation, ce qui vous permet de modifier les spans à des fins de sécurité, de conformité ou de débogage. Les processeurs s’exécutent une seule fois et agissent sur tous les exportateurs.

Processeurs intégrés
Lien direct vers Processeurs intégrés

Créer des processeurs personnalisés
Lien direct vers Créer des processeurs personnalisés

Vous pouvez créer des processeurs de spans personnalisés en implémentant l’interface SpanOutputProcessor. Voici un exemple simple qui convertit en minuscules tout le texte d’entrée des spans :

src/processors/lowercase-input-processor.ts
import type { SpanOutputProcessor, AnySpan } from '@mastra/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()],
},
},
}),
})

Les processeurs sont exécutés dans l’ordre de leur définition, ce qui vous permet d’enchaîner plusieurs transformations. Les cas d’utilisation courants incluent :

  • Le masquage des données sensibles (mots de passe, tokens, clés d’API)
  • L’ajout de métadonnées propres à l’environnement
  • L’exclusion de spans selon certains critères
  • La normalisation des formats de données
  • L’enrichissement des spans avec du contexte métier

Pour en savoir plus sur le modèle global des exportateurs, bridges et processeurs, consultez la vue d’ensemble des intégrations.

Filtrage des spans
Lien direct vers Filtrage des spans

Le filtrage des spans vous permet de réduire le bruit et les coûts par span avant que les données n’atteignent votre plateforme d’observabilité. Configurez-le pour chaque instance d’observabilité afin que les différents exportateurs ou environnements puissent conserver des niveaux de détail distincts.

  • Utilisez excludeSpanTypes pour exclure des catégories entières de spans avec une configuration minimale.
  • Utilisez spanFilter lorsque vous avez besoin d’une logique personnalisée fondée sur les données du span exporté.

L’exemple suivant montre comment combiner les deux options dans une même configuration :

src/mastra/index.ts
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
},
},
},
}),
})

Le filtrage a lieu au moment de l’exportation, dans l’ordre suivant :

  1. Les spans internes sont exclus, sauf si includeInternalSpans vaut true.
  2. excludeSpanTypes supprime les types de spans correspondants.
  3. spanOutputProcessors transforme les spans restants.
  4. spanFilter détermine si le span exporté final doit être conservé.

Si spanFilter lève une exception, Mastra conserve le span et journalise l’erreur afin d’éviter toute perte de données silencieuse. Pour obtenir la liste complète des types de spans et davantage d’exemples, consultez la référence sur le filtrage des spans.

Formateurs de spans personnalisés
Lien direct vers Formateurs de spans personnalisés

Les formateurs de spans personnalisés transforment la façon dont les spans apparaissent dans des plateformes d’observabilité précises. Contrairement aux processeurs de spans, les formateurs sont configurés pour chaque exportateur, ce qui permet d’appliquer une mise en forme différente selon la destination. Les formateurs prennent en charge les opérations synchrones et asynchrones.

Cas d’utilisation
Lien direct vers Cas d’utilisation

  • Extraire du texte brut des messages AI SDK : convertir des tableaux de messages structurés en texte lisible
  • Transformer les formats d’entrée et de sortie : personnaliser l’affichage des données dans des plateformes précises
  • Mapper les champs selon la plateforme : ajouter ou supprimer des champs selon les exigences de la plateforme
  • Enrichir les données de façon asynchrone : récupérer du contexte supplémentaire depuis des API externes ou des bases de données

Configuration
Lien direct vers Configuration

Ajoutez un customSpanFormatter à la configuration de n’importe quel exportateur :

src/mastra/index.ts
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(),
],
},
},
}),
})

Enchaîner plusieurs formateurs
Lien direct vers Enchaîner plusieurs formateurs

Utilisez chainFormatters pour combiner plusieurs formateurs. Les chaînes prennent en charge les formateurs synchrones et asynchrones :

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]),
})

Formateurs asynchrones
Lien direct vers Formateurs asynchrones

Les formateurs de spans personnalisés prennent en charge les opérations asynchrones, ce qui permet notamment de récupérer des données depuis des API externes ou des bases de données afin d’enrichir vos 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
]),
})
remarque

Les formateurs asynchrones augmentent la latence de l’exportation des spans. Veillez à ce que les opérations asynchrones restent rapides (moins de 100 ms) pour ne pas ralentir votre application. Envisagez une mise en cache pour les données fréquemment consultées.

Options de sérialisation
Lien direct vers Options de sérialisation

Les options de sérialisation contrôlent la troncature des données de span (entrée, sortie et attributs) avant leur exportation. Elles sont utiles lorsque vous manipulez des charges utiles volumineuses, des objets profondément imbriqués ou lorsque vous devez optimiser le stockage des traces.

Configuration
Lien direct vers Configuration

Ajoutez serializationOptions à votre configuration d’observabilité :

src/mastra/index.ts
export const mastra = new Mastra({
observability: new Observability({
configs: {
default: {
serviceName: 'my-service',
serializationOptions: {
maxStringLength: 2048, // Maximum length for string values (default: 1024)
maxDepth: 10, // Maximum depth for nested objects (default: 6)
maxArrayLength: 100, // Maximum number of items in arrays (default: 50)
maxObjectKeys: 75, // Maximum number of keys in objects (default: 50)
},
exporters: [new MastraStorageExporter()],
},
},
}),
})

Options disponibles
Lien direct vers Options disponibles

OptionValeur par défautDescription
maxStringLength1024Longueur maximale des chaînes. Les chaînes plus longues sont tronquées.
maxDepth6Profondeur maximale des objets imbriqués. Les niveaux plus profonds sont omis.
maxArrayLength50Nombre maximal d’éléments dans les tableaux. Les éléments supplémentaires sont omis.
maxObjectKeys50Nombre maximal de clés dans les objets. Les clés supplémentaires sont omises.

Cas d’utilisation
Lien direct vers Cas d’utilisation

Augmenter les limites pour le débogage : si vos agents ou outils travaillent avec des documents volumineux, des réponses d’API ou des structures de données complexes, augmentez ces limites afin de capturer davantage de contexte dans vos traces :

serializationOptions: {
maxStringLength: 8192, // Capture longer text content
maxDepth: 12, // Handle deeply nested JSON responses
maxArrayLength: 200, // Keep more items from large lists
}

Réduire la taille des traces en production : diminuez ces valeurs afin de réduire les coûts de stockage et d’améliorer les performances lorsque vous n’avez pas besoin de voir l’intégralité des charges utiles :

serializationOptions: {
maxStringLength: 256, // Truncate strings aggressively
maxDepth: 3, // Shallow object representation
maxArrayLength: 10, // Keep only first few items
maxObjectKeys: 20, // Limit object keys
}

Toutes les options sont facultatives. Si elles ne sont pas définies, les valeurs par défaut indiquées ci-dessus sont utilisées.

Récupérer les identifiants de trace
Lien direct vers Récupérer les identifiants de trace

Lorsque vous exécutez des agents ou des workflows avec le traçage activé, la réponse inclut un traceId qui vous permet de retrouver la trace complète dans votre plateforme d’observabilité. Cela s’avère utile pour le débogage ou l’assistance client, ainsi que pour corréler les traces avec d’autres événements de votre système.

Identifiants de trace des agents
Lien direct vers Identifiants de trace des agents

Les méthodes generate et stream renvoient toutes deux l’identifiant de trace dans leur réponse :

// 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)

Identifiants de trace des workflows
Lien direct vers Identifiants de trace des workflows

Les exécutions de workflows renvoient elles aussi des identifiants de trace :

// 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)

Utiliser les identifiants de trace
Lien direct vers Utiliser les identifiants de trace

Une fois que vous disposez d’un identifiant de trace, vous pouvez :

  1. Rechercher des traces dans Studio : accédez à la vue des traces et effectuez une recherche par identifiant
  2. Interroger les traces sur des plateformes externes : utilisez l’identifiant dans Langfuse, Braintrust, MLflow ou votre plateforme d’observabilité
  3. Effectuer une corrélation avec les journaux : incluez l’identifiant de trace dans les journaux de votre application afin de pouvoir établir des correspondances
  4. Le partager pour le débogage : fournissez des identifiants de trace aux équipes d’assistance ou aux développeurs à des fins d’analyse

L’identifiant de trace n’est disponible que lorsque le traçage est activé. Si le traçage est désactivé ou si l’échantillonnage exclut la requête, traceId vaudra undefined.

Intégration avec des systèmes de traçage externes
Lien direct vers Intégration avec des systèmes de traçage externes

Lorsque vous exécutez des agents ou workflows Mastra dans des applications qui disposent déjà d’un traçage distribué (OpenTelemetry, Datadog, etc.), vous pouvez relier les traces Mastra au contexte de votre trace parente. Vous obtenez ainsi une vue unifiée de l’ensemble du flux de requête, ce qui facilite la compréhension de la place des opérations Mastra dans le système global.

Transmettre des identifiants de trace externes
Lien direct vers Transmettre des identifiants de trace externes

Utilisez le paramètre tracingOptions pour préciser le contexte de trace de votre système parent :

// 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

Intégration d’OpenTelemetry
Lien direct vers Intégration d’OpenTelemetry

L’intégration d’OpenTelemetry permet aux traces Mastra d’apparaître directement dans votre plateforme d’observabilité existante :

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,
},
})
}

Intégration des workflows
Lien direct vers Intégration des workflows

Les workflows prennent en charge le même modèle pour propager les traces :

const workflow = mastra.getWorkflow('data-pipeline')
const run = await workflow.createRun()

const result = await run.start({
inputData: { data: '...' },
tracingOptions: {
traceId: externalTraceId,
parentSpanId: externalSpanId,
},
})

Exigences de format des identifiants
Lien direct vers Exigences de format des identifiants

Mastra valide les identifiants de trace et de span afin de garantir leur compatibilité :

  • Identifiants de trace : de 1 à 32 caractères hexadécimaux (OpenTelemetry en utilise 32)
  • Identifiants de span : de 1 à 16 caractères hexadécimaux (OpenTelemetry en utilise 16)

Les identifiants non valides sont gérés sans interrompre l’exécution : Mastra journalise une erreur et poursuit :

  • Identifiant de trace non valide → génère un nouvel identifiant de trace
  • Identifiant du span parent non valide → ignore la relation avec le parent

Le traçage ne fait donc jamais planter votre application, même si l’entrée est mal formée.

Exemple : middleware Express
Lien direct vers Exemple : middleware Express

Voici un exemple complet de propagation des traces dans une application Express :

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)
})

Cela crée une seule trace distribuée qui comprend à la fois le traitement de la requête HTTP et l’exécution de l’agent Mastra, et que vous pouvez consulter dans la plateforme d’observabilité de votre choix.

Éléments tracés
Lien direct vers Éléments tracés

Mastra crée automatiquement des spans pour les éléments suivants :

Opérations des agents
Lien direct vers Opérations des agents

  • Exécutions d’agents : exécution complète avec les instructions et les outils
  • Appels de LLM : interactions avec les modèles, avec tokens et paramètres
  • Exécutions d’outils : appels de fonctions avec leurs entrées et sorties
  • Opérations de mémoire : thread et rappel sémantique

Opérations des workflows
Lien direct vers Opérations des workflows

  • Exécutions de workflows : exécution complète du début à la fin
  • Étapes individuelles : traitement de chaque étape avec ses entrées et sorties
  • Flux de contrôle : conditions, boucles et exécution parallèle
  • Opérations d’attente : délais et attente d’événements

Voir aussi
Lien direct vers Voir aussi

Documentation de référence
Lien direct vers Documentation de référence