前端记录日志生成文件保存到本地

2024-06-22 00:44

本文主要是介绍前端记录日志生成文件保存到本地,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、前言

项目上线后业务人员反馈说是打印数据不准确,通过websocket连接打印机服务去进行打印,会出现条码漏打的情况;通过后端日志和打印机日志均没有找到问题原因,猜测是websocket连接断开导致的问题。

也想通过前端日志去排查问题,本人据理力争说控制台有日志输出;奈何现场人员不会看控制台信息,无奈只能研究如何去生成前端日志。

二、日志思路

首先需要了解前端如何去生成日志,最终保存到用户电脑中。为此需要明确几点:

  1. 日志的生成方法;
  2. 日志信息如何展示;
  3. 保存方法与保存路径;
  4. 哪些信息需要保存到日志中;

2.1 日志生成的方法

日志信息需要定义一个变量,这个根据具体需求;如果是单一功能需要日志操作信息,则只需要定义局部变量;如果是整个项目都需要日志操作信息,则需要定义全局变量。

本次示例日志变量挂载到window上,这样可以直接获取及更改。

// 判断是否有日志变量
if (window.historryRecordLogs) {// 初始化日志变量window.historryRecordLogs = [];
}
// 根据项目需求去跟更改日志信息类型,建立一个消息队列;
// 需要记录的信息放进日志队列里面去
window.historryRecordLogs.push({// 如果需要前台展示效果可以根据类型展示不同样式type: "日志类型",	message: "具体日志信息",userName: "操作人",dateTime: "操作时间",
});

2.2 整理生成txt文件下载

最终我们需要得到这样一个日志文件,就需要前端生成一个文件,手动或被动去生成一个日志文件。

实现步骤:

  1. 整理日志信息,汇总输出文字;
  2. JS通过Blob方法生成一个Blob文件;
  3. 在生成一个临时a标签,来模拟手动下载;

简单示例:

// 导出下载日志文件
const exportFileTxt = () => {// 判断是否有日志变量if (window.historryRecordLogs && window.historryRecordLogs.length) {// 整理日志信息const dataTxt = window.historryRecordLogs.reduce((cur, next) => cur +=`操作人:${next.userName},日志信息:<${next.message}> 操作时间:${next.dataTime}\n`, "");// 生成一个Blob文件const urlObject = window.URL || window.webkitURL || window;const blobFile = new Blob([dataTxt]);// 生成一个a标签模拟下载const aDom = document.createElement("a")aDom.href = urlObject.createObjectURL(blobFile);// 定义文件名称aDom.download = `${moment(new Date())}_logs`;aDom.click();}
};

2.3 保存路径

保存路径是当前浏览器的默认下载路径,无法手动指定下载文件路径;

2.3.1 下载方式:
  1. 可以设置用户退出登录后默认下载;
  2. 放在头部导航栏,有需求的情况下再点击下载;
2.3.2 注意事项
  1. 如果采用默认下载的情况需要结合具体情况;
  2. 当用户直接关闭浏览器时无法自动下载;
  3. 直接关闭标签页也无法下载(这个可以监听关闭当前标签页的事件);
window.addEventListener('beforeunload', function (e) {// 取消关闭标签页的默认行为e.preventDefault();// 自定义确认消息e.returnValue = '您有未保存的更改,确定要离开吗?';
});

2.4 整理哪些信息存储日志

  1. 前端接口的报错信息;
  2. 敏感数据的操作流程;
  3. websocket连接状态详细日志记录;

三、详细记录

3.1 前端接口报错信息记录

// 封装一个请求方法,在catch阶段进行错误捕获
const request = async (url, options) => {try {const response = await fetch(url, options);if (!response.ok) {throw new Error(response.statusText);}return await response.json();} catch (error) {window.historryRecordLogs.push({type: "error",message: error.message,userName: "操作人",dateTime: moment(new Date()).format('YYYY-MM-DD HH:mm:ss')});throw error;}
};

3.2 敏感数据的操作流程

