Harbor
Monitoring

Mastra

Add Harbor as an exporter in Mastra's observability config.

Mastra runs its own observability pipeline rather than emitting OpenTelemetry directly, so Harbor joins it as an exporter. There is no tracer provider to register and no Harbor client to construct.

Install

npm install harbor-ai-sdk @mastra/otel-exporter

@mastra/otel-exporter converts Mastra's spans to the OpenTelemetry GenAI conventions Harbor ingests. It is an optional peer dependency, so it is only needed for this integration.

Set up

src/mastra/index.ts
import { Mastra } from '@mastra/core/mastra'
import { SpanType } from '@mastra/core/observability'
import {
  MastraStorageExporter,
  Observability,
  SensitiveDataFilter,
} from '@mastra/observability'
import { HarborExporter } from 'harbor-ai-sdk/mastra'
import { agent } from './agents/agent'

export const mastra = new Mastra({
  agents: { agent },
  observability: new Observability({
    configs: {
      harbor: {
        serviceName: 'support-agent',
        exporters: [new MastraStorageExporter(), new HarborExporter()],
        excludeSpanTypes: [SpanType.MODEL_CHUNK],
        spanOutputProcessors: [new SensitiveDataFilter()],
      },
    },
  }),
})

That is the whole integration. HarborExporter reads HARBOR_API_KEY and HARBOR_BASE_URL from the environment, and takes the same options explicitly if you load configuration some other way.

What you get

Agent runs, model calls and tool calls arrive as one nested trace, carrying model, provider, token usage, messages, tool definitions and tool arguments. Mastra's own identifiers map onto Harbor's concepts without any work on your side:

MastraHarbor
threadIdsession — reuse it and turns stitch into one conversation
resourceIduser.id
agent namegen_ai.agent.name

Choices worth making

Keep MastraStorageExporter if you want traces in Mastra Studio as well as Harbor. It is what fills Studio's own trace view, and it is independent of Harbor.

Set excludeSpanTypes. Mastra emits one span per streamed chunk. Those spans carry nothing Harbor reads and roughly double the span count of a short turn, so dropping SpanType.MODEL_CHUNK costs nothing and saves a lot of volume.

SensitiveDataFilter redacts sensitive fields before export. Mastra applies one automatically if you do not, but naming it keeps the behaviour visible.

The config key — harbor above — is a label, not a keyword: the first entry is the default regardless of its name. Additional backends belong in the same config's exporters array. A second config is for routing between environments and requires a configSelector.

Mastra puts the provider's entire HTTP response and its response headers in span metadata. Harbor keeps both out of a trace's metadata for size and safety, but they still arrive as raw span attributes — worth excluding at the source if response headers are sensitive in your environment.

On this page