PinoLogger
A Logger instance is created using new PinoLogger() and provides methods to record events at various severity levels.
When deploying to Mastra Cloud, logs are displayed on the Logs page. In self-hosted or custom environments, logs can be directed to files or external services depending on the configured transports.
Usage exampleDirect link to Usage example
import { Mastra } from '@mastra/core'
import { PinoLogger } from '@mastra/loggers'
export const mastra = new Mastra({
logger: new PinoLogger({
name: 'Mastra',
level: 'info',
}),
})
ParametersDirect link to Parameters
name:
level:
transports:
overrideDefaultTransports?:
formatters?:
redact?:
prettyPrint?:
mixin?:
customLevels?:
Log enrichment with mixinDirect link to log-enrichment-with-mixin
Use mixin when you want the same structured fields on every line (for correlation with the rest of your services):
import { Mastra } from '@mastra/core'
import { PinoLogger } from '@mastra/loggers'
function getTraceContext() {
return { traceId: 'abc-123' }
}
export const mastra = new Mastra({
logger: new PinoLogger({
name: 'Mastra',
level: 'info',
mixin() {
return getTraceContext()
},
}),
})
Custom levelsDirect link to Custom levels
customLevels is passed through to Pino. PinoLogger only exposes debug, info, warn, and error; for any extra level name (for example audit), subclass and forward to the underlying Pino instance:
import { Mastra } from '@mastra/core'
import { PinoLogger } from '@mastra/loggers'
type AuditLevel = 'audit'
class MastraPinoWithAudit extends PinoLogger<AuditLevel> {
audit(message: string, meta: Record<string, unknown> = {}) {
this.logger.audit(meta, message)
}
}
const logger = new MastraPinoWithAudit({
name: 'Mastra',
level: 'info',
customLevels: { audit: 35 },
})
export const mastra = new Mastra({ logger })
Numeric values follow Pino’s ordering (built-in levels use 10–60). A level of 35 sits between info (30) and warn (40), so with level: 'info' both info and audit lines are emitted.
File transport (structured logs)Direct link to File transport (structured logs)
Writes structured logs to a file using the FileTransport. The logger accepts a plain message as the first argument and structured metadata as the second argument. These are internally converted to a BaseLogMessage and persisted to the configured file path.
import { FileTransport } from '@mastra/loggers/file'
import { PinoLogger } from '@mastra/loggers/pino'
export const fileLogger = new PinoLogger({
name: 'Mastra',
transports: { file: new FileTransport({ path: 'test-dir/test.log' }) },
level: 'warn',
})
File transport usageDirect link to File transport usage
fileLogger.warn('Low disk space', {
destinationPath: 'system',
type: 'WORKFLOW',
})
Upstash transport (remote log drain)Direct link to Upstash transport (remote log drain)
Streams structured logs to a remote Redis list using the UpstashTransport. The logger accepts a string message and a structured metadata object. This enables centralized logging for distributed environments, supporting filtering by destinationPath, type, and runId.
import { UpstashTransport } from '@mastra/loggers/upstash'
import { PinoLogger } from '@mastra/loggers/pino'
export const upstashLogger = new PinoLogger({
name: 'Mastra',
transports: {
upstash: new UpstashTransport({
listName: 'production-logs',
upstashUrl: process.env.UPSTASH_URL!,
upstashToken: process.env.UPSTASH_TOKEN!,
}),
},
level: 'info',
})
Upstash transport usageDirect link to Upstash transport usage
upstashLogger.info('User signed in', {
destinationPath: 'auth',
type: 'AGENT',
runId: 'run_123',
})
Custom transportDirect link to Custom transport
You can create custom transports using the createCustomTransport utility to integrate with any logging service or stream.
Sentry transport exampleDirect link to Sentry transport example
Creates a custom transport using createCustomTransport and integrates it with a third-party logging stream such as pino-sentry-transport. This allows forwarding logs to an external system like Sentry for advanced monitoring and observability.
import { createCustomTransport } from '@mastra/core/loggers'
import { PinoLogger } from '@mastra/loggers/pino'
import pinoSentry from 'pino-sentry-transport'
const sentryStream = await pinoSentry({
sentry: {
dsn: 'YOUR_SENTRY_DSN',
_experiments: {
enableLogs: true,
},
},
})
const customTransport = createCustomTransport(sentryStream)
export const sentryLogger = new PinoLogger({
name: 'Mastra',
level: 'info',
transports: { sentry: customTransport },
})