Koa.js 中的日志管理

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 本文总结了在 Koa.js 项目中使用第三方日志插件 log4js 的方法,首先是定义log4js的配置,它决定了该如何记录日志。然后在应用入口中使用 log4js,让其生效。

日志

日志用来记录程序的运行信息。开发服务端程序,必须集成日志管理的功能,一旦系统出现故障可以及时排查问题所在。

日志一般分为:

  • 访问日志:记录系统的访问记录。
  • 运行日志:输出系统运行时的一些信息
  • 错误日志:记录系统出错的状态

一般我们都是通过 nginx 做负载均衡,它具备了记录访问日志的功能。所以访问日志交给 Nginx 去做就好。

在后端程序开发中,我们只需要关注运行日志和错误日志。

Koa-logger

Koa.js 官方的日志插件是 koa-logger,功能比较简单,只能打印一些请求的信息,并不会记录日志,不能满足复杂场景的需求。

const logger = require('koa-logger')
​
app.use(logger())
​
// logger
app.use(async (ctx, next) => {
  const start = new Date()
  await next()
  const ms = new Date() - start
  console.log(`${ctx.method} ${ctx.url} - ${ms}ms`)
})

看似是一个日志中间件,本质只是一个 console.log 打印内容的格式化。只能开发模式下打印的更加美观。

所以通常会使用一些第三方的日志模块,比如 log4jswinston 等。

Log4js

Log4js 是一个优秀的日志插件,常用的功能包括按级别输出不同的日志信息,保存日志为文件等。

使用 log4js

安装依赖:

npm install log4js

配置

新建 log4js 的配置文件, utils/log4js.js:

// log4js.js
​
const path = require('path')
const log4js = require('log4js')
​
const { isProd } = require('./index')
​
​
// 日志配置对象
log4js.configure({
  // 日志记录方式
  appenders: {
    // 自定义category为error,记录服务器报错信息
    error: {
      type: 'file',           //日志类型 指定单一文件存储
      filename: path.join('logs/', 'error/error.log'), //日志输出位置,当目录文件或文件夹不存在时自动创建
      maxLogSize: 1024 * 1000 * 100, // 文件最大存储空间,单位是字节 1024k 1m
      backups: 100  //当文件内容超过文件存储空间时,备份文件的数量
    },
​
    // 自定义category为response,记录服务器的响应情况 用户访问服务的情况
    response: {
      type: 'dateFile', // 以日期命名的文件记录日志
      filename: path.join('logs/', 'access/response'),
      pattern: 'yyyy-MM-dd.log', //日志输出模式
      alwaysIncludePattern: true,
​
      // dateFile类型的appender没有这个选项
      maxLogSize: 1024 * 1000 * 100,
      // dateFile类型的appender没有这个选项
      backups: 1
    },
​
    console: {
      type: "console",
      layout: {
        // 开发环境下带颜色输出,生产环境下使用基本输出
        type: isProd ? 'basic' : 'coloured'
      }
    }
  },
​
  // log4js.getLogger(type):就是读取这里的key
  categories: {
    error: { appenders: ['error'], level: 'error' },
    response: { appenders: ['response'], level: 'info' },
    default: { appenders: ['console'], level: 'all' }
  }
​
  replaceConsole: true
})
​
let logger = {}
​
// 自定义输出格式,确定哪些内容输出到日志文件中
const formatError = (ctx, err) => {
  const { method, url } = ctx
  let body = ctx.request.body
  const user = ctx.state.user
​
  // 将请求方法,请求路径,请求体,登录用户,错误信息
  return { method, url, body, user, err }
}
​
const formatRes = (ctx, costTime) => {
  // const { method, url, response: { status, message, body: { success } }, request: { header: { authorization } } } = ctx
  const { ip, method, url, response: { status, message }, request: { header: { authorization } } } = ctx
  let body = ctx.request.body
  const user = ctx.state.user
​
  // 将请求方法,请求路径,请求体,登录用户,请求消耗时间,请求头中的authorization字段即token,响应体中的状态码,消息,以及自定义的响应状态
  return { ip, method, url, body, user, costTime, authorization, response: { status, message } }
}
​
// 生成一个error类型的日志记录器
let errorLogger = log4js.getLogger('error')
​
// 生成一个response类型的日志记录器
let resLogger = log4js.getLogger('response')
​
// 生成一个控制台类型的日志记录器
let console = log4js.getLogger()
​
// 封装错误日志
logger.errLogger = (ctx, error) => {
  if (ctx && error) {
    errorLogger.error(formatError(ctx, error))
  }
}
​
// 封装响应日志
logger.resLogger = (ctx, resTime) => {
  if (ctx) {
    resLogger.info(formatRes(ctx, resTime))
  }
}
​
// 控制台输出
logger.log = console
​
module.exports = logger

