Node.js躬行记(10)——接口日志查询
当运营向我们上报BUG时,我们第一时间是捕获相关的接口。从监控系统中,就可以查到用户使用时接口的请求和响应数据。
若接口的请求正常,那么就需要深入到接口代码中,查看相关的日志,通常会先浏览数据库查询语句以及内部接口的通信日志。
在本地也可以查看到上述日志,但有个问题,有时候打开某个页面会报错,那是因为本地的数据库没有与测试或正式环境的同步。
可能是有些字段缺失了,也可能是某张表缺失了,情况比较多。所以,最保险的是在测试或正式环境查看。
在这两个环境中,都有日志管理系统,但日志量是非常巨大的,若要查找某一条记录,就得有非常精确的过滤条件,并且日志无法连续。
这条日志下面的一条,很可能是另外一个接口留下的,因此,需要一个小工具能查看到指定接口的日志,解决日常开发的一个痛点。
一、搜集日志
1)管理系统
首先需要将需要的日志搜集起来,我使用了一个比较简单的方法。
就是在启动文件中,新增一个全局的logMessages变量,声明为一个空数组。
global.logMessages = [];
然后在MongoDB、MySQL、请求内部接口函数中,将他们的查询语句日志和通信日志塞入logMessages数组内。
mongoose.set('debug', (...args) => {
logger.debug(...args);
global.logMessages.push(args);
});
new Sequelize(database, username, password, {
...options,
logging: (msg, benchmark) => {
logger.debug(msg, `${benchmark}ms`);
global.logMessages.push(msg);
}
});
再新增一个中间件(Server项目基于KOA2),这个中间件的作用就是清空logMessages数组,免得将所有接口的日志都搜集起来,因为我只要一个接口的日志。
export default () => async (ctx, next) => {
//每次请求清空要读取的日志数组
global.logMessages.length = 0;
await next();
};
这么设计会有一个问题,服务器在处理多个请求(高并发)时,互相会影响各自的日志搜集,可能会出现这个接口日志中夹杂着另一个接口的日志,也可能是搜集到一半的日志就被清除了。
当然,在测试环境,这种情况可以控制住。但是测试环境有时候数据不完整,逻辑可能走不下去,得上生产环境,那生产环境就有概率出现上述问题。
后面将中间件去除,logMessages变量在一个接口中声明,这个接口就是下面界面中点提交时请求的接口,能解决日志被无故清除的问题,但还是会出现串线的问题。
生产环境暂时无解,好在还有一个预发环境,它使用的数据源和生产是相同的,只要保证代码和生产同步,那么就能得到想要的日志列表。
2)Web API
Web API是另一个接口服务,也需要监控其中的日志,但是它与之前的管理系统不同,它是一个独立的服务。
也就是说,我无法直接在管理系统中通过 global.logMessages 读取日志。
一开始是想将日志写入缓存中,然后在管理系统中读取缓存中的日志,不过这样做不仅太绕,平添复杂度,而且日志写法也会与之前的不一致。
于是否决了此方案,改用一个中间件,日志的写入和读取与之前保持一致。不同点是在一个中间件中,将日志作为响应的参数返回。
在下面的代码中,当需要日志时,我会带上一个特殊的参数:isLogMessages,只有这个参数存在时,才表示需要返回记录。
export default () => async (ctx, next) => {
// 只有带了特殊参数的请求,才会把接口日志带上
const isLogMessages = ctx.query.isLogMessages || ctx.request.body.isLogMessages;
if(isLogMessages) {
global.logMessages = [];
}
await next();
if(isLogMessages) {
const { body } = ctx;
if(typeof body === 'string') {
ctx.body = {
data: body
};
}else {
ctx.body = {
...body
}
}
ctx.body.logMessages = global.logMessages;
delete global.logMessages;
}
二、界面
在完成上述的日志搜集之后,就需要有一张操作界面(如图所示),提升我们组自己的用户体验,借助之前封装的模板组件,搭建这样一个页面几十分钟就好了。

界面中包括API路径、方法、项目和参数,其中参数可动态增加,点击提交就会开始模拟请求接口,得到日志(如图所示)和响应。

这样一套操作之后,就能马上知道接口内的细节,可帮助我们快速定位问题,也是一种降低时间成本的手段。
Node.js躬行记(10)——接口日志查询的更多相关文章
- Node.js躬行记(21)——花10分钟入门Node.js
Node.js 不是一门语言,而是一个基于 V8 引擎的运行时环境,下图是一张架构图. 由图可知,Node.js 底层除了 JavaScript 代码之外,还有大量的 C/C++ 代码. 常说 Nod ...
- Node.js躬行记(8)——通用接口
一.GraphQL 最近服务端的同事分享了GraphQL,他分享的目的就是要把我们与他们的数据库隔离,这么做我们也求之不得. 我们组目前维护着一个后台管理系统,会直接读取数据库中的表,如果能隔离的话, ...
- Node.js躬行记(1)——Buffer、流和EventEmitter
一.Buffer Buffer是一种Node的内置类型,不需要通过require()函数额外引入.它能读取和写入二进制数据,常用于解析网络数据流.文件等. 1)创建 通过new关键字初始化Buffer ...
- Node.js躬行记(2)——文件系统和网络
一.文件系统 fs模块可与文件系统进行交互,封装了常规的POSIX函数.POSIX(Portable Operating System Interface,可移植操作系统接口)是UNIX系统的一个设计 ...
- Node.js躬行记(4)——自建前端监控系统
这套前端监控系统用到的技术栈是:React+MongoDB+Node.js+Koa2.将性能和错误量化.因为自己平时喜欢吃菠萝,所以就取名叫菠萝系统.其实在很早以前就有这个想法,当时已经实现了前端的参 ...
- Node.js躬行记(6)——自制短链系统
短链顾名思义是一种很短的地址,应用广泛,例如页面中有一张二维码图片,包含的是一个原始地址(如下所示),如果二维码中的链接需要修改,那么就得发代码替换掉. 原始地址:https://github.com ...
- Node.js躬行记(19)——KOA源码分析(上)
本次分析的KOA版本是2.13.1,它非常轻量,诸如路由.模板等功能默认都不提供,需要自己引入相关的中间件. 源码的目录结构比较简单,主要分为3部分,__tests__,lib和docs,从名称中就可 ...
- Node.js躬行记(23)——Worker threads
Node.js 官方提供了 Cluster 和 Child process 创建子进程,通过 Worker threads 模块创建子线程.但前者无法共享内存,通信必须使用 JSON 格式,有一定的局 ...
- Node.js躬行记(15)——活动规则引擎
在日常的业务开发中,会包含许多的业务规则,一般就是用if-else硬编码的方式实现,这样就会增加逻辑的维护成本,若无注释,可能都无法理解规则意图. 因为一旦规则有所改变,那么就需要修改代码再发布代码, ...
随机推荐
- Docker部署Zookeeper部署实践(1)
Zookeeper可提供的服务主要有:配置服务.名字服务.分布式同步.组服务等 1. 抓取Zookeeper镜像 命令:docker pull zookeeper 2. 将Zookeeper镜像保存为 ...
- Thymeleaf页面静态化技术
Teymeleaf的使用 案例一:springboot搭建Thymeleaf 1.导入依赖 2.新建html页面模板 3.新建前端控制层Controller 4.新建启动类 1.导入依赖 <?x ...
- 把对象交给spring管理的3种方法及经典应用
背景 先说一说什么叫把对象交给spring管理.它区别于把类交给spring管理.在spring里采用注解方式@Service.@Component这些,实际上管理的是类,把这些类交给spring来负 ...
- Linux搭建Radius服务器
安装环境介绍 以下服务器信息为该文档安装Radius服务环境 服务器信息:CentOS7 内核版本:3.10.0-1062.el7.x86_64 安装软件版本 freeradius-utils-3.0 ...
- noip17
复杂度分析全部摘自题解 T1 sb优化暴力 暴力20-40pts,我只拿了20pts. 正解: bitset 优化暴力,但是会MLE. 再次考虑如何优化,我们统计一下每个点的入度,每次遍历到这个点的时 ...
- 常用css样式(文字超出部分用省略号显示、鼠标经过图片放大、出现阴影)
文字超出部分用省略号显示: white-space: nowrap; /* 不换行 */ overflow: hidden; /* 超出部分不显示 */ text-overflow: ellipsis ...
- reduce使用技巧
一.使用reduce同时执行map(循环)和filter(过滤) 例如,将数组中的项的值加倍,然后只选择那些大于50的项 const numbers = [10, 20, 30, 40]; const ...
- ES6中新增的数组知识记录
JSON数组格式转换 let json = { '0': 'hello', '1': 'I am ', '2': 'michael', length:3 } 这就是一个JSON数组格式,跟普通的JSO ...
- QT 编译的过程
- 1、Spark简介(Python版)
此文为个人学习笔记如需系统学习请访问http://dblab.xmu.edu.cn/blog/1709-2/ Spark具有如下几个主要特点: 运行速度快 Spark使用先进的DAG(Dir ...