Egg.js 日志系统
1. Egg 企业级日志系统解决什么问题Egg 内置日志能力主要由egg-logger提供目标不是简单地console.log而是解决 Web 服务中的如下问题1.日志分级egg 日志级别级别含义适合场景DEBUG调试日志最详细给开发者看的细节本地开发、排查问题INFO普通信息日志记录正常业务流程比如“订单创建成功”WARN警告日志出现异常苗头但不一定导致请求失败ERROR错误日志程序异常、请求失败、服务调用失败NONE不输出日志关闭日志输出日志级别的控制可通过如下进行配置exports.logger{level:INFO,// 默认INFO只打印INFO、WARN、ERROR如果配置WARN则只打印WARN、ERROR其他类推};2.请求上下文日志在请求处理中使用ctx.logger日志里会自动带上请求相关信息例如在代码里写的是ctx.logger.info([AgentChat] chatStream 用户请求入参: %j,{sessionId,message});但是在日志文件里会生成如下2026-07-26 11:22:06,879 INFO 10837 [-/::1/723f86b7-0038-48a9-987f-6e4158c55ab4/342.335ms POST /api/agent/chat/stream] [OpenClaw chatStream] 请求参数 {endpoint:http://dev1-ge.back.jd.com/oxygen/api/oxygen/chat/stream,sessionId:session_xxxx-ec35-4210-937c-xxxx,clientRequestId:req_516de26c-89a1-461b-8f8c-80e9bb5fd3e3}字段含义如下字段示例含义时间2026-07-26 09:54:26,351日志打印时间精确到毫秒日志级别INFO日志等级表示普通信息不是错误进程 ID77817当前 Node/Egg 进程的 PID日志分类[egg:lib:core:logger]打印日志的模块或命名空间日志内容init all loggers with options...具体事件说明3.错误日志集中收敛任意 logger 调用.error()打印的错误日志都会额外进入统一错误日志文件common-error.log。这方便排查线上异常。4.应用日志、框架日志、Agent 日志分离应用业务日志和框架内部日志不会混在一起。5.自动切割默认按天切割。也支持按小时、按文件大小切割。6.高性能默认不是每条日志都立刻写磁盘而是先写入内存 buffer再定时刷盘。2. Egg 日志分类Egg 里最核心的日志可以分成这几类分类Logger 对象常见使用入口默认日志文件主要用途备注应用业务日志appLogger / loggerctx.logger/app.logger${appInfo.name}-web.log例如server-web.log业务代码最常用的日志ctx.logger用于请求内app.logger用于应用级逻辑框架/插件日志coreLoggerctx.coreLogger/app.coreLoggeregg-web.logEgg 框架内部、插件日志普通业务代码一般不用写插件或框架扩展时更常用统一错误日志errorLogger一般不直接调用由所有 logger 的.error()自动汇总common-error.log汇总所有ERROR级别日志方便排查异常例如ctx.logger.error(err)会同时写入业务日志和common-error.logAgent 进程日志agentLoggeragent.logger/agent.coreLoggeregg-agent.logAgent 进程中的日志用于 Egg 多进程模型里的 Agent 进程自定义日志自定义 Logger例如payLogger/auditLoggerapp.getLogger(xxx)/ctx.getLogger(xxx)自定义文件例如pay.log独立业务日志如支付、审计、安全日志通过config.customLogger配置调用.error()也会汇总到common-error.log插件专用日志插件自定义 Logger例如scheduleLogger插件提供的 logger例如 schedule 插件 logger插件自定义例如egg-schedule.log某些插件自己的运行日志不是 Egg 基础必有日志是否存在取决于是否启用对应插件简版记忆ctx.logger / app.logger → 业务日志 → ${appInfo.name}-web.log ctx.coreLogger / app.coreLogger → 框架、插件日志 → egg-web.log 所有 logger.error(...) → 额外复制到 common-error.log agent.logger → Agent 进程日志 → egg-agent.log 自定义 logger → 自定义业务日志 → 自定义文件 scheduleLogger → schedule 插件日志 → egg-schedule.logEgg 默认把日志放在${appInfo.root}/logs/${appInfo.name}本地和单测环境的root是项目目录生产等其他环境的root是 HOME 目录name来自package.json。可以这样自定义日志目录// config/config.default.js exports.logger { dir: /path/to/your/custom/log/dir, };也可以自定义日志文件名// config/config.default.js module.exports appInfo { return { logger: { appLogName: ${appInfo.name}-web.log, coreLogName: egg-web.log, agentLogName: egg-agent.log, errorLogName: common-error.log, }, }; };3. 日志怎么打印3.1 请求处理中优先用ctx.loggerController、Service、Middleware 里处理一次请求时推荐用ctx.logger.info(some request data: %j, ctx.request.body); ctx.logger.warn(业务参数异常%j, ctx.query); ctx.logger.error(new Error(something wrong));为什么请求里推荐用ctx.logger因为它能带上请求上下文信息类似[userid/ip/traceId/12ms GET /api/user] message这样排查问题时可以知道哪个请求触发的日志请求耗时是多少请求路径是什么有没有 traceId 可以串联链路参数与格式化占位符ctx.logger.info([SessionController] 创建会话入口 %s,JSON.stringify({...}));第一个参数是格式化模板,%s是字符串占位符,第二个参数填进占位符位置。常用占位符:%s字符串、%d数字、%jJSON(自动序列化对象)。可简化:用%j省掉手动JSON.stringify:ctx.logger.info([SessionController] 创建会话入口 %j,{requestId,appId});3.2 应用级别用app.logger比如启动阶段、定时任务、应用级初始化逻辑// app.js module.exports app { app.logger.info(应用启动完成); app.logger.warn(某个配置缺失使用默认值); app.logger.error(new Error(启动阶段异常)); };3.3 框架/插件级别用coreLogger如果你是在写框架或插件不建议把框架内部日志打到业务日志里应该用app.coreLogger.info(plugin initialized); ctx.coreLogger.warn(framework warning);3.4 Agent 进程用agent.logger// agent.js module.exports agent { agent.logger.info(agent started); agent.logger.error(new Error(agent error)); };4. 错误日志要特别注意什么Egg 文档里有一个非常重要的建议ctx.logger.error(new Error(whoops));不要随便这样ctx.logger.error(something wrong);虽然字符串也能打印但如果你希望线上异常可追踪最好传Error对象。原因是Error对象有namemessagestackcause自定义属性源码中egg-logger会专门格式化Error输出完整堆栈相关实现可以看egg/packages/logger/src/utils.ts其中formatError()会把错误格式化成包含pid、hostname、stack 等信息的日志。5. 日志切割参考链接日志切割Egg 默认使用eggjs/logrotator进行日志切割。默认按天切割比如当前文件example-app-web.log到第二天会切成example-app-web.log.2026-07-24按大小切割例如egg-web.log超过 2GB 后切割const path require(path); module.exports appInfo { return { logrotator: { filesRotateBySize: [ path.join(appInfo.root, logs, appInfo.name, egg-web.log), ], maxFileSize: 2 * 1024 * 1024 * 1024, }, }; };按小时切割const path require(path); module.exports appInfo { return { logrotator: { filesRotateByHour: [ path.join(appInfo.root, logs, appInfo.name, common-error.log), ], }, }; };切割的定时任务(内置)Egg「约定优于配置」:插件把定时任务放在自己的app/schedule/目录,框架启动自动加载。位置:node_modules/eggjs/logrotator/dist/app/schedule/ ├── rotate_by_file.js → 按天切割 ├── rotate_by_size.js → 按大小切割 ├── rotate_by_hour.js → 按小时切割(默认关闭) └── clean_log.js → 删除过期日志任务文件cron触发时机干什么rotate_by_file.js1 0 0 * * *每天 00:00:01xxx.log→xxx.log.YYYY-MM-DD,建空文件clean_log.js0 0 * * *每天 00:00:00删除超过maxDays天的归档文件rotate_by_size.js每 60 秒轮询持续检查单文件超maxFileSize立即切cron 两种写法都支持:clean_log用标准 5 段(分 时 日 月 周),rotate_by_file用 6 段(最前多了秒)。这些任务本身就是 schedule 任务,所以会产生egg-schedule.log。保留天数与自动清理删除逻辑在clean_log.js的removeExpiredLogFiles:扫描日志目录所有文件;只挑后缀是日期格式的归档文件(如.2026-07-23);算过期线 今天往前推maxDays天;归档日期早于过期线的,直接fs.unlink删除。要点:只删带日期后缀的归档文件,永不删正在写入的活动文件。默认已开启清理,maxDays: 31(保留 31 天)。maxDays: 0表示永不删除、全部保留(才会无限堆积)。logrotator 默认配置logrotator:{disableRotateByDay:false,filesRotateByHour:null,hourDelimiter:-,filesRotateBySize:null,maxFileSize:50*1024*1024,// 50MBmaxFiles:10,// 按大小切割时最多保留数rotateDuration:60000,// 按大小轮询间隔 60smaxDays:31,// 保留天数,0 不删gzip:false,// 归档是否 gzip 压缩}自定义(在config/config.default.ts覆盖)config.logrotator{maxDays:7,// 只留 7 天maxFileSize:100*1024*1024,// 100MBgzip:true,// 归档压缩省空间};11. 源码视角Egg 日志初始化流程可以重点看这几个文件11.1 默认配置egg/packages/egg/src/config/config.default.ts这里定义config.logger { dir: path.join(appInfo.root, logs, appInfo.name), encoding: utf8, env: appInfo.env, level: INFO, consoleLevel: INFO, disableConsoleAfterReady: appInfo.env ! local appInfo.env ! unittest, outputJSON: false, buffer: true, appLogName: ${appInfo.name}-web.log, coreLogName: egg-web.log, agentLogName: egg-agent.log, errorLogName: common-error.log, coreLogger: {}, allowDebugAtProd: false, enableFastContextLogger: true, };11.2 创建 Loggersegg/packages/egg/src/lib/core/logger.ts这里会从app.config.logger读取配置创建EggLoggers生产环境保护 DEBUG应用 ready 后按配置关闭 console注册全局 logger应用关闭时清理全局 logger。11.3 Logger Manageregg/packages/logger/src/egg/loggers.ts这里创建errorLoggerloggercoreLoggercustom loggers并配置错误日志集中logger.duplicate(ERROR, concentrateLogger, { excludes: [console] });也就是说业务 logger 打一条 ERROR除了进入业务日志也会复制一份到common-error.log。12. 推荐实践12.1 业务请求日志ctx.logger.info(创建订单成功orderId%s, order.id);不要打印过大的对象// 不推荐 ctx.logger.info(request body: %j, ctx.request.body);如果 body 很大或有敏感字段应该筛选ctx.logger.info(创建订单请求%j, { userId: ctx.user.id, skuId: ctx.request.body.skuId, count: ctx.request.body.count, });12.2 错误日志推荐try { await service.doSomething(); } catch (err) { ctx.logger.error(err); throw err; }如果要补充上下文try { await service.pay(order); } catch (err) { ctx.logger.error([pay failed] orderId%s userId%s, order.id, ctx.user.id); ctx.logger.error(err); throw err; }12.3 不要滥用debugdebug适合开发和临时排查不适合长期在线上大量打开。12.4 不要在日志里打印敏感信息避免打印passwordtokencookie等12.5 自定义 logger 要克制只有当日志具有明确独立消费场景时才拆比如审计日志安全日志支付流水日志调度执行日志否则优先使用默认app.logger。13. 总结一句话Egg 的日志系统可以理解成业务代码调用 ctx.logger/app.logger ↓ EggLoggers 管理多个 logger ↓ 每个 logger 绑定多个 transporttransport负责判断当前日志级别是否应该输出 ↓ transport 根据日志级别、格式、上下文输出到文件/终端/JSON/远端 ↓ ERROR 日志额外集中到 common-error.log ↓ logrotator 负责日志切割

相关新闻

Spring AI Document类设计与企业级应用实践

Spring AI Document类设计与企业级应用实践

1. Spring AI Document核心功能解析在Spring AI框架中,Document类扮演着数据载体的关键角色。这个看似简单的POJO类实际上承载了AI模型处理过程中的结构化数据流转任务。我最近在几个企业级AI项目中深度使用了这个组件,发现其设计暗含了许多工程实践的智…

2026/10/17 21:41:52 阅读更多 →
【单片机】空闲池结构

【单片机】空闲池结构

#define MSG_POOL_SIZE 8 // 消息池容量 #define MSG_MAX_LEN 256 // 单帧最大长度typedef struct {uint8_t data[MSG_MAX_LEN];uint16_t len;uint8_t in_use; // 1已分配, 0空闲 } msg_block_t;typedef struct {msg_block_t blocks[MSG_POOL_SI…

2026/10/17 20:15:31 阅读更多 →
Coze智能体开发全流程与实战技巧

Coze智能体开发全流程与实战技巧

1. Coze 智能体概述第一次接触Coze平台时,我被"智能体"这个概念深深吸引。这不同于传统聊天机器人,而是一个具备完整身份设定和任务执行能力的AI实体。简单来说,你可以把它想象成一位虚拟员工——有明确的职责范围(天气…

2026/10/17 18:27:13 阅读更多 →

最新新闻

NPDP备考核心:从产品创新工具到组合管理的实战指南

NPDP备考核心:从产品创新工具到组合管理的实战指南

简介:《NPDP Body of Knowledge-2nd》是产品开发与管理协会(PDMA)官方出版的产品创新与产品管理知识体系指南,主要面向备战NPDP认证考试的产品经理和产品开发从业者,也适合希望系统构建产品创新方法论的初中级产品人员…

2026/10/17 23:10:03 阅读更多 →
Raymarching 入门:SDF 与光线步进实现实时渲染

Raymarching 入门:SDF 与光线步进实现实时渲染

1. 从零理解 raymarching:它到底在解决什么问题第一次接触 raymarching 的人,多半是被 Shadertoy 上那些炫酷的实时渲染画面吸引过来的——一个纯片元着色器,没有模型文件,没有顶点数据,却能渲染出体积云、无限分形、流…

2026/10/17 23:10:03 阅读更多 →
Excel数据透视表实战:从数据清洗到多维分析全链路

Excel数据透视表实战:从数据清洗到多维分析全链路

简介:本资源是一份面向Excel初学者与办公人员的《数据透视表应用大全》系统教程,聚焦企业数据分析场景下的核心技能提升。文档全面解析数据透视表的创建逻辑、字段布局规则、多维汇总技巧及常见结构优化方法,覆盖销售分析、区域对比、产品统计…

2026/10/17 23:10:03 阅读更多 →
Python图像处理全流程:从像素操作到连通域分析的避坑指南

Python图像处理全流程:从像素操作到连通域分析的避坑指南

简介:这是一份Python图像处理入门PDF,面向对图像分析与处理感兴趣的初学者,也适合需要快速回顾常用工具方法的技术人员。文档从图像在计算机中的表示讲起:单通道灰度图像对应8位无符号整型矩阵,多通道图像则由红绿蓝三…

2026/10/17 23:10:03 阅读更多 →
无损验证环的秘密:NVIDIA-Nemotron-3.5-Lightning-30B-A3B-DSpark-bf16 中 Mamba-2 递归状态回滚机制解析

无损验证环的秘密:NVIDIA-Nemotron-3.5-Lightning-30B-A3B-DSpark-bf16 中 Mamba-2 递归状态回滚机制解析

【免费下载链接】NVIDIA-Nemotron-3.5-Lightning-30B-A3B-DSpark-bf16 项目地址: https://ai.gitcode.com/hf_mirrors/mlx-community/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-DSpark-bf16 点击查看 免费下载 NVIDIA-Nemotron-3.5-Lightning-30B-A3B-DSpark-bf16 是…

2026/10/17 23:10:03 阅读更多 →
Python Flask + MySQL学生成绩管理系统源码全解析

Python Flask + MySQL学生成绩管理系统源码全解析

简介:面向需要完成数据库课程设计的高校学生,这份MySQL学生成绩管理系统课设报告提供了一套完整的系统设计与实现方案。该系统基于Python Flask与MySQL构建,覆盖管理员、教师、学生三类用户角色,实现选课、成绩录入、修改、删除、…

2026/10/17 23:09:02 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →