日志
- 访问日志access log(server端最重要的日志)
- 自定义日志(包括自定义事件、错误记录等)
nodeJS文件操作, nodeJs stream
文件操作
我们新建一个‘file-test’文件夹来做我们操作文件的测试,不需要安装第三方包,值使用默认的fs
和path
即可。其中fs
用来操作文件,path
用来操作路径
const fs = require('fs')
const path = require('path')
const fileName = path.resolve(__dirname, 'data.txt')
// 读取文件内容
fs.readFile(fileName, (err, data) => {
if(err) {
console.log(err)
return
}
// data为二进制类型,需要转换为字符串
console.log(data.toString())
})
// 写入文件
const content = '这是新写入的内容\n'
const opt = {
flag: 'a' // 追加写入。 覆盖写入: 'w'
}
fs.writeFile(fileName, content, opt, (err) => {
if (err) {
console.log(err)
}
})
// 判断文件是否存在
fs.exists(fileName, (exists) => {
console.log('exists', exists)
})
分别试一试上面的文件操作功能吧,我们在‘file-test’文件夹下面新建‘file.js’和‘data.txt’文件。
注意:上面的代码只作为演示使用,实际存在着巨大问题,如,文件过大的时候,内存会吃不消造成很大浪费。我们之后会解决他。
IO操作的性能瓶颈
- IO包括“网络IO”和“文件IO”
- 相比于CPU计算和内存读写,IO的突出特点就是:慢!
如何在有限的硬件资源下提高IO的操作效率?---Stream!

上面的实例就是一个Stream的示意图,意思就像“鱼缸换水”一样,我们把大文件通过一个“管道”流向我们的客户端,这就是stream,当然我们只需要学习如何去使用即可。
下面是我们学习去操作Stream,体验一下文件流吧
我们新建一个目录,目录下面有‘test.js’文件用来写入操作Stream
的代码,再新建‘data.text’和'data-bak.txt'来作为我们的测试文件,其中我们在'data.txt'中随便写入点什么文本。准备好了就开始我们的操作吧
// 标准输入输出
process.stdin.pipe(process.stdout)
// stream 操作数据
const http = require('http')
const server = http.createServer((req,res) => {
if(req.method === 'POST') {
req.pipe(res) //最主要
}
})
server.listen(8000)
// stream 操作例子
// 复制文件
const fs = require('fs')
const path = require('path')
const fileName1 = path.resolve(__dirname, 'data.txt')
const fileName2 = path.resolve(__dirname, 'data-bak.txt')
const readStream = fs.createReadStream(fileName1)
const writeStream = fs.createWriteStream(fileName2)
readStream.pipe(writeStream)
readStream.on('data', chunk => { // 监听每次流动的内容
console.log(chunk.toString())
})
readStream.on('end', () => {
console.log('copy done')
})
//通过流的方式生成服务端数据
const http = require('http')
const fs = require('fs')
const path = require('path')
const fileName1 = path.resolve(__dirname, 'data.txt')
const server = http.createServer((req, res) => {
if (req.method === 'GET') {
const readStream = fs.createReadStream(fileName1)
readStream.pipe(res)
}
})
server.listen(8090)
上面进行了标准输入输出、操作数据、复制文件、生成服务端数据*这样的demo,不需要安装任何依赖,利用Stream
的思想以及一些API即可完成。试试吧!
日志功能开发和使用
我们已经学会了使用Stream
来高效的读写文件,下面就将它用在我么之前的项目中吧。
- 首先我们在之前的博客项目根目录中新建logs文件夹,在下面新建access.log的文件,用来记录日志。
- 在src目录下新建untils文件夹,用来放以后的一些工具方法,其下新建log.js文件,用来写一个写入日志的工具方法
准备工作做完,那我们开始写这个工具方法吧!
const fs = require('fs')
const path = require('path')
// 写日志
function writeLog(writeStream, log) {
writeStream.write(log + '\n') // 关键代码
}
// 生成 write Stream
function createWriteStream(fileName) {
const fullFileName = path.join(__dirname, '../', '../', 'logs', fileName)
const writeStream = fs.createWriteStream(fullFileName, {
flags: 'a'
})
return writeStream
}
// 访问日志
const accessWriteStream = createWriteStream('access.log')
function access(log) {
writeLog(accessWriteStream, log)
}
module.exports = {
access
}
上面是我们的工具方法,其中我们用Stream
创建一个写入文件的对象,然后就可以通过传入相应的“日志”来将其写入到我们之前新建的日志文件下了。
那么我们将在app.js中,将日志传入到本方法中
const { access } = require('./src/untils/log')
...
access(`${req.method} -- ${req.url} -- ${req.headers['user-agent']} -- ${Date.now()}`)
现在访问任一接口试试吧!是不是我们将对应的内容写入到了对应的文件夹中呢?
日志文件拆分,日志内容拆分
- 日志会慢慢积累,放在一个文件中不好处理
- 所以我们一般需要按时间来拆分日志
- 实现方式,linux的crontab命令,即定时任务。应该实现日志的拆分一般都是在服务端进行的,所以就不去研究在windows下拆分日志了,至于怎么在linux下做日志拆分,这里也不介绍了,感兴趣的可自行网上查找,因为小编是windows系统,哈哈
- 日志拆分其实主要还是运维同学的工作。我们后端开发了解即可
日志分析
- 如针对access.log日志,分析Chrome的占比
- 日志是按行存储的,一行就是一条日志
- 使用nodeJS的readline(基于Stream,效率高)
下面我们简单做一个示例,用来演示如何分析接口访问的Chrome浏览器的占比
const fs = require('fs')
const path = require('path')
const readline = require('readline')
// 文件名
const fileName = path.join(__dirname, '../', '../', 'logs', 'access.log')
// 创建 read stream
const readStream = fs.createReadStream(fileName)
// 创建 readline对象
const rl = readline.createInterface({
input: readStream
})
let chromeNum = 0
let sum = 0
// 逐行读取
rl.on('line', (lineData) => {
if(!lineData) {
return
}
// 记录总行数
sum++
const arr = lineData.split('--')
if(arr[2] && arr[2].indexOf('Chrome ') > 0) {
chromeNum ++
}
})
// 监听读取完成
rl.on('close', () => {
console.log('chrome 占比' + chromeNum/ sum )
})
然后我们按照之前做的在不同浏览器下访问接口,完成日志的写入,然后在去通过node
命令去执行这个文件,我们就会发现我们做了一个简单的日志分析,其他的应用也是同理。这里建议该文件建在untils下,作为一个工具使用。
到此为止,我们在nodeJS中做日志分析,就完成了,动手练练吧
网友评论