说明
对于后端程序应用来说,日志是必不可少的,在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-logger
:npm i koa-logger --save
-
修改
app.js
const logger = require('koa-logger')
// middleware
app.use(logger())
增加时间
-
下载
moment
:npm 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-onerror
:npm 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-log4
在log4js-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 || '服务器错误'
}
})
发表评论