Node系列学习之日志(二)

360 阅读2分钟

这是我参与更文挑战的第30天,活动详情查看:更文挑战

写日志

新建src/logs 文件夹, 并新建access.log, error.log, event.log 三个日志文件

新建 utils/log.js 写封装的日志方法

utils/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, {
    flogs: 'a'
  })
  return writeStream
}

// 写访问日志
const accessWriteStream = createWriteStream('access.log')
function access(log) {
  writeLog(accessWriteStream, log)
}
module.exports = {
  access
}

然后引入使用

app.js

...
const {access}  = require('./src/utils/log')
...
const serverHandle = (req, res) => {
  // 记录 access log
  access(`${req.method} -- ${req.url} -- ${req.headers['user-agent']} -- ${Date.now()}`)
  // 设置返回格式
  res.setHeader('Content-Type', 'application/json')

  // 获取path
  const url = req.url
  req.path = url.split('?')[0]

  // 解析 query
  req.query = querystring.parse(url.split('?')[1])

  // 解析cookie
  req.cookie = {}
  const cookieStr = req.headers.cookie || ''
  cookieStr.split(';').forEach(item => {
    if (!item) {
      return
    }
    console.log('item: ', item);
    const arr = item.split('=')
    const key = arr[0].trim()
    const val = arr[1].trim()
    req.cookie[key] = val
  })
  console.log('req.cookie', req.cookie);
  // 解析session, 使用redis
  let needSetCookie = false // 是否设置Set-Cookie, 默认为false
  let userId = req.cookie.userId // 在req中获取userId
  console.log('userId', req.cookie.userId);
  // 对是否存在userId分别进行处理
  if (!userId) {
    needSetCookie = true // 打开需要服务端设置Cookie开关
    userId = `${Date.now()}_${Math.random()}` // 随机生成userId
    // 初始化 redis 中的 session 值
    set(userId, {})
  }
  // 获取session
  req.sessionId = userId // 设置req.sessionId
  get(req.sessionId)
    .then(sessionData => {
      console.log('sessionData',sessionData);
      // debugger
      // redis中的sessionData为null时
      if (sessionData == null) {
        // 初始化 redis 中的 session 值
        set(req.sessionId, {})
        // 设置session
        req.session = {}
      } else {
        req.session = sessionData
      }
      // 处理 postData
      return getPostData(req)
    })
    .then(postData => {
      req.body = postData
      // 处理 blog 路由 旧

      // const blogData = handleBlogRouter(req, res)
      // if (blogData) {
      //   res.end(JSON.stringify(blogData))
      //   return
      // }

      // 处理 blog 路由 新
      const blogResult = handleBlogRouter(req, res)
      if (blogResult) {
        blogResult.then(blogData => {
          // 路由处理完成后, 如果needSetCookie为true时,设置Set-Cookie
          if (needSetCookie) {
            res.setHeader('Set-Cookie', `userId=${userId}; path=/; httponly; expires=${getCookieExpires()}`)
            needSetCookie = false
          }
          res.end(JSON.stringify(blogData))
        })
        return
      }

      // 处理 user 路由
      // const userData = handleUserRouter(req, res)
      // if (userData) {
      //   res.end(JSON.stringify(userData))
      //   return
      // }
      const userResult = handleUserRouter(req, res)
      if (userResult) {
        userResult.then(userData => {
          // 路由处理完成后, 如果needSetCookie为true时,设置Set-Cookie
          if (needSetCookie) {
            res.setHeader('Set-Cookie', `userId=${userId}; path=/; httponly; expires=${getCookieExpires()}`)
            needSetCookie = false
          }
          res.end(JSON.stringify(userData))
        })
        return
      }

      // 未命中路由, 返回404
      res.writeHead(404, { 'Content-Type': 'text/plain' })
      res.write('404 Not Found\n')
      res.end()
    })
}

然后刷新一下接口, 发现 access.log 中写入记录

GET -- /api/blog/list?isadmin=1 -- Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 -- 1625066885837
GET -- /api/blog/list?isadmin=1 -- Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 -- 1625066886470
GET -- /api/blog/list?isadmin=1 -- Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 -- 1625066887164
GET -- /api/blog/detail?id=17 -- Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 -- 1625066917923
GET -- /api/blog/detail?id=17 -- Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 -- 1625066919531
GET -- /api/blog/list?isadmin=1 -- Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 -- 1625066920573

日志拆分

utils 下新建 copy.sh

#!/bin/sh
cd D:/GithubPro/node-blog/src/logs
cp access.log $(date +%Y-%m-%d).access.log
echo "" > access.log

在执行命令的时候会将当前日志备份, 并以时间戳重命名, 完成后清空当前日志内容~