express-日志、开发环境、生产环境
为了记录在开发的过程以及项目使用过程中的操作,通常会使用日志记录用户操作
日志的使用
日志
由于使用的是express的脚手架创建项目,所以自带了一个日志的插件,我们可以直接使用这个插件进行打印和保存日志
打印日志
在开发的时候可以打印日志进行查看操作
var logger = require('morgan');
// 使用morgan中间件,默认格式直接打印日志
app.use(logger('dev'));
// 自定义格式打印日志 具体格式类型可以去查看文档
app.use(logger(':method :url :status :res[content-length] - :response-time ms'));
打印结果
将log写入文件中
由于打印日志是在开发的时候使用的,所以要对用户的操作日志进行保存,要将日志写入文件中,写入文件中有两种方法
1、使用fs进行文件写入
var logger = require('morgan');
var fs = require('fs')
const accessLogStream = fs.createWriteStream(path.join(__dirname, '/log/access.log'), {
flags: 'a'
})
app.use(logger(function (tokens, req, res) {
return [
tokens.method(req, res),
tokens.url(req, res),
tokens.status(req, res),
tokens.res(req, res, 'content-length'), '-',
tokens['response-time'](req, res), 'ms'
].join(' ')
}, {stream: accessLogStream}));
2、使用插件file-stream-rotator进行文件写入
由于用户数量太多,所有日志写入同一个文件会导致文件内容太多,所以需要分不同文件插入,这里可以使用file-stream-rotator插件进行对文件进行每天插入一个文件中(具体用法格式等可以参考文档)
安装插件
npm i file-stream-rotator -S
引用插件
var fileStreamRotato = require('file-stream-rotator')
写入文件
// 写入文件中 file-stream-rotator所有日志
// 这个会写入所有的日志
var accessLogStream = fileStreamRotato.getStream({
filename:'./log/access-%DATE%.log',
frequency:'daily',
verbose:false,
date_format:'YYYYMMDD'
})
app.use(logger(function (tokens, req, res) {
return [
tokens.method(req, res),
tokens.url(req, res),
tokens.status(req, res),
tokens.res(req, res, 'content-length'), '-',
tokens['response-time'](req, res), 'ms'
].join(' ')
}, {stream: accessLogStream}));
// 使用skip可以写入错误操作的日志
// 写入文件中 file-stream-rotator 错误日志
var accessLogStreamErr = fileStreamRotato.getStream({
filename:'./log/access-err-%DATE%.log',
frequency:'daily',
verbose:false,
date_format:'YYYYMMDD'
})
app.use(logger(function (tokens, req, res) {
return [
tokens.method(req, res),
tokens.url(req, res),
tokens.status(req, res),
tokens.res(req, res, 'content-length'), '-',
tokens['response-time'](req, res), 'ms'
].join(' ')
}, {
stream: accessLogStreamErr,
skip: function (req, res) { return res.statusCode < 400 }
}));
封装log代码
之前都是在app.js上进行日志操作,但是app.js作为入口函数,不应该写过多的代码,所以对日志代码进行封装
封装准备
创建一个utils文件夹,文件夹中创建一个logger.js文件 如图
logger.js代码
// 日志的封装
// 写入文件中 file-stream-rotator所有日志
var express = require('express');
var logger = require('morgan');
var fileStreamRotato = require('file-stream-rotator')
var app = express()
var accessLogStream = fileStreamRotato.getStream({
filename: './log/access-%DATE%.log',
frequency: 'daily',
verbose: false,
date_format: 'YYYYMMDD'
})
// 格式化日志输出格式 由于代码重复,对输出格式进行封装
function formatLog(tokens, req, res) {
return [
tokens.method(req, res),
tokens.url(req, res),
tokens.status(req, res),
decodeURI(tokens.url(req, res)), // 获取get参数
JSON.stringify(req.body),
tokens.res(req, res, 'content-length'), '-',
tokens['response-time'](req, res), 'ms'
].join(' ')
}
const accessLog = (logger(function (tokens, req, res) {
return formatLog(tokens, req, res)
}, {stream: accessLogStream}));
// 写入文件中 file-stream-rotator 错误日志
var accessLogStreamErr = fileStreamRotato.getStream({
filename: './log/access-err-%DATE%.log',
frequency: 'daily',
verbose: false,
date_format: 'YYYYMMDD'
})
const accessLogErr = (logger(function (tokens, req, res) {
return formatLog(tokens, req, res)
}, {
stream: accessLogStreamErr,
skip: function (req, res) {
return res.statusCode < 400
}
}));
// 导出代码
module.exports = {accessLog, accessLogErr, logger}
app.js的部分代码
const logger = require('./utils/logger')
// 写入所有日志
app.use(logger.accessLog)
// 写入错误日志
app.use(logger.accessLogErr)
// 打印日志
app.use(logger.logger('dev'))
生产环境和开发环境
由于开发和部署到服务器上以后的使用是在不同的环境中,所以每次部署之前都要对代码进行修改,这样的话太麻烦了,express脚手架封装了判断开发环境还是生产环境的代码,所以我么可以对代码进行配置,这样就可以让代码自动判断当前环境
环境配置
在package.json文件中对启动命令进行配置
打印当前环境
express中的这段代码会对当前环境进行判断使用npm run dev 和 npm run start会在控制台上打印当前的环境
根据当前环境判断是将日志保存到文件还是打印在控制台上
由于开发的时候不需要将日志打印在控制台上,所以对环境进行判断是将日志保存到文件还是打印在控制台上
if (process.env.NODE_ENV === 'development'){
// 开发环境打印日志不保存
app.use(logger.logger('dev'))
}else {
// 生产环境
app.use(logger.accessLog)
app.use(logger.accessLogErr)
}
根据生产环境的开放环境的判断可以对数据库之类的进行不同的配置,这样就不需要在每一次部署都要修改配置数据了