> Discover all available pages from the documentation index: https://mastra.zisheng.pro/ko/llms.txt # 트레이싱 추적은 요청이 Agent, Workflow, Tool 및 Model 호출을 통해 이동하는 방식을 기록하는 Observability 신호입니다. Mastra는 각 작업을 범위로 나타내고 관련 범위를 추적으로 그룹화하므로 전체 실행 경로를 검사할 수 있습니다. 이 페이지에서는 범위 계층 구조, 샘플링, 메타데이터, 필터링, 추적 ID, 타사 추적 컨텍스트 등 추적 관련 개념에 중점을 둡니다. **AI Agent의 경우:**달리다`npx mastra api trace list '{"page":0,"perPage":20}'` 를 사용하면 Studio를 열거나 임시 스크립트를 작성하지 않고 최근 Trace를 직접 검사할 수 있습니다. 이 명령을 사용하려면 Observability가 구성된 Mastra 서버가 실행 중이어야 합니다. 다음 명령으로 로컬 서버를 시작하세요: `npx mastra dev`, 또는 연결 가능한 서버의 기본 URL을 다음과 함께 전달합니다.`--url`. 달리다`npx mastra api trace list --schema`다른 필터를 구성하기 전에. 마스트라의 스킬을 설치하세요.`npx skills add mastra-ai/skills --skill mastra`완전한 API CLI 검색, 타겟팅, 스키마, 인증 및 오류 처리 지침을 제공합니다. ## 추적을 사용해야 하는 경우 - 전체 실행 경로를 검사하여 예기치 않은 Agent 또는 Workflow 동작을 디버그합니다. - 단일 요청 내에서 Model 호출, Tool 호출 및 Workflow 단계를 따르세요. - 필터링 및 조사를 위해 추적별 메타데이터와 태그를 첨부합니다. - Mastra 추적을 타사 추적 시스템에 연결합니다. ## 시작하기 추적을 시작하려면 Mastra 인스턴스에서 Observability을 구성하고 Agent 또는 Workflow를 실행하세요. 다음 기능을 통해 동작을 구성할 수 있습니다. - [구성](https://mastra.zisheng.pro/ko/docs/observability/overview): 기본 관측성 구성 및 다중 구성과 서버리스 플러싱 - [저장](https://mastra.zisheng.pro/ko/docs/observability/overview): 추적, 로그, 측정항목에 대한 스토리지 라우팅 - [통합 개요](https://mastra.zisheng.pro/ko/docs/observability/integrations/overview): 수출업자, 교량, 가공업자 ## 샘플링 전략 샘플링을 사용하면 수집되는 추적을 제어하여 Observability 요구 사항과 리소스 비용 간의 균형을 맞추는 데 도움이 됩니다. 트래픽이 많은 프로덕션 환경에서는 모든 추적을 수집하는 데 비용이 많이 들고 불필요할 수 있습니다. 샘플링 전략을 사용하면 트레이스의 대표적인 하위 집합을 캡처하는 동시에 오류나 중요한 작업에 대한 중요한 정보를 놓치지 않도록 할 수 있습니다. 관측 가능성 구성 수준에서 샘플링을 구성할 수 있습니다. ```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()], }, }, }), }) ``` 그만큼`sampling` 옵션을 사용하면 수집할 Trace를 제어하여 Observability 요구 사항과 리소스 비용 사이의 균형을 맞출 수 있습니다. Mastra는 네 가지 샘플링 전략을 지원합니다: 1. **항상 샘플링**: 흔적을 100% 수집합니다. 완전한 가시성이 필요한 개발, 디버깅 또는 트래픽이 적은 시나리오에 가장 적합합니다. ```ts sampling: { type: 'always' } ``` 2. **샘플링하지 않음**: 추적을 완전히 비활성화합니다. 추적이 가치를 추가하지 않거나 구성을 제거하지 않고 추적을 일시적으로 비활성화해야 하는 특정 환경에 유용합니다. ```ts sampling: { type: 'never' } ``` 3. **비율 기반 샘플링**: 트레이스의 일정 비율을 무작위로 샘플링합니다. 전체 추적 비용 없이 통계적 통찰력을 원하는 프로덕션 환경에 이상적입니다. 확률 값의 범위는 0(추적 없음)부터 1(모든 추적)까지입니다. ```ts sampling: { type: 'ratio', probability: 0.1 // Sample 10% of traces } ``` 4. **맞춤 샘플링**: 요청 컨텍스트, 메타데이터 또는 비즈니스 규칙을 기반으로 자체 샘플링 논리를 구현합니다. 사용자 계층, 요청 유형 또는 오류 조건을 기반으로 한 샘플링과 같은 복잡한 시나리오에 적합합니다. ```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; } } ``` ## 커스텀 메타데이터 추가 사용자 정의 메타데이터를 사용하면 추적에 추가 컨텍스트를 첨부할 수 있으므로 문제를 더 쉽게 디버깅하고 프로덕션에서 시스템 동작을 이해할 수 있습니다. 메타데이터에는 비즈니스 논리와 성능 지표가 포함될 수 있습니다. 또한 실행 중에 발생한 일을 설명하는 사용자 컨텍스트나 기타 정보를 전달할 수도 있습니다. 추적 컨텍스트를 사용하여 모든 범위에 메타데이터를 추가할 수 있습니다. ```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() } ``` 여기에 설정된 메타데이터는 구성된 모든 내보내기에 표시됩니다. ### 배포 환경으로 추적에 태그 지정 최상위 수준 설정`environment` 필드를 Mastra에 설정하면 다음을 전달하지 않고도 배포 환경을 모든 Observability 신호에 자동으로 연결할 수 있습니다: `tracingOptions.metadata.environment` on each call. ```ts export const mastra = new Mastra({ environment: 'production', observability: new Observability({ configs: { default: { serviceName: 'my-service', exporters: [new MastraStorageExporter()], }, }, }), }) ``` 만약에`environment` isn't set, Mastra falls back to `process.env.NODE_ENV`. 둘 다 설정되지 않으면 값을 추측하지 않고 필드를 정의되지 않은 상태로 둡니다. 통화별`tracingOptions.metadata.environment` 가 항상 우선하므로 필요할 때 개별 호출에서 값을 재정의할 수 있습니다. ### 다음의 자동 메타데이터`RequestContext` 각 범위에 메타데이터를 수동으로 추가하는 대신, RequestContext에서 자동으로 값을 추출하고 이를 추적의 모든 범위에 메타데이터로 첨부하도록 Mastra를 구성할 수 있습니다. 이는 전체 추적에서 사용자 식별자, 환경 정보, 기능 플래그 또는 요청 범위 데이터를 일관되게 추적하는 데 유용합니다. #### 구성 수준 추출 추적 구성에서 추출할 RequestContext 키를 정의하십시오. 이러한 키는 이 구성으로 생성된 모든 스팬의 메타데이터로 자동으로 포함됩니다. ```ts export const mastra = new Mastra({ observability: new Observability({ configs: { default: { serviceName: 'my-service', requestContextKeys: ['userId', 'environment', 'tenantId'], exporters: [new MastraStorageExporter()], }, }, }), }) ``` 이제 RequestContext를 사용하여 Agent나 Workflow를 실행하면 다음 값이 자동으로 추출됩니다. ```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, }) ``` #### 요청별 추가 다음을 사용하여 트레이스별 키를 추가할 수 있습니다.`tracingOptions.requestContextKeys`. These are merged with the configuration-level keys: ```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 ``` #### 중첩된 값 추출 점 표기법을 사용하여 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' } } } ``` #### 작동 원리 1. **TraceState 계산**: 추적 시작(루트 범위 생성) 시 Mastra는 구성 수준 키와 요청별 키를 병합하여 추출할 키를 계산합니다. 2. **자동 추출**: 루트 범위(Agent 실행, Workflow 실행)는 RequestContext에서 자동으로 메타데이터를 추출합니다. 3. **하위 범위 추출**: 하위 스팬도 통과하면 메타데이터를 추출할 수 있습니다.`requestContext` when creating them 4. **메타데이터 우선순위**: 범위 옵션에 전달된 명시적 메타데이터는 항상 추출된 메타데이터보다 우선합니다. ### 추적에 태그 추가 태그는 추적을 분류하고 필터링하는 데 도움이 되는 문자열 레이블입니다. 구조화된 키-값 데이터가 포함된 메타데이터와 달리 태그는 빠른 필터링 및 구성을 위해 설계된 일반 문자열입니다. 사용`tracingOptions.tags` 를 사용하여 Agent 또는 Workflow를 실행할 때 태그를 추가하세요: ```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'], }, }) ``` #### 태그 작동 방식 - **루트 범위만**: 태그는 추적의 루트 범위(Agent 실행 또는 Workflow 실행 범위)에만 적용됩니다. - **널리 지원됨**: 추적 필터링 및 검색을 위해 대부분의 내보내기 프로그램에서 태그를 지원합니다. - **브레인트러스트**: 토종의`tags` field - **랭퓨즈**: 토종의`tags` field on traces - **Arize수출업체**: `tag.tags` OpenInference attribute - **오텔엑스포터**: `mastra.tags` span attribute - **오텔브릿지**: `mastra.tags` span attribute - **메타데이터와 결합 가능**: 둘 다 사용할 수 있습니다`tags` and `metadata` in the same `tracingOptions` ```ts const result = await agent.generate([{ role: 'user', content: 'Analyze this' }], { tracingOptions: { tags: ['production', 'analytics'], metadata: { userId: 'user-123', experimentId: 'exp-456' }, }, }) ``` #### 일반적인 태그 패턴 - **환경**: `"production"`, `"staging"`, `"development"` - **기능 플래그**: `"feature-x-enabled"`, `"beta-user"` - **요청 유형**: `"user-request"`, `"batch-job"`, `"scheduled-task"` - **우선순위 수준**: `"priority-high"`, `"priority-low"` - **실험**: `"experiment-v1"`, `"control-group"`, `"treatment-a"` ### 민감한 입력/출력 숨기기 민감한 데이터를 처리할 때 입력 및 출력 값이 관찰 플랫폼에 기록되지 않도록 할 수 있습니다. 사용`hideInput` and `hideOutput` in `tracingOptions` 를 사용하여 Trace의 모든 Span에서 이 데이터를 제외하세요: ```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, }, }) ``` #### 작동 원리 - **추적 범위 효과**: 루트 범위에 설정된 경우 이러한 옵션은 추적의 모든 하위 범위(Tool 호출, Model 생성 등)에 적용됩니다. - **내보내기 시간 필터링**: 데이터는 실행 중에 내부적으로 사용 가능하지만 범위를 관측 플랫폼으로 내보낼 때 제외됩니다. - **다른 옵션과 결합 가능**: 당신은 사용할 수 있습니다`hideInput`/`hideOutput` alongside `tags`, `metadata`, and other `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' }, }, }) ``` 민감한 데이터를 보다 세밀하게 제어하려면 다음을 사용하는 것이 좋습니다.[Sensitive Data Filter](https://mastra.zisheng.pro/ko/docs/observability/integrations/processors/sensitive-data-filter) 프로세서를 사용하면 입력/출력의 나머지 부분은 보존하면서 특정 필드(예: 비밀번호, 토큰, 키)를 마스킹할 수 있습니다. #### 하위 범위 및 메타데이터 추출 Tool 또는 Workflow 단계 내에서 하위 범위를 생성할 때 다음을 전달할 수 있습니다.`requestContext` parameter to enable metadata extraction: ```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 } ``` RequestContext 메타데이터를 포함하는 하위 범위를 세밀하게 제어할 수 있습니다. 루트 범위(Agent/Workflow 실행)는 항상 메타데이터를 자동으로 추출하는 반면, 하위 범위는 명시적으로 전달하는 경우에만 추출합니다.`requestContext`. ## 하위 범위 만들기 하위 범위를 사용하면 Workflow 단계 또는 Tool 내에서 세분화된 작업을 추적할 수 있습니다. 데이터베이스 쿼리, API 호출, 파일 작업 또는 복잡한 계산과 같은 하위 작업에 대한 가시성을 제공합니다. 이 계층 구조는 성능 병목 현상을 식별하고 정확한 작업 순서를 이해하는 데 도움이 됩니다. 특정 작업을 추적하려면 Tool 호출 또는 Workflow 단계 내에서 하위 범위를 만듭니다. ```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 } } ``` 하위 범위는 상위로부터 추적 컨텍스트를 자동으로 상속하여 Observability 플랫폼에서 관계 계층 구조를 유지합니다. ## 범위 형식화 Mastra는 관측 가능성 플랫폼에 도달하기 전에 범위 데이터를 변환하는 두 가지 방법을 제공합니다.**span processors** and **custom span formatters**. 둘 다 Trace 데이터를 수정하거나 필터링하거나 보강할 수 있지만, 서로 다른 수준에서 작동하며 용도도 다릅니다. | 기능 | 스팬 프로세서 | 사용자 정의 범위 포맷터 | | ------ | ---------------- | --------------------------- | | 구성 수준 | Observability 구성 | 수출자별 | | 작동 | 내부`Span` object | Exported `ExportedSpan` 데이터 | | 적용 대상 | 모든 익스포터 | 단일 익스포터 | | 비동기 지원 | 아니요 | 예 | | 사용 사례 | 보안, 필터링, 보강 | 플랫폼별 서식 지정, 비동기 보강 | 사용**span processors** 를 사용하면 모든 익스포터에 적용해야 하는 동기식 변환(예: 민감한 데이터 마스킹)을 수행할 수 있습니다. 다음을 사용하세요: **custom span formatters** 서로 다른 익스포터에서 같은 데이터를 다르게 표현해야 하거나(예: 한 플랫폼에는 일반 텍스트, 다른 플랫폼에는 구조화된 데이터), 외부 API에서 데이터를 가져오는 것과 같은 비동기 작업을 수행해야 할 때 사용하세요. ### 스팬 프로세서 Span 프로세서는 추적 데이터를 내보내기 전에 변환, 필터링 또는 강화합니다. 범위 생성과 내보내기 사이의 파이프라인 역할을 하여 보안, 규정 준수 또는 디버깅 목적으로 범위를 수정할 수 있습니다. 프로세서는 한 번 실행되고 모든 내보내기에 영향을 줍니다. #### 내장 프로세서 - [민감한 데이터 필터](https://mastra.zisheng.pro/ko/docs/observability/integrations/processors/sensitive-data-filter)민감한 정보를 수정합니다. 기본 Observability 구성에서 활성화되어 있습니다. #### 맞춤형 프로세서 만들기 다음을 구현하여 사용자 정의 범위 프로세서를 생성할 수 있습니다.`SpanOutputProcessor` 인터페이스입니다. 다음은 Span의 모든 입력 텍스트를 소문자로 변환하는 기본 예제입니다: ```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()], }, }, }), }) ``` 프로세서는 정의된 순서대로 실행되므로 여러 변환을 연결할 수 있습니다. 일반적인 사용 사례는 다음과 같습니다. - 민감한 데이터 수정(비밀번호, 토큰, API 키) - 환경별 메타데이터 추가 - 기준에 따라 범위 필터링 - 데이터 형식 정규화 - 비즈니스 컨텍스트로 범위 강화 더 광범위한 내보내기, 브리지 및 프로세서 Model에 대해서는 다음을 참조하세요.[Integrations overview](https://mastra.zisheng.pro/ko/docs/observability/integrations/overview). ## 스팬 필터링 범위 필터링을 사용하면 데이터가 관측 플랫폼에 도달하기 전에 노이즈와 범위당 비용을 줄일 수 있습니다. Observability 인스턴스별로 구성하여 다양한 내보내기 또는 환경에서 다양한 세부 수준을 유지할 수 있습니다. - 사용`excludeSpanTypes` 를 사용하면 최소한의 구성으로 Span의 전체 범주를 제외할 수 있습니다. - 사용`spanFilter` 내보낸 Span 데이터를 기반으로 사용자 지정 로직이 필요할 때 사용하세요. 다음 예에서는 단일 구성에서 두 옵션을 결합하는 방법을 보여줍니다. ```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 }, }, }, }), }) ``` 필터링은 내보내기 시 다음 순서로 발생합니다. 1. 다음을 제외하면 내부 스팬은 삭제됩니다.`includeInternalSpans` is `true`. 2. `excludeSpanTypes`일치하는 범위 유형을 제거합니다. 3. `spanOutputProcessors`나머지 범위를 변환합니다. 4. `spanFilter`최종 내보낸 범위를 유지할지 여부를 결정합니다. 만약에`spanFilter` 에서 예외가 발생하면 Mastra는 데이터가 조용히 손실되는 것을 방지하기 위해 Span을 유지하고 오류를 기록합니다. 전체 Span 유형 목록과 추가 예제는 다음을 참조하세요: [Span filtering reference](https://mastra.zisheng.pro/ko/reference/observability/tracing/span-filtering). ### 사용자 정의 범위 포맷터 사용자 정의 범위 포맷터는 특정 관측 플랫폼에서 범위가 표시되는 방식을 변환합니다. 스팬 프로세서와 달리 포맷터는 내보내기별로 구성되므로 대상마다 다른 형식을 지정할 수 있습니다. 포맷터는 동기 및 비동기 작업을 모두 지원합니다. #### 사용 사례 - **AI SDK 메시지에서 일반 텍스트 추출**: 구조화된 메시지 배열을 읽을 수 있는 텍스트로 변환합니다. - **입력/출력 형식 변환**: 특정 플랫폼에서 데이터가 표시되는 방식을 사용자 정의합니다. - **플랫폼별 필드 매핑**: 플랫폼 요구 사항에 따라 필드를 추가하거나 제거합니다. - **비동기 데이터 강화**: 외부 API 또는 데이터베이스에서 추가 컨텍스트를 가져옵니다. #### 구성 추가`customSpanFormatter` to any exporter configuration: ```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(), ], }, }, }), }) ``` #### 여러 포맷터 연결 사용`chainFormatters` 를 사용하여 여러 포매터를 결합하세요. 체인은 동기 및 비동기 포매터를 모두 지원합니다: ```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]), }) ``` #### 비동기 포맷터 사용자 정의 범위 포맷터는 비동기 작업을 지원하므로 외부 API 또는 데이터베이스에서 데이터를 가져오는 등의 사용 사례를 통해 범위를 강화할 수 있습니다. ```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 ]), }) ``` :::참고 비동기 포맷터는 범위 내보내기에 대기 시간을 추가합니다. 애플리케이션 속도가 느려지는 것을 방지하려면 비동기 작업을 빠르게(100ms 미만) 유지하세요. 자주 액세스하는 데이터에는 캐싱을 사용하는 것이 좋습니다. ::: ## 직렬화 옵션 직렬화 옵션은 내보내기 전에 범위 데이터(입력, 출력 및 속성)가 잘리는 방법을 제어합니다. 이는 큰 페이로드, 깊게 중첩된 개체로 작업할 때 또는 추적 저장소를 최적화해야 할 때 유용합니다. ### 구성 추가하다`serializationOptions` to your observability configuration: ```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()], }, }, }), }) ``` ### 사용 가능한 옵션 | 옵션 | 기본값 | 설명 | | ----------------- | ---- | --------------------------------- | | `maxStringLength` | 1024 | 문자열 값의 최대 길이입니다. 더 긴 문자열은 잘립니다. | | `maxDepth` | 6 | 중첩된 객체의 최대 깊이입니다. 더 깊은 수준은 생략됩니다. | | `maxArrayLength` | 50 | 배열의 최대 항목 수입니다. 추가 항목은 생략됩니다. | | `maxObjectKeys` | 50 | 객체의 최대 키 수입니다. 추가 키는 생략됩니다. | ### 사용 사례 **디버깅 한도 증가**: Agent나 Tool이 대용량 문서, API 응답 또는 데이터 구조를 사용하는 경우 추적에서 더 많은 컨텍스트를 캡처하려면 다음 한도를 늘리세요. ```ts serializationOptions: { maxStringLength: 8192, // Capture longer text content maxDepth: 12, // Handle deeply nested JSON responses maxArrayLength: 200, // Keep more items from large lists } ``` **생산을 위한 추적 크기 줄이기**: 전체 페이로드 가시성이 필요하지 않은 경우 스토리지 비용을 줄이고 성능을 향상시키려면 이러한 값을 낮추십시오. ```ts serializationOptions: { maxStringLength: 256, // Truncate strings aggressively maxDepth: 3, // Shallow object representation maxArrayLength: 10, // Keep only first few items maxObjectKeys: 20, // Limit object keys } ``` 모든 옵션은 선택 사항이며, 지정하지 않으면 위에 표시된 기본값으로 돌아갑니다. ## 추적 ID 검색 추적이 활성화된 상태에서 Agent 또는 Workflow를 실행하면 응답에 다음이 포함됩니다.`traceId` 를 사용하면 Observability 플랫폼에서 전체 Trace를 조회할 수 있습니다. 이는 디버깅이나 고객 지원 또는 Trace를 시스템의 다른 이벤트와 연관 짓는 데 유용합니다. ### Agent 추적 ID 둘 다`generate` and `stream` 메서드는 응답에 Trace ID를 반환합니다: ```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) ``` ### Workflow 추적 ID Workflow 실행은 추적 ID도 반환합니다. ```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) ``` ### 추적 ID 사용 추적 ID가 있으면 다음을 수행할 수 있습니다. 1. **Studio에서 추적 조회**: 추적 보기로 이동하여 ID로 검색합니다. 2. **외부 플랫폼의 쿼리 추적**: Langfuse, Braintrust, MLflow 또는 관찰 플랫폼에서 ID를 사용합니다. 3. **로그와 연관**: 상호 참조를 위해 애플리케이션 로그에 추적 ID를 포함합니다. 4. **디버깅을 위해 공유**: 조사를 위해 지원팀이나 개발자에게 추적 ID를 제공합니다. 추적 ID는 추적이 활성화된 경우에만 사용할 수 있습니다. 추적이 비활성화되거나 샘플링이 요청을 제외하는 경우`traceId` will be `undefined`. ## 외부 추적 시스템과 통합 기존 분산 추적(OpenTelemetry, Datadog 등)이 있는 애플리케이션 내에서 Mastra Agent 또는 Workflow를 실행할 때 Mastra 추적을 상위 추적 컨텍스트에 연결할 수 있습니다. 이를 통해 전체 요청 흐름에 대한 통합 보기가 생성되어 Mastra 운영이 더 넓은 시스템에 어떻게 적용되는지 더 쉽게 이해할 수 있습니다. ### 외부 추적 ID 전달 사용`tracingOptions` 매개변수를 사용하여 상위 시스템의 Trace 컨텍스트를 지정하세요: ```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 ``` ### OpenTelemetry 통합 OpenTelemetry와 통합하면 Mastra 추적을 기존 관찰 플랫폼에 직접 표시할 수 있습니다. ```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, }, }) } ``` ### Workflow 통합 Workflow는 추적 전파에 대해 동일한 패턴을 지원합니다. ```ts const workflow = mastra.getWorkflow('data-pipeline') const run = await workflow.createRun() const result = await run.start({ inputData: { data: '...' }, tracingOptions: { traceId: externalTraceId, parentSpanId: externalSpanId, }, }) ``` ### ID 형식 요구 사항 Mastra는 호환성을 보장하기 위해 추적 및 범위 ID를 검증합니다. - **추적 ID**: 1-32개의 16진수 문자(OpenTelemetry에서는 32자를 사용함) - **스팬 ID**: 1-16개의 16진수 문자(OpenTelemetry에서는 16자를 사용함) 잘못된 ID는 정상적으로 처리되며 Mastra는 오류를 기록하고 계속됩니다. - 잘못된 추적 ID → 새 추적 ID 생성 - 잘못된 상위 스팬 ID → 상위 관계를 무시합니다. 결과적으로 잘못된 입력이 있어도 추적으로 인해 애플리케이션이 충돌하지 않습니다. ### 예: Express 미들웨어 다음은 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) }) ``` 그러면 선택한 관찰 플랫폼에서 볼 수 있는 HTTP 요청 처리와 Mastra Agent 실행을 모두 포함하는 단일 분산 추적이 생성됩니다. ## 추적되는 내용 Mastra는 다음에 대한 범위를 자동으로 생성합니다. ### Agent 작업 - **Agent 실행**: 지침과 Tool을 사용하여 완벽한 실행 - **LLM 통화**: 토큰 및 매개변수와의 Model 상호작용 - **Tool 실행**: 입력과 출력이 포함된 함수 호출 - **Memory 작업**: 스레드 및 의미적 회상 ### Workflow 작업 - **Workflow 실행**: 처음부터 끝까지 전체 실행 - **개별 단계**: 입력/출력을 통한 단계 처리 - **제어 흐름**: 조건부, 루프, 병렬 실행 - **대기 작업**: 지연 및 이벤트 대기 ## 또한보십시오 ### 참조 문서 - [구성 API](https://mastra.zisheng.pro/ko/reference/observability/tracing/configuration): ObservabilityConfig 세부정보 - [추적 클래스](https://mastra.zisheng.pro/ko/reference/observability/tracing/instances): 핵심 클래스 및 메소드 - [스팬 인터페이스](https://mastra.zisheng.pro/ko/reference/observability/tracing/spans): Span 유형 및 수명주기 - [유형 정의](https://mastra.zisheng.pro/ko/reference/observability/tracing/interfaces): 완전한 인터페이스 참조 - [스팬 필터링](https://mastra.zisheng.pro/ko/reference/observability/tracing/span-filtering): 필터링 동작 및 범위 유형과 예시