node服务:日志、配置、路由与控制器
日志框架winston
- 系统发布上线,出了bug?保存在文件中日志
- 记录系统运行的日志,包括正常,异常等
- 安装日志框架:
cnpm i -S winston
-S保存到package.json文件 - 添加日志框架配置文件
app/util/logger.js
- 输出日志默认json格式, 可以使用
format
选项配置输出格式 - 输出2种方式:控制台(便于开发调试),文件(发布后调试)
- 新创建日志文件 2个条件:文件达到指定大小 或 按天记录
logger.js文件:
const {createLogger, format, transports} = require("winston") //记录日志
//自定义日志格式 添加时间
const myFormat = format.printf(log => {
return `${log.timestamp} ${log.level}: ${log.message}`
})
//日志级别: info普通 warn error
const logger = createLogger({ //创建日志记录对象
level: "info", //指定输出日志级别
// format: winston.format.simple(), //指定输出日志格式
format: format.combine( //使用组合的方式 给日志加时间
format.timestamp(), //时间
myFormat
),
transports: [
new transports.Console(), //把日志输出在控制台
//指定保存的文件 .当前目录
new transports.File({filename: './logs/log.log'})
]
})
export default logger
可配置性
- 后端框架需要可配置(系统后端测试环境8081 线上环境8082 改代码)
- 改配置文件 或 环境变量
process.env
可以package.json
配置(npm run dev
) cross-env PORT=4000
设置环境变量为4000- 文件:
config/config.js
//配置文件config/config.js
const config = {
//配置环境变量 若有环境变量则使用 否则使用默认的
port: process.env.PORT || 3000
}
export default config
//package.json
{
"name": "0",
"version": "1.0.0",
"description": "",
"main": "express-run.js",
"scripts": {
"start": "cross-env PORT=4000 babel-node main.js",
"dev": "babel-node main.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"babel-cli": "^6.26.0",
"babel-node": "^0.0.1-security",
"babel-plugin-add-module-exports": "^1.0.2",
"babel-preset-env": "^1.7.0",
"body-parser": "^1.19.0",
"cross-env": "^7.0.2",
"express": "^4.17.1",
"winston": "^3.3.2"
}
}
//main.js
import express from './config/myexpress'
import logger from './app/util/logger'
import config from './config/config'
const server = express(); //server.listenAsync ==== promise
//配置文件处理---取端口号---port
// const port = 3000;
server.listenAsync(config.port).then(()=>{
logger.info("Server started on port "+config.port) //日志 不会被记录到文件
})
路由
- express完整的web框架,有路由(可类比为vue-router),映射到指定的接口地址
- 文件命名: 驼峰,点号分割
process.cwd()
当前工程目录 D:\node\2
my.route.js文件:
//路由
import express from 'express'
import userCtrl from '../controllers/user.ctrl'
const router = express.Router(); //使用express框架自带的路由 类比vue-router
export default function(app){
//控制器接口--需要路由 接口请求方式(get post)
//接口定义请求方式: get post delete put
//用户 路由地址 请求方式 控制器接口
router.route('/user/list').get(userCtrl.list);
router.route('/user/login').post(userCtrl.login);// /api/user/login
//权限
//合同
//把路由配置在myexpress实例上
app.use('/api', router);
}
//myexpress.js
//导入依赖包
import util from 'util'
import express from 'express'
import bodyParser from 'body-parser'
import logger from '../app/util/logger'
export default () => {
var app = express();
// 使用promise方式将app.listen导出到外边
app.listenAsync = util.promisify(app.listen); //node8.x提供的
//跨域处理
var allowCrossDomain = function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', '*');
res.setHeader('Access-Control-Allow-Headers', '*');
next();
};
app.use(allowCrossDomain);
logger.warn('配置跨域处理')
app.use(bodyParser.json()); //解析前端发送的json数据
app.use(bodyParser.urlencoded({extended: true})); //解析前端发表单数据
//定义接口 http://localhost:3000/
app.get("/", function(req, res){
res.send('index') //接口返回字符串
})
//把user.route.js关联到app实例上
console.log(process.cwd())
require(process.cwd() + '/app/routes/my.route.js')(app)
// require('../app/routes/my.route.js')(app)
logger.warn('配置路由')
//启动服务
//app.listen(3000, function(){console.log("Server started on port 3000.")});
return app; //返回promise
}
控制器
- 用户控制器,权限控制器,合同控制器
- 控制器就是一个接口的细分, 分类
- 给浏览器返回数据
res.status(200).send(users)
res.status(200).json(users)
user.ctrl.js文件:
//用户控制器 操作用户的接口
import logger from '../util/logger'
const operations = {
// 用户登录接口
login: function(req, res){
logger.info("调用用户登录接口开始"+JSON.stringify(req.body))
//......
let msg = {msg:"登录成功"}
res.status(200).json(msg)
logger.info("调用登录结束")
},
// 用户查询列表接口
list: function(req, res){//req--request res-response
logger.info("调用用户查询接口")
let users = [{name:"小张"}, {name:"小王"}]
//给浏览器返回数据
// res.status(200).send(users)
res.status(200).json(users)
logger.info("调用用户查询接口结束")
}
}
export default operations