@mastra/loggers 1.3.1 → 1.3.2-alpha.0

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.
@@ -3,7 +3,7 @@ name: mastra-loggers
3
3
  description: Documentation for @mastra/loggers. Use when working with @mastra/loggers APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/loggers"
6
- version: "1.3.1"
6
+ version: "1.3.2-alpha.0"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.3.1",
2
+ "version": "1.3.2-alpha.0",
3
3
  "package": "@mastra/loggers",
4
4
  "exports": {},
5
5
  "modules": {}
package/dist/index.cjs CHANGED
@@ -27,6 +27,27 @@ pino = __toESM(pino, 1);
27
27
  let pino_pretty = require("pino-pretty");
28
28
  pino_pretty = __toESM(pino_pretty, 1);
29
29
  //#region src/pino.ts
30
+ /**
31
+ * Provides Pino-backed logging for Mastra applications.
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * import { Mastra } from '@mastra/core/mastra';
36
+ * import { PinoLogger } from '@mastra/loggers';
37
+ *
38
+ * const mastra = new Mastra({
39
+ * logger: new PinoLogger({ name: 'my-app', level: 'info' }),
40
+ * });
41
+ * ```
42
+ *
43
+ * @see For documentation bundled with your installed package, locate
44
+ * `@mastra/loggers/package.json` with your project's resolver or package-manager
45
+ * tooling, then read `dist/docs/SKILL.md` from that package root and follow its
46
+ * reference links. Use package-manager tools for virtual or archived packages.
47
+ *
48
+ * @see [Pino logger documentation](https://mastra.ai/reference/logging/pino-logger)
49
+ * if packaged docs are unavailable.
50
+ */
30
51
  var PinoLogger = class PinoLogger extends _mastra_core_logger.MastraLogger {
31
52
  logger;
32
53
  #adapterContextRef;
@@ -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 * 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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"}
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\n/**\n * Provides Pino-backed logging for Mastra applications.\n *\n * @example\n * ```typescript\n * import { Mastra } from '@mastra/core/mastra';\n * import { PinoLogger } from '@mastra/loggers';\n *\n * const mastra = new Mastra({\n * logger: new PinoLogger({ name: 'my-app', level: 'info' }),\n * });\n * ```\n *\n * @see For documentation bundled with your installed package, locate\n * `@mastra/loggers/package.json` with your project's resolver or package-manager\n * tooling, then read `dist/docs/SKILL.md` from that package root and follow its\n * reference links. Use package-manager tools for virtual or archived packages.\n *\n * @see [Pino logger documentation](https://mastra.ai/reference/logging/pino-logger)\n * if packaged docs are unavailable.\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
@@ -2,6 +2,27 @@ import { LogLevel, MastraLogger, buildLogRecordData, exportTrackedException } fr
2
2
  import pino from "pino";
3
3
  import pretty from "pino-pretty";
4
4
  //#region src/pino.ts
5
+ /**
6
+ * Provides Pino-backed logging for Mastra applications.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { Mastra } from '@mastra/core/mastra';
11
+ * import { PinoLogger } from '@mastra/loggers';
12
+ *
13
+ * const mastra = new Mastra({
14
+ * logger: new PinoLogger({ name: 'my-app', level: 'info' }),
15
+ * });
16
+ * ```
17
+ *
18
+ * @see For documentation bundled with your installed package, locate
19
+ * `@mastra/loggers/package.json` with your project's resolver or package-manager
20
+ * tooling, then read `dist/docs/SKILL.md` from that package root and follow its
21
+ * reference links. Use package-manager tools for virtual or archived packages.
22
+ *
23
+ * @see [Pino logger documentation](https://mastra.ai/reference/logging/pino-logger)
24
+ * if packaged docs are unavailable.
25
+ */
5
26
  var PinoLogger = class PinoLogger extends MastraLogger {
6
27
  logger;
7
28
  #adapterContextRef;
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 * 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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"}
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\n/**\n * Provides Pino-backed logging for Mastra applications.\n *\n * @example\n * ```typescript\n * import { Mastra } from '@mastra/core/mastra';\n * import { PinoLogger } from '@mastra/loggers';\n *\n * const mastra = new Mastra({\n * logger: new PinoLogger({ name: 'my-app', level: 'info' }),\n * });\n * ```\n *\n * @see For documentation bundled with your installed package, locate\n * `@mastra/loggers/package.json` with your project's resolver or package-manager\n * tooling, then read `dist/docs/SKILL.md` from that package root and follow its\n * reference links. Use package-manager tools for virtual or archived packages.\n *\n * @see [Pino logger documentation](https://mastra.ai/reference/logging/pino-logger)\n * if packaged docs are unavailable.\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
@@ -38,6 +38,27 @@ export interface PinoLoggerOptions<CustomLevels extends string = never> {
38
38
  */
39
39
  serializers?: pino.LoggerOptions['serializers'];
40
40
  }
41
+ /**
42
+ * Provides Pino-backed logging for Mastra applications.
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * import { Mastra } from '@mastra/core/mastra';
47
+ * import { PinoLogger } from '@mastra/loggers';
48
+ *
49
+ * const mastra = new Mastra({
50
+ * logger: new PinoLogger({ name: 'my-app', level: 'info' }),
51
+ * });
52
+ * ```
53
+ *
54
+ * @see For documentation bundled with your installed package, locate
55
+ * `@mastra/loggers/package.json` with your project's resolver or package-manager
56
+ * tooling, then read `dist/docs/SKILL.md` from that package root and follow its
57
+ * reference links. Use package-manager tools for virtual or archived packages.
58
+ *
59
+ * @see [Pino logger documentation](https://mastra.ai/reference/logging/pino-logger)
60
+ * if packaged docs are unavailable.
61
+ */
41
62
  export declare class PinoLogger<CustomLevels extends string = never> extends MastraLogger {
42
63
  #private;
43
64
  protected logger: pino.Logger<CustomLevels>;
@@ -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;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"}
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;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,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.2-alpha.0",
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/lint": "0.0.130",
80
- "@internal/types-builder": "0.0.105",
81
- "@mastra/core": "1.64.0"
79
+ "@internal/lint": "0.0.132",
80
+ "@mastra/core": "1.67.0-alpha.3",
81
+ "@internal/types-builder": "0.0.107"
82
82
  },
83
83
  "peerDependencies": {
84
84
  "@mastra/core": ">=1.0.0-0 <2.0.0-0"