xiaozhi-client 1.9.4-beta.2 → 1.9.4-beta.3

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.
Files changed (87) hide show
  1. package/dist/backend/Logger.js +3 -0
  2. package/dist/backend/Logger.js.map +1 -0
  3. package/dist/backend/WebServer.js +93 -0
  4. package/dist/backend/WebServer.js.map +1 -0
  5. package/dist/backend/WebServerLauncher.js +9 -15
  6. package/dist/backend/WebServerLauncher.js.map +1 -1
  7. package/dist/backend/lib/config/manager.js +3 -0
  8. package/dist/backend/lib/config/manager.js.map +1 -0
  9. package/dist/backend/managers/MCPServiceManagerSingleton.js +27 -0
  10. package/dist/backend/managers/MCPServiceManagerSingleton.js.map +1 -0
  11. package/dist/backend/package.json +20 -30
  12. package/dist/backend/templates/json5/xiaozhi.config.json5 +14 -14
  13. package/dist/cli/index.js +4473 -0
  14. package/dist/cli/index.js.map +1 -0
  15. package/package.json +20 -30
  16. package/templates/json5/xiaozhi.config.json5 +14 -14
  17. package/dist/backend/WebServerLauncher.d.ts +0 -1
  18. package/dist/backend/cli.d.ts +0 -1
  19. package/dist/backend/cli.js +0 -129
  20. package/dist/backend/cli.js.map +0 -1
  21. package/dist/cli.js +0 -2
  22. package/dist/docs/404/index.html +0 -19
  23. package/dist/docs/404.html +0 -19
  24. package/dist/docs/_next/static/chunks/112-c9cbd8401d35f825.js +0 -4
  25. package/dist/docs/_next/static/chunks/2a9bc5d7-4c434acf20ba934a.js +0 -1
  26. package/dist/docs/_next/static/chunks/782-c26ca6c69e488d48.js +0 -1
  27. package/dist/docs/_next/static/chunks/799-fe0d35806fd12012.js +0 -1
  28. package/dist/docs/_next/static/chunks/9b1cb2c3-cc9ed703e6aef1a2.js +0 -1
  29. package/dist/docs/_next/static/chunks/app/[[...mdxPath]]/page-48f5c8f3210e0a8a.js +0 -1
  30. package/dist/docs/_next/static/chunks/app/_not-found/page-2e38866a1cbb77e4.js +0 -1
  31. package/dist/docs/_next/static/chunks/app/layout-e8f420537fd59e8d.js +0 -1
  32. package/dist/docs/_next/static/chunks/framework-b73126dabbf07067.js +0 -1
  33. package/dist/docs/_next/static/chunks/main-75dc65850b89d90d.js +0 -1
  34. package/dist/docs/_next/static/chunks/main-app-3303134270964ce6.js +0 -1
  35. package/dist/docs/_next/static/chunks/pages/_app-e698a68d07c8993d.js +0 -1
  36. package/dist/docs/_next/static/chunks/pages/_error-189a41ab5833da03.js +0 -1
  37. package/dist/docs/_next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
  38. package/dist/docs/_next/static/chunks/webpack-10e2bf7d852ddb6e.js +0 -1
  39. package/dist/docs/_next/static/css/2d82b615fcca1590.css +0 -1
  40. package/dist/docs/_next/static/css/b03484a3c350cf6e.css +0 -1
  41. package/dist/docs/_next/static/css/b289318ef4b60b0a.css +0 -1
  42. package/dist/docs/_next/static/media/get-parameter.62eee93d.png +0 -0
  43. package/dist/docs/_next/static/n-fSNbLuSo5pbGuhnk2qQ/_buildManifest.js +0 -1
  44. package/dist/docs/_next/static/n-fSNbLuSo5pbGuhnk2qQ/_ssgManifest.js +0 -1
  45. package/dist/docs/changelog/index.html +0 -585
  46. package/dist/docs/changelog/index.txt +0 -1079
  47. package/dist/docs/images/add-to-cherry-studio/step-1.png +0 -0
  48. package/dist/docs/images/add-to-cherry-studio/step-2.png +0 -0
  49. package/dist/docs/images/add-to-cherry-studio/step-3.png +0 -0
  50. package/dist/docs/images/add-to-cherry-studio/step-4.png +0 -0
  51. package/dist/docs/images/add-to-cherry-studio/step-5.png +0 -0
  52. package/dist/docs/images/add-to-cursor/step-1.png +0 -0
  53. package/dist/docs/images/add-to-cursor/step-2.png +0 -0
  54. package/dist/docs/images/add-to-cursor/step-3.png +0 -0
  55. package/dist/docs/images/coze-workflow/config-workflow-step-1.png +0 -0
  56. package/dist/docs/images/coze-workflow/config-workflow-step-2.png +0 -0
  57. package/dist/docs/images/coze-workflow/config-workflow-step-3.png +0 -0
  58. package/dist/docs/images/coze-workflow/get-parameter.png +0 -0
  59. package/dist/docs/images/integrate-to-cherry-studio.png +0 -0
  60. package/dist/docs/images/integrate-to-cursor.png +0 -0
  61. package/dist/docs/images/modelscope/step-1.png +0 -0
  62. package/dist/docs/images/modelscope/step-2.png +0 -0
  63. package/dist/docs/images/modelscope/step-3.png +0 -0
  64. package/dist/docs/images/modelscope/step-4.png +0 -0
  65. package/dist/docs/images/preview.png +0 -0
  66. package/dist/docs/images/use-multi-xiaozhi-mcp-endpoints/step-1.png +0 -0
  67. package/dist/docs/images/use-multi-xiaozhi-mcp-endpoints/step-2.png +0 -0
  68. package/dist/docs/images/use-multi-xiaozhi-mcp-endpoints/step-3.png +0 -0
  69. package/dist/docs/images/use-multi-xiaozhi-mcp-endpoints/step-4.png +0 -0
  70. package/dist/docs/images/use-multi-xiaozhi-mcp-endpoints/step-5.png +0 -0
  71. package/dist/docs/images/web-ui-preview.png +0 -0
  72. package/dist/docs/index.html +0 -22
  73. package/dist/docs/index.txt +0 -41
  74. package/dist/docs/quickstart/index.html +0 -64
  75. package/dist/docs/quickstart/index.txt +0 -185
  76. package/dist/docs/reference/command/index.html +0 -20
  77. package/dist/docs/reference/command/index.txt +0 -42
  78. package/dist/docs/usage/as-mcp/index.html +0 -36
  79. package/dist/docs/usage/as-mcp/index.txt +0 -101
  80. package/dist/docs/usage/coze-workflow/index.html +0 -35
  81. package/dist/docs/usage/coze-workflow/index.txt +0 -120
  82. package/dist/docs/usage/docker/index.html +0 -40
  83. package/dist/docs/usage/docker/index.txt +0 -154
  84. package/dist/docs/usage/modelscope/index.html +0 -32
  85. package/dist/docs/usage/modelscope/index.txt +0 -109
  86. package/dist/docs/usage/multi-endpoint/index.html +0 -32
  87. package/dist/docs/usage/multi-endpoint/index.txt +0 -118