// 假设有一个敏感操作的函数
function sensitiveOperation() {try {// 操作逻辑} catch (e) {window.historryRecordLogs.push({type: "sensitiveOperation",message: e.message || '未知错误',userName: "操作人",dateTime: moment(new Date()).format('YYYY-MM-DD HH:mm:ss')});}
}

3.3 websocket连接状态详细日志记录

const ws = new WebSocket("ws://example.com");ws.onopen = () => {window.historryRecordLogs.push({type: "websocket",message: "WebSocket连接已打开",userName: "操作人",dateTime: moment(new Date()).format('YYYY-MM-DD HH:mm:ss')});
};ws.onclose = (event) => {window.historryRecordLogs.push({type: "websocket",message: `WebSocket连接已关闭,代码:${event.code},原因:${event.reason}`,userName: "操作人",dateTime: moment(new Date()).format('YYYY-MM-DD HH:mm:ss')});
};ws.onerror = (error) => {window.historryRecordLogs.push({type: "websocket",message: `WebSocket错误:${error.message}`,userName: "操作人",dateTime: moment(new Date()).format('YYYY-MM-DD HH:mm:ss')});
};

四、总结

通过以上步骤,我们可以实现前端日志的记录和下载,方便我们排查问题。但是需要注意的是,这种方式并不能解决所有的问题,有些问题可能需要结合后端日志或者浏览器的开发者工具来解决。同时,这种方式也有一定的风险,因为日志信息可能会被恶意用户利用,所以我们需要确保日志信息的安全性。

这篇关于前端记录日志生成文件保存到本地的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1082810

相关文章

51单片机学习记录———定时器

文章目录 前言一、定时器介绍二、STC89C52定时器资源三、定时器框图四、定时器模式五、定时器相关寄存器六、定时器练习 前言 一个学习嵌入式的小白~ 有问题评论区或私信指出~ 提示:以下是本篇文章正文内容,下面案例可供参考 一、定时器介绍 定时器介绍:51单片机的定时器属于单片机的内部资源,其电路的连接和运转均在单片机内部完成。 定时器作用: 1.用于计数系统,可

Javascript高级程序设计(第四版)--学习记录之变量、内存

原始值与引用值 原始值:简单的数据即基础数据类型,按值访问。 引用值:由多个值构成的对象即复杂数据类型,按引用访问。 动态属性 对于引用值而言,可以随时添加、修改和删除其属性和方法。 let person = new Object();person.name = 'Jason';person.age = 42;console.log(person.name,person.age);//'J

vue, 左右布局宽,可拖动改变

1:建立一个draggableMixin.js  混入的方式使用 2:代码如下draggableMixin.js  export default {data() {return {leftWidth: 330,isDragging: false,startX: 0,startWidth: 0,};},methods: {startDragging(e) {this.isDragging = tr

vcpkg安装opencv中的特殊问题记录(无法找到opencv_corexd.dll)

我是按照网上的vcpkg安装opencv方法进行的(比如这篇:从0开始在visual studio上安装opencv(超详细,针对小白)),但是中间出现了一些别人没有遇到的问题,虽然原因没有找到,但是本人给出一些暂时的解决办法: 问题1: 我在安装库命令行使用的是 .\vcpkg.exe install opencv 我的电脑是x64,vcpkg在这条命令后默认下载的也是opencv2:x6

vue项目集成CanvasEditor实现Word在线编辑器

CanvasEditor实现Word在线编辑器 官网文档:https://hufe.club/canvas-editor-docs/guide/schema.html 源码地址:https://github.com/Hufe921/canvas-editor 前提声明: 由于CanvasEditor目前不支持vue、react 等框架开箱即用版,所以需要我们去Git下载源码,拿到其中两个主

React+TS前台项目实战(十七)-- 全局常用组件Dropdown封装

文章目录 前言Dropdown组件1. 功能分析2. 代码+详细注释3. 使用方式4. 效果展示 总结 前言 今天这篇主要讲全局Dropdown组件封装,可根据UI设计师要求自定义修改。 Dropdown组件 1. 功能分析 (1)通过position属性,可以控制下拉选项的位置 (2)通过传入width属性, 可以自定义下拉选项的宽度 (3)通过传入classN

android 带与不带logo的二维码生成

该代码基于ZXing项目,这个网上能下载得到。 定义的控件以及属性: public static final int SCAN_CODE = 1;private ImageView iv;private EditText et;private Button qr_btn,add_logo;private Bitmap logo,bitmap,bmp; //logo图标private st

js+css二级导航

效果 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Con

记录AS混淆代码模板

开启混淆得先在build.gradle文件中把 minifyEnabled false改成true,以及shrinkResources true//去除无用的resource文件 这些是写在proguard-rules.pro文件内的 指定代码的压缩级别 -optimizationpasses 5 包明不混合大小写 -dontusemixedcaseclassnames 不去忽略非公共

基于Springboot + vue 的抗疫物质管理系统的设计与实现

目录 📚 前言 📑摘要 📑系统流程 📚 系统架构设计 📚 数据库设计 📚 系统功能的具体实现    💬 系统登录注册 系统登录 登录界面   用户添加  💬 抗疫列表展示模块     区域信息管理 添加物资详情 抗疫物资列表展示 抗疫物资申请 抗疫物资审核 ✒️ 源码实现 💖 源码获取 😁 联系方式 📚 前言 📑博客主页: