@mastra/loggers 1.3.1-alpha.1 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/reference-core-mastra-class.md +1 -1
- package/dist/docs/references/reference-logging-pino-logger.md +2 -0
- package/dist/index.cjs +5 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/pino.d.ts +8 -0
- package/dist/pino.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/docs/SKILL.md
CHANGED
|
@@ -125,7 +125,7 @@ Visit the [Configuration reference](https://mastra.ai/reference/configuration) f
|
|
|
125
125
|
|
|
126
126
|
**backgroundTasks.defaultRetries** (`RetryConfig`): Default retry configuration.
|
|
127
127
|
|
|
128
|
-
**scheduler** (`object`): Configure the scheduler worker for cron-driven workflow triggers. Auto-enables when any workflow declares a schedule. See Scheduled workflows.
|
|
128
|
+
**scheduler** (`object`): Configure the scheduler worker for cron-driven workflow triggers. Auto-enables when any workflow declares a schedule, when schedule rows already exist in storage, or when a schedule is created at runtime. Apps that never schedule anything run one listSchedules() check at boot and never poll after that. See Scheduled workflows.
|
|
129
129
|
|
|
130
130
|
**scheduler.enabled** (`boolean`): Explicitly enable or disable the scheduler.
|
|
131
131
|
|
|
@@ -40,6 +40,8 @@ export const mastra = new Mastra({
|
|
|
40
40
|
|
|
41
41
|
**customLevels** (`Record<string, number>`): Custom log levels and numeric values, forwarded to Pino. Standard severity is still logged via debug, info, warn, and error; extra levels follow Pino’s custom-level behavior.
|
|
42
42
|
|
|
43
|
+
**serializers** (`pino.LoggerOptions['serializers']`): Custom Pino serializers, merged over the defaults. By default the error key uses Pino’s standard error serializer (alongside the built-in err), so logger.warn("...", { error }) records the type, message, and stack instead of an empty object.
|
|
44
|
+
|
|
43
45
|
## Log enrichment with `mixin`
|
|
44
46
|
|
|
45
47
|
Use `mixin` when you want the same structured fields on every line (for correlation with the rest of your services):
|
package/dist/index.cjs
CHANGED
|
@@ -70,7 +70,11 @@ var PinoLogger = class PinoLogger extends _mastra_core_logger.MastraLogger {
|
|
|
70
70
|
redact: options.redact,
|
|
71
71
|
mixin: correlationMixin,
|
|
72
72
|
customLevels: options.customLevels,
|
|
73
|
-
messageKey: options.messageKey ?? "msg"
|
|
73
|
+
messageKey: options.messageKey ?? "msg",
|
|
74
|
+
serializers: {
|
|
75
|
+
error: pino.default.stdSerializers.err,
|
|
76
|
+
...options.serializers
|
|
77
|
+
}
|
|
74
78
|
}, options.overrideDefaultTransports ? options?.transports?.default : transportsAry.length === 0 ? prettyStream : pino.default.multistream([...transportsAry.map(([, transport]) => ({
|
|
75
79
|
stream: transport,
|
|
76
80
|
level: options.level || _mastra_core_logger.LogLevel.INFO
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["MastraLogger","#adapterContextRef","LogLevel","#export"],"sources":["../src/pino.ts"],"sourcesContent":["import type { LoggerTransport, LoggerAdapterContext } from '@mastra/core/logger';\nimport { LogLevel, MastraLogger, buildLogRecordData, exportTrackedException } from '@mastra/core/logger';\nimport pino from 'pino';\nimport pretty from 'pino-pretty';\n\ntype TransportMap = Record<string, LoggerTransport>;\n\nexport type { LogLevel } from '@mastra/core/logger';\n\nexport interface PinoLoggerOptions<CustomLevels extends string = never> {\n name?: string;\n level?: LogLevel;\n transports?: TransportMap;\n overrideDefaultTransports?: boolean;\n formatters?: pino.LoggerOptions['formatters'];\n redact?: pino.LoggerOptions['redact'];\n mixin?: pino.MixinFn<CustomLevels>;\n customLevels?: { [level in CustomLevels]: number };\n /**\n * When false, disables pino-pretty and outputs raw JSON.\n * Useful when sending logs to aggregators like Datadog,\n * Loki, or CloudWatch that expect single-line JSON per entry.\n * @default true\n */\n prettyPrint?: boolean;\n /**\n * Override the key used for the log message.\n * Defaults to Pino's built-in 'msg' key.\n * Set to 'message' for compatibility with Google Cloud Logging,\n * Elastic Common Schema (ECS), Datadog, and AWS CloudWatch.\n * @example 'message'\n */\n messageKey?: string;\n}\n\ninterface PinoLoggerInternalOptions<CustomLevels extends string = never> extends PinoLoggerOptions<CustomLevels> {\n /** @internal Used internally for child loggers */\n _logger?: pino.Logger<CustomLevels>;\n /** @internal Shared adapter-context ref so root and children correlate together */\n _adapterContextRef?: { current?: LoggerAdapterContext };\n}\n\nexport class PinoLogger<CustomLevels extends string = never> extends MastraLogger {\n protected logger: pino.Logger<CustomLevels>;\n // Mutable ref shared with child loggers: the root's mixin (which children's\n // pino instances inherit) reads through this ref, so attaching observability\n // to a child (e.g. `new Mastra({ logger: base.child({...}) })`) correlates\n // the records it actually logs through.\n #adapterContextRef: { current?: LoggerAdapterContext };\n\n constructor(options: PinoLoggerOptions<CustomLevels> = {}) {\n super(options);\n\n const internalOptions = options as PinoLoggerInternalOptions<CustomLevels>;\n this.#adapterContextRef = internalOptions._adapterContextRef ?? {};\n\n // If an existing pino logger is provided (for child loggers), use it directly\n if (internalOptions._logger) {\n this.logger = internalOptions._logger;\n return;\n }\n\n // Compose the user mixin with trace correlation. Pino mixins run\n // synchronously on every log call, so the trace fields land in the\n // native record before serialization — for ALL destinations (stdout,\n // transports, files). Trace fields win on key conflicts.\n const userMixin = options.mixin;\n const correlationMixin: pino.MixinFn<CustomLevels> = (mergeObject, level, logger) => {\n const userFields = userMixin ? userMixin(mergeObject, level, logger) : {};\n const ctx = this.#adapterContextRef.current;\n if (!ctx?.options.correlation) return userFields;\n try {\n return { ...userFields, ...(ctx.resolveTraceFields() ?? {}) };\n } catch {\n return userFields;\n }\n };\n\n const shouldPrettyPrint = options.prettyPrint ?? true;\n let prettyStream: ReturnType<typeof pretty> | undefined = undefined;\n if (!options.overrideDefaultTransports && shouldPrettyPrint) {\n prettyStream = pretty({\n colorize: true,\n levelFirst: true,\n ignore: 'pid,hostname,component',\n colorizeObjects: true,\n translateTime: 'SYS:standard',\n singleLine: false,\n });\n }\n\n const transportsAry = [...this.getTransports().entries()];\n this.logger = pino(\n {\n name: options.name || 'app',\n level: options.level || LogLevel.INFO,\n formatters: options.formatters,\n redact: options.redact,\n mixin: correlationMixin,\n customLevels: options.customLevels,\n messageKey: options.messageKey ?? 'msg',\n },\n options.overrideDefaultTransports\n ? options?.transports?.default\n : transportsAry.length === 0\n ? prettyStream // undefined when prettyPrint:false → pino native JSON\n : pino.multistream([\n ...transportsAry.map(([, transport]) => ({\n stream: transport,\n level: options.level || LogLevel.INFO,\n })),\n ...(prettyStream // only add prettyStream to multistream if it exists\n ? [{ stream: prettyStream, level: options.level || LogLevel.INFO }]\n : []),\n ]),\n );\n }\n\n /**\n * Creates a child logger with additional bound context.\n * All logs from the child logger will include the bound context.\n *\n * @param bindings - Key-value pairs to include in all logs from this child logger\n * @returns A new PinoLogger instance with the bound context\n *\n * @example\n * ```typescript\n * const baseLogger = new PinoLogger({ name: 'MyApp' });\n *\n * // Create module-scoped logger\n * const serviceLogger = baseLogger.child({ module: 'UserService' });\n * serviceLogger.info('User created', { userId: '123' });\n * // Output includes: { module: 'UserService', userId: '123', msg: 'User created' }\n *\n * // Create request-scoped logger\n * const requestLogger = baseLogger.child({ requestId: req.id });\n * requestLogger.error('Request failed', { err: error });\n * // Output includes: { requestId: 'abc', msg: 'Request failed', err: {...} }\n * ```\n */\n child(bindings: Record<string, unknown>): PinoLogger<CustomLevels> {\n const childPino = this.logger.child(bindings);\n const childOptions: PinoLoggerInternalOptions<CustomLevels> = {\n name: this.name,\n level: this.level,\n transports: Object.fromEntries(this.transports),\n _logger: childPino,\n _adapterContextRef: this.#adapterContextRef,\n };\n return new PinoLogger(childOptions);\n }\n\n /**\n * Adapter hook (see `AdaptableLogger` in `@mastra/core/logger`): enables\n * native trace correlation (trace_id/span_id merged into the pino record\n * via mixin, for every destination) and observability export derived from\n * the same record. Called by Mastra during setup.\n */\n __attachObservability(ctx: LoggerAdapterContext): void {\n // Shared ref: attaching to a child also enables correlation on the root\n // mixin the child's records flow through (and vice versa).\n this.#adapterContextRef.current = ctx;\n }\n\n /**\n * The adapter context lives on the ref cell shared by the whole\n * root/child family, so re-attach detection (multi-Mastra warning) must\n * key on that cell — attaching to a child re-targets the root too.\n */\n __observabilityAttachmentKey(): object {\n return this.#adapterContextRef;\n }\n\n /**\n * Export the record derived from the same native call to observability.\n * Runs regardless of pino's level filter and never throws into the caller.\n */\n #export(level: 'debug' | 'info' | 'warn' | 'error', message: string, args: Record<string, any>): void {\n const ctx = this.#adapterContextRef.current;\n if (!ctx?.options.export) return;\n try {\n // An Error passed as the args value often has no enumerable keys but\n // must still be exported (serialized by buildLogRecordData).\n const hasPayload = args instanceof Error || Object.keys(args).length > 0;\n // Trace identity travels on ExportedLog.traceId/spanId (the sink is\n // span-correlated); data stays reserved for the user payload. The mixin\n // still injects trace fields into the native pino record for stdout.\n ctx.getLogSink()?.[level](message, buildLogRecordData(hasPayload ? [args] : []));\n } catch {\n // Never let observability export break the primary logger\n }\n }\n\n debug(message: string, args: Record<string, any> = {}): void {\n this.logger.debug(args, message);\n this.#export('debug', message, args);\n }\n\n info(message: string, args: Record<string, any> = {}): void {\n this.logger.info(args, message);\n this.#export('info', message, args);\n }\n\n warn(message: string, args: Record<string, any> = {}): void {\n this.logger.warn(args, message);\n this.#export('warn', message, args);\n }\n\n error(message: string, args: Record<string, any> = {}): void {\n this.logger.error(args, message);\n this.#export('error', message, args);\n }\n\n override trackException(error: Error, metadata?: Record<string, unknown>): void {\n exportTrackedException(this.#adapterContextRef.current, error, metadata);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["MastraLogger","#adapterContextRef","LogLevel","#export"],"sources":["../src/pino.ts"],"sourcesContent":["import type { LoggerTransport, LoggerAdapterContext } from '@mastra/core/logger';\nimport { LogLevel, MastraLogger, buildLogRecordData, exportTrackedException } from '@mastra/core/logger';\nimport pino from 'pino';\nimport pretty from 'pino-pretty';\n\ntype TransportMap = Record<string, LoggerTransport>;\n\nexport type { LogLevel } from '@mastra/core/logger';\n\nexport interface PinoLoggerOptions<CustomLevels extends string = never> {\n name?: string;\n level?: LogLevel;\n transports?: TransportMap;\n overrideDefaultTransports?: boolean;\n formatters?: pino.LoggerOptions['formatters'];\n redact?: pino.LoggerOptions['redact'];\n mixin?: pino.MixinFn<CustomLevels>;\n customLevels?: { [level in CustomLevels]: number };\n /**\n * When false, disables pino-pretty and outputs raw JSON.\n * Useful when sending logs to aggregators like Datadog,\n * Loki, or CloudWatch that expect single-line JSON per entry.\n * @default true\n */\n prettyPrint?: boolean;\n /**\n * Override the key used for the log message.\n * Defaults to Pino's built-in 'msg' key.\n * Set to 'message' for compatibility with Google Cloud Logging,\n * Elastic Common Schema (ECS), Datadog, and AWS CloudWatch.\n * @example 'message'\n */\n messageKey?: string;\n /**\n * Custom pino serializers, merged over Mastra's defaults.\n * By default the `error` key is serialized with pino's standard error\n * serializer (alongside pino's built-in `err`), so that\n * `logger.warn('...', { error })` records the message and stack rather\n * than an empty object.\n */\n serializers?: pino.LoggerOptions['serializers'];\n}\n\ninterface PinoLoggerInternalOptions<CustomLevels extends string = never> extends PinoLoggerOptions<CustomLevels> {\n /** @internal Used internally for child loggers */\n _logger?: pino.Logger<CustomLevels>;\n /** @internal Shared adapter-context ref so root and children correlate together */\n _adapterContextRef?: { current?: LoggerAdapterContext };\n}\n\nexport class PinoLogger<CustomLevels extends string = never> extends MastraLogger {\n protected logger: pino.Logger<CustomLevels>;\n // Mutable ref shared with child loggers: the root's mixin (which children's\n // pino instances inherit) reads through this ref, so attaching observability\n // to a child (e.g. `new Mastra({ logger: base.child({...}) })`) correlates\n // the records it actually logs through.\n #adapterContextRef: { current?: LoggerAdapterContext };\n\n constructor(options: PinoLoggerOptions<CustomLevels> = {}) {\n super(options);\n\n const internalOptions = options as PinoLoggerInternalOptions<CustomLevels>;\n this.#adapterContextRef = internalOptions._adapterContextRef ?? {};\n\n // If an existing pino logger is provided (for child loggers), use it directly\n if (internalOptions._logger) {\n this.logger = internalOptions._logger;\n return;\n }\n\n // Compose the user mixin with trace correlation. Pino mixins run\n // synchronously on every log call, so the trace fields land in the\n // native record before serialization — for ALL destinations (stdout,\n // transports, files). Trace fields win on key conflicts.\n const userMixin = options.mixin;\n const correlationMixin: pino.MixinFn<CustomLevels> = (mergeObject, level, logger) => {\n const userFields = userMixin ? userMixin(mergeObject, level, logger) : {};\n const ctx = this.#adapterContextRef.current;\n if (!ctx?.options.correlation) return userFields;\n try {\n return { ...userFields, ...(ctx.resolveTraceFields() ?? {}) };\n } catch {\n return userFields;\n }\n };\n\n const shouldPrettyPrint = options.prettyPrint ?? true;\n let prettyStream: ReturnType<typeof pretty> | undefined = undefined;\n if (!options.overrideDefaultTransports && shouldPrettyPrint) {\n prettyStream = pretty({\n colorize: true,\n levelFirst: true,\n ignore: 'pid,hostname,component',\n colorizeObjects: true,\n translateTime: 'SYS:standard',\n singleLine: false,\n });\n }\n\n const transportsAry = [...this.getTransports().entries()];\n this.logger = pino(\n {\n name: options.name || 'app',\n level: options.level || LogLevel.INFO,\n formatters: options.formatters,\n redact: options.redact,\n mixin: correlationMixin,\n customLevels: options.customLevels,\n messageKey: options.messageKey ?? 'msg',\n // Pino applies its error serializer only to `errorKey` (default `err`).\n // Mastra logs errors as `{ error }` throughout, and an Error's `message`\n // and `stack` are non-enumerable, so without this they serialize to `{}`.\n serializers: { error: pino.stdSerializers.err, ...options.serializers },\n },\n options.overrideDefaultTransports\n ? options?.transports?.default\n : transportsAry.length === 0\n ? prettyStream // undefined when prettyPrint:false → pino native JSON\n : pino.multistream([\n ...transportsAry.map(([, transport]) => ({\n stream: transport,\n level: options.level || LogLevel.INFO,\n })),\n ...(prettyStream // only add prettyStream to multistream if it exists\n ? [{ stream: prettyStream, level: options.level || LogLevel.INFO }]\n : []),\n ]),\n );\n }\n\n /**\n * Creates a child logger with additional bound context.\n * All logs from the child logger will include the bound context.\n *\n * @param bindings - Key-value pairs to include in all logs from this child logger\n * @returns A new PinoLogger instance with the bound context\n *\n * @example\n * ```typescript\n * const baseLogger = new PinoLogger({ name: 'MyApp' });\n *\n * // Create module-scoped logger\n * const serviceLogger = baseLogger.child({ module: 'UserService' });\n * serviceLogger.info('User created', { userId: '123' });\n * // Output includes: { module: 'UserService', userId: '123', msg: 'User created' }\n *\n * // Create request-scoped logger\n * const requestLogger = baseLogger.child({ requestId: req.id });\n * requestLogger.error('Request failed', { err: error });\n * // Output includes: { requestId: 'abc', msg: 'Request failed', err: {...} }\n * ```\n */\n child(bindings: Record<string, unknown>): PinoLogger<CustomLevels> {\n const childPino = this.logger.child(bindings);\n const childOptions: PinoLoggerInternalOptions<CustomLevels> = {\n name: this.name,\n level: this.level,\n transports: Object.fromEntries(this.transports),\n _logger: childPino,\n _adapterContextRef: this.#adapterContextRef,\n };\n return new PinoLogger(childOptions);\n }\n\n /**\n * Adapter hook (see `AdaptableLogger` in `@mastra/core/logger`): enables\n * native trace correlation (trace_id/span_id merged into the pino record\n * via mixin, for every destination) and observability export derived from\n * the same record. Called by Mastra during setup.\n */\n __attachObservability(ctx: LoggerAdapterContext): void {\n // Shared ref: attaching to a child also enables correlation on the root\n // mixin the child's records flow through (and vice versa).\n this.#adapterContextRef.current = ctx;\n }\n\n /**\n * The adapter context lives on the ref cell shared by the whole\n * root/child family, so re-attach detection (multi-Mastra warning) must\n * key on that cell — attaching to a child re-targets the root too.\n */\n __observabilityAttachmentKey(): object {\n return this.#adapterContextRef;\n }\n\n /**\n * Export the record derived from the same native call to observability.\n * Runs regardless of pino's level filter and never throws into the caller.\n */\n #export(level: 'debug' | 'info' | 'warn' | 'error', message: string, args: Record<string, any>): void {\n const ctx = this.#adapterContextRef.current;\n if (!ctx?.options.export) return;\n try {\n // An Error passed as the args value often has no enumerable keys but\n // must still be exported (serialized by buildLogRecordData).\n const hasPayload = args instanceof Error || Object.keys(args).length > 0;\n // Trace identity travels on ExportedLog.traceId/spanId (the sink is\n // span-correlated); data stays reserved for the user payload. The mixin\n // still injects trace fields into the native pino record for stdout.\n ctx.getLogSink()?.[level](message, buildLogRecordData(hasPayload ? [args] : []));\n } catch {\n // Never let observability export break the primary logger\n }\n }\n\n debug(message: string, args: Record<string, any> = {}): void {\n this.logger.debug(args, message);\n this.#export('debug', message, args);\n }\n\n info(message: string, args: Record<string, any> = {}): void {\n this.logger.info(args, message);\n this.#export('info', message, args);\n }\n\n warn(message: string, args: Record<string, any> = {}): void {\n this.logger.warn(args, message);\n this.#export('warn', message, args);\n }\n\n error(message: string, args: Record<string, any> = {}): void {\n this.logger.error(args, message);\n this.#export('error', message, args);\n }\n\n override trackException(error: Error, metadata?: Record<string, unknown>): void {\n exportTrackedException(this.#adapterContextRef.current, error, metadata);\n }\n}\n"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -45,7 +45,11 @@ var PinoLogger = class PinoLogger extends MastraLogger {
|
|
|
45
45
|
redact: options.redact,
|
|
46
46
|
mixin: correlationMixin,
|
|
47
47
|
customLevels: options.customLevels,
|
|
48
|
-
messageKey: options.messageKey ?? "msg"
|
|
48
|
+
messageKey: options.messageKey ?? "msg",
|
|
49
|
+
serializers: {
|
|
50
|
+
error: pino.stdSerializers.err,
|
|
51
|
+
...options.serializers
|
|
52
|
+
}
|
|
49
53
|
}, options.overrideDefaultTransports ? options?.transports?.default : transportsAry.length === 0 ? prettyStream : pino.multistream([...transportsAry.map(([, transport]) => ({
|
|
50
54
|
stream: transport,
|
|
51
55
|
level: options.level || LogLevel.INFO
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["#adapterContextRef","#export"],"sources":["../src/pino.ts"],"sourcesContent":["import type { LoggerTransport, LoggerAdapterContext } from '@mastra/core/logger';\nimport { LogLevel, MastraLogger, buildLogRecordData, exportTrackedException } from '@mastra/core/logger';\nimport pino from 'pino';\nimport pretty from 'pino-pretty';\n\ntype TransportMap = Record<string, LoggerTransport>;\n\nexport type { LogLevel } from '@mastra/core/logger';\n\nexport interface PinoLoggerOptions<CustomLevels extends string = never> {\n name?: string;\n level?: LogLevel;\n transports?: TransportMap;\n overrideDefaultTransports?: boolean;\n formatters?: pino.LoggerOptions['formatters'];\n redact?: pino.LoggerOptions['redact'];\n mixin?: pino.MixinFn<CustomLevels>;\n customLevels?: { [level in CustomLevels]: number };\n /**\n * When false, disables pino-pretty and outputs raw JSON.\n * Useful when sending logs to aggregators like Datadog,\n * Loki, or CloudWatch that expect single-line JSON per entry.\n * @default true\n */\n prettyPrint?: boolean;\n /**\n * Override the key used for the log message.\n * Defaults to Pino's built-in 'msg' key.\n * Set to 'message' for compatibility with Google Cloud Logging,\n * Elastic Common Schema (ECS), Datadog, and AWS CloudWatch.\n * @example 'message'\n */\n messageKey?: string;\n}\n\ninterface PinoLoggerInternalOptions<CustomLevels extends string = never> extends PinoLoggerOptions<CustomLevels> {\n /** @internal Used internally for child loggers */\n _logger?: pino.Logger<CustomLevels>;\n /** @internal Shared adapter-context ref so root and children correlate together */\n _adapterContextRef?: { current?: LoggerAdapterContext };\n}\n\nexport class PinoLogger<CustomLevels extends string = never> extends MastraLogger {\n protected logger: pino.Logger<CustomLevels>;\n // Mutable ref shared with child loggers: the root's mixin (which children's\n // pino instances inherit) reads through this ref, so attaching observability\n // to a child (e.g. `new Mastra({ logger: base.child({...}) })`) correlates\n // the records it actually logs through.\n #adapterContextRef: { current?: LoggerAdapterContext };\n\n constructor(options: PinoLoggerOptions<CustomLevels> = {}) {\n super(options);\n\n const internalOptions = options as PinoLoggerInternalOptions<CustomLevels>;\n this.#adapterContextRef = internalOptions._adapterContextRef ?? {};\n\n // If an existing pino logger is provided (for child loggers), use it directly\n if (internalOptions._logger) {\n this.logger = internalOptions._logger;\n return;\n }\n\n // Compose the user mixin with trace correlation. Pino mixins run\n // synchronously on every log call, so the trace fields land in the\n // native record before serialization — for ALL destinations (stdout,\n // transports, files). Trace fields win on key conflicts.\n const userMixin = options.mixin;\n const correlationMixin: pino.MixinFn<CustomLevels> = (mergeObject, level, logger) => {\n const userFields = userMixin ? userMixin(mergeObject, level, logger) : {};\n const ctx = this.#adapterContextRef.current;\n if (!ctx?.options.correlation) return userFields;\n try {\n return { ...userFields, ...(ctx.resolveTraceFields() ?? {}) };\n } catch {\n return userFields;\n }\n };\n\n const shouldPrettyPrint = options.prettyPrint ?? true;\n let prettyStream: ReturnType<typeof pretty> | undefined = undefined;\n if (!options.overrideDefaultTransports && shouldPrettyPrint) {\n prettyStream = pretty({\n colorize: true,\n levelFirst: true,\n ignore: 'pid,hostname,component',\n colorizeObjects: true,\n translateTime: 'SYS:standard',\n singleLine: false,\n });\n }\n\n const transportsAry = [...this.getTransports().entries()];\n this.logger = pino(\n {\n name: options.name || 'app',\n level: options.level || LogLevel.INFO,\n formatters: options.formatters,\n redact: options.redact,\n mixin: correlationMixin,\n customLevels: options.customLevels,\n messageKey: options.messageKey ?? 'msg',\n },\n options.overrideDefaultTransports\n ? options?.transports?.default\n : transportsAry.length === 0\n ? prettyStream // undefined when prettyPrint:false → pino native JSON\n : pino.multistream([\n ...transportsAry.map(([, transport]) => ({\n stream: transport,\n level: options.level || LogLevel.INFO,\n })),\n ...(prettyStream // only add prettyStream to multistream if it exists\n ? [{ stream: prettyStream, level: options.level || LogLevel.INFO }]\n : []),\n ]),\n );\n }\n\n /**\n * Creates a child logger with additional bound context.\n * All logs from the child logger will include the bound context.\n *\n * @param bindings - Key-value pairs to include in all logs from this child logger\n * @returns A new PinoLogger instance with the bound context\n *\n * @example\n * ```typescript\n * const baseLogger = new PinoLogger({ name: 'MyApp' });\n *\n * // Create module-scoped logger\n * const serviceLogger = baseLogger.child({ module: 'UserService' });\n * serviceLogger.info('User created', { userId: '123' });\n * // Output includes: { module: 'UserService', userId: '123', msg: 'User created' }\n *\n * // Create request-scoped logger\n * const requestLogger = baseLogger.child({ requestId: req.id });\n * requestLogger.error('Request failed', { err: error });\n * // Output includes: { requestId: 'abc', msg: 'Request failed', err: {...} }\n * ```\n */\n child(bindings: Record<string, unknown>): PinoLogger<CustomLevels> {\n const childPino = this.logger.child(bindings);\n const childOptions: PinoLoggerInternalOptions<CustomLevels> = {\n name: this.name,\n level: this.level,\n transports: Object.fromEntries(this.transports),\n _logger: childPino,\n _adapterContextRef: this.#adapterContextRef,\n };\n return new PinoLogger(childOptions);\n }\n\n /**\n * Adapter hook (see `AdaptableLogger` in `@mastra/core/logger`): enables\n * native trace correlation (trace_id/span_id merged into the pino record\n * via mixin, for every destination) and observability export derived from\n * the same record. Called by Mastra during setup.\n */\n __attachObservability(ctx: LoggerAdapterContext): void {\n // Shared ref: attaching to a child also enables correlation on the root\n // mixin the child's records flow through (and vice versa).\n this.#adapterContextRef.current = ctx;\n }\n\n /**\n * The adapter context lives on the ref cell shared by the whole\n * root/child family, so re-attach detection (multi-Mastra warning) must\n * key on that cell — attaching to a child re-targets the root too.\n */\n __observabilityAttachmentKey(): object {\n return this.#adapterContextRef;\n }\n\n /**\n * Export the record derived from the same native call to observability.\n * Runs regardless of pino's level filter and never throws into the caller.\n */\n #export(level: 'debug' | 'info' | 'warn' | 'error', message: string, args: Record<string, any>): void {\n const ctx = this.#adapterContextRef.current;\n if (!ctx?.options.export) return;\n try {\n // An Error passed as the args value often has no enumerable keys but\n // must still be exported (serialized by buildLogRecordData).\n const hasPayload = args instanceof Error || Object.keys(args).length > 0;\n // Trace identity travels on ExportedLog.traceId/spanId (the sink is\n // span-correlated); data stays reserved for the user payload. The mixin\n // still injects trace fields into the native pino record for stdout.\n ctx.getLogSink()?.[level](message, buildLogRecordData(hasPayload ? [args] : []));\n } catch {\n // Never let observability export break the primary logger\n }\n }\n\n debug(message: string, args: Record<string, any> = {}): void {\n this.logger.debug(args, message);\n this.#export('debug', message, args);\n }\n\n info(message: string, args: Record<string, any> = {}): void {\n this.logger.info(args, message);\n this.#export('info', message, args);\n }\n\n warn(message: string, args: Record<string, any> = {}): void {\n this.logger.warn(args, message);\n this.#export('warn', message, args);\n }\n\n error(message: string, args: Record<string, any> = {}): void {\n this.logger.error(args, message);\n this.#export('error', message, args);\n }\n\n override trackException(error: Error, metadata?: Record<string, unknown>): void {\n exportTrackedException(this.#adapterContextRef.current, error, metadata);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["#adapterContextRef","#export"],"sources":["../src/pino.ts"],"sourcesContent":["import type { LoggerTransport, LoggerAdapterContext } from '@mastra/core/logger';\nimport { LogLevel, MastraLogger, buildLogRecordData, exportTrackedException } from '@mastra/core/logger';\nimport pino from 'pino';\nimport pretty from 'pino-pretty';\n\ntype TransportMap = Record<string, LoggerTransport>;\n\nexport type { LogLevel } from '@mastra/core/logger';\n\nexport interface PinoLoggerOptions<CustomLevels extends string = never> {\n name?: string;\n level?: LogLevel;\n transports?: TransportMap;\n overrideDefaultTransports?: boolean;\n formatters?: pino.LoggerOptions['formatters'];\n redact?: pino.LoggerOptions['redact'];\n mixin?: pino.MixinFn<CustomLevels>;\n customLevels?: { [level in CustomLevels]: number };\n /**\n * When false, disables pino-pretty and outputs raw JSON.\n * Useful when sending logs to aggregators like Datadog,\n * Loki, or CloudWatch that expect single-line JSON per entry.\n * @default true\n */\n prettyPrint?: boolean;\n /**\n * Override the key used for the log message.\n * Defaults to Pino's built-in 'msg' key.\n * Set to 'message' for compatibility with Google Cloud Logging,\n * Elastic Common Schema (ECS), Datadog, and AWS CloudWatch.\n * @example 'message'\n */\n messageKey?: string;\n /**\n * Custom pino serializers, merged over Mastra's defaults.\n * By default the `error` key is serialized with pino's standard error\n * serializer (alongside pino's built-in `err`), so that\n * `logger.warn('...', { error })` records the message and stack rather\n * than an empty object.\n */\n serializers?: pino.LoggerOptions['serializers'];\n}\n\ninterface PinoLoggerInternalOptions<CustomLevels extends string = never> extends PinoLoggerOptions<CustomLevels> {\n /** @internal Used internally for child loggers */\n _logger?: pino.Logger<CustomLevels>;\n /** @internal Shared adapter-context ref so root and children correlate together */\n _adapterContextRef?: { current?: LoggerAdapterContext };\n}\n\nexport class PinoLogger<CustomLevels extends string = never> extends MastraLogger {\n protected logger: pino.Logger<CustomLevels>;\n // Mutable ref shared with child loggers: the root's mixin (which children's\n // pino instances inherit) reads through this ref, so attaching observability\n // to a child (e.g. `new Mastra({ logger: base.child({...}) })`) correlates\n // the records it actually logs through.\n #adapterContextRef: { current?: LoggerAdapterContext };\n\n constructor(options: PinoLoggerOptions<CustomLevels> = {}) {\n super(options);\n\n const internalOptions = options as PinoLoggerInternalOptions<CustomLevels>;\n this.#adapterContextRef = internalOptions._adapterContextRef ?? {};\n\n // If an existing pino logger is provided (for child loggers), use it directly\n if (internalOptions._logger) {\n this.logger = internalOptions._logger;\n return;\n }\n\n // Compose the user mixin with trace correlation. Pino mixins run\n // synchronously on every log call, so the trace fields land in the\n // native record before serialization — for ALL destinations (stdout,\n // transports, files). Trace fields win on key conflicts.\n const userMixin = options.mixin;\n const correlationMixin: pino.MixinFn<CustomLevels> = (mergeObject, level, logger) => {\n const userFields = userMixin ? userMixin(mergeObject, level, logger) : {};\n const ctx = this.#adapterContextRef.current;\n if (!ctx?.options.correlation) return userFields;\n try {\n return { ...userFields, ...(ctx.resolveTraceFields() ?? {}) };\n } catch {\n return userFields;\n }\n };\n\n const shouldPrettyPrint = options.prettyPrint ?? true;\n let prettyStream: ReturnType<typeof pretty> | undefined = undefined;\n if (!options.overrideDefaultTransports && shouldPrettyPrint) {\n prettyStream = pretty({\n colorize: true,\n levelFirst: true,\n ignore: 'pid,hostname,component',\n colorizeObjects: true,\n translateTime: 'SYS:standard',\n singleLine: false,\n });\n }\n\n const transportsAry = [...this.getTransports().entries()];\n this.logger = pino(\n {\n name: options.name || 'app',\n level: options.level || LogLevel.INFO,\n formatters: options.formatters,\n redact: options.redact,\n mixin: correlationMixin,\n customLevels: options.customLevels,\n messageKey: options.messageKey ?? 'msg',\n // Pino applies its error serializer only to `errorKey` (default `err`).\n // Mastra logs errors as `{ error }` throughout, and an Error's `message`\n // and `stack` are non-enumerable, so without this they serialize to `{}`.\n serializers: { error: pino.stdSerializers.err, ...options.serializers },\n },\n options.overrideDefaultTransports\n ? options?.transports?.default\n : transportsAry.length === 0\n ? prettyStream // undefined when prettyPrint:false → pino native JSON\n : pino.multistream([\n ...transportsAry.map(([, transport]) => ({\n stream: transport,\n level: options.level || LogLevel.INFO,\n })),\n ...(prettyStream // only add prettyStream to multistream if it exists\n ? [{ stream: prettyStream, level: options.level || LogLevel.INFO }]\n : []),\n ]),\n );\n }\n\n /**\n * Creates a child logger with additional bound context.\n * All logs from the child logger will include the bound context.\n *\n * @param bindings - Key-value pairs to include in all logs from this child logger\n * @returns A new PinoLogger instance with the bound context\n *\n * @example\n * ```typescript\n * const baseLogger = new PinoLogger({ name: 'MyApp' });\n *\n * // Create module-scoped logger\n * const serviceLogger = baseLogger.child({ module: 'UserService' });\n * serviceLogger.info('User created', { userId: '123' });\n * // Output includes: { module: 'UserService', userId: '123', msg: 'User created' }\n *\n * // Create request-scoped logger\n * const requestLogger = baseLogger.child({ requestId: req.id });\n * requestLogger.error('Request failed', { err: error });\n * // Output includes: { requestId: 'abc', msg: 'Request failed', err: {...} }\n * ```\n */\n child(bindings: Record<string, unknown>): PinoLogger<CustomLevels> {\n const childPino = this.logger.child(bindings);\n const childOptions: PinoLoggerInternalOptions<CustomLevels> = {\n name: this.name,\n level: this.level,\n transports: Object.fromEntries(this.transports),\n _logger: childPino,\n _adapterContextRef: this.#adapterContextRef,\n };\n return new PinoLogger(childOptions);\n }\n\n /**\n * Adapter hook (see `AdaptableLogger` in `@mastra/core/logger`): enables\n * native trace correlation (trace_id/span_id merged into the pino record\n * via mixin, for every destination) and observability export derived from\n * the same record. Called by Mastra during setup.\n */\n __attachObservability(ctx: LoggerAdapterContext): void {\n // Shared ref: attaching to a child also enables correlation on the root\n // mixin the child's records flow through (and vice versa).\n this.#adapterContextRef.current = ctx;\n }\n\n /**\n * The adapter context lives on the ref cell shared by the whole\n * root/child family, so re-attach detection (multi-Mastra warning) must\n * key on that cell — attaching to a child re-targets the root too.\n */\n __observabilityAttachmentKey(): object {\n return this.#adapterContextRef;\n }\n\n /**\n * Export the record derived from the same native call to observability.\n * Runs regardless of pino's level filter and never throws into the caller.\n */\n #export(level: 'debug' | 'info' | 'warn' | 'error', message: string, args: Record<string, any>): void {\n const ctx = this.#adapterContextRef.current;\n if (!ctx?.options.export) return;\n try {\n // An Error passed as the args value often has no enumerable keys but\n // must still be exported (serialized by buildLogRecordData).\n const hasPayload = args instanceof Error || Object.keys(args).length > 0;\n // Trace identity travels on ExportedLog.traceId/spanId (the sink is\n // span-correlated); data stays reserved for the user payload. The mixin\n // still injects trace fields into the native pino record for stdout.\n ctx.getLogSink()?.[level](message, buildLogRecordData(hasPayload ? [args] : []));\n } catch {\n // Never let observability export break the primary logger\n }\n }\n\n debug(message: string, args: Record<string, any> = {}): void {\n this.logger.debug(args, message);\n this.#export('debug', message, args);\n }\n\n info(message: string, args: Record<string, any> = {}): void {\n this.logger.info(args, message);\n this.#export('info', message, args);\n }\n\n warn(message: string, args: Record<string, any> = {}): void {\n this.logger.warn(args, message);\n this.#export('warn', message, args);\n }\n\n error(message: string, args: Record<string, any> = {}): void {\n this.logger.error(args, message);\n this.#export('error', message, args);\n }\n\n override trackException(error: Error, metadata?: Record<string, unknown>): void {\n exportTrackedException(this.#adapterContextRef.current, error, metadata);\n }\n}\n"],"mappings":"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"}
|
package/dist/pino.d.ts
CHANGED
|
@@ -29,6 +29,14 @@ export interface PinoLoggerOptions<CustomLevels extends string = never> {
|
|
|
29
29
|
* @example 'message'
|
|
30
30
|
*/
|
|
31
31
|
messageKey?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Custom pino serializers, merged over Mastra's defaults.
|
|
34
|
+
* By default the `error` key is serialized with pino's standard error
|
|
35
|
+
* serializer (alongside pino's built-in `err`), so that
|
|
36
|
+
* `logger.warn('...', { error })` records the message and stack rather
|
|
37
|
+
* than an empty object.
|
|
38
|
+
*/
|
|
39
|
+
serializers?: pino.LoggerOptions['serializers'];
|
|
32
40
|
}
|
|
33
41
|
export declare class PinoLogger<CustomLevels extends string = never> extends MastraLogger {
|
|
34
42
|
#private;
|
package/dist/pino.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pino.d.ts","sourceRoot":"","sources":["../src/pino.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,EAAE,QAAQ,EAAE,YAAY,EAA8C,MAAM,qBAAqB,CAAC;AACzG,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AAEpD,YAAY,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,WAAW,iBAAiB,CAAC,YAAY,SAAS,MAAM,GAAG,KAAK;IACpE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,UAAU,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IAC9C,MAAM,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACtC,KAAK,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACnC,YAAY,CAAC,EAAE;SAAG,KAAK,IAAI,YAAY,GAAG,MAAM;KAAE,CAAC;IACnD;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"pino.d.ts","sourceRoot":"","sources":["../src/pino.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,EAAE,QAAQ,EAAE,YAAY,EAA8C,MAAM,qBAAqB,CAAC;AACzG,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AAEpD,YAAY,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,WAAW,iBAAiB,CAAC,YAAY,SAAS,MAAM,GAAG,KAAK;IACpE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,UAAU,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IAC9C,MAAM,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACtC,KAAK,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACnC,YAAY,CAAC,EAAE;SAAG,KAAK,IAAI,YAAY,GAAG,MAAM;KAAE,CAAC;IACnD;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;CACjD;AASD,qBAAa,UAAU,CAAC,YAAY,SAAS,MAAM,GAAG,KAAK,CAAE,SAAQ,YAAY;;IAC/E,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAO5C,YAAY,OAAO,GAAE,iBAAiB,CAAC,YAAY,CAAM,EAsExD;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,UAAU,CAAC,YAAY,CAAC,CAUjE;IAED;;;;;OAKG;IACH,qBAAqB,CAAC,GAAG,EAAE,oBAAoB,GAAG,IAAI,CAIrD;IAED;;;;OAIG;IACH,4BAA4B,IAAI,MAAM,CAErC;IAsBD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,IAAI,CAG3D;IAED,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,IAAI,CAG1D;IAED,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,IAAI,CAG1D;IAED,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,IAAI,CAG3D;IAEQ,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAE9E;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/loggers",
|
|
3
|
-
"version": "1.3.1
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -76,9 +76,9 @@
|
|
|
76
76
|
"tsx": "^4.23.1",
|
|
77
77
|
"typescript": "^7.0.2",
|
|
78
78
|
"vitest": "4.1.10",
|
|
79
|
-
"@internal/
|
|
80
|
-
"@internal/
|
|
81
|
-
"@mastra/core": "1.64.0
|
|
79
|
+
"@internal/lint": "0.0.130",
|
|
80
|
+
"@internal/types-builder": "0.0.105",
|
|
81
|
+
"@mastra/core": "1.64.0"
|
|
82
82
|
},
|
|
83
83
|
"peerDependencies": {
|
|
84
84
|
"@mastra/core": ">=1.0.0-0 <2.0.0-0"
|