后端微服务云原生【免费下载链接】midway A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 项目地址https://gitcode.com/gh_mirrors/mi/midway点击查看免费下载导读Midway 为不同场景提供了一套统一、开箱即用的日志接入方式底层基于社区广受欢迎的 [winston] 日志库winston 是对 node 生态非常流行的日志方案的统称具体指winstonjs/winston项目。本文以 logger.md 为主线完整覆盖普通使用、默认日志对象、日志路径、装饰器/API 获取、输出格式、日志等级、日志切割、标签label、自定义日志、显示格式定制以及 EggJSmidwayjs/web下的兼容配置。读完本文你将掌握 Midway 日志体系的全部核心 API 与配置方式并能在自己的项目中灵活定制日志行为。简介Midway 的统一日志体系Midway 通过midwayjs/logger包导出的方法为不同场景提供统一的日志接入方式。其设计核心是无论你在 WebKoa/Egg、gRPC、Socket.io 还是其他框架下开发日志 API 保持一致。从源码结构看框架层面通过 loggerService.ts 中的MidwayLoggerService统一管理日志对象的创建与获取它继承自ServiceFactoryILogger内部持有一个LoggerFactory实例。而 loggerFactory.ts 定义了抽象工厂的契约createLogger(name, options)创建日志对象getLogger(loggerName)获取日志对象close/removeLogger关闭与移除getDefaultMidwayLoggerConfig(appInfo)生成框架默认日志配置midwayLogger.default与midwayLogger.clientscreateContextLogger(ctx, appLogger, contextOptions)创建上下文日志这意味着框架启动时默认的coreLogger、appLogger会通过默认配置自动初始化业务层无需任何额外配置即可使用。普通使用三行代码接入日志日常开发中最常见的用法是直接通过装饰器注入日志对象import { Get } from midwayjs/decorator; import { Inject, Controller, Provide } from midwayjs/decorator; Provide() Controller() export class HelloController { Inject() logger; // 获取上下文日志等价于 ctx.logger Logger(logger) appLogger; // 获取 appLogger非请求链路下比如 configuration 或者单例中 Inject() ctx; Get(/) async ctx() { // 请求链路的日志包含请求的 url请求协议等信息 this.logger.info(hello world); // 普通日志 this.appLogger.info(hello world); } }访问接口后日志会出现在两个地方console 栏可以看到输出日志目录的midway-app.log文件中。输出结果示例2021-07-22 14:50:59,388 INFO 7739 [-/::ffff:127.0.0.1/-/0ms GET /api/get_user] hello world可以看到请求链路日志上下文日志自动携带了请求的 IP、耗时、方法、路由等信息方便问题定位。默认日志对象coreLogger / appLogger / 上下文日志Midway 默认已将日志库埋入整个框架框架启动时就能自动输出信息到控制台与文件。默认逻辑为将日志输出到控制台并写入文件按日期每天切割同时按文件大小切割将错误.error()输出的内容统一输出到一个固定的错误文件。框架默认提供三种日志对应三种不同的行为日志释义描述常见使用coreLogger框架、组件层面的日志默认输出控制台日志和文本日志midway-core.log并且默认会将错误日志发送到common-error.log框架和组件的错误一般打印到其中appLogger业务层面的日志默认输出控制台日志和文本日志midway-app.log并且默认会将错误日志发送到common-error.log业务使用的日志一般业务日志打印到其中上下文日志复用 appLogger 的配置请求链路的日志默认使用appLogger进行输出除了会将错误日志发送到common-error.log之外还增加了上下文信息修改日志输出的标记Label不同的框架有不同的请求标记比如 HTTP 下就会输出路由信息从 loggerService.ts 的init()方法可以看到框架是如何组装这套默认体系的它先通过loggerFactory.getDefaultMidwayLoggerConfig(appInfo)拿到默认配置并合并进用户配置然后initClients(this.configService.getConfiguration(midwayLogger))初始化所有客户端最后把appLogger以别名logger注册到应用上下文容器registerObject(logger, this.getLogger(appLogger))。这也解释了为什么业务代码里Inject() logger拿到的是appLogger。日志路径和文件默认情况下Midway 会在本地开发和服务器部署时输出日志到日志根目录本地日志根目录为${app.appDir}/logs/项目名目录下服务器日志根目录为用户目录${process.env.HOME}/logs/项目名Linux/Mac以及${process.env.USERPROFILE}/logs/项目名Windows下例如/home/admin/logs/example-app。日志根目录下默认生成以下文件midway-core.log框架、组件打印信息的日志对应coreLoggermidway-app.log应用打印信息的日志对应appLoggercommon-error.log所有错误的日志所有 Midway 创建出来的日志都会将错误重复打印一份到该文件。:::info 在 EggJSmidwayjs/web下为了兼容以前的日志依旧会将日志打印在midway-web.log下。这一点可以从 config.default.ts 看到web 框架的默认配置将appLogger.fileLogName改为midway-web.log并设置了aliasName: logger与contextFormat来格式化上下文日志。 :::使用日志对象一般来说框架开发者需要获取coreLogger记录框架、组件层面的日志业务开发者需要获取appLogger记录业务日志在业务和请求相关的流程中则需要拿到上下文日志对象方便追踪请求。使用装饰器获取日志对象在任意类中都可以通过装饰器获取日志对象。1、获取coreLoggerimport { Provide, Logger } from midwayjs/decorator; import { ILogger } from midwayjs/logger; Provide() export class UserService { Logger() coreLogger: ILogger; // 获取 coreLogger Logger(coreLogger) anotherLogger: ILogger; // 这里和依赖注入的规则相同依旧获取的是 coreLogger async getUser() { // this.coreLogger this.anotherLogger this.coreLogger.warn(warn message); } }2、获取appLogger为了使用更简单Midway 将appLogger的 key 变为了最为普通的loggerimport { Provide, Logger } from midwayjs/decorator; import { ILogger } from midwayjs/logger; Provide() export class UserService { Logger() logger: ILogger; // 获取 appLogger async getUser() { this.logger.info(hello user); this.coreLogger.warn(warn message); } }3、获取上下文日志对象Context Logger上下文日志是在每个请求实例中动态创建的日志对象因此它和请求作用域绑定即和请求实例绑定。Midway 默认会将上下文日志对象挂载到上下文ctx上即ctx.loggerimport { Provide, Logger } from midwayjs/decorator; import { ILogger } from midwayjs/logger; Provide() export class UserService { Inject() logger: ILogger; // 获取上下文日志 async getUser() { this.logger.info(hello user); } }:::info 和全局的日志不同上下文日志对象默认会放在请求作用域的依赖注入容器中它的 key 为logger所以可以使用Inject装饰器注入它。 :::从实现上看Logger装饰器定义在 framework.ts本质是DecoratorManager.createCustomPropertyDecorator(LOGGER_KEY, { identifier })与App、Config等共用一套属性装饰器机制解析时框架会通过loggerService.getLogger(identifier)完成注入。使用 API 接口获取日志对象有时候我们不在 Class 的场景下可以直接从app上的方法获取这些默认的日志对象import { Provide, Logger } from midwayjs/decorator; import { ILogger } from midwayjs/logger; Provide() export class UserService { App() app: IMidwayApplication; Inject() ctx; async getUser() { this.app.getLogger(logger).info(hello user); // 获取 appLogger this.app.getLogger(coreLogger).warn(warn message); // 获取 coreLogger // this.ctx.logger 获取请求上下文日志 } }输出方法和格式Midway 的日志对象继承自 winston 的日志对象一般情况下只提供error()、warn()、info()、debug()四种方法logger.debug(debug info); logger.info(启动耗时 %d ms, Date.now() - start); logger.warn(warning!); logger.error(new Error(my error));默认的输出行为在大部分普通类型下日志库都能工作得很好logger.info(hello world); // 输出字符串 logger.info(123); // 输出数字 logger.info([b, c]); // 输出数组 logger.info(new Set([2, 3, 4])); // 输出 Set logger.info( new Map([ [key1, value1], [key2, value2], ]) ); // 输出 Map:::info Midway 针对 winston 无法输出的Array、Set、Map类型做了特殊定制使其也能正常输出。 :::需要注意的是日志对象在一般情况下只能传入一个参数它的第二个参数有其他作用logger.info(plain error message, 321); // 会忽略 321错误输出针对错误对象Midway 也对 winston 做了定制使其能方便地和普通文本结合到一起输出// 输出错误对象 logger.error(new Error(error instance)); // 输出自定义的错误对象 const error new Error(named error instance); error.name NamedError; logger.error(error); // 文本在前加上 error 实例 logger.info(text before error, new Error(error instance after text));:::caution 注意错误对象只能放在最后且有且只有一个其后面的所有参数都会被忽略。 :::格式化内容基于util.format的格式化方式logger.info(%s %d, aaa, 222);常用的占位符有%s字符串占位%d数字占位%jjson 占位更多占位符和详细信息可以参考 Node.js 官方文档中util.format方法的说明node 内置模块无需额外依赖。输出自定义对象或者复杂类型基于性能考虑Midwaywinston大部分时间只会输出基本类型所以当输出的参数为高级对象时需要用户手动转换为需要打印的字符串。如下示例将不会得到希望的结果const obj { a: 1 }; logger.info(obj); // 默认情况下输出 [object Object]需要手动输出希望打印的内容const obj { a: 1 }; logger.info(JSON.stringify(obj)); // 可以输出格式化文本 logger.info(obj.a); // 直接输出属性值 logger.info(%j, obj); // 直接占位符输出整个 json纯输出内容特殊场景下我们需要单纯地输出内容不希望输出时间戳、label 等和格式相关的信息。这种需求可以使用write方法。write方法是个非常底层的方法并且不管什么级别的日志它都会写入到文件中。虽然write方法在每个 logger 上都有但只在IMidwayLogger定义中提供它希望你明确地知道自己在调用它(logger as IMidwayLogger).write(hello world); // 文件中只会有 hello world日志定义ILogger 与 IMidwayLogger默认情况下用户应该使用最简单的ILogger定义import { Provide, Logger } from midwayjs/decorator; import { ILogger } from midwayjs/logger; Provide() export class UserService { Inject() logger: ILogger; // 获取上下文日志 async getUser() { this.logger.info(hello user); } }ILogger定义只提供最简单的debug、info、warn以及error方法。在某些场景下我们需要更为复杂的定义比如修改日志属性或者动态调节此时需要使用更为复杂的IMidwayLogger定义import { Provide, Logger } from midwayjs/decorator; import { IMidwayLogger } from midwayjs/logger; Provide() export class UserService { Inject() logger: IMidwayLogger; // 获取上下文日志 async getUser() { this.logger.disableConsole(); // 禁止控制台输出 this.logger.info(hello user); // 这句话在控制台看不到 this.logger.enableConsole(); // 开启控制台输出 this.logger.info(hello user); // 这句话在控制台可以看到 } }IMidwayLogger的完整定义可以参考midwayjs/logger包中 interface 的描述对应的接口源码在独立的midwayjs/logger仓库中维护。日志等级winston 的日志等级分为以下几类等级依次降低数字越大等级越低const levels { none: 0, error: 1, trace: 2, warn: 3, info: 4, verbose: 5, debug: 6, silly: 7, all: 8, }在 Midway 中为了简化一般情况下只使用error、warn、info、debug这四种等级。日志等级表示当前可输出日志的最低等级。比如当日志 level 设置为warn时仅warn以及更高的error等级的日志能被输出。框架的默认等级Midway 有自己的默认日志等级在开发环境下local、test、unittest日志等级统一为info在服务器环境除开发环境外为减少日志数量日志等级统一为warn。动态调整等级在开发调试时我们往往有动态调整等级的诉求。Midway 的日志支持方法级动态调整logger.updateLevel(debug); // 动态调整等级为 debug也可以单独调整文本和控制台输出的等级// 动态调整文件的日志等级 logger.updateFileLevel(warn); // 动态调整控制台输出日志等级 logger.updateConsoleLevel(error);日志输出管道TransportMidway 的日志对象基于 Winston 日志默认包含三个日志管道ConsoleTransport用于向控制台输出日志FileTransport用于向文件写入日志ErrorTransport用于将 Error 级别输出到特定的错误日志我们可以通过方法动态更新这三个管道控制输出logger.enableFile(); logger.disableFile(); logger.enableConsole(); logger.disableConsole(); logger.enableError(); logger.disableError();同时还提供了判断的 APIlogger.isEnableConsole(); logger.isEnableFile(); logger.isEnableError();日志切割轮转默认行为下同一个日志对象会生成两个文件。以midway-core.log为例应用启动时会生成一个带当日时间戳midway-core.YYYY-MM-DD格式的文件以及一个不带时间戳的midway-core.log软链文件。为方便配置日志采集和查看该软链文件永远指向最新的日志文件。当凌晨00:00时会生成一个以当天日志结尾midway-core.log.YYYY-MM-DD的形式的新文件。同时当单个日志文件超过 200M 时也会自动切割产生新的日志文件。日志标签label日志标签label指的是日志输出时带有[xx]的部分。默认的日志标签默认情况下Midway 对coreLogger的标签做了特殊处理使用coreLogger输出的日志会自动携带当前的框架信息。比如2021-01-22 12:34:24,354 INFO 34458 [midway:gRPC] Find 1 class has gRPC provider decorator 2021-01-22 12:34:24,372 INFO 34458 [midway:gRPC] Proto helloworld.Greeter found and add to gRPC server 2021-01-22 12:34:24,381 INFO 34458 [midway:gRPC] Server port 6565 start success 2021-01-22 12:34:24,416 INFO 34458 [midway:gRPC] Server shutdown successMidway 没有对appLogger做特殊处理即输出的日志不带标签。Midway 对contextLogger做了特殊处理默认的标签会关联上下文信息。比如在 Web 下会输出 ip、method、path 等2021-01-20 15:13:25,408 INFO 66376 [-/127.0.0.1/-/5ms GET /] xxxx修改日志标签有两个地方可以修改日志标签。1、初始化时const logger this.app.createLogger(custom, { // 创建了一个日志等级为 level只输出到终端的日志 level: info, defaultLabel: main label, }); logger.info(hello world); // output 2021-01-20 15:13:25,408 INFO 66376 [main label] hello world2、动态调整const logger this.app.createLogger(custom, { // 创建了一个日志等级为 level只输出到终端的日志 level: info, }); // 可以传递一个字符串 logger.info(hello world, { label: UserService }); // output 2021-01-20 15:13:25,408 INFO 66376 [UserService] hello world // 也可以传递数组会使用:进行组合 logger.info(hello world, { label: [a, b] }); // output 2021-01-20 15:13:25,408 INFO 66376 [a:b] hello world:::info 注意动态调整标签不会影响默认标签即下一次如果不带{label: xxx}依旧会输出默认标签。 :::自定义日志如果用户不满足于默认的日志对象也可以自行创建。创建日志有两种方法从 app/framework 创建从日志库midwayjs/logger创建不管哪一种都是代理自日志容器的createLogger方法。日志容器日志容器用来存放日志对象以及管理日志对象你可以把它理解为一个 Mapkey 为日志对象的名称value 为日志对象本身。默认情况下引入midwayjs/logger库时会在全局创建一个日志容器import { loggers } from midwayjs/logger; console.log(loggers); // 当前全局默认的日志容器所有通过框架以及自定义创建的日志对象都会存储其中。每次使用Logger装饰器以及app.getLogger()获取日志的行为本质上都是从默认的日志容器中获取同名的日志对象import { Provide, Logger } from midwayjs/decorator; import { ILogger } from midwayjs/logger; Provide() export class UserService { App() app: IMidwayApplication; Logger() logger; // 即 loggers.getLogger(logger) async getUser() { // 即 loggers.getLogger(coreLogger) this.app.getLogger(coreLogger).warn(warn message); } }除了getLogger之外还有其他一些方法这些最基础的方法可以以最原始的方式来获取、修改日志对象import { loggers, ILogger } from midwayjs/logger; const customLogger loggers.createLogger(customLogger, { // ... }); customLogger.info(hello world); loggers.getLogger(customLogger); // 从容器获取一个日志 loggers.addLogger(anotherLogger, customLogger); // 添加一个新的日志 loggers.removeLogger(customLogger); // 移除一个日志 loggers.close(); // 关闭并移除所有日志这种方法一般用于和框架无关的场景需要传递相对完整的参数比如日志文件的路径等。同时midwayjs/logger也提供两个简化的方法用于快速创建日志import { createLogger, createConsoleLogger } from midwayjs/logger; // 一个只有控制台输出的日志并添加到默认的日志容器中 const consoleLogger createConsoleLogger(customConsoleLogger); // 一个只写文本的日志并添加到默认的日志容器中不会将错误转到其他日志也不会输出控制台 const onlyFileLogger createFileLogger(customOnlyFileConsoleLogger, { dir: logsDir, fileLogName: test-logger.log, }); // 文本日志并添加到默认的日志容器中 const fileLogger createLogger(customFileLogger, { level: warn, dir: __dirname, });注意如果创建同名的日志日志容器会自动判断重名跳过创建并返回原有日志对象const customLogger1 loggers.createLogger(customLogger, { // ... }); const customLogger2 loggers.createLogger(customLogger, { // ... }); // customLogger1 customLogger2:::info 这个特性很有用使得在不同场景下能够让业务使用到同一个日志对象。 :::从当前框架、App 创建日志在大多数情况下用户会使用这种方式创建日志。Midway 在app上增加了createLogger方法以方便用户快速基于框架默认的日志配置创建自己的日志实例。比如在入口的configuration.ts中我们可以创建出自己的日志export class AutoConfiguration { App() app: IMidwayApplication; async onReady() { this.app.createLogger(custom1); // 创建一个全功能的自定义日志 this.app.createLogger(custom2, { // 创建了一个日志等级为 level只输出到终端的日志 level: error, disableFile: true, disableError: true, }); this.app.createLogger(custom3, { fileLevel: warn, // 只修改文件日志等级 disableConsole: true, // 禁止终端输出 }); } }这样创建出的日志会自动绑定到框架中并且使用框架默认的路径创建日志后期可以直接根据日志名获取使用import { ILogger } from midwayjs/logger; export class UserService { Logger(custom1) custom1Logger: ILogger; Logger(custom2) custom2Logger: ILogger; Logger(custom3) custom3Logger: ILogger; }:::info 所有创建的日志在全局日志容器loggers中都能获取到。创建日志等价于在全局日志容器中调用loggers.createLogger()方法。 :::从实现上印证MidwayLoggerService.createLogger见 loggerService.ts正是委托给loggerFactory.createLogger同时createClient支持aliasName别名映射和lazyLoad懒加载两种能力框架把appLogger以别名logger注册正是依赖这套别名机制。相关的行为在 base-app-logger 测试夹具 中也有验证this.app.createLogger(otherLogger)返回的对象与this.app.getLogger(otherLogger)严格相等Logger() logger与app.getLogger(logger)也严格相等。创建日志选项createLogger方法支持的所有参数如下用户可以自行调整更多选项可参考midwayjs/logger包 interface 中LoggerOptions的描述选项作用level日志等级如info、warn、error、debugfileLevel仅修改文件日志等级consoleLevel仅修改控制台日志等级defaultLabel默认日志标签输出[xx]部分printFormat自定义单行输出格式返回字符串的方法dir日志输出目录从日志库直接创建时必须显式指定fileLogName文件日志名如midway-app.logdisableFile禁止文件输出disableConsole禁止控制台输出disableError禁止错误日志转到common-error.log这些选项与 loggerFactory.ts 中定义的getDefaultMidwayLoggerConfig返回结构midwayLogger.default与midwayLogger.clients一一对应框架启动时会先取默认配置再与用户配置合并因此用户只需在config.default.ts中修改midwayLogger.clients即可覆盖任意默认日志的行为。修改显示格式Display显示格式指的是日志输出时单行文本的字符串结构。Midway 对 Winston 的日志做了定制提供了一些默认对象。显示格式是一个返回字符串结构的方法参数为 Winston 的 info 对象。默认情况下显示格式为(info) { return ${info.timestamp} ${info.LEVEL} ${info.pid} ${info.labelText}${info.message}; };输出如下2020-12-30 07:50:10,453 ERROR 3847 [customLabel] Error: another test error at Object.anonymous (/home/runner/work/midway/midway/packages/logger/test/index.test.ts:224:18)info 对象的默认属性如下属性名描述示例timestamp时间戳默认为YYYY-MM-DD HH:mm:ss,SSS格式2020-12-30 07:50:10,453level小写的日志等级infoLEVEL大写的日志等级INFOpid当前进程 pid3847labelText标签的聚合文本[abcde]message普通消息 错误消息 错误堆栈的组合普通文本如123456、hello world错误文本错误名堆栈Error: another test error at Object.anonymous (...)普通文本错误文本hello world Error: another test error at ...stack错误堆栈originError原始错误对象错误实例本身originArgs原始的用户入参[a, b, c]示例创建一个自定义格式的 Loggerexport class AutoConfiguration { App() app: IMidwayApplication; async onReady() { this.app.createLogger(custom1, { printFormat: (info) { return ${info.timestamp} ${info.level} ${info.message}; }, }); this.app.getLogger(custom1).info(hello world); } }该日志的输出效果则为2020-12-30 07:50:10,453 info hello world动态修改默认显示内容在某些场景下我们无法在初始化时修改日志对象如果希望修改输出内容也可以使用动态修改 info 对象的值来达到类似的效果logger.updateTransformableInfo((info) { info.timestamp 123; return info; });在原有输出的时间字段的位置则会变成123,408 INFO 66376 [-/127.0.0.1/-/5ms GET /] xxxx:::info 注意该方法只能修改属性值但是不能修改输出结构。 :::配置框架日志Midway 在框架中提供了默认日志如果需要修改默认日志的行为可以在初始化框架时传入不同的日志对象进行覆盖。覆盖框架日志框架的初始化入口一般为下面的代码在其中创建日志实例替换即可const { Bootstrap } require(midwayjs/bootstrap); import { Framework } from midwayjs/koa; import { createLogger, createConsoleLogger } from midwayjs/logger; // 一个只有控制台输出的日志 const consoleLogger createConsoleLogger(customConsoleLogger); // 文本日志 const fileLogger createLogger(customFileLogger, { dir: __dirname, }); const koaFramework new Framework().configure({ port: 7001, logger: consoleLogger, // or fileLogger }); Bootstrap.load(koaFramework).run();覆盖请求链路日志的 Label每个框架Framework可能会有默认的上下文日志输出。ContextLogger 是基于 appLogger 来打日志的会复用 appLogger 的所有信息唯一不同的是ContextLogger 会输出特殊的 label。比如 HTTP 下的默认输出为2021-01-20 15:13:25,408 INFO 66376 [-/127.0.0.1/-/5ms GET /] xxxxlabel 为-/127.0.0.1/-/5ms GET /这一部分。我们可以通过重写上下文日志类来修改上下文输出信息ContextLogger的 label。首先你需要定义一个文件继承默认的MidwayContextLogger类实现formatContextLabel来返回 label 内容。比如 HTTP 下// src/custom/logger.ts import { MidwayContextLogger } from midwayjs/logger; import { Context } from egg; export class MidwayCustomContextLogger extends MidwayContextLoggerContext { formatContextLabel() { const ctx this.ctx; return ${Date.now() - ctx.startTime}ms ${ctx.method}; } }Midway 为每个框架的 app 增加了一个setContextLoggerClass方法用于覆盖默认的ctx.logger输出的 label。你可以在启动时进行覆盖// configuration.ts import { Configuration } from midwayjs/decorator; import { ILifeCycle, IMidwayContainer } from midwayjs/core; import { MidwayCustomContextLogger } from ./custom/logger; import { Application } from egg; Configuration() export class ContainerConfiguration implements ILifeCycle { App() app: Application; async onReady(container: IMidwayContainer): Promisevoid { this.app.setContextLoggerClass(MidwayCustomContextLogger); } }则你在使用ctx.logger输出时会默认变成你 format 的样子ctx.logger.info(hello world); // 2021-01-28 11:10:19,334 INFO 9223 [2ms POST] hello world在 web 框架侧上下文日志的默认格式同样可以通过配置定制。以 config.default.ts 中的appLogger.contextFormat为例它读取ctx.userId、ctx.traceId或ctx.tracer.traceId、ctx.ip、耗时与ctx.method、ctx.url组装成[userId/ip/traceId/use_ms method url]的完整请求追踪标签这也是请求链路日志能够自动带出调用链信息的关键所在。midwayjs/webEggJS下特殊情况:::info 在 2021-01-28 之前创建的项目默认使用 egg-logger之后创建的项目将使用midwayjs/logger。 :::兼容配置由于 Egg 下原日志配置是非 API 形式统一放在 config 文件中在这一场景下我们依旧支持大部分的参数用于快速将应用迁移到新的日志体系。以下配置只在 Egg 下生效。config.logger配置项说明dir日志根目录level文本日志等级consoleLevel控制台日志等级errorLogName错误日志文件名coreLogNamecore 日志文件名agentLogNameagent 日志名appLogName应用日志名disableConsoleAfterReadyready 之后禁止控制台输出config.customLogger配置项说明dir日志根目录file日志文件名level文本日志等级consoleLevel控制台日志等级替换日志库默认情况下脚手架生成的日志库为midwayjs/logger并且默认关闭 egg 的日志切割能力因为 midway 的日志库自带了。如果希望继续使用egg-logger可以通过配置改回// src/config.default.ts export const midwayFeature { // true 代表 使用 midway logger // false 或者为空代表使用 egg-logger replaceEggLogger: false, };同时由于 egg-logger 日志需要额外开启切割能力需要开启切割插件// src/config/plugin.ts import { EggPlugin } from egg; export default { logrotator: true, // 这行改成 true或者删掉 static: false, } as EggPlugin;调整默认 level// config.local.ts export const logger { level: INFO, consoleLevel: WARN, };启动输出开发时框架的默认输出都使用coreLoggeregg 默认的coreLogger的consoleLevel为WARN如有查看的需求可以覆盖默认的 egg 配置// config.local.ts export const logger { coreLogger: { consoleLevel: INFO, }, };小结Midway 的日志体系以midwayjs/logger为核心向下统一封装了 winston 的管道、格式与等级机制向上为框架、业务、请求链路三个层次提供了coreLogger、appLogger、上下文日志三套默认对象并借助日志容器、createLogger、printFormat、updateLevel等 API 提供从创建到定制的完整能力。无论是快速接入、动态调级、自定义标签、日志切割还是 EggJS 场景下的兼容迁移都可以在框架文档 logger.md 与源码loggerService.ts、loggerFactory.ts、config.default.ts中找到对应的依据与落地方式。赞分享后端微服务云原生【免费下载链接】midway A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 项目地址https://gitcode.com/gh_mirrors/mi/midway点击查看免费下载相关推荐PlayIntegrityFix日志系统自定义日志框架实现PlayIntegrityFix日志系统自定义日志框架实现 日志系统在Android逆向工程中的关键作用 在Android应用开发与逆向工程领域日志系统扮演应用安全系统编程Egg 框架日志系统深度指南分类、配置、自定义与日志切割Egg 框架日志系统深度指南分类、配置、自定义与日志切割 日志是 Web 应用可观测性的基石直接关系到线上问题排查效率与运行状态监控。本文以 Egg 框架内后端Web框架OpenSpec社区贡献指南如何参与开源项目开发OpenSpec社区贡献指南如何参与开源项目开发 OpenSpec是一个创新的规范驱动开发框架旨在帮助开发者与AI编码助手在编写代码之前就达成共识。如果你对开发工具CLIAI 应用工作流自动化上一篇终极对比TeleStyleV2-Qwen-Image-Edit-2511-bf16 vs 传统风格迁移工具优势究竟在哪里下一篇如何快速上手EGO-Planner-v2零配置无人机集群仿真终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考