在应用中使用 log4js 插件:

const Koa = require('koa')
​
const { isProd } = require('./utils/index')
const { log, errLogger, resLogger } = require('./utils/log4js')
​
​
// 初始化web服务
const app = new Koa()
​
const router = new Router()
​
// 通过log4js记录访问日志
app.use(async (ctx, next) => {
  const start = new Date()
  await next()
  const end = new Date() - start
  // 生产环境下,使用中间件记录日志,使用console.log打印消息。
  // 其他环境下,使用log4js的console打印信息。
  if (isProd) {
    resLogger(ctx, end)
    console.log((`${ctx.method} ${ctx.url} - ${end}ms`))
  } else {
    log.info(`${ctx.method} ${ctx.url} - ${end}ms`)
  }
})
​
// error-handling
app.on('error', (err, ctx) => {
  if (isProd) {
    errLogger(ctx, err);
    log.error(`${ctx.method} ${ctx.url}`, err)
  } else {
    console.error(`${ctx.method} ${ctx.url}`, err)
  }
})

小结

本文总结了在 Koa.js 项目中使用第三方日志插件 log4js 的方法,首先是定义log4js的配置,它决定了该如何记录日志。然后在应用入口中使用 log4js,让其生效。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
2月前
|
缓存 中间件
Nest.js 实战 (九):使用拦截器记录用户 CURD 操作日志
这篇文章介绍了在Nest.js中如何实现记录用户CURD操作的需求。首先解释了什么是拦截器以及拦截器的作用,然后通过创建Prisma模型,添加Log模型,并通过编写LoggerInterceptor拦截器,实现了记录用户操作的功能。最后通过效果演示和总结,强调了使用拦截器实现此功能的有效性。
|
2月前
|
SQL 运维 监控
Nest.js 实战 (十):使用 winston 打印和收集日志记录
这篇文章介绍了在Nest服务中如何使用Winston记录日志。文章首先强调了日志记录在后台服务中的重要性,接着提到Nest默认的内部日志记录器,并指出可以通过@nestjs/common包中的Logger类来全面控制日志系统的行为。文章还提到,为了在生产环境中实现更高级的日志功能,可以使用如Winston之类的Node.js日志包。接下来,文章介绍了如何在Nest服务中使用Winston记录日志,包括安装相关依赖、创建winston配置文件以及实现简单的日志记录示例。最后,文章指出更高级的自定义日志功能需要读者自己去探索。
Nest.js 实战 (十):使用 winston 打印和收集日志记录
|
2月前
|
JavaScript Serverless Linux
函数计算产品使用问题之遇到Node.js环境下的请求日志没有正常输出时,该如何排查
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
2月前
|
SQL JavaScript 前端开发
【Azure 应用服务】Azure JS Function 异步方法中执行SQL查询后,Callback函数中日志无法输出问题
【Azure 应用服务】Azure JS Function 异步方法中执行SQL查询后,Callback函数中日志无法输出问题
|
4月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的公司员工工作日志办公系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的公司员工工作日志办公系统附带文章和源代码部署视频讲解等
31 0
|
5月前
|
JavaScript 前端开发
autox.js如何打印日志?
autox.js如何打印日志?
|
缓存 监控 JavaScript
日志服务(SLS) 的桌面端 Node.js SDK 封装
日志服务(SLS) 的桌面端 Node.js SDK 封装
16182 7
|
Web App开发 JavaScript 测试技术
工银e生活开发脱坑日志(4)工行页面及jsAPI交互接口hybrid_app.js登录情况说明
工银e生活开发脱坑日志(4)工行页面及jsAPI交互接口hybrid_app.js登录情况说明
246 0
|
资源调度 监控
[Nestjs] 使用log4js-node实现日志生成
安装依赖:使用 npm 或 yarn 安装 log4js。
407 0
|
NoSQL JavaScript 前端开发
【Node.js实战】一文带你开发博客项目之Koa2重构(实现session、开发路由、联调、日志)
【Node.js实战】一文带你开发博客项目之Koa2重构(实现session、开发路由、联调、日志)
231 0