본문으로 건너뛰기

트레이싱

추적은 요청이 Agent, Workflow, Tool 및 Model 호출을 통해 이동하는 방식을 기록하는 Observability 신호입니다. Mastra는 각 작업을 범위로 나타내고 관련 범위를 추적으로 그룹화하므로 전체 실행 경로를 검사할 수 있습니다.

이 페이지에서는 범위 계층 구조, 샘플링, 메타데이터, 필터링, 추적 ID, 타사 추적 컨텍스트 등 추적 관련 개념에 중점을 둡니다.

추적을 사용해야 하는 경우
추적을 사용해야 하는 경우에 대한 직접 링크

  • 전체 실행 경로를 검사하여 예기치 않은 Agent 또는 Workflow 동작을 디버그합니다.
  • 단일 요청 내에서 Model 호출, Tool 호출 및 Workflow 단계를 따르세요.
  • 필터링 및 조사를 위해 추적별 메타데이터와 태그를 첨부합니다.
  • Mastra 추적을 타사 추적 시스템에 연결합니다.

시작하기
시작하기에 대한 직접 링크

추적을 시작하려면 Mastra 인스턴스에서 Observability을 구성하고 Agent 또는 Workflow를 실행하세요. 다음 기능을 통해 동작을 구성할 수 있습니다.

  • 구성: 기본 관측성 구성 및 다중 구성과 서버리스 플러싱
  • 저장: 추적, 로그, 측정항목에 대한 스토리지 라우팅
  • 통합 개요: 수출업자, 교량, 가공업자

샘플링 전략
샘플링 전략에 대한 직접 링크

샘플링을 사용하면 수집되는 추적을 제어하여 Observability 요구 사항과 리소스 비용 간의 균형을 맞추는 데 도움이 됩니다.

트래픽이 많은 프로덕션 환경에서는 모든 추적을 수집하는 데 비용이 많이 들고 불필요할 수 있습니다.

샘플링 전략을 사용하면 트레이스의 대표적인 하위 집합을 캡처하는 동시에 오류나 중요한 작업에 대한 중요한 정보를 놓치지 않도록 할 수 있습니다.

관측 가능성 구성 수준에서 샘플링을 구성할 수 있습니다.

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

그만큼sampling 옵션을 사용하면 수집할 Trace를 제어하여 Observability 요구 사항과 리소스 비용 사이의 균형을 맞출 수 있습니다. Mastra는 네 가지 샘플링 전략을 지원합니다:

  1. 항상 샘플링: 흔적을 100% 수집합니다. 완전한 가시성이 필요한 개발, 디버깅 또는 트래픽이 적은 시나리오에 가장 적합합니다.

    sampling: {
    type: 'always'
    }
  2. 샘플링하지 않음: 추적을 완전히 비활성화합니다. 추적이 가치를 추가하지 않거나 구성을 제거하지 않고 추적을 일시적으로 비활성화해야 하는 특정 환경에 유용합니다.

    sampling: {
    type: 'never'
    }
  3. 비율 기반 샘플링: 트레이스의 일정 비율을 무작위로 샘플링합니다. 전체 추적 비용 없이 통계적 통찰력을 원하는 프로덕션 환경에 이상적입니다. 확률 값의 범위는 0(추적 없음)부터 1(모든 추적)까지입니다.

    sampling: {
    type: 'ratio',
    probability: 0.1 // Sample 10% of traces
    }
  4. 맞춤 샘플링: 요청 컨텍스트, 메타데이터 또는 비즈니스 규칙을 기반으로 자체 샘플링 논리를 구현합니다. 사용자 계층, 요청 유형 또는 오류 조건을 기반으로 한 샘플링과 같은 복잡한 시나리오에 적합합니다.

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

커스텀 메타데이터 추가
커스텀 메타데이터 추가에 대한 직접 링크

사용자 정의 메타데이터를 사용하면 추적에 추가 컨텍스트를 첨부할 수 있으므로 문제를 더 쉽게 디버깅하고 프로덕션에서 시스템 동작을 이해할 수 있습니다.

메타데이터에는 비즈니스 논리와 성능 지표가 포함될 수 있습니다. 또한 실행 중에 발생한 일을 설명하는 사용자 컨텍스트나 기타 정보를 전달할 수도 있습니다.

추적 컨텍스트를 사용하여 모든 범위에 메타데이터를 추가할 수 있습니다.

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.

src/mastra/index.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
automatic-metadata-from-requestcontext에 대한 직접 링크

