express-日志、开发环境、生产环境

express-日志、开发环境、生产环境

为了记录在开发的过程以及项目使用过程中的操作,通常会使用日志记录用户操作

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 devnpm run start会在控制台上打印当前的环境

根据当前环境判断是将日志保存到文件还是打印在控制台上

由于开发的时候不需要将日志打印在控制台上,所以对环境进行判断是将日志保存到文件还是打印在控制台上

if (process.env.NODE_ENV === 'development'){
  // 开发环境打印日志不保存
  app.use(logger.logger('dev'))
}else {
  // 生产环境
  app.use(logger.accessLog)
  app.use(logger.accessLogErr)
}

根据生产环境的开放环境的判断可以对数据库之类的进行不同的配置,这样就不需要在每一次部署都要修改配置数据了

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实训报告:使用 Express 框架搭建 Web 项目 一、实验目的 通过本次实训,学生应该掌握以下技能: 1. 使用 Express 框架搭建 Web 项目; 2. 使用路由来处理不同的 HTTP 请求; 3. 使用模板引擎来渲染页面; 4. 使用中间件来处理请求和响应; 5. 实现基本的用户认证和授权。 二、实验环境 1. 操作系统:Windows 或 macOS; 2. 开发工具:Visual Studio Code; 3. 语言:Node.js 和 JavaScript。 三、实验步骤 1. 创建新项目 在 Visual Studio Code 中创建一个新的文件夹并打开终端。在终端中使用 `npm init` 命令初始化项目,并根据提示输入项目信息。接着,使用 `npm install express --save` 命令安装 Express 框架。 2. 创建主文件 在项目根目录下创建一个名为 `app.js` 的文件,并添加以下代码: ``` const express = require('express'); const app = express(); app.get('/', (req, res) => { res.send('Hello World!'); }); app.listen(3000, () => { console.log('App listening on port 3000!'); }); ``` 在这个例子中,我们创建了一个简单的 Express 应用程序,并在根路径上添加了一个路由,响应一个字符串。然后,我们使用 `app.listen()` 方法来监听端口 3000。 3. 添加路由 我们可以使用路由来处理不同的 HTTP 请求。在 `app.js` 文件中,添加以下代码: ``` // 处理 GET 请求 app.get('/users', (req, res) => { res.send('Get a list of users'); }); // 处理 POST 请求 app.post('/users', (req, res) => { res.send('Create a new user'); }); // 处理 PUT 请求 app.put('/users/:id', (req, res) => { res.send(`Update a user with ID ${req.params.id}`); }); // 处理 DELETE 请求 app.delete('/users/:id', (req, res) => { res.send(`Delete a user with ID ${req.params.id}`); }); ``` 在这个例子中,我们定义了四个路由来处理 GET、POST、PUT 和 DELETE 请求。其中,PUT 和 DELETE 请求通过 URL 中的参数来指定要操作的资源的 ID。 4. 使用模板引擎 Express 框架支持多种模板引擎,如 EJS、Pug、Handlebars 等。在本次实训中,我们使用 EJS 模板引擎来渲染页面。首先,使用 `npm install ejs --save` 命令安装 EJS 模板引擎。然后,在 `app.js` 文件中添加以下代码: ``` // 设置模板引擎 app.set('view engine', 'ejs'); // 渲染页面 app.get('/users', (req, res) => { const users = [ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' } ]; res.render('users', { users }); }); ``` 在这个例子中,我们使用 `app.set()` 方法来设置模板引擎为 EJS。然后,在 `/users` 路由中,我们定义了一个数组 `users`,并将其传递给 EJS 模板引擎进行渲染。最后,我们使用 `res.render()` 方法来渲染页面,并将渲染后的 HTML 响应给客户端。 5. 使用中间件 Express 框架允许我们使用中间件来处理请求和响应。在 `app.js` 文件中,添加以下代码: ``` // 记录请求日志 app.use((req, res, next) => { console.log(`${new Date().toISOString()}: ${req.method} ${req.url}`); next(); }); // 处理静态文件 app.use(express.static('public')); ``` 在这个例子中,我们定义了两个中间件。第一个中间件用来记录请求日志,它会在每个请求到达时输出请求的时间、请求方法和 URL。第二个中间件用来处理静态文件,它会将请求的 URL 映射到项目根目录下的 `public` 文件夹中。 6. 实现用户认证和授权 在本次实训中,我们使用 Passport.js 库来实现用户认证和授权。首先,使用 `npm install passport passport-local passport-local-mongoose express-session --save` 命令安装所需的库和插件。然后,在 `app.js` 文件中添加以下代码: ``` const passport = require('passport'); const LocalStrategy = require('passport-local').Strategy; const session = require('express-session'); const mongoose = require('mongoose'); const User = require('./models/user'); // 连接 MongoDB 数据库 mongoose.connect('mongodb://localhost/myapp', { useNewUrlParser: true, useUnifiedTopology: true }).then(() => { console.log('Connected to MongoDB'); }).catch((err) => { console.error('Failed to connect to MongoDB', err); }); // 配置 Passport.js const strategy = new LocalStrategy({ usernameField: 'email', passwordField: 'password' }, async (email, password, done) => { try { const user = await User.findOne({ email }); if (!user) { return done(null, false, { message: 'Incorrect email or password.' }); } const isMatch = await user.comparePassword(password); if (!isMatch) { return done(null, false, { message: 'Incorrect email or password.' }); } return done(null, user); } catch (err) { return done(err); } }); passport.use(strategy); passport.serializeUser((user, done) => { done(null, user.id); }); passport.deserializeUser(async (id, done) => { try { const user = await User.findById(id); done(null, user); } catch (err) { done(err); } }); // 配置 Express.js app.use(express.urlencoded({ extended: true })); app.use(session({ secret: 'myapp', resave: false, saveUninitialized: false })); app.use(passport.initialize()); app.use(passport.session()); // 处理登录请求 app.get('/login', (req, res) => { res.render('login'); }); app.post('/login', passport.authenticate('local', { successRedirect: '/', failureRedirect: '/login', failureFlash: true })); // 处理注销请求 app.get('/logout', (req, res) => { req.logout(); res.redirect('/'); }); // 处理用户信息请求 app.get('/profile', (req, res) => { if (!req.user) { return res.redirect('/login'); } res.render('profile', { user: req.user }); }); ``` 在这个例子中,我们使用 `mongoose` 库连接到 MongoDB 数据库,并定义了一个名为 `User` 的模型来表示用户。然后,我们使用 Passport.js 配置了本地认证策略,并将其添加到 Express.js 应用程序中。接着,我们使用中间件来处理登录请求、注销请求和用户信息请求。在登录请求中,我们使用 `passport.authenticate()` 方法来验证用户的邮箱和密码,并在验证成功时重定向到首页。在注销请求中,我们使用 `req.logout()` 方法来注销用户。在用户信息请求中,我们检查用户是否已登录,如果未登录,则重定向到登录页面,否则渲染用户信息页面。 四、实验总结 通过本次实训,我们学习了使用 Express 框架搭建 Web 项目的基本步骤,并实现了路由、模板引擎、中间件和用户认证和授权等功能。这些技能在 Web 开发中都非常重要,可以帮助我们更加高效地开发 Web 应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值