此文章主要讲解如何使用Nuxt进行日志监控,例如服务端请求日志,客户端请求日志,方便线上出现问题能及时排查问题所在
一、下载依赖
npm install winston winston-daily-rotate-file
二、plugin下创建日志处理插件winston.js,对日志进行分级
export default function ({ app }) {
if (process.server) {
const winston = require('winston');
const path = require('path');
const { combine, timestamp } = winston.format;
const infoLogPath = path.resolve(process.cwd(), './logs', `info.log`);
const errorLogPath = path.resolve(process.cwd(), './logs', `error.log`);
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.printf(({ timestamp, level, message }) => {
return `${timestamp} [${level}]: ${message}`;
})
),
transports: [
new winston.transports.File({
format: combine(timestamp()),
level: 'info',
filename: infoLogPath,
maxsize: 5 * 1024 * 1024, // 单个日志文件大小
maxFiles: 3 // 最大文件数
}),
new winston.transports.File({
format: combine(timestamp()),
level: 'error',
filename: errorLogPath,
maxsize: 5 * 1024 * 1024,
maxFiles: 3
})
]
});
app.$winstonLog = logger;
}
}
三、客户端错误全局监听,plugin中创建errorHandler.js
// plugin/errorHandler.js
import Vue from 'vue'
import axios from 'axios'
export default ({ app }) => {
Vue.config.errorHandler = (error, instance, info) => {
// 获取当前页面的路由信息
const currentRoute = app.router.currentRoute;
const str = `Client error on page: ${currentRoute.fullPath} | Error: ${error.message} | Info: ${info}`
// 直接请求后端接口,把错误信息给后端,让后端进行客户端错误的日志存储
axios.post('/xxxxxxx',{ message: str })
};
};
四、插件挂载nuxt.config.js
一定要放在plugins中最前面,后续的插件中才能拿到app.$winstonLog
// nuxt.config.js
export default {
plugins: [
{ src: '~/plugin/winston.js', ssr: true },
{ src: '~/plugin/errorHandler.js' },
....
]
}
五、在服务端请求axios 里做日志打点
捕获在Node端接口请求错误,对日志进行添加
// utils/axios.js
export default ({ $axios, app }) => {
$axios.onResponse((response) => {
// app.$winstonLog只在服务端存在,需要判断是否存在 正常返回这里可以无需记录
if (app.$winstonLog) {
app.$winstonLog.info(`[${response.status}] ${response.request.path}`);
}
return response.data;
});
$axios.onError((err) => {
// 接口请求异常 添加日志记录
if (app.$winstonLog) {
app.$winstonLog.error(
`ServerApi | ${err.request.path} | ${err.message}`
);
app.$winstonLog.error(err.response && err.response.data);
}
});
};
六、查看日志记录
winston会在每次请求页面的时候自动打印一次日志,在 node 端出错的时候也会自动打印日志,会在当前项目中生成logs文件夹
---------------------------------------客户端错误日志前端自行处理版本----------------------------------------------
一、下载依赖
npm install winston winston-daily-rotate-file express
二、plugin下创建日志处理插件logger.js,对日志进行分级
export const loggerFun = () => {
const winston = require('winston');
const path = require('path');
const { combine, timestamp } = winston.format;
const infoLogPath = path.resolve(process.cwd(), './logs', `info.log`);
const errorLogPath = path.resolve(process.cwd(), './logs', `error.log`);
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.printf(({ timestamp, level, message }) => {
return `${timestamp} [${level}]: ${message}`;
})
),
transports: [
new winston.transports.File({
format: combine(timestamp()),
level: 'info',
filename: infoLogPath,
maxsize: 5 * 1024 * 1024, // 单个日志文件大小
maxFiles: 3 // 最大文件数
}),
new winston.transports.File({
format: combine(timestamp()),
level: 'error',
filename: errorLogPath,
maxsize: 5 * 1024 * 1024,
maxFiles: 3
})
]
});
return logger
}
三、plugin下创建日志处理插件winston.js插件
export default function ({ app }) {
if (process.server) {
const {loggerFun} = require('./logger');
app.$winstonLog = loggerFun();
}
}
四、plugin下创建客户端错误插件errorHandler.js
import Vue from 'vue'
import axios from 'axios'
export default ({ app }) => {
Vue.config.errorHandler = (error, instance, info) => {
// 获取当前页面的路由信息
const currentRoute = app.router.currentRoute;
const str = `Client error on page: ${currentRoute.fullPath} | Error: ${error.message} | Info: ${info}`
// 请求Nuxt自定义node接口,因为客户端错误无法访问app.$winstonLog,需要注意的是线上不同端口要做区分 及跨域处理
axios.post('/logs/setLog',{ message: str })
};
};
五、根目录创建serverMiddleware文件夹,并创建setLog.js,自定义Node接口设置日志
const express = require('express');
const app = express();
app.use(express.json());
const {loggerFun} = require('../plugin/logger');
app.post('/setLog', (req, res) => {
const logger = loggerFun()
logger.error(req.body.message);
res.json({
status: 'ok'
})
})
module.exports = {
path: 'logs',
handler: app
}
六、插件挂载nuxt.config.js
一定要放在plugins中最前面,后续的插件中才能拿到app.$winstonLog
// nuxt.config.js
export default {
serverMiddleware: [
'~/serverMiddleware/setLog.js'
],
plugins: [
{ src: '~/plugin/winston.js', ssr: true },
{ src: '~/plugin/errorHandler.js' },
....
]
}