각 범위에 메타데이터를 수동으로 추가하는 대신, RequestContext에서 자동으로 값을 추출하고 이를 추적의 모든 범위에 메타데이터로 첨부하도록 Mastra를 구성할 수 있습니다. 이는 전체 추적에서 사용자 식별자, 환경 정보, 기능 플래그 또는 요청 범위 데이터를 일관되게 추적하는 데 유용합니다.

구성 수준 추출
구성 수준 추출에 대한 직접 링크

추적 구성에서 추출할 RequestContext 키를 정의하십시오. 이러한 키는 이 구성으로 생성된 모든 스팬의 메타데이터로 자동으로 포함됩니다.

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

이제 RequestContext를 사용하여 Agent나 Workflow를 실행하면 다음 값이 자동으로 추출됩니다.

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:

const requestContext = new RequestContext()
requestContext.set('userId', 'user-123')
requestContext.set('environment', 'production')
requestContext.set('experimentId', 'exp-789')

const result = await agent.generate('Hello', {
requestContext,
tracingOptions: {
requestContextKeys: ['experimentId'], // Adds to configured keys
},
})

// All spans now have: userId, environment, AND experimentId

중첩된 값 추출
중첩된 값 추출에 대한 직접 링크

점 표기법을 사용하여 RequestContext에서 중첩된 값을 추출합니다.

export const mastra = new Mastra({
observability: new Observability({
configs: {
default: {
requestContextKeys: ['user.id', 'session.data.experimentId'],
exporters: [new MastraStorageExporter()],
},
},
}),
})

const requestContext = new RequestContext()
requestContext.set('user', { id: 'user-456', name: 'John Doe' })
requestContext.set('session', { data: { experimentId: 'exp-999' } })

// Metadata will include: { user: { id: 'user-456' }, session: { data: { experimentId: 'exp-999' } } }

작동 원리
작동 원리에 대한 직접 링크

  1. TraceState 계산: 추적 시작(루트 범위 생성) 시 Mastra는 구성 수준 키와 요청별 키를 병합하여 추출할 키를 계산합니다.
  2. 자동 추출: 루트 범위(Agent 실행, Workflow 실행)는 RequestContext에서 자동으로 메타데이터를 추출합니다.
  3. 하위 범위 추출: 하위 스팬도 통과하면 메타데이터를 추출할 수 있습니다.requestContext when creating them
  4. 메타데이터 우선순위: 범위 옵션에 전달된 명시적 메타데이터는 항상 추출된 메타데이터보다 우선합니다.

추적에 태그 추가
추적에 태그 추가에 대한 직접 링크

태그는 추적을 분류하고 필터링하는 데 도움이 되는 문자열 레이블입니다. 구조화된 키-값 데이터가 포함된 메타데이터와 달리 태그는 빠른 필터링 및 구성을 위해 설계된 일반 문자열입니다.

사용tracingOptions.tags 를 사용하여 Agent 또는 Workflow를 실행할 때 태그를 추가하세요:

// 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
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에서 이 데이터를 제외하세요:

// 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
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 프로세서를 사용하면 입력/출력의 나머지 부분은 보존하면서 특정 필드(예: 비밀번호, 토큰, 키)를 마스킹할 수 있습니다.

하위 범위 및 메타데이터 추출
하위 범위 및 메타데이터 추출에 대한 직접 링크

Tool 또는 Workflow 단계 내에서 하위 범위를 생성할 때 다음을 전달할 수 있습니다.requestContext parameter to enable metadata extraction:

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 단계 내에서 하위 범위를 만듭니다.

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 objectExported ExportedSpan 데이터
적용 대상모든 익스포터단일 익스포터
비동기 지원아니요
사용 사례보안, 필터링, 보강플랫폼별 서식 지정, 비동기 보강

사용span processors 를 사용하면 모든 익스포터에 적용해야 하는 동기식 변환(예: 민감한 데이터 마스킹)을 수행할 수 있습니다. 다음을 사용하세요: custom span formatters 서로 다른 익스포터에서 같은 데이터를 다르게 표현해야 하거나(예: 한 플랫폼에는 일반 텍스트, 다른 플랫폼에는 구조화된 데이터), 외부 API에서 데이터를 가져오는 것과 같은 비동기 작업을 수행해야 할 때 사용하세요.

스팬 프로세서
스팬 프로세서에 대한 직접 링크

Span 프로세서는 추적 데이터를 내보내기 전에 변환, 필터링 또는 강화합니다. 범위 생성과 내보내기 사이의 파이프라인 역할을 하여 보안, 규정 준수 또는 디버깅 목적으로 범위를 수정할 수 있습니다. 프로세서는 한 번 실행되고 모든 내보내기에 영향을 줍니다.