@@ -0,0 +1,3 @@
1
+ var u=Object.defineProperty;var a=(n,e)=>u(n,"name",{value:e,configurable:!0});import*as s from"fs";import*as r from"path";import f from"chalk";import g from"pino";import{z as L}from"zod";var y=L.enum(["fatal","error","warn","info","debug","trace"]);function F(n){let e=n.getFullYear(),t=String(n.getMonth()+1).padStart(2,"0"),o=String(n.getDate()).padStart(2,"0"),i=String(n.getHours()).padStart(2,"0"),l=String(n.getMinutes()).padStart(2,"0"),c=String(n.getSeconds()).padStart(2,"0");return`${e}-${t}-${o} ${i}:${l}:${c}`}a(F,"formatDateTime");var p=class{static{a(this,"Logger")}logFilePath=null;pinoInstance;isDaemonMode;logLevel;maxLogFileSize=10*1024*1024;maxLogFiles=5;constructor(e="info"){this.isDaemonMode=process.env.XIAOZHI_DAEMON==="true",this.logLevel=this.validateLogLevel(e),this.pinoInstance=this.createPinoInstance()}validateLogLevel(e){let t=e.toLowerCase(),o=y.safeParse(t);return o.success?o.data:"info"}createPinoInstance(){let e=[];if(!this.isDaemonMode){let t=this.createOptimizedConsoleStream();e.push({level:this.logLevel,stream:t})}return this.logFilePath&&e.push({level:this.logLevel,stream:g.destination({dest:this.logFilePath,sync:!1,append:!0,mkdir:!0})}),e.length===0&&e.push({level:this.logLevel,stream:g.destination({dest:"/dev/null"})}),g({level:this.logLevel,timestamp:g.stdTimeFunctions?.isoTime||(()=>`,"time":${Date.now()}`),formatters:{level:a((t,o)=>({level:o}),"level")},base:null,serializers:{err:g.stdSerializers?.err||(t=>t)}},g.multistream(e,{dedupe:!0}))}createOptimizedConsoleStream(){let e=new Map([[20,{name:"DEBUG",color:f.gray}],[30,{name:"INFO",color:f.blue}],[40,{name:"WARN",color:f.yellow}],[50,{name:"ERROR",color:f.red}],[60,{name:"FATAL",color:f.red}]]);return{write:a(t=>{try{let o=JSON.parse(t),i=this.formatConsoleMessageOptimized(o,e);this.safeWrite(`${i}
2
+ `)}catch{this.safeWrite(t)}},"write")}}safeWrite(e){try{process.stderr&&typeof process.stderr.write=="function"&&process.stderr.write(e)}catch{}}formatConsoleMessageOptimized(e,t){let o=F(new Date),i=t.get(e.level)||{name:"UNKNOWN",color:a(m=>m,"color")},l=i.color(`[${i.name}]`),c=e.msg;if(e.args&&Array.isArray(e.args)){let m=e.args.map(d=>typeof d=="object"?JSON.stringify(d):String(d)).join(" ");c=`${c} ${m}`}return`[${o}] ${l} ${c}`}initLogFile(e){this.logFilePath=r.join(e,"xiaozhi.log"),this.rotateLogFileIfNeeded(),s.existsSync(this.logFilePath)||s.writeFileSync(this.logFilePath,""),this.pinoInstance=this.createPinoInstance()}enableFileLogging(e){e&&this.logFilePath&&(this.pinoInstance=this.createPinoInstance())}info(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.info(e):this.pinoInstance.info({args:t},e):this.pinoInstance.info(e,t[0]||"")}success(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.info(e):this.pinoInstance.info({args:t},e):this.pinoInstance.info(e,t[0]||"")}warn(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.warn(e):this.pinoInstance.warn({args:t},e):this.pinoInstance.warn(e,t[0]||"")}error(e,...t){if(typeof e=="string")if(t.length===0)this.pinoInstance.error(e);else{let o=t.map(i=>i instanceof Error?this.pinoInstance.level==="debug"?i.message:{message:i.message,stack:i.stack,name:i.name,cause:i.cause}:i);this.pinoInstance.error({args:o},e)}else{let o=this.enhanceErrorObject(e);this.pinoInstance.error(o,t[0]||"")}}debug(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.debug(e):this.pinoInstance.debug({args:t},e):this.pinoInstance.debug(e,t[0]||"")}log(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.info(e):this.pinoInstance.info({args:t},e):this.pinoInstance.info(e,t[0]||"")}enhanceErrorObject(e){let t={...e};for(let[o,i]of Object.entries(t))i instanceof Error&&(t[o]={message:i.message,stack:i.stack,name:i.name,cause:i.cause});return t}rotateLogFileIfNeeded(){if(!(!this.logFilePath||!s.existsSync(this.logFilePath)))try{s.statSync(this.logFilePath).size>this.maxLogFileSize&&this.rotateLogFile()}catch{}}rotateLogFile(){if(this.logFilePath)try{let e=r.dirname(this.logFilePath),t=r.basename(this.logFilePath,".log");for(let i=this.maxLogFiles-1;i>=1;i--){let l=r.join(e,`${t}.${i}.log`),c=r.join(e,`${t}.${i+1}.log`);s.existsSync(l)&&(i===this.maxLogFiles-1?s.unlinkSync(l):s.renameSync(l,c))}let o=r.join(e,`${t}.1.log`);s.renameSync(this.logFilePath,o)}catch{}}cleanupOldLogs(){if(this.logFilePath)try{let e=r.dirname(this.logFilePath),t=r.basename(this.logFilePath,".log");for(let o=this.maxLogFiles+1;o<=this.maxLogFiles+10;o++){let i=r.join(e,`${t}.${o}.log`);s.existsSync(i)&&s.unlinkSync(i)}}catch{}}setLogFileOptions(e,t){this.maxLogFileSize=e,this.maxLogFiles=t}close(){}setLevel(e){this.logLevel=this.validateLogLevel(e),this.pinoInstance=this.createPinoInstance()}getLevel(){return this.logLevel}},h=null,v="info";function $(n){return new p(n||v)}a($,"createLogger");function I(){return h||(h=new p(v)),h}a(I,"getLogger");function w(n){h=n}a(w,"setGlobalLogger");function z(n){v=n,h&&h.setLevel(n)}a(z,"setGlobalLogLevel");function D(){return v}a(D,"getGlobalLogLevel");var N=I();export{p as Logger,$ as createLogger,D as getGlobalLogLevel,I as getLogger,N as logger,z as setGlobalLogLevel,w as setGlobalLogger};
3
+ //# sourceMappingURL=Logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../apps/backend/Logger.ts"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport chalk from \"chalk\";\nimport pino from \"pino\";\nimport type { Logger as PinoLogger } from \"pino\";\nimport { z } from \"zod\";\n\nconst LogLevelSchema = z.enum([\n \"fatal\",\n \"error\",\n \"warn\",\n \"info\",\n \"debug\",\n \"trace\",\n]);\ntype Level = z.infer<typeof LogLevelSchema>;\n\n/**\n * 格式化日期时间为 YYYY-MM-DD HH:mm:ss 格式\n * @param date 要格式化的日期对象\n * @returns 格式化后的日期时间字符串\n */\nfunction formatDateTime(date: Date): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\n const day = String(date.getDate()).padStart(2, \"0\");\n const hours = String(date.getHours()).padStart(2, \"0\");\n const minutes = String(date.getMinutes()).padStart(2, \"0\");\n const seconds = String(date.getSeconds()).padStart(2, \"0\");\n\n return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;\n}\n\n/**\n * 高性能日志记录器,基于 pino 实现\n *\n * 特性:\n * - 支持控制台和文件双重输出\n * - 支持守护进程模式(仅文件输出)\n * - 支持结构化日志记录\n * - 自动日志文件轮转和管理\n * - 高性能异步写入\n * - 完整的错误堆栈跟踪\n */\nexport class Logger {\n private logFilePath: string | null = null;\n private pinoInstance: PinoLogger;\n private isDaemonMode: boolean;\n private logLevel: Level; // 新增:动态日志级别\n private maxLogFileSize = 10 * 1024 * 1024; // 10MB 默认最大文件大小\n private maxLogFiles = 5; // 最多保留5个日志文件\n\n constructor(level: Level = \"info\") {\n // 检查是否为守护进程模式\n this.isDaemonMode = process.env.XIAOZHI_DAEMON === \"true\";\n\n // 设置并验证日志级别\n this.logLevel = this.validateLogLevel(level);\n\n // 创建 pino 实例\n this.pinoInstance = this.createPinoInstance();\n }\n\n /**\n * 验证日志级别\n * @param level 日志级别\n * @returns 验证后的日志级别\n */\n private validateLogLevel(level: string): Level {\n const normalizedLevel = level.toLowerCase();\n const result = LogLevelSchema.safeParse(normalizedLevel);\n\n if (result.success) {\n return result.data;\n }\n\n return \"info\";\n }\n\n private createPinoInstance(): PinoLogger {\n const streams: pino.StreamEntry[] = [];\n\n // 控制台流 - 只在非守护进程模式下添加\n if (!this.isDaemonMode) {\n // 使用高性能的控制台输出流\n const consoleStream = this.createOptimizedConsoleStream();\n streams.push({\n level: this.logLevel, // 修改:使用动态日志级别\n stream: consoleStream,\n });\n }\n\n // 文件流 - 如果有日志文件路径,使用高性能异步写入\n if (this.logFilePath) {\n streams.push({\n level: this.logLevel, // 修改:使用动态日志级别\n stream: pino.destination({\n dest: this.logFilePath,\n sync: false, // 异步写入提升性能\n append: true,\n mkdir: true,\n }),\n });\n }\n\n // 如果没有流,创建一个空的流避免错误\n if (streams.length === 0) {\n streams.push({\n level: this.logLevel, // 修改:使用动态日志级别\n stream: pino.destination({ dest: \"/dev/null\" }),\n });\n }\n\n return pino(\n {\n level: this.logLevel, // 修改:使用动态日志级别\n // 高性能配置\n timestamp:\n pino.stdTimeFunctions?.isoTime || (() => `,\"time\":${Date.now()}`),\n formatters: {\n // 优化级别格式化\n level: (_label: string, number: number) => ({ level: number }),\n },\n // 禁用不必要的功能以提升性能\n base: null, // 不包含 pid 和 hostname\n serializers: {\n // 优化错误序列化,在测试环境中安全处理\n err: pino.stdSerializers?.err || ((err: any) => err),\n },\n },\n pino.multistream(streams, { dedupe: true })\n );\n }\n\n private createOptimizedConsoleStream() {\n // 预编译级别映射以提升性能\n const levelMap = new Map([\n [20, { name: \"DEBUG\", color: chalk.gray }],\n [30, { name: \"INFO\", color: chalk.blue }],\n [40, { name: \"WARN\", color: chalk.yellow }],\n [50, { name: \"ERROR\", color: chalk.red }],\n [60, { name: \"FATAL\", color: chalk.red }],\n ]);\n\n return {\n write: (chunk: string) => {\n try {\n const logObj = JSON.parse(chunk);\n const message = this.formatConsoleMessageOptimized(logObj, levelMap);\n // 在测试环境中安全地写入\n this.safeWrite(`${message}\\n`);\n } catch (error) {\n // 如果解析失败,直接输出原始内容\n this.safeWrite(chunk);\n }\n },\n };\n }\n\n /**\n * 安全地写入到 stderr,在测试环境中避免错误\n */\n private safeWrite(content: string): void {\n try {\n if (process.stderr && typeof process.stderr.write === \"function\") {\n process.stderr.write(content);\n } else if (console && typeof console.error === \"function\") {\n // 在测试环境中回退到 console.error\n console.error(content.trim());\n }\n } catch (error) {\n // 在极端情况下静默失败,避免测试中断\n }\n }\n\n private formatConsoleMessageOptimized(\n logObj: any,\n levelMap: Map<number, { name: string; color: (text: string) => string }>\n ): string {\n const timestamp = formatDateTime(new Date());\n\n const levelInfo = levelMap.get(logObj.level) || {\n name: \"UNKNOWN\",\n color: (text: string) => text,\n };\n const coloredLevel = levelInfo.color(`[${levelInfo.name}]`);\n\n // 处理结构化日志中的 args,保持兼容性\n let message = logObj.msg;\n if (logObj.args && Array.isArray(logObj.args)) {\n const argsStr = logObj.args\n .map((arg: any) =>\n typeof arg === \"object\" ? JSON.stringify(arg) : String(arg)\n )\n .join(\" \");\n message = `${message} ${argsStr}`;\n }\n\n return `[${timestamp}] ${coloredLevel} ${message}`;\n }\n\n /**\n * 初始化日志文件\n * @param projectDir 项目目录\n */\n initLogFile(projectDir: string): void {\n this.logFilePath = path.join(projectDir, \"xiaozhi.log\");\n\n // 检查并轮转日志文件\n this.rotateLogFileIfNeeded();\n\n // 确保日志文件存在\n if (!fs.existsSync(this.logFilePath)) {\n fs.writeFileSync(this.logFilePath, \"\");\n }\n\n // 重新创建 pino 实例以包含文件流\n this.pinoInstance = this.createPinoInstance();\n }\n\n /**\n * 设置是否启用文件日志\n * @param enable 是否启用\n */\n enableFileLogging(enable: boolean): void {\n // 在 pino 实现中,文件日志的启用/禁用通过重新创建实例来实现\n // 这里保持方法兼容性,但实际上文件日志在 initLogFile 时就已经启用\n if (enable && this.logFilePath) {\n // 重新创建 pino 实例以确保文件流正确配置\n this.pinoInstance = this.createPinoInstance();\n }\n }\n\n /**\n * 记录信息级别日志\n * @param message 日志消息\n * @param args 额外参数\n * @example\n * logger.info('用户登录', 'userId', 12345);\n * logger.info({ userId: 12345, action: 'login' }, '用户登录');\n */\n info(message: string, ...args: any[]): void;\n /**\n * 记录结构化信息级别日志\n * @param obj 结构化日志对象\n * @param message 可选的日志消息\n */\n info(obj: object, message?: string): void;\n info(messageOrObj: string | object, ...args: any[]): void {\n if (typeof messageOrObj === \"string\") {\n if (args.length === 0) {\n this.pinoInstance.info(messageOrObj);\n } else {\n this.pinoInstance.info({ args }, messageOrObj);\n }\n } else {\n // 结构化日志支持\n this.pinoInstance.info(messageOrObj, args[0] || \"\");\n }\n }\n\n success(message: string, ...args: any[]): void;\n success(obj: object, message?: string): void;\n success(messageOrObj: string | object, ...args: any[]): void {\n // success 映射为 info 级别,保持 API 兼容性\n if (typeof messageOrObj === \"string\") {\n if (args.length === 0) {\n this.pinoInstance.info(messageOrObj);\n } else {\n this.pinoInstance.info({ args }, messageOrObj);\n }\n } else {\n this.pinoInstance.info(messageOrObj, args[0] || \"\");\n }\n }\n\n warn(message: string, ...args: any[]): void;\n warn(obj: object, message?: string): void;\n warn(messageOrObj: string | object, ...args: any[]): void {\n if (typeof messageOrObj === \"string\") {\n if (args.length === 0) {\n this.pinoInstance.warn(messageOrObj);\n } else {\n this.pinoInstance.warn({ args }, messageOrObj);\n }\n } else {\n this.pinoInstance.warn(messageOrObj, args[0] || \"\");\n }\n }\n\n error(message: string, ...args: any[]): void;\n error(obj: object, message?: string): void;\n error(messageOrObj: string | object, ...args: any[]): void {\n if (typeof messageOrObj === \"string\") {\n if (args.length === 0) {\n this.pinoInstance.error(messageOrObj);\n } else {\n // 改进错误处理 - 特殊处理 Error 对象\n const errorArgs = args.map((arg) => {\n if (arg instanceof Error) {\n if (this.pinoInstance.level === \"debug\") return arg.message;\n return {\n message: arg.message,\n stack: arg.stack,\n name: arg.name,\n cause: arg.cause,\n };\n }\n return arg;\n });\n this.pinoInstance.error({ args: errorArgs }, messageOrObj);\n }\n } else {\n // 结构化错误日志,自动提取错误信息\n const enhancedObj = this.enhanceErrorObject(messageOrObj);\n this.pinoInstance.error(enhancedObj, args[0] || \"\");\n }\n }\n\n debug(message: string, ...args: any[]): void;\n debug(obj: object, message?: string): void;\n debug(messageOrObj: string | object, ...args: any[]): void {\n if (typeof messageOrObj === \"string\") {\n if (args.length === 0) {\n this.pinoInstance.debug(messageOrObj);\n } else {\n this.pinoInstance.debug({ args }, messageOrObj);\n }\n } else {\n this.pinoInstance.debug(messageOrObj, args[0] || \"\");\n }\n }\n\n log(message: string, ...args: any[]): void;\n log(obj: object, message?: string): void;\n log(messageOrObj: string | object, ...args: any[]): void {\n // log 方法使用 info 级别\n if (typeof messageOrObj === \"string\") {\n if (args.length === 0) {\n this.pinoInstance.info(messageOrObj);\n } else {\n this.pinoInstance.info({ args }, messageOrObj);\n }\n } else {\n this.pinoInstance.info(messageOrObj, args[0] || \"\");\n }\n }\n\n /**\n * 增强错误对象,提取更多错误信息\n */\n private enhanceErrorObject(obj: any): any {\n const enhanced = { ...obj };\n\n // 遍历对象属性,查找 Error 实例\n for (const [key, value] of Object.entries(enhanced)) {\n if (value instanceof Error) {\n enhanced[key] = {\n message: value.message,\n stack: value.stack,\n name: value.name,\n cause: value.cause,\n };\n }\n }\n\n return enhanced;\n }\n\n /**\n * 检查并轮转日志文件(如果需要)\n */\n private rotateLogFileIfNeeded(): void {\n if (!this.logFilePath || !fs.existsSync(this.logFilePath)) {\n return;\n }\n\n try {\n const stats = fs.statSync(this.logFilePath);\n if (stats.size > this.maxLogFileSize) {\n this.rotateLogFile();\n }\n } catch (error) {\n // 忽略文件状态检查错误\n }\n }\n\n /**\n * 轮转日志文件\n */\n private rotateLogFile(): void {\n if (!this.logFilePath) return;\n\n try {\n const logDir = path.dirname(this.logFilePath);\n const logName = path.basename(this.logFilePath, \".log\");\n\n // 移动现有的编号日志文件\n for (let i = this.maxLogFiles - 1; i >= 1; i--) {\n const oldFile = path.join(logDir, `${logName}.${i}.log`);\n const newFile = path.join(logDir, `${logName}.${i + 1}.log`);\n\n if (fs.existsSync(oldFile)) {\n if (i === this.maxLogFiles - 1) {\n // 删除最老的文件\n fs.unlinkSync(oldFile);\n } else {\n fs.renameSync(oldFile, newFile);\n }\n }\n }\n\n // 将当前日志文件重命名为 .1.log\n const firstRotatedFile = path.join(logDir, `${logName}.1.log`);\n fs.renameSync(this.logFilePath, firstRotatedFile);\n } catch (error) {\n // 轮转失败时忽略错误,继续使用当前文件\n }\n }\n\n /**\n * 清理旧的日志文件\n */\n cleanupOldLogs(): void {\n if (!this.logFilePath) return;\n\n try {\n const logDir = path.dirname(this.logFilePath);\n const logName = path.basename(this.logFilePath, \".log\");\n\n // 删除超过最大数量的日志文件\n for (let i = this.maxLogFiles + 1; i <= this.maxLogFiles + 10; i++) {\n const oldFile = path.join(logDir, `${logName}.${i}.log`);\n if (fs.existsSync(oldFile)) {\n fs.unlinkSync(oldFile);\n }\n }\n } catch (error) {\n // 忽略清理错误\n }\n }\n\n /**\n * 设置日志文件管理参数\n */\n setLogFileOptions(maxSize: number, maxFiles: number): void {\n this.maxLogFileSize = maxSize;\n this.maxLogFiles = maxFiles;\n }\n\n /**\n * 关闭日志文件流\n */\n close(): void {\n // pino 实例会自动处理流的关闭\n // 这里保持方法兼容性\n }\n\n /**\n * 动态设置日志级别\n * @param level 新的日志级别\n * @description 动态更新Logger实例的日志级别\n */\n setLevel(level: Level): void {\n this.logLevel = this.validateLogLevel(level);\n\n // 重新创建pino实例以应用新的日志级别\n this.pinoInstance = this.createPinoInstance();\n }\n\n /**\n * 获取当前日志级别\n * @returns 当前日志级别\n */\n getLevel(): Level {\n return this.logLevel;\n }\n}\n\n// 全局Logger实例管理\nlet globalLogger: Logger | null = null;\nlet globalLogLevel: Level = \"info\"; // 全局日志级别\n\n/**\n * 创建Logger实例\n * @param level 日志级别,默认为全局级别\n * @returns Logger实例\n */\nexport function createLogger(level?: Level): Logger {\n return new Logger(level || globalLogLevel);\n}\n\n/**\n * 获取全局Logger实例\n * @returns 全局Logger实例\n */\nexport function getLogger(): Logger {\n if (!globalLogger) {\n globalLogger = new Logger(globalLogLevel); // 使用全局级别\n }\n return globalLogger;\n}\n\n/**\n * 设置全局Logger实例\n * @param logger 新的Logger实例\n */\nexport function setGlobalLogger(logger: Logger): void {\n globalLogger = logger;\n}\n\n/**\n * 设置全局日志级别\n * @param level 新的日志级别\n * @description 更新全局日志级别,并影响现有和未来的Logger实例\n */\nexport function setGlobalLogLevel(level: Level): void {\n globalLogLevel = level;\n\n // 如果已存在全局Logger实例,更新其级别\n if (globalLogger) {\n globalLogger.setLevel(level);\n }\n}\n\n/**\n * 获取当前全局日志级别\n * @returns 当前日志级别\n */\nexport function getGlobalLogLevel(): Level {\n return globalLogLevel;\n}\n\n// 导出默认实例(向后兼容)\nexport const logger = getLogger();\n"],"mappings":"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","names":["fs","path","chalk","pino","z","LogLevelSchema","z","formatDateTime","date","year","month","day","hours","minutes","seconds","__name","Logger","level","normalizedLevel","result","streams","consoleStream","pino","_label","number","err","levelMap","chalk","chunk","logObj","message","content","timestamp","levelInfo","text","coloredLevel","argsStr","arg","projectDir","enable","messageOrObj","args","errorArgs","enhancedObj","obj","enhanced","key","value","logDir","logName","oldFile","newFile","firstRotatedFile","i","maxSize","maxFiles","globalLogger","globalLogLevel","createLogger","getLogger","setGlobalLogger","logger","setGlobalLogLevel","getGlobalLogLevel"]}