十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

NocoBase Logger 日志系统深度解析:从 ctx.logger 客户端调试到服务端日志治理

NocoBase Logger 日志系统深度解析:从 ctx.logger 客户端调试到服务端日志治理 NocoBase Logger 日志系统深度解析从 ctx.logger 客户端调试到服务端日志治理【免费下载链接】nocobaseNocoBase is an open-source AI no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobaseNocoBase 内置了一套完整的日志系统让开发者无论在服务端插件、请求处理上下文还是应用运行过程中都能通过统一的logger实例记录结构化日志。本篇以官方文档《Logger 日志客户端》为主线结合 packages/core/logger 的真实实现源码系统讲解ctx.logger/app.logger的六种日志级别、结构化 JSON 输出格式、上下文绑定、子 Logger 自定义以及环境变量配置、输出通道Transport、请求日志脱敏等服务端治理能力帮助你写出可追踪、可分析、可运维的高质量插件日志。基本用法在任何 context 中记录日志NocoBase 的日志 API 遵循「在拥有context的地方即可获取日志实例」的设计。无论是插件的执行上下文、模型实例还是请求处理链路都可以直接通过ctx.logger调用各级别方法记录日志// 记录致命错误例如初始化失败 ctx.logger.fatal(应用初始化失败, { error }); // 记录一般错误例如接口请求出错 ctx.logger.error(数据加载失败, { status, message }); // 记录警告信息例如性能风险或用户操作异常 ctx.logger.warn(当前表单包含未保存的更改); // 记录一般运行信息例如组件加载完成 ctx.logger.info(用户资料组件加载完成); // 记录调试信息例如状态变化 ctx.logger.debug(当前用户状态, { user }); // 记录详细跟踪信息例如渲染流程 ctx.logger.trace(组件渲染完成, { component: UserProfile });这六个方法对应六种日志级别从高到低级别方法说明fatalctx.logger.fatal()致命错误通常导致程序退出errorctx.logger.error()错误日志表示请求或操作失败warnctx.logger.warn()警告信息提示潜在风险或非预期情况infoctx.logger.info()常规运行信息debugctx.logger.debug()调试信息用于开发环境tracectx.logger.trace()详细跟踪信息通常用于深度诊断从源码层面看日志实例的级别体系在 packages/core/logger/src/logger.ts 中定义为trace: 4, debug: 3, info: 2, warn: 1, error: 0createLogger()通过level: getLoggerLevel()应用当前阈值低于阈值的日志会被过滤。需要说明的是官方文档描述该系统“基于 pino”而当前仓库nocobase/logger包的实际底层实现基于winston见 logger.ts并自建了trace级别与 pino 风格的方法命名fatal/error/warn/info/debug/trace因此 API 用法与级别语义与 pino 保持一致可放心按本文示例使用。日志格式默认的结构化 JSON每条日志输出均为结构化 JSON 格式默认包含以下字段字段类型说明levelnumber日志级别timenumber时间戳毫秒pidnumber进程 IDhostnamestring主机名msgstring日志消息其他object自定义上下文信息示例输出{ level: 30, time: 1730540153064, pid: 12765, hostname: nocobase.local, msg: HelloModel rendered, a: a }在仓库实现中日志格式由 packages/core/logger/src/format.ts 统一负责支持四种内置格式jsonwinston.format.json({ deterministic: false })生产环境默认格式方便日志平台采集与检索console人类可读的带颜色控制台输出[INFO]、[DEBUG]等标签开发环境默认格式logfmtkeyvalue键值对形式参考 brandur.org/logfmt适合 grep 与命令行管道处理delimiter以|分隔字段适合与现有日志清洗管线对接。其中json与console的默认切换逻辑在 packages/core/logger/src/config.ts 中APP_ENVdevelopment时默认console否则默认json——也就是说开发环境看可读日志、生产环境出 JSON 是开箱即用的默认行为。上下文绑定让每条日志自带来源信息ctx.logger会自动注入上下文信息例如当前插件、模块或请求来源使日志能更准确地追踪来源plugin.context.logger.info(Plugin initialized); model.context.logger.error(Model validation failed, { model: User });输出示例带上下文{ level: 30, msg: Plugin initialized, plugin: plugin-audit-trail }服务端请求链路中packages/core/logger/src/request-logger.ts 会在每个请求进入时创建带reqId、module、submodule的子 Logger 并挂载到ctx.loggerctx.app.log.child({ reqId, module: path?.[1], submodule: path?.[2] })。其中module与submodule从 API 路径解析例如/api/xxx:yyy会拆出xxx与yyy并把reqId写入响应头X-Request-Id从而让一条请求从进入到返回的日志可以按reqId串联检索。自定义日志通过 child 创建子 Logger你可以在插件中创建自定义的 logger 实例继承或扩展默认配置const logger ctx.logger.child({ module: MyPlugin }); logger.info(Submodule started);子 logger 会继承主 logger 的配置并自动附加上下文。在服务端nocobase/logger对child方法做了特殊代理见 packages/core/logger/src/system-logger.ts确保Error对象的stack、message、cause也能随子 Logger 一并写入弥补了 winston 原生 child 对error.cause支持的不足。日志级别划分数值阈值与过滤规则日志级别遵循从高到低的数值定义数值越大优先级越高等级名称数值方法名说明fatal60logger.fatal()致命错误通常导致程序无法继续运行error50logger.error()一般错误表示请求失败或操作异常warn40logger.warn()警告信息提示潜在风险或非预期情况info30logger.info()普通信息记录系统状态或正常操作debug20logger.debug()调试信息用于开发阶段分析问题trace10logger.trace()详细跟踪信息用于深入诊断silent-Infinity无对应方法关闭所有日志输出过滤规则系统只会输出大于或等于当前level配置的日志。例如当日志级别为info时debug和trace的日志将被忽略。这套“数值阈值过滤”语义在源码createLogger中通过level: getLoggerLevel()生效而自定义的trace级别映射为 winston 的levels定义见 logger.tssilent则通过process.env.LOGGER_SILENT true直接关闭所有输出。环境变量与运行时配置虽然文档正文侧重 API 用法但要让日志真正可用环境变量配置是关键一环。从 packages/core/logger/src/config.ts 与 transports.ts 可以梳理出以下开箱即用的配置项环境变量默认值说明LOGGER_LEVELAPP_ENVdevelopment时debug否则info全局日志级别阈值LOGGER_TRANSPORTconsole,dailyRotateFile输出通道支持console、file、dailyRotateFileLOGGER_FORMATAPP_ENVdevelopment时console否则json日志格式logfmt/json/delimiter/consoleLOGGER_SILENTfalse设为true关闭所有日志输出LOGGER_MAX_SIZE1024 * 1024 * 2020MBfile 通道单个日志文件大小上限LOGGER_MAX_FILES10file 通道/14ddailyRotateFile 通道保留文件数量或天数日志文件默认写入storage/logs目录getLoggerFilePath()基于storagePathJoin(logs)解析且dirname支持绝对路径相对路径会以process.cwd()为基准解析见 transports.ts。应用级日志的默认配置默认应用配置在 packages/core/app/src/config/logger.ts 中request与system两套日志均使用getLoggerTransport()与getLoggerLevel()export default { request: { transports: getLoggerTransport(), level: getLoggerLevel(), }, system: { transports: getLoggerTransport(), level: getLoggerLevel(), }, } as AppLoggerOptions;AppLoggerOptions的定义见 packages/core/server/src/application.ts包含request请求日志与system系统日志两部分。应用级日志system / request / sql 三套实例在 packages/core/server/src/application.ts 的initLogger()中每个应用实例会创建三套相互独立的日志app.logger系统日志createSystemLogger({ dirname, filename: system, seperateError: true })用于记录应用与插件运行日志可通过app.logger获取getter 见 application.tsapp.requestLogger请求日志createLogger({ dirname, filename: request })由请求中间件逐条记录每个 API 请求的进出app.sqlLoggerSQL 日志createLogger({ filename: sql, level: debug })记录数据库执行的 SQL默认级别为debug仅在调试时需要开启。其中系统日志的seperateError: true意味着 error 级别日志会额外写入独立的system_error.log文件见 system-logger.ts方便快速定位异常。实际运行中插件加载链路就是典型的app.logger使用场景例如 packages/core/server/src/plugin-manager/plugin-manager.ts 中通过this.app.logger.trace/debug记录插件的load、install等生命周期事件this.app.logger.trace(before load plugin [${name}], { submodule: plugin-manager, method: load, name }); this.app.logger.debug(install plugin [${name}]...);请求日志自动统计耗时与敏感信息脱敏packages/core/logger/src/request-logger.ts 的requestLogger中间件会在每个请求完成后输出两条日志请求进入时request METHOD url携带method、path、请求头白名单字段x-role、x-hostname、x-locale等、action、app、reqId请求结束时response url携带status、cost毫秒耗时、userId/username、bodySize等并按状态码分级——5xx 记error、4xx 记warn、其余记info。出于安全考虑默认黑名单会剔除密码类字段避免敏感信息落入日志见 request-logger.tsconst defaultActionBlackList [ params.values.password, params.values.confirmPassword, params.values.oldPassword, params.values.newPassword, ];同时支持通过requestWhitelist/responseWhitelist定制请求、响应字段的采集范围skip回调可对指定请求跳过日志适合排除健康检查等高频率请求。在插件开发中的最佳实践使用上下文日志在插件、模型或应用上下文中使用ctx.logger/app.logger可自动携带module、reqId等来源信息便于按请求或模块串联排查。区分日志级别使用error记录业务异常服务端会额外写入system_error.log使用info记录状态变化如插件安装、模型加载使用debug记录开发调试信息使用trace记录细粒度的执行链路如插件生命周期。避免过量日志尤其在debug与trace级别下建议仅在开发环境开启APP_ENVdevelopment时默认即为debug生产环境保持info阈值避免 I/O 与磁盘开销。使用结构化数据传入对象参数而非拼接字符串日志平台才能按字段索引、过滤与聚合对敏感字段密码、Token 等务必脱敏后再记录。通过以上方式开发者可以更高效地追踪插件执行过程、排查问题并保持日志系统的结构化与可扩展性——无论你在前端控制台调试客户端逻辑还是在服务端治理请求与系统日志NocoBase 这套以logger为核心的日志体系都能提供一致的体验与完整的可观测性。【免费下载链接】nocobaseNocoBase is an open-source AI no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表