> Discover all available pages from the documentation index: https://mastra.zisheng.pro/fr/llms.txt # 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. **Pour les agents d’IA :** Exécutez `npx mastra api trace list '{"page":0,"perPage":20}'` pour inspecter directement les traces récentes au lieu d’ouvrir Studio ou d’écrire un script temporaire. La commande nécessite un serveur Mastra en cours d’exécution avec l’observabilité configurée ; démarrez le serveur local avec `npx mastra dev`, ou transmettez l’URL de base du serveur accessible avec `--url`. Exécutez `npx mastra api trace list --schema` avant de créer d’autres filtres. Installez la skill de Mastra avec `npx skills add mastra-ai/skills --skill mastra` pour disposer d’instructions complètes sur la découverte de l’API CLI, le ciblage, le schéma, l’authentification et la gestion des erreurs. ## 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 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](https://mastra.zisheng.pro/fr/docs/observability/overview) : configuration d’observabilité de base et configurations multiples, ainsi que vidage dans les environnements serverless - [Stockage](https://mastra.zisheng.pro/fr/docs/observability/overview) : routage du stockage pour les traces, journaux et métriques - [Vue d’ensemble des intégrations](https://mastra.zisheng.pro/fr/docs/observability/integrations/overview) : exportateurs, bridges et processeurs ## 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é : ```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. ```ts 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. ```ts 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). ```ts 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. ```ts 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 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 : ```ts 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 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. ```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` 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 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 : ```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 : ```ts 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 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 : ```ts 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 Utilisez la notation par points pour extraire des valeurs imbriquées de RequestContext : ```ts 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 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 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 : ```ts // 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 - **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` ```ts 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 - **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 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 : ```ts // 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 - **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` ```ts 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](https://mastra.zisheng.pro/fr/docs/observability/integrations/processors/sensitive-data-filter), 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 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 : ```ts 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 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 : ```ts 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 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 spans | Formateurs de spans personnalisés | | -------------------------- | ---------------------------------- | --------------------------------------------------------------- | | Niveau de configuration | Configuration d’observabilité | Par exportateur | | Objet traité | Objet `Span` interne | Données `ExportedSpan` exportées | | S’applique à | Tous les exportateurs | Un seul exportateur | | Prise en charge asynchrone | Non | Oui | | Cas d’utilisation | Sécurité, filtrage, enrichissement | Mise 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 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 - Le [filtre de données sensibles](https://mastra.zisheng.pro/fr/docs/observability/integrations/processors/sensitive-data-filter) masque les informations sensibles. Il est activé dans la configuration d’observabilité par défaut. #### 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 : ```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 { // 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](https://mastra.zisheng.pro/fr/docs/observability/integrations/overview). ## 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 : ```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](https://mastra.zisheng.pro/fr/reference/observability/tracing/span-filtering). ### 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 - **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 Ajoutez un `customSpanFormatter` à la configuration de n’importe quel exportateur : ```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 Utilisez `chainFormatters` pour combiner plusieurs formateurs. Les chaînes prennent en charge les formateurs synchrones et asynchrones : ```ts 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 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 : ```ts 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 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 Ajoutez `serializationOptions` à votre configuration d’observabilité : ```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 | Option | Valeur par défaut | Description | | ----------------- | ----------------- | ------------------------------------------------------------------------------------ | | `maxStringLength` | 1024 | Longueur maximale des chaînes. Les chaînes plus longues sont tronquées. | | `maxDepth` | 6 | Profondeur maximale des objets imbriqués. Les niveaux plus profonds sont omis. | | `maxArrayLength` | 50 | Nombre maximal d’éléments dans les tableaux. Les éléments supplémentaires sont omis. | | `maxObjectKeys` | 50 | Nombre maximal de clés dans les objets. Les clés supplémentaires sont omises. | ### 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 : ```ts 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 : ```ts 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 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 Les méthodes `generate` et `stream` renvoient toutes deux l’identifiant de trace dans leur réponse : ```ts // 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 Les exécutions de workflows renvoient elles aussi des identifiants de trace : ```ts // 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 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 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 Utilisez le paramètre `tracingOptions` pour préciser le contexte de trace de votre système parent : ```ts // 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 L’intégration d’OpenTelemetry permet aux traces Mastra d’apparaître directement dans votre plateforme d’observabilité existante : ```ts 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 Les workflows prennent en charge le même modèle pour propager les traces : ```ts 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 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 Voici un exemple complet de propagation des traces dans une application Express : ```ts 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 Mastra crée automatiquement des spans pour les éléments suivants : ### 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 - **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 ### Documentation de référence - [API de configuration](https://mastra.zisheng.pro/fr/reference/observability/tracing/configuration) : détails de ObservabilityConfig - [Classes de traçage](https://mastra.zisheng.pro/fr/reference/observability/tracing/instances) : classes et méthodes principales - [Interfaces de span](https://mastra.zisheng.pro/fr/reference/observability/tracing/spans) : types de spans et cycle de vie - [Définitions de types](https://mastra.zisheng.pro/fr/reference/observability/tracing/interfaces) : référence complète des interfaces - [Filtrage des spans](https://mastra.zisheng.pro/fr/reference/observability/tracing/span-filtering) : comportement du filtrage et types de spans, avec des exemples