내장 프로세서
내장 프로세서에 대한 직접 링크

맞춤형 프로세서 만들기
맞춤형 프로세서 만들기에 대한 직접 링크

다음을 구현하여 사용자 정의 범위 프로세서를 생성할 수 있습니다.SpanOutputProcessor 인터페이스입니다. 다음은 Span의 모든 입력 텍스트를 소문자로 변환하는 기본 예제입니다:

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

프로세서는 정의된 순서대로 실행되므로 여러 변환을 연결할 수 있습니다. 일반적인 사용 사례는 다음과 같습니다.

  • 민감한 데이터 수정(비밀번호, 토큰, API 키)
  • 환경별 메타데이터 추가
  • 기준에 따라 범위 필터링
  • 데이터 형식 정규화
  • 비즈니스 컨텍스트로 범위 강화

더 광범위한 내보내기, 브리지 및 프로세서 Model에 대해서는 다음을 참조하세요.Integrations overview.

스팬 필터링
스팬 필터링에 대한 직접 링크

범위 필터링을 사용하면 데이터가 관측 플랫폼에 도달하기 전에 노이즈와 범위당 비용을 줄일 수 있습니다. Observability 인스턴스별로 구성하여 다양한 내보내기 또는 환경에서 다양한 세부 수준을 유지할 수 있습니다.

  • 사용excludeSpanTypes 를 사용하면 최소한의 구성으로 Span의 전체 범주를 제외할 수 있습니다.
  • 사용spanFilter 내보낸 Span 데이터를 기반으로 사용자 지정 로직이 필요할 때 사용하세요.

다음 예에서는 단일 구성에서 두 옵션을 결합하는 방법을 보여줍니다.

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

필터링은 내보내기 시 다음 순서로 발생합니다.

  1. 다음을 제외하면 내부 스팬은 삭제됩니다.includeInternalSpans is true.
  2. excludeSpanTypes일치하는 범위 유형을 제거합니다.
  3. spanOutputProcessors나머지 범위를 변환합니다.
  4. spanFilter최종 내보낸 범위를 유지할지 여부를 결정합니다.

만약에spanFilter 에서 예외가 발생하면 Mastra는 데이터가 조용히 손실되는 것을 방지하기 위해 Span을 유지하고 오류를 기록합니다. 전체 Span 유형 목록과 추가 예제는 다음을 참조하세요: Span filtering reference.

사용자 정의 범위 포맷터
사용자 정의 범위 포맷터에 대한 직접 링크

사용자 정의 범위 포맷터는 특정 관측 플랫폼에서 범위가 표시되는 방식을 변환합니다. 스팬 프로세서와 달리 포맷터는 내보내기별로 구성되므로 대상마다 다른 형식을 지정할 수 있습니다. 포맷터는 동기 및 비동기 작업을 모두 지원합니다.

사용 사례
사용 사례에 대한 직접 링크

  • AI SDK 메시지에서 일반 텍스트 추출: 구조화된 메시지 배열을 읽을 수 있는 텍스트로 변환합니다.
  • 입력/출력 형식 변환: 특정 플랫폼에서 데이터가 표시되는 방식을 사용자 정의합니다.
  • 플랫폼별 필드 매핑: 플랫폼 요구 사항에 따라 필드를 추가하거나 제거합니다.
  • 비동기 데이터 강화: 외부 API 또는 데이터베이스에서 추가 컨텍스트를 가져옵니다.

구성
구성에 대한 직접 링크

추가customSpanFormatter to any exporter configuration:

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

여러 포맷터 연결
여러 포맷터 연결에 대한 직접 링크

사용chainFormatters 를 사용하여 여러 포매터를 결합하세요. 체인은 동기 및 비동기 포매터를 모두 지원합니다:

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 또는 데이터베이스에서 데이터를 가져오는 등의 사용 사례를 통해 범위를 강화할 수 있습니다.

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:

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

사용 가능한 옵션
사용 가능한 옵션에 대한 직접 링크

옵션기본값설명
maxStringLength1024문자열 값의 최대 길이입니다. 더 긴 문자열은 잘립니다.
maxDepth6중첩된 객체의 최대 깊이입니다. 더 깊은 수준은 생략됩니다.
maxArrayLength50배열의 최대 항목 수입니다. 추가 항목은 생략됩니다.
maxObjectKeys50객체의 최대 키 수입니다. 추가 키는 생략됩니다.

사용 사례
사용 사례에 대한 직접 링크

