Koa框架日志和错误日志

说明

对于后端程序应用来说,日志是必不可少的,在nodeJs当中并没有自带的日志模块

原生logger

  • 修改app.js文件
// 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`) })

koa-logger

在控制台输出请求日志,可以配合moment(格式化时间)使用

基本使用

  • 下载koa-loggernpm i koa-logger --save

  • 修改app.js

const logger = require('koa-logger') // middleware app.use(logger())

增加时间

  • 下载momentnpm i moment --save

  • 修改app.js

const logger = require('koa-logger') const Moment = require('moment') // middleware app.use(logger(str => { console.log(Moment().format('YYYY-MM-DD HH:mm:ss') + str) }))

koa-onerror

  • 下载koa-onerrornpm i koa-onerror --save

  • 修改app.js文件

const onerror = require('koa-onerror') // error handler onerror(app) app.on('error', (err, ctx) => { console.error('server', err, ctx) })
  • 修改app.js,修改404设置,设置404显示页面
app.use(async (ctx, next) => { await next() if (ctx.status == 404) { ctx.status = 404; await ctx.render('404', {}) } })

log4js

  • 在根目录下新建logger/目录

  • logger/目录下新建logs/目录,用来存放日志文件

  • logger/目录下新建log4js.js文件

const path = require('path') const log4js = require('log4js'); //加载log4js模块 log4js.configure({ appenders: { info: { type: "dateFile", filename: path.join(__dirname, 'logs', 'info', 'info'),// 您要写入日志文件的路径 //compress: true, //(默认为false) - 在滚动期间压缩备份文件(备份文件将具有.gz扩展名) pattern: "yyyy-MM-dd.log", //(可选,默认为.yyyy-MM-dd) - 用于确定何时滚动日志的模式。格式:.yyyy-MM-dd-hh:mm:ss.log encoding: 'utf-8', // default "utf-8",文件的编码 // maxLogSize: 10000000, // 文件最大存储空间,当文件内容超过文件存储空间会自动生成一个文件xxx.log.1的序列自增长的文件 alwaysIncludePattern: true, //(默认为false) - 将模式包含在当前日志文件的名称以及备份中 }, error: {// 错误日志 type: 'dateFile', filename: path.join(__dirname, 'logs', 'error', 'error'), pattern: 'yyyy-MM-dd.log', encoding: 'utf-8', // default "utf-8",文件的编码 // maxLogSize: 10000000, // 文件最大存储空间,当文件内容超过文件存储空间会自动生成一个文件xxx.log.1的序列自增长的文件 alwaysIncludePattern: true } }, categories: { default: { appenders: ['info'], level: 'info' }, info: { appenders: ['info'], level: 'info' }, error: { appenders: ['error'], level: 'error' } } }); /** * 错误日志记录方式 * @param {*} content 日志输出内容 */ function logError(content) { const log = log4js.getLogger("error"); log.error(content) } /** * 日志记录方式 * @param {*} content 日志输出内容 */ function logInfo(content) { const log = log4js.getLogger("info"); log.info(content) } module.exports = { logError, logInfo }
  • 修改app.js文件,捕获全局状态下的error
const log4js = require('./logger/log4js') app.on('error', (err, ctx) => { log4js.logError(err) }) app.on('error-info', (err, ctx) => { log4js.logInfo(err) })
  • try-catch中可以使用ctx.app.emit('error', e, ctx)抛出错误;或者使用ctx.app.emit('error-info', e, ctx)抛出info错误

koa-log4

log4js-node是一款比较好的在node环境下对于日志处理的模块

koa-log4log4js-node的基础上做了一次包装,是koa的一个处理日志的中间件,此模块可以帮助你按照你配置的规则分叉日志消息。

  • 在根目录下新建logger/目录

  • logger/目录下新建logs/目录,用来存放日志文件

  • logger/目录下新建index.js文件

const path = require('path') const log4js = require('koa-log4') log4js.configure({ appenders: { access: { type: 'dateFile', // 生成文件的规则 pattern: '-yyyy-MM-dd.log', // 文件名始终以日期区分 alwaysIncludePattern: true, encoding: 'utf-8', // 生成文件路径和文件名 filename: path.join(__dirname, 'logs', 'access') }, application: { type: 'dateFile', pattern: '-yyyy-MM-dd.log', alwaysIncludePattern: true, encoding: 'utf-8', filename: path.join(__dirname, 'logs', 'application') }, out: { type: 'console' } }, categories: { default: { appenders: ['out'], level: 'info' }, access: { appenders: ['access'], level: 'info' }, application: { appenders: ['application'], level: 'WARN' } } }) // // 记录所有访问级别的日志 // exports.accessLogger = () => log4js.koaLogger(log4js.getLogger('access')) // // 记录所有应用级别的日志 // exports.logger = log4js.getLogger('application') module.exports = { // 记录所有访问级别的日志 accessLogger: () => log4js.koaLogger(log4js.getLogger('access')), // 记录所有应用级别的日志 logger: log4js.getLogger('application') }
  • 访问级别的,记录用户的所有请求,作为koa的中间件,直接使用便可。修改app.js文件
const { accessLogger } = require('./logger/logger') app.use(accessLogger())
  • 应用级别的日志,可记录全局状态下的error,修改app.js全局捕捉异常
const { logger } = require('./logger/logger') // 在try-catch错误是无法监听的 // 需要手动释放:ctx.app.emit('error', err, ctx) // 或者在try-catch中直接logger.error(e) // 在需要的代码中放入即可监听 app.on('error', (err, ctx) => { logger.error(err) // 这里可以优化下,开发环境才记录日志 // if (process.env.NODE_ENV !== 'development') { // logger.error(err) // } })
  • 应用级别的日志,也可记录接口请求当中的错误处理。
const { logger } = require('../logger/logger') router.get('/test', async ctx => { try { ddd() ctx.body = 'test' } catch (e) { logger.error(e) // 用这种方式手动释放也可以 - app.js文件里面,已经监听了error事件 // ctx.app.emit('error', e, ctx) ctx.body = { code: -1, msg: e.message } } })

全局错误捕捉

app.js文件中有个app.on('error', (err, ctx) => { //... })
这个只能捕捉到应用的错误。比如在路由,在控制器中出现的错误捕捉不到

可以写一个中间件,用来捕捉全局的错误

  • 修改app.js文件,添加捕获全局错误代码
/* 错误捕捉中间件 */ app.use(async(ctx, next) => { try { // 这里给ctx对象添加了一个error方法 // 后面的代码中,当执行ctx.error方法时,就会抛出一个异常 // 这样,在其他的路由或中间件里,代码执行到ctx.error时就会直接跳回到这个的错误捕捉中间件,ctx.error后面的代码就不会再执行了 ctx.error = (code, message) => { if (typeof code === 'string') { message = code code = 500 } ctx.throw(code || 500, message || '服务器错误') } await next() } catch (e) { log4js.logError(e) const status = e.status || 500 ctx.error(status, e.message || '服务器错误') // ctx.status = e.status || 500 // ctx.body = e.message || '服务器错误' } })

创作不易,若本文对你有帮助,欢迎打赏支持作者!

 分享给好友: