目录结构
环境搭建
安装nodemon
npm i nodemon cross-env --save-dev
// package.json
"dev": "cross-env NODE_ENV=dev --inspect=9229 nodemon ./index.js"
创建http服务
const http = require('http')
const server = http.createServer((req, res) => {
res.end('hello node')
})
server.listen(3000)
执行脚本npm run dev,看到下图说明服务启动成功
写日志
选择stream方式写文件的原因
- 内存效率: 无需加载大量的数据到内存中即可进行处理。
- 时间效率: 当获得数据之后即可立即开始处理数据,这样所需的时间更少,而不必等到整个数据有效负载可用才开始。
log.js
const fs = require('fs')
const path = require('path')
// 写日志
function writeLog(writeStream, log) {
writeStream.write(log + '\n')
}
function createWriteStream(fileName) {
const fullWriteFilePath = path.resolve(__dirname, '../', 'log', fileName)
console.log(fullWriteFilePath)
// 创建这个
const writeStream = fs.createWriteStream(fullWriteFilePath, {
flags: 'a' // 打开文件进行追加。 如果文件不存在,则创建该文件。
})
return writeStream
}
function access(log) {
const accessWriteStream = createWriteStream('access.log')
writeLog(accessWriteStream, log)
}
module.exports = {
access
}
index.js
引入操作日志的方法,进行写日志
const http = require('http')
const { access } = require('./utils/log')
const server = http.createServer((req, res) => {
access(`${req.method} -- ${req.url} -- ${req.headers['user-agent']} -- ${Date.now()}`)
res.end('hello node')
})
server.listen(3000)
此时可以看到access.log里边有记录了
分析日志
readline.js
const fs = require('fs')
const path = require('path')
const readline = require('readline')
const fullPathName = path.resolve(__dirname, '../', 'log', 'access.log')
// 创建read stream
const readStream = fs.createReadStream(fullPathName)
// 创建readline对象
const rl = readline.createInterface({
input: readStream
})
let chromeNum = 0
let sum = 0
rl.on('line', lineData => {
if(!lineData) {
return
}
sum ++
if(/Chrome/.test(lineData)) {
chromeNum ++
}
})
rl.on('close', () => {
console.log('chrome占比', chromeNum / sum)
})
总结
流是一种以高效的方式处理读/写文件、网络通信、或任何类型的端到端的信息交换。使用流,则可以逐个片段地读取并处理(而无需全部保存在内存中)。因此日志的读写使用流的方式,避免文件过大时内存负载过大影响性能。