디버깅 한도 증가: Agent나 Tool이 대용량 문서, API 응답 또는 데이터 구조를 사용하는 경우 추적에서 더 많은 컨텍스트를 캡처하려면 다음 한도를 늘리세요.

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

생산을 위한 추적 크기 줄이기: 전체 페이로드 가시성이 필요하지 않은 경우 스토리지 비용을 줄이고 성능을 향상시키려면 이러한 값을 낮추십시오.

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

모든 옵션은 선택 사항이며, 지정하지 않으면 위에 표시된 기본값으로 돌아갑니다.

추적 ID 검색
추적 ID 검색에 대한 직접 링크

추적이 활성화된 상태에서 Agent 또는 Workflow를 실행하면 응답에 다음이 포함됩니다.traceId 를 사용하면 Observability 플랫폼에서 전체 Trace를 조회할 수 있습니다. 이는 디버깅이나 고객 지원 또는 Trace를 시스템의 다른 이벤트와 연관 짓는 데 유용합니다.

Agent 추적 ID
Agent 추적 ID에 대한 직접 링크

둘 다generate and stream 메서드는 응답에 Trace ID를 반환합니다:

// Using generate
const result = await agent.generate('Hello')

console.log('Trace ID:', result.traceId)

// Using stream
const streamResult = await agent.stream('Tell me a story')

console.log('Trace ID:', streamResult.traceId)

Workflow 추적 ID
Workflow 추적 ID에 대한 직접 링크

Workflow 실행은 추적 ID도 반환합니다.

// 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 사용에 대한 직접 링크

추적 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 전달
외부 추적 ID 전달에 대한 직접 링크

사용tracingOptions 매개변수를 사용하여 상위 시스템의 Trace 컨텍스트를 지정하세요:

// Get trace context from your existing tracing system
const parentTraceId = getCurrentTraceId() // Your tracing system
const parentSpanId = getCurrentSpanId() // Your tracing system

// Execute Mastra operations as part of the parent trace
const result = await agent.generate('Analyze this data', {
tracingOptions: {
traceId: parentTraceId,
parentSpanId: parentSpanId,
},
})

// The Mastra trace will now appear as a child in your distributed trace

OpenTelemetry 통합
OpenTelemetry 통합에 대한 직접 링크

OpenTelemetry와 통합하면 Mastra 추적을 기존 관찰 플랫폼에 직접 표시할 수 있습니다.

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 통합에 대한 직접 링크

Workflow는 추적 전파에 대해 동일한 패턴을 지원합니다.

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

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

ID 형식 요구 사항
ID 형식 요구 사항에 대한 직접 링크

Mastra는 호환성을 보장하기 위해 추적 및 범위 ID를 검증합니다.

  • 추적 ID: 1-32개의 16진수 문자(OpenTelemetry에서는 32자를 사용함)
  • 스팬 ID: 1-16개의 16진수 문자(OpenTelemetry에서는 16자를 사용함)

잘못된 ID는 정상적으로 처리되며 Mastra는 오류를 기록하고 계속됩니다.

  • 잘못된 추적 ID → 새 추적 ID 생성
  • 잘못된 상위 스팬 ID → 상위 관계를 무시합니다.

결과적으로 잘못된 입력이 있어도 추적으로 인해 애플리케이션이 충돌하지 않습니다.

예: Express 미들웨어
예: Express 미들웨어에 대한 직접 링크

다음은 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)
})

그러면 선택한 관찰 플랫폼에서 볼 수 있는 HTTP 요청 처리와 Mastra Agent 실행을 모두 포함하는 단일 분산 추적이 생성됩니다.

추적되는 내용
추적되는 내용에 대한 직접 링크

Mastra는 다음에 대한 범위를 자동으로 생성합니다.

Agent 작업
Agent 작업에 대한 직접 링크

  • Agent 실행: 지침과 Tool을 사용하여 완벽한 실행
  • LLM 통화: 토큰 및 매개변수와의 Model 상호작용
  • Tool 실행: 입력과 출력이 포함된 함수 호출
  • Memory 작업: 스레드 및 의미적 회상

Workflow 작업
Workflow 작업에 대한 직접 링크

  • Workflow 실행: 처음부터 끝까지 전체 실행
  • 개별 단계: 입력/출력을 통한 단계 처리
  • 제어 흐름: 조건부, 루프, 병렬 실행
  • 대기 작업: 지연 및 이벤트 대기

또한보십시오
또한보십시오에 대한 직접 링크

참조 문서
참조 문서에 대한 직